返回顶部
热门问答 更多热门问答
技术文章 更多技术文章

如何构建一个支持GPU的Llamafile容器

[复制链接]
链载Ai 显示全部楼层 发表于 4 小时前 |阅读模式 打印 上一主题 下一主题

用CPU玩那些大型的语言模型确实挺有意思的,但看着电脑一个字一个字地慢慢显示结果,那股兴奋劲儿很快就过去了。让这些语言模型软件在GPU上跑起来可能会有点麻烦,因为这得看你的系统和硬件支不支持。我这篇文章就是想告诉你,怎么在你的NVIDIA RTX 2060上跑起来llamafile这个软件。里面的例子会用到llamafile、NVIDIA CUDA、Ubuntu 22.04操作系统还有Docker这几个工具。

先检查一下你的GPU和NVIDIA CUDA软件

首先得确认一下你的CUDA装了没有。NVIDIA有个工具,能显示你的GPU和CUDA的状态。

%nvidia-smi

+---------------------------------------------------------------------------------------+
|NVIDIA-SMI535.154.05DriverVersion:535.154.05CUDAVersion:12.2|
|-----------------------------------------+----------------------+----------------------+
|GPUNamePersistence-M|Bus-IdDisp.A|VolatileUncorr.ECC|
|FanTempPerfPwr:Usage/Cap|Memory-Usage|GPU-UtilComputeM.|
|||MIGM.|
|=========================================+======================+======================|
|0NVIDIAGeForceRTX2060Off|00000000:01:00.0On|N/A|
|N/A44CP88W/90W|1322MiB/6144MiB|6%Default|
|||N/A|
+-----------------------------------------+----------------------+----------------------+

如果你看到的输出和这个差不多,那就说明你的CUDA已经装好了。别忘了看一眼CUDA的版本号。这个版本号还有你的显卡的计算能力,会决定你构建镜像时得用哪个基础镜像。NVIDIA有提供一张图表(https://developer.nvidia.com/cuda-gpus#compute),上面列出了他们家各种设备的计算能力。你可以根据你的设备型号去查对应的菜单选项。比如说,你要是用的RTX 2060这款显卡,就在图表里找到它对应的那一项。

配置Docker

NVIDIA Container Toolkit这个工具能让Docker用上GPU的能力。NVIDIA也给出了安装Container Toolkit的详细指南。但如果你等不及想看简化版的,我这就来给你说说简化后的步骤。

%distribution=$(./etc/os-release;echo$ID$VERSION_ID)\
&&curl-fsSLhttps://nvidia.github.io/libnvidia-container/gpgkey|sudogpg--dearmor-o/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg\
&&curl-s-Lhttps://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list|\
sed's#debhttps://#deb[signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg]https://#g'|\
sudotee/etc/apt/sources.list.d/nvidia-container-toolkit.list

%sudoapt-getupdate

%sudoapt-getinstall-ynvidia-docker2

在Linux系统里,你得更新这个文件/etc/docker/daemon.json来设置Docker Engine后台服务,并且把NVIDIA的容器运行时加进去。要是你的系统里没有daemon.json这个文件呢,你就新建一个,内容大概是这样的:

{
"runtimes":{
"nvidia":{
"path":"/usr/bin/nvidia-container-runtime",
"runtimeArgs":[]
}
}
}

这样设置好之后,重启Docker以应用更改。你的Docker就能用上NVIDIA的GPU加速功能了。

%sudosystemctlrestartdocker

测试运行时是否工作。

%$dockerrun--rm--gpusallnvidia/cuda:11.6.2-base-ubuntu20.04nvidia-smi

如果工作正常,你应该看到类似的结果。

+---------------------------------------------------------------------------------------+
|NVIDIA-SMI535.154.05DriverVersion:535.154.05CUDAVersion:12.2|
|-----------------------------------------+----------------------+----------------------+
|GPUNamePersistence-M|Bus-IdDisp.A|VolatileUncorr.ECC|
|FanTempPerfPwr:Usage/Cap|Memory-Usage|GPU-UtilComputeM.|
|||MIGM.|
|=========================================+======================+======================|
|0NVIDIAGeForceRTX2060Off|00000000:01:00.0On|N/A|
|N/A44CP810W/90W|1530MiB/6144MiB|6%Default|
|||N/A|
+-----------------------------------------+----------------------+----------------------+

来聊聊怎么构建Llamafile的镜像吧

咱们得一步步来分析这个Dockerfile。我会详细解释我做每个选择的原因。Dockerfile用的是多阶段构建的方法,咱们先从编译llamafile的二进制文件开始说起。

FROMdebian:trixieasbuilder

WORKDIR/download

RUNmkdirout&&\
apt-getupdate&&\
apt-getinstall-ycurlgitgccmake&&\
gitclonehttps://github.com/Mozilla-Ocho/llamafile.git&&\
curl-L-o./unziphttps://cosmo.zip/pub/cosmos/bin/unzip&&\
chmod755unzip&&mvunzip/usr/local/bin&&\
cdllamafile&&make-j8&&\
makeinstallPREFIX=/download/out

这段Dockerfile是用来编译llamafile的二进制文件的。就像很多开源项目一样,llamafile非常活跃,几乎每周都有新功能更新和bug修复。所以我选择从源代码来编译llamafile,而不是直接用现成的二进制文件。另外,llamafile还能被编译成一个包含模型的单个可执行文件,但为了保持简单,我就没包括这一步。

接下来,多阶段构建的下一步是创建一个运行llamafile的镜像,这个镜像会用到主机上的GPU。NVIDIA提供了适合像llamafile这种GPU应用的CUDA基础镜像。前面我们记下了CUDA的版本和驱动程序的版本,NVIDIA也特别指出了:

“为了运行CUDA应用程序,系统应该具有支持CUDA的GPU和与用于构建应用程序本身的CUDA Toolkit兼容的NVIDIA显示驱动程序。如果应用程序依赖于库的动态链接,则系统还应该具有正确版本的这些库。”

基础的NVIDIA CUDA镜像得和你的主机上的CUDA版本对得上号。比如说,你手里有个挺新的显卡,那你就应该选一个最新的主机平台镜像。你还能挑挑不同的Linux发行版,决定是用那种带软件开发工具链的开发镜像,还是用那种拿来部署现成应用的运行时版本。

不过得注意啊,我这篇文章里头做的实验,用的GeForce RTX 2060显卡和最新的CUDA镜像不兼容。我们其实可以用老一点的镜像,但是NVIDIA的CUDA仓库里头维护了各种不同CUDA版本的Dockerfiles。所以我们可以为我们自己的CUDA版本和Linux发行版定制一个镜像。如果你想自己来构建一个CUDA镜像,那就去下载对应的Dockerfile,然后动手构建吧:

%dockerbuild-tcuda12.2-base-ubuntu-22.04.

这部分的Dockerfile是用来安装和设置CUDA工具包的,这对于让llamafile在CUDA基础镜像里用上GPU功能是必不可少的。你得用一个跟你的CUDA版本和Linux发行版相匹配的基础镜像来替换。另外,这里还创建了一个用户,这样容器就不会以root用户的身份运行了,安全性更高。

FROMcuda-12.2-base-ubuntu-22.04asout

RUNapt-getupdate&&\
apt-getinstall-ylinux-headers-$(uname-r)&&\
apt-keydel7fa2af80&&\
apt-getupdate&&\
apt-getinstall-yclang&&\
apt-getinstall-ycuda-toolkit&&\
addgroup--gid1000user&&\
adduser--uid1000--gid1000--disabled-password--gecos""user

USERuser

接下来的步骤是从构建器镜像中复制llamafile的二进制文件、手册页,还有LLM模型。在这个例子里,LLM模型codellama-7b-instruct.Q4_K_M.gguf是从Hugging Face上下载的。你也可以用任何和llamafile(或者llama.cpp)兼容的GGUF格式的模型。要记住,llamafile是作为服务器启动的,它包含了一个OPENAI API的接口,而且通过-ng 9999这个参数来启用GPU功能。

WORKDIR/usr/local

COPY--from=builder/download/out/bin./bin
COPY--from=builder/download/out/share./share/man
COPYcodellama-7b-instruct.Q4_K_M.gguf/model/codellama-7b-instruct.Q4_K_M.gguf

#不要写日志文件。
ENVLLAMA_DISABLE_LOGS=1

#暴露8080端口。
EXPOSE8080

#设置入口点。
ENTRYPOINT["/bin/sh","/usr/local/bin/llamafile"]

#设置默认命令。
CMD["--server","--nobrowser","-ngl","9999","--host","0.0.0.0","-m","/model/codellama-7b-instruct.Q4_K_M.gguf"]

构建并标记镜像。

%dockerbuild-tllamafile-codellama-gpu.

这是完整的Dockerfile。

FROMdebian:trixieasbuilder

WORKDIR/download

RUNmkdirout&&\
apt-getupdate&&\
apt-getinstall-ycurlgitgccmake&&\
gitclonehttps://github.com/Mozilla-Ocho/llamafile.git&&\
curl-L-o./unziphttps://cosmo.zip/pub/cosmos/bin/unzip&&\
chmod755unzip&&mvunzip/usr/local/bin&&\
cdllamafile&&make-j8&&\
makeinstallPREFIX=/download/out

FROMcuda-12.2-baseasout

RUNapt-getupdate&&\
apt-getinstall-ylinux-headers-$(uname-r)&&\
apt-keydel7fa2af80&&\
apt-getupdate&&\
apt-getinstall-yclang&&\
apt-getinstall-ycuda-toolkit&&\
addgroup--gid1000user&&\
adduser--uid1000--gid1000--disabled-password--gecos""user

USERuser

WORKDIR/usr/local

COPY--from=builder/download/out/bin./bin
COPY--from=builder/download/out/share./share/man
COPYcodellama-7b-instruct.Q4_K_M.gguf/model/codellama-7b-instruct.Q4_K_M.gguf

#不要写日志文件。
ENVLLAMA_DISABLE_LOGS=1

#暴露8080端口。
EXPOSE8080

#设置入口点。
ENTRYPOINT["/bin/sh","/usr/local/bin/llamafile"]

#设置默认命令。
CMD["--server","--nobrowser","-ngl","9999","--host","0.0.0.0","-m","/model/codellama-7b-instruct.Q4_K_M.gguf"]

享受性能提升

咱们可以利用continue.dev这个开源的LLM编码VSCode插件,来试试看给llamafile开启GPU后搭配codellama-7b-instruct.Q4_K_M.gguf模型的效果。Continue.dev这个插件兼容任何支持OpenAI API的LLM。如果你想在装有GPU的笔记本上用服务器模式运行llamafile,同时在M2 Mac mini上使用VSCode,那下面这些步骤就能帮到你。

提示:

“深度优先搜索URL并打印页面作为树。”

补全:

importrequests
frombs4importBeautifulSoup
defdepth_first_search(url):
"""深度优先搜索URL并打印页面作为树。"""
#初始化一个集合来跟踪访问过的URL
visited=set()
#创建一个队列来存储要访问的URL
queue=[url]
whilequeue:
#从队列中获取下一个URL
url=queue.pop(0)
#如果URL尚未访问,则访问它并将其子项添加到队列中
ifurlnotinvisited:
response=requests.get(url)
soup=BeautifulSoup(response.text,'html.parser')
forlinkinsoup.find_all('a'):
queue.append(link.get('href'))
print(f"{url}->{','.join(queue)}")
visited.add(url)

首先,我先在CPU上跑了跑llamafile的可执行文件,作为性能对比的基准。

%llamafile--server--host0.0.0.0-mcodellama-7b-instruct.Q4_K_M.gguf

用CPU跑的话,提示评估的速度是每秒24个标记,整个补全过程得花上超过一分钟的时间。

print_timings:promptevaltime=4963.79ms/121tokens(41.02mspertoken,24.38tokenspersecond)
print_timings:evaltime=64191.60ms/472runs(136.00mspertoken,7.35tokenspersecond)
print_timings:totaltime=69155.39ms

然后呢,我开启了GPU,又运行了一遍llamafile的可执行文件。

%llamafile--server--host0.0.0.0-ngl9999-mcodellama-7b-instruct.Q4_K_M.gguf

用上GPU之后,提示评估的速度比用CPU快了17倍,每秒能处理426个标记。整个补全过程在11秒内就搞定了,响应时间明显提升了不少。

print_timings:promptevaltime=283.92ms/121tokens(2.35mspertoken,426.18tokenspersecond)
print_timings:evaltime=11134.10ms/470runs(23.69mspertoken,42.21tokenspersecond)
print_timings:totaltime=11418.02ms

后来我又试了试运行开了GPU功能的llamafile容器,想看看容器化会不会对性能有啥影响。

%dockerrun-it--gpusall--runtimenvidia-p8111:8080llamafile-codellama-gpu

可以看出,容器的性能并没有下降,因为容器其本质上就是一个进程,下面的测量结果反而比单纯启用GPU的可执行文件还要稍微好那么一点儿。这个我感觉不是特别准确,应该是差不多才对。

print_timings:promptevaltime=257.56ms/121tokens(2.13mspertoken,469.80tokenspersecond)
print_timings:evaltime=11498.98ms/470runs(24.47mspertoken,40.87tokenspersecond)
print_timings:totaltime=11756.53ms

总结一下哈

给llamafile加上GPU支持,一下子就让它从一个实验性的玩具变成了软件工具箱里的实用工具。而且,把LLM容器化了之后,大家就不用安装和下载那些二进制文件,就能直接跑LLM了。我们可以直接从仓库拉取LLM,用很少的设置就能启动。另外,容器化还为在各种编排框架里部署LLM提供了新的可能性,你觉得呢?

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

链载AI是专业的生成式人工智能教程平台。提供Stable Diffusion、Midjourney AI绘画教程,Suno AI音乐生成指南,以及Runway、Pika等AI视频制作与动画生成实战案例。从提示词编写到参数调整,手把手助您从入门到精通。
  • 官方手机版

  • 微信公众号

  • 商务合作

  • Powered by Discuz! X3.5 | Copyright © 2025-2025. | 链载Ai
  • 桂ICP备2024021734号 | 营业执照 | |广西笔趣文化传媒有限公司|| QQ