# Publishing weights

If you've trained a model that you'd like to share with the community, you can
publish any number of checkpoints you've previously saved.

Once published, your checkpoint can be loaded by any tinker user and used to
further train a new model or be sampled against.

### Publishing

```bash
tinker checkpoint publish $TINKER_CHECKPOINT_PATH
```

where `$TINKER_CHECKPOINT_PATH` is a checkpoint path in the form of `tinker://14bdf3a1-0b95-55c7-8659-5edb1bc870af:train:17/weights/checkpoint_id_to_publish`.

You may confirm your checkpoint is published by dumping the checkpoint info and checking the `Public` property:

```bash
tinker checkpoint info tinker://14bdf3a1-0b95-55c7-8659-5edb1bc870af/weights/checkpoint_id_to_publish
                              Checkpoint: weights/checkpoint_id_to_publish
┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Property        ┃ Value                                                                          ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Checkpoint ID   │ weights/checkpoint_id_to_publish                                               │
│ Type            │ training                                                                       │
│ Tinker Path     │ tinker://14bdf3a1-0b95-55c7-8659-5edb1bc870af/weights/checkpoint_id_to_publish │
│ Size            │ 342.4 MB                                                                       │
│ Public          │ No                                                                             │
│ Created         │ 23 minutes ago                                                                 │
│ Training Run ID │ 14bdf3a1-0b95-55c7-8659-5edb1bc870af                                           │
└─────────────────┴────────────────────────────────────────────────────────────────────────────────┘
```

### Unpublishing

```bash
tinker checkpoint unpublish $TINKER_CHECKPOINT_PATH
```

### Loading public weights

Loading public weights is exactly the same as loading a non-public one:

```python
ckpt_path = ...
training_client = service_client.create_training_client_from_state(ckpt_path)
```

## Publishing to HuggingFace Hub

You can also publish trained weights directly to the [HuggingFace Hub](https://huggingface.co/) using `publish_to_hf_hub`. This works with outputs from both `build_hf_model` (merged models) and `build_lora_adapter` (PEFT adapters).

### Basic usage

```python
from tinker_cookbook.weights import publish_to_hf_hub

url = publish_to_hf_hub(
    model_path="./model",
    repo_id="user/my-model",
)
```

By default, repositories are created as **private**. Pass `private=False` to make them public. Authentication uses the `HF_TOKEN` environment variable or a cached login from `huggingface-cli login`.

### Auto-generated model cards

Pass a `ModelCardConfig` to auto-generate a `README.md` with HuggingFace-compatible YAML frontmatter:

```python
from tinker_cookbook.weights import publish_to_hf_hub, ModelCardConfig

publish_to_hf_hub(
    model_path="./model",
    repo_id="user/my-model",
    model_card=ModelCardConfig(
        base_model="Qwen/Qwen3-8B",
        datasets=["my-org/my-dataset"],
        tags=["sft"],
        license="apache-2.0",
        language=["en"],
    ),
)
```

The only required field is `base_model`. Tags `tinker` and `tinker-cookbook` are added automatically. For adapters (detected by the presence of `adapter_config.json`), `peft` and `lora` tags are also added, and the usage snippet shows `PeftModel` loading.

If the model directory already contains a `README.md`, it is preserved and the model card is not generated.

### Previewing a model card

Use `generate_model_card` to preview or manually save a card without publishing:

```python
from tinker_cookbook.weights import generate_model_card, ModelCardConfig

card = generate_model_card(
    config=ModelCardConfig(base_model="Qwen/Qwen3-8B"),
    repo_id="user/my-model",
    model_path="./model",
)
print(card)           # preview
card.save("README.md")  # save manually
```
