ChatGLM2-6B 开源双语对话大模型:从架构特性到本地部署与微调全指南

原创2026-10-03 00:49:121,621 阅读
文章标签:大模型人工智能模型推理服务NLP

ChatGLM2-6B 开源双语对话大模型:从架构特性到本地部署与微调全指南

ChatGLM2-6B 是智谱 AI 开源的第二代中英双语对话大语言模型,在延续初代 ChatGLM-6B 流畅对话与低部署门槛的同时,通过 GLM 混合目标函数、FlashAttention 与 Multi-Query Attention 三项核心技术全面升级了性能、上下文长度与推理效率。本文以官方英文文档 README_EN.md 为主体,结合仓库内 api.py、cli_demo.py、utils.py、ptuning、evaluation 等源码,系统讲解模型的核心特性、评测结果、推理显存占用,以及代码调用、Web/CLI Demo、API 部署、量化、CPU/Mac/多卡部署等完整实战方案,帮助你快速在本机跑通 ChatGLM2-6B 并理解其底层实现原理。

模型核心特性与架构升级

ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本,在保留初代模型对话流畅、部署门槛较低等特性基础上,围绕"更强性能、更长上下文、更高推理效率、更开放协议"四个维度进行了升级:

  1. 更强大的性能:基于初代模型开发经验全面升级基座模型,采用 GLM 的混合目标函数,经过 1.4T 中英标识符的预训练与人类偏好对齐训练。官方评测显示,相比初代模型,ChatGLM2-6B 在 MMLU(+23%)、CEval(+33%)、GSM8K(+571%)、BBH(+60%)等数据集上均有大幅提升,在同尺寸开源模型中具有较强的竞争力。
  2. 更长的上下文:基于 FlashAttention 技术,将基座模型上下文长度从初代的 2K 扩展到 32K,并在对话对齐阶段使用 8K 上下文长度训练,支持更多轮次的对话。需要说明的是,当前版本对单轮超长文档的理解能力仍有限,属于后续迭代优化方向。
  3. 更高效的推理:基于 Multi-Query Attention(MQA)技术,推理速度与显存占用双双优化:官方实现下推理速度相比初代提升 42%;INT4 量化下,6G 显存支持的对话长度由 1K 提升到 8K。
  4. 更开放的协议:模型权重对学术研究完全开放,在登记问卷后亦允许免费商业使用。

仓库 README.md 中的更新日志还显示:项目组后续发布了基于 ChatGLM2-6B 的 32K 长文本版本(ChatGLM2-6B-32K)、代码能力全面升级的 CodeGeeX2 模型,并于 2023/07/04 发布了 P-Tuning v2 与全参数微调脚本(见 ptuning 目录)。

免责声明与合规提示

官方文档明确要求开发者遵守 开源协议,勿将开源模型、代码及衍生品用于任何可能危害国家和社会、或未经安全评估和备案的服务。同时需要了解:由于模型规模较小且受概率随机性影响,输出内容无法保证准确性、易被误导,项目方不承担由此产生的数据安全、舆情风险或滥用责任。官方项目团队未基于 ChatGLM2-6B 开发任何网页端、安卓、苹果 iOS 及 Windows App 应用。

评测结果:MMLU / C-Eval / GSM8K / BBH

官方选取了中英文典型数据集进行评测,包括 MMLU(英文)、C-Eval(中文)、GSM8K(数学)、BBH(英文)。Chat 版本使用 zero-shot CoT(Chain-of-Thought)评测,Base 版本使用 few-shot answer-only 评测。

MMLU(英文综合)

Model Average STEM Social Sciences Humanities Others
ChatGLM-6B 40.63 33.89 44.84 39.02 45.71
ChatGLM2-6B (base) 47.86 41.20 54.44 43.66 54.46
ChatGLM2-6B 45.46 40.06 51.61 41.23 51.24

C-Eval(中文综合)

Model Average STEM Social Sciences Humanities Others
ChatGLM-6B 38.9 33.3 48.3 41.3 38.0
ChatGLM2-6B (base) 51.7 48.6 60.5 51.3 49.8
ChatGLM2-6B 50.1 46.4 60.4 50.6 46.9

GSM8K(数学推理)

Model Accuracy Accuracy (Chinese)*
ChatGLM-6B 4.82 5.85
ChatGLM2-6B (base) 32.37 28.95
ChatGLM2-6B 28.05 20.45

所有版本均使用 few-shot CoT 评测,CoT prompt 来自 http://arxiv.org/abs/2201.11903;\* 行为使用翻译 API 翻译 GSM8K 中 500 道题目与对应 CoT prompt 并人工校对后的结果。

BBH(英文推理)

Model Accuracy
ChatGLM-6B 18.73
ChatGLM2-6B (base) 33.68
ChatGLM2-6B 30.00

所有版本均使用 few-shot CoT 评测,CoT prompt 来自 https://github.com/suzgunmirac/BIG-Bench-Hard/tree/main/cot-prompts

复现 C-Eval 评测

仓库 evaluation 目录提供了在 C-Eval 上进行评测的脚本,可以自行复现验证:先从清华云盘下载处理好的 C-Eval 数据集并解压到 evaluation 目录,然后运行:

cd evaluation
python evaluate_ceval.py

脚本会在 C-Eval 验证集上预测并输出准确率。如需得到测试集结果,可将 evaluate_ceval.py 中的 ./CEval/val/**/*.jsonl 改为 ./CEval/test/**/*.jsonl,按 C-Eval 规定格式保存结果并在官网提交。官方说明中指出,汇报结果使用内部并行测试框架,结果可能有轻微波动。

推理效率与显存占用分析

生成速度对比(Multi-Query Attention)

ChatGLM2-6B 采用 Multi-Query Attention 提升生成速度,官方实现下生成 2000 个 token 的平均速度对比如下:

Model Inference Speed (tokens/s)
ChatGLM-6B 31.49
ChatGLM2-6B 44.62

测试条件:官方实现,batch size = 1,max length = 2048,bf16 精度,硬件为 A100-SXM-80G,软件环境为 PyTorch 2.0。

KV Cache 优化与低显存推理

Multi-Query Attention 同时降低了生成过程中 KV Cache 的显存占用。此外,ChatGLM2-6B 采用 Causal Mask 进行对话训练,连续对话时可复用前面轮次的 KV Cache,进一步优化显存占用。因此,使用 6GB 显存显卡进行 INT4 量化推理时,初代 ChatGLM-6B 最多生成 1119 个 token 就会显存耗尽,而 ChatGLM2-6B 可生成至少 8192 个 token:

Quantization Encoding 2048 Tokens Decoding 8192 Tokens
FP16 / BF16 13.1 GB 12.8 GB
INT8 8.2 GB 8.1 GB
INT4 5.5 GB 5.1 GB

实现细节:ChatGLM2-6B 利用 PyTorch 2.0 引入的 torch.nn.functional.scaled_dot_product_attention 实现高效 Attention 计算;如果 PyTorch 版本较低,会 fallback 到朴素 Attention 实现,显存占用可能高于上表数值。这也是文档与 requirements.txt 均推荐 torch>=2.0 的原因。

量化对性能的影响

官方还测试了量化对模型性能的影响,结果表明量化带来的性能损失在可接受范围内:

Quantization Accuracy (MMLU) Accuracy (C-Eval dev)
BF16 45.47 53.57
INT4 43.13 50.30

环境安装与代码调用

环境准备

首先克隆本仓库并安装依赖:

git clone https://github.com/THUDM/ChatGLM2-6B
cd ChatGLM2-6B
pip install -r requirements.txt

requirements.txt 的完整依赖包括 transformers==4.30.2、torch>=2.0、protobuf、cpm_kernels、gradio、mdtex2html、sentencepiece、accelerate、sse-starlette、streamlit>=1.24.0。官方建议 transformers 使用 4.30.2、torch 使用 2.0 及以上版本以获得最佳推理性能。

代码调用生成对话

使用 HuggingFace Transformers 的 AutoTokenizer 与 AutoModel 即可加载模型并对话(需要 trust_remote_code=True 以信任模型仓库中的自定义代码):

>>> from transformers import AutoTokenizer, AutoModel
>>> tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True)
>>> model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True, device='cuda').eval()
>>> response, history = model.chat(tokenizer, "你好", history=[])
>>> print(response)
你好👋!我是人工智能助手 ChatGLM2-6B,很高兴见到你,欢迎问我任何问题。
>>> response, history = model.chat(tokenizer, "晚上睡不着应该怎么办", history=history)
>>> print(response)
晚上睡不着可能会让你感到焦虑或不舒服,但以下是一些可以帮助你入睡的方法:

1. 制定规律的睡眠时间表:保持规律的睡眠时间表可以帮助你建立健康的睡眠习惯,使你更容易入睡。尽量在每天的相同时间上床,并在同一时间起床。
2. 创造一个舒适的睡眠环境:确保睡眠环境舒适,安静,黑暗且温度适宜。可以使用舒适的床上用品,并保持房间通风。
3. 放松身心:在睡前做些放松的活动,例如泡个热水澡,听些轻柔的音乐,阅读一些有趣的书籍等,有助于缓解紧张和焦虑,使你更容易入睡。
4. 避免饮用含有咖啡因的饮料:咖啡因是一种刺激性物质,会影响你的睡眠质量。尽量避免在睡前饮用含有咖啡因的饮料,例如咖啡,茶和可乐。
5. 避免在床上做与睡眠无关的事情:在床上做些与睡眠无关的事情,例如看电影,玩游戏或工作等,可能会干扰你的睡眠。
6. 尝试呼吸技巧:深呼吸是一种放松技巧,可以帮助你缓解紧张和焦虑,使你更容易入睡。试着慢慢吸气,保持几秒钟,然后缓慢呼气。

如果这些方法无法帮助你入睡,你可以考虑咨询医生或睡眠专家,寻求进一步的建议。

model.chat() 每次返回 (response, history),把 history 回传给下一次调用即可实现多轮对话。模型的实现仍在变动中,若希望固定模型实现以保证兼容性,可在 from_pretrained 调用中加入 revision="v1.0" 参数(v1.0 为当前最新版本号,完整版本列表参见模型的 HuggingFace Change Log)。

从本地加载模型

以上代码会由 transformers 自动下载模型实现与参数。网络环境较差时下载可能较慢甚至失败,可先下载到本地再从本地加载。先安装 Git LFS,然后:

git clone https://huggingface.co/THUDM/chatglm2-6b

若只想先下载模型实现(跳过 LFS 大文件),可运行:

GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/THUDM/chatglm2-6b

再从清华云盘手动下载模型参数文件并替换到本地 chatglm2-6b 目录。下载完成后,将代码中的 THUDM/chatglm2-6b 替换为本地文件夹路径即可:

model = AutoModel.from_pretrained("your local path", trust_remote_code=True).eval()

交互式 Demo:Web 版与命令行版

Web 版 Demo(Gradio)

安装 Gradio 后运行仓库中的 web_demo.py:

python web_demo.py

程序会运行一个 Web Server 并输出地址,在浏览器中打开即可使用。从源码看,web_demo.py 基于 gr.Blocks() 构建界面,提供 Maximum length(0~32768,默认 8192)、Top P(默认 0.8)、Temperature(默认 0.95)三个可调参数,并支持多显卡加载(注释中给出了改用 utils.py 中 load_model_on_gpus 的示例)。界面渲染上,它覆写了 gr.Chatbot.postprocess 使用 mdtex2html 做 Markdown/LaTeX 转换,并通过 parse_text 将输出中的代码块转为 HTML 高亮展示。

Streamlit 版 Demo

仓库还提供基于 Streamlit 的 web_demo2.py,运行方式:

streamlit run web_demo2.py

官方实测表明基于 Streamlit 的网页版 Demo 会更流畅。

命令行 Demo

运行 cli_demo.py:

python cli_demo.py

程序在命令行中进行交互式对话:输入指令并回车即可生成回复,输入 clear 清空对话历史,输入 stop 终止程序。从源码实现看,cli_demo.py 使用 model.stream_chat(..., return_past_key_values=True) 流式输出,并通过 past_key_values 跨轮次复用 KV Cache(正是上文 Causal Mask + KV Cache 复用的实际落地);它还支持 Ctrl+C 中断当前流式输出(signal_handler 设置 stop_stream 标志位)。

API 部署:FastAPI 与 OpenAI 兼容接口

基础 FastAPI 接口

安装额外依赖后运行仓库中的 api.py:

pip install fastapi uvicorn
python api.py

默认部署在本地 8000 端口,通过 POST 方法调用:

curl -X POST "http://127.0.0.1:8000" \
     -H 'Content-Type: application/json' \
     -d '{"prompt": "你好", "history": []}'

返回值为:

{
  "response":"你好👋!我是人工智能助手 ChatGLM2-6B,很高兴见到你,欢迎问我任何问题。",
  "history":[["你好","你好👋!我是人工智能助手 ChatGLM2-6B,很高兴见到你,欢迎问我任何问题。"]],
  "status":200,
  "time":"2023-03-23 21:38:40"
}

从 api.py 源码看,接口支持 prompt、history、max_length(默认 2048)、top_p(默认 0.7)、temperature(默认 0.95)五个字段;每次请求后调用 torch_gc() 主动清空 CUDA 缓存并执行 ipc_collect,避免长期服务显存碎片堆积;启动时通过 uvicorn.run(app, host='0.0.0.0', port=8000, workers=1) 监听所有网卡。

OpenAI 兼容的流式 API

仓库还提供了 OpenAI 格式的流式 API 部署脚本 openai_api.py(感谢 @hiyouga 实现),可作为任意基于 ChatGPT 的应用后端(例如 ChatGPT-Next-Web):

python openai_api.py

它实现了 /v1/models 与 /v1/chat/completions 两个 OpenAI 兼容端点,支持 stream=True 的 SSE(Server-Sent Events)流式输出(依赖 requirements.txt 中的 sse-starlette),并内置 CORS 中间件方便前端跨域调用。调用示例:

import openai
if __name__ == "__main__":
    openai.api_base = "http://localhost:8000/v1"
    openai.api_key = "none"
    for chunk in openai.ChatCompletion.create(
        model="chatglm2-6b",
        messages=[
            {"role": "user", "content": "你好"}
        ],
        stream=True
    ):
        if hasattr(chunk.choices[0].delta, "content"):
            print(chunk.choices[0].delta.content, end="", flush=True)

注意:从 openai_api.py 源码看,/v1/models 返回的 model id 为 gpt-3.5-turbo(用于兼容 ChatGPT 生态的客户端校验),实际调用时 model 字段可传任意值。流式输出以 [DONE] 标记结束。

低成本部署:量化、CPU、Mac 与多卡方案

模型量化

默认情况下模型以 FP16 精度加载,运行需要约 13GB 显存。显存有限时可使用量化加载(支持 4/8 bit):

# 根据硬件调整,当前仅支持 4/8 bit 量化
model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True).quantize(8).cuda()

量化会带来一定性能损失,但官方实测表明 4-bit 量化下模型仍能自然流畅地生成(参考上文"量化对性能的影响"表格)。更简单的方式是直接加载官方发布的 INT4 量化模型 THUDM/chatglm2-6b-int4:

model = AutoModel.from_pretrained("THUDM/chatglm2-6b-int4", trust_remote_code=True).cuda()

CPU 部署

没有 GPU 时也可在 CPU 上推理,但速度更慢,且需要约 32GB 内存:

model = AutoModel.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True).float()

内存不足时也可以使用量化后的模型:

model = AutoModel.from_pretrained("THUDM/chatglm2-6b-int4", trust_remote_code=True).float()

在 CPU 上运行量化模型需要安装 gcc 与 openmp(多数 Linux 发行版默认已安装;Windows 可安装 TDM-GCC 并勾选 openmp;MacOS 参考 FAQ.md 的 Q1)。

Mac(Apple Silicon)部署

搭载 Apple Silicon 或 AMD GPU 的 Mac 可使用 MPS 后端在 GPU 上运行模型。需参考 Apple 官方说明安装 PyTorch-Nightly(正确版本号应为 2.x.x.dev2023xxxx 形式,而非 2.x.x 稳定版)。目前在 MacOS 上仅支持从本地加载模型:

model = AutoModel.from_pretrained("your local path", trust_remote_code=True).to('mps')

加载 FP16 模型需要约 13GB 内存;内存较小的机器(如 16GB MacBook Pro)在空余内存不足时会使用硬盘虚拟内存,导致推理速度严重变慢,此时可改用 chatglm2-6b-int4 量化模型。需要注意:量化 kernel 基于 CUDA 编写,无法在 MacOS 的 GPU 上使用,只能回退到 CPU 推理,并需单独安装 OpenMP 以充分利用 CPU 并行(见 FAQ.md)。Mac 上推理也可使用社区方案 ChatGLM.cpp。

多卡部署

多张 GPU 且单卡显存不足时,可将模型切分到多张 GPU。首先安装 accelerate:

pip install accelerate

然后从 utils.py 导入 load_model_on_gpus 加载模型:

from utils import load_model_on_gpus
model = load_model_on_gpus("THUDM/chatglm2-6b", num_gpus=2)

num_gpus 可改为期望使用的 GPU 数量;默认均匀切分,也可传入 device_map 参数自定义分配。从 utils.py 源码可以看到切分逻辑:模型共 30 层(word_embeddings、final_layernorm、lm_head、rotary_pos_emb 各占 1 层 + 28 个 encoder layer),auto_configure_device_map 会按 GPU 数自动把 28 个 transformer.encoder.layers.{i} 均匀分配到各卡;同时将 word_embeddings、final_layernorm、lm_head 都放在第一张卡上,以避免 Linux 下 model.device(指向 lm_head.device)与 word_embeddings.device 不一致引发的 RuntimeError。切分后通过 accelerate 的 dispatch_model 完成跨卡分发。

进阶:P-Tuning v2 与全参数微调

自 2023/07/04 起,仓库提供了对 ChatGLM2-6B 的 P-Tuning v2 与全参数微调脚本,位于 ptuning 目录。P-Tuning v2 将需要微调的参数量减少到原来的 0.1%,配合模型量化与 Gradient Checkpoint,最低只需 7GB 显存即可运行微调。

安装依赖与准备数据

除基础依赖外,还需安装:

pip install rouge_chinese nltk jieba datasets

以 ADGEN(广告生成)数据集为例:任务是根据输入 content 生成一段广告词 summary,数据格式为:

{
    "content": "类型#上衣*版型#宽松*版型#显瘦*图案#线条*衣样式#衬衫*衣袖型#泡泡袖*衣款式#抽绳",
    "summary": "这件衬衫的款式非常的宽松,利落的线条可以很好的隐藏身材上的小缺点,穿在身上有着很好的显瘦效果。领口装饰了一个可爱的抽绳,漂亮的绳结展现出了十足的个性,配合时尚的泡泡袖型,尽显女性甜美可爱的气息。"
}

训练与推理

P-Tuning v2 训练直接运行:

bash train.sh

train.sh 中的 PRE_SEQ_LEN(soft prompt 长度)与 LR(学习率)可以调节。P-Tuning v2 冻结全部模型参数,可通过 quantization_bit 调整原始模型的量化等级(不加该选项则为 FP16 加载)。默认配置(quantization_bit=4、per_device_train_batch_size=1、gradient_accumulation_steps=16)下,INT4 模型参数被冻结,一次训练迭代以 1 的批大小进行 16 次累加的前后向传播,等效总批大小为 16,最低只需约 6.7G 显存。若要保持等效批大小并提升训练效率,可在二者乘积不变的前提下增大 per_device_train_batch_size(会带来更多显存消耗)。

全参数 Finetune 需要安装 Deepspeed 后运行:

bash ds_train_finetune.sh

推理时,P-Tuning v2 训练只保存 PrefixEncoder 部分参数,因此需同时加载原 ChatGLM2-6B 模型与 PrefixEncoder 权重,在 evaluate.sh 中指定:

--model_name_or_path THUDM/chatglm2-6b
--ptuning_checkpoint $CHECKPOINT_PATH

评测指标为中文 Rouge score 和 BLEU-4,生成结果保存在 ./output/adgen-chatglm2-6b-pt-128-2e-2/generated_predictions.txt。从 trainer.py 源码可以看到,PrefixTrainer 在 save_changed=True 时会只保存 requires_grad=True 的 PrefixEncoder 参数,这正是"微调后仅需加载小体积 checkpoint"的实现基础。

协议与引用

本仓库代码依照 Apache-2.0 协议开源,ChatGLM2-6B 模型权重的使用遵循 Model License:权重对学术研究完全开放,在填写问卷登记后亦允许免费商业使用。

如果相关工作对你有帮助,可引用官方论文(BibTeX 条目参见 README.md 与 README_EN.md 的 Citation 部分):

@misc{glm2024chatglm,
      title={ChatGLM: A Family of Large Language Models from GLM-130B to GLM-4 All Tools},
      author={Team GLM and ...},
      year={2024},
      eprint={2406.12793},
      archivePrefix={arXiv},
      primaryClass={cs.CL}
}

总结

ChatGLM2-6B 通过 GLM 混合目标函数预训练、FlashAttention 长上下文、Multi-Query Attention 高效推理三大技术升级,在中英双语对话、数学推理与长对话场景下提供了高于同尺寸模型的性价比。本文覆盖了从环境搭建、代码调用、Gradio/Streamlit/CLI 三套 Demo、FastAPI 与 OpenAI 兼容 API,到量化、CPU、Mac、多卡等低成本部署方案,以及 P-Tuning v2 微调与 C-Eval 评测复现的完整链路。所有关键结论均有仓库源码(api.py、cli_demo.py、utils.py、web_demo.py、ptuning、evaluation)与官方文档佐证,你可以直接参照上述命令在本机实践。

登录后查看全文
ChatGLM2-6B-code