初学大模型之——大模型推理部署手册(Docker+vllm)

一、dokcer

(一)Dockferfile介绍

以Qwen-72B模型为例,该模型提供了一个Dokcerfile文件,因此推荐使用Dockerfile来构建镜像。

关于Qwen的Dockerfile:

https://github.com/QwenLM/Qwen/tree/23a01b06960a1f3976b0746445f503bfaa813613/docker

关于Dockerfile文件内容的说明:

https://blog.csdn.net/weixin_53742691/article/details/130087006

Dockerfile文件内容的基本定义:

  • FROM

语法:FROM <image>[:<tag>] 解释:设置要制作的镜像基于哪个镜像,FROM指令必须是整个Dockerfile的第一个指令,如果指定的镜像不存在默认会自动从Docker Hub上下载。
  • MAINTAINER

语法:MAINTAINER <name> 解释:MAINTAINER指令允许你给将要制作的镜像设置作者信息
  • RUN

语法: ①RUN <command> #将会调用/bin/sh -c <command> ②RUN ["executable", "param1", "param2"] #将会调用exec执行,以避免有些时候shell方式执行时的传递参数问题,而且有些基础镜像可能不包含/bin/sh 解释:RUN指令会在一个新的容器中执行任何命令,然后把执行后的改变提交到当前镜像,提交后的镜像会被用于Dockerfile中定义的下一步操作,RUN中定义的命令会按顺序执行并提交,这正是Docker廉价的提交和可以基于镜像的任何一个历史点创建容器的好处,就像版本控制工具一样。
  • CMD

语法:①CMD ["executable", "param1", "param2"] #将会调用exec执行,首选方式 ②CMD ["param1", "param2"] #当使用ENTRYPOINT指令时,为该指令传递默认参数 ③CMD <command> [ <param1>|<param2> ] #将会调用/bin/sh -c执行 解释:CMD指令中指定的命令会在镜像运行时执行,在Dockerfile中只能存在一个,如果使用了多个CMD指令,则只有最后一个CMD指令有效。当出现ENTRYPOINT指令时,CMD中定义的内容会作为ENTRYPOINT指令的默认参数,也就是说可以使用CMD指令给ENTRYPOINT传递参数。 注意:RUN和CMD都是执行命令,他们的差异在于RUN中定义的命令会在执行docker build命令创建镜像时执行,而CMD中定义的命令会在执行docker run命令运行镜像时执行,另外使用第一种语法也就是调用exec执行时,命令必须为绝对路径。
  • EXPOSE

语法:EXPOSE <port> [ ...] 解释:EXPOSE指令用来告诉Docker这个容器在运行时会监听哪些端口,Docker在连接不同的容器(使用–link参数)时使用这些信息。
  • ENV

语法:ENV <key> <value> 解释:ENV指令用于设置环境变量,在Dockerfile中这些设置的环境变量也会影响到RUN指令,当运行生成的镜像时这些环境变量依然有效,如果需要在运行时更改这些环境变量可以在运行docker run时添加–env <key>=<value>参数来修改。 注意:最好不要定义那些可能和系统预定义的环境变量冲突的名字,否则可能会产生意想不到的结果。
  • ADD

语法:ADD <src> <dest> 解释:ADD指令用于从指定路径拷贝一个文件或目录到容器的指定路径中,<src>是一个文件或目录的路径,也可以是一个url,路径是相对于该Dockerfile文件所在位置的相对路径,<dest>是目标容器的一个绝对路径,例如/home/yooke/Docker/Dockerfile这个文件中定义的,那么ADD /data.txt /db/指令将会尝试拷贝文件从/home/yooke/Docker/data.txt到将要生成的容器的/db/data.txt,且文件或目录的属组和属主分别为uid和gid为0的用户和组,如果是通过url方式获取的文件,则权限是600。 注意:①如果执行docker build – < somefile即通过标准输入来创建时,ADD指令只支持url方式,另外如果url需要认证,则可以通过RUN wget …或RUN curl …来完成,ADD指令不支持认证。 ②<src>路径必须与Dockerfile在同级目录或子目录中,例如不能使用ADD ../somepath,因为在执行docker build时首先做的就是把Dockerfile所在目录包含子目录发送给docker的守护进程。 ③如果<src>是一个url且<dest>不是以”/“结尾,则会下载文件并重命名为<dest>。 ④如果<src>是一个url且<dest>以“/”结尾,则会下载文件到<dest>/<filename>,url必须是一个正常的路径形式,“http://example.com”像这样的url是不能正常工作的。 ⑤如果<src>是一个本地的压缩包且<dest>是以“/”结尾的目录,则会调用“tar -x”命令解压缩,如果<dest>有同名文件则覆盖,但<src>是一个url时不会执行解压缩。
  • COPY

语法:COPY <src> <dest> 解释:用法与ADD相同,不过<src>不支持使用url,所以在使用docker build – < somefile时该指令不能使用。

(二)使用Dockerfile的具体步骤

1、构建镜像:

进入Dockerfile所在目录,确保本目录下有该文件:

使用如下命令可构建镜像:

docker build -f 指定的Dockerfile(默认名不需要指定,若为'Dockerfile-cu121') -t 指定的镜像名称 .

如果是在示例的当前目录下构建,e.g. :(注意一定要有.-这是个英文的点)

Docker build -t dacongming(镜像名):v1(版本,可以自行制定,不指定则默认为latest) . 
2、查看构建好的镜像:
docker images

可以查看当前本机当前包含的所有镜像:

3、启动docker容器:
docker run --gpus all -v /需要挂载的本地目录:/挂载到的容器内目录 -itd --name 容器名 镜像名:版本

例:以使用home/dacongming/llm:v1 为例,通过pwd获得想要挂载的本地/mnt/user/dacongming/Qwen,需要挂载到的容器内目录为/data(事先在dockerfile里面通过mkdir data 创建过,具体命令如下:

docker run --gpus all -v /mnt/user/dacongming/Qwen-:/data -itd --name audio home/dacongming/llm:v1

4、查看正在运行的容器:
docker ps

会显示当前正在运行的容器

docker ps -a 

会包含之前启动过但是因为退出被暂停的容器

进入容器之前需要确保其正在运行,如果docker ps未显示镜像,但之前docker run过可以使用docker ps -a查看之前构建好的,可使用docker start 容器id重新启动:

例:

1、使用docker ps -a

2、docker start 123456abcd

5、进入容器

检查当前容器正在运行后,可使用下列命令进入容器即可正常使用。

方式一:(exit后会stop容器,不推荐;如果不小心exit 可以通过docker start 容器id 重启)

docker attach 容器id

方式二:

docker exec -it 容器id bash

例:docker exec -it 123456abcd bash

二、推理加速

使用vllm框架可以加速大模型推理,在业务场景中可提升推理性能由15s -> 5s

(一)vllm推理加速的原理:

vLLM 是在加州大学伯克利分校开发,配备了PagedAttention的vLLM重新定义了 LLM 服务的最新技术水平:它的吞吐量比 HuggingFace Transformers 高出 24 倍,且无需更改任何模型架构。

链接:https://blog.vllm.ai/2023/06/20/vllm.html

(二)vllm安装教程:

参考:https://blog.csdn.net/tdaajames/article/details/136740761

安装flash-attention:https://github.com/Dao-AILab/flash-attention

具体步骤:

1、安装flash-attention:
2、安装vllm(需要版本对应):

pip install "vllm>=0.4.3"

(三)vllm实践:

不使用vllm加速的代码:

from modelscope import AutoModelForCausalLM, AutoTokenizer
from modelscope import GenerationConfig

tokenizer = AutoTokenizer.from_pretrained("qwen/Qwen-7B-Chat", trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained("qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True).eval()

# 第一轮对话 1st dialogue turn
response, history = model.chat(tokenizer, "你好", history=None)
print(response)
# 你好!很高兴为你提供帮助。

# 第二轮对话 2nd dialogue turn
response, history = model.chat(tokenizer, "给我讲一个年轻人奋斗创业最终取得成功的故事。", history=history)
print(response)
# 这是一个关于一个年轻人奋斗创业最终取得成功的故事。
# 故事的主人公叫李明,他来自一个普通的家庭,父母都是普通的工人。从小,李明就立下了一个目标:要成为一名成功的企业家。
# 为了实现这个目标,李明勤奋学习,考上了大学。在大学期间,他积极参加各种创业比赛,获得了不少奖项。他还利用课余时间去实习,积累了宝贵的经验。
# 毕业后,李明决定开始自己的创业之路。他开始寻找投资机会,但多次都被拒绝了。然而,他并没有放弃。他继续努力,不断改进自己的创业计划,并寻找新的投资机会。
# 最终,李明成功地获得了一笔投资,开始了自己的创业之路。他成立了一家科技公司,专注于开发新型软件。在他的领导下,公司迅速发展起来,成为了一家成功的科技企业。
# 李明的成功并不是偶然的。他勤奋、坚韧、勇于冒险,不断学习和改进自己。他的成功也证明了,只要努力奋斗,任何人都有可能取得成功。

# 第三轮对话 3rd dialogue turn
response, history = model.chat(tokenizer, "给这个故事起一个标题", history=history)
print(response)
# 《奋斗创业:一个年轻人的成功之路》

换用vllm加速框架的代码:

from vllm import LLM, SamplingParams



prompts = [

"Hello, my name is",

"The president of the United States is",

"The capital of France is",

"The future of AI is",

]

sampling_params = SamplingParams(temperature=0.8, top_p=0.95)



llm = LLM(model="qwen/Qwen-7B-Chat", revision="v1.1.8", trust_remote_code=True)



outputs = llm.generate(prompts, sampling_params)



for output in outputs:

prompt = output.prompt

generated_text = output.outputs[0].text

print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}")

三、Qwen具体部署官方流程:

以Qwen2-72B-Instruct为例,也可自己换用其他模型:https://modelscope.cn/models/qwen/Qwen2-72B-Instruct

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值