convert-model.yml 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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: 'model'
  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. cache: 'pip'
  40. - name: Install Dependencies
  41. run: |
  42. pip install torch --index-url https://download.pytorch.org/whl/cpu
  43. pip install huggingface_hub gguf librosa einops pyyaml numpy
  44. - name: Download Model from HuggingFace
  45. env:
  46. HF_TOKEN: ${{ secrets.HF_TOKEN }}
  47. run: |
  48. python -c "
  49. from huggingface_hub import hf_hub_download
  50. import os
  51. token = os.environ.get('HF_TOKEN') or None
  52. repo = '${{ inputs.hf_repo }}'
  53. print(f'Downloading from {repo}...')
  54. # Download checkpoint
  55. ckpt_path = hf_hub_download(
  56. repo,
  57. '${{ inputs.checkpoint_path }}',
  58. local_dir='./model',
  59. token=token
  60. )
  61. print(f' Checkpoint: {ckpt_path}')
  62. # Download config
  63. config_path = hf_hub_download(
  64. repo,
  65. '${{ inputs.config_path }}',
  66. local_dir='./model',
  67. token=token
  68. )
  69. print(f' Config: {config_path}')
  70. "
  71. - name: Show Model Info
  72. run: |
  73. echo "=== Model Configuration ==="
  74. cat model/${{ inputs.config_path }}
  75. echo ""
  76. echo "=== Checkpoint File Size ==="
  77. ls -lh model/${{ inputs.checkpoint_path }}
  78. - name: Create Output Directory
  79. run: mkdir -p output
  80. - name: Convert to All Quantization Types
  81. run: |
  82. #!/bin/bash
  83. set -e
  84. CHECKPOINT="model/${{ inputs.checkpoint_path }}"
  85. CONFIG="model/${{ inputs.config_path }}"
  86. MODEL_NAME="${{ inputs.model_name }}"
  87. QUANT_TYPES="${{ inputs.quantization_types }}"
  88. # If no types specified, use all supported types
  89. if [ -z "$QUANT_TYPES" ]; then
  90. QUANT_TYPES="${{ env.SUPPORTED_QUANT_TYPES }}"
  91. fi
  92. echo "=== Converting Model: $MODEL_NAME ==="
  93. echo "Checkpoint: $CHECKPOINT"
  94. echo "Config: $CONFIG"
  95. echo "Quantization Types: $QUANT_TYPES"
  96. echo ""
  97. # Convert comma-separated to array
  98. IFS=',' read -ra TYPES <<< "$QUANT_TYPES"
  99. for qtype in "${TYPES[@]}"; do
  100. # Trim whitespace
  101. qtype=$(echo "$qtype" | xargs)
  102. # Generate output filename following GGUF naming convention
  103. # Format: {model_name}-{quantization}.gguf
  104. OUTPUT_FILE="output/${MODEL_NAME}-${qtype^^}.gguf"
  105. echo ">>> Converting to $qtype -> $OUTPUT_FILE"
  106. python scripts/convert_to_gguf.py \
  107. --ckpt "$CHECKPOINT" \
  108. --config "$CONFIG" \
  109. --out "$OUTPUT_FILE" \
  110. --dtype "$qtype"
  111. # Show file size
  112. SIZE=$(ls -lh "$OUTPUT_FILE" | awk '{print $5}')
  113. echo " Output size: $SIZE"
  114. echo ""
  115. done
  116. echo "=== Conversion Complete ==="
  117. ls -lh output/
  118. - name: Generate Summary Report
  119. run: |
  120. python -c "
  121. import os
  122. import json
  123. output_dir = 'output'
  124. model_name = '${{ inputs.model_name }}'
  125. report = {
  126. 'model_name': model_name,
  127. 'hf_repo': '${{ inputs.hf_repo }}',
  128. 'checkpoint': '${{ inputs.checkpoint_path }}',
  129. 'config': '${{ inputs.config_path }}',
  130. 'files': []
  131. }
  132. total_size = 0
  133. for f in sorted(os.listdir(output_dir)):
  134. if f.endswith('.gguf'):
  135. path = os.path.join(output_dir, f)
  136. size_bytes = os.path.getsize(path)
  137. total_size += size_bytes
  138. # Extract quant type from filename
  139. quant_type = f.replace(f'{model_name}-', '').replace('.gguf', '')
  140. report['files'].append({
  141. 'filename': f,
  142. 'quant_type': quant_type,
  143. 'size_bytes': size_bytes,
  144. 'size_mb': round(size_bytes / 1024 / 1024, 2)
  145. })
  146. report['total_size_bytes'] = total_size
  147. report['total_size_mb'] = round(total_size / 1024 / 1024, 2)
  148. # Write JSON report
  149. with open('output/conversion_report.json', 'w') as f:
  150. json.dump(report, f, indent=2)
  151. # Print markdown table for GitHub Actions summary
  152. print('## Conversion Report')
  153. print('')
  154. print(f'**Model**: {model_name}')
  155. print(f'**Source**: [{report[\"hf_repo\"]}](https://huggingface.co/{report[\"hf_repo\"]})')
  156. print('')
  157. print('| Quantization | Filename | Size |')
  158. print('|--------------|----------|------|')
  159. for f in report['files']:
  160. print(f'| {f[\"quant_type\"]} | {f[\"filename\"]} | {f[\"size_mb\"]} MB |')
  161. print('')
  162. print(f'**Total Size**: {report[\"total_size_mb\"]} MB')
  163. " | tee -a $GITHUB_STEP_SUMMARY
  164. - name: Upload Converted Models
  165. uses: actions/upload-artifact@v4
  166. with:
  167. name: gguf-models-${{ inputs.model_name }}
  168. path: |
  169. output/*.gguf
  170. output/conversion_report.json
  171. retention-days: 30
  172. compression-level: 0 # GGUF is already compressed for quantized types