CentOS 7使用K8s部署模型 CPU 和 GPU 双模式环境
本文分享用 CentOS 7 服务器,使用 K8s 部署模型,总共介绍两种方式,纯CPU的 Ollama ,GPU的 vllm
Ollama实际上是由三个核心部分组成的“全家桶”,底层计算核心(真正的引擎)是llama.cpp,中间管理层(Ollama 的核心贡献)它定义了 GGUF 格式的加载方式,帮你自动下载、版本管理模型(像 Docker 管理镜像一样),用户交互层的命令行工具 (ollama run) 和 REST API
vllm 它本身是个 python 开发的解析式语言类库,它的启动脚本本质上依靠 python 环境
要说一个关键事情,本文用 Ollama ,本质的目的是分享向 gpu 过度用的 纯cpu 模型部署环境搭建,如果你是个人使用者或者一些小团体可以这样玩,毕竟 gpu 的使用成本确实不低。尤其是对于个人使用者来讲,手里的环境通常是虚拟化软件做的 linux 虚拟机,这些软件本身直通物理机的 gpu 受限于具体软件不同会很困难,比如 VMware 从架构上就不支持gpu直通。如果你用的是 VirtualBox 它虽然基于 kvm 开发,也有显卡直通的功能,但这个功能是实验性的,它基于 kvm 的显卡直通实现,而 kvm 的显卡直通本身只能在宿主机是 linux 时使用,因此保不齐 VirtualBox 的功能有问题。但话分两头,这种用虚拟化软件做出linux虚拟机,再用linux虚拟机做 k8s 环境,本身就不是一个有助于模型部署学习的环境,中间层有点繁琐了,会拖响应速度的后腿,其他不涉及 gpu 的技术学习,这种虚拟化软件环境确实是性价比很高,但涉及 gpu 由于它本身支持困难,会把你拖进不必要的坑里,建议各位读者在手头能有三台物理linux机器,且最少其中一台有最低 RTX 3070 8G显卡时,在考虑 gpu 搭载模型的事情,docker自身只需要一个开关参数和对应的驱动就可以让容器能够访问宿主机的显卡
当然,如果你不需要 k8s 提供的服务运维能力,就想有一个模型能自己用用看,感受一下,那一台有显卡的机器就够了。你面临的问题就只有两个,一是如果你要物理机直接部署就要考虑系统方面的影响,国内使用的系统环境,除了所谓的自研系统外,通常比较旧,比如本文用的 centos 7.2209 ,要基于它直接部署,需要升级的系统依赖会让你奔溃,尤其是 Ollama 要使用 glibc 2.27 以上版本,这个东西在任何 linux 上升级一个搞不好都会导致系统所有基础命令失效,二是要考虑可用的硬件,RTX 3070 8G显卡,首选AMD的CPU,次选Intel的,网卡要兼容Linux驱动。因此,对于从体验出发的读者,推荐你可以在 Windows 上用 Docker 桌面版,平替物理linux机器,能省去不必要的麻烦,但是也有缺点,基于windows部署模型,由于它的内核限制,导致模型的响应速度很可能比你用Linux虚拟机还慢
如果最终任然想使用linux物理机部署,一定要选择比较新的其他发行版linux ,比如 ubantu 或者 兼容 CentOS 的 AImaLinux。安装时不能直接用官方的安装脚本,有资源下载问题。使用国内魔塔的镜像包安装 -》 https://modelscope.cn/models/modelscope/ollama-linux。这个安装方式需要用魔塔的python工具下载安装包,因此需要服务器上有 python 3.11 的环境
pip3 install modelscope
modelscope download --model=modelscope/ollama-linux --local_dir ./ollama-linux --revision v0.17.5
cd ollama-linux
yum install -y zstd
chmod 777 ./ollama-modelscope-install.sh
./ollama-modelscope-install.sh
# 修改环境变量
vi /etc/profile
# 监听地址
export OLLAMA_HOST="0.0.0.0:11434"
# 模型文件存放地址
export OLLAMA_MODELS=/opt/model
# 单个模型同时处理的并发请求数
export OLLAMA_NUM_PARALLEL=2
# 模型在内存中的保活时长
export OLLAMA_KEEP_ALIVE=24h
# GPU同时加载的最大模型数量
#export OLLAMA_MAX_LOADED_MODELS=2
# 启动服务
systemctl restart ollama
systemctl status ollama
从实际出发其实没有将精力消耗在 Ollama 物理机直接部署的必要,因为无论是出于商用环境讲,还是个人学习,docker的环境交付能力,能省去你非常多的麻烦事,而且 Ollama 它不会出现在企业商用环境内,除非是上面说到的小团体,Ollama 确实是出现时机最早的一批工具,但是它的架构也是最拉跨的那一批,它的优点是多平台易用,支持 gguf 格式模型文件,且支持纯CPU运行模型,非常适合新手用来练手,但是它对模型的应用性能非常垫底,尤其是使用它的 gpu 模式会让人非常难受,OOM 等各种问题频出不断。Vllm 才是目前主流做模型加载工具的商用环境,从行业地位来讲 Ollama 就是一个随手可丢掉的工具,而 Vllm 是模型领域的基座
系统方面,要单独说一点,如果你自己可以决定或者说还有的选,就不要用 CentOS 7 ,比如你用的阿里云服务器,那最好直接用 Alibaba Cloud Linux。如果是完全的离线服务器模式,先考虑是否能用 ubantu,如果担心架构问题,你可以选择尝试用 AlmaLinux 9 ,在部署方式上差别基本不大
ollama准备
言归正传,首先在单台 docker 上,拉取镜像,测试版本是否可用。由于本质的目的要生成一个未来要挂载的模型文件路径,以及其他需要的资源,因此本文在 k8s 主节点上单独安装了一个 docker 做这些操作,Ollama 使用 0.17.0 ,拉取镜像用国内源。各位读者自己根据情况来决定即可,后期使用 pv 在 k8s中挂载
docker pull docker.m.daocloud.io/ollama/ollama:0.17.0
mkdir /opt/ollama_data
docker run -d --name ollama \
-p 11434:11434 \
-e OLLAMA_MODELS=/root/.ollama/models \
-e OLLAMA_ORIGINS="*" \
-e OLLAMA_HOST=0.0.0.0 \
-e OLLAMA_NUM_PARALLEL=2 \
-e OLLAMA_KEEP_ALIVE=24h \
-e OLLAMA_REGISTRY_MIRRORS="https://ollama.modelscope.cn" \
-v /opt/ollama_data:/root/.ollama \
-v /etc/localtime:/etc/localtime:ro \
--restart unless-stopped \
docker.m.daocloud.io/ollama/ollama:0.17.0
OLLAMA_REGISTRY_MIRRORS 指定模型下载加速器
OLLAMA_ORIGINS 允许跨域
OLLAMA_NUM_PARALLEL 同时处理几个访问请求
OLLAMA_KEEP_ALIVE 模型加载后保持多长时间
--restart unless-stopped 跟随宿主机或docker重启时的自动重启命令
--gpus all 如果在有GPU的服务器上可以使用该参数使得启动的容器可以访问所有gpu,前提是安装了显卡驱动
[root@node1 opt]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8e2e88f8ff3c ollama/ollama:latest "/bin/ollama serve" 5 seconds ago Up 4 seconds 0.0.0.0:11434->11434/tcp, :::11434->11434/tcp ollama
[root@node1 opt]# curl http://localhost:11434/api/tags
{"models":[]}
对于模型上,如果你直接 run 也可以,会从指定的镜像源下载,但是模型往往很大,所以这里使用 ollama 提供的ModelFile,来加载预先下载好的模型。 ModelFile 和 DockerFile 是一个类型的东西。你会 DockerFile 就能看明白 ModelFile
首先下载好的 gguf 文件放在容器的挂载路径下,可以去魔塔https://www.modelscope.cn/models,并准备一个 ModelFile
# 假设你的模型文件叫 Qwen3-2B-UD-IQ2_M.gguf ,指定相对路径
FROM ./Qwen3-2B-UD-IQ2_M.gguf
随后进入容器,让 ollama 加载。API调用的话,基本和OpenAi一样
# 加载 Qwen3 是你为模型取的本地名字
ollama create qwen25 -f ./Modelfile
# 查看当前本地可用的模型
ollama list
# 运行模型,启动一个交互式对话,Ctrl + d 退出
ollama run qwen25:latest
# 后期不需要可以删除模型
ollama rm qwen25:latest
温馨提示:gguf 格式低参数不要下载 qianwen ,本文亲测模型会相当智障,所以如果要使用qianwen 可以和本文一样直接从魔塔上 pull 一个
ollama pull qwen2.5:0.5b
交互式没问题,就调用接口测试一下
curl http://127.0.0.1:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen2.5:0.5b",
"messages": [
{"role": "user", "content": "你好,请简单介绍一下你自己"}
],
"stream": false
}'
预期结果。注意由于测试用的模型非常参数非常小,所以大概率答非所问,到这一步主要是验证服务可以用即可。各位读者实际操作时参数方面自己注意一下,如果太小不止会导致能力不足答非所问,严重的还可能连话也不会说
[root@master01 ollama_data]# curl http://127.0.0.1:11434/v1/chat/completions \
> -H "Content-Type: application/json" \
> -d '{
> "model": "qwen2.5:0.5b",
> "messages": [
> {"role": "user", "content": "你好,请简单介绍一下你自己"}
> ],
> "stream": false
> }'
{"id":"chatcmpl-253","object":"chat.completion","created":1777564440,"model":"qwen2.5:0.5b","system_fingerprint":"fp_ollama","choices":[{"index":0,"message":{"role":"assistant","content":"你好!我是阿里云从阿里集团自主研发,经过多年积累而成为领先的AI、机器学习和自然语言处理专家的人工智能助手。你有什么问题或需求,我都愿意为您提供帮助。"},"finish_reason":"stop"}],"usage":{"prompt_tokens":34,"completion_tokens":42,"total_tokens":76}}
随后需要用 ollama 下载一个嵌入式的文本处理模型
docker exec -it ollama ollama pull nomic-embed-text
如果你只关注英文文本处理,可以使用
docker exec -it ollama ollama pull all-minilm
open-webui准备
Ollama 它只负责模型的挂载,对外服务通常需要丰富的非训练模型形式的挂载知识库等应用层需求,这方面推荐使用 Open WebUI 易用性非常高,支持多种知识库关联,同样支持docker部署
docker pull ghcr.io/open-webui/open-webui:main
mkdir -p /opt/openui
docker run -d \
--name open-webui \
-p 3000:8080 \
-v /opt/openui:/app/backend/data \
-e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
--add-host=host.docker.internal:host-gateway \
--restart unless-stopped \
ghcr.io/open-webui/open-webui:main
--add-host=host.docker.internal:host-gateway 这个配置非常重要,它是依靠 docker 20 版本开始提供的一个关键字 host-gateway 指向宿主机。这个配置相当于在容器的/etc/hosts文件中插入了一条dns映射。host.docker.internal部分你可以改成自定义的名称
-e OLLAMA_BASE_URL=http://host.docker.internal:11434:告诉 Open WebUI 去哪里找 Ollama
open-webui 设置默认模型,不要通过网上说的环境变量,通过页面上管理员在模型列表右上角点击设置,且生效范围只是在web上访问,不会影响api,通过api访问时必须带模型
访问宿主机 3000 端口。首次访问需要创建一个管理员账号,后期其他人的账号需要管理员创建

Open WebUI 支持丰富的搜索外部数据挂载,你还可以以知识库的形式存在,细节功能各位读者自己探索,本文不扩展
联网搜索
不管你用的是何种模型,始终逃脱不了模型自身数据的落后性,比如上图中默认自身的知识储备终止到2023年04月18日,但本质上谁来也无法让一个模型天天更新自己的知识库,因此你需要让open-webui拥有联网搜索的能力。同样的需要使用私有化,且支持外部API调用的搜索引擎,这里使用searxng
docker pull searxng/searxng
mkdir -p /opt/searxng
docker run -d \
--name searxng \
-p 3050:8080 \
-v /opt/searxng:/etc/searxng \
-e BASE_URL=http://host.docker.internal:8080/ \
-e INSTANCE_NAME=searxng \
--add-host=host.docker.internal:host-gateway \
--restart unless-stopped \
searxng/searxng
启动容器后,在宿主机的 /opt/searxng 会生成对应的本地卷里面是searxng配置文件,把它下载到本地修改两个东西。第一个是 search 部分最后改成json格式
# remove format to deny access, use lower case.
# formats: [html, csv, json, rss]
formats:
- json
第二个将 engines 部分替换成下面的,原配置文件非常长,这一步修改是把支持的搜索引擎列表中除了bing、baidu其他的都关掉,不然会影响搜索效率,而且其他的国内也用不了
engines:
- name: bing
engine: bing
shortcut: bi
- name: bing images
engine: bing_images
shortcut: bii
- name: bing news
engine: bing_news
shortcut: bin
- name: bing videos
engine: bing_videos
shortcut: biv
- name: baidu
baidu_category: general
categories: [general]
engine: baidu
shortcut: bd
- name: baidu images
baidu_category: images
categories: [images]
engine: baidu
shortcut: bdi
- name: baidu kaifa
baidu_category: it
categories: [it]
engine: baidu
shortcut: bdk
现在删掉刚才启动的容器,将改好的配置文件放到原路径,重新 run 一个容器,访问宿主机 3050 端口,http://宿主机:3050/search?q=llm&format=json,预期返回结果
现在回到 open-webui 界面,用管理员账号登录,鼠标点击 右下角用户 -》点击展开弹窗中的管理员面板 -》 顶部导航栏的设置 -》 联网搜索 。把 seareng 的 api地址消息 写进去,注意用容器能找到的dns,也就是run容器配置的宿主机映射dns。点击保存
随后在点击文档配置,将开头用 Ollama 下载的嵌入式文档处理模型配置上去
随后打开新会话对话框扩展功能里打开联网搜索,就可以发送消息了。但注意回复的速度和结果准确率受到模型本身的影响,比如本文当前测试用的0.5b模型,它返回结果不失真还是个正常人,不是个啊吧啊吧的傻子,就阿弥陀佛了
openwebui的api功能需要管理员在设置中打开,你还可以点击下面的提示使用限制能力根据官方文档设置接口限制
随后所有用户在右下角点击头像,打开设置,在账号里面就能看见 api 密钥的生成界面
随后你可以在服务器上测试一下
curl http://localhost:3000/api/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-6cdf1ef77df04fa7acea4d7b1dc489ad" \
-d '{
"model": "qwen2:0.5b",
"messages": [
{ "role": "user", "content": "你好,介绍一下自己吧" }
],
"stream": false
}'
预期结果
[root@node1 opt]# curl http://localhost:3000/api/chat/completions \
> -H "Content-Type: application/json" \
> -H "Authorization: Bearer sk-dcd14a013ae04a1db876823813eeaea4" \
> -d '{
> "model": "qwen2:0.5b",
> "messages": [
> { "role": "user", "content": "你好,介绍一下自己吧" }
> ]
> }'
{"id":"qwen2:0.5b-d227755f-1f17-4174-815e-6dccf54c8857","created":1777543743,"model":"qwen2:0.5b","choices":[{"index":0,"logprobs":null,"finish_reason":"stop","message":{"role":"assistant","content":"我是来自阿里云的自然语言处理模型。我叫通义千问。"}}],"object":"chat.completion","usage":{"input_tokens":13,"output_tokens":18,"total_tokens":31,"prompt_tokens":13,"completion_tokens":18,"response_token/s":42.41,"prompt_token/s":138.98,"total_duration":854380853,"load_duration":279415223,"prompt_eval_count":13,"prompt_eval_duration":93537669,"eval_count":18,"eval_duration":424472416,"approximate_total":"0h0m0s","completion_tokens_details":{"reasoning_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}}
通过
到此,模型相关的工作就结束了。如果你是开头说到的个人用户,纯体验目的,就可以把上面的流程复现在 Windows 系统的 Docker 桌面版上。下面的内容讲操作 k8s 让容器跑在集群上
k8s nfs pv 准备
删除上面准备环境用的容器,Ollama不用删除,后续加载部署模型继续用即可
docker stop 容器id
docker rm 容器id
将三个容器产生的数据放到一个路径下,用 nfs 共享出去
mkdir -p /opt/nfs
cp -r ollama_data/ ./nfs/
cp -r openui/ ./nfs/
cp -r searxng/ ./nfs/
vi /etc/exports
/opt/nfs *(rw,sync,no_root_squash)
exportfs -r
systemctl enable --now nfs-server
systemctl status nfs-server
[root@master01 nfs]# showmount -e
Export list for master01.k8s.com:
/opt/nfs *
向k8s注册 nfs pv 和 pvc
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs
spec:
capacity:
storage: 1Gi
# 多节点读写挂载,因为 openwebui 需要写
accessModes:
- ReadWriteMany
nfs:
path: /opt/nfs
server: master01.k8s.com
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs
spec:
volumeName: pv-nfs
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
生效 nfs pv 和 pvc
[root@master01 opt]# kubectl apply -f pvc
persistentvolume/pv-nfs created
persistentvolumeclaim/pvc-nfs created
[root@master01 opt]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs 1Gi RWX Retain Bound default/pvc-nfs 36s
[root@master01 opt]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-nfs Bound pv-nfs 1Gi RWX 40s
给要运行 Ollama 模型的节点配置不接受新调度的污点,本文给 worker01.k8s.com 配置。给 woker02 节点打 ui 标签用来调度 open-webui 和 searxng
# worker01 打 Ollama 专用标签,并添加污点防止其他新的 Pod 调度
kubectl label node worker01.k8s.com role=ollama
kubectl taint node worker01.k8s.com dedicated=ollama:NoSchedule
# worker02 打 UI 专用标签
kubectl label node worker02.k8s.com role=ui
# 查询节点信息,确定标签和污点设置正确
kubectl describe node worker01.k8s.com
定义三种容器的控制器和service,由于没啥值得说的注意点,这里就直接写一起了
# ollama 的控制器
apiVersion: apps/v1
kind: Deployment
metadata:
name: ollama
spec:
replicas: 1
selector:
matchLabels:
app: ollama
template:
metadata:
labels:
app: ollama
spec:
# 容忍 worker01 的污点
tolerations:
- key: "dedicated"
operator: "Equal"
value: "ollama"
effect: "NoSchedule"
# 节点亲和性:必须调度到 role=ollama 的节点
nodeSelector:
role: ollama
containers:
- name: ollama
image: docker.m.daocloud.io/ollama/ollama:0.17.0
ports:
- containerPort: 11434
volumeMounts:
- name: nfs-storage
mountPath: /root/.ollama
# nfs pvc 的子路径
subPath: ollama_data
env:
- name: OLLAMA_MODELS
value: "/root/.ollama/models"
- name: OLLAMA_ORIGINS
value: "*"
- name: OLLAMA_NUM_PARALLEL
value: "2"
- name: OLLAMA_KEEP_ALIVE
value: "24h"
- name: OLLAMA_REGISTRY_MIRRORS
value: "https://ollama.modelscope.cn"
#初始 2c 4g 最大 3c 6g
resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "6Gi"
cpu: "3"
# 活性探针:容器启动 60 秒后,每 10 秒检查一次
livenessProbe:
tcpSocket:
port: 11434
initialDelaySeconds: 60
periodSeconds: 10
# 就绪探针:启动 60 秒后,每 10 秒检查一次
readinessProbe:
tcpSocket:
port: 11434
initialDelaySeconds: 60
periodSeconds: 10
volumes:
- name: nfs-storage
persistentVolumeClaim:
claimName: pvc-nfs
---
# openwebui 的控制器
apiVersion: apps/v1
kind: Deployment
metadata:
name: openwebui
spec:
replicas: 1
selector:
matchLabels:
app: openwebui
template:
metadata:
labels:
app: openwebui
spec:
# 节点亲和性:调度到 role=ui 的节点(worker02)
nodeSelector:
role: ui
containers:
- name: openwebui
image: ghcr.io/open-webui/open-webui:main
ports:
- containerPort: 8080
env:
- name: OLLAMA_BASE_URL
value: "http://ollama-service:11434" # 指向 Ollama 的 Service
volumeMounts:
- name: nfs-storage
mountPath: /app/backend/data
subPath: openui
resources:
requests:
memory: "2Gi"
cpu: "2"
limits:
memory: "2Gi"
cpu: "2"
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
volumes:
- name: nfs-storage
persistentVolumeClaim:
claimName: pvc-nfs
---
# searxng 的控制器
apiVersion: apps/v1
kind: Deployment
metadata:
name: searxng
spec:
replicas: 1
selector:
matchLabels:
app: searxng
template:
metadata:
labels:
app: searxng
spec:
nodeSelector:
role: ui
containers:
- name: searxng
image: searxng/searxng:latest
ports:
- containerPort: 8080
env:
- name: BASE_URL
value: "http://searxng-service:8080"
- name: INSTANCE_NAME
value: "searxng"
volumeMounts:
- name: nfs-storage
mountPath: /etc/searxng
subPath: searxng
resources:
requests:
memory: "2Gi"
cpu: "2"
limits:
memory: "2Gi"
cpu: "2"
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
volumes:
- name: nfs-storage
persistentVolumeClaim:
claimName: pvc-nfs
---
# 三个容器控制器的service
apiVersion: v1
kind: Service
metadata:
name: ollama-service
spec:
selector:
app: ollama
ports:
- protocol: TCP
port: 11434
targetPort: 11434
type: ClusterIP # Ollama 仅集群内访问
---
apiVersion: v1
kind: Service
metadata:
name: openwebui-service
spec:
selector:
app: openwebui
ports:
- protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30080 # 外部浏览器访问用 NodePort,也可用 LoadBalancer
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
name: searxng-service
spec:
selector:
app: searxng
ports:
- protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30090
type: NodePort # 考虑到后续要通过webui页面该配置的需求所以也用NodePort
为了节省镜像拉取时间,从上面准备数据的节点导出镜像并分发到对应节点上
# 导出两个镜像文件
docker save -o ollama.tar docker.m.daocloud.io/ollama/ollama:0.17.0
docker save -o ui.tar searxng/searxng:latest ghcr.io/open-webui/open-webui:main
# 在 worker01 上导入 ollama
docker load -i ollama.tar
# woker02 上导入 searxng 和 open-webui
docker load -i ui.tar
访问任何节点的 30080 端口 就可访问到 open-web-ui。需要做的是把外部连接、文档模型、联网搜索用的 api 地址,改为 service 对应的入口



随后测试一下对话即可
Vllm 环境准备
这里只介绍挂起模型的工具使用不同点,其他的 open-webui、联网搜索等都是一样的。这里有一个要点要先说明,基于 Centos 7 搭建 GPU 模式的模型环境,由于系统老旧问题,所以用到的 docker 和 k8s 都要用老版本,这里面涉及到一个显卡让容器访问的插件问题,下面会提到,总之如果各位读者要用 vllm,建议先和本文一样用 Docker 1.18.03 和 k8s 1.17 的集群版本
由于放在 k8s 中,内核肯定是自己编译升级好的,公开源没有非默认内核版本需要的显卡引导程序,因此你需要找到升级内核时的源码文件,如果没有就需要下载一个同版本源码自适应配置内容后编译一份
# 编译,找自己的版本
tar -zxf linux-5.6.15.tar.gz
cd linux-5.6.15
# 按照当前内核参数生成配置文件,无法识别的自动用默认值
make olddefconfig
# 开始编译
make -j 4
要注意安装显卡驱动时,官方下载的显卡文件里有签名,如果安装过程中,各位读者遇到因为签名引发的莫名其妙的bug,可以重新编译 Linux 内核,编译时 Enable loadable module support -> Module signature verification 取消勾选状态
随后就是驱动。买服务器时,驱动方面注意有个非常坑的点,买服务器之前,先去 https://hub.docker.com/r/vllm/vllm-openai 看一下目前能拉取到的镜像支持那些系统和CUDA工具包版本,截止 2026年5月 最显眼的能拉到 CU129 ,和可选的 ubantu 24 系统。系统方面没有 ubantu 标识的其他镜像版本都可以在Centos上用,但是建议直接使用 CU129 这种带明确后缀的版本,也就是对应 CUDA 工具包12.9 版本,直接去下载对应版本体系的最新版显卡即可,至于其他的,也能用,但是会让你非常难受,因为 vllm 会在启动时检查驱动版本,而且检查非常呆板,只认大版本,通常只有一个大版本的容错,而英伟达驱动变动往往不是那么尽人意,如果不依靠明显的 CUDA 工具包来减小范围,你会发现光找适配驱动就能找一天。再一个就是要和服务供应商确定好安装指导手册中不同型号服务器,能否满足对应驱动的安装条件,比如本文用阿里云服务器,手册中的版本对应关系只是最低要求,因此本文用了一台 gn7i 型号的服务器实例,安装了 CUDA 12.9 - NVIDIA-Linux-x86_64-575.57.08.run 版本的驱动,阿里的安装指导文档 -》https://help.aliyun.com/document_detail/163824.html#concept-ecy-qrz-wgb


本文的部署场景基于 k8s 升级了内核,所以根据客服指引去英伟达官网下载 linux 系统的驱动安装程序,是个 .run 后缀的执行文件,https://www.nvidia.cn/drivers/。下载时要注意,如果你是自己买了一个消费级电脑,做个人学习环境用,那在驱动版本兼容上可能需要费点心思,比如 RTX 系列选卡不要去安装最新的驱动,找老一点的
#禁用默认的驱动
bash -c "echo -e 'blacklist nouveau\noptions nouveau modeset=0' > /etc/modprobe.d/blacklist-nouveau.conf"
# 刷新配置,不报错正常结束,则重启系统
dracut --force
reboot
# 重启后预计没有输出
lsmod | grep nouveau
# 给驱动执行权限
chmod 777 /opt/gpt1/NVIDIA-Linux-x86_64-575.57.08.run
# 安装必备插件
yum install -y dkms epel-release
[root@wangyang gpt1]# dkms --version
dkms-3.0.12
# 临时切换服务器连接到纯文本模式
systemctl isolate multi-user.target
# 安装驱动 --kernel-source-path 是你的内核编译源码路径
/opt/gpt1/NVIDIA-Linux-x86_64-575.57.08.run --dkms --kernel-source-path=/opt/gpt1/linux-5.6.15
安装开始出现选择安装那个架构的驱动,一定要选择 NVIDIA Proprietary
随后一路 yes 和 ok
到最后出现 选择那种方式加载驱动,一定要选择 Rebuild initramfs 已系统模块的方式加载
# 如果安装出现问题 先卸载
/opt/gpt1/NVIDIA-Linux-x86_64-575.57.08.run --uninstall
# 安装完成后,尝试加载驱动模块
modprobe nvidia
# 加载不报错,就可以持久化
vi /etc/modules-load.d/nvidia.conf
# 追加如下内容
nvidia
nvidia_uvm
nvidia_drm
nvidia_modeset
nvidia_peermem
英伟达驱动有个 nvidia-persistenced 功能,能让 GPU 运行更稳定,可选启动,本文这里没有使用,开启方式见阿里云文档
# 安装成功后,预计看到如下输出
[root@wangyang gpt1]# nvidia-smi
Mon May 4 21:14:55 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 575.57.08 Driver Version: 575.57.08 CUDA Version: 12.9 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA A10 Off | 00000000:00:03.0 Off | 0 |
| 0% 29C P0 59W / 150W | 0MiB / 23028MiB | 21% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
要让容器可访问 GPU 需要安装英伟达提供的一个单独的驱动依赖 ,如果你不是 centos 7 而是其他较新的发行版,可以去英伟达官方安装新版架构的驱动https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html。如果你和本文一样用的是 centos 7 ,就不能用 container-toolkit 了,需要装旧版驱动,叫做nvidia-docker2,这个旧版驱动不太好找,本文用的是 docker-ce 18.03.0 版本下用的,如果你自己能找到其他高版本的就用,找不到就用和本文一样的 https://github.com/wangyang159/nvidia-docker2
# 用阿里源先安装 docker
wget -O /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum clean all
yum makecache
# 这个版本 cli 没分离出来,不用另行安装 docker-ce-cli-18.03.0.ce
yum -y install docker-ce-18.03.0.ce
#启动
systemctl start docker
systemctl status docker
systemctl enable docker
安装需要的显卡驱动插件
yum install -y unzip
mkdir nva
mv nvidia-docker2.zip ./nva
cd nva
unzip nvidia-docker2.zip
yum localinstall *.rpm
现在就可以调起 vllm 了。vllm 有一点不方便的就是一个容器只能启一个模型,它是防止多模型抢占 GPU,且一个容器内的模型出问题导致容器挂了,不影响其他容器,外部使用需要一个转发工具,后面会说
# vllm 的镜像非常大,你需要至少有 40G 的磁盘空间
docker pull docker.1ms.run/vllm/vllm-openai:latest-cu129
# 提一嘴,显卡不是说非要 英伟达 的 ,你可以用 AMD 的,驱动方面自己找找官网,然后 vllm 用 vllm/vllm-openai-rocm
mkdir /opt/vllm_data/modelscope
docker run -d \
--runtime=nvidia \
--name vllm-service \
-p 8000:8000 \
--shm-size=8g \
-e VLLM_USE_MODELSCOPE=True \
-v /opt/vllm_data/modelscope:/root/.cache/modelscope \
docker.1ms.run/vllm/vllm-openai:latest-cu129 \
--model Qwen/Qwen2.5-7B-Instruct \
--served-model-name qwen2.5-7b \
--host 0.0.0.0 \
--port 8000
-d: 后台运行容器
--runtime=nvidia 和 --gpus all 都是允许容器使用宿主机的所有 GPU,--gpus是 19 版本以后支持的参数
--name vllm-service: 一个易于管理的名字。
--shm-size 8g共享内存,最少2g
-e VLLM_USE_MODELSCOPE=True: 核心设置! 设置环境变量,让 vLLM 知道要从魔搭社区(ModelScope)而不是 Hugging Face 下载模型。
-v /opt/vllm_data/modelscope:/root/.cache/modelscope 模型挂载路径
如果各位读者在运行时提示需要特权模式就带上这三个,但通常不需要,因为有了足够大的进程内部共享内存不需要访问宿主机的资源
--ipc=host: 共享宿主机的 IPC 命名空间,这对于大模型在容器内高效共享内存至关重要,可以避免很多启动错误。
--privileged 和 --security-opt seccomp=unconfined 是启动特权容器, vllm 启动需要访问系统权限
后面的参数传给了 vllm
--model Qwen/Qwen2.5-7B-Instruct: 指定要启动的模型 ID。首次运行时,vLLM 会自动从魔搭下载该模型到挂载的目录中。
--served-model-name qwen2.5-7b: 为正在服务的模型指定一个友好的名称,在调用 API 时会用到。
--host 0.0.0.0 和 --port 8000: 让 API 服务监听所有网络接口的 8000 端口。
然后测试一下接口
[root@wangyang ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e47b07f94207 docker.1ms.run/vllm/vllm-openai:latest-cu129 "vllm serve --model …" 5 seconds ago Up 2 seconds 0.0.0.0:8000->8000/tcp vllm-service
启动时间会比较长,通过下面的命令看日志进度
docker logs -f vllm-service
直到日志出现如下信息,就表示可以用了
(APIServer pid=1) INFO: Started server process [1]
(APIServer pid=1) INFO: Waiting for application startup.
(APIServer pid=1) INFO: Application startup complete.
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" \
-d '{
"model": "qwen2.5-7b",
"messages": [
{"role": "system", "content": "你是一个乐于助人的助手。"},
{"role": "user", "content": "请简单介绍一下 vLLM 是什么?"}
],
"temperature": 0.7,
"max_tokens": 128
}'
[root@wangyang modelscope]# curl http://localhost:8000/v1/chat/completions \
> -H "Content-Type: application/json" \
> -d '{
> "model": "qwen2.5-7b",
> "messages": [
> {"role": "system", "content": "你是一个乐于助人的助手。"},
> {"role": "user", "content": "请简单介绍一下 vLLM 是什么?"}
> ],
> "temperature": 0.7,
> "max_tokens": 128
> }'
{"id":"chatcmpl-a86039f9c3e59f60","object":"chat.completion","created":1777904001,"model":"qwen2.5-7b","choices":[{"index":0,"message":{"role":"assistant","content":"vLLM(Vectorized Large Language Model)是一种用于加速大规模语言模型推理的开源库,旨在提高生成文本的速度和效率。它支持多种流行的大型语言模型架构,如GPT-3、LLaMA等,并通过优化计算和内存使用来加速模型推理过程。\n\nvLLM的核心功能包括:\n\n1. **向量化处理**:通过并行化处理多个输入序列,显著提高了推理速度。\n2. **内存优化**:利用更高效的内存管理技术减少显存占用,使得更大规模的语言模型能够在有限资源的设备上运行。\n3. **灵活性**:支持","refusal":null,"annotations":null,"audio":null,"function_call":null,"tool_calls":[],"reasoning":null},"logprobs":null,"finish_reason":"length","stop_reason":null,"token_ids":null}],"service_tier":null,"system_fingerprint":null,"usage":{"prompt_tokens":30,"total_tokens":158,"completion_tokens":128,"prompt_tokens_details":null},"prompt_logprobs":null,"prompt_token_ids":null,"kv_transfer_params":null}
curl http://localhost:8000/v1/models
[root@wangyang modelscope]# curl http://localhost:8000/v1/models
{"object":"list","data":[{"id":"qwen2.5-7b","object":"model","created":1777904148,"owned_by":"vllm","root":"Qwen/Qwen2.5-7B-Instruct","parent":null,"max_model_len":32768,"permission":[{"id":"modelperm-a5ece3df5376354a","object":"model_permission","created":1777904148,"allow_create_engine":false,"allow_sampling":true,"allow_logprobs":true,"allow_search_indices":false,"allow_view":true,"allow_fine_tuning":false,"organization":"*","group":null,"is_blocking":false}]}]}
如果启动时,docker直接在当前会话框输出下面这种报错,说明你下载的显卡驱动不在支持的范围内,这很正常,因为本身也不是一条产业线的。看最后一个driver>=575,driver<576去下载这个版本的
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused
"process_linux.go:402: container init caused \"process_linux.go:385: running prestart hook 1 caused \\\"error running hook: exit
status 1, stdout: , stderr: exec command: [/usr/bin/nvidia-container-cli --load-kmods configure --ldconfig=@/sbin/ldconfig
--device=all --compute --utility --require=cuda>=13.0 brand=unknown,driver>=535,driver<536 brand=grid,driver>=535,driver<536
brand=tesla,driver>=535,driver<536 brand=nvidia,driver>=535,driver<536 brand=quadro,driver>=535,driver<536
brand=quadrortx,driver>=535,driver<536 brand=nvidiartx,driver>=535,driver<536 brand=vapps,driver>=535,driver<536
brand=vpc,driver>=535,driver<536 brand=vcs,driver>=535,driver<536 brand=vws,driver>=535,driver<536
brand=cloudgaming,driver>=535,driver<536 brand=unknown,driver>=550,driver<551 brand=grid,driver>=550,driver<551
brand=tesla,driver>=550,driver<551 brand=nvidia,driver>=550,driver<551 brand=quadro,driver>=550,driver<551
brand=quadrortx,driver>=550,driver<551 brand=nvidiartx,driver>=550,driver<551 brand=vapps,driver>=550,driver<551
brand=vpc,driver>=550,driver<551 brand=vcs,driver>=550,driver<551 brand=vws,driver>=550,driver<551
brand=cloudgaming,driver>=550,driver<551 brand=unknown,driver>=565,driver<566 brand=grid,driver>=565,driver<566
brand=tesla,driver>=565,driver<566 brand=nvidia,driver>=565,driver<566 brand=quadro,driver>=565,driver<566
brand=quadrortx,driver>=565,driver<566 brand=nvidiartx,driver>=565,driver<566 brand=vapps,driver>=565,driver<566
brand=vpc,driver>=565,driver<566 brand=vcs,driver>=565,driver<566 brand=vws,driver>=565,driver<566
brand=cloudgaming,driver>=565,driver<566 brand=unknown,driver>=570,driver<571 brand=grid,driver>=570,driver<571
brand=tesla,driver>=570,driver<571 brand=nvidia,driver>=570,driver<571 brand=quadro,driver>=570,driver<571
brand=quadrortx,driver>=570,driver<571 brand=nvidiartx,driver>=570,driver<571 brand=vapps,driver>=570,driver<571
brand=vpc,driver>=570,driver<571 brand=vcs,driver>=570,driver<571 brand=vws,driver>=570,driver<571
brand=cloudgaming,driver>=570,driver<571 brand=unknown,driver>=575,driver<576 brand=grid,driver>=575,driver<576
brand=tesla,driver>=575,driver<576 brand=nvidia,driver>=575,driver<576 brand=quadro,driver>=575,driver<576
brand=quadrortx,driver>=575,driver<576 brand=nvidiartx,driver>=575,driver<576 brand=vapps,driver>=575,driver<576
brand=vpc,driver>=575,driver<576 brand=vcs,driver>=575,driver<576 brand=vws,driver>=575,driver<576
brand=cloudgaming,driver>=575,driver<576 --pid=29608
/opt/gpt1/docker/overlay2/2d8879785624b208cf579d4cb74fbc79c69a36fd1ba90e7552fc14188987e499/merged]\\\\nnvidia-container-cli:
requirement error: invalid expression\\\\n\\\"\"": unknown.
vllm 使用上没有 Ollama 那样的命令行操作
| 特性 | Ollama (像手机 App) | vLLM (像服务器软件) |
|---|---|---|
| 模型管理 | 内置管理ollama pull / ollama rm |
无管理 全靠你自己管文件,或者写脚本 |
| 存储方式 | 复杂的分层存储(类似 Docker 镜像层) | 简单的文件目录(类似 Windows 文件夹) |
| 删除模型 | ollama rm llama3 (自动清理缓存) |
rm -rf ./llama3 (手动删文件夹) |
| 适用场景 | 个人开发、本地测试、快速体验 | 生产环境、高并发服务、K8s 部署 |
部署到 k8s 集群时,由于 vllm 不支持一个容器内存在多个模型,因此需要 vllm 提供的一个转发工具提供统一的后端
docker pull docker.1ms.run/lmcache/lmstack-router:latest
随后按照需求正常启动 一对一 的 vllm 容器,本文这里只写一个,因为就准备了一张 GPU 多了带不动了
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-qwen2.5-7b
labels:
app: vllm-qwen2.5-7b
spec:
replicas: 1
selector:
matchLabels:
app: vllm-qwen2.5-7b
template:
metadata:
labels:
app: vllm-qwen2.5-7b
spec:
# 容忍污点,创建方式见上文 ollama
tolerations:
- key: "dedicated"
operator: "Equal"
value: "vllm"
effect: "NoSchedule"
# 调度到有 GPU 的节点,创建方式见上文 ollama
nodeSelector:
app: nvidia-gpu
# 对应 Docker 的 --ipc=host
#hostIPC: true
containers:
- name: vllm
image: docker.1ms.run/vllm/vllm-openai:latest-cu129
imagePullPolicy: IfNotPresent
args:
- "--model"
- "Qwen/Qwen2.5-7B-Instruct"
- "--served-model-name"
- "qwen2.5-7b"
- "--host"
- "0.0.0.0"
- "--port"
- "8000"
- "--trust-remote-code" # Qwen 模型通常需要
env:
- name: VLLM_USE_MODELSCOPE
value: "True" # 对应 Docker 的 -e VLLM_USE_MODELSCOPE=True
# K8s 中通过 volumes 声明并挂载共享内存
volumeMounts:
- name: modelscope-cache
mountPath: /root/.cache/modelscope # 对应 Docker 的 -v ...:/root/.cache/modelscope
- name: dshm
mountPath: /dev/shm # 对应 Docker 的 --shm-size=8g
#securityContext:
#privileged: true # 对应 Docker 的 --privileged
# Kubernetes 文档指出:
# "你不可以将 seccomp 配置文件应用到在容器的 securityContext 中设置了 privileged: true 的 Pod 或容器。特权容器始终以Unconfined 运行。" 因此无需单独设置 seccompProfile。
resources:
limits:
nvidia.com/gpu: 1 # 对应 Docker 的 使用gpu参数 例如新版的 --gpus all (k8s需要声明具体数量的 GPU)
requests:
nvidia.com/gpu: 1 # 请求 1 张 GPU
volumes:
- name: modelscope-cache
hostPath:
path: /opt/vllm_data/modelscope # 对应 Docker 的 -v 主机路径,这里先简写成本地路径了,实际部署时用pvc
type: DirectoryOrCreate
- name: dshm
emptyDir:
medium: Memory
sizeLimit: 8Gi # 对应 Docker 的 --shm-size=8g
---
apiVersion: v1
kind: Service
metadata:
name: vllm-qwen2.5-7b
spec:
selector:
app: vllm-qwen2.5-7b
ports:
- protocol: TCP
port: 8000
targetPort: 8000
type: ClusterIP
随后是用 vllm 转发工具将这些后端容器关联起来
apiVersion: v1
kind: ConfigMap
metadata:
name: router-config
data:
config.yaml: |
models:
- name: "qwen2.5-7b" # 对外显示的模型名,同时需要和上面 vllm 设置的模型名称一致
backend: "http://vllm-qwen2.5-7b:8000"
# 其他的模型也是一样的,把service 放在这里
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-router
spec:
replicas: 1
selector:
matchLabels:
app: vllm-router
template:
metadata:
labels:
app: vllm-router
spec:
containers:
- name: router
image: docker.1ms.run/lmcache/lmstack-router:latest
args:
- "--config=/etc/router/config.yaml"
- "--port=8000"
volumeMounts:
- name: config
mountPath: /etc/router
volumes:
- name: config
configMap:
name: router-config
---
apiVersion: v1
kind: Service
metadata:
name: vllm-router
spec:
selector:
app: vllm-router
ports:
- protocol: TCP
port: 8000
targetPort: 8000
type: ClusterIP
其他的就和上面 Ollama 一样了,不过 open-webui 的后端模型接口不能用 Ollama 的环境变量,应该用ENABLE_OPENAI_API = vllm-router 的 service
其他发行版安装GPU驱动参考
当你使用其他发现版时,就没有上面各种版本相关的问题,反而对你来说可能有困难点的是标准发行版内核,默认情况下需要安装软件存在证书签名,因此安装前需要查询内核信息
[root@node1 opt]# grep -E "CONFIG_MODULE_SIG|CONFIG_LOCK_DOWN_IN_SECURE_BOOT" /boot/config-$(uname -r)
CONFIG_MODULE_SIG_FORMAT=y
CONFIG_MODULE_SIG=y
# CONFIG_MODULE_SIG_FORCE is not set
CONFIG_MODULE_SIG_ALL=y
# CONFIG_MODULE_SIG_SHA1 is not set
# CONFIG_MODULE_SIG_SHA224 is not set
# CONFIG_MODULE_SIG_SHA256 is not set
# CONFIG_MODULE_SIG_SHA384 is not set
CONFIG_MODULE_SIG_SHA512=y
CONFIG_MODULE_SIG_HASH="sha512"
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
CONFIG_MODULE_SIG_KEY_TYPE_RSA=y
# CONFIG_MODULE_SIG_KEY_TYPE_ECDSA is not set
以上输出中 CONFIG_MODULE_SIG=y 说明当前内核检查软件签名能力是开启的
# 随后查看系统启动方式
yum install -y mokutil
mokutil --sb-state
如果输出是 EFI variables are not supported on this system 意思是当前系统采用传统BIOS启动方式,就不需要担心签名能力的影响
安装需要的内核引导软件,以及安装驱动过程中需要的工具包
# devel 和 headers 是需要的引导,dkms 是显卡驱动需要的模块生成工具,epel-release是社区软件补充仓库
dnf install -y kernel-devel-$(uname -r) kernel-headers-$(uname -r) dkms epel-release
安装驱动
#禁用默认的驱动
bash -c "echo -e 'blacklist nouveau\noptions nouveau modeset=0' > /etc/modprobe.d/blacklist-nouveau.conf"
# 刷新配置,不报错正常结束,则重启系统
dracut --force
reboot
# 重启后预计没有输出
lsmod | grep nouveau
# 给驱动执行权限
chmod 777 /opt/gpt1/NVIDIA-Linux-x86_64-575.57.08.run
# 临时切换服务器连接到纯文本模式
systemctl isolate multi-user.target
# 安装驱动
/opt/gpt1/NVIDIA-Linux-x86_64-575.57.08.run --dkms
不指定内核源码安装驱动,就没有上面那么麻烦的选择,一路 yes 和 ok 即可
# 如果安装出现问题 先卸载
/opt/gpt1/NVIDIA-Linux-x86_64-575.57.08.run --uninstall
# 安装完成后,尝试加载驱动模块
modprobe nvidia
# 加载不报错,就可以持久化
vi /etc/modules-load.d/nvidia.conf
# 追加如下内容
nvidia
nvidia_uvm
nvidia_drm
nvidia_modeset
nvidia_peermem
英伟达驱动有个 nvidia-persistenced 功能,能让 GPU 运行更稳定,可选启动,本文这里没有使用,开启方式见阿里云文档
# 安装成功后,预计看到如下输出
[root@wangyang gpt1]# nvidia-smi
Mon May 4 21:14:55 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 575.57.08 Driver Version: 575.57.08 CUDA Version: 12.9 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA A10 Off | 00000000:00:03.0 Off | 0 |
| 0% 29C P0 59W / 150W | 0MiB / 23028MiB | 21% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| No running processes found |
+-----------------------------------------------------------------------------------------+
# 检查这些文件是否正常存在
[root@node1 opt]# ls /lib/modules/$(uname -r)/extra/nvidia*.ko
/lib/modules/5.14.0-611.49.2.el9_7.x86_64/extra/nvidia-drm.ko
/lib/modules/5.14.0-611.49.2.el9_7.x86_64/extra/nvidia-modeset.ko
/lib/modules/5.14.0-611.49.2.el9_7.x86_64/extra/nvidia-peermem.ko
/lib/modules/5.14.0-611.49.2.el9_7.x86_64/extra/nvidia-uvm.ko
/lib/modules/5.14.0-611.49.2.el9_7.x86_64/extra/nvidia.ko
[root@node1 opt]# dkms status
nvidia/575.57.08, 5.14.0-611.49.2.el9_7.x86_64, x86_64: installed
[root@node1 opt]# which nvidia-smi
/usr/bin/nvidia-smi
如果,在安装过程中,发现装不上,先查询日志看原因
sudo dmesg | grep -i "nvidia\|nvrm\|error\|fail"
如果真的是签名能力影响,网上有个帖子说是通过如下方法关闭系统引导配置文件中的软件签名能力,但由于本文顺利安装上了,所以没机会验证,各位读者遇到的话试一试
vi /etc/default/grub
# 在 GRUB_CMDLINE_LINUX 加入 module.sig_enforce=0
GRUB_CMDLINE_LINUX="rd.lvm.lv=almalinux/root module.sig_enforce=0"
# 重新生成引导,并重启系统
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot
随后就是容器访问GPU的驱动的安装
# 如果你用的云服务器,去找售后会有内网可用的软件源。如果不是,就不要用官网的方式,国内访问不到,也不要试图用公开的国内镜像
# 不然你会发现一个非常傻逼的事情,直接下载官网的 repo 包下载不到东西,然后国内能拉到的镜像文件,最终全是指向官网的yum源
# 直接手动常见一个 repo 文件从 Geekery 镜像安装最新版 RPM 包并安装
vi /etc/yum.repos.d/nvidia-container-toolkit.repo
[nvidia-container-toolkit-geekery]
name=NVIDIA Container Toolkit (Geekery Mirror)
baseurl=https://nvidia-docker.geekery.cn/libnvidia-container/stable/rpm/$basearch
enabled=1
gpgcheck=0
# 查看是否有包输出
yum clean all
dnf list available --disablerepo='*' --enablerepo='nvidia-container-toolkit-geekery'
# 安装
sudo dnf install -y nvidia-container-toolkit
# 预计结果会有四个包安装
libnvidia-container-tools-1.19.0-1.x86_64
libnvidia-container1-1.19.0-1.x86_64
nvidia-container-toolkit-1.19.0-1.x86_64
nvidia-container-toolkit-base-1.19.0-1.x86_64
最后查看版本
[root@node1 yum.repos.d]# nvidia-container-toolkit --version
NVIDIA Container Runtime Hook version 1.19.0
commit: ec7b4e2fa2caecad6d89be4a26029b831fe7503a
API 接口使用注意点
本文在此要强调的是 ollama 和 vllm 提供的接口都是 OpenAI 标准规范的格式
ollama 的
curl http://127.0.0.1:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen2.5:0.5b",
"messages": [
{"role": "user", "content": "你好,请简单介绍一下你自己"}
],
"stream": false
}'
vllm 的
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen2.5-7b",
"messages": [
{"role": "system", "content": "你是一个乐于助人的助手。"},
{"role": "user", "content": "请简单介绍一下 vLLM 是什么?"}
],
"temperature": 0.7,
"max_tokens": 128
}'
但是 open-webui 提供的对外接口是 api 开头的
curl http://localhost:3000/api/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-6cdf1ef77df04fa7acea4d7b1dc489ad" \
-d '{
"model": "qwen2:0.5b",
"messages": [
{ "role": "user", "content": "你好,介绍一下自己吧" }
],
"stream": false
}'
这并不是说 open-webui 内部没有 v1 接口,而是 open-webui 它的核心设计点是一个平台,如果各位读者在公司内部用过定制化的模型服务应该都会见过各式各样的接口,open-webui 也是这样,它是一个涵盖知识库、外部网页、文件、联网搜索等等的集合体,而模型加载工具它的设计非常直白就只是提供这个模型自身的语言对话能力,没有其他复杂功能,所以采用了同一套标准接口。而 v1 接口在 webui 中是内部端口不允许外部调用,强行调用会报错没有权限,且它的 api 接口完全兼容 OpenAI 的使用方式,不需要使用者操心兼容问题
包括接口在内的使用问题,看官方文档 https://docs.openwebui.com/reference/api-endpoints/
最后再强调一点,open-webui 官方文档中有默认模型的环境变量,但实际测试多次尝试下都不生效,就很怪异,不能在调接口的时候生效,倒是用户通过 ui 界面设置默认,新开会话会显示,但任然作用不到 api 接口上,当做没有这个设置调接口必须带模型就行。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)