Hugging Face Jobs 训练结果持久化:使用 TRL push_to_hub 与 HF_TOKEN 将模型安全保存至 Hub
2026/9/15 14:20:28 网站建设 项目流程

Hugging Face Jobs 训练结果持久化:使用 TRL push_to_hub 与 HF_TOKEN 将模型安全保存至 Hub

【免费下载链接】skillsGive your agents the power of the Hugging Face ecosystem项目地址: https://gitcode.com/GitHub_Trending/skills7/skills

导读

本文以 huggingface-llm-trainer 技能中的 hub_saving.md 为骨架,系统讲解在 Hugging Face Jobs 临时 GPU 环境上训练 LLM 时,如何通过push_to_hubhub_model_idsecrets={"HF_TOKEN": "$HF_TOKEN"}三件套确保训练产物永久落盘到 Hub。读完本文,你将掌握完整可复制的 SFT/DPO/GRPO 训练脚本模板、检查点保存策略、三种认证方式、仓库命名与创建规则,以及 401/403 等典型推送故障的排查思路。

为什么必须推送:临时环境没有本地持久化

Hugging Face Jobs 的每一个训练任务都运行在一次性(ephemeral)容器中,其环境具有以下特性:

  • 环境是临时的,任务结束后即销毁;
  • 容器内所有文件随任务结束被删除;
  • 没有本地磁盘持久化能力;
  • 任务结束后无法再访问任何结果文件。

因此 hub_saving.md 开篇就用加粗警告强调:"Without Hub push, training is completely wasted."(不推送到 Hub,训练就完全白费)。这一点在 SKILL.md 的"Prerequisites Checklist"与"Critical: Saving Results to Hub"两节中被反复标注为 ⚠️ CRITICAL,是提交任何训练任务前必须满足的硬性前提。

源码佐证:仓库内所有生产级训练脚本(train_sft_example.py、train_dpo_example.py、train_grpo_example.py)无一例外都在配置中开启push_to_hub=True,并在训练结束后显式调用trainer.push_to_hub(),这印证了"推送是流程终点而非可选项"的设计原则。

必需配置:训练侧与任务侧各一处

要让模型成功落盘,必须在两个位置同时配置,缺一不可。

1. 训练配置(SFTConfig / trainer config)

SFTConfig( push_to_hub=True, # 启用 Hub 推送 hub_model_id="username/model-name", # 目标仓库 )
  • push_to_hub=True:告诉 Trainer 在每个 checkpoint 保存时同步推送权重。
  • hub_model_id:指定目标仓库,格式必须为用户名/仓库名,且必须显式指定(文档原文为 MUST specify)。

2. 任务配置(hf_jobs 提交)

hf_jobs("uv", { "script": "train.py", "secrets": {"HF_TOKEN": "$HF_TOKEN"} # 提供认证 })

其中$HF_TOKEN占位符会在提交任务时自动替换为你的 Hugging Face 真实令牌,无需在脚本中硬编码任何密钥。这正是 SKILL.md 中强调的$HF_TOKEN语法:它引用的是你账号的真实 token 值,容器启动后HF_TOKEN会作为环境变量注入。

完整最小示例:SFT 训练并推送

以下脚本直接复刻自 hub_saving.md 的完整示例,并保持原样的关键配置:

# train.py # /// script # dependencies = ["trl"] # /// from trl import SFTTrainer, SFTConfig from datasets import load_dataset dataset = load_dataset("trl-lib/Capybara", split="train") # 配置 Hub 推送 config = SFTConfig( output_dir="my-model", num_train_epochs=3, # ✅ CRITICAL: Hub push 配置 push_to_hub=True, hub_model_id="myusername/my-trained-model", # 可选:推送策略 push_to_hub_model_id="myusername/my-trained-model", push_to_hub_organization=None, push_to_hub_token=None, # 使用环境变量中的 token ) trainer = SFTTrainer( model="Qwen/Qwen2.5-0.5B", train_dataset=dataset, args=config, ) trainer.train() # ✅ 推送最终模型 trainer.push_to_hub()

提交命令(带认证):

hf_jobs("uv", { "script": "train.py", "flavor": "a10g-large", "timeout": "2h", "secrets": {"HF_TOKEN": "$HF_TOKEN"} # ✅ 必需! })

参数说明:

参数含义备注
script训练脚本(内联代码或 Hub/GitHub 上的 URL)本地文件路径在 Jobs 中无效
flavorGPU 机型,如a10g-large硬件选择见 hardware_guide.md
timeout任务超时(如"2h""90m""1.5h"或整数秒)默认 30 分钟对训练几乎必然过短
secrets以密文方式注入的敏感环境变量推荐用"$HF_TOKEN"引用真实令牌

从源码结构看,脚本中可通过os.environ["HF_TOKEN"]直接读取注入的令牌。unsloth_sft_example.py 展示了这一用法:先读取HF_TOKEN调用login(token=token)完成 Hub 登录,再开始训练,并在脚本开头断言assert "HF_TOKEN" in os.environ提前暴露缺失问题。

推送时会保存哪些内容

push_to_hub=True时,随模型一并推送到仓库的包括:

  1. 模型权重(Model weights)—— 训练得到的最终参数;
  2. 分词器(Tokenizer)—— 关联的分词器文件;
  3. 模型配置(Configuration)——config.json
  4. 训练参数(Training arguments)—— 本次训练使用的超参数记录;
  5. 模型卡片(Model card)—— 自动生成的 README 文档;
  6. 检查点(Checkpoints)—— 若启用了save_strategy="steps"则包含中间检查点。

检查点保存:长任务的"后悔药"

训练中途失败在长任务中难以避免,配置检查点保存可显著降低损失:

SFTConfig( output_dir="my-model", push_to_hub=True, hub_model_id="username/my-model", # 检查点配置 save_strategy="steps", save_steps=100, # 每 100 步保存一次 save_total_limit=3, # 仅保留最近 3 个检查点 )

收益包括:任务失败后可断点续训、可横向对比不同检查点效果、可提前使用中间模型。检查点推送至username/my-model(与最终模型同一仓库)

进一步地,通过hub_strategy可以控制检查点的推送节奏。hub_saving.md 的"完整生产设置"示例中使用hub_strategy="checkpoint",而仓库中的三个生产脚本(train_sft_example.py 等)统一使用hub_strategy="every_save"——含义为每次保存都推送,保证任何时刻的检查点都已在 Hub 上,即便任务中途被杀也不丢进度。save_total_limit用于控制仓库内检查点数量,避免占用过多存储。

关于检查点与断点续训,troubleshooting.md 给出了可复现的恢复方式:

trainer = SFTTrainer( model="username/model-name", resume_from_checkpoint="username/model-name/checkpoint-1000", )

三种认证方式对比

hub_saving.md 提供了三种向任务注入令牌的方法,安全级别从高到低:

方法一:自动令牌(推荐)

"secrets": {"HF_TOKEN": "$HF_TOKEN"}

自动使用你已登录的 Hugging Face 账号令牌,无需在代码中接触任何密钥明文。始终优先选择此方法

方法二:显式令牌

"secrets": {"HF_TOKEN": "hf_abc123..."}

直接写死令牌明文,文档明确标注"not recommended for security"(出于安全考虑不推荐),因为明文会进入任务配置与日志。

方法三:普通环境变量

"env": {"HF_TOKEN": "hf_abc123..."}

以普通环境变量传入,文档同样标注"less secure than secrets"(安全性低于 secrets),因为普通 env 的可见性高于 secrets 机制。

提交前验证清单

在提交任何训练任务之前,逐项核对:

  • 训练配置中push_to_hub=True
  • 已指定hub_model_id(格式:username/model-name
  • 任务配置中包含secrets={"HF_TOKEN": "$HF_TOKEN"}
  • 仓库名与已有仓库不冲突
  • 你对目标命名空间(namespace)具备写权限

这一清单与 SKILL.md 中"Verification Checklist"完全一致,也呼应了 troubleshooting.md 中"Model Not Saved to Hub"一节,其中还额外补充了一条常被遗漏的项:训练脚本末尾必须调用trainer.push_to_hub()

仓库创建与命名规范

自动创建

如果目标仓库不存在,首次推送时会自动创建,无需任何手工步骤。

手动预创建

也可以在训练前手动创建仓库,以便提前配置权限、可见性或描述:

from huggingface_hub import HfApi api = HfApi() api.create_repo( repo_id="username/model-name", repo_type="model", private=False, # 或 True 创建私有仓库 )

命名规范

合法命名:

  • username/my-model
  • username/model-name
  • organization/model-name

非法命名:

  • model-name—— 缺少用户名/命名空间
  • username/model name—— 不允许空格
  • username/MODEL—— 不建议使用大写

故障排查:推送失败怎么办

错误:401 Unauthorized

原因:HF_TOKEN未提供或无效。

解决方案:

  1. 检查任务配置中secrets={"HF_TOKEN": "$HF_TOKEN"}
  2. 确认本地已登录:hf auth whoami
  3. 重新登录:hf auth login

错误:403 Forbidden

原因:对目标仓库没有写权限。

解决方案:

  1. 确认hub_model_id的命名空间与你的用户名一致;
  2. 若使用组织命名空间,确认你是该组织成员;
  3. 检查仓库是否为私有(访问组织私有仓库需成员权限)。

错误:Repository not found

原因:仓库不存在且自动创建失败。

解决方案:

  1. 先手动创建仓库(见上文HfApi.create_repo);
  2. 检查仓库名格式是否合法;
  3. 确认命名空间存在。

错误:训练中途推送失败

原因:网络问题或 Hub 临时不可用。

解决方案:

  1. 训练会继续运行,但最终推送失败;
  2. 检查点可能已保存(若启用了检查点与hub_strategy="every_save");
  3. 任务结束后可手动重新推送(见下节)。

问题:模型已保存但不可见

可能原因:

  1. 仓库是私有的——检查你自己的 Hub 主页是否可见该仓库;
  2. 命名空间错误——核对hub_model_id是否与你登录的账号一致;
  3. 推送仍在进行中——等待几分钟后刷新。

补充事实:troubleshooting.md 在 Hub Push 相关修复中额外提示:可调用hf_whoami()验证当前认证身份,并确认 token 在 Hub 设置页具备write(写入)权限而非 read-only;同时hub_private_repo=True可让自动创建仓库默认设为私有,从而规避权限类 403。

训练完成后的手动推送

若训练已结束但自动推送失败(且容器尚未销毁、文件仍存在),可加载本地输出目录手动推送:

from transformers import AutoModel, AutoTokenizer # 从本地 checkpoint 加载 model = AutoModel.from_pretrained("./output_dir") tokenizer = AutoTokenizer.from_pretrained("./output_dir") # 推送到 Hub model.push_to_hub("username/model-name", token="hf_abc123...") tokenizer.push_to_hub("username/model-name", token="hf_abc123...")

注意:这仅在任务尚未完成(文件仍存在)时可行;任务一旦结束,临时文件已全部删除,只能通过检查点恢复。

最佳实践七条

  1. 始终开启push_to_hub=True—— 不开启意味着训练结果归零;
  2. 长任务务必配置检查点保存—— 用save_strategy="steps"+save_steps细化保存粒度;
  3. 在任务完成前从日志确认 Hub 推送成功—— 不要等任务结束才检查;
  4. 设置合理的save_total_limit—— 防止检查点无限堆积占用仓库空间;
  5. 使用有描述性的仓库名—— 例如qwen-capybara-sft而不是model1
  6. 为模型添加 model card—— 记录训练细节便于复用与协作;
  7. 给模型打上相关标签—— 如text-generationfine-tuned,提升可发现性。

监控推送进度

推送过程可通过日志实时观察:

hf_jobs("logs", {"job_id": "your-job-id"})

关注日志中的关键输出:

Pushing model to username/model-name... Upload file pytorch_model.bin: 100% ✅ Model pushed successfully

hf_jobs还支持ps(列出所有任务)、inspect(查看任务详情)等查询,详见 SKILL.md 的"Check Job Status"一节。

完整生产级示例:LoRA + 检查点 + 推送

以下综合示例来自 hub_saving.md 的 production_train.py,展示了生产环境的完整配置形态:

# production_train.py # /// script # dependencies = ["trl>=0.12.0", "peft>=0.7.0"] # /// from datasets import load_dataset from peft import LoraConfig from trl import SFTTrainer, SFTConfig import os # 验证 token 可用 assert "HF_TOKEN" in os.environ, "HF_TOKEN not found in environment!" # 加载数据集 dataset = load_dataset("trl-lib/Capybara", split="train") print(f"✅ Dataset loaded: {len(dataset)} examples") # 完整 Hub 配置 config = SFTConfig( output_dir="qwen-capybara-sft", # Hub 配置 push_to_hub=True, hub_model_id="myusername/qwen-capybara-sft", hub_strategy="checkpoint", # 推送检查点 # 检查点配置 save_strategy="steps", save_steps=100, save_total_limit=3, # 训练设置 num_train_epochs=3, per_device_train_batch_size=4, # 日志 logging_steps=10, logging_first_step=True, ) # 使用 LoRA 训练 trainer = SFTTrainer( model="Qwen/Qwen2.5-0.5B", train_dataset=dataset, args=config, peft_config=LoraConfig(r=16, lora_alpha=32), ) print("🚀 Starting training...") trainer.train() print("💾 Pushing final model to Hub...") trainer.push_to_hub() print("✅ Training complete!")

提交方式:

hf_jobs("uv", { "script": "production_train.py", "flavor": "a10g-large", "timeout": "6h", "secrets": {"HF_TOKEN": "$HF_TOKEN"} })

源码佐证:仓库中 train_sft_example.py 是上述生产脚本的更完整版本,额外加入了train_test_split评估集划分、Trackio 监控(report_to="trackio")、warmup_ratio=0.1lr_scheduler_type="cosine"、LoRA 的target_modules=["q_proj", "v_proj"]等细节,并以 PEP 723 头声明trl>=0.12.0peft>=0.7.0transformers>=4.36.0accelerate>=0.24.0trackio依赖。该脚本可直接作为hf_jobs("uv", ...)script内联内容使用。Unsloth 路线(unsloth_sft_example.py)则提供了--merge-model合并 LoRA 权重后经push_to_hub_merged(..., save_method="merged_16bit")推送全量模型的可选项。

扩展阅读与关联文档

  • SKILL.md —— 技能主文档,含 Jobs 提交流程、超时管理、模型选择;
  • training_methods.md —— SFT/DPO/GRPO/Reward 方法与数据集格式速查;
  • training_patterns.md —— 多 GPU、DPO、GRPO 等训练模式模板;
  • troubleshooting.md —— 含"Model Not Saved to Hub"与 Hub Push Failures 专项排查;
  • train_sft_example.py、train_dpo_example.py、train_grpo_example.py —— 三个生产级训练模板;
  • unsloth_sft_example.py —— Unsloth 优化路线(约省 60% 显存)的 Hub 推送实现。

关键结论

如果不同时配置push_to_hub=Truesecrets={"HF_TOKEN": "$HF_TOKEN"},所有训练结果都会永久丢失。

在提交任何训练任务前,请务必核对这两个条件都已就位——这是 Hugging Face Jobs 上所有训练工作流的第一安全准则。训练结束后,请确认日志中出现模型推送成功的输出,再放心宣告任务完成。

【免费下载链接】skillsGive your agents the power of the Hugging Face ecosystem项目地址: https://gitcode.com/GitHub_Trending/skills7/skills

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

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

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

立即咨询