
文章目录
-
- [1. 先把问题讲清楚:学习 ChatGLM 不该只问"强不强"](#1. 先把问题讲清楚:学习 ChatGLM 不该只问“强不强”)
- [2. GLM 的训练目标直觉:理解和生成要统一](#2. GLM 的训练目标直觉:理解和生成要统一)
- [3. 对话模板:模型行为的一部分](#3. 对话模板:模型行为的一部分)
- [4. Loss Masking:让模型学回答,而不是学用户怎么提问](#4. Loss Masking:让模型学回答,而不是学用户怎么提问)
- [5. 中文对话难点:不是普通话闲聊那么简单](#5. 中文对话难点:不是普通话闲聊那么简单)
- [6. 多轮对话:要测状态保持和约束继承](#6. 多轮对话:要测状态保持和约束继承)
- [7. 本地部署:能跑不等于能用](#7. 本地部署:能跑不等于能用)
- [8. 量化:省显存,也可能改变行为](#8. 量化:省显存,也可能改变行为)
- [9. ChatGLM 类模型适合什么项目](#9. ChatGLM 类模型适合什么项目)
- [10. 中文业务评估集怎么设计](#10. 中文业务评估集怎么设计)
- [11. 常见误区](#11. 常见误区)
- [12. 小结](#12. 小结)
- 大模型视角
- 下一篇
摘要:ChatGLM/GLM 系列适合作为中文对话模型路线的学习案例。它的价值不只是"国产开源对话模型",而是帮助开发者理解:预训练目标如何影响生成与理解,对话模板为什么会影响模型行为,SFT 的 loss masking 为什么关键,本地部署和量化为什么必须重新评估,以及中文业务场景该如何构造测试集。本文不会追逐某一代模型的榜单,而是从技术机制和工程评估角度拆解 ChatGLM/GLM 给开发者的启发。
- 前置知识:专栏一 Transformer、 Encoder-Decoder vs Decoder-Only、Tokenization
- 阅读时间:55-70 分钟
- 代码环境:Python 3.10+,示例只依赖标准库
- 读完目标:能解释 GLM/ChatGLM 的基本定位,能理解对话模板和 loss mask 的作用,能设计中文对话、本地部署和量化评估闭环
1. 先把问题讲清楚:学习 ChatGLM 不该只问"强不强"
很多人看 ChatGLM,第一反应是拿它和 LLaMA、Qwen、DeepSeek 做横向比较。比较当然有用,但如果只问"谁更强",很容易忽略真正可迁移的知识。
ChatGLM/GLM 系列更适合作为一个中文对话模型案例来学习。它让我们看到:
text
1. 预训练目标不只有"简单续写"一种设计;
2. 对话模型的模板、特殊 token 和角色标记会影响行为;
3. 中文业务输入往往口语化、中英混合、格式不规整;
4. 本地部署时,量化、上下文和推理框架会改变质量;
5. 模型能聊天,不等于能稳定处理业务任务。
所以本文的重点不是复述版本历史,而是回答:如果你要用 ChatGLM/GLM 类模型做中文应用,应该理解哪些机制,评估哪些风险,怎样避免"demo 能跑、业务不可用"。
2. GLM 的训练目标直觉:理解和生成要统一
传统语言模型常见两条路线:
| 路线 | 大白话理解 | 典型能力 |
|---|---|---|
| 自回归语言模型 | 根据前文预测后文 | 续写、生成、对话 |
| 掩码/填空模型 | 根据上下文恢复缺失片段 | 理解、分类、补全 |
GLM(General Language Model)的公开路线强调用较统一的方式处理理解和生成任务。入门读者不需要在这里深挖所有论文细节,先抓住一个直觉:它不是只把文本从左到右续写,而是希望模型能在更灵活的上下文条件下生成目标片段。
这对对话模型有什么启发?用户输入并不总是干净的"文章开头"。真实对话可能是:
text
这个报销咋整?
上次那个接口又 500 了,帮我看看。
合同第 4.2 条和第 7 条是不是冲突?
模型既要理解上下文,又要生成有结构的回答。ChatGLM 的学习价值就在于:把中文对话、理解和生成放在一个工程链路里看。
3. 对话模板:模型行为的一部分
对话模型不是简单把用户问题拼到输入后面。训练时通常会使用固定 chat template,把 system、user、assistant 等角色转成特殊格式。推理时如果模板不一致,模型就可能角色混乱、输出奇怪标记、停止位置错误。
下面是一个 toy 模板,只用于说明结构:
python
# Python 3.10+
def build_prompt(messages, add_assistant_prompt=True):
parts = []
for msg in messages:
parts.append(f"<|{msg['role']}|>\n{msg['content']}\n")
if add_assistant_prompt:
parts.append("<|assistant|>\n")
return "".join(parts)
messages = [
{"role": "system", "content": "你是一个严谨的中文技术助手。"},
{"role": "user", "content": "解释什么是 KV Cache,并给一个例子。"},
]
print(build_prompt(messages))
真实 ChatGLM/GLM 模型应使用官方或模型仓库提供的 tokenizer 和模板。不要手写"看起来差不多"的格式。模板是训练协议的一部分,不是排版。
模板错误常见后果:
| 错误 | 表现 |
|---|---|
| 缺少 assistant 起始标记 | 模型继续复述用户或 system |
| 角色标记不匹配 | 输出 <user>、<assistant> 等残留 |
| 结束符错误 | 模型停不下来或过早停止 |
| 多轮拼接错误 | 忘记前文约束或混淆角色 |
| 训练和推理模板不同 | SFT 效果明显变差 |
4. Loss Masking:让模型学回答,而不是学用户怎么提问
SFT 时,输入中包含 system、user 和 assistant。我们通常只希望模型学习 assistant 的回复,不希望它学习复述 system 或 user。这就需要 loss masking。
直觉是:
text
system/user:作为条件输入,不计算 loss;
assistant:作为目标输出,计算 loss;
padding:无效位置,不计算 loss。
下面用字符级 token 模拟:
python
# Python 3.10+
IGNORE = "IGNORE"
tokens = [
"<system>", "你是助手", "<user>", "解释RAG", "<assistant>",
"RAG", "是", "检索", "增强", "生成", "<eos>"
]
labels = []
learn = False
for tok in tokens:
if tok == "<assistant>":
learn = True
labels.append(IGNORE)
elif learn:
labels.append(tok)
else:
labels.append(IGNORE)
for tok, label in zip(tokens, labels):
print(f"{tok:12s} -> {label}")
真实训练里 IGNORE 常对应 -100。如果 mask 错了,会出现很隐蔽的问题:
- 训练 loss 看起来下降,但模型没学会回答;
- 模型学会输出用户问题;
- 模型在多轮里角色错乱;
- 工具返回内容被当作 assistant 自己的回答;
- padding 参与 loss,训练被污染。
所以用 ChatGLM/GLM 做 SFT 前,必须抽样打印模板化后的文本和 labels,确认 assistant 部分才是训练目标。
5. 中文对话难点:不是普通话闲聊那么简单
中文业务对话有几个常见难点:
| 难点 | 示例 | 风险 |
|---|---|---|
| 口语化 | "这个发票咋整?" | 模型需要补全意图 |
| 中英混合 | "OAuth 回调一直 401" | tokenizer 和术语理解影响大 |
| 省略上下文 | "还是上次那个问题" | 需要多轮状态 |
| 制度条款 | "按第4.2条能报吗?" | 需要证据和边界 |
| 格式输出 | "给我 JSON" | 需要稳定 schema |
| 权限/隐私 | "查一下同事工资" | 需要拒答和审计 |
因此中文对话评估不能只看闲聊、写作文或常识问答。必须贴近真实输入。
一个最小评估样本可以这样写:
json
{
"id": "reimburse_001",
"messages": [
{"role": "user", "content": "北京出差住了720一晚,没提前审批,能全报吗?"}
],
"expected_behavior": [
"识别北京住宿和720元",
"说明需要依据公司制度判断",
"不能承诺全额报销",
"建议补充制度或转财务审核"
],
"risk": "finance_policy"
}
这种样本比"介绍一下北京"更能说明模型是否适合业务。
6. 多轮对话:要测状态保持和约束继承
多轮对话不只是把历史记录塞进上下文。模型要能识别哪些信息已经给过、哪些约束仍然有效、哪些问题需要继续澄清。
示例:
text
用户:我想报销住宿费。
助手:请提供城市、金额、日期和是否提前审批。
用户:北京,720 元,昨天,没有审批。
助手:北京住宿标准和审批规则需要以公司制度为准。若制度规定标准为 600 元且超标需提前审批,则 720 元可能无法全额报销,建议提交财务审核或补充审批说明。
评估点:
text
1. 是否记住城市、金额、日期、审批状态;
2. 是否重复询问已给信息;
3. 是否区分事实、假设和制度依据;
4. 是否避免直接承诺审批结果;
5. 是否给出下一步操作。
可以用简单脚本统计多轮评估结果:
python
# Python 3.10+
results = [
{"case": "turn_state", "remembered": True, "no_overclaim": True},
{"case": "turn_state", "remembered": False, "no_overclaim": True},
{"case": "policy", "remembered": True, "no_overclaim": False},
]
metrics = {
"remember_rate": sum(r["remembered"] for r in results) / len(results),
"no_overclaim_rate": sum(r["no_overclaim"] for r in results) / len(results),
}
print(metrics)
多轮能力要用多轮样本测,不能用单轮问答代替。
7. 本地部署:能跑不等于能用
ChatGLM 类模型常被用于本地或私有化部署。很多开发者会先关心"显存能不能放下"。这是必要问题,但不够。
权重大小可以粗略估算:
python
# Python 3.10+
def weight_gb(params_billion, bits):
return params_billion * 1_000_000_000 * bits / 8 / 1024**3
for params in [6, 9, 32]:
print(f"\n{params}B model")
for bits in [16, 8, 4]:
print(f" {bits}bit weights ≈ {weight_gb(params, bits):.2f} GB")
但真实推理还要加上:
text
1. KV Cache;
2. 上下文长度;
3. batch size 和并发;
4. 推理框架临时缓存;
5. tokenizer 和 CPU 预处理;
6. 量化 kernel 是否高效;
7. 操作系统和驱动开销。
所以"模型启动成功"只是第一步。上线前还要压测首 token 延迟、tokens/s、并发、长上下文、异常输入和重启恢复。
8. 量化:省显存,也可能改变行为
量化能把权重从 FP16/BF16 压到 INT8、INT4 等格式,降低显存。但量化不是免费午餐。
量化后要重点评估:
| 能力 | 为什么可能受影响 |
|---|---|
| 中文表达 | 细粒度词义和格式可能退化 |
| JSON 输出 | 小概率格式错误可能增加 |
| 数学和代码 | 对数值和符号更敏感 |
| 长上下文 | 累积误差和注意力稳定性 |
| 拒答边界 | 安全行为可能被扰动 |
| 多轮对话 | 状态保持可能变差 |
一个最小量化前后评估记录:
python
# Python 3.10+
eval_result = [
{"case": "json_output", "fp16": True, "int4": False},
{"case": "normal_qa", "fp16": True, "int4": True},
{"case": "policy_refusal", "fp16": True, "int4": True},
]
for row in eval_result:
changed = row["fp16"] != row["int4"]
print(row["case"], "changed_after_quantization=", changed)
如果你的任务强依赖格式和边界,量化后必须重新评估,不要只看困惑度或几个 demo。
9. ChatGLM 类模型适合什么项目
适合尝试的场景:
text
1. 中文对话和问答原型;
2. 私有化部署实验;
3. 中文 RAG 助手;
4. 中小规模 SFT/LoRA 实验;
5. 对话模板、loss mask、量化部署教学;
6. 成本敏感的内部工具。
需要谨慎的场景:
text
1. 高风险金融、法律、医疗决策;
2. 复杂多工具 Agent 自动执行;
3. 极长文档精确引用;
4. 高并发生产服务;
5. 未经评估的量化模型上线;
6. 需要最新事实且没有 RAG 的场景。
不是模型不能做,而是必须有对应评估、权限、RAG、人工审核和监控。
10. 中文业务评估集怎么设计
一个可用的中文评估集至少覆盖:
| 类别 | 测什么 |
|---|---|
| 普通中文问答 | 表达清楚、事实正确 |
| 中英混合 | 技术术语、缩写、错误码 |
| 业务制度 | 能否基于证据回答,不乱承诺 |
| 多轮对话 | 状态保持和约束继承 |
| 格式输出 | JSON、Markdown、表格稳定性 |
| RAG | 引用准确、无证据拒答 |
| 安全边界 | 隐私、越权、高风险建议 |
| 量化回归 | 量化前后行为差异 |
评估时不要只给总分。要按类别记录失败原因:事实错、格式错、拒答错、模板错、上下文漏读、越权、幻觉。这样才能指导下一轮 prompt、RAG、SFT 或模型选型。
11. 常见误区
误区一:中文模型适合所有中文业务。 通用中文能力和垂直业务能力不同,必须用业务评估集验证。
误区二:对话模板可以随便改。 模板是模型后训练的一部分,训练和推理不一致会直接影响行为。
误区三:本地能跑就能上线。 上线还需要并发、监控、权限、日志、评估、回滚和安全策略。
误区四:量化只影响显存。 量化也可能影响格式、数学、代码、长上下文和安全边界。
误区五:SFT 只要问答数据就够。 还要有拒答、澄清、多轮、格式、边界和真实噪声样本。
12. 小结
ChatGLM/GLM 系列的学习价值在于,它把中文对话模型的几个关键问题集中呈现出来:训练目标如何兼顾理解和生成,对话模板如何成为模型行为协议,SFT loss masking 如何决定模型学什么,本地部署和量化如何改变成本与质量,中文业务评估如何超越闲聊 demo。
对开发者来说,不要只看模型名和榜单。真正决定项目成败的是:模板是否正确、数据是否贴近业务、mask 是否可靠、量化后是否回归、RAG 和权限是否补齐、评估集是否覆盖真实失败场景。
大模型视角
从大模型工程视角看,ChatGLM 这类模型提醒我们:模型能力不是单独存在的,它总是和 tokenizer、chat template、训练数据、推理框架、量化方式和评估体系绑定。理解这些绑定关系,比记住某个模型版本更重要。
下一篇
下一篇会讲 DeepSeek 系列。我们会从 MoE、MLA、MTP、推理训练和成本结构出发,理解另一条强调效率和复杂推理能力的技术路线。