> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tuneplane.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 部署一个模型版本

> 把一个模型放到稳定的内部地址后面，带可升级可回滚的 revision。

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
curl -X POST https://tuneplane.your-company.com/api/model-deployments \
  -H "Authorization: Bearer $TUNEPLANE_CLIENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "support-agent",
    "model_source": {"kind": "model", "model": "alice/support-agent"},
    "config": {"engine": "vllm", "gpus": 2, "max_model_len": 8192},
    "fleet_id": "fleet-gpu-a",
    "serve_mode": "proxied"
  }'
```

你得到一个 Model Deployment：一个应用流量可以调用的稳定地址，提供当前被升级上去的那个 revision。

多数人是在控制台的[部署页](/zh-Hans/console/deployments)上创建它。这里放 API，是因为 deployment
恰恰是最常想写进脚本里的那个东西。

## Deployment 不是 Playground Session

|     | Playground Session | Model Deployment        |
| --- | ------------------ | ----------------------- |
| 给谁  | 一个人试用某个 checkpoint | 应用流量                    |
| 生命期 | 一个空闲 TTL，然后停       | 直到你挂起或删除它               |
| 地址  | 每个 session 单独签发    | 稳定，比每个 revision 都活得久    |
| 鉴权  | 你自己的登录             | 一个可吊销的 Deployment Token |
| 换模型 | 再起一个 session       | 建一个 revision 并升级上去      |

## 模型从哪来

`model_source.kind` 是以下之一：

| Kind          | 字段                                              | 用于                  |
| ------------- | ----------------------------------------------- | ------------------- |
| `model`       | `model` 形如 `<owner>/<name>`，可选 `version`        | 常规情况。省略版本表示跟随被升级的那个 |
| `artifact`    | `run_id`，可选 `step`                              | 直接用某次运行的导出          |
| `huggingface` | `repository`、`revision`、`use_linked_credential` | 一个 hub 模型           |
| `modelscope`  | `repository`、`revision`                         | 一个公开的魔搭仓库           |
| `shared_path` | 一个路径                                            | 已经在共享存储上的权重         |

`model` 不带版本，正是让 `tp model promote` 成为改变在线内容唯一一步的原因。见
[模型注册表](/zh-Hans/guides/model-registry)。

两者在进来时都会被钉住。`artifact` 来源会记下它取了哪个导出 step，而不带版本的 `model` 来源会把
生产解析一次并存下拿到的号。一个重启之后加载不同权重的 revision 不是 revision，而每次启动都重新
跟随一个会动的指针正是那样发生的。

## 服务配置

```json theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
{
  "engine": "vllm",
  "gpus": 4,
  "dtype": "bfloat16",
  "quantization": "none",
  "max_model_len": 8192,
  "gpu_memory_utilization": 0.9,
  "served_model_name": "support-agent",
  "tensor_parallel_size": 2,
  "data_parallel_size": 2
}
```

| 字段                       | 默认      | 说明                                |
| ------------------------ | ------- | --------------------------------- |
| `engine`                 | `vllm`  | 或 `sglang`。是不同的引擎，不是后端选择          |
| `gpus`                   | `1`     | 这个 deployment 占多少张卡               |
| `dtype`                  | `auto`  | `float16`、`bfloat16`              |
| `quantization`           | `none`  | `awq`、`gptq`、`bitsandbytes`、`fp8` |
| `max_model_len`          | 引擎默认    | 上下文长度                             |
| `gpu_memory_utilization` | `0.9`   |                                   |
| `max_concurrency`        | 未设      |                                   |
| `served_model_name`      | `model` | 调用方在 `model` 字段里写的名字              |
| `tensor_parallel_size`   | 全部卡     |                                   |
| `pipeline_parallel_size` | `1`     | 用于不能整齐切分的模型                       |
| `data_parallel_size`     | `1`     | 用于把一个小模型在多卡上开多副本                  |

`tensor_parallel_size × pipeline_parallel_size × data_parallel_size` 必须等于 `gpus`。不等于的话，
容器要么起不来，要么静悄悄只用了分配给它的一部分卡 —— 后者更糟，因为看不出哪里不对，而配额是按
全部收的。

schema 没建模的旋钮用 `extra_args`，它在平台自己的参数之后原样传给引擎；`env` 设引擎进程的环境
—— `VLLM_*`、`NCCL_*`、`HF_HOME`。平台必须说对的参数，比如 `--port` 和 `--model`，是保留的，会被
拒绝。

凭据不属于 `env`。私有模型来源用一个受管的 Model Credential，它在读取时从不回显。

## proxied 还是 direct

`serve_mode` 决定控制台是否在数据通路上。

| 模式            | 流量走向    | Reflow 采集 |
| ------------- | ------- | --------- |
| `proxied`（默认） | 经控制台到引擎 | 有         |
| `direct`      | 直达引擎    | **没有**    |

`direct` 的 deployment 什么都不采集，所以之后没有 [Reflow](/zh-Hans/guides/reflow) buffer 可挖。
为延迟选它，但要知道这一点。

## 哪个 Fleet 承载它

`fleet_id` 由你选，平台从不替你挑。deployment 是长期对象，它的地址比这个决定活得更久，而各个 Fleet
在平台无法排序的维度上不同：机器归哪个部门、哪些数据可以碰它们。

## 调用它

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
curl -X POST https://tuneplane.your-company.com/api/model-deployments/<id>/tokens \
  -H "Authorization: Bearer $TUNEPLANE_CLIENT_TOKEN" \
  -d '{"name": "support-service"}'
```

令牌只返回一次。之后应用流量用 OpenAI 兼容的端点：

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
curl https://tuneplane.your-company.com/inference/<id>/v1/chat/completions \
  -H "Authorization: Bearer <deployment token>" \
  -H "Content-Type: application/json" \
  -d '{"model": "support-agent", "messages": [{"role": "user", "content": "Hello"}]}'
```

一个 Deployment Token 只授权访问一个 deployment，可以单独吊销，与任何人的登录会话无关。吊销用
`DELETE /api/model-deployments/<id>/tokens/<token_id>`。

## 换掉它在提供的东西

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
# 一个新 revision，在它报告就绪时升上去
curl -X POST .../api/model-deployments/<id>/revisions \
  -d '{"model_source": {...}, "config": {...}, "allow_downtime": false}'

# 回到一个已知可用的
curl -X POST .../api/model-deployments/<id>/rollback \
  -d '{"revision_id": "rev-7", "allow_downtime": false}'
```

一个 revision 是模型来源与服务配置合在一起的不可变快照。升级把端点切到一个**已经就绪**的
revision 上，所以那个地址从不指向还在启动的东西。`allow_downtime: true` 跳过等待，用于卡数不足以
同时容纳两个 revision 的 deployment。

`suspend` 释放服务容量，保留身份、revision、地址和令牌。它不是删除。

## 确认成功

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
curl -H "Authorization: Bearer $TUNEPLANE_CLIENT_TOKEN" \
  https://tuneplane.your-company.com/api/model-deployments/<id>
```

`status` 显示就绪，且 `current_revision.internal_endpoint` 已填。控制台的部署页显示同样的信息，
另外还有引擎进程的 `logs` 和 `metrics`。

`desired_state` 是你要求的，`status` 是观察到的。一个 revision 启动期间它们会不同，持续不同的话
原因在 `last_error` 里。

## 下一步

[模型注册表](/zh-Hans/guides/model-registry) · [Reflow](/zh-Hans/guides/reflow) ·
[部署页](/zh-Hans/console/deployments) · [推理 API](/zh-Hans/api-reference/inference)
