convert-model.yml 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. name: Convert Model to GGUF
  2. on:
  3. workflow_dispatch:
  4. inputs:
  5. hf_repo:
  6. description: 'HuggingFace 仓库名称 (例如: GaboxR67/MelBandRoformers)'
  7. required: true
  8. type: string
  9. checkpoint_path:
  10. description: '权重文件路径 (相对于仓库, 例如: melbandroformers/vocals/voc_fv6.ckpt)'
  11. required: true
  12. type: string
  13. config_path:
  14. description: '配置文件路径 (相对于仓库, 例如: melbandroformers/vocals/voc_gabox.yaml)'
  15. required: true
  16. type: string
  17. model_name:
  18. description: '输出模型名称 (用于文件命名, 例如: voc_fv6)'
  19. required: false
  20. type: string
  21. default: 'MelBandRoformer-'
  22. quantization_types:
  23. description: '要转换的量化类型 (用逗号分隔, 留空则转换全部)'
  24. required: false
  25. type: string
  26. default: 'fp32,fp16,q8_0,q4_0,q4_1,q5_0,q5_1'
  27. env:
  28. SUPPORTED_QUANT_TYPES: 'fp32,fp16,q8_0,q4_0,q4_1,q5_0,q5_1'
  29. jobs:
  30. convert-to-all-quant-types:
  31. runs-on: ubuntu-latest
  32. steps:
  33. - name: Checkout
  34. uses: actions/checkout@v4
  35. - name: Setup Python
  36. uses: actions/setup-python@v5
  37. with:
  38. python-version: '3.11'
  39. - name: Install Dependencies
  40. run: |
  41. pip install torch --index-url https://download.pytorch.org/whl/cpu
  42. pip install huggingface_hub gguf librosa einops pyyaml numpy
  43. - name: Download Model from HuggingFace
  44. env:
  45. HF_TOKEN: ${{ secrets.HF_TOKEN }}
  46. run: |
  47. python -c "
  48. from huggingface_hub import hf_hub_download
  49. import os
  50. token = os.environ.get('HF_TOKEN') or None
  51. repo = '${{ inputs.hf_repo }}'
  52. print(f'Downloading from {repo}...')
  53. # Download checkpoint
  54. ckpt_path = hf_hub_download(
  55. repo,
  56. '${{ inputs.checkpoint_path }}',
  57. local_dir='./model',
  58. token=token
  59. )
  60. print(f' Checkpoint: {ckpt_path}')
  61. # Download config
  62. config_path = hf_hub_download(
  63. repo,
  64. '${{ inputs.config_path }}',
  65. local_dir='./model',
  66. token=token
  67. )
  68. print(f' Config: {config_path}')
  69. "
  70. - name: Show Model Info
  71. run: |
  72. echo "=== Model Configuration ==="
  73. cat model/${{ inputs.config_path }}
  74. echo ""
  75. echo "=== Checkpoint File Size ==="
  76. ls -lh model/${{ inputs.checkpoint_path }}
  77. - name: Create Output Directory
  78. run: mkdir -p output
  79. - name: Convert to All Quantization Types
  80. run: |
  81. #!/bin/bash
  82. set -e
  83. CHECKPOINT="model/${{ inputs.checkpoint_path }}"
  84. CONFIG="model/${{ inputs.config_path }}"
  85. MODEL_NAME="${{ inputs.model_name }}"
  86. QUANT_TYPES="${{ inputs.quantization_types }}"
  87. # If no types specified, use all supported types
  88. if [ -z "$QUANT_TYPES" ]; then
  89. QUANT_TYPES="${{ env.SUPPORTED_QUANT_TYPES }}"
  90. fi
  91. echo "=== Converting Model: $MODEL_NAME ==="
  92. echo "Checkpoint: $CHECKPOINT"
  93. echo "Config: $CONFIG"
  94. echo "Quantization Types: $QUANT_TYPES"
  95. echo ""
  96. # Convert comma-separated to array
  97. IFS=',' read -ra TYPES <<< "$QUANT_TYPES"
  98. for qtype in "${TYPES[@]}"; do
  99. # Trim whitespace
  100. qtype=$(echo "$qtype" | xargs)
  101. # Generate output filename following GGUF naming convention
  102. # Format: {model_name}-{quantization}.gguf
  103. OUTPUT_FILE="output/${MODEL_NAME}-${qtype^^}.gguf"
  104. echo ">>> Converting to $qtype -> $OUTPUT_FILE"
  105. python scripts/convert_to_gguf.py \
  106. --ckpt "$CHECKPOINT" \
  107. --config "$CONFIG" \
  108. --out "$OUTPUT_FILE" \
  109. --dtype "$qtype"
  110. # Show file size
  111. SIZE=$(ls -lh "$OUTPUT_FILE" | awk '{print $5}')
  112. echo " Output size: $SIZE"
  113. echo ""
  114. done
  115. echo "=== Conversion Complete ==="
  116. ls -lh output/
  117. - name: Generate Summary Report
  118. run: |
  119. python -c "
  120. import os
  121. import json
  122. output_dir = 'output'
  123. model_name = '${{ inputs.model_name }}'
  124. report = {
  125. 'model_name': model_name,
  126. 'hf_repo': '${{ inputs.hf_repo }}',
  127. 'checkpoint': '${{ inputs.checkpoint_path }}',
  128. 'config': '${{ inputs.config_path }}',
  129. 'files': []
  130. }
  131. total_size = 0
  132. for f in sorted(os.listdir(output_dir)):
  133. if f.endswith('.gguf'):
  134. path = os.path.join(output_dir, f)
  135. size_bytes = os.path.getsize(path)
  136. total_size += size_bytes
  137. # Extract quant type from filename
  138. quant_type = f.replace(f'{model_name}-', '').replace('.gguf', '')
  139. report['files'].append({
  140. 'filename': f,
  141. 'quant_type': quant_type,
  142. 'size_bytes': size_bytes,
  143. 'size_mb': round(size_bytes / 1024 / 1024, 2)
  144. })
  145. report['total_size_bytes'] = total_size
  146. report['total_size_mb'] = round(total_size / 1024 / 1024, 2)
  147. # Write JSON report
  148. with open('output/conversion_report.json', 'w') as f:
  149. json.dump(report, f, indent=2)
  150. # Print markdown table for GitHub Actions summary
  151. print('## Conversion Report')
  152. print('')
  153. print(f'**Model**: {model_name}')
  154. print(f'**Source**: [{report[\"hf_repo\"]}](https://huggingface.co/{report[\"hf_repo\"]})')
  155. print('')
  156. print('| Quantization | Filename | Size |')
  157. print('|--------------|----------|------|')
  158. for f in report['files']:
  159. print(f'| {f[\"quant_type\"]} | {f[\"filename\"]} | {f[\"size_mb\"]} MB |')
  160. print('')
  161. print(f'**Total Size**: {report[\"total_size_mb\"]} MB')
  162. " | tee -a $GITHUB_STEP_SUMMARY
  163. - name: Upload Converted Models
  164. uses: actions/upload-artifact@v4
  165. with:
  166. name: gguf-models-${{ inputs.model_name }}
  167. path: |
  168. output/*.gguf
  169. output/conversion_report.json
  170. retention-days: 30
  171. compression-level: 0 # GGUF is already compressed for quantized types