跳转到主要内容
首次操作时,请先完成账号的注册、实名认证和账户充值。详情请参见新手指引 本文以部署一个基于 PPIO SDK 的 ComfyUI worker 镜像 image.ppinfra.com/prod-gpucloudpublic/comfyui-worker:v0.0.1 为例,介绍如何创建一个 Async Serverless Endpoint。

1. 准备容器镜像

您需要提前将运行环境打包成 Docker 镜像,并上传至镜像仓库。支持指定公共镜像仓库地址和私有镜像仓库地址(需提供镜像仓库认证凭证)。
  • 您可以将镜像上传至 Docker Hub,目前平台已针对该站点提供镜像预热服务。详情请参见使用镜像预热服务
本示例使用 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 如有更多需求,请联系我们

3. 创建云存储(可选)

如果有共享存储和持久化存储的需求,可以在存储管理页面创建云存储,然后在创建实例时为容器挂载云存储。详情请参见管理云存储

4.创建 Endpoint

  1. 进入 Serverless GPUs 页面,选择规格,单击「创建 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 24GBGPUs / Worker 设置为 1
  • Type
    • Endpoint类型,请选择 异步(Async)
  • 弹性策略
    • 策略类型请选择 队列请求数策略
    • 单 worker 目标并发请配置为 1。本示例中的 ComfyUI worker 每个 Worker 同一时间处理一个 job;当排队请求数超过当前 Worker 可处理能力时,平台会根据队列请求数自动扩容,直到达到最大 Worker 数。
  • 镜像配置
    • 镜像地址:要部署的镜像的地址。例如 image.ppinfra.com/prod-gpucloudpublic/comfyui-worker:v0.0.1
    • 镜像仓库凭证:如果指定的镜像为私有镜像,需要配置镜像仓库访问凭证才能拉取镜像。您可以在安全凭证管理页面创建凭证。
    • HTTP 端口:Worker 对外开放的 HTTP 端口。
    • 容器启动命令:容器启动时执行的命令。
  • 存储配置
    • 系统盘:每个 Worker 的系统盘容量大小。
    • 云存储:如果要挂载云存储,请选择云存储。详情请参见管理云存储
  • 其他
    • 健康检查路径:此参数暂未启用。
    • 环境变量:设置服务所需的环境变量,以便在 Worker 启动时自动初始化。以腾讯云对象存储 COS 示例如下:
    Bash
      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 运行时鉴权信息由平台注入。
  1. 确认费用信息,单击「一键部署」。

5.访问服务

  1. Serverless GPUs 页面,找到新创建的 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
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 如下,其中的 idjob_id
JSON
{"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
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
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
curl -X GET https://async-public.serverless.ppinfra.com/v1/0f43a6867e05fddd/health \
  -H 'Authorization: Bearer sk_xxxx'
得到的 response 如下:
JSON
{
  "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
pip install ppio-gpus
Python
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 文档;