☰
H2O LLM Studio 因果分类实验摘要卡模板详解:classification_head.pth 与 transformers 分类推理
2026/10/13 7:43:01 网站建设 项目流程
  • 微调
  • 大模型
  • AI 应用

【免费下载链接】h2o-llmstudio

H2O LLM Studio - a framework and no-code GUI for fine-tuning LLMs. Documentation: https://docs.h2o.ai/h2o-llmstudio/

项目地址:https://gitcode.com/gh_mirrors/h2/h2o-llmstudio
点击查看免费下载

在 H2O LLM Studio 中完成一个text_causal_classification_modeling实验后,系统会在实验详情页自动渲染一张"摘要代码卡",告诉使用者如何把微调结果部署回 Hugging Face Hub 并用transformers库做分类推理。本文围绕仓库中的模板文件 text_causal_classification_experiment_summary_card_template.md 展开,完整继承模板中的安装、登录、权重下载与推理代码,并结合源码解析模板变量如何被填充、classification_head.pth从何而来、以及分类头在模型前向中的具体作用,帮助读者把一份因果分类实验的产物完整落地到生产环境。

一、模板定位:实验详情页的"摘要代码卡"

这份模板并不是独立文档,而是一套按问题类型区分的实验摘要卡(summary card)模板之一。在配置类 text_causal_classification_modeling_config.py 中可以看到它与问题类型的绑定关系:

_model_card_template: str = "text_causal_classification_model_card_template.md" _summary_card_template: str = ( "text_causal_classification_experiment_summary_card_template.md" )

也就是说,当实验的problem_type为text_causal_classification_modeling时,两个模板各司其职:

  • 模型卡模板(text_causal_classification_model_card_template.md):推送模型到 Hugging Face 时由huggingface_hub.ModelCard.from_template渲染,作为仓库里的README展示,其生成逻辑位于 hugging_face_utils.py;
  • 摘要卡模板(即本文主角):由 experiment.py 中的get_experiment_summary_code_card(cfg)函数渲染,作为代码卡展示在实验详情页的 UI 中(见 experiment.py 中q.page["experiment/display/summary/code"]的 markdown 卡片)。

两者共享同一段"Usage with HF transformers"使用说明,因此理解本文模板,也就同时理解了推送出去的模型卡里那部分内容的含义。

二、模板全文继承:从安装到分类推理

下面按模板原文顺序,逐段说明每个步骤的意图,并给出仓库源码中的对应证据。

2.1 第一步:通过 GUI 推送模型

模板开篇写道:要使用这份模型,先点击 GUI 中的Push checkpoint to huggingface按钮把模型推送到 Hugging Face 仓库。这一步的完整操作流程在官方文档 export-trained-model.md 中有图文说明(进入View experiments页面 → 点击实验名 → 点击Push checkpoint to huggingface→ 填写 Account name 与 API Key → Export)。

从源码看,这个按钮最终调用 publish_model_to_hugging_face,它会依次上传:

  1. tokenizer(tokenizer.push_to_hub,且对生成类问题类型会写入 chat template);
  2. 渲染好的模型卡(get_model_card+card.push_to_hub);
  3. classification_head.pth——若实验目录中存在该文件,则单独上传到仓库根目录(hugging_face_utils.py);
  4. 完整的实验配置cfg.yaml(hugging_face_utils.py);
  5. 骨干网络权重(model.backbone.push_to_hub,默认safe_serialization=True)。

此外,若选择从 GUI下载模型而非推送,experiment_download_model打包 zip 时同样会把classification_head.pth、model_card.md等文件列入FILES_TO_PUSH(见 experiment.py)。因此无论哪条分发路径,分类头都会随模型一起到达最终使用方。

2.2 第二步:安装 transformers 并登录 Hugging Face

模板要求安装与训练时一致的 transformers 版本:

pip install transformers=={{transformers_version}}

其中{{transformers_version}}是占位符,渲染时被替换为当前环境的transformers.__version__(experiment.py)。

如果模型仓库是私有的(publish_model_to_hugging_face中push_to_hub(..., private=True)表明默认推送为私有仓库),则必须提供 Hugging Face token 登录:

import huggingface_hub huggingface_hub.login(<ACCESS_TOKEN>)

2.3 第三步:下载分类头classification_head.pth

这是因果分类模型区别于普通因果语言模型的关键:骨干网络只输出词表维度的 logits,真正的分类判据保存在一个独立的线性层里。模板给出下载方式:

from huggingface_hub import hf_hub_download model_name = "{{repo_id}}" # either local folder or Hugging Face model name hf_hub_download(repo_id=model_name, filename="classification_head.pth", local_dir="./")

{{repo_id}}渲染逻辑在 experiment.py:若实验目录中存在hf.yaml(推送成功时由 save_hf_yaml 写入),则读取其中的repo_id;否则回退为占位串"account/model",提示用户自行替换为真实的仓库路径或本地目录。

classification_head.pth本身从何而来?它由训练框架在保存 checkpoint 时从完整 state_dict 中拆出单独落盘:

if ( cfg.environment._local_rank == 0 and "classification_head.weight" in checkpoint["model"] ): torch.save( checkpoint["model"]["classification_head.weight"], os.path.join(path, "classification_head.pth"), )

见 modeling_utils.py。该权重对应的就是模型类中定义的分类头(text_causal_classification_modeling_model.py):

self.classification_head = nn.Linear( self.backbone_config.vocab_size, cfg.dataset.num_classes, bias=False )

即一个从vocab_size维映射到num_classes维、无偏置的线性层。

2.4 第四步:加载骨干与分类头,完成一次分类推理

模板给出的完整推理示例如下(保留模板占位符原貌,并逐行解释):

from transformers import AutoModelForCausalLM, AutoTokenizer import torch model_name = "{{repo_id}}" # either local folder or Hugging Face model name # Important: The prompt needs to be in the same format the model was trained with. # You can find an example prompt in the experiment logs. prompt = "{{text_prompt_start}}How are you?{{end_of_sentence}}{{text_answer_separator}}" tokenizer = AutoTokenizer.from_pretrained( model_name, trust_remote_code={{trust_remote_code}}, ) model = ( AutoModelForCausalLM.from_pretrained( model_name, torch_dtype="auto", device_map={"": "cuda:0"}, trust_remote_code={{trust_remote_code}}, ) .cuda() .eval() ) head_weights = torch.load("classification_head.pth", map_location="cuda") # settings can be arbitrary here as we overwrite with saved weights head = torch.nn.Linear(1, 1, bias=False).to("cuda") head.weight.data = head_weights inputs = tokenizer(prompt, return_tensors="pt", add_special_tokens=False).to("cuda") out = model(**inputs).logits logits = head(out[:, -1]) print(logits)

关键细节解读:

  • Prompt 必须与训练格式一致。{{text_prompt_start}}、{{end_of_sentence}}、{{text_answer_separator}}三个占位符分别渲染自cfg.dataset.text_prompt_start、tokenizer 的 EOS token(仅当cfg.dataset.add_eos_token_to_prompt为真,否则渲染为空串)、cfg.dataset.text_answer_separator(experiment.py)。这与 get_chat_template 生成的 chat template 遵循同一条拼接规则,因此模板中特别提醒"可在实验日志中查看示例 prompt"。
  • trust_remote_code渲染自cfg.environment.trust_remote_code,与训练时保持一致,避免使用自定义代码的骨干在加载时报错。
  • device_map={"": "cuda:0"}表示整模型放到第一块 GPU;模板在注释中也说明torch_dtype="auto"会沿用仓库config.json中的精度设置。模型卡模板中还额外提示了量化与多卡分片用法(load_in_8bit=True/load_in_4bit=True,device_map=auto),可按需替换。
  • 分类头加载的小技巧:torch.nn.Linear(1, 1, bias=False)只是一个"壳",通过head.weight.data = head_weights直接替换.data张量绕过了形状校验,因此无论分类头真实形状是(num_classes, vocab_size)的什么尺寸都能正确载入——这正是模板注释 "settings can be arbitrary here as we overwrite with saved weights" 的含义。
  • 取最后一个位置的 logits:head(out[:, -1])与训练前向完全一致。训练时同样只对序列末位的隐藏状态过分类头(text_causal_classification_modeling_model.py):
output = forward( self.backbone, input_ids=batch["prompt_input_ids"], attention_mask=batch["prompt_attention_mask"], ) output.logits = self.classification_head(output[0][:, -1].float())

因此推理输出是原始 logits,后续解释方式取决于训练时选择的损失函数。

三、logits 的解读:由损失函数决定后处理方式

仓库中因果分类支持的损失函数只有两种(text_causal_classification_modeling_losses.py):

损失函数底层实现约束条件对推理 logits 的解读
BinaryCrossEntropyLossnn.BCEWithLogitsLossnum_classes == 1单值 logit,取 sigmoid 得到正类概率(如 AUC 场景)
CrossEntropyLossnn.CrossEntropyLossnum_classes > 1多类 logits,取 argmax 得类别

约束条件由配置校验逻辑强制执行:CrossEntropyLoss requires num_classes > 1、BinaryCrossEntropyLoss requires num_classes == 1(text_causal_classification_modeling_config.py),num_classes本身取值范围为 1~100(text_causal_classification_modeling_config.py)。

由于BCEWithLogitsLoss内部自带 sigmoid,训练时 loss 直接吃裸 logits;推理时若需要概率值,用户需自行对输出做torch.sigmoid。这一点在模板的print(logits)处没有展开,但结合损失实现可以明确:模板输出的是未归一化的 logits。

官方文档对这类问题的描述见 supported-problem-types.md:因果分类建模用于"为输入文本分配一个或多个类别标签",支持二分类、多分类与多标签。

四、模板变量一览与渲染机制

get_experiment_summary_code_card采用简单的字符串替换完成渲染,本文模板涉及的占位符及其来源如下:

占位符来源(cfg 路径)说明
{{repo_id}}hf.yaml中的repo_id,缺省为account/modelHugging Face 仓库或本地目录
{{transformers_version}}transformers.__version__建议安装的 transformers 版本
{{text_prompt_start}}cfg.dataset.text_prompt_start用户输入前缀,如<\|prompt\|>
{{end_of_sentence}}cfg.tokenizer._tokenizer_eos_token(仅当add_eos_token_to_prompt)提示末尾是否追加 EOS
{{text_answer_separator}}cfg.dataset.text_answer_separator提示与"回答"的分隔符
{{trust_remote_code}}cfg.environment.trust_remote_code是否允许加载骨干自定义代码

值得注意的一个设计点:模板渲染函数还会为生成类问题类型替换{{max_new_tokens}}、{{temperature}}、{{do_sample}}等生成参数(experiment.py),但因果分类属于非生成类问题类型,因此本模板不含这些占位符——分类任务不做自回归生成,只需一次前向加一个线性头。这正是因果分类摘要卡与因果语言建模摘要卡(text_causal_language_modeling_experiment_summary_card_template.md)在结构上的本质区别。

五、结合集成测试配置验证实际用法

仓库的集成测试配置 test_causal_binary_classification_modeling_cfg.yaml 提供了一个真实可运行的二分类实验参数样例,可与本文的模板推理链路互相印证:

problem_type: text_causal_classification_modeling dataset: num_classes: 1 # 二分类 => 单列标签 answer_column: [binary_label] text_prompt_start: '' text_answer_separator: '' add_eos_token_to_prompt: false validation_strategy: automatic training: loss_function: BinaryCrossEntropyLoss lora: true differential_learning_rate_layers: [classification_head] # 分类头使用独立学习率 differential_learning_rate: 1.0e-05 prediction: metric: AUC # 二分类指标为 AUC environment: trust_remote_code: true

可以看到几个与模板直接相关的呼应:num_classes: 1配合BinaryCrossEntropyLoss满足前述校验约束;differential_learning_rate_layers显式把classification_head单列出来施加独立学习率,说明该头在训练中被视为需要单独调优的组件;评估指标使用AUC,与BCEWithLogitsLoss输出的裸 logits 语义一致。多分类/多标签的完整配置可参考 test_causal_multiclass_classification_modeling_cfg.yaml 与 test_causal_multilabel_classification_modeling_cfg.yaml。

六、实操要点小结

  1. 分发链路:GUI 的 Push 按钮 / 模型下载都会携带classification_head.pth与cfg.yaml,二者缺一不可——前者承载分类判据,后者记录全部训练配置(模型卡模板中也通过 cfg.yaml 链接引用它)。
  2. 推理只跑一次前向:与生成式用法不同,因果分类模型不需要model.generate(...),只需取logits[:, -1]过分类头,推理成本显著低于文本生成任务。
  3. 格式一致性:prompt 必须严格复刻text_prompt_start + 文本 + (EOS) + text_answer_separator的拼接顺序,示例可直接取自实验日志。
  4. logits 后处理:二分类做 sigmoid,多分类做 argmax;num_classes与损失函数的配对关系受配置校验强制约束。
  5. 私有仓库:默认推送为 private 仓库,下载骨干与classification_head.pth前需huggingface_hub.login(<ACCESS_TOKEN>)。

至此,从模板占位符到源码实现、从 checkpoint 落盘到 Hugging Face 分发、再到最终的 transformers 分类推理,text_causal_classification_modeling实验产物的完整使用闭环已经覆盖。读者可按本文路径直接对照仓库源码复核每一处结论。

  • 微调
  • 大模型
  • AI 应用

【免费下载链接】h2o-llmstudio

H2O LLM Studio - a framework and no-code GUI for fine-tuning LLMs. Documentation: https://docs.h2o.ai/h2o-llmstudio/

项目地址:https://gitcode.com/gh_mirrors/h2/h2o-llmstudio
点击查看免费下载

相关推荐

上一篇:Protobuf Python 运行时反射核心:google.protobuf.descriptor_pool 模块深度解析
下一篇:GoodbyeDPI 完整教程:Windows 上绕过 DPI 拦截被封锁网站

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询