ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

FreeToken 支持模型完全指南:模型家族、图片输入与 MoE 专家调度策略

FreeToken 支持模型完全指南:模型家族、图片输入与 MoE 专家调度策略

FreeToken 支持模型完全指南:模型家族、图片输入与 MoE 专家调度策略

FreeToken 是一个面向个人硬件(消费级 GPU、主机内存与 PCIe 互连)的边缘原生 MoE(Mixture-of-Experts)推理引擎,其核心目标是把数据中心级别的模型服务搬到桌面上。本文以官方文档 docs/models.md 为骨架,完整梳理 FreeToken 当前支持的全部模型家族与已验证的 HF 检查点、各家族图片输入(视觉编码器)的接入方式与 token 预算语义,以及决定 MoE 专家驻留与调度方式的五种策略(fused/offload/cpu/hybrid/auto)。读完本文,你将能依据自己的显存、内存与 PCIe 带宽,为任意受支持检查点选择正确的启动参数,并理解 FTW 快速加载格式、图片输入与 MoE offload 背后源码级的实现原理。

支持的模型与 HF 检查点

FreeToken 直接加载 Hugging Face 的 safetensors 检查点(ft serve --model <path-or-hf-id>),无需预先转换。下表列出的是**已知良好(known-good)**的检查点——预编译内核针对它们做过调优;同一架构的其它检查点通常也可以工作,但不在官方验证范围内。

模型HF 检查点
DeepSeek-V4deepseek-ai/DeepSeek-V4-Flash-0731
GLM-5.3-FlashRedHatAI/GLM-5.3-Flash-NVFP4
GLM-5.2nvidia/GLM-5.2-NVFP4
GLM-4.7nvidia/GLM-4.7-NVFP4
Qwen3.8-Flash-NextQwen/Qwen3.8-Flash-Next-FP8、RadixArk/Qwen3.8-Flash-Next-NVFP4、nvidia/Qwen3.8-Flash-Next-NVFP4
Qwen3.6 / Qwen3.5 MoEQwen/Qwen3.6-35B-A3B(及-FP8)、nvidia/Qwen3.6-35B-A3B-NVFP4、Qwen/Qwen3.5-35B-A3B(及-FP8)
Qwen3.8 / Qwen3.6 denseQwen/Qwen3.8-27B(及-FP8)、RadixArk/Qwen3.8-27B-NVFP4、Qwen/Qwen3.6-27B(及-FP8)、nvidia/Qwen3.6-27B-NVFP4
Qwen3-MoEQwen/Qwen3-30B-A3B
Qwen3-VLQwen/Qwen3-VL-8B-Instruct、Qwen/Qwen3-VL-30B-A3B-Instruct
gpt-ossopenai/gpt-oss-120b、openai/gpt-oss-20b
Gemma-4google/gemma-4-26B-A4B-it、nvidia/Gemma-4-26B-A4B-NVFP4、google/gemma-4-12B-it、nvidia/Gemma-4-31B-IT-NVFP4等
MiniMax-M2.5nvidia/MiniMax-M2.5-NVFP4
MiniMax-M3nvidia/MiniMax-M3-NVFP4
Muse-Glimmermeta-models/Muse-Glimmer-30B、RedHatAI/Muse-Glimmer-30B-NVFP4

从仓库源码看,每个家族都在模型注册表 python/freetoken/models/register.py 中登记为一张ModelSpec:DeepseekV4ForCausalLM对应 deepseek_v4,GlmMoeDsaForCausalLM对应 GLM-5.2(glm_moe_dsa),Glm5NextForConditionalGeneration对应 GLM-5.3-Flash(glm5_next),Qwen4ExpForConditionalGeneration对应 Qwen3.8-Flash-Next(qwen4_exp),dense 与 MoE 的 Qwen3.5/3.6/3.8 统一落在 qwen3_5_moe 包内,Qwen3-VL 在 qwen3_vl,Gemma-4 的gemma4/gemma4_unified两个变体都在 gemma4,gpt-oss 在 gpt_oss。注册表通过architectures字段自动识别检查点,因此ft serve只需要--model一个必填参数。

不同量化的落地方式

上表中同一模型往往有 FP8、NVFP4、BF16 等多个 HF 发布,FreeToken 按量化配置(quantization_config)自动选择内核路径:例如 NVFP4 专家可由--quant-backend moe.nvfp4=指定marlin/b12x/triton之一(--nvfp4-backend是已废弃的旧拼写,等价于--quant-backend moe.nvfp4=<...>,详见 docs/cli.md)。量化方案的解析逻辑集中在 layers/quantization,ModelSpec中的packed_modules_mapping(如把qkv_proj拆回 HF 的q_proj/k_proj/v_proj叶子)保证量化配置查表时能找到与 HF 检查点一致的名字。

图片输入(Image input)

以下家族默认接受图片输入;传--text-model-only可跳过视觉编码器只做纯文本服务。相关 flags 的完整说明见 CLI 参考,每个家族用自己的单位解释这些 flag(token 预算的换算方式不同,见下表)。

家族图片 token 计算--image-min-tokens/--image-max-tokens语义--mm-processor-kwargs示例
Qwen3.6(两种变体、表内全部权重格式)、Qwen3.8-Flash-Next、Qwen3-VL缩放后图片每 32x32 像素 1 个 token,动态分辨率以像素面积形式传给size.shortest_edge/longest_edge;检查点默认 64 到 16384 token{"size": {"longest_edge": 1048576}}
Gemma-4 26B-A4B、31B(gemma4:ViT tower,--mm-encoder-weights host下流式加载)从 70 / 140 / 280 / 560 / 1120 软 token 预算中取一档,每张图在宽高比允许范围内缩放到对应预算最大值会选取落在区间内的最大档位,低于 70 启动时直接拒绝;最小值无效{"max_soft_tokens": 1120}
Gemma-4 12B(gemma4_unified:线性 patch embedder,两种驻留方式下都常驻)同上预算,每个软 token 对应一个 48x48 超级 patch与 tower 版本一致同上
GLM-5.3-Flash(glm5_next:ViT tower,--mm-encoder-weights host下流式加载)缩放后图片每 28x28 像素 1 个 token,动态分辨率,画布零填充到 28 的倍数直接透传为处理器的min_image_tokens/max_image_tokens;检查点默认 16 到 8000 token{"max_image_tokens": 2048}
Muse-Glimmer-30B(windowed ViT tower,--mm-encoder-weights host下流式加载)缩放后图片每 28x28 像素 1 个 token,宽高比控制在 token 上限内;检查点默认 4096 token最大值即上限(max_image_tokens);最小值无效{"max_image_tokens": 1024}
MiniMax-M3(minimax_m3:CLIP 风格 ViT tower,--mm-encoder-weights host下流式加载)缩放后图片每 28x28 像素 1 个 token,动态分辨率以像素面积形式传给size.shortest_edge/longest_edge;检查点默认 4 到 576 token{"size": {"longest_edge": 1048576}}

视觉编码器在源码中的登记与接入

  • 编码器塔以EncoderSpec登记在ModelSpec.encoders上(kind 为"vision"/"audio",即--mm-disable可关闭的种类),并在register.py中挂接对应的多模态处理器:Qwen 系共用QwenVLMMProcessor(mm/processors/qwen_vl.py),Gemma-4 用Gemma4MMProcessor/Gemma4UnifiedMMProcessor(mm/processors/gemma4.py),GLM-5.3-Flash 用Glm5NextMMProcessor(mm/processors/glm5_next.py),MiniMax-M3 与 Muse-Glimmer 各有独立处理器。这些处理器把上表的 token 预算语义翻译成各家的图像缩放与 patch 划分逻辑。
  • --mm-encoder-weights host(默认)表示编码器塔的块权重从 pinned host bank 每次两块地流式送入 GPU(计算与拷贝重叠),GPU 只保留两块而非整座塔;gpu则让权重常驻显存。没有块堆栈的编码器无论哪种方式都常驻。
  • GET /v1/stats会以model.input_modalities(["text"]或["text", "image"])上报服务器实际接受的输入模态,客户端无需解析检查点配置即可决定是否开放附件入口(docs/cli.md)。

MoE 策略(专家驻留与调度)

MoE 模型的专家权重很大,不可能全部常驻消费级显存。FreeToken 通过ft serve --moe-strategy {auto,fused,offload,cpu,hybrid}控制专家"住哪里、miss 时怎么办"(--moe-backend是已废弃的旧拼写;在 engine/config.py 的EngineConfig.__post_init__中会把它折叠进moe_strategy):

  • fused— 所有专家常驻 GPU(需要足够的显存);永远不会被自动选中。
  • offload— 专家存放在主机 RAM(pinned host banks),GPU 上维护一个专家槽位的 LRU 缓存;缓存 miss 时通过 PCIe 流式取回。
  • cpu— miss 的专家不取回 GPU,而是直接在 CPU 上用主机内存计算。
  • hybrid— 每个 step 一部分 miss 走 PCIe 取回,其余在 CPU 计算,两者重叠执行。需要在每台机器上跑一次ft bench bw校准拆分比例。
  • auto— dense 模型恒定为fused;MoE 模型解析为offload,当存在ft bench bw的缓存 profile 且推荐 hybrid 时升级为hybrid。

策略集合在 python/freetoken/moe/init.py 中定义为MOE_STRATEGIES = ("fused", "offload", "cpu", "hybrid"),offload/cpu/hybrid同属 offload 家族(OFFLOAD_MOE_STRATEGIES)。

源码视角:offload 家族如何工作

  • 专家 bank 与 LRU 槽位缓存:offload_cache.py 中的OffloadMoeCache以cache_policy="lru"在 GPU 上维护专家槽位,并记录每个 (layer, expert) 的最近活跃 step(expert_recency)供 hybrid 的逐层抓取上限挑选最活跃的 miss 先取。缓存大小由--moe-cache-size(槽位数)/--moe-cache-rate(专家总数占比)/--moe-cache-auto(按空闲显存自动推导)三者互斥指定;offload 家族默认开启 auto,由 engine/cache_budget.py 的resolve_moe_cache_auto统一求解专家槽位与 KV page 的显存划分。
  • 最小缓存约束:engine.py 中的_require_offload_cache_size强制缓存至少每层每专家一个槽位,太小会直接报错——这是避免 offload 空转的关键保护。
  • CPU 层拆分:--moe-cpu-layers与--moe-strategy offload组合时,可以把指定 MoE 层的 decode 放到 CPU 执行(_resolve_cpu_layers);--moe-strategy cpu则所有层都在 CPU。该参数仅接受 CPU 执行器能服务的专家格式(bf16、nvfp4、mxfp4),fp8 专家无法使用(docs/cli.md)。
  • hybrid 的自动决策:auto升级到 hybrid 依赖 moe/bench_profile.py 的load_backend_recommendation,它读取ft bench bw写入的 profile(按 GPU UUID 存放于~/.cache/freetoken/benchbw/<gpu-uuid>.json,按专家格式 + GPU 键控,硬件不匹配时直接忽略)。只有当 CPU 带宽超过 PCIe 带宽达到--threshold(默认 2.0)倍才推荐 hybrid;统一内存设备(GB10/DGX Spark、Jetson)没有 host/device 边界,会直接跳过该升级逻辑并默认fused,因为此时 offload 家族只会引入无意义的搬运。

用 ft bench bw 校准本机

ft bench bw用真实的 cpu/offload MoE 内核测量主机内存与 PCIe 的带宽,并把 profile 交给--moe-strategy auto与--moe-hybrid-max-fetch -1读取:

ft bench bw # 每块 GPU 跑一次即可 ft bench bw --dtype nvfp4,bf16 # 只测你实际服务的格式 ft bench bw --gpu 1 # 指定 GPU(UUID 或 nvidia-smi 索引,同 ft serve)

注意事项(Notes)

  • FTW 转换是可选的:ft checkpoint 把 HF 检查点预先转换为 FreeToken 的 FTW 快速加载格式,ft serve --model会自动探测 FTW 目录(也接受原始 HF 目录或 HF repo id)。
  • 旧版 FTW 兼容性:量化重构之前构建的 FTW 可能加载失败;受影响检查点与修复工具见 FTW 修复指南。修复脚本 scripts/ftw_hotfix.py 按字节范围只下载缺失的张量,从不下载整个检查点,且能在中断后安全续跑(每步原子替换 index)。
  • 图片能力缺失的 FTW:在某个家族支持图片输入之前转换的 FTW 不含视觉编码器,ft serve会拒绝加载它,除非以--text-model-only(或--mm-disable vision)启动;解决办法是用ft checkpoint重新转换,或通过 scripts/ftw_hotfix.py 就地补齐编码器。加载侧对"缺视觉编码器"的判定在 models/weight.py 的ftw_lacks_vision中实现。
  • DeepSeek-V4 的目录结构要求:检查点必须保留inference/config.json子目录——权威的模型参数从那里读取(对应 register.py 中DeepseekV4ForCausalLM的特殊checkpoint_roots映射)。
  • Qwen3.8-Flash-Next 的 PLE 表:该模型把 47.7 GiB 的 PLE n-gram 表钉在主机 RAM(ple_backend="pinned",见 engine/config.py),启动时需要预留足够的主机内存。

快速上手示例

# 用 Qwen3.6-35B-A3B(MoE,自动选择 offload/hybrid)启动服务 ft serve --model Qwen/Qwen3.6-35B-A3B # 在无显存压力的机器上让专家全部常驻 GPU ft serve --model Qwen/Qwen3.6-35B-A3B --moe-strategy fused # 先用 benchbw 校准本机,再让 auto 决定是否升级 hybrid ft bench bw --dtype nvfp4,bf16 ft serve --model nvidia/Qwen3.6-35B-A3B-NVFP4 # 多模态模型只做文本服务,省下视觉编码器的显存给 KV/专家池 ft serve --model Qwen/Qwen3-VL-8B-Instruct --text-model-only # 限制单张图片的 token 预算并调整 GLM-5.3-Flash 的视觉处理器 ft serve --model RedHatAI/GLM-5.3-Flash-NVFP4 --image-max-tokens 2048

至此,你可以依据模型家族(dense 还是 MoE、是否多模态)、可用显存与主机内存、以及ft bench bw校准出的 CPU/PCIe 带宽比,为受支持检查点组合出正确的启动参数;遇到旧 FTW 加载失败时,也知道该用ft checkpoint重转还是用scripts/ftw_hotfix.py就地修复。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表