云服务器内容精选

  • 操作事项 ModelArts:设置资源池的网络 用户VPC:安装和配置正向代理 算法镜像:设置DNS代理和公网地址调用 ModelArts:设置资源池的网络 专属资源池的创建作业类型包含推理服务,选择的网络需打通VPC网络,如下图所示: 图2 创建专属资源池 图3 打通VPC 打通VPC可实现ModelArts资源池和用户VPC的网络打通。打通VPC前需要提前创建好VPC和子网,具体步骤请参考创建虚拟私有云和子网。 用户VPC:安装和配置正向代理 在安装正向代理前,需要先购买一台弹性 云服务器ECS (镜像可选择Ubuntu最新版本),并配置好弹性EIP,然后登录E CS 进行正向代理Squid的安装和配置,步骤如下: 如果没有安装Docker,执行以下命令进行Docker安装 curl -sSL https://get.daocloud.io/docker | sh 拉取Squid镜像 docker pull ubuntu/squid 创建主机目录,配置whitelist.conf和squid.conf 先创建主机目录: mkdir –p /etc/squid/ 添加whitelist.conf配置文件,内容为安全控制可访问的地址,如: .apig.cn-east-3.huaweicloudapis.com 添加squid.conf配置文件,内容如下: # An ACL named 'whitelist' acl whitelist dstdomain '/etc/squid/whitelist.conf' # Allow whitelisted URLs through http_access allow whitelist # Block the rest http_access deny all # Default port http_port 3128 然后设置主机目录和配置文件权限如下: chmod 640 -R /etc/squid 启动squid实例 docker run -d --name squid -e TZ=UTC -v /etc/squid:/etc/squid -p 3128:3128 ubuntu/squid:latest 如果whitelist.conf或squid.conf有更新,则进入容器刷新squid docker exec –it squid bash root@{container_id}:/# squid -k reconfigure 算法镜像:设置DNS代理和公网地址调用 设置代理 在代码中设置代理指向代理服务器私有IP和端口,如下所示: proxies = { "http": "http://{proxy_server_private_ip}:3128", "https": "http://{proxy_server_private_ip}:3128" } 服务器私有IP获取如下图所示: 图4 ECS私有IP 地址调用 在推理代码中,使用服务URL进行业务请求,如: https://e8a048ce25136addbbac23ce6132a.apig.cn-east-3.huaweicloudapis.com
  • 自定义镜像 创建为AI应用 参考从容器镜像中选择元模型导入元模型,您需要特别关注以下参数: 元模型来源:选择“从容器镜像中选择” 容器镜像所在的路径:选择已制作好的自有镜像 图4 选择已制作好的自有镜像 容器调用接口:指定模型启动的协议和端口号。请确保协议和端口号与自定义镜像中提供的协议和端口号保持一致。 镜像复制:选填,选择是否将容器镜像中的模型镜像复制到ModelArts中。 健康检查:选填,用于指定模型的健康检查。仅当自定义镜像中配置了健康检查接口,才能配置“健康检查”,否则会导致AI应用创建失败。 apis定义:选填,用于编辑自定义镜像的apis定义。模型apis定义需要遵循ModelArts的填写规范,参见模型配置文件说明。 本样例的配置文件如下所示: [{ "url": "/", "method": "post", "request": { "Content-type": "application/json" }, "response": { "Content-type": "application/json" } }, { "url": "/greet", "method": "post", "request": { "Content-type": "application/json" }, "response": { "Content-type": "application/json" } }, { "url": "/goodbye", "method": "get", "request": { "Content-type": "application/json" }, "response": { "Content-type": "application/json" } } ]
  • 本地构建镜像 以linux x86_x64架构的主机为例,您可以购买相同规格的ECS或者应用本地已有的主机进行自定义镜像的制作。 购买ECS服务器的具体操作请参考购买并登录弹性云服务器。镜像选择公共镜像,推荐使用ubuntu18.04的镜像。 图1 创建ECS服务器-选择X86架构的公共镜像 登录主机后,安装Docker,可参考Docker官方文档。也可执行以下命令安装docker。 curl -fsSL get.docker.com -o get-docker.sh sh get-docker.sh 获取基础镜像。本示例以Ubuntu18.04为例。 docker pull ubuntu:18.04 新建文件夹“self-define-images”,在该文件夹下编写自定义镜像的“Dockerfile”文件和应用服务代码“test_app.py”。本样例代码中,应用服务代码采用了flask框架。 文件结构如下所示 self-define-images/ --Dockerfile --test_app.py “Dockerfile” From ubuntu:18.04 # 配置华为云的源,安装 python、python3-pip 和 Flask RUN cp -a /etc/apt/sources.list /etc/apt/sources.list.bak && \ sed -i "s@http://.*security.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list && \ sed -i "s@http://.*archive.ubuntu.com@http://repo.huaweicloud.com@g" /etc/apt/sources.list && \ apt-get update && \ apt-get install -y python3 python3-pip && \ pip3 install --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple Flask # 复制应用服务代码进镜像里面 COPY test_app.py /opt/test_app.py # 指定镜像的启动命令 CMD python3 /opt/test_app.py “test_app.py” from flask import Flask, request import json app = Flask(__name__) @app.route('/greet', methods=['POST']) def say_hello_func(): print("----------- in hello func ----------") data = json.loads(request.get_data(as_text=True)) print(data) username = data['name'] rsp_msg = 'Hello, {}!'.format(username) return json.dumps({"response":rsp_msg}, indent=4) @app.route('/goodbye', methods=['GET']) def say_goodbye_func(): print("----------- in goodbye func ----------") return '\nGoodbye!\n' @app.route('/', methods=['POST']) def default_func(): print("----------- in default func ----------") data = json.loads(request.get_data(as_text=True)) return '\n called default func !\n {} \n'.format(str(data)) # host must be "0.0.0.0", port must be 8080 if __name__ == '__main__': app.run(host="0.0.0.0", port=8080) 进入“self-define-images”文件夹,执行以下命令构建自定义镜像“test:v1”。 docker build -t test:v1 . 您可以使用“docker images”查看您构建的自定义镜像。
  • 创建AI应用的自定义镜像规范 针对您本地开发的模型,在制作AI应用的自定义镜像时,需满足ModelArts定义的规范。 自定义镜像中不能包含恶意代码。 自定义镜像大小不超过50GB。 对于同步请求模式的AI应用,如果预测请求时延超过60s,会造成请求失败,甚至会有服务业务中断的风险,预测请求时延超过60s时,建议制作异步请求模式的镜像。 镜像对外接口 设置镜像的对外服务接口,推理接口需与config.json文件中apis定义的url一致,当镜像启动时可以直接访问。下面是mnist镜像的访问示例,该镜像内含mnist数据集训练的模型,可以识别手写数字。其中listen_ip为容器IP,您可以通过启动自定义镜像,在容器中获取容器IP。 请求示例 curl -X POST \ http://{listen_ip}:8080/ \ -F images=@seven.jpg 图1 listen_ip获取示例 返回示例 {"mnist_result": 7} (可选)健康检查接口 如果在滚动升级时要求不中断业务,那么必须在config.json文件中配置健康检查的接口,供ModelArts调用,在config.json文件中配置。当业务可提供正常服务时,健康检查接口返回健康状态,否则返回异常状态。 如果要实现无损滚动升级,必须配置健康检查接口。 自定义镜像如果需要在“在线服务”模块使用OBS外部存储挂载功能,需要新建一个OBS挂载专属目录如“/obs-mount/”,避免选择存量目录覆盖已有文件。OBS挂载仅开放对挂载目录文件新增、查看、修改功能不支持删除挂载目录文件对象,若需要删除文件请到OBS并行文件系统中手动删除。 健康检查接口示例如下。 URI GET /health 请求示例curl -X GET \ http://{listen_ip}:8080/health 响应示例 {"health": "true"} 状态码 表1 状态码 状态码 编码 状态码说明 200 OK 请求成功 日志文件输出 为保证日志内容可以正常显示,日志信息需要打印到标准输出。 镜像启动入口 如果需要部署批量服务,镜像的启动入口文件需要为“/home/run.sh”,采用CMD设置默认启动路径,例如Dockerfile如下: CMD ["sh", "/home/run.sh"] 镜像依赖组件 如果需要部署批量服务,镜像内需要安装python、jre/jdk、zip等组件包。 (可选)保持Http长链接,无损滚动升级 如果需要支持滚动升级的过程中不中断业务,那么需要将服务的Http的“keep-alive”参数设置为200s。以gunicorn服务框架为例,gunicorn缺省情形下不支持keep-alive,需要同时安装gevent并配置启动参数“--keep-alive 200 -k gevent”。不同服务框架参数设置有区别,请以实际情况为准。 (可选)处理SIGTERM信号,容器优雅退出 如果需要支持滚动升级的过程中不中断业务,那么需要在容器中捕获SIGTERM信号,并且在收到SIGTERM信号之后等待60秒再优雅退出容器。提前优雅退出容器可能会导致在滚动升级的过程中业务概率中断。要保证容器优雅退出,从收到SIGTERM信号开始,业务需要将收到的请求全部处理完毕再结束,这个处理时长最多不超过90秒。例如run.sh如下所示: #!/bin/bash gunicorn_pid="" handle_sigterm() { echo "Received SIGTERM, send SIGTERM to $gunicorn_pid" if [ $gunicorn_pid != "" ]; then sleep 60 kill -15 $gunicorn_pid # 传递 SIGTERM 给gunicorn进程 wait $gunicorn_pid # 等待gunicorn进程完全终止 fi } trap handle_sigterm TERM 父主题: 使用自定义镜像创建AI应用(推理部署)
  • Step1 检查环境 SSH登录机器后,检查NPU设备检查。运行如下命令,返回NPU设备信息。 npu-smi info 如出现错误,可能是机器上的NPU设备没有正常安装,或者NPU镜像被其他容器挂载。请先正常安装NPU设备和驱动,或释放被挂载的NPU。 检查docker是否安装。 docker -v #检查docker是否安装 如尚未安装,运行以下命令安装docker。 yum install -y docker-engine.aarch64 docker-engine-selinux.noarch docker-runc.aarch64
  • Step5 启动推理服务 配置推理服务需要的环境变量。 export ATB_LAYER_INTERNAL_TENSOR_REUSE=1 配置需要使用的NPU卡,例如:实际使用的是第1张和第2张卡,此处填写为0,1,以此类推。 export ASCEND_RT_VISIBLE_DEVI CES =0,1 NPU卡编号可以通过命令npu-smi info查询。 配置使用的显存,376T配置56,280T配置26。 export MAX_MEMORY_GB=56 启动推理服务,本服务使用的开源服务框架是TGI,具体命令参考https://huggingface.co/docs/text-generation-inference/main/en/basic_tutorials/launcher。该版本不支持https和身份认证机制。 可以根据官网说明修改参数。推荐参数配置如下。 表1 推理服务启动参数表 参数配置 推荐值 参数说明 --max-input-length 1024 推理时最大输入的tokens数量,默认值为1024,可以根据实际修改。该参数会影响推理性能。 --max-total-tokens 2048 推理时最大输入+最大输出的tokens数量,默认值为2048,可以根据实际修改。该参数会影响推理性能。 --max-batch-prefill-tokens 4096 在prefill阶段,最多会使用多少token,一般为--max-input-length的整数倍。该参数会影响推理性能。 --trust-remote-code 无 是否相信远程代码。 --max-waiting-tokens 1 推理进行时,新到达的请求需要等待多少增量推理后,切换成全量推理。 --max-concurrent-requests 1000 最大同时处理的请求数,超过后拒绝访问。 --waiting-served-ratio 0.2 当等待的请求数量达到增量推理的多少比例后,切换成全量推理。 TGI服务需要safetensor的权重格式,如果权重格式不是safetensor,首次启动时,需要先将权重转换成safetensor格式(自动进行)。首次启动耗时在5~10分钟。 如果权重格式包含safetensor,启动时间在1~3分钟。服务启动后,会打印如下信息。 2024-01-22T03:27:22.252926Z INFO text_generation_router: router/src/main.rs:239: Setting max batch total tokens to 970242024-01-22T03:27:22.252952Z INFO text_generation_router: router/src/main.rs:240: Connected
  • Step3 启动容器镜像 启动容器镜像前请先按照参数说明修改${}中的参数。 docker run -itd \ -p 8085:8085 \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ -v /etc/localtime:/etc/localtime \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /etc/ascend_install.info:/etc/ascend_install.info \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /var/log/npu/:/usr/slog \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -v ${dir}:${container_dir} \ --name ${container_name} \ ${image_id} \ /bin/bash 参数说明: -e ASCEND_VISIBLE_DEVICES=0-7,挂载机器上的0-7卡。 -p 8085:8085代表需要在宿主机和容器中绑定的端口。示例中,http server使用了8085端口,根据实际需要修改。 -v ${dir}:${container_dir} 代表需要在容器中挂载宿主机的目录。宿主机和容器使用不同大的文件系统,dir为宿主机中权重文件目录,container_dir为要挂载到的容器中的目录。为方便两个地址可以相同。请确保在容器中有weight_dir的权限。可以在宿主机中执行chmod 777 -R ${weight_dir}来放开权限 --name ${container_name} 容器名称,进入容器时会用到 {image_id} 为docker镜像的id,在宿主机上可通过docker images查询得到。
  • 启动服务 启动OpenAI服务器服务,具体操作命令如下,可以根据参数说明修改配置。 export ATB_LAYER_INTERNAL_TENSOR_REUSE=1 python -m vllm.entrypoints.openai.api_server --model ${container_model_path} \ --max-num-seqs=256 \ --max-model-len=4096 \ --max-num-batched-tokens=4096 \ --dtype=float16 \ --tensor-parallel-size=1 \ --block-size=128 \ --host=${docker_ip} \ --port=8080 \ --gpu-memory-utilization=0.9 \ --trust-remote-code \ --served-model-name="baichuan-13b-chat" 具体参数说明如下: --model ${container_model_path}:模型地址,模型格式是HuggingFace的目录格式。即Step4 获取权重文件上传的HuggingFace权重文件存放目录。 --max-num-seqs:最大同时处理的请求数,超过后拒绝访问。 --max-model-len:推理时最大输入+最大输出tokens数量,输入超过该数量会直接返回。 --max-num-batched-tokens:prefill阶段,最多会使用多少token,必须大于或等于--max-model-len,推荐使用4096或8192。 --dtype:模型推理的数据类型,当前只支持float16。 --tensor-parallel-size:模型并行数,13B模型一般为1即可。 --block-size:PagedAttention的block大小,推荐设置为128。 --host=${docker_ip}:服务部署的IP,${docker_ip}替换为容器实际的IP地址。可以在宿主机上通过docker inspect 容器ID |grep IPAddress 命令查询。 --port:服务部署的端口,和Step4 启动容器镜像中设置的端口保持一致,否则不能在容器外访问推理服务。 --gpu-memory-utilization:NPU使用的显存比例,复用原vLLM的入参名称,默认为0.9。 --trust-remote-code:是否相信远程代码,baichuan-13b必须增加此项。 --served-model-name:模型名称。
  • 请求服务 使用命令测试推理服务是否正常启动。 curl -X POST http://127.0.0.1:8080/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "baichuan-13b-chat", "messages": [ { "role": "user", "content": "你是谁?" } ], "max_tokens": 100, "top_k": -1, "top_p": 1, "temperature": 0, "ignore_eos": false, "stream": false }' 服务的API与vLLM官网相同:https://github.com/vllm-project/vllm。此处介绍关键参数。 表1 请求服务参数说明 参数 是否必选 默认值 参数类型 描述 model 是 - Str 模型名称,参数--served-model-name的值。 messages 是 - LIst 请求输入的问题。 max_tokens 否 16 Int 每个输出序列要生成的最大tokens数量。 top_k 否 -1 Int 控制要考虑的前几个tokens的数量的整数。设置为 -1 表示考虑所有tokens。 适当降低该值可以减少采样时间。 top_p 否 1.0 Float 控制要考虑的前几个tokens的累积概率的浮点数。必须在 (0, 1] 范围内。设置为 1 表示考虑所有toekns。 temperature 否 1.0 Float 控制采样的随机性的浮点数。较低的值使模型更加确定性,较高的值使模型更加随机。0表示贪婪采样。 stop 否 None None/Str/List 用于停止生成的字符串列表。返回的输出将不包含停止字符串。 例如:["你", "好"],生成文本时遇到"你"或者"好"将停止文本生成。 stop_token_ids 否 None List 用于停止生成的token列表。返回的输出将包含停止tokens,除非停止tokens是特殊tokens。 ignore_eos 否 False Bool 是否忽略EOS tokens并继续生成EOS tokens后的tokens。False表示不忽略。 presence_penalty 否 0.0 Float 基于生成文本中新tokens是否已出现来对其进行惩罚的浮点数。大于0的值鼓励模型使用新的tokens,小于0的值鼓励模型重复使用tokens。 取值范围为[-2, 2] frequency_penalty 否 0.0 Float 基于生成文本中新tokens的频率来对其进行惩罚的浮点数。大于0的值鼓励模型使用新的tokens,小于0的值鼓励模型重复使用tokens。 取值范围为[-2, 2] skip_special_tokens 否 True Bool 是否跳过输出中的特殊tokens。默认为True,表示跳过。 stream 否 False Bool 是否开启流式推理。默认为False,表示不开启流式推理。 查看返回是否符合预期
  • Step1 获取推理代码 根据下表链接下载“ascendcloud-llmframework_6.3.902_*.tar.gz”解压获得ascend-vllm代码包,将文件夹中的vllm-dev文件夹上传至OBS中预训练权重合并及转换或LoRA微调权重合并及转换输出的模型同级目录下。 表1 准备代码 代码包名称 代码说明 下载地址 ascendcloud-llmframework_6.3.902_*.tar.gz Ascend-vllm插件 获取路径:Support网站。 说明: 如果没有下载权限,请您联系所在企业的华为方技术支持购买资源。 创建推理脚本run-vllm.sh,脚本内容如下: source /home/ma-user/.bashrc export ASCEND_RT_VISIBLE_DEVICES=${ASCEND_RT_VISIBLE_DEVICES} export PYTHONPATH=$PYTHONPATH:/home/mind/model/vllm-dev cd /home/mind/model/vllm-dev/ python /home/mind/model/vllm-dev/vllm/entrypoints/api_server.py --model="${model_path}" --ssl-keyfile="/home/mind/model/key.pem" --ssl-certfile="/home/mind/model/cert.pem" --tensor-parallel-size 1 --gpu-memory-utilization 0.95 --max-model-len=4096 --trust-remote-code --dtype="float16" --host=0.0.0.0 --port=8080 并将推理脚本上传至OBS中预训练权重合并及转换或LoRA微调权重合并及转换输出的模型同级目录下。 参数说明: ${ASCEND_RT_VISIBLE_DEVICES} 使用的NPU卡,单卡设为0即可,4卡可设为:0,1,2,3。 ${model_path} 模型路径,填写为'/home/mind/model/权重文件夹名称',如:'home/mind/model/llama2-13b-sft-hf'。 --tensor-parallel-size并行卡数。 --hostname服务部署的IP,使用本机IP 0.0.0.0。 --port服务部署的端口。 推理启动脚本必须名为run_vllm.sh,不可修改其他名称。 hostname和port也必须分别是0.0.0.0和8080不可更改。 通过openssl创建ssl pem证书,并上传至OBS桶。 以预训练权重合并及转换为例,在转换后的模型目录“obs://standard-llama2-13b/code/outputs/job-name”上传上述文件后,结果如下: 图1 上传ssl pem证书
  • 获取软件 表1 软件名称 软件名称 说明 下载地址 Ascend-cann-atb_7.0.0_linux-aarch64_abi0.run 推理依赖软件 https://ascend-cloud-llm-infer-ops.obs.cn-southwest-2.myhuaweicloud.com/version_packages/atb_llm_7.0.T61.B010.tar Ascend-cann-llm_7.0.0_linux-aarch64_torch2.0.1-abi0.tar.gz ascendcloud-llmframework_6.3.902_*.tar.gz 说明: 这里的*表示具体的时间戳。 Ascend-vllm插件 获取路径:Support网站。 说明: 如果没有软件下载权限,请联系您所在企业的华为方技术支持下载获取。 Baichuan-13b 从Huggingface下载的预训练权重文件 https://huggingface.co/baichuan-inc/Baichuan-13B-Base https://huggingface.co/baichuan-inc/Baichuan-13B-Chat (推荐) 下载完毕后的权重文件夹包含以下内容,此处以Baichuan-13b-chat为例。 Baichuan-13B-Chat ├── Baichuan-13B 模型社区许可协议.pdf ├── Community License for Baichuan-13B Model.pdf ├── config.json ├── configuration_baichuan.py ├── generation_config.json ├── generation_utils.py ├── gitattributes.txt ├── handler.py ├── modeling_baichuan.py ├── model.safetensors.index.json ├── pytorch_model-00001-of-00003.bin ├── pytorch_model-00002-of-00003.bin ├── pytorch_model-00003-of-00003.bin ├── pytorch_model.bin.index.json ├── quantizer.py ├── README.md ├── requirements.txt ├── special_tokens_map.json └── tokenization_baichuan.py
  • 完整的Dockerfile参考 FROM tensorflow/serving:2.8.0 RUN useradd -d /home/ma-user -m -u 1000 -g 100 -s /bin/bash ma-user RUN apt-get update && apt-get -y --no-install-recommends install nginx && apt-get clean RUN mkdir /home/mind && \ mkdir -p /etc/nginx/keys && \ mkfifo /etc/nginx/keys/fifo && \ chown -R ma-user:100 /home/mind && \ rm -rf /etc/nginx/conf.d/default.conf && \ chown -R ma-user:100 /etc/nginx/ && \ chown -R ma-user:100 /var/log/nginx && \ chown -R ma-user:100 /var/lib/nginx && \ sed -i "s#/var/run/nginx.pid#/home/ma-user/nginx.pid#g" /etc/init.d/nginx ADD nginx /etc/nginx ADD run.sh /home/mind/ ENV MODEL_BASE_PATH /home/mind ENV MODEL_NAME model ENTRYPOINT [] CMD /bin/bash /home/mind/run.sh