没有独显也能试:4.7B 量化模型纯 CPU 推理的可用边界
没有独显也能试:4.7B 量化模型纯 CPU 推理的可用边界
Qwen3.5-4B-3D-Coder 这个项目最容易被忽略的一点,不是它能把 Three.js 场景生成得多漂亮,而是它的体积恰好落在"老笔记本还能喘气"的那条线上:仓库里放着的两档 GGUF,一个是 2.52 GiB,一个是 4.17 GiB。这意味着你不必先买卡,就能把一个真正能干活的代码模型塞进内存里跑起来。
但"能跑"和"能用"之间隔着一条由 token 堆出来的沟。这篇文章不谈玄学体感,只做三件事:把两档量化的体积与内存账算清,把纯 CPU 的时延用带宽公式推一遍,再结合仓库里的提示词、模板和画廊样例,划出哪些题材值得在低精度下先试、什么节点必须换成显卡。
先把参数量与体积对齐:4.7B 到底是什么口径
社区普遍把这次发布的模型称作 4B 级、约 4.7B 的小模型,但仓库里的账本写得很直白。权重索引 里记录的是:
{ "total_parameters": 4539265536, "total_size": 9078531072 }也就是4,539,265,536 个参数、9,078,531,072 字节的 FP16 权重。之所以"4B 的模型"会跑到 4.5B 以上,是因为这个仓库不是纯文本权重:它带有完整的视觉塔(config.json 中vision_config为 24 层、hidden_size1024),还包含 1 层 MTP 结构(mtp_num_hidden_layers: 1)。按层数粗算,视觉部分约占 0.3B 参数,真正的文本主干落在 4.2B 上下——这解释了"标题写 4.7B、索引写 4.54B"的差异,也提醒我们:你下载的 GGUF 里,只有文本部分会被 CPU 真正跑起来。
两档量化的体积画像
| 版本 | 精确字节数 | 换算 | 相对 FP16 的有效位宽 | 定位 |
|---|---|---|---|---|
| FP16 全量(4 个分片) | 9,078,531,072 | 8.45 GiB | 16 bit | 微调与对照实验 |
| Q8_0 | 4,482,402,816 | 4.17 GiB | 约 7.9 bit/参数 | 质量优先,内存宽裕 |
| Q4_K_M | 2,708,804,096 | 2.52 GiB | 约 4.8 bit/参数 | 内存受限、追求速度 |
Q4_K_M 相对 FP16 压掉了约 70% 的体积,Q8_0 压掉约 50%。注意 Q8_0 的有效位宽接近 8 bit 而非 8.5 bit,是因为这个模型tie_word_embeddings: true,输入嵌入与输出头共享同一份矩阵,压缩时省下了一份 248320×2560 的大表。
内存不止权重
真正的门槛是"权重 + 上下文 + 运行时开销"的加总。这个模型的注意力结构对 CPU 相当友好:config.json 的layer_types是一个线性注意力 ×3 + 全注意力 ×1的循环,32 层里只有8 层是全注意力。
- 每 token 的 KV Cache = 8 层 × K/V 两份 × 4 个 KV 头 × 256 维 × 2 字节 =32 KiB
- 8K 上下文约 256 MiB,16K 约 512 MiB,32K 约 1 GiB
- 另外 24 层线性注意力维持的是与序列长度无关的递归状态,
mamba_ssm_dtype为float32,单序列量级约几百 KiB,可忽略
所以一张实用的内存清单是:Q4_K_M 起步 4~6 GB(8 GB 机器能开 8K 上下文,但要给系统和编辑器留出余量);Q8_0 建议 8 GB 以上,16 GB 才会舒服;FP16 在 CPU 上需要 10 GB 以上的常驻权重,纯属能加载但没有收益的选项。
纯 CPU 的时延账:解码是带宽题,预填充才是算力题
自回归解码每吐一个 token,都要把几乎全部权重从内存搬到计算单元一次。因此 CPU 上的生成速度有一个相当硬的乐观上限:
tokens/s ≈ 实际可达内存带宽 ÷ 权重字节数以一台双通道 DDR4-3200 的机器为例:理论带宽 51.2 GB/s,实测内存拷贝通常在 25~30 GB/s,而自回归推理的有效带宽往往只用到其中的四到六成,即 12~18 GB/s。
| 版本 | 单 token 权重读取量 | 乐观上限 | 需要做好的心理准备 |
|---|---|---|---|
| Q4_K_M | 2.71 GB | 4.4~6.6 tok/s | 实测多在 2~5 tok/s |
| Q8_0 | 4.48 GB | 2.7~4.0 tok/s | 实测多在 1.5~3 tok/s |
单通道内存直接对半砍。这也是为什么在纯 CPU 场景下,Q4_K_M 不是"将就",而是唯一合理的选择——它换来的不只是省 1.6 GiB 内存,而是接近翻倍的解码速度。
真正吃时间的是输出长度,不是提示词
预填充(prefill)是把提示词一次性算进模型,属于算力密集型,几百个 token 的提示词在 CPU 上通常只需数秒到数十秒;解码才是那个把分钟变成小时的环节。
更要紧的是,这个模型默认开启思考链。chat_template.jinja 在add_generation_prompt分支里写得很明确:
{%- if enable_thinking is defined and enable_thinking is false %} {{- '<think>\n\n</think>\n\n' }} {%- else %} {{- '<think>\n' }} {%- endif %}也就是说,除非显式传enable_thinking=false,模型会先吐一段思考再吐代码,而训练数据里连"完整思考轨迹"都作为字段保留(README.md 对数据集的描述:提示词、完整思考轨迹、完整 HTML/JS 响应、复杂度分级)。对一个要生成上千行自包含 HTML 的模型来说,这等于在本来就长的输出上再叠一层。
据此估算一次"像样的 3D 场景"生成:
| 场景规模 | 输出 token 量级 | Q4_K_M @3 tok/s | Q4_K_M @5 tok/s |
|---|---|---|---|
| 单主体小场景 | 3K~5K | 17~28 分钟 | 10~17 分钟 |
| 中等复杂度(含交互) | 8K~12K | 45~67 分钟 | 27~40 分钟 |
| 多结构组合场景 | 15K+ | 一个半小时以上 | 50 分钟以上 |
所以纯 CPU 的第一条纪律不是调参,而是控制输出规模:把"我要一个赛博朋克城市"改成"我要一个体素发射台,只用一个主体结构"。
纯 CPU 的实际落地配置
在小内存机器上,最省事的路径是 llama.cpp 系的开源运行时(LM Studio 的内核同源)。命令行示例如下,重点在-ngl 0明确走纯 CPU、-t用满物理核、-c保守设上下文:
llama-cli \ -m Qwen3.5-4B-3D-Coder-Q4_K_M.gguf \ -ngl 0 \ -t 8 \ -c 8192 \ -n 6144 \ --temp 0.7 --top-p 0.95 --top-k 20 --repeat-penalty 1.0 \ -f prompt.txt参数不是随手填的,generation_config.json 给出的默认值就是temperature 0.6 / top_k 20 / top_p 0.95 / repetition_penalty 1.0,README.md 针对两档量化统一给出的则是Temperature 0.6–0.8、Top P 0.90–0.95、Top K 20–40、Repeat penalty 1.0。Q4_K_M 与 Q8_0 共用同一套参数,不需要分别调。
两处必须注意的工程细节:
- 在 LM Studio 里关掉 MTP。README 用加粗警告标出了这一点,社区里也把它列为"跑不起来"的头号原因:LM Studio 默认开启多 token 预测,而该模型的 MTP 层与这套推测解码并不兼容,表现是乱码、截断或直接无响应。这与量化格式无关,Q4_K_M 和 Q8_0 一样中招。
- 尽量复用提示词前缀。CPU 上最贵的是重复预填充,把系统提示词与用户需求固定写成文件,配合 prompt cache 反复重试时能省掉一大段 prefill。
若用 Transformers 走 FP16 路线(8.45 GiB 权重,纯 CPU 无加速收益),关闭思考链的方式是给模板传参:
prompt = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True, enable_thinking=False, # 注入空的 <think></think>,跳过推理段 )哪些题材适合低精度先试
仓库的画廊其实是一份很好的"难度分级表"。按社区对这 10 个场景的归类,大致可分成自然园林、幻想科幻、家具手作、机械硬件四类,而它们的生成难度并不相同。判断标准只有一个:几何是否可以被少数几个明确的结构描述完全约束。
适合 Q4_K_M 先试的类型:
- 体素类。立方块本身就是离散的,模型不需要为连续曲面做数值妥协,体素发射台 这类题材在低精度下最容易一次成型。
- 单件家具与器物。桌面、抽屉、支腿、木纹,结构词汇有限,弯身前秘书桌 这类样例的部件关系可以被一句话说清。
- 机械硬件。强调尺寸关系与对称性,LGA 3647 插槽 这种"有标准答案"的对象,反而不容易跑偏。
- 小型园林。Kōrin Garden 这类以光线、水面、植被层次取胜的场景,即使个别细节走形,观感损失也有限。
需要谨慎的类型是"多结构 + 多层级动线"的组合场景,例如 README 里那个海上石柱的龙骑士巢穴:四个突出石台环抱孵化洞、木制着陆平台带吊机与挂架、折返楼梯连接水边船屋。这类提示词本身就包含十几个空间约束,一次生成的成功率天然更低——而在 CPU 上,每一次"再生成一遍"都是半小时起步的代价,失败成本被放大了十几倍。
这也解释了为什么在弱算力环境下,提示词的写法比模型选择更重要。仓库给出的系统提示词是一条硬约束,直接决定了输出能否在浏览器里跑起来:
Use only the Three.js core ES module from https://cdnjs.cloudflare.com/ajax/libs/three.js/0.160.0/three.module.min.js. Do not import addons or legacy examples/js paths; implement any camera controls directly inside the HTML.把版本、来源、禁用 addons 三件事钉死,模型就不会在OrbitControls的导入路径上翻车。再配合"主题 + 布局 + 风格"的结构化写法(例如结尾固定加一句"Render it as a deliberate 3D voxel model built from visible cubic blocks, with clear depth, readable silhouettes, and solid spatial relationships"),等于把自由度收窄到几何本身,减少一次生成的随机性。
至于生成结果的质量演进,README 保留了 10 月 25、26、27 三个 checkpoint 的罗马场景对比,可以直观看到一次性成功率的提升:
另外要有预期:README 的"Known issues"写得很克制——目前观察到的 bug 多为变量名重复这类小瑕疵,而不是结构性错误。对人类来说,改个重名变量是十秒钟的事;但纯 CPU 用户要付出的不是这十秒,而是"发现→定位→让模型重写整段"的又一轮长生成。所以低算力环境下的正确姿势是:先拿最小可运行版本,再局部追加,而不是一次许愿要一个完整世界。
什么情况下必须上显卡
把上面的账算完,边界其实很清楚。以下几种需求,CPU 不是"慢一点",而是"方案不成立":
- 要迭代,而不是要结果。3D 场景生成本质是"生成—预览—修正"的循环,通常需要 2~4 轮才收敛。当单轮成本超过 20 分钟,这个循环就断了。
- 要长上下文。模型标称
max_position_embeddings为 262144,但 16K 上下文在 CPU 上就是 512 MiB 的 KV 加翻倍的注意力开销;真要跑满 32K 以上,KV 单项就吃掉 1 GiB,且全注意力层的计算会显著拖慢 prefill。 - 要批量或并发。数据集侧有 4146 个场景样本(3933 训练 / 213 验证),任何"跑一批提示词做筛选或蒸馏"的想法都需要 GPU 侧的批处理能力,CPU 串行吞吐连零头都够不上。
- 要做二次微调。仓库这次放出了 4 个分片的 FP16 权重与完整配置、tokenizer、chat template,明确是为了高质量二次微调准备的。8.45 GiB 的权重加上优化器状态和激活,纯 CPU 训练不是"能不能"的问题,而是时间尺度的问题。
- 要用视觉输入。这个架构是
Qwen3_5ForConditionalGeneration,带 24 层视觉塔与独立的图像/视频预处理配置(preprocessor_config.json、video_preprocessor_config.json),chat template 里也完整处理<|vision_start|>与image_pad。但 GGUF 路线通常只加载文本主干,想要"给一张截图让它复刻布局",需要走 Transformers 全量权重,这就回到了显卡的地盘。
反过来,只要你的目标是验证可行性、做低频单次生成、或者在没有独显的办公机上先摸清模型脾气,2.52 GiB 的 Q4_K_M 就是当前性价比最高的入口:它足够小,能塞进大多数机器的空闲内存;它也足够完整,遵循同一套系统提示词、同一套采样参数、同一份 Apache-2.0 许可。
真正的门槛从来不是显存,而是耐心。把输出控制在几千 token、把结构约束写清楚、把思考链按需关掉、把失败重试当成一次要花半小时的决定——做到这四条,没有独显也能跑出可以打开、可以转视角、可以截图发人的 3D 场景。超出这个范围的部分,交给显卡更诚实。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考