跳到主内容
芝麻园地
EN
← 返回博客
#freetoken#qwen#moe#wsl2#llm

FreeToken 部署 Qwen3.6-35B-A3B-NVFP4 实战总结(RTX5060Ti 16G + WSL2)

在 WSL2 + RTX5060Ti 16GB 上成功部署 Qwen3.6-35B-A3B-NVFP4 的完整实战记录:与教程的四处关键差异(仓库 404、CLI 参数、模型格式、Blackwell 编译链)、WSL 进程存活与显存记账问题的根因与解法(WSL 2.7.13 + systemd)、最终性能指标(冷加载 34s、解码 22~24 tok/s)与 OpenAI 兼容 API 接入方式。

编程快车 17 分钟

硬件:RTX5060Ti 16GB VRAM + 整机 32GB 物理内存 + WSL2 Ubuntu-24.04。 结果:部署成功,OpenAI 兼容 API 运行于 http://127.0.0.1:8000/v1,稳定解码 22~24 tok/s。 本文是上一篇《FreeToken 部署 Qwen3.6-35B-A3B-NVFP4 操作计划》的实战回执:教程给出的计划在执行中遇到 4 个与文档不符的坑,本文记录每个坑的根因与最终解法,供同配置机器复现。

1. 最终部署汇总报告

# FreeToken 部署最终汇总报告
✅ 部署结果:成功
🖥️ 硬件:RTX5060Ti 16G + 整机 32G 内存(WSL2 Ubuntu-24.04)
📌 模型:Qwen3.6-35B-A3B-NVFP4(NVIDIA modelopt 官方量化版,22GB,3 分片)
📊 运行指标:
- 冷加载耗时:约 34 秒(CUDA 内核缓存命中后;首次冷启约 2~3 分钟)
- 稳定解码速度:22 ~ 24 tok/s(实测多次采样:22.5 / 24.2 / 24.4 / 23.7 / 24.0 / 23.4)
- 峰值显存占用:约 5.9 GB / 16 GB(推理中 nvidia-smi 实测)
- 峰值内存占用:约 19 GB / 23 GB(WSL 限制;专家权重 16.9GB 常驻系统内存)
- Swap 最大使用:约 0 GB(未发生 swap 风暴)
🧪 API 测试结果:成功,模型可正常自我介绍、生成代码,回答质量正常
⚠️ 发现的问题:详见第 3 节(4 个部署坑,均已解决)
🔄 备选方案建议:无需切换 Unsloth Desktop

2. 最终启动配置(可直接复现)

python -m freetoken \
  --model-path /home/dev/models/Qwen3.6-35B-A3B-NVFP4-nvidia \
  --moe-strategy offload \
  --moe-cache-size 256 \
  --num-tokens 4096 \
  --kv-reserve-tokens 8192 \
  --max-prefill-length 8192 \
  --max-running-requests 1 \
  --moe-cpu-layers auto \
  --attention-backend triton \
  --host 127.0.0.1 --port 8000

关键参数说明(与教程的差异已在括号标注)

参数 值 说明
--moe-strategy offload 必选 专家权重驻留系统内存(16.9GB),GPU 只放 dense 权重 + 小缓存
--moe-cache-size 256 关键 不要用 auto 或 2048(见坑 4),本机 256 槽可稳定启动
--num-tokens 4096 关键 KV 实际容量;教程的 8192 上下文在本机需要配合 offload 才能稳定
--moe-cpu-layers auto 推荐 自动按 pin 预算锁 18 层 CPU decode,其余 GPU 拉取
--attention-backend triton 必选 教程写 --attn,实际参数名是 --attention-backend
--max-running-requests 1 必选 单并发,硬件限制

WSL 系统配置

%UserProfile%\.wslconfig(在教程基础上增加了 vmIdleTimeout=0):

[wsl2]
memory=24GB
processors=8
swap=4GB
localhostForwarding=true
vmIdleTimeout=0

另:建议用 systemd 托管服务(/etc/systemd/system/freetoken.service + [boot] systemd=true),服务不再依赖任何终端会话,配合 Restart=on-failure 自动拉起。

3. 实战中踩过的 4 个坑(教程与实际的关键差异)

坑 1:教程给的仓库、CLI、参数名与真实版本不符

教程描述 实际情况
github.com/freetoken/freetoken 404 死路;真实仓库为 github.com/FlashML-org/FreeToken(镜像:https://ghproxy.net/https://github.com/FlashML-org/FreeToken.git)
freetoken serve <model> CLI 入口为 python -m freetoken(entry point 另有 ft)
--attn triton 参数名为 --attention-backend triton
--moe-cache-size auto 本机 auto 会 OOM(见坑 4),需显式 256

坑 2:unsloth 混合量化模型不被 FreeToken 支持 → 换 NVIDIA 官方 modelopt 版

教程指向 ModelScope 的 unsloth/Qwen3.6-35B-A3B-NVFP4(26.5GB,compressed-tensors 混合布局:部分专家 FP8、部分 NVFP4)。FreeToken 的 MoE 量化注册表只有 nvfp4 / fp8_block / mxfp4 / mxfp8 / unquantized,不支持 per-tensor FP8 专家,启动即报:

NotImplementedError: no quant method for moe.fp8_tensor

解法:改用 NVIDIA 官方 nvidia/Qwen3.6-35B-A3B-NVFP4(modelopt MIXED_PRECISION:161 个 W4A16_NVFP4 专家 + 130 个 FP8 attention),经国内镜像 hf-mirror.com 下载 22GB(3 分片),并设 HF_HUB_DISABLE_XET=1 绕过 Xet 协议 401 报错。

坑 3:RTX 5060 Ti(Blackwell SM120)需要 CUDA 13 工具链

FreeToken 启动时会用 tvm_ffi JIT 编译 CUDA 内核(CUDA Graphs 阶段),目标架构 compute_120。系统自带的 nvcc 12.0 不认识 Blackwell:

nvcc fatal: Unsupported gpu architecture 'compute_120'

解法:从 NVIDIA 官方 apt 源安装 CUDA 13 工具链(仅编译需要):

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
dpkg -i cuda-keyring_1.1-1_all.deb && apt-get update
apt-get install -y cuda-nvcc-13-0 cuda-cudart-dev-13-0 cuda-cccl-13-0
export CUDA_HOME=/usr/local/cuda-13.0

同时需 pip install ninja(FreeToken 的 tvm_ffi 编译依赖)。注意 PyPI 的 nvidia-cuda-nvcc-cu13 在清华源是占位包、官方源构建失败,apt 源才是正解。

坑 4:两个“假 OOM”——WSL 会话回收 + WDDM 显存记账

这是本次部署最折腾的部分,两种现象都表现为“服务启动成功后又消失 / 报 CUDA OOM 但显存明明没用满”:

现象 A:服务进程随 WSL 会话退出被杀

  • 现象:日志停在专家加载 0%~33%,进程消失、无 OOM、无 traceback,内存全部释放
  • 排查:dmesg 有 systemd shutdown 记录;sleep 保持进程也消失
  • 根因:任何由 wsl.exe 前端启动的进程(包括 setsid nohup),在 wsl.exe 断开后都会被 WSL 会话回收;WSL 发行版空闲 60 秒后还会自动关闭(vmIdleTimeout 默认 60000ms)
  • 解法:升级 WSL 到 2.7.13(修复会话/进程回收)+ 配置 vmIdleTimeout=0 + 用 systemd 托管服务

现象 B:CUDA OOM,但 nvidia-smi 显示显存只用了不到 1GB

  • 现象:Tried to allocate 540.00 MiB 失败,报错称 “this process has 17179869184.00 GiB memory in use”(16GB 虚拟记账假象),实际 PyTorch 只分配了 3.1GB
  • 排查:最小 torch 脚本复现——单次分配 1GB 成功、4GB 失败;但单独跑又能连续分配 16GB;cudaMemGetInfo 显示 free 11.6GB 却连 32MB 都分配失败。banks(cudaHostRegister)经探针验证不占 GPU 配额,排除嫌疑
  • 根因:WSL2 的 WDDM 显存管理在特定状态下把进程可用显存锁死为 0,与物理显存占用无关(WSL 旧版本 bug)
  • 解法:升级 WSL 到 2.7.13 后问题消失

结论:遇到“显存没用满却 OOM”或“进程莫名消失”,先查 WSL 版本(wsl --version),旧版本升级到 2.7.13+ 是最优先动作。

4. 性能与资源实测

指标 实测值 说明
冷加载 ~34s CUDA 内核缓存命中后;首次冷启约 2~3 分钟(专家加载 45s + CUDA Graphs 42s + warmup 16s)
稳定解码 22~24 tok/s 高于教程预期的 14~22 tok/s
峰值显存 ~5.9GB / 16GB 推理中;空闲时约 1GB(offload 架构正常现象)
峰值内存 ~19GB / 23GB 专家权重 16.9GB 常驻系统内存
Swap ~0 未触发 swap 风暴
模型大小 22GB NVIDIA modelopt 版,3 分片

显存占用低是 offload 架构的正常现象:dense 权重 + 小专家缓存放显存,专家主体在系统内存按需搬入,物理显存占用不代表性能问题。

5. API 接入信息

  • API base url:http://127.0.0.1:8000/v1
  • model name:Qwen3.6-35B-A3B-NVFP4-nvidia(默认取模型目录尾名)
  • api key:任意字符串(本地无鉴权,如 sk-local)
curl http://127.0.0.1:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-local" \
  -d '{"model":"Qwen3.6-35B-A3B-NVFP4-nvidia",
       "messages":[{"role":"user","content":"你是谁"}]}'

实测返回正常(见截图),可接入 Claude Code / OpenClaw 等工具的 OpenAI 兼容端点。

6. 运维建议

  1. 服务托管:用 systemd(systemctl enable freetoken)而非终端前台,避免会话回收导致服务掉线
  2. 监控:每 30 秒采样 free -h 与 nvidia-smi --query-gpu=memory.used,memory.total --format=csv;Swap 持续 >2GB 或 CUDA OOM 即停止服务释放内存
  3. 禁止调整:--max-running-requests 保持 1;--num-tokens / KV 上下文不要盲目调大(16GB 显存 + 32GB 内存的硬上限)
  4. 遇到“假 OOM”:先 wsl --version 确认 WSL ≥ 2.7.13,再排查业务配置