# Best Practices for Saving Trained Models to Hugging Face Hub in Jobs

> Learn best practices for saving trained models to Hugging Face Hub in jobs. Discover how to use HF_TOKEN for persistent artifact storage in ephemeral job containers.

- Repository: [Hugging Face/skills](https://github.com/huggingface/skills)
- Tags: best-practices
- Published: 2026-03-08

---

**To persist trained models from Hugging Face Jobs, you must explicitly push artifacts to the Hugging Face Hub using `HF_TOKEN` authentication, as job containers are ephemeral and local filesystem writes are lost upon completion.**

When running training workloads on the Hugging Face Jobs platform, understanding the ephemeral nature of execution environments is critical for preserving your work. According to the `huggingface/skills` repository, any files written to local disk during job execution disappear immediately when the container terminates, making explicit persistence to the Hugging Face Hub the recommended approach for saving trained models, datasets, and experiment artifacts.

## Understanding Job Ephemerality and Persistence Requirements

Hugging Face Jobs execute in isolated containers with no persistent disk attached. As documented in [`skills/hugging-face-jobs/references/hub_saving.md`](https://github.com/huggingface/skills/blob/main/skills/hugging-face-jobs/references/hub_saving.md), this architecture means that any model checkpoints, processed datasets, or log files written to the local filesystem during training will be permanently deleted when the job finishes.

The standard workflow for saving trained models to Hugging Face Hub in jobs follows this pattern: inject authentication token → execute training script → push artifacts to Hub → verify persistence. This ensures your trained parameters survive beyond the job lifecycle.

## Configuring HF_TOKEN Authentication for Hub Access

Before pushing any artifacts, you must provide a valid Hugging Face authentication token. The job runtime injects secrets as environment variables, making the token available via `os.environ["HF_TOKEN"]`.

In your job definition, explicitly declare the secret mapping:

```python
hf_jobs("uv", {
    "script": "...", 
    "secrets": {"HF_TOKEN": "$HF_TOKEN"}
})

```

Always validate token presence at runtime to catch misconfigured jobs early:

```python
import os
assert "HF_TOKEN" in os.environ, "HF_TOKEN required for Hub authentication!"

```

## Saving Trained Models Using push_to_hub

The Transformers library provides the `push_to_hub()` method, which automatically detects the `HF_TOKEN` environment variable and handles repository creation and file uploads.

### Complete Training Job Example

This example from [`skills/hugging-face-jobs/references/hub_saving.md`](https://github.com/huggingface/skills/blob/main/skills/hugging-face-jobs/references/hub_saving.md) demonstrates a minimal training job that persists both model and tokenizer:

```python
hf_jobs("uv", {
    "script": """

# /// script

# dependencies = ["transformers"]

# ///

import os
from transformers import AutoModel, AutoTokenizer

# Ensure token is available

assert "HF_TOKEN" in os.environ, "HF_TOKEN required!"

# Load / train your model (placeholder)

model = AutoModel.from_pretrained("bert-base-uncased")
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")

# Push both model and tokenizer to the Hub

model.push_to_hub("username/my-model")
tokenizer.push_to_hub("username/my-model")
print("✅ Model and tokenizer successfully pushed!")
""",
    "flavor": "a10g-large",
    "timeout": "2h",
    "secrets": {"HF_TOKEN": "$HF_TOKEN"}
})

```

The `push_to_hub` method creates the repository if it doesn't exist, uploads the model weights and configuration, and returns the URL of the new Hub repository.

## Persisting Datasets and Processed Data

For dataset artifacts, the Datasets library offers an identical `push_to_hub()` interface. This pattern applies to processed training data, evaluation splits, or augmented datasets generated during job execution.

```python
hf_jobs("uv", {
    "script": """

# /// script

# dependencies = ["datasets", "huggingface-hub"]

# ///

import os
from datasets import Dataset

assert "HF_TOKEN" in os.environ, "HF_TOKEN required!"

# Example data processing

data = {"text": ["example 1", "example 2"], "label": [0, 1]}
dataset = Dataset.from_dict(data)

# Push to Hub (token auto‑detected)

dataset.push_to_hub("username/my-dataset")
print("✅ Dataset pushed!")
""",
    "flavor": "cpu-basic",
    "timeout": "30m",
    "secrets": {"HF_TOKEN": "$HF_TOKEN"}
})

```

## Uploading Arbitrary Artifacts with HfApi

When saving trained models to Hugging Face Hub in jobs, you may need to persist non-model files such as JSON metrics, CSV logs, or custom checkpoint formats. The `huggingface_hub.HfApi` class provides granular control via `upload_file()` and `upload_folder()`.

### Metrics and Experiment Results

This example demonstrates uploading evaluation metrics generated during training:

```python
hf_jobs("uv", {
    "script": """

# /// script

# dependencies = ["pandas", "huggingface-hub"]

# ///

import os, json, pandas as pd
from huggingface_hub import HfApi

assert "HF_TOKEN" in os.environ, "HF_TOKEN required!"

# Generate results

results = {"accuracy": 0.94, "loss": 0.06}
df = pd.DataFrame([results])

# Save locally (temporary)

with open("metrics.json", "w") as f:
    json.dump(results, f)
df.to_csv("metrics.csv", index=False)

# Upload to Hub

api = HfApi()
repo_id = "username/experiment-results"
api.upload_file(
    path_or_fileobj="metrics.json",
    path_in_repo="metrics.json",
    repo_id=repo_id,
    repo_type="dataset"
)
api.upload_file(
    path_or_fileobj="metrics.csv",
    path_in_repo="metrics.csv",
    repo_id=repo_id,
    repo_type="dataset"
)
print("✅ Metrics uploaded to Hub!")
""",
    "flavor": "cpu-basic",
    "timeout": "30m",
    "secrets": {"HF_TOKEN": "$HF_TOKEN"}
})

```

The `HfApi` approach supports both `repo_type="model"` and `repo_type="dataset"`, allowing you to organize artifacts logically within the Hub ecosystem.

## Summary

- **Job containers are ephemeral**: Any data written to local disk during Hugging Face Jobs execution is destroyed when the job completes.
- **Authentication is mandatory**: Always declare `HF_TOKEN` in the job's `secrets` section and validate its presence at runtime with `assert "HF_TOKEN" in os.environ`.
- **Use high-level methods when possible**: The `push_to_hub()` methods from Transformers and Datasets libraries provide the simplest path for saving trained models and datasets.
- **Handle arbitrary files with HfApi**: For metrics, logs, or custom formats, use `HfApi.upload_file()` or `upload_folder()` with explicit `repo_type` parameters.
- **Reference the official guide**: Detailed patterns are documented in [`skills/hugging-face-jobs/references/hub_saving.md`](https://github.com/huggingface/skills/blob/main/skills/hugging-face-jobs/references/hub_saving.md) within the `huggingface/skills` repository.

## Frequently Asked Questions

### What happens to my model files if I don't push them to the Hub?

If you write model checkpoints to the local filesystem during a job but fail to call `push_to_hub()` or `upload_file()`, those files will be permanently deleted when the ephemeral job container terminates. The Hugging Face Jobs platform does not preserve local disk state between runs.

### Can I use external storage providers instead of the Hugging Face Hub?

Yes, while the Hub is the most integrated solution, you can fall back to external storage such as Amazon S3, Google Cloud Storage, or custom API endpoints. However, this requires additional authentication configuration and client libraries, whereas the Hub integration automatically handles token-based authentication via the `HF_TOKEN` secret.

### How do I upload entire directories or multiple files at once?

For batch uploads, use `HfApi.upload_folder()` instead of individual `upload_file()` calls. This method recursively uploads all files in a local directory to a specified repository path. Alternatively, you can zip your artifacts and upload the single archive file, though `upload_folder()` is preferred for Hub-native repositories.

### Is HF_TOKEN automatically available in all Hugging Face Job environments?

No, the `HF_TOKEN` environment variable is only injected when you explicitly declare it in the job's `secrets` configuration. You must include `"secrets": {"HF_TOKEN": "$HF_TOKEN"}` in your `hf_jobs()` call. Always validate token presence at runtime to ensure your job fails fast with a clear error message rather than attempting unauthorized API calls.