mlx-vlm 模型转换与量化完全指南:使用 mlx_vlm.convert 将 Hugging Face 权重转为 MLX 格式(RTN/AWQ/混合位宽)
【免费下载链接】mlx-vlmMLX-VLM is a package for inference and fine-tuning of Vision Language Models (VLMs) on your Mac using MLX.项目地址: https://gitcode.com/GitHub_Trending/ml/mlx-vlm
导读
本文是 mlx-vlm 仓库中convert-quantize技能文档的完整展开。它系统讲解mlx_vlm.convert这一核心命令行入口:如何把一个 Hugging Face(下称 HF)检查点转换为可在 Mac 上运行的 MLX 格式,以及如何用 RTN、AWQ、mxfp4/nvfp4/mxfp8 等量化模式压缩权重。读完本文,你将掌握从纯转换、4-bit 仿射量化、混合位宽 recipe、dtype 转换、反量化到上传 Hub 的完整实战流程,并能结合源码理解每一步背后的实现原理,最后用验证步骤确保转换结果可直接用于推理。
1. 认识 mlx_vlm.convert
mlx_vlm.convert是 mlx-vlm 用于把 HF 检查点转换为 MLX 格式(可选量化)的统一入口,其核心实现位于 mlx_vlm/convert.py,流程如下(见 convert() 及其函数体):
- 通过
get_model_path解析--hf-path(Hub repo id 或本地目录); - 用
fetch_from_hub惰性加载模型、配置与 processor; - 按需执行 dtype 转换(
--dtype)、量化(-q,RTN 或 AWQ)、反量化(-d); - 写权重、复制配套
*.py/*.json与子目录、保存 processor 与重新生成的config.json,并生成模型卡(model card); - 可选上传 Hub(
--upload-repo)。
入口调用方式
技能文档特别强调入口规范(见 SKILL.md 的 First Checks):
- 推荐方式:
uv run mlx_vlm.convert ...(在 pyproject/uv 管理环境中); - 等价方式:
python -m mlx_vlm convert ...; python -m mlx_vlm.convert ...已被弃用。在 convert.py 的__main__中会直接打印弃用提示,并仍代为执行main()。
在敲定任何参数前,建议先查看帮助:uv run mlx_vlm.convert --help,以确认当前版本实际支持的 flags。
2. 开始前检查(First Checks)
技能文档要求转换前完成以下四项确认:
- 确认来源:
--hf-path(别名--model)接受一个 HF repo id(如Qwen/Qwen2.5-VL-7B-Instruct)或一个本地目录路径。 - 确认模型家族受支持:在 mlx_vlm/models/ 下应存在一个以该模型
config.json中model_type命名的文件夹。若不存在,说明这是一个模型移植(porting)任务,应转向add-new-model技能,而非强行转换。 - 核实参数:
uv run mlx_vlm.convert --help。 - 使用正确入口:
mlx_vlm.convert(或python -m mlx_vlm convert),不要使用已弃用的python -m mlx_vlm.convert。
从 configure_parser() 可见,除--hf-path/--mlx-path外,还有--revision(Hub 分支,默认None)、--trust-remote-code(信任远程代码,CLI 默认False)等参数,可按需组合。
3. 命令模式速览
技能文档给出的核心命令模式如下(均可在本仓库环境直接套用):
# 纯转换(不量化),默认保存到 ./mlx_model uv run mlx_vlm.convert --hf-path <repo-or-path> --mlx-path ./out-mlx # 4-bit 仿射量化(RTN,默认方法) uv run mlx_vlm.convert --hf-path <repo-or-path> --mlx-path ./out-4bit -q --q-bits 4 --q-group-size 64 # 其他量化模式(--q-mode 自带 bit/group 默认值) # mxfp4 (group 32, 4 bit)、nvfp4 (group 16, 4 bit)、mxfp8 (group 32, 8 bit) uv run mlx_vlm.convert --hf-path <repo-or-path> --mlx-path ./out-mxfp4 -q --q-mode mxfp4 # 混合位宽 recipe(逐层位宽分配,llama.cpp 风格) # recipes: mixed_2_6 mixed_3_4 mixed_3_5 mixed_3_6 mixed_3_8 mixed_4_6 mixed_4_8 uv run mlx_vlm.convert --hf-path <repo-or-path> --mlx-path ./out-mixed -q --quant-predicate mixed_3_6 # AWQ(激活感知,需要校准流程) uv run mlx_vlm.convert --hf-path <repo-or-path> --mlx-path ./out-awq -q --quant-method awq \ --calibration multimodal --calibration-data /path/to/media # 或 --calibration text(默认) # 仅 dtype 转换 / 反量化 uv run mlx_vlm.convert --hf-path <repo-or-path> --mlx-path ./out-bf16 --dtype bfloat16 uv run mlx_vlm.convert --hf-path <quantized-repo> --mlx-path ./out-fp -d # 反量化 # 转换并上传结果到 Hub uv run mlx_vlm.convert --hf-path <repo> --mlx-path ./out -q --upload-repo <user>/<name>-mlx4. 量化模式:affine / mxfp4 / nvfp4 / mxfp8
--q-mode决定量化格式,每种模式带有自己的 group size 与 bit 默认值。该默认表定义在 quant_utils.py 的QUANTIZATION_MODE_DEFAULTS:
--q-mode | 默认 group size | 默认 bits | 说明 |
|---|---|---|---|
affine(默认) | 64 | 4 | 经典仿射(scale + bias)量化,兼容性最好 |
mxfp4 | 32 | 4 | 4-bit 微缩放浮点格式 |
nvfp4 | 16 | 4 | NVIDIA FP4 风格格式 |
mxfp8 | 32 | 8 | 8-bit 微缩放浮点格式 |
关键约束(见 get_quantization_params()):非 affine 模式不允许用--q-bits/--q-group-size覆盖默认值,否则会抛出ValueError。只有affine模式支持自由调整 bits 与 group size。
对于mxfp8/nvfp4量化的模型,README 提示在 NVIDIA GPU(MLX CUDA)上需要激活量化(--quantize-activations)才能正常工作,而在 Apple Silicon(Metal)上无需该 flag(见 README.md 的 Activation Quantization 章节)。
从 quantize_model() 的实现可以看到,量化时会计算并打印模型的实际 bits-per-weight([INFO] Quantized model with {bpw:.3f} bits per weight.),量化配置会被写入config.json的quantization字段(同时镜像到quantization_config以兼容 HF 模型树,见 convert.py)。
5. RTN 与 AWQ:两种量化方法
--quant-method有两个取值(见 configure_parser()):
rtn(默认):round-to-nearest,直接就近取整,无需校准数据,开箱即用;awq:activation-aware weight quantization,先跑一次激活统计校准,再按激活分布施加缩放,通常在同位宽下质量更优,但需要额外校准步骤。
AWQ 校准流程
当指定--quant-method awq时,convert() 会调用_apply_awq_calibration:
--calibration text(默认):使用内置的DEFAULT_CALIBRATION_TEXT(16 句英文句子,定义在 quant/calibration.py)对语言模型主干跑若干次前向,通过 hook 采集每个nn.Linear输入激活的逐通道均值与原始输入行(见 collect_activation_stats()),随后由 quant/awq.py 的apply_awq计算并施加缩放;--calibration multimodal:当模型含视觉/音频塔时,会走_build_multimodal_awq_run(convert.py),把「图片/音频 + 文本」组合成提示,经apply_chat_template与prepare_inputs后路由整个多模态模型做前向,使校准覆盖视觉/音频路径。若未提供--calibration-data,则使用内置合成媒体(8 张合成图片与 8 段合成波形,见 synthetic_calibration_images() 与 synthetic_calibration_audio()),并打印[INFO] AWQ: using synthetic calibration media; pass --calibration-data for real image/audio samples.;--calibration-data:可选的媒体目录,按扩展名识别图片(png/jpg/jpeg/webp/bmp)与音频(wav/mp3/flac/m4a/ogg/opus),加载逻辑见 load_calibration_media();- 若模型既无视觉也无音频塔,
multimodal校准会自动回退为文本校准。
AWQ 的量化 bit 默认取q_bits or 4、group size 默认取q_group_size or 64(见 convert.py)。
6. 混合位宽 recipe(--quant-predicate)
--quant-predicate提供 7 种 llama.cpp 风格的逐层位宽分配 recipe(定义在 convert.py 的QUANT_RECIPES):
mixed_2_6 mixed_3_4 mixed_3_5 mixed_3_6 mixed_3_8 mixed_4_6 mixed_4_8命名规则为mixed_<低bits>_<高bits>,例如mixed_3_6表示大部分层用 3 bit、敏感层用 6 bit。
其实现位于 mixed_quant_predicate_builder(),要点包括:
- 底层 group size 固定为 64;
- 通过模型
down_proj路径定位层索引位置,按层数分配位宽:首尾各 1/8 层以及中间每隔 3 层的层((index - num_layers // 8) % 3 == 2)被判定为「敏感层」; - 敏感层中的
v_proj/down_proj、以及lm_head/embed_tokens使用高 bits,其余线性层使用低 bits; - 多模态模块(见下节)一律跳过;
- 权重维度不能整除 64 的模块跳过。
predicate 返回{"group_size": 64, "bits": high/low}字典,由 quantize_model() 逐路径写入quantization配置,实现 per-layer 位宽记录。
7. 关键事实(Key Facts)
结合技能文档与源码,以下事实需要牢记:
- 多模态模块默认跳过量化:
skip_multimodal_module(utils.py)会识别vision_model、vision_tower、vl_connector、sam_model、audio_model、audio_tower、code_predictor、img_projector、multi_modal_projector、patch_merge_mlp等路径并跳过——视觉/音频塔保持全精度,只量化语言模型。这是预期行为,不是 bug。 --q-mode四个取值及其默认参数见第 4 节表格;--q-bits/--q-group-size仅对affine模式可覆盖默认值。--quant-method为rtn(默认)或awq(需校准;--calibration text|multimodal,可选--calibration-data)。-q/--quantize与-d/--dequantize互斥:同时指定会抛出ValueError: Choose either quantize or dequantize, not both.(见 convert.py)。--dtype:默认取config.json的torch_dtype(无则取text_config.dtype),仅在float16/bfloat16/float32三个取值内有效(utils.py 的MODEL_CONVERSION_DTYPES)。它只对浮点权重做astype转换,适合把 fp32 模型压到 bf16 而完全不量化。转换时会遵循模型自定义的cast_predicate(若存在)来决定哪些层参与 dtype 转换。- 转换输出目录内容:权重文件、复制的
*.py/*.json(跳过model.safetensors.index.json,因为save_weights会重新生成正确的 index)、processor(save_pretrained,对 Mage-VL 等无save_pretrained的 processor 则原样复制处理器文件)、重新生成的config.json,以及模型卡README.md——转换完成后即可直接交给mlx_vlm.generate与 server 使用。
反量化(-d)
-d/--dequantize调用 dequantize_model(),把QuantizedLinear、QuantizedEmbedding、QuantizedSwitchLinear、QuantizedMultiLinear还原为对应的浮点层(通过mx.dequantize重建权重),适用于把量化检查点恢复为全精度,或作为二次转换的中间步骤。
8. 额外参数:revision、trust-remote-code 与 MTP
除技能文档强调的参数外,mlx_vlm.convert还支持(见 configure_parser()):
--revision <branch>:从 Hub 转换时指定 HF 分支/版本;--trust-remote-code:信任远程自定义代码(部分模型的 modeling 文件需要);--mtp与--mtp-output:为带原生 MTP(multi-token prediction)张量的模型提取独立 drafter,默认输出到<mlx-path>-mtp。通过detect_mtp_splitter探测,若无原生 MTP 张量则打印提示并跳过;drafter 提取失败不会影响已成功的基础转换(见 convert.py)。
9. 上传到 Hugging Face Hub
使用--upload-repo <user>/<name>-mlx即可在转换后自动上传。上传前会先通过 create_model_card() 生成/补全模型卡:写入library_name: mlx、pipeline_tag: image-text-to-text、tags: ["mlx"]与base_model(原始 HF repo id),然后由 upload_to_hub() 在模型卡中追加 provenance 说明(注明由 mlx-vlm 的哪个版本从哪个仓库转换而来)与mlx_vlm.generate使用示例,再通过HfApi上传。注意:上传需要本机已配置 Hugging Face 凭据(如huggingface-cli login)。
10. 转换后的验证(Validation)
转换完成不等于万事大吉,技能文档给出三级验证建议:
- 功能验证:加载转换结果跑一次极小规模生成,证明检查点可用(参考
cli-inference技能,也可参见 docs/usage.md 的 CLI 与 Python 调用示例,如python -m mlx_vlm.generate --model <mlx-path> --max-tokens 100 --temperature 0.0 --image <image> --prompt "Describe this image.")。运行需在 Apple Silicon 且内存足够的机器上进行——不要试图在 8 GB 内存的机器上跑大模型。 - 质量对比:用贪婪解码(
--temperature 0.0)分别跑原始模型与量化模型,对比若干条输出;若量化后质量大幅下降,通常是位宽过低或为该模型选择了错误的--q-mode(如非 affine 模式、或对敏感模型使用了过低的 bits)。 - 回归测试:若改动了与转换相关的代码,运行
uv run --with pytest python -m pytest mlx_vlm/tests/test_utils.py -q以及对应模型族的相关测试(转换/量化工具测试集中在 mlx_vlm/tests/ 下)。
若验证过程中发现疑似 bug,可参考reproducible-github-issues技能整理可复现的问题报告。
11. 常见问题速查
- 转换后目录里没有量化视觉塔?正常。多模态模块默认跳过量化,见第 7 节。
--q-mode mxfp4配--q-bits 3报错?非 affine 模式不允许覆盖默认 bit/group,见第 4 节。- 同时加了
-q和-d?二者互斥,去掉其一。 python -m mlx_vlm.convert打印弃用提示?改用uv run mlx_vlm.convert ...或python -m mlx_vlm convert ...。--calibration multimodal却提示没有多模态?说明该模型没有视觉/音频塔,已自动回退文本校准,可忽略该提示。
结语
mlx_vlm.convert把「HF 检查点 → MLX 可推理格式」收敛为一条命令:先确认模型家族受支持,再按需选择纯转换、affine/微缩放量化、混合位宽或 AWQ,配合--dtype、-d、--upload-repo完成整个生命周期。理解第 4~7 节中的量化模式默认表、多模态跳过规则与互斥约束,即可避免绝大多数转换陷阱;最后用第 10 节的生成与质量对比验证收尾,就能得到可直接交付给mlx_vlm.generate与 server 的高质量 MLX 模型。技能原文见 skills/skills/convert-quantize/SKILL.md,核心实现见 mlx_vlm/convert.py 与 mlx_vlm/quant_utils.py。
【免费下载链接】mlx-vlmMLX-VLM is a package for inference and fine-tuning of Vision Language Models (VLMs) on your Mac using MLX.项目地址: https://gitcode.com/GitHub_Trending/ml/mlx-vlm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考