ollama 预加载的模型未加载到GPU上问题方案详解
针对Ubuntu系统重启后Ollama服务无法自动使用GPU的问题,提出三种解决方案:1)优化启动脚本增加GPU驱动就绪检查;2)配置Systemd服务确保GPU初始化完成后再启动容器;3)调整Docker启动参数确保正确挂载GPU。
目录
3.1 方案一:优化启动脚本 (init_models.sh)
前言
在某台ubuntu系统的机器上部署了dify和ollama服务,使用下述命令启动的ollama服务:
sudo docker run -d --gpus=all -v /dify_workspace/ollama_weights:/root/.ollama -v /dify_workspace/ollama_weights/init_models.sh:/init_models.sh -p 11434:11434 --network host --restart=always --name ollama --entrypoint /bin/sh ollama/ollama:latest /init_models.sh
问题:机器重启之后,ollama服务中加载的模型还是跑在cpu上,还必须再执行sudo docker restart ollama命令,然后模型才能使用GPU运行。
init_models.sh文件的内容如下:
#!/bin/sh
# 后台启动 ollama 服务
ollama serve &
# 等待服务就绪,通过尝试列出模型来检查
# sleep 5
max_attempts=30
attempt=1
until ollama list >/dev/null 2>&1; do
if [ $attempt -eq $max_attempts ]; then
echo "错误:等待Ollama服务启动超时"
exit 1
fi
sleep 2
attempt=$((attempt + 1))
done
# 模型预加载(不会输出内容)
ollama run qwen2.5:14b "warmup" >/dev/null 2>&1
# ollama run shaw/dmeta-embedding-zh:latest "warmup" >/dev/null 2>&1
ollama run lrs33/bce-embedding-base_v1:latest "warmup" >/dev/null 2>&1
# 保持前台运行
wait
1. 问题解析
根据描述的情况,Ollama容器在主机重启后能自动运行,但GPU却无法正常使用,这通常是由于Ollama服务的启动速度快于主机上NVIDIA GPU驱动的初始化所导致的时序问题。
简单来说,当你的启动脚本开始检查Ollama是否就绪时,GPU环境可能还未准备好,导致后续加载的模型都默认使用了CPU。
2. 解决方案对比与选择
你可以从以下几个方案中选择适合你的解决路径,它们各有侧重点:
| 方案 | 核心思路 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|---|
| 方案一:优化启动脚本 | 在脚本中增加对GPU驱动的就绪检查。 | 改动小,直接针对问题根源。 | 依赖脚本逻辑,可能与Docker的重启策略存在时序竞争。 | 作为快速验证和补充方案。 |
| 方案二:使用Systemd服务 | 通过Systemd确保GPU就绪后再启动容器。 | 启动顺序可控,Linux系统原生支持。 | 需要额外配置Systemd单元文件。 | 生产环境首选,确保稳定性。 |
| 方案三:调整Docker配置 | 为容器添加必要的环境和权限参数。 | 配置集中在Docker层面,管理方便。 | 不直接解决主机驱动时序问题。 |
3. 各方案具体配置步骤
3.1 方案一:优化启动脚本 (init_models.sh)
在脚本中ollama serve &命令之后,增加对GPU驱动就绪的检查。可以将下面这段代码插入到“等待服务就绪”的循环之前:
# 新增:等待NVIDIA驱动和GPU设备就绪
max_gpu_attempts=30
gpu_attempt=1
until nvidia-smi >/dev/null 2>&1; do
if [ $gpu_attempt -eq $max_gpu_attempts ]; then
echo "错误:等待NVIDIA GPU驱动就绪超时"
exit 1
fi
sleep 2
gpu_attempt=$((gpu_attempt + 1))
done
echo "NVIDIA GPU驱动已就绪。"
3.2 方案二:配置Systemd服务
这个方法可以让系统在网络和基本服务启动后,再启动你的Ollama容器,给GPU驱动留出足够的初始化时间。
1. 创建Systemd服务文件
使用以下命令创建并编辑文件:
sudo nano /etc/systemd/system/ollama-docker.service
2. 编写服务配置
将以下内容写入文件,注意替换其中 /dify_workspace 为你的实际路径:
[Unit]
Description=Ollama Docker Container with GPU
Requires=docker.service
After=docker.service network.target nvidia-persistenced.service
# 明确等待docker、网络和NVIDIA持久化服务
Wants=nvidia-persistenced.service
[Service]
Restart=always
ExecStartPre=/usr/bin/docker stop ollama 2>/dev/null || true
ExecStartPre=/usr/bin/docker rm ollama 2>/dev/null || true
# 启动命令(已整合了你原有的docker run参数)
ExecStart=/usr/bin/docker run -d --gpus=all \
-v /dify_workspace/ollama_weights:/root/.ollama \
-v /dify_workspace/ollama_weights/init_models.sh:/init_models.sh \
-p 11434:11434 \
--network host \
--name ollama \
--entrypoint /bin/sh \
ollama/ollama:latest \
/init_models.sh
ExecStop=/usr/bin/docker stop ollama
[Install]
WantedBy=multi-user.target
3. 启用并启动服务
依次执行以下命令:
sudo systemctl daemon-reload
sudo systemctl enable ollama-docker.service # 设置开机自启
sudo systemctl start ollama-docker.service # 立即启动服务
sudo systemctl status ollama-docker.service # 检查状态
3.3 方案三:调整Docker启动参数
在现有或新的 docker run 命令中,确保添加了正确的GPU和环境变量参数,这是GPU能正确挂载的基础。
# 关键参数示例,请整合到你的命令中
--gpus all \
--runtime=nvidia \
-e NVIDIA_VISIBLE_DEVICES=all \
-e NVIDIA_DRIVER_CAPABILITIES=compute,utility \
4. 行动建议与验证
综合以上方案,我为你梳理出一条清晰的解决路径:
-
立即验证(快速方案):先执行 方案三,确保你的
docker run命令包含了完整的GPU参数。这是最基础的检查。 -
根本解决(推荐方案):优先实施 方案二(Systemd服务),因为它能从系统层面最可靠地解决启动时序问题。在配置Systemd时,可以将 方案一 中对GPU的检查脚本也整合进去,作为双重保障。
-
验证效果:配置完成后,重启你的Ubuntu主机。等待几分钟后,通过以下命令检查是否成功:
-
检查容器状态:
docker ps -
检查GPU是否被容器识别:
docker exec ollama nvidia-smi或docker exec ollama bash -c "ollama run qwen2.5:14b 'hello'"并观察日志是否提示使用GPU。
-
如果按照方案二配置Systemd,在后续的重启中,系统就会自动按正确顺序启动服务。如果重启后问题依然存在,可以执行 sudo systemctl status ollama-docker.service 和 docker logs ollama 这两个命令查看输出结果,进行进一步分析。
更多推荐

所有评论(0)