# djl-serving deepspeed 模型部署流程 (python mode)
# 相关介绍
# DeepSpeed
deepspeed 是一款微软发布的深度学习优化软件套件,能提供一键深度学习加速推理和训练能力。
DeepSpeed 为使用 DeepSpeed、Megatron 和 HuggingFace 训练的基于兼容 Transformer 的模型提供无缝推理模式,无需修改模型即可实现高效推理。
# djl-serving
DJL Serving 是由 DJL 提供支持的高性能通用独立模型服务解决方案。它将深度学习模型或工作流程包装成服务,并通过 HTTP 提供它们。
djl-serving python mode
djl-serving 推理服务支持 python 模式,用户只需准备一个 Python 脚本文件即可执行,除此之外,djl-serving 还提供如下支持:
Java 模式:用户需要准备 Java 前 / 后处理脚本和模型文件。
二进制模式:用户只需要准备一个模型文件,我们就可以运行 tensor-in,tensor out 操作。
# 相应关系
对应的推理服务流程:
用户向 DJL-Serving 请求 -->DJL-serving 将请求定位到模型并将输入交给推理引擎(DeepSpeed)-->DeepSpeed 对 pytorch 模型进行自动优化,进行推理,推理结果返还给 DJL-Serving-->DJL-Serving 响应用户请求
# 测试模型
使用的测试模型为 Qwen-1.8B
通义千问 - 1.8B(Qwen-1.8B 是阿里云研发的通义千问大模型系列的 18 亿参数规模的模型。Qwen-1.8B 是基于 Transformer 的大语言模型,在超大规模的预训练数据上进行训练得到。预训练数据类型多样,覆盖广泛,包括大量网络文本、专业书籍、代码等。
# docker 部署
首先拉取 djl-serving:0.19.0-deepspeed
镜像
1 docker pull deepjavalibrary/djl-serving:0.19.0-deepspeed
# 使用 docker compose
首先创建 model
目录
建立使用 gpu 的容器
创建 docker-compose.yaml
文件并添加如下文本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 --- version: "2.1" services: djl_deepspeed: image: deepjavalibrary/djl-serving:0.19.0-deepspeed container_name: djl_deepspeed environment: - PUID=1000 - PGID=1000 - TZ=Etc/UTC - WEBUI_PORT=8080 - NVIDIA_DRIVER_CAPABILITIES=all - NVIDIA_VISIBLE_DEVICES=0 deploy: resources: reservations: devices: - driver: "nvidia" device_ids: ["0" ] capabilities: ["gpu" ] volumes: - ./models:/opt/ml/model ports: - 8080:8080 restart: no
# 构建模型结构
创建 serving.properties
并写入如下配置项
1 2 3 4 engine=DeepSpeed option.model_id=Qwen/Qwen-1-8B option.tensor_parallel_degree=1 option.enable_streaming=true
创建 model.py
,写入代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 from modelscope import AutoModelForCausalLM, AutoTokenizerfrom transformers import pipelineimport deepspeedimport osimport torchfrom djl_python import Input, Outputdef get_model (): model_name = 'Qwen-1_8B-Chat' tokenizer = AutoTokenizer.from_pretrained(model_name, revision='master' , trust_remote_code=True ) model = AutoModelForCausalLM.from_pretrained(model_name, trust_remote_code=True ) tensor_parallel = int (os.getenv('TENSOR_PARALLEL_DEGREE' , '1' )) local_rank = int (os.getenv('LOCAL_RANK' , '0' )) generator = pipeline('text-generation' , model=model, tokenizer=tokenizer, device=local_rank) generator.model = deepspeed.init_inference(generator.model, mp_size=tensor_parallel, dtype=torch.float , replace_method='auto' , replace_with_kernel_inject=True ) return generator predictor = get_model() def handle (inputs: Input ) -> None : global predictor if predictor is None : predictor = get_model() if inputs.is_empty(): return None data = inputs.get_as_string() result = predictor(data, do_sample=True , min_length=50 ) return Output().add(result)
# 下载模型
模型文件为使用 snapshot_download
从 modelscope/huggingface 中下载的快照
模型下载脚本如下
1 2 3 from modelscope import snapshot_download snapshot_download("Qwen/Qwen-1_8B-Chat" ,local_dir="./models/Qwen" , revision='master' )
# 安装依赖
进入容器中,进入 /opt/ml/model/Qwen
模型目录
# 自动化安装
正常情况下,容器在启动时会自动检测模型目录和存在的 requirements.txt
依赖文件,如果出现异常需要移除该文件,并手动进入容器内安装依赖。
# 手动安装
pip install -r requirements.txt
# 测试
容器内服务启动成功后, docker logs djl_deepspeed
应该会有如下输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [INFO ] PyProcess - [1,0]<stdout>:Python engine started. [INFO ] PyProcess - Model [Qwen] initialized. [INFO ] PyModel - Qwen model loaded in 24574 ms. [INFO ] FolderScanPluginManager - scanning for plugins... [INFO ] FolderScanPluginManager - scanning in plug-in folder :/opt/djl/plugins [INFO ] PropertyFilePluginMetaDataReader - Plugin found: console/jar:file:/opt/djl/plugins/management-console-0.19.0.jar!/META-INF/plugin.definition [INFO ] PropertyFilePluginMetaDataReader - Plugin found: static-file-plugin/jar:file:/opt/djl/plugins/static-file-plugin-0.19.0.jar!/META-INF/plugin.definition [INFO ] FolderScanPluginManager - Loading plugin: {console/jar:file:/opt/djl/plugins/management-console-0.19.0.jar!/META-INF/plugin.definition} [INFO ] PluginMetaData - plugin console changed state to INITIALIZED [INFO ] FolderScanPluginManager - Loading plugin: {static-file-plugin/jar:file:/opt/djl/plugins/static-file-plugin-0.19.0.jar!/META-INF/plugin.definition} [INFO ] PluginMetaData - plugin static-file-plugin changed state to INITIALIZED [INFO ] PluginMetaData - plugin console changed state to ACTIVE reason: plugin ready [INFO ] PluginMetaData - plugin static-file-plugin changed state to ACTIVE reason: plugin ready [INFO ] FolderScanPluginManager - 2 plug-ins found and loaded. [INFO ] ModelServer - Initialize BOTH server with: EpollServerSocketChannel. [INFO ] ModelServer - BOTH API bind to: http://0.0.0.0:8080
此时从宿主机可以通过 curl
命令进行测试
1 curl -X POST http://localhost:8080/predictions/Qwen --header 'content-type: text/string' --data-raw '通义千问是'
预期响应
1 2 3 4 5 [ { "generated_text" :"通义千问是阿里云研发的超大规模语言模型,具有什么样的能力?\nA. A:理解自然语言、生成人类对话\nB. B:理解复杂文本、总结文本内容\nC. C:生成艺术作品、写故事\nD. D:写作诗歌、歌词\n\n答案:A\n" } ]