MOSS-Image 小文本编码器适配器
用 Qwen3.5-0.8B / 2B / 4B 替代 MOSS-Image 的 Qwen3.5-9B 文本编码器。
学生模型完全冻结,只学一个逐 token 的线性投影,把隐状态映射到 DiT 期望的 4096 维。 配套代码与节点:moss-image-mini-encoder。 完整的 8 档 × 10 条测试矩阵(含全部出图、余弦矩阵、耗时)见 docs/benchmark.md。
学生权重(已量化,在 weights/)
这些 w4a8 / int8 文件是用 ComfyUI 的 comfy_kitchen 量化器从官方 Qwen3.5 权重转出来的,
格式与 ComfyUI 的 asym_w4a8_int8 / int8_tensorwise 一致,直接放进
ComfyUI/models/text_encoders/ 就能用,不需要自己再量化。
| 文件 | 基座 | 格式 | 体积 | 配套适配器 |
|---|---|---|---|---|
weights/qwen3.5-0.8b-int8.safetensors |
Qwen3.5-0.8B | int8 | 1.17 GB | qwen3.5-0.8b_int8_linear.safetensors |
weights/qwen3.5-0.8b-w4a8.safetensors |
Qwen3.5-0.8B | w4a8 | 0.96 GB | qwen3.5-0.8b_w4a8_linear.safetensors |
weights/qwen3.5-2b-int8.safetensors |
Qwen3.5-2B | int8 | 2.97 GB | qwen3.5-2b_int8_linear.safetensors |
weights/qwen3.5-2b-w4a8.safetensors |
Qwen3.5-2B | w4a8 | 2.38 GB | qwen3.5-2b_w4a8_linear.safetensors |
weights/qwen3.5-4b-w4a8.safetensors |
Qwen3.5-4B | w4a8 | 3.84 GB | qwen3.5-4b_w4a8_linear.safetensors |
bf16 档直接用官方 Qwen/Qwen3.5-0.8B / Qwen/Qwen3.5-2B 原版权重,不需要转换。
量化文件由本项目的 src/scripts/quantize_encoder.py 生成,基座权重遵循其原始许可。
文件
| 文件 | 学生 | 量化 | 训练集 cos | relL2 |
|---|---|---|---|---|
qwen3.5-0.8b_linear.safetensors |
0.8B | bf16 | 0.85192 | 0.5237 |
qwen3.5-0.8b_int8_linear.safetensors |
0.8B | int8 | 0.85169 | 0.5241 |
qwen3.5-0.8b_w4a8_linear.safetensors |
0.8B | w4a8 | 0.84997 | 0.5268 |
qwen3.5-2b_linear.safetensors |
2B | bf16 | 0.87478 | 0.4846 |
qwen3.5-2b_int8_linear.safetensors |
2B | int8 | 0.87474 | 0.4846 |
qwen3.5-2b_w4a8_linear.safetensors |
2B | w4a8 | 0.87326 | 0.4873 |
qwen3.5-4b_w4a8_linear.safetensors |
4B | w4a8 | 0.89692 | 0.4422 |
训练集 cos 是在 6,374,951 token 的验证集上逐 token 评估的均值。
适配器必须与学生尺寸和量化格式同时匹配。同一学生的 bf16 与 w4a8 权重会产出不同特征, 用错适配器时条件向量只能对上 0.9927,出图肉眼可见掉细节,不要交叉使用。
用法
- 下载对应的 Qwen3.5 学生权重,放到
ComfyUI/models/text_encoders/ - 本仓库的
.safetensors(一个文件即完整适配器)放到ComfyUI/models/moss_encoder_adapters/ - 节点:
MossCLIPLoader(学生权重, moss_image, adapter) → CLIPTextEncode → KSampler
adapter 选 none 时不投影,等价于官方 CLIPLoader——9B 走这条。
实测:同一组提示,四档出图
固定 seed 42、4 步 LoRA、cfg 1、1024×1024。左到右:9B / 4B w4a8 / 2B w4a8 / 0.8B bf16。
只给角色名「蔚蓝档案的鬼方カヨコ蹲在巷子里喂流浪猫」
- 9B:白发黑挑染、红瞳、双角、光环、黑外套——角色对
- 4B:有角和光环,但蓝瞳、无挑染——落进「蔚蓝档案」这个域,认错人
- 2B:白发蓝瞳的普通少女,没有角也没有光环,与 0.8B 的区别只是换了发色
- 0.8B:金发蓝眼、白衬衫蓝裙——完全没识别,落回通用萌系
只给品牌名「蜜雪冰城的雪王站在店门口」
- 9B:招牌「蜜雪冰城」、白胖雪人、金冠、红披风、冰淇淋火炬,身上还有竖排「蜜雪冰城」,全对
- 4B:以上要素齐全,只少了身上的竖排字
- 2B:招牌与金冠正确,但雪人变成了真的雪堆、披风变成红围巾、没有火炬
- 0.8B:招牌写成「𠳨雪冰城」,雪王被画成穿龙袍的白胡子老者
实测:条件向量与耗时
对 9B 条件逐 token 计算,10 条中英混合提示(含一条 627 token 的长 JSON):
| 档位 | cos 均值 | cos 最小 | relL2 | 纯编码 30/326 tok | 端到端热态 |
|---|---|---|---|---|---|
| 9B w4a8 | 1.0000 | 1.0000 | 0.0000 | 87.0 / 130.7 ms | 33.1 s |
| 4B w4a8 | 0.8638 | 0.8099 | 0.537 | 87.9 / 86.9 ms | 23.6 s |
| 2B bf16 | 0.8406 | 0.7924 | 0.697 | 43.1 / 44.8 ms | 21.7 s |
| 2B w4a8 | 0.8372 | 0.7862 | 0.720 | 72.9 / 71.1 ms | 20.4 s |
| 0.8B bf16 | 0.8149 | 0.7640 | 0.830 | 47.3 / 43.4 ms | 20.3 s |
| 0.8B w4a8 | 0.8136 | 0.7633 | 0.780 | 91.3 / 76.8 ms | 20.9 s |
- 纯编码远小于端到端:编码只占 20
33 秒里的 0.20.5%,其余是 4 步采样与每张图的模型装卸 - w4a8 比 bf16 慢(要反量化),它省的是显存:0.8B 958 MB / 2B 2.4 GB / 4B 3.8 GB
- 量化对余弦几乎没有影响:同尺寸下 int8 与 bf16 差 0.0001
0.0003,w4a8 差 0.00130.0034
是什么、不是什么
- 是:把 6 个中间层的隐状态沿特征轴拼起来(0.8B 得 6144 维、2B 12288、4B 15360),
做
((h-mean)/std) @ W * std_y + mean_y,逐 token 独立映射 - 不是:不是微调。学生权重一个字节都没改,只有这一份 48~120 MB 的矩阵
- 训练数据 38,496 条提示词,含中英 caption、tag、MOSS layout JSON、负面提示词
- 抽头固定为第 2 / 4 / 8 / 12 / 16 层与最后一层,已写进适配器 metadata
已知限制
- 专名绑定随尺寸退化:9B 画得对;4B 只学到「属于哪个作品」;0.8B 认不出。
- 0.8B 在长结构化提示里会单字错:627 token 的 layout JSON 里,
捐被系统性画成抬, 同图出现 5 次。短提示不受影响。4B 无此问题。 - 训练集 P99 长度 937 token、最长 3235;再长的提示属于分布外。
- 只适用于 MOSS-Image,输出固定 4096 维。
致谢
- ComfyUI-ClipProj — 投影层训练方法
- moss-image-smaller-encoder — 适配器格式
- MOSS-Image — 提示词模板与 layout 格式
- Qwen3.5 — 基座模型:0.8B / 2B / 4B / 9B

