在线服务

模型包创建完成后,用户可以将模型包部署为在线服务,调用在线服务提供的 HTTP API 进行推理。

创建在线服务

  1. 左侧功能栏选择“部署上线->在线服务”;

  2. 单击右上角“创建在线服务”;

  3. 按照页面提示配置参数:

    表 207 创建在线服务参数

    名称

    必填项

    说明

    在线服务名称

    他人访问权限

    具体参见 他人访问权限

    版本号

    需要包含3位数字,如 1.0.0

    服务类型

    服务类型代表了在线服务的 API 协议

    不同服务类型的访问方式参见 访问在线服务 章节

    模型包

    只能选择对应类型的推理模型包

    环境变量

    覆盖模型包中的环境变量值

    此选项仅对指定了环境变量的模型包有效

    参数

    覆盖模型包中的参数值

    此选项仅对自定义服务类型且指定了运行参数的模型包有效

    单节点规格

    单个节点的算力规格

    节点名称

    指定在线服务可运行的节点,不可与“驱动版本”同时指定

    4.2 版本新增: 支持指定可运行节点

    驱动版本

    选择 MLU 或 GPU 规格时可用

    存储卷

    根据 在线服务目录结构 进行映射

    伸缩模式

    • 手动伸缩:固定在线服务节点数

    • 弹性伸缩:根据服务负载调整节点数

    弹性伸缩相关参数配置请参见 弹性伸缩 章节

    节点数

    指定手动伸缩时的节点数

    使用时长

    超过使用时长后自动停止

    4.2 版本新增: 支持使用时长。

    APP 认证

    若开启 APP 认证,访问 API 请参见 开启 APP 认证 章节

  4. 单击“添加”。

    ../../_images/create_realtime_service.png

    图 257 创建在线服务

节点规格说明

节点规格是在线服务中单个节点的资源配置。

4.0 版本新增: 支持根据所选规格查看集群可用资源

  1. 选择一个规格后,单击规格列表下面的 “集群可用资源” 链接;

  2. 页面下方会弹出一个表格,展示所选规格对应的可调度节点;

  3. 信息包括节点名称,状态,OS 和内核版本,内存, CPU 信息,AI 资源信息,驱动版本,适用算力规格和目前使用情况,以表格形式展示;

  4. 表格中内存,CPU 核数,AI 资源数量以分数形式展示,意义为(已经使用的资源 / 资源总量);

  5. 状态为空闲时,表示规格申请的资源小于等于节点目前可用的资源;状态为紧张时,表示规格申请的某个或某些资源大于节点目前可用的资源;

  6. 目前使用情况的条目显示格式为 1(1):application-name

    • 1: 物理卡,即板卡在节点中的位置;

    • (1): 虚拟卡,即板卡切分之后的虚拟卡序号;

    • application-name: 应用名称。

4.5 版本新增: 创建在线服务按照人工智能板卡型号筛选算力规格

  1. 选择非 CPU 类型的算力规格;

  2. 在算力规格类型下方会出现具体的人工智能板卡型号;

  3. 在板卡型号下方统计了当前所有在排队中的应用所需的各型号板卡数量;

  4. 选择一个或多个人工智能板卡型号,算力规格列表会根据所选型号过滤。

弹性伸缩

开启弹性伸缩后,在线服务能够根据负载动态调整节点数。

../../_images/set_realtime_service_hpa.png

图 258 设置弹性伸缩参数

参数说明:

名称

必填项

说明

节点数

设置最小和最大节点数

期望

设置期望指标和对应的数值。当监控实际值与期望值不相等时执行相应动作

期望条目可以设置多个

执行动作

设置当监控实际值与期望值不相等时执行的动作

弹性伸缩行为说明:

弹性伸缩控制器根据以下公式来计算期望节点数:

\[\text{期望节点数} = \lceil \text{当前节点数} \times \frac{\text{监控实际值}}{\text{期望值}} \rceil\]

即不小于 当前节点数 * (监控实际值 / 期望值) 的最小整数。

用户可以在界面上设置:

  1. 增加、减少节点数的时间间隔

  2. 每次最多增加、减少的节点数

  3. 每次最多增加、减少的节点数相对于当前节点数的百分比

注意

增加节点数和减少节点数的行为不同。

减少节点数时有 300s 稳定窗口。当 300s 稳定窗口中的所有监控实际值都小于期望值时, 才会执行减少节点数的动作。

增加节点数没有稳定窗口。

在线服务目录结构

在线服务容器内的目录结构为:

/
└── output

output 目录对应创建时选择的存储卷中的 /output/<在线服务版本>/<模型包名称> 目录。

查看在线服务详情

  1. 左侧功能栏选择“部署上线->在线服务”;

  2. 查找需要查看详情的在线服务,单击在线服务名称。

    在线服务详情页展示了在线服务的具体配置、监控日志 信息。 用户可以在页面中停止/启动、删除在线服务、调整使用时长、调整伸缩策略、流量分配、发布/下线版本等操作。

搜索在线服务

  1. 左侧功能栏选择“部署上线->在线服务”;

  2. 单击左上角搜索框;

  3. 在下拉列表中,可基于“名称”、“状态”、“创建人”、“算力规格”和“模型包”搜索在线服务。

停止在线服务

  1. 左侧功能栏选择“部署上线->在线服务”;

  2. 选择需要停止的在线服务,单击该服务的“操作”按钮;

  3. 在下拉列表中,单击“停止”;

  4. 单击“确认停止”。

启动在线服务

  1. 左侧功能栏选择“部署上线->在线服务”;

  2. 选择需要启动的在线服务,单击该环境的“操作”按钮;

  3. 在下拉列表中,单击“启动”;

  4. 重新选择“规格”、“伸缩模式”、“节点数”、“使用时长”;

  5. 单击“启动”。

删除在线服务

  1. 左侧功能栏选择“部署上线->在线服务”;

  2. 单个删除:查找需要删除的在线服务,单击该在线服务的“操作”按钮,在下拉列表中,单击“删除”;

  3. 批量删除:单击表格右上角“编辑”按钮,勾选多个需要删除的在线服务,单击表格右上角“删除”按钮;

  4. 单击“确认删除”。

访问在线服务

用户可以在详情页获取在线服务的访问地址:

../../_images/get_realtime_service_url.png

图 259 获取在线服务访问地址

TFServing 类型在线服务

TFServing 类型的在线服务采用 TFServing HTTP Predict API 进行推理。API 形式为:

POST http://host:port/v1/models:predict

不同于官方的 TFServing 协议,TFServing 类型在线服务的 URL 中不带有模型名。这样在发布金丝雀版本时可以选择不同的模型包而不用修改 URL。

输入数据格式:

{
  "signature_name": <string>,

  // 输入张量,以下输入形式只能选其一。
  // 以行形式输入
  "instances": <value>|<(nested)list>|<list-of-objects>
  // 以列形式输入
  "inputs": <value>|<(nested)list>|<object>
}

以行形式输入时的输出格式:

{
  "predictions": <value>|<(nested)list>|<list-of-objects>
}

以列形式输入时的输出格式:

{
  "outputs": <value>|<(nested)list>|<object>
}

用户可参照 TFServing RESTful API 访问方法 获取具体 API 调用方式。

Seldon 类型的在线服务

Seldon 类型的在线服务使用 Seldon HTTP Prediction API 进行推理,API 形式为:

POST http://host:port/api/v1.0/predictions

输入数据格式:

{
  // 输入数据,以下输入形式只能选其一
  // 以张量形式输入
  "data": {
    "names": <list>,
    "tensor": { "shape": <list>, "values": <list> }
  },
  // 以二进制形式输入
  "binData": <base64 encoded string>
  // 以 json 形式输入
  "jsonData": <json>
  // 以字符串形式输入
  "strData": <string>
}

输出数据由推理代码 predict() 函数的输出经过 JSON 序列化得到。 具体推理代码编写方法请参见 准备 Seldon 类型模型包推理代码

用户可参照 Seldon Prediction API 访问方法 获取具体 API 调用方式。

自定义类型的在线服务

5.1 版本新增: 自定义类型的在线服务

自定义类型的在线服务使用任意 HTTP API 格式进行推理。支持 server-sent events 和 websocket 协议。

开启 APP 认证

2.1 版本新增: 在线服务支持开启 APP 认证。

创建在线服务时,可以选择开启 APP 认证。

../../_images/enable_realtime_service_app_auth.png

图 260 开启在线服务 APP 认证

开启 APP 认证后,访问在线服务时需在 Header 中添加: Authorization: APPCODE <AppCode> 。 具体访问方式可 查看 APP 认证详情

编辑 APP 认证

在详情页右上角选择“编辑”,然后选择“APP 认证”即可进行编辑,如开启、关闭 APP 认证,添加新的 APP 认证。

../../_images/edit_realtime_service_app_auth.png

图 261 编辑在线服务 APP 认证

金丝雀发布

用户可以为推理服务发布金丝雀版本,并设置金丝雀版本的节点数、伸缩规则和流量比例。

../../_images/create_realtime_service_canary.png

图 262 创建金丝雀版本

可以在金丝雀发布的详情页分别设置常规版本和金丝雀版本的节点数和伸缩策略。

../../_images/modify_realtime_service_canary_replicas.png

图 263 修改金丝雀版本节点数

可以通过 HTTP Header 设置流量发送到特定的版本。HTTP Header 说明:

  • Canary: Never 把请求强制发送到常规版本

  • Canary: Always 把请求强制发送到金丝雀版本

可以调整金丝雀版本的流量比例,也可以让某个版本接管所有流量或者下线。 可以通过拖动滑块来调整流量比例。

../../_images/modify_realtime_service_traffic.png

图 264 修改金丝雀版本流量

如果设置了 HTTP Header,流量比例对于此请求将不生效。

调整使用时长

在“运行中”的在线服务的详情页右上角,选择“调整使用时长”,然后选择时长并确认,即可更新在线服务的过期时间。

../../_images/edit_realtime_service_duration.png

图 265 调整在线服务使用时长

根据过期时间排序

状态为“运行中”的在线服务将在列表页显示过期时间,该时间由开始运行的时间加上使用时长得到,若不限使用时长,“过期时间”栏将显示“不限”。 超过过期时间后在线服务将停止运行,状态变成为“过期”。非“运行中”的在线服务的过期时间栏将显示“–”。

  1. 左侧功能栏选择“在线服务”;

  2. 点击名称为“过期时间”的表头;

  3. 在列表页中,在线服务将通过过期时间排序;

在线测试

2.3 版本新增: 在网页上测试在线服务。

3.2 版本改动: 在线测试服务支持的检测框坐标字段由 dboxes 改为 dobjects

5.1 版本新增: 在线测试服务支持“文生文”和“文生图”模式。

详情页切换到“在线测试”标签页,可对在线服务进行测试。在线测试支持 3 种模式:“图像”, “文生文” 和 “文生图”。

图像模式

图像模式支持的在线服务需满足:

  1. 输入为图片(支持 PNG、JPG、SVG 格式)

  2. TFServing 类型的服务必须接受 Predict 请求 ,即输入格式需为:

    {"instances": [{"b64": "<base64 encoded image>"}]}
    

    TFServing 框架会自动对传入的 Base64 字符串解码。

    代码示例:

    该示例创建 Prediction API 请求签名,并将传入的 PNG 图片转换成模型可接受的 28 × 28 = 784 长度的矩阵:

    def preprocess(input_bytes):
      """
      接受 PNG 图片的二进制数据(已由 TFServing 框架自动 Base64 解码),
      输出 28 × 28 = 784 的矩阵。
    
      参数
      -----
      input_bytes: PNG 二进制数据。
      """
      images = tf.compat.v1.image.decode_png(tf.reshape(input_bytes, []), channels=1)
      images = tf.compat.v1.image.resize(images, [28, 28])
      images = tf.compat.v1.image.convert_image_dtype(images, dtype=tf.float32)
      images = tf.compat.v1.reshape(images, [784])
      images = tf.compat.v1.expand_dims(images, 0)
      return images
    
    
    def build_predict_signature(input_bytes):
      """
      创建 TFServing Prediction API 请求签名。
    
      参数
      -----
      input_bytes: string 类型 placeholder,存放 Base64 解码后的 PNG 二进制数据。
      """
      inputs = tf.compat.v1.saved_model.utils.build_tensor_info(input_bytes)
      signature_def = tf.compat.v1.saved_model.signature_def_utils.build_signature_def(
        inputs=[{"image_bytes": inputs}],
        outputs={"scores": tensor_info_y},
        method_name=tf.compat.v1.saved_model.signature_constants.PREDICT_METHOD_NAME,
      )
      signature_def_key = (
        tf.compat.v1.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY
      )
      builder.add_meta_graph_and_variables(
        sess,
        [tf.compat.v1.saved_model.tag_constants.SERVING],
        signature_def_map={
          signature_def_key: signature_def,
        },
        main_op=tf.compat.v1.tables_initializer(),
        strip_default_attrs=True,
      )
    
    
    # 创建 string 类型的 placeholder 作为 PNG 数据的输入
    input_bytes = tf.compat.v1.placeholder(tf.string, shape=[], name="input_bytes")
    build_predict_signature(input_bytes)
    images = preprocess(input_bytes)
    
  3. 自定义类型的服务输入格式需为:

    {"strData": "<base64 encoded image>"}
    

    用户需要在 predict 函数中进行 Base64 解码,代码示例:

    class inference_service(object):
      def predict(self, X, features_names):
        input = base64.b64decode(X)
        nparr = np.fromstring(input, np.uint8)
        raw_img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    
  4. 目标检测类型的在线服务输出格式需为:

    {
      "dclasses": ["<detection rule code>"],
      "dobjects": [["<detection object coordinate>"]],
      "dconfidences": ["<detection confidence>"]
    }
    
    表 208 在线测试支持的输出参数

    字段名

    类型

    描述

    dclasses

    string[]

    输出物体的检测类别列表。

    dobjects

    float[][]

    输出物体的检测框坐标列表。

    多个矩形构成数组的第一维;

    每四个值 [x, y, w, h] 构成一个矩形,为数组第二维。

    其中 [x, y] 为矩形左上角坐标, [w, h] 为矩形的宽和高。

    dconfidences

    float[]

    输出每种检测列表的置信度,用来衡量识别的准确度。

    如下图右侧展示的内容:

    ../../_images/predictor_test_result.png

    图 266 在线测试结果展示

文生文模式

文生文模式支持的在线服务需要同时支持 OpenAI List models APICreate chat completion API 格式。

List models API 请求示例:

curl http://host:port/v1/models

返回示例:

{
   "object": "list",
   "data": [
      {
         "id": "model-id-0",
         "object": "model",
         "created": 1686935002,
         "owned_by": "organization-owner"
      },
      {
         "id": "model-id-1",
         "object": "model",
         "created": 1686935002,
         "owned_by": "organization-owner",
      },
      {
         "id": "model-id-2",
         "object": "model",
         "created": 1686935002,
         "owned_by": "openai"
      },
   ],
   "object": "list"
}

Create chat completion API 请求示例:

curl http://host:port/v1/chat/completions \
   -H "Content-Type: application/json" \
   -d '{
      "model": "<model name>",
      "messages": [
         {
         "role": "system",
         "content": "You are a helpful assistant."
         },
         {
         "role": "user",
         "content": "Hello!"
         }
      ]
   }'

返回示例:

{
   "choices": [
      {
         "role": "assistant",
         "content": "Hello! How can I help you today?"
      }
   ]
}

文生文模式在线测试支持 server-sent events,即流式输出。

请求示例:

curl http://host:port/v1/chat/completions \
   -H "Content-Type: application/json" \
   -d '{
      "model": "<model name>",
      "messages": [
         {
         "role": "system",
         "content": "You are a helpful assistant."
         },
         {
         "role": "user",
         "content": "Hello!"
         }
      ],
      "stream": true
   }'

返回示例:

data: {"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}

data: {"choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]}

data: {"choices":[{"index":0,"delta":{"content":" How"},"finish_reason":null}]}

data: {"choices":[{"index":0,"delta":{"content":" can"},"finish_reason":null}]}

data: {"choices":[{"index":0,"delta":{"content":" I"},"finish_reason":null}]}

data: {"choices":[{"index":0,"delta":{"content":" assist"},"finish_reason":null}]}

data: {"choices":[{"index":0,"delta":{"content":" you"},"finish_reason":null}]}

data: {"choices":[{"index":0,"delta":{"content":" today"},"finish_reason":null}]}

data: {"choices":[{"index":0,"delta":{"content":"?"},"finish_reason":null}]}

data: {"choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

结果展示:

../../_images/predictor_test_result_text.png

图 267 在线测试文生文模式结果展示

文生图模式

文生图模式支持的在线服务要求如下:

  1. 服务推理 API 协议为 Websocket,路径为:“ws://host:port/generate”

  2. 客户端向在线服务发送的消息格式示例为:

    {
       "prompt": "<生成描述>",
       "negativePrompt": "<反向描述>",
       "cfg": 7.5,
       "step": 10,
       "width": 568,
       "height": 568
    }
    

    其中 cfg 代表描述相符系数,step 代表迭代步数,width 和 height 代表生成图片的宽和高。

  3. 服务返回的消息格式示例为:

    开始消息:

    {
       "type": "status",
       "message": "start"
    }
    

    进度消息:

    {
       "type": "progress",
       "message": "0.0"
    }
    

    结果消息:

    {
       "type": "output",
       "message": "<base64 encoded image>"
    }
    

Websocket 对话示例:

../../_images/predictor_test_websocket_image.png

图 268 在线测试文生图模式 Websocket 对话示例

结果展示:

../../_images/predictor_test_result_image.png

图 269 在线测试文生图模式结果展示

他人访问权限

4.1 版本新增: 支持为在线服务配置他人访问权限。

创建时,可以限制同项目内其他用户的访问权限,包括:“可读写”、“只读”和“不可读写”。 应用访问权限不得高于资源访问权限。 若管理员关闭共享权限,则他人访问权限只能为“不可读写”。

不同权限支持的操作如下:

表 209 他人支持的操作

可读写

只读

不可读写

查看详情

X

启动

X

X

停止

X

X

编辑

X

X

创建推理任务

X

创建金丝雀版本

X

X

编辑金丝雀发布

X

X

调整使用时长

X

X

删除

X

X