CipherMorphAI

Quantizing AI Models with convert_to_quant (Windows + NVIDIA)

Jun 28th, 2026
688
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.54 KB | None | 0 0
  1. # Quantizing AI Models with convert_to_quant (Windows + NVIDIA)
  2.  
  3. A practical guide to setting up [silveroxides/convert_to_quant](https://github.com/silveroxides/convert_to_quant) on Windows and quantizing diffusion models to INT8 ConvRot for use in ComfyUI.
  4.  
  5. ---
  6.  
  7. ## What is INT8 ConvRot?
  8.  
  9. INT8 ConvRot is a quantization method that compresses model weights from 16-bit (BF16/FP16) down to 8-bit integers, roughly halving VRAM usage with minimal quality loss. The "ConvRot" part refers to a rotation-based technique that improves quantization accuracy by redistributing outliers before quantizing — giving you better results than naive INT8 at the same file size.
  10.  
  11. ---
  12.  
  13. ## Requirements
  14.  
  15. | Feature | Requirement |
  16. |---|---|
  17. | Minimum (FP8/INT8) | Python 3.10+, PyTorch 2.8+, CUDA 12.8+ |
  18. | Full (NVFP4/MXFP8) | Python 3.12+, PyTorch 2.10+, CUDA 13.0+ |
  19. | INT8 Kernels | Triton (Linux native, Windows via `triton-windows`) |
  20.  
  21. > **Note:** PyTorch must be installed manually with the correct CUDA version. The package intentionally does not install it automatically to avoid environment conflicts.
  22.  
  23. ---
  24.  
  25. ## Installation (Windows)
  26.  
  27. ### 1. Create and activate a virtual environment
  28.  
  29. ```powershell
  30. python -m venv venv
  31. .\venv\Scripts\Activate.ps1
  32. ```
  33.  
  34. ### 2. Install PyTorch with CUDA 13.0
  35.  
  36. CUDA 13.0 is the current recommended version:
  37.  
  38. ```powershell
  39. pip install torch --index-url https://download.pytorch.org/whl/cu130
  40. ```
  41.  
  42. Check which torch version was installed:
  43.  
  44. ```powershell
  45. python -c "import torch; print(torch.__version__)"
  46. ```
  47.  
  48. ### 3. Install Triton for Windows (required for INT8)
  49.  
  50. Match your Triton version to your torch version:
  51.  
  52. ```powershell
  53. # torch 2.10 or 2.11
  54. pip install -U "triton-windows<3.7"
  55.  
  56. # torch 2.12
  57. pip install -U "triton-windows<3.8"
  58. ```
  59.  
  60. ### 4. Install convert_to_quant
  61.  
  62. ```powershell
  63. pip install convert-to-quant
  64. ```
  65.  
  66. Or from source:
  67.  
  68. ```powershell
  69. git clone https://github.com/silveroxides/convert_to_quant.git
  70. cd convert_to_quant
  71. pip install -e .
  72. ```
  73.  
  74. ---
  75.  
  76. ## How INT8 ConvRot Quantization Works
  77.  
  78. The basic command structure for INT8 ConvRot looks like this:
  79.  
  80. ```powershell
  81. ctq -i model_bf16.safetensors -o model_int8_convrot.safetensors \
  82. --int8 --scaling_mode tensor --simple --low-memory \
  83. --convrot --convrot-group-size [GROUP_SIZE] \
  84. --comfy_quant --save-quant-metadata
  85. ```
  86.  
  87. The key flags:
  88.  
  89. - `--int8` — use INT8 quantization instead of the default FP8
  90. - `--scaling_mode tensor` — one global scale per tensor (most compatible)
  91. - `--convrot` — enable the ConvRot rotation technique
  92. - `--convrot-group-size` — group size for ConvRot; must evenly divide all 2D weight dimensions
  93. - `--simple` — skip SVD optimization (faster, still good quality)
  94. - `--low-memory` — stream tensors from disk instead of loading all at once (essential for large models)
  95. - `--comfy_quant --save-quant-metadata` — ComfyUI compatibility
  96.  
  97. ---
  98.  
  99. ## Determining the Right ConvRot Group Size
  100.  
  101. Before running quantization, you need to find the largest power-of-4 that divides all 2D weight tensor dimensions in the model. Run this shape check:
  102.  
  103. ```powershell
  104. python -c "
  105. from safetensors import safe_open
  106. f = safe_open(r'path\to\your_model.safetensors', framework='pt')
  107. shapes = set()
  108. [shapes.add(f.get_slice(k).get_shape()[-1]) for k in f.keys() if len(f.get_slice(k).get_shape()) == 2]
  109. print(sorted(shapes))
  110. "
  111. ```
  112.  
  113. Then find the smallest dimension in that list and pick the largest value from `[4, 16, 64, 256]` that divides it evenly:
  114.  
  115. | Smallest dim | Max group size |
  116. |---|---|
  117. | 12 or 64 | 4 |
  118. | 128+ (divisible by 64) | 64 |
  119. | 256+ (divisible by 256) | 256 |
  120.  
  121. A smaller group size means slightly less accurate quantization, but it's still far better than no ConvRot at all.
  122.  
  123. ---
  124.  
  125. ## Handling Model-Specific Layer Exclusions
  126.  
  127. Some layers should be kept in full precision (BF16/F32) rather than quantized — typically input/output projections, embedding layers, and timestep pathways. Quantizing these can cause quality degradation or instability.
  128.  
  129. `convert_to_quant` includes built-in presets for common architectures (check them with `ctq --help-filters`). For models without a preset, you can identify and exclude the right layers manually.
  130.  
  131. ### Step 1: Dump the layer list
  132.  
  133. ```powershell
  134. python -c "
  135. from safetensors import safe_open
  136. f = safe_open(r'path\to\model.safetensors', framework='pt')
  137. for k in sorted(f.keys()):
  138. print(k, f.get_slice(k).get_shape())
  139. " | Out-File -FilePath layers.txt
  140.  
  141. # Filter out repetitive block layers to find top-level structure
  142. Get-Content layers.txt | Where-Object { $_ -notmatch "^blocks\." }
  143. ```
  144.  
  145. ### Step 2: Identify what to protect
  146.  
  147. Look for layers matching these patterns:
  148.  
  149. - **Input projections** — `img_in`, `vid_in`, `txt_in`, `x_embedder`, `first`
  150. - **Output projections** — `proj_out`, `vid_out`, `last`
  151. - **Timestep/conditioning embeddings** — `time_text_embed`, `tmlp`, `tproj`, `emb_in`
  152. - **Fixed conditioning tensors** — `positive_conditioning`, `negative_conditioning`
  153. - **Tiny matrices** — anything with a dimension under 64 (e.g. `[1, 12]`, `[64, 3072]`)
  154.  
  155. ### Step 3: Exclude them with a regex
  156.  
  157. ```powershell
  158. --exclude-layers "^(vid_in|vid_out|txt_in|emb_in|first|last|tmlp|tproj)"
  159. ```
  160.  
  161. ---
  162.  
  163. ## Real Examples
  164.  
  165. ### Krea 2 Turbo (12B DiT, group size 4)
  166.  
  167. Krea 2 has a custom architecture with an `[6144, 64]` input projection that caps the group size at 4. The top-level layers `first`, `last`, `tmlp`, and `tproj` are excluded.
  168.  
  169. ```powershell
  170. ctq -i "krea2_turbo_bf16.safetensors" -o "krea2_turbo_int8_convrot.safetensors" `
  171. --int8 --scaling_mode tensor --simple --low-memory `
  172. --convrot --convrot-group-size 4 `
  173. --exclude-layers "^(first|last|tmlp|tproj|txtfusion\.projector)\." `
  174. --comfy_quant --save-quant-metadata
  175. ```
  176.  
  177. ### SeedVR2 7B (video upscaler, group size 4)
  178.  
  179. SeedVR2's `vid_in.proj.weight` has a `[3072, 132]` shape — the 132 dimension caps the group size at 4. Input/output projections and conditioning tensors are excluded.
  180.  
  181. ```powershell
  182. ctq -i "seedvr2_7b_fp16.safetensors" -o "seedvr2_7b_int8_convrot.safetensors" `
  183. --int8 --scaling_mode tensor --simple --low-memory `
  184. --convrot --convrot-group-size 4 `
  185. --exclude-layers "^(vid_in|vid_out|txt_in|emb_in|negative_conditioning|positive_conditioning)" `
  186. --comfy_quant --save-quant-metadata
  187. ```
  188.  
  189. ---
  190.  
  191. ## Verifying the Output
  192.  
  193. After conversion, inspect which layers stayed in full precision:
  194.  
  195. ```powershell
  196. python -c "
  197. from safetensors import safe_open
  198. f = safe_open(r'path\to\output_model.safetensors', framework='pt')
  199. for k in sorted(f.keys()):
  200. d = f.get_slice(k).get_dtype()
  201. if 'I8' not in str(d).upper() and 'U8' not in str(d).upper():
  202. print(k, f.get_slice(k).get_shape(), d)
  203. "
  204. ```
  205.  
  206. You should see your excluded layers listed as `F32`, and everything else will show as `I8` (the quantized weights) plus `F32` scale tensors and `U8` metadata blobs — that's the expected structure for a ComfyUI-compatible INT8 ConvRot file.
  207.  
  208. ---
  209.  
  210. ## Tips
  211.  
  212. - **Group size 4 is still worth it.** Even with a small group size forced by a bottleneck dimension, ConvRot outperforms plain INT8.
  213. - **Check built-in presets first.** Run `ctq --help-filters` — if your model architecture has a preset (like `--qwen`, `--wan`, `--ltxv2`), use it instead of manual exclusions.
  214. - **`--low-memory` is almost always recommended** for models over a few GB — it keeps peak RAM manageable.
  215. - **The `--simple` flag** skips learned rounding (SVD optimization). For most use cases the quality difference is negligible and it's dramatically faster.
  216.  
Advertisement
Add Comment
Please, Sign In to add comment