> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/developer/python-sdk/upload-custom-model-weights.md).

# Upload Custom Model Weights

Roboflow can host model weights you trained outside the platform - locally with [Ultralytics](https://docs.ultralytics.com/), in a Sagemaker job, or in any framework that exports to PyTorch / ONNX. Once uploaded, the model is reachable through every Roboflow inference path: the SDK's `model.predict()`, the REST API, hosted Workflows, and Dedicated Deployments.

The SDK exposes two equivalent paths:

* `Workspace.deploy_model()` - for one-shot uploads against an arbitrary set of projects.
* `Version.deploy()` - for attaching weights to a specific dataset version.

## Upload weights to a version

Use `Version.deploy()` when the weights correspond to a specific Roboflow dataset version (recommended - keeps the dataset → weights → inference URL chain coherent).

```python
import roboflow

rf = roboflow.Roboflow(api_key="YOUR_API_KEY")
version = rf.workspace().project("my-detector").version(3)

version.deploy(
    model_type="yolov8",                  # or yolov5, yolov11, rfdetr-nano, etc.
    model_path="./training-runs/exp42",    # directory containing weights/best.pt
    filename="weights/best.pt",            # optional, default
)
```

`model_path` is the run directory; `filename` is the path within that directory to the `.pt` weights file. The SDK uploads the weights and registers them against the version, after which `version.model.predict(...)` runs against the uploaded weights instead of any prior Roboflow-trained version.

## Upload weights to one or more projects

Use `Workspace.deploy_model()` when the weights aren't tied to a specific dataset version (e.g. an externally trained generalist model that you want to make available across several projects).

```python
ws = rf.workspace()

ws.deploy_model(
    model_type="yolov8",
    model_path="./generalist-run",
    project_ids=["my-detector", "my-classifier"],
    model_name="generalist-v3",
    filename="weights/best.pt",
)
```

### Parameters

* `model_type` (str) - model architecture identifier. Pass an invalid value to get the full list back as an error.
* `model_path` (str) - directory containing the trained weights.
* `project_ids` (list\[str]) - projects to attach the model to.
* `model_name` (str) - name for the uploaded model in the web app.
* `filename` (str, default `"weights/best.pt"`) - path within `model_path` to the weights file.

## Where it ends up

After upload completes, the model is available:

* In the Roboflow web app under the project's **Versions → Deploy** tab.
* Through the SDK as `version.model.predict(...)`.
* Through the REST API at `https://serverless.roboflow.com/infer/...`.
* As a target for [Dedicated Deployments](/developer/python-sdk/manage-dedicated-deployments.md).

For a deeper walk-through of supported architectures and edge formats, see the product documentation on [uploading custom weights](https://docs.roboflow.com/deploy/upload-custom-weights).
