news 2026/9/8 16:10:59

Transformers 原生集成 GLM-4:模型架构解读、GlmConfig 配置与 glm-4-9b-chat 推理实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Transformers 原生集成 GLM-4:模型架构解读、GlmConfig 配置与 glm-4-9b-chat 推理实战

Transformers 原生集成 GLM-4:模型架构解读、GlmConfig 配置与 glm-4-9b-chat 推理实战

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

本文以 Hugging Face Transformers 官方文档 docs/source/en/model_doc/glm.md 为骨架,结合本仓库src/transformers/models/glm/下的真实实现,系统讲解 GLM-4 系列模型在 Transformers 中的架构设计、GlmConfig全部关键参数,以及如何基于 ChatML 格式完成glm-4-9b-chat的加载与生成推理。读完本文,你将掌握 GLM-4 的源码组织结构、逐参数配置方法,以及一套可直接运行的对话推理代码。

GLM-4 是什么:从 ChatGLM 家族到本次集成

glm.md明确说明:GLM-4 由THUDM 与智谱 AI(ZhipuAI)团队在论文ChatGLM: A Family of Large Language Models from GLM-130B to GLM-4 All Tools(发布于 2024-06)中提出,本仓库于 2024-10 完成社区集成。

根据论文摘要,ChatGLM 是一个持续迭代的大语言模型家族,报告重点围绕 GLM-4 系列展开,包含GLM-4、GLM-4-Air、GLM-4-9B等版本,它们在超过 10 万亿 token 的中英文为主语料(外加 24 种语言的小规模语料)上完成预训练,并通过"监督微调 + 人类反馈学习"的多阶段后训练实现高质量对齐。GLM-4 All Tools 进一步对齐了工具调用能力(网页浏览、Python 解释器、文生图模型与用户自定义函数)。文档同时提到该系列已开源包括 ChatGLM-6B(三代)、GLM-4-9B(128K、1M 上下文版本)、GLM-4V-9B、WebGLM、CodeGeeX 等模型。

在本仓库语境下,GLM-4 并非"远程代码(remote code)"式接入,而是拥有完整原生实现:模型代码位于 src/transformers/models/glm/modeling_glm.py,配置类位于 src/transformers/models/glm/configuration_glm.py,同时配套权重转换脚本 src/transformers/models/glm/convert_glm_weights_to_hf.py 与完整测试套件 tests/models/glm/test_modeling_glm.py。

从代码生成方式看,modeling_glm.py由 src/transformers/models/glm/modular_glm.py 自动生成——文件头部有明确的 "Do NOT edit this file manually" 告警。该 modular 文件显示,GLM-4 的实现大量复用 Llama 与 Phi-3 的既有代码骨架GlmMLP直接继承自Phi3MLPGlmForCausalLMGlmForSequenceClassificationGlmForTokenClassification分别继承自 Llama 的对应类,仅注意力模块与 RoPE 旋转位置编码做了定制。这也意味着 GLM-4 的推理体验与行为会与这些成熟架构高度一致。

架构核心:基于 GQA + 部分旋转 RoPE 的稠密解码器

阅读 modeling_glm.py 的源码,GLM-4 是一个仅解码器(decoder-only)的自回归稠密模型,逐层结构如下:

embed_tokens(词嵌入) → 40 × GlmDecoderLayer → GlmRMSNorm →(可选 lm_head)

每个GlmDecoderLayer(见 modeling_glm.py#L295-L335)采用Pre-Norm + 残差结构:

  1. input_layernorm归一化 → 多头自注意力;
  2. 残差相加;
  3. post_attention_layernorm归一化 →GlmMLP
  4. 残差相加。

GQA 分组查询注意力与偏置细节

GlmAttention(modeling_glm.py#L209-L271)实现了标准 GQA(Grouped-Query Attention):查询头数为num_attention_heads,而键/值头数仅为num_key_value_heads(默认 2),num_key_value_groups = num_attention_heads // num_key_value_heads;推理时通过repeat_kv(modeling_glm.py#L125-L134)把 KV 头复制回全量头数再计算注意力。

与常见 Llama 变体不同的是:GLM-4 的q_proj/k_proj/v_proj投影层携带 bias(由config.attention_bias控制,默认True),而o_proj与 MLP 投影均无 bias。eager_attention_forward(modeling_glm.py#L137-L159)在 fp32 上做 softmax 以提升数值稳定性。

SwiGLU 门控 MLP 与分段写法

GlmMLP(modeling_glm.py#L48-L63)采用 SwiGLU 门控结构:单个gate_up_proj把隐层映射到2 * intermediate_size,然后chunk(2, dim=-1)拆成 gate 与 up 两路,乘以 SiLU 激活后由down_proj投影回hidden_size。官方配置中intermediate_size=13696,而GlmConfig的 TP(张量并行)计划为此特别标注了 "我们因chunk操作需要复制/切分输入输出" 的注释(见 configuration_glm.py#L42-L49)。

RMSNorm 与部分旋转 RoPE

GlmRMSNorm(modeling_glm.py#L274-L292)是无偏置的均方根归一化,计算在 fp32 下完成,参数rms_norm_eps默认取1.5625e-7

GLM-4 RoPE 最独特的点在于partial rotary(部分旋转)compute_default_rope_parameters(modeling_glm.py#L86-L104)先以head_dim * partial_rotary_factor计算实际参与旋转的维度,partial_rotary_factor默认0.5(见GlmConfig.__post_init__kwargs.setdefault("partial_rotary_factor", 0.5),configuration_glm.py#L76-L80),即每个注意力头的 128 维中仅前 64 维注入位置信息。配套的apply_rotary_pos_emb(modeling_glm.py#L169-L206)使用**交错(interleave)而非拼接(concat)**的旋转排列,并把张量切成 rot/pass 两段,只对前段做旋转后拼接还原。这与 GlmRotaryEmbedding 中 "Interleave them instead of usual shape" 的注释一致。

GlmConfig 参数速查:默认值与设计含义

GlmConfig(model_type 为glm)继承自PreTrainedConfig。以官方发布配置(对应THUDM/glm-4-9b-chat检查点)为准,全部核心字段及默认值如下表:

参数默认值含义
vocab_size151552词表大小
hidden_size4096隐藏层维度
intermediate_size13696MLP 中间维度
num_hidden_layers40解码器层数
num_attention_heads32查询头数
num_key_value_heads2KV 头数(GQA 压缩)
head_dim128每头维度
hidden_act"silu"激活函数
attention_dropout0.0注意力 dropout
max_position_embeddings131072最大序列长度(128K)
initializer_range0.02参数初始化范围
rms_norm_eps1.5625e-7RMSNorm 数值稳定项
use_cacheTrue是否缓存 KV
tie_word_embeddingsFalse是否共享词嵌入与 LM 头
rope_parametersNoneRoPE 超参字典
pad_token_id151329pad token
eos_token_idNone→ 由__post_init__设为[151329, 151336, 151338]EOS 序列
bos_token_idNoneBOS(对话首 token 由 ChatML 模板处理)
attention_biasTrueQ/K/V 投影是否带 bias

需要特别注意的运行时行为(全部有源码可查):

  • 多 EOS__post_init__中当eos_token_id未显式指定时,会被替换为三个 token[151329, 151336, 151338](configuration_glm.py#L78-L80),这是 GLM-4 使用 ChatML 多终止符的特性;
  • partial rotary 默认值兜底:为了向后兼容,__post_init__会自动补上partial_rotary_factor=0.5
  • 推理忽略键keys_to_ignore_at_inference = ["past_key_values"],确保past_key_values不会随输出一起被序列化(configuration_glm.py#L41)。

实战:加载 glm-4-9b-chat 并进行对话推理

文档给出了最简洁的推理入口——使用AutoModelForCausalLM+AutoTokenizer加载官方对话模型THUDM/glm-4-9b-chat。GLM-4 对话使用ChatML 消息格式(含system/user/assistant角色与专用终止符),正确做法是借助分词器的apply_chat_template自动组装提示词,而不是手工拼接模板。

下面这段代码完整继承自glm.md,并做了最小必要补充以保证可直接运行(同样适用于单卡、多卡场景):

from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained("THUDM/glm-4-9b-chat", device_map="auto", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained("THUDM/glm-4-9b-chat") prompt = "Give me a short introduction to large language model." messages = [{"role": "user", "content": prompt}] # 用 ChatML 模板生成带生成标记的完整文本 text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) model_inputs = tokenizer([text], return_tensors="pt").to(model.device) generated_ids = model.generate(model_inputs.input_ids, max_new_tokens=512, do_sample=True) # 去掉输入前缀,只保留新生成的 token generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] print(response)

几个可以按需调整的关键点:

  • max_new_tokens=512限制本次新生成的最大 token 数;do_sample=True开启随机采样,若需要确定性输出可改do_sample=False
  • device_map="auto"会在多 GPU 环境中自动做层切分;trust_remote_code=True用于兜底加载 Hub 上的辅助配置代码;
  • 多轮对话只需不断向messages追加assistant与新的user消息后重新apply_chat_template即可。

若想跳过对话模板、以"纯文本续写"方式测试模型,可参考GlmForCausalLMdocstring 中演示的简单流程(modeling_glm.py#L461-L477):

from transformers import AutoTokenizer, GlmForCausalLM model = GlmForCausalLM.from_pretrained("meta-glm/Glm-2-7b-hf") tokenizer = AutoTokenizer.from_pretrained("meta-glm/Glm-2-7b-hf") prompt = "Hey, are you conscious? Can you talk to me?" inputs = tokenizer(prompt, return_tensors="pt") generate_ids = model.generate(inputs.input_ids, max_length=30) tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]

四种面向任务的入口:从因果 LM 到序列标注

glm.md的 autodoc 区块共列出四类可实例化的 API,本仓库中对应类均在 modeling_glm.py 中导出:

用途实现要点(源码依据)
GlmModel基础解码器,输出隐状态embed_tokens+ 40 层GlmDecoderLayer+ 末尾GlmRMSNorm+GlmRotaryEmbedding构成(modeling_glm.py#L357-L428)
GlmForCausalLM对话 / 文本生成,返回词表 logits额外带无 bias 的lm_head,支持labels计算交叉熵损失(modeling_glm.py#L431-L503)
GlmForSequenceClassification整句分类(情感等)GenericForSequenceClassification泛型混入类(modeling_glm.py#L506-L507)
GlmForTokenClassification序列标注(NER 等)GenericForTokenClassification泛型混入类(modeling_glm.py#L510-L511)

高效生成相关的实现细节

  • logits 裁剪GlmForCausalLM.forward接收logits_to_keep(默认 0),仅对最后若干位置计算 LM logits,显著降低长上下文下的显存与算力开销(modeling_glm.py#L490-L491);
  • 词嵌入独立tie_word_embeddings默认False,即lm_head为独立权重;不过_tied_weights_keys仍登记了与embed_tokens的映射关系,方便用户自行开启权重绑定(modeling_glm.py#L433)。

特性支持矩阵与并行方案:FlashAttention、SDPA 与 TP/PP

glm.md页首的徽章标明了 GLM-4 集成支持 FlashAttention、SDPA 与张量并行,这与源码中的能力声明完全对应:

  • GlmPreTrainedModel声明了_supports_flash_attn = True_supports_sdpa = True_supports_flex_attn = True,并支持_can_compile_fullgraph全图编译与梯度检查点(supports_gradient_checkpointing = True,modeling_glm.py#L338-L354);
  • 注意力实现通过ALL_ATTENTION_FUNCTIONS.get_interface(config._attn_implementation, eager_attention_forward)统一分发(modeling_glm.py#L254-L256),因此可在from_pretrained时通过attn_implementation="flash_attention_2" / "sdpa" / "eager"切换后端;
  • 张量并行(TP)计划base_model_tp_plan描述 Q/K/V 投影做colwiseo_projrowwise、MLP 因chunk语义做colwise_gather_output/rowwise_split_input的切分策略(configuration_glm.py#L42-L49);
  • 流水线并行(PP)计划base_model_pp_plan给出embed_tokenslayersnorm各阶段输入输出张量的交接约定(configuration_glm.py#L50-L54);
  • _no_split_modules = ["GlmDecoderLayer"]让层内不跨设备切分,是 device_map 自动分层的依据。

回归验证:集成测试在做什么

仓库用 tests/models/glm/test_modeling_glm.py 保证实现的正确性,其中有两层测试值得关注:

  1. 通用小模型测试GlmModelTester/GlmModelTest复用仓库统一的CausalLMModelTest体系做大规模随机化前向/梯度测试,并强制attention_dropout = 0.0——测试注释说明这是为了兼容 TP 反向传播测试的 RNG 一致性(test_modeling_glm.py#L41-L57);
  2. 慢速集成测试(@slow):以THUDM/glm-4-9b(revisionrefs/pr/15)为基准,分别以 fp16 / bf16 / eager / sdpa / flash_attention_2 后端跑generate,并断言 batch 解码文本与期望输出逐字一致(test_modeling_glm.py#L59-L183)。

这说明四种注意力后端在 GLM-4 上被持续验证为输出一致,是你在生产环境切换attn_implementation时的可靠性依据。

小结与延伸阅读

一句话概括本仓库的 GLM-4 集成:以 Llama 解码器骨架为基座,叠加 GLM 特有的 128K 上下文、ChatML 三终止符、GQA 与"前 64 维参与旋转"的部分 RoPE 与带 bias 注意力,并通过 modular 机制统一维护。

如果你想继续深挖,推荐按以下路径阅读当前仓库:

  • 配置全文:src/transformers/models/glm/configuration_glm.py
  • 模型主实现:src/transformers/models/glm/modeling_glm.py
  • 复用了哪些 Llama/Phi-3 骨架:src/transformers/models/glm/modular_glm.py
  • 官方 checkpoint 到 HF 格式的权重转换:src/transformers/models/glm/convert_glm_weights_to_hf.py
  • 各注意力后端回归测试:tests/models/glm/test_modeling_glm.py

以上内容均以docs/source/en/model_doc/glm.md为主线整理,参数默认值与行为细节均可通过上述源码文件核对,可放心作为二次开发与模型部署的参考资料。

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 16:10:35

腾讯云AI Skills实战:从工具调用到Agent高效编排的最佳实践

做 Agent 开发这一年多,我最大的感受是:真正让项目“活”起来的往往不是模型本身,而是工具调用这一层。模型再聪明,如果它不知道你的业务接口怎么用、不知道参数该传什么、返回结构一变化就没法处理,整个 Agent 就卡死…

作者头像 李华
网站建设 2026/9/8 16:10:03

单片机毕业设计-基于 STM32 的多生理体征声光语音报警终端设计 基于 STM32 的便携式人体健康监测设备设计与开发(013207)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/8 16:09:57

P3366最小生成树模板题详解:Kruskal与Prim实现与边界处理

1. 先看懂题目信息:P3366 究竟想让你做什么 1.1 题面信息剥开之后只剩一件事 洛谷P3366【模板】最小生成树,大概是很多算法竞赛选手写的第一道带“模板”标签的图论题。页面上的题目信息非常干净:给出一张无向图,有N个点&#xf…

作者头像 李华
网站建设 2026/9/8 16:08:32

Java 后端转 AI Agent 开发:2026 年学习清单与面试高频考点

第一章 先想明白:你转的到底是 "AI 开发" 还是 "Agent 工程" 很多 Java 后端第一次接触 AI,会把三件事混成一件事:调用大模型、RAG、Agent。这三者的技术含量和面试含金量差着好几个等级,混着学的人最后往往什么都学不深。 调用大模型是最底层的东西。…

作者头像 李华