文档中心>TI-ONE 训练平台>实践教程>TI-ONE 内置大模型推理镜像使用说明

TI-ONE 内置大模型推理镜像使用说明

最近更新时间:2024-05-23 11:54:41

我的收藏

推理镜像介绍

TI-ONE 训练平台内置了大模型的通用推理镜像,支持 huggingface 格式的 LLM 运行推理,提供兼容 OpenAI 接口格式文本对话的 HTTP 服务,并支持了腾讯自研的大模型推理加速能力。

当前预置了两个大模型推理镜像:
【推荐】angel-vllm:TI-ONE 团队基于开源 vllm 优化的版本,支持在线 int8 weight-only 和 LayerwiseSearchSMQ 等多种量化加速方式,对生产环境并发要求高的推荐使用此镜像;
angel-deepspeed:TI-ONE 团队基于开源 deepspeed 优化的版本,支持了算子、通信、量化等多项优化技术;

本文将介绍如何使用 TI-ONE 内置大模型推理镜像来启动提供大模型对话 API 的推理服务。


模型目录准备

首先您需要将要推理的模型放到自己的 CFS 文件系统中,模型目录结构与 huggingface 上的 Text Generation 类型的模型相同,模型格式支持 .bin 格式及 .safetensors 格式。
说明:
angel-vllm 镜像还支持推理使用 tilearn-llm 库进行 LayerwiseSearchSMQ 量化得到的模型,请确认模型目录中包含 smoothq_model-8bit-auto.safetensors 文件,并建议删除原始的非量化模型文件。
若您希望使用 TI-ONE 提供的 LayerwiseSearchSMQ 量化加速技术,请提工单反馈。


模型配置文件

为了让推理镜像更好地识别到您推理用的是什么模型,推荐在模型目录中额外保存一个 ti_model_config.json 配置文件,格式如下:
{"model_id": "Baichuan2-13B-Chat", "conv_template_name": "baichuan2-chat"}
字段含义:
model_id
conv_template_name
含义:模型名称
推荐值:若要运行的是 huggingface 上的开源模型,推荐直接指定为 huggingface 上的模型 ID,例如"Baichuan2-13B-Chat","Qwen1.5-14B-Chat",模型名称中是否包含斜杠"/"、及文本的大小写均不影响实际使用。
其他指定方式:若您不想在模型目录中增加ti_model_config.json 文件,也可以在启动服务时通过 MODEL_ID 环境变量来指定。
含义:对话模板名称
推荐值:若您的 model_id 与开源模型相同,且没有在 SFT 阶段修改过模型的对话模板,您可以不添加 conv_template_name 参数,推理镜像会尝试自动匹配;若您明确模型用了哪种对话模板,建议您手动指定对话模板。
其他指定方式:若您不想在模型目录中增加ti_model_config.json 文件,也可以在启动服务时通过 CONV_TEMPLATE 环境变量来指定。
目前常用的对话模板名称如下表所示,镜像剩余当前支持的对话模板列表详见:conversation.py
对话模板名称
支持的模型系列
generate
非对话模型(直接生成,无对话模板)
shennong_chat
腾讯行业大模型(行业大模型需要开通白名单)
llama-3
llama-3-8b-instruct、llama-3-70b-instruct 模型
llama-2
llama-2-chat 系列模型
qwen-7b-chat
qwen-chat 系列模型(chatml格式)
baichuan2-chat
baichuan2-chat 系列模型
baichuan-chat
baichuan-13b-chat 模型
chatglm3
chatglm3-6b 模型
chatglm2
chatglm2-6b 模型


启动推理服务

您可以通过腾讯云 TI 平台的【模型服务】-【在线服务】-【新建服务】入口来启动推理服务,以下是服务实例配置的指引。

模型来源及运行环境

大模型推理服务模型来源请选择【CFS】,路径直接填上文模型目录准备在 CFS 上的路径。
运行环境请选择 【内置 / LLM / angel-vllm】或【内置 / LLM / angel-deepspeed】,推荐选择 angel-vllm。

资源申请建议

大模型推理时需要的机器资源与模型的参数量相关,我们推荐按如下规则配置推理服务资源(使用包年包月资源组时,CPU 和内存建议按照机型的实际配置按占用的卡数等比例分配)
模型参数量
GPU 卡类型和数量
6 ~ 8B
L20 * 1 / A10 * 1 / A100 * 1 / V100 * 1
12 ~ 14B
L20 * 1 / A10 * 2 / A100 * 1 / V100 * 2
65 ~ 72B
L20 * 8 / A100 * 8
推荐使用 L20、A10、A100 显卡用于大模型推理。

angel-vllm 镜像高级设置

大多数情况下,您无需做任何修改直接启动镜像即可。若您有进一步的高级设置需求,可以通过【启动命令】或【环境变量】调整容器的启动参数。
镜像默认的启动命令为
run
目前支持的启动参数和环境变量如下(下表中同一行中启动参数与环境变量的作用是等价的,若同时设置了,启动命令的参数的优先级更高):
启动参数
环境变量
默认值
含义
MODEL_ID
模型名称,详见模型配置文件 model_id 的介绍
CONV_TEMPLATE
对话模板名称,详见模型配置文件 conv_template_name 的介绍
--model-path
MODEL_PATH
/data/model
模型加载路径,启动服务时指定的 CFS 路径默认会自动挂载到容器中的 "/data/model" 路径,大多数情况您不需修改
--num-gpus
TP
容器分配的显卡数量
模型并行推理的显卡数量,用于当单张显卡显存不够时,用多张显卡来加载模型。默认为您为单个容器分配的 GPU 资源数
--worker-num
WORKER_NUM
1
推理 Worker 数量,影响单个容器中跑推理服务的进程数,默认为1。一般分配给容器的 GPU 卡数等于 TP * WORKER_NUM
--limit-worker-concurrency
MAX_CONCURRENCY
128
每个推理 Worker 支持的最大并发数,正在处理的请求超过此数值时,新来的请求会进行排队
--dtype
DTYPE
float16
模型精度类型,可选值 ["auto", "float16", "bfloat16", "float32"],若配置 "auto" 则自动根据模型训练时使用的精度来配置
--seed
SEED
每次生成的随机种子,默认不指定
--max-model-len
MAX_MODEL_LEN
模型上下文长度
推理服务支持的最大上下文token数,默认自动读取模型配置信息的上下文长度,若一些长上下文的模型按默认配置加载显存不足,您可以手动设置此参数来调小此数值
--quantization
QUANTIZATION
none
量化加速模式,可选值 ["none", "ifq", "smoothquant", "auto"]
"none":表示关闭量化加速;
"ifq":表示开启在线 Int8 Weight-Only 量化,可以在效果基本不损失的情况下加速推理,并减少模型权重的显存占用;
"smoothquant":表示开启 LayerwiseSearchSMQ 量化 ,可以在效果略微损失的情况下进一步加速推理(依赖提前准备量化后的模型文件,当前仅部分模型支持);
"auto":表示自动判断量化模式,其中:
若机型的显卡不支持量化,自动关闭量化;
若模型目录中包含 smoothq_model-8bit-auto.safetensors 文件,会自动开启 LayerwiseSearchSMQ 量化加速;
其他情况下,默认开启在线 Int8 Weight-Only 量化加速(ifq);
若您对推理速度有较高要求,推荐您开启量化加速。
--api-keys
OPENAI_API_KEYS
API_KEY 列表,默认不设置。支持的格式为英文逗号分割的字符串,例如"sk-xxxx,sk-yyyy,sk-zzzz",设置后表示服务的 API 接口开启 Bearer Token 鉴权,用户请求时需要带上任意一个可用的 API_KEY 作为访问令牌,例如 curl 请求时带上 -H "Authorization: Bearer sk-xxxx",或者用 openai sdk 调用时设置 OPENAI_API_KEY。开启鉴权后,请求鉴权不通过会返回 HTTP 401 错误。 请注意:开启API_KEY鉴权后将不再支持在线体验,仅支持服务调用
--max-num-batched-tokens
max(模型上下文长度, 2048)
每次迭代最大处理的 token 数,默认取2048和模型支持的上下文长度的较大值;若显存富余较多,且输入文本较长,可以适当调大此参数,以获得更好的吞吐性能。
--max-num-seqs
256
每次迭代最大处理的生成序列数
--enforce-eager
False
是否强制开启 Pytorch 的 eager 模式,默认不开启,此时会额外使用 CUDA graph 做进一步加速,但会占用额外显存,并增加一些服务启动耗时。若启动报显存不足,您可以尝试启动命令中添加--enforce-eager参数来节约显存占用,但是推理性能会稍有下降。

angel-deepspeed 镜像高级设置

大多数情况下,您无需做任何修改直接启动镜像即可。若您有进一步的高级设置需求,可以通过【启动命令】或【环境变量】调整容器的启动参数。
镜像默认的启动命令为
run
目前支持的启动参数和环境变量如下(下表中同一行中启动参数与环境变量的作用是等价的,若同时设置了,启动命令的参数的优先级更高):
启动参数
环境变量
默认值
含义
MODEL_ID
模型名称,详见模型配置文件 model_id 的介绍
CONV_TEMPLATE
对话模板名称,详见模型配置文件 conv_template_name 的介绍
--model-path
MODEL_PATH
/data/model
模型加载路径,启动服务时指定的 CFS 路径默认会自动挂载到容器中的 "/data/model" 路径,大多数情况您不需修改
--num-gpus
TP
1
模型并行推理的显卡数量,默认为 1
--worker-num
WORKER_NUM
1
推理 Worker 数量,影响单个容器中跑推理服务的进程数,一般在分配给容器的 GPU 卡数大于设置的 --num-gpus 参数时才修改
--limit-worker-concurrency
MAX_CONCURRENCY
32
每个推理 Worker 支持的最大并发数,正在处理的请求超过此数值时,新来的请求会进行排队
--dtype
DTYPE
float16
模型精度类型,可选值 ["float16", "bfloat16", "float32"],若配置 "auto" 则自动根据模型训练时使用的精度来配置
--seed
SEED
每次生成的随机种子,默认不指定
--ds-dtype
DS_DTYPE
float16
表示使用 Angel-Deepspeed 加速时的精度类型,可选值 ["float16", "bfloat16", "int8"]
--max-batch-size
MAX_BATCH_SIZE
16
动态组 Batch 时,每个批次的请求数上限
--batch-wait-timeout
BATCH_WAIT_TIMEOUT
0.1
动态组 Batch 时,每个批次的最长等待时间(秒)


对话 API 接口文档

推理镜像容器启动后默认会监听容器的 8501 端口,您可以通过在线服务的【实例列表】-【进入容器】按钮直接进入容器调试。

若您需要在服务外部访问模型的对话接口,有以下几种方式:
1. 
在线体验
:直接使用前端在线体验页面访问或使用快速试一试开源大模型 - 第三步:在线体验模型效果中的接口访问,这种方式会经过内容审核,支持内置大模型和自定义大模型;
2. 
服务调用
:参考在线服务调用文档,在服务的【服务调用】标签页获取服务的公网或VPC内调用地址(使用内置大模型镜像的推理服务的此标签页面目前暂未展示,后续会展示自定义大模型的服务调用地址,平台内置大模型不支持);您可以基于此接口二次开发您的大模型应用,若有内容审核需求需要您自行接入;

1. 接口描述

POST /v1/chat/completions
对话接口,基本兼容 OpenAI 的 Chat 接口格式 (https://platform.openai.com/docs/api-reference/chat)

2. 输入参数

HTTP Header 参数
名称
Content-Type
application/json
HTTP 请求体参数
参数名称
必填
类型
描述
messages
Array of Message
会话内容,按对话时间序排列。
max_tokens
Integer
默认为模型支持的上下文长度,表示模型可生成内容的最长 token 数量,最大不能超过模型支持的上下文长度;
stream
Boolean
默认 false,表示非流式返回;设置为 true 时表示流式返回,如果对首字返回延迟敏感建议使用流式,以获得更好的体验。
temperature
Float
默认 0.7,取值区间为 [0.0, 2.0],表示采样温度,用于调整随机从生成模型中抽样的程度。 较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定。设置为 0 时,表示使用贪心采样策略,此时生成结果没有随机性。
此参数会影响模型生成的回复的质量和多样性。
top_p
Float
默认 1.0,取值区间为 (0.0, 1.0],表示将可能性之和不超过 top_p 的 tokens 列入候选名单。 影响输出文本的多样性,取值越大,生成文本的多样性越强。
此参数会影响模型生成的回复的质量和多样性。
top_k
Integer
默认 -1,表示禁用 top-k 过滤采样。当取值大于 0 时,会先过滤可能性最高的 top-k 个 tokens 后再使用 top_p 采样。
此参数会影响模型生成的回复的质量和多样性。
presence_penalty
Float
默认 0.0,取值区间为 [-2.0, 2.0],表示存在惩罚,为正时对于新 token 在现文本中是否出现进行惩罚,增大模型讨论新话题的概率。
此参数会影响模型生成的回复的质量和多样性。
frequency_penalty
Float
默认 0.0,取值区间为 [-2.0, 2.0],表示频率惩罚,为正时对于新 token 在现文本中的出现次数进行惩罚,降低模型重复同一文本的概率。
此参数会影响模型生成的回复的质量和多样性。
stop
Array of String
默认 None,表示无额外停止词;可以根据实际业务需要设置1个或多个停止词,遇到停止词时自动停止生成。
ignore_eos
Boolean
默认 false,表示不忽略停止词;设置为 true 时会强制生成 max_tokens 数量的 token 后才停止生成,一般只在调试时使用(此参数仅 angel-vllm 镜像支持)。
seed
Integer
默认 None,表示不设置随机种子;设置为具体的数值后会在每次生成时使用此随机种子,一般用于复现特定生成结果使用(此参数仅 angel-vllm 镜像支持)。
Message
参数名称
必填
类型
描述
role
String
对话消息对应的角色,当前支持以下取值:
system:表示系统提示(仅支持最开始出现一次)
user:表示用户
assistant:表示对话助手
在 message 中必须是 user 与 assistant 交替出现(一问一答)
content
String
对话消息的内容

3. 输出参数

非流式情况,会返回 content-type: application/json 数据,格式如下:
参数名称
类型
描述
id
String
对话的唯一标识符
choices
Array of Choice
生成结果
created
Integer
对话开始的 Unix 时间戳 (秒级)
model
String
对话使用的模型名称
object
String
本对象的类型,固定为 chat.completion
usage
Usage
token 数量统计信息:
包含生成结果中的 token 数量 completion_tokens;
提示词中的 token 数量 prompt_tokens;
请求中的总 token 数量(提示词和生成结果)total_tokens;
流式输出,会以 SSE 形式返回 content-type: text/event-stream; charset=utf-8 数据
流式输出每行返回的数据为 data: 分片,分片数据格式如下:
参数名称
类型
描述
id
String
对话的唯一标识符
choices
Array of StreamChoice
生成结果
created
Integer
对话开始的 Unix 时间戳 (秒级)
model
String
对话使用的模型名称
object
String
本对象的类型,固定为 chat.completion.chunk
流式输出会以 data: [DONE] 作为结尾,详见示例

4. 示例

示例1 非流式请求

输入示例
curl -H "content-type: application/json" http://localhost:8501/v1/chat/completions -d '{"messages":[{"role": "user", "content": "你好"}], "temperature": 0.0}'
输出示例
{"id":"chatcmpl-4aeRgYwnaYe4RzmmcyKtYs","object":"chat.completion","created":1698291242,"model":"baichuan-13b-chat","choices":[{"index":0,"message":{"role":"assistant","content":"你好!有什么我能帮到你的吗?"},"finish_reason":"stop"}],"usage":{"prompt_tokens":4,"total_tokens":16,"completion_tokens":12}}

示例2 流式请求

输入示例
curl -H "content-type: application/json" http://localhost:8501/v1/chat/completions -d '{"messages":[{"role": "user", "content": "你好"}], "temperature": 0.0, "stream": true}'
输出示例
data: {"id": "chatcmpl-3fYW8fqN3YYMJiebiZgpzZ", "model": "baichuan-13b-chat", "choices": [{"index": 0, "delta": {"role": "assistant"}, "finish_reason": null}]}

data: {"id": "chatcmpl-3fYW8fqN3YYMJiebiZgpzZ", "model": "baichuan-13b-chat", "choices": [{"index": 0, "delta": {"content": "你"}, "finish_reason": null}]}

data: {"id": "chatcmpl-3fYW8fqN3YYMJiebiZgpzZ", "model": "baichuan-13b-chat", "choices": [{"index": 0, "delta": {"content": "好!"}, "finish_reason": null}]}

data: {"id": "chatcmpl-3fYW8fqN3YYMJiebiZgpzZ", "model": "baichuan-13b-chat", "choices": [{"index": 0, "delta": {"content": "有什么我"}, "finish_reason": null}]}

data: {"id": "chatcmpl-3fYW8fqN3YYMJiebiZgpzZ", "model": "baichuan-13b-chat", "choices": [{"index": 0, "delta": {"content": "能帮"}, "finish_reason": null}]}

data: {"id": "chatcmpl-3fYW8fqN3YYMJiebiZgpzZ", "model": "baichuan-13b-chat", "choices": [{"index": 0, "delta": {"content": "到你的"}, "finish_reason": null}]}

data: {"id": "chatcmpl-3fYW8fqN3YYMJiebiZgpzZ", "model": "baichuan-13b-chat", "choices": [{"index": 0, "delta": {"content": "吗?"}, "finish_reason": null}]}

data: {"id": "chatcmpl-3fYW8fqN3YYMJiebiZgpzZ", "object": "chat.completion.chunk", "created": 1698290857, "model": "baichuan-13b-chat", "choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}]}

data: [DONE]

5. 开发者资源

Python SDK

可以直接使用 openai 的 sdk 来调用本推理服务,示例如下:
import os
from openai import OpenAI

# 示例1:容器本地访问地址
os.environ["OPENAI_BASE_URL"] = "http://127.0.0.1:8501/v1"
# 示例2:外网访问地址,可以通过服务调用页面获取(使用openai sdk时,地址后面加上v1)
os.environ["OPENAI_BASE_URL"] = "https://service-********.sh.tencentapigw.com:443/tione/v1"
# 若服务启动设置了 --api-keys 参数或 OPENAI_API_KEYS 环境变量开启了鉴权,OPENAI_API_KEY 需要设置为任意一个可用的 api_key;否则可以任意填写
os.environ["OPENAI_API_KEY"] = "EMPTY"
client = OpenAI()

# 非流式请求示例:
print("----- standard request -----")
completion = client.chat.completions.create(
model="model",
messages=[
{
"role": "user",
"content": "你好",
},
],
temperature=0.7,
top_p=1.0,
max_tokens=128,
)
print(completion.choices[0].message.content)
# 流式请求示例:
print("----- streaming request -----")
stream = client.chat.completions.create(
model="model",
messages=[
{
"role": "user",
"content": "你好",
},
],
temperature=0.7,
top_p=1.0,
max_tokens=128,
stream=True,
)
for chunk in stream:
if not chunk.choices or not chunk.choices[0].delta.content:
continue
print(chunk.choices[0].delta.content, end="")
print()



命令行对话 Demo

您也可以使用 python 常用的 requests 库来请求对话接口,下面是一个命令行中与大模型推理服务进行对话交互的 Demo 示例:
import argparse
import requests
import json


def chat(messages):
data = {
"messages": messages,
"temperature": args.temperature,
"max_tokens": args.max_tokens,
"top_p": args.top_p,
"stream": True, # 开启流式输出
}
header = {
"Content-Type": "application/json",
}
if args.token:
header["Authorization"] = f"Bearer {args.token}"

response = requests.post(f"{args.server}/v1/chat/completions", json=data, headers=header, stream=True) # 设置 stream=True 参数获取实时数据流
if response.status_code != 200:
print(response.json())
exit()

result = ""
print("Assistant: ", end = "", flush = True)
for part in response.iter_lines():
if part:
if "content" in part.decode("utf-8"):
content = json.loads(part.decode("utf-8")[5:])["choices"][0]["delta"]["content"] # 字符串过滤 data: 之后转成 json 格式再取文本
result += content
print(content, end = "", flush = True)
print("\\n")

return result


if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Chat CLI Demo.")
parser.add_argument("--server", type=str, default="http://127.0.0.1:8501")
parser.add_argument("--max-tokens", type=int, default=512)
parser.add_argument("--temperature", type=float, default=0.7)
parser.add_argument("--top_p", type=float, default=1.0)
parser.add_argument("--system", type=str, default=None)
parser.add_argument("--token", type=str, default=None)
args = parser.parse_args()

messages = []
if args.system:
messages.append({"role": "system", "content": args.system})

while True:
user_input = input("User: ")
messages.append({"role": "user", "content": user_input})
response = chat(messages)
messages.append({"role": "assistant", "content": response})