在 Apple Silicon Mac 上执行 mlx_lm.convert --hf-path meta-llama/Llama-3.1-8B-Instruct --mlx-path ./mlx-llama31-8b -q,通常会以三种方式失败:报 ValueError: Model type X not supported(往往同时出现 No module named 'mlx_lm.models.X');下载时报 GatedRepoError: 401 Client Error;或者进程跑到接近结束时卡住,被 macOS 以内存不足(OOM)杀掉。
mlx-lm(Apple MLX 框架之上的大模型推理层)为每个支持的架构都内置了一个明确的 Python 类。所以一旦模型比你装的版本新、仓库是 gated 而你没登录、或者未量化权重在量化前装不进统一内存,转换就会失败。
最快修复(覆盖大多数情况):先 pip install --upgrade mlx-lm mlx 升级;gated 仓库(Llama、Gemma、部分 Mistral)用 hf auth login 登录;然后重跑。如果架构太新、PyPI 正式版仍不支持,就从 GitHub 安装 mlx-lm。如果 Mac 内存不够,干脆别本地转换,直接从 mlx-community 拉一个已转好的模型。截至 2026 年 6 月,mlx-lm 当前版本是 0.31.3(2026 年 4 月 22 日发布)。
先判断你属于哪一类
| 屏幕上的报错 | 最可能的原因 | 跳到 |
|---|---|---|
ValueError: Model type X not supported / No module named 'mlx_lm.models.X' | 你装的 mlx-lm 没有该架构 | Step 1 |
GatedRepoError、401 Client Error、You are trying to access a gated repo | 未登录 / 访问权限未批准 | Step 2 |
跑到接近 100% 卡住,然后 Killed: 9 或转圈 + OOM | 未量化权重超出统一内存 | Step 3 |
No such file / 缺少分片 model-0000N-of-...safetensors | 下载中断,缓存不完整 | Step 4 |
Error while deserializing / 目录里只有 pytorch_model.bin | 仓库只提供 PyTorch pickle,没有 safetensors | Step 5 |
ImportError: cannot import name ... from 'mlx.core' | mlx 与 mlx-lm 版本不匹配 | Step 6 |
常见原因
按命中率从高到低排列。
1. mlx-lm 没有这个架构的实现类
mlx-lm 在 mlx_lm/models/ 下为每个架构放一个模块,并按仓库 config.json 里的 model_type 字段去匹配。找不到对应模块时,加载器就报 ValueError: Model type X not supported,常常还带 No module named 'mlx_lm.models.X'。这是最常见的失败,而且总是先砸到新模型头上:2025-2026 年间,qwen3_moe、minimax、gemma4_unified、minicpmv 等架构在被支持之前都报过这个错。
怎么判断:查模型的 model_type,再和你的安装对比:
python3 -c "
import os, mlx_lm.models as m
d = os.path.dirname(m.__file__)
print(sorted(f[:-3] for f in os.listdir(d) if f.endswith('.py') and not f.startswith('_')))
"
如果 model_type 不在这个列表里,你装的 mlx-lm 就转不了它。先升级(Step 1);如果该架构只在 main 分支落地,就从 GitHub 安装。
2. gated 仓库未认证
Llama 3.x、Gemma 以及部分 Mistral 仓库是 gated 的:你必须先在模型页接受许可协议,并且处于登录状态。没有有效 token 时,mlx_lm.convert 会在下载阶段失败,报 GatedRepoError、401 Client Error,或 Cannot access gated repo ... You are trying to access a gated repo. Make sure to request access。
怎么判断:执行 hf auth whoami。如果输出 Not logged in,问题就在这。注意 CLI 已在 2025 年中从 huggingface-cli 改名为 hf;老的 huggingface-cli login/whoami 仍可用,但会打印一条弃用提示,引导你改用 hf auth ...。
3. OOM —— 全精度权重在量化前装不下
mlx_lm.convert 会先按权重的存储精度加载(即 config.json 里的 torch_dtype,现代 Llama/Qwen/Mistral/Gemma 一般是 bfloat16),再做量化。所以峰值内存由 bf16 体积决定,而不是 fp32。粗算:bf16 体积(GB)约等于参数量(十亿)乘以 2(每个权重 2 字节)。一个 70B 模型 bf16 约 140 GB,转换时还要在此之上留余量,因此在 128 GB 的 Mac 上会 OOM,只有 192 GB 及以上的 Studio/Ultra 才装得下。macOS 会杀掉进程(Killed: 9)或卡进转圈。
怎么判断:转换前在 Activity Monitor(内存标签页,看 Memory Pressure/内存压力)或 vm_stat 查看可用内存;运行卡住时,vm_stat 1 显示 Pageouts 大量且持续增长,就说明内存耗尽了。
4. 分片模型没下完整
大仓库会把权重拆成 model-00001-of-0000N.safetensors 多个分片。下载中断会导致部分分片缺失;转换器加载完前几个分片后,会在缺失文件上失败。
怎么判断:把磁盘上的分片和清单对比。仓库的 model.safetensors.index.json 列出了所有应有的分片:
ls ~/.cache/huggingface/hub/models--*/snapshots/*/model-*.safetensors | wc -l
如果这个数小于 index.json 里引用的分片数,就重新下载(Step 4)。
5. 仓库只有 PyTorch pickle,没有 safetensors
一些较老或自定义的仓库只含 pytorch_model.bin(Python pickle),没有 model.safetensors。mlx_lm.convert 期望的是 safetensors;只有 .bin 时可能加载失败,或在意外的权重键名上失败。(注意:mlx_lm.convert 完全不接受 GGUF 作为输入,详见 FAQ。)
怎么判断:ls ~/.cache/huggingface/hub/models--*/snapshots/*/ —— 如果看到 pytorch_model*.bin 而没有 *.safetensors,先把权重转成 safetensors(Step 5)。
6. mlx 与 mlx-lm 版本不匹配
mlx-lm 会锁定一个兼容的核心 mlx 版本范围。只升级其中一个,可能导致导入失败或结果错误。
怎么判断:ImportError: cannot import name 'X' from 'mlx.core' 就是信号。执行 pip show mlx mlx-lm,并把两者一起升级(Step 1)。
最短修复路径
Step 1:把 mlx-lm 和 mlx 一起升级
# 两个一起升,保持版本兼容
pip install --upgrade mlx-lm mlx
# 确认安装版本(截至 2026 年 6 月为 0.31.3)
python3 -c "import mlx_lm; print(mlx_lm.__version__)"
# 确认你的架构现在有对应模块
python3 -c "
import os, mlx_lm.models as m
d = os.path.dirname(m.__file__)
print(sorted(f[:-3] for f in os.listdir(d) if f.endswith('.py') and not f.startswith('_')))
"
如果该架构只在 main 分支落地、PyPI 正式版还没收录,就装开发版:
pip install --upgrade "mlx-lm @ git+https://github.com/ml-explore/mlx-lm.git"
Step 2:为 gated 仓库做 HuggingFace 认证
# 新版 CLI(huggingface-cli 仍可用但已弃用)
hf auth login
# 粘贴 https://huggingface.co/settings/tokens 上的 token(read 权限即可)
# 验证已登录
hf auth whoami
# gated 模型还必须在模型页接受许可,例如
# https://huggingface.co/meta-llama/Llama-3.1-8B-Instruct -> 点 "Agree and access"
如果 hf auth whoami 成功但仍报 401,说明这个具体仓库的访问申请尚未批准 —— 审批可能要几分钟到几天。确认模型页上出现绿色的 “You have been granted access” 横幅。
Step 3:带量化转换,并选一个能装下的 dtype
-q(即 --quantize)默认产出 4-bit 模型(group size 64,affine 量化),这是内存占用最小的输出。但转换仍会先加载源权重,所以 bf16 体积是你的下限。
# 8B 模型:一步转换并量化到 4-bit
mlx_lm.convert \
--hf-path meta-llama/Llama-3.1-8B-Instruct \
--mlx-path ./mlx-llama31-8b-4bit \
-q --q-bits 4 --q-group-size 64
# 如果要不量化的输出,但用更小的 dtype 省空间:
mlx_lm.convert \
--hf-path meta-llama/Llama-3.1-8B-Instruct \
--mlx-path ./mlx-llama31-8b-bf16 \
--dtype bfloat16
如果某模型 bf16 能转、但一加 -q 就失败,说明问题在量化步骤而非架构支持 —— 试试 --q-group-size 32,或者干脆不量化、跑 bf16。
如果 bf16 权重根本装不进你的统一内存,就别在本地转了。从 mlx-community 下载已转好的 MLX 模型(Step 6),或者换台内存更大的机器做量化。
Step 4:转换前先下完所有分片
# 提前把每个分片都拉下来,这样即便中断也不会留下半截缓存
python3 << 'EOF'
from huggingface_hub import snapshot_download
snapshot_download(
"meta-llama/Llama-3.1-8B-Instruct",
local_dir="./llama31-8b-hf",
ignore_patterns=["*.msgpack", "*.h5", "*.bin"], # 只要 safetensors
)
print("Download complete")
EOF
# 然后从本地目录转换
mlx_lm.convert \
--hf-path ./llama31-8b-hf \
--mlx-path ./mlx-llama31-8b-4bit \
-q --q-bits 4
Step 5:先把 PyTorch .bin 权重转成 safetensors
pip install safetensors torch
python3 << 'EOF'
from safetensors.torch import save_file
import torch, os
model_path = "./model-path"
for f in os.listdir(model_path):
if f.endswith(".bin"):
sd = torch.load(f"{model_path}/{f}", map_location="cpu")
out = f.replace(".bin", ".safetensors")
save_file(sd, f"{model_path}/{out}")
print(f"Converted {f} -> {out}")
EOF
转好后,把 --hf-path 指向包含新 .safetensors 文件的本地目录。
Step 6:跳过转换 —— 直接拉已转好的 MLX 模型
如果转换一直跟你较劲(架构不支持、OOM、gated 访问),HuggingFace 上的 mlx-community 组织已经发布了数千个预转换的 MLX 模型。mlx_lm.generate 和 mlx_lm.load 会在首次使用时自动下载:
# 4-bit(占用最小)
mlx_lm.generate \
--model mlx-community/Llama-3.1-8B-Instruct-4bit \
--prompt "你好" --max-tokens 200
# 8-bit(质量更高,体积更大)
mlx_lm.generate \
--model mlx-community/Llama-3.1-8B-Instruct-8bit \
--prompt "你好" --max-tokens 200
如何确认已修复
对转换后的目录跑一次快速生成,再检查权重是否真的被量化了:
# 1. 应当产出连贯文本,而非乱码或报错
mlx_lm.generate --model ./mlx-llama31-8b-4bit --prompt "说出三种原色。" --max-tokens 30
# 2. 确认量化确实生效(4-bit 模型会带 quantization 配置)
python3 -c "
import json, glob
cfg = json.load(open(glob.glob('./mlx-llama31-8b-4bit/config.json')[0]))
print('quantization:', cfg.get('quantization'))
"
如果 quantization 是 None,说明 -q 没生效、模型是全尺寸的 —— 带 -q 重跑 Step 3。
预防建议
- 在
requirements.txt里把mlx-lm和mlx一起固定,并同时升级;单独升mlx是ImportError的常见来源。 - 转换全新模型前,先在
mlx-lm的 GitHub issues 里搜它的model_type—— 不支持的架构通常都有 issue 跟踪,并注明在哪个版本加入支持。 - 长时间转换前先跑一遍
hf auth whoami,免得 token 过期、白下载半小时。 - 提前估算内存:bf16 体积(GB)约等于参数量(十亿)乘以 2。若超过你的空闲统一内存,就别本地转,直接从
mlx-community拉预转换模型。 - 用
snapshot_download在转换前下完所有分片,避免中断留下半截缓存。 - 转换后先跑一次短生成测试,并确认
config.json里量化字段符合预期,再删除 HuggingFace 源权重。
常见问答 (FAQ)
Q: 能用 mlx_lm.convert 把 GGUF 转成 MLX 吗?
A: 不能 —— 它只接受 HuggingFace safetensors(或 PyTorch .bin)作为输入,不接受 GGUF。你得先用 llama.cpp 的转换脚本把 GGUF 还原成 HuggingFace 仓库,再跑 mlx_lm.convert,这意味着二次量化和质量损失。几乎总是更划算的做法是:下载原始 safetensors 仓库,或者直接从 mlx-community 拉预转换模型。
Q: 升级后仍报 ValueError: Model type X not supported,怎么办?
A: PyPI 正式版可能落后 main 好几周。用 pip install --upgrade "mlx-lm @ git+https://github.com/ml-explore/mlx-lm.git" 装开发版。如果 main 也不支持,说明该架构还没被移植 —— 去 GitHub issues 看进度,期间先用 llama.cpp/Ollama 跑 GGUF 版本。
Q: 在 Apple Silicon 上,MLX 4-bit 比 bf16 慢多少? A: 4-bit 模型每 token 的吞吐通常低于 bf16,因为有反量化开销;但 4-bit 往往是唯一装得下的选项。一个 13B 模型 bf16 约 26 GB、4-bit 约 7-8 GB,所以在 16 GB 的 Mac 上只有 4-bit 能加载。
Q: 转换后的模型能跑但很慢,为什么?
A: 先确认它真的被量化了。按「如何确认已修复」里的 config.json 检查跑一遍。如果 quantization 是 None,说明漏了 -q、你在跑全精度权重;带 -q --q-bits 4 重转。也要确认没有其他 App 把你顶进内存压力、强制换页。
Q: 是不是每个模型都得登录?
A: 不用。hf auth login 只需存一次 token。只有 gated 仓库(Llama、Gemma、部分 Mistral)才需要逐个申请访问。像大多数 mlx-community 和 Qwen 这类开放仓库完全不用登录。
相关阅读
- llama.cpp 换更激进量化后质量明显下降
- LM Studio 加载模型时显存 OOM
- vLLM 启动时报 CUDA 版本不匹配
- 本地模型冷启动后首 token 极慢
- Chat template 不匹配导致输出全是乱码
标签: #local-llm #mlx #排查