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_hub、hub_model_id与secrets={"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 中无效 |
flavor | GPU 机型,如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时,随模型一并推送到仓库的包括:
- 模型权重(Model weights)—— 训练得到的最终参数;
- 分词器(Tokenizer)—— 关联的分词器文件;
- 模型配置(Configuration)——
config.json; - 训练参数(Training arguments)—— 本次训练使用的超参数记录;
- 模型卡片(Model card)—— 自动生成的 README 文档;
- 检查点(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-modelusername/model-nameorganization/model-name
非法命名:
model-name—— 缺少用户名/命名空间username/model name—— 不允许空格username/MODEL—— 不建议使用大写
故障排查:推送失败怎么办
错误:401 Unauthorized
原因:HF_TOKEN未提供或无效。
解决方案:
- 检查任务配置中
secrets={"HF_TOKEN": "$HF_TOKEN"}; - 确认本地已登录:
hf auth whoami; - 重新登录:
hf auth login。
错误:403 Forbidden
原因:对目标仓库没有写权限。
解决方案:
- 确认
hub_model_id的命名空间与你的用户名一致; - 若使用组织命名空间,确认你是该组织成员;
- 检查仓库是否为私有(访问组织私有仓库需成员权限)。
错误:Repository not found
原因:仓库不存在且自动创建失败。
解决方案:
- 先手动创建仓库(见上文
HfApi.create_repo); - 检查仓库名格式是否合法;
- 确认命名空间存在。
错误:训练中途推送失败
原因:网络问题或 Hub 临时不可用。
解决方案:
- 训练会继续运行,但最终推送失败;
- 检查点可能已保存(若启用了检查点与
hub_strategy="every_save"); - 任务结束后可手动重新推送(见下节)。
问题:模型已保存但不可见
可能原因:
- 仓库是私有的——检查你自己的 Hub 主页是否可见该仓库;
- 命名空间错误——核对
hub_model_id是否与你登录的账号一致; - 推送仍在进行中——等待几分钟后刷新。
补充事实: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...")注意:这仅在任务尚未完成(文件仍存在)时可行;任务一旦结束,临时文件已全部删除,只能通过检查点恢复。
最佳实践七条
- 始终开启
push_to_hub=True—— 不开启意味着训练结果归零; - 长任务务必配置检查点保存—— 用
save_strategy="steps"+save_steps细化保存粒度; - 在任务完成前从日志确认 Hub 推送成功—— 不要等任务结束才检查;
- 设置合理的
save_total_limit—— 防止检查点无限堆积占用仓库空间; - 使用有描述性的仓库名—— 例如
qwen-capybara-sft而不是model1; - 为模型添加 model card—— 记录训练细节便于复用与协作;
- 给模型打上相关标签—— 如
text-generation、fine-tuned,提升可发现性。
监控推送进度
推送过程可通过日志实时观察:
hf_jobs("logs", {"job_id": "your-job-id"})关注日志中的关键输出:
Pushing model to username/model-name... Upload file pytorch_model.bin: 100% ✅ Model pushed successfullyhf_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.1、lr_scheduler_type="cosine"、LoRA 的target_modules=["q_proj", "v_proj"]等细节,并以 PEP 723 头声明trl>=0.12.0、peft>=0.7.0、transformers>=4.36.0、accelerate>=0.24.0、trackio依赖。该脚本可直接作为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=True与secrets={"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),仅供参考