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

# 创建 Async Serverless Endpoint

首次操作时，请先完成账号的注册、实名认证和账户充值。详情请参见[新手指引](/support/quickstart)。

本文以部署一个基于 PPIO SDK 的 ComfyUI worker 镜像 `image.ppinfra.com/prod-gpucloudpublic/comfyui-worker:v0.0.1` 为例，介绍如何创建一个 Async Serverless Endpoint。

## 1. 准备容器镜像

您需要提前将运行环境打包成 Docker 镜像，并上传至镜像仓库。支持指定公共镜像仓库地址和私有镜像仓库地址（需提供镜像仓库认证凭证）。

* 您可以将镜像上传至 Docker Hub，目前平台已针对该站点提供镜像预热服务。详情请参见[使用镜像预热服务](/gpu/image-pre-warming)。

本示例使用 `image.ppinfra.com/prod-gpucloudpublic/comfyui-worker:v0.0.1` 模型镜像。该镜像内置 ComfyUI 与 PPIO worker SDK，任务输入为 ComfyUI workflow JSON，输出图片会通过 worker handler 返回。建议配置 `BUCKET_ENDPOINT_URL` 等对象存储相关环境变量，将 Async Serverless Endpoint 产生的图片、视频上传到对象存储 Bucket，并在任务结果中返回文件 URL。

## 2. 选择实例规格

目前Async Serverless Endpoint 支持以下两种 GPU 实例规格：

* RTX 4090 24GB
* H100 SXM 80GB

本示例中的 `comfyui-worker` 推荐选择 **RTX 4090 24GB**。

如有更多需求，请[联系我们](https://ppio.com/about?index=2)。

## 3. 创建云存储（可选）

如果有共享存储和持久化存储的需求，可以在[存储管理页面](https://ppio.com/gpu-instance/console/storage)创建云存储，然后在创建实例时为容器挂载云存储。详情请参见[管理云存储](/gpu/manage-cloud-storage)。

## 4.创建 Endpoint

1. 进入 [Serverless GPUs 页面](https://ppio.com/gpu-instance/console/serverless)，选择规格，单击「创建 Endpoint」。
2. 完成 Endpoint 的参数配置。

* Endpoint 名称：用于唯一标识 Endpoint，在创建job时是URL的一部分。系统会自动生成一个默认随机生产的名称，支持自定义，请优先用默认的名称。
* Worker 配置
  | **配置项**           | **说明**                                                                                                    |
  | ----------------- | --------------------------------------------------------------------------------------------------------- |
  | **最小 Worker 数**   | Endpoint 最少需要保留的实例数。设置最小实例数可以帮助减少冷启动时间。如果设置为0，则服务没有请求时不会保留任何实例，这可能会导致无法快速响应后续的请求，因此对于响应时间要求较高的场景，请谨慎设置为0。 |
  | **最大 Worker 数**   | Endpoint 最大可以扩展的实例数。当服务请求增加，触发自动扩容机制时，会增加 Worker 数，因此限制最大 Worker 数可以帮助控制成本。                               |
  | **空闲超时（秒）**       | 当触发自动缩容机制而准备释放 Worker 时，在指定的时间内（即空闲超时），平台会为您保留该 Worker ，以便快速应对后续可能上涨的请求量。请注意，平台会收取这段时间对应的 Worker 费用。      |
  | **最大并发数**         | 每个 Worker 能处理的请求最大并发数，当并发数超过最大值时，会将请求调度到其他 Worker 上。如果所有 Worker 并发都被打满，则会将请求存放到队列中等待被执行。                  |
  | **GPUs / Worker** | 每个 Worker 占用的 GPU 卡数。                                                                                     |
  | **CUDA 版本**       | 支持指定 CUDA 版本。                                                                                             |
  * 本示例推荐选择 **RTX 4090 24GB**，`GPUs / Worker` 设置为 `1`。
* Type
  * Endpoint类型，请选择 **异步（Async）**；
* 弹性策略
  * 策略类型请选择 **队列请求数策略**。
  * 单 worker 目标并发请配置为 `1`。本示例中的 ComfyUI worker 每个 Worker 同一时间处理一个 job；当排队请求数超过当前 Worker 可处理能力时，平台会根据队列请求数自动扩容，直到达到最大 Worker 数。
* 镜像配置
  * 镜像地址：要部署的镜像的地址。例如 `image.ppinfra.com/prod-gpucloudpublic/comfyui-worker:v0.0.1`。
  * 镜像仓库凭证：如果指定的镜像为私有镜像，需要配置镜像仓库访问凭证才能拉取镜像。您可以在[安全凭证管理页面](https://ppio.com/gpu-instance/console/settings)创建凭证。
  * HTTP 端口：Worker 对外开放的 HTTP 端口。
  * 容器启动命令：容器启动时执行的命令。
* 存储配置
  * 系统盘：每个 Worker 的系统盘容量大小。
  * 云存储：如果要挂载云存储，请选择云存储。详情请参见[管理云存储](/gpu/manage-cloud-storage)。
* 其他
  * 健康检查路径：此参数暂未启用。
  * 环境变量：设置服务所需的环境变量，以便在 Worker 启动时自动初始化。以腾讯云对象存储 COS 示例如下：
  ```bash Bash icon="terminal" theme={null}
    BUCKET_ENDPOINT_URL=https://<your-bucket-name>cos.<region>.myqcloud.com
    BUCKET_ACCESS_KEY_ID=AKIASVYYYN6L4S6TTTTTT
    BUCKET_SECRET_ACCESS_KEY=maVz2OwY98UUUUUUGjMsmR/Yo8/Zzw0qWMMMMMMM
  ```
  在使用 `comfyui-worker` 这个镜像时，**强烈推荐配置对象存储相关配置，将输出图片上传到对象存储的 Bucket 中**；最终的图片上传效果取决于 worker handler 的实现。客户端调用使用的 API Key 不需要配置到 worker 环境变量中，worker 运行时鉴权信息由平台注入。

3. 确认费用信息，单击「一键部署」。

## 5.访问服务

1. [Serverless GPUs 页面](https://ppio.com/gpu-instance/console/serverless)，找到新创建的 Endpoint，确认状态已变为**运行中**。
2. 确认 Endpoint 中至少有一个 Worker 处于运行中。
3. 确认拥有对应的 API Key 用于调用鉴权，创建 Endpoint 的用户与 API Key 对应的用户应处于同一团队中。

调用 Async Serverless Endpoint 需要准备以下信息：

| **参数**          | **说明**                                                                             |
| --------------- | ---------------------------------------------------------------------------------- |
| **公网调用地址**      | `https://async-public.serverless.ppinfra.com/v1`                                   |
| **Endpoint 名称** | 创建 Endpoint 后得到的名称，例如 `0f43a6867e05fddd`。该名称是任务提交 URL 的一部分。                        |
| **API Key**     | 进入控制台的 API Key / 密钥管理页面创建或复制 API Key。调用时放在 `Authorization: Bearer <API_KEY>` 请求头中。 |

获取 API Key：

1. 登录 PPIO 控制台。
2. 进入 API Key / 密钥管理页面。
3. 单击创建 API Key，复制生成的 `sk_...` 字符串。
4. 确认该 API Key 所属用户与 Endpoint 所属用户在同一团队中。

### 5.1 通过Curl的方式来创建job 以及获取执行结果

**创建Job**

这里给出一个 `comfyui-worker` worker 中实际可执行的例子。该请求地址和 payload 与测试用例保持一致。请将 URL 中的 `0f43a6867e05fddd` 替换为您的真实 Endpoint 名称，并将 `sk_xxxx` 替换为您的真实 API Key。

请注意：Async Serverless Endpoint 所能接受**最大的 job size 大小为 4MiB**；

```bash Bash icon="terminal" theme={null}
curl -X POST https://async-public.serverless.ppinfra.com/v1/0f43a6867e05fddd/run \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer sk_xxxx' \
  -d '{
    "input": {
      "workflow": {
        "4": {
          "class_type": "CheckpointLoaderSimple",
          "inputs": {
            "ckpt_name": "flux1-dev-fp8.safetensors"
          }
        },
        "5": {
          "class_type": "EmptyLatentImage",
          "inputs": {
            "width": 512,
            "height": 512,
            "batch_size": 1
          }
        },
        "6": {
          "class_type": "CLIPTextEncode",
          "inputs": {
            "clip": ["4", 1],
            "text": "a red apple on a table"
          }
        },
        "7": {
          "class_type": "CLIPTextEncode",
          "inputs": {
            "clip": ["4", 1],
            "text": "blurry, low quality"
          }
        },
        "3": {
          "class_type": "KSampler",
          "inputs": {
            "model": ["4", 0],
            "positive": ["6", 0],
            "negative": ["7", 0],
            "latent_image": ["5", 0],
            "seed": 42,
            "steps": 10,
            "cfg": 7,
            "sampler_name": "euler",
            "scheduler": "normal",
            "denoise": 1
          }
        },
        "8": {
          "class_type": "VAEDecode",
          "inputs": {
            "samples": ["3", 0],
            "vae": ["4", 2]
          }
        },
        "9": {
          "class_type": "SaveImage",
          "inputs": {
            "filename_prefix": "test",
            "images": ["8", 0]
          }
        }
      },
      "output_node_id": "9"
    }
}'
```

创建成功得到的 response 如下，其中的 `id` 为 `job_id`：

```json JSON icon="brackets-curly" theme={null}
{"id": "8cb6a77c-62aa-4eb4-9226-1ca5724fd9dd","status":"PENDING"}
```

**查看job状态及获取执行结果：**

请注意：您能通过 Async Service Endpoint 的 `status` 接口能获取到的**最大 output size 为 4MiB**；所以请通过配置 S3 环境变量的方式在 `handler.py` 中将输出的图片或视频上传到 S3 对象存储，这种情况下 output 的大小不受限制；

请注意：Job执行结束后，执行结果在Async serverless Endpoint中**最多保存 6 小时**；

```bash Bash icon="terminal" theme={null}
curl -X GET https://async-public.serverless.ppinfra.com/v1/0f43a6867e05fddd/status/33a0bc4b-7312-41f6-ad15-eb9016bd68f9 \
  -H 'Authorization: Bearer sk_xxxx'
```

**Cancel（取消） Job ：**

```bash Bash icon="terminal" theme={null}
curl -X POST https://async-public.serverless.ppinfra.com/v1/0f43a6867e05fddd/cancel/e5f3c3c0-c3b1-49c2-9452-bb96eaa34ce6 \
  -H 'Authorization: Bearer sk_xxxx'
```

**查看Endpoint Job队列状态：**

```bash Bash icon="terminal" theme={null}
curl -X GET https://async-public.serverless.ppinfra.com/v1/0f43a6867e05fddd/health \
  -H 'Authorization: Bearer sk_xxxx'
```

得到的 response 如下：

```json JSON icon="brackets-curly" theme={null}
{
  "workers": {
    "idle": 0,
    "running": 0,
    "throttled": 0,
    "total": 0
  },
  "jobs": {
    "completed": 0,
    "failed": 0,
    "inProgress": 0,
    "inQueue": 0,
    "retried": 0
  }
}
```

### 5.2 通过 PPIO SDK 来创建 Job 及获取执行结果

安装 SDK：

```bash Bash icon="terminal" theme={null}
pip install ppio-gpus
```

```python Python icon="python" theme={null}
import ppio_gpus

ppio_gpus.api_key = "sk_xxx"

input_payload = {
    "workflow": {
        "4": {
            "class_type": "CheckpointLoaderSimple",
            "inputs": {"ckpt_name": "flux1-dev-fp8.safetensors"},
        },
        "5": {
            "class_type": "EmptyLatentImage",
            "inputs": {"width": 512, "height": 512, "batch_size": 1},
        },
        "6": {
            "class_type": "CLIPTextEncode",
            "inputs": {"clip": ["4", 1], "text": "a red apple on a table"},
        },
        "7": {
            "class_type": "CLIPTextEncode",
            "inputs": {"clip": ["4", 1], "text": "blurry, low quality"},
        },
        "3": {
            "class_type": "KSampler",
            "inputs": {
                "model": ["4", 0],
                "positive": ["6", 0],
                "negative": ["7", 0],
                "latent_image": ["5", 0],
                "seed": 42,
                "steps": 10,
                "cfg": 7,
                "sampler_name": "euler",
                "scheduler": "normal",
                "denoise": 1,
            },
        },
        "8": {
            "class_type": "VAEDecode",
            "inputs": {"samples": ["3", 0], "vae": ["4", 2]},
        },
        "9": {
            "class_type": "SaveImage",
            "inputs": {"filename_prefix": "test", "images": ["8", 0]},
        },
    },
    "output_node_id": "9",
}

endpoint = ppio_gpus.Endpoint("0f43a6867e05fddd")
run_request = endpoint.run(input_payload)

status = run_request.status()
print(f"Initial job status: {status}")

if status != "COMPLETED":
    # Polling with timeout for long-running tasks
    output = run_request.output(timeout=60)
else:
    output = run_request.output()
print(f"Job output: {output}")
```

`ppio-gpus` SDK 默认请求地址已经是 `https://async-public.serverless.ppinfra.com/v1`。这里设置的 `ppio_gpus.api_key` 只用于客户端提交、查询、取消任务，不用于 worker 拉取任务或回传结果。

如需使用 `ppio-gpus` SDK 编写自定义 worker handler、上报进度或上传图片/文件，请参见《PPIO GPUs SDK 使用指南》。

## 6. 管理 Async Serverless Endpoint

参考 [管理 serverless Endpoint](/gpu/manage-serverless-endpoint) 文档；
