Ollama本地部署大模型实战:企业私有化LLM方案
前言
2024年大模型火得一塌糊涂,但很多公司不敢把业务数据往OpenAI、文心一言这些公网API传——合规问题、数据安全、成本控制,哪个都是痛点。
我们公司从年中开始搞私有化部署,踩了不少坑,也积累了一些经验。Ollama是我们最终选定的方案,原因很简单:部署简单、模型生态好、资源占用可控。
这篇文章把整个过程记录下来,从单机部署到多节点调度,希望对有同样需求的朋友有帮助。
为什么选Ollama
市面上本地部署LLM的方案不少:
| 方案 | 优点 | 缺点 |
|---|---|---|
| Ollama | 部署简单,模型库丰富 | 功能相对基础 |
| vLLM | 推理性能强,支持并发 | 部署复杂,硬件要求高 |
| llama.cpp | 资源占用小,CPU可跑 | 需要手动编译,维护成本高 |
| LocalAI | 兼容OpenAI API | 社区相对小 |
| Text Generation WebUI | 界面友好 | 性能一般 |
我们的场景是内部知识库问答和代码辅助,QPS不高但要稳定。Ollama的部署成本和维护成本都最低,最终选了它。
环境准备
硬件要求
跑大模型最重要的是显存。参考配置:
- 7B模型(如Qwen2-7B):8GB显存起步,16GB流畅
- 13B模型:16GB显存起步,24GB流畅
- 70B模型:至少48GB显存,或者用多卡
我们用的是RTX 4090(24GB),跑Qwen2-7B绰绰有余,13B也能跑。
安装Ollama
Linux一行命令:
curl -fsSL https://ollama.com/install.sh | sh
验证安装:
ollama --version
# ollama version is 0.5.4
启动服务:
# 默认监听127.0.0.1:11434
ollama serve
# 如果需要远程访问,设置环境变量
OLLAMA_HOST=0.0.0.0:11434 ollama serve
设为systemd服务:
cat > /etc/systemd/system/ollama.service << 'EOF'
[Unit]
Description=Ollama Service
After=network-online.target
[Service]
ExecStart=/usr/local/bin/ollama serve
User=root
Restart=always
RestartSec=3
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_MODELS=/data/ollama/models"
[Install]
WantedBy=default.target
EOF
systemctl daemon-reload
systemctl enable ollama
systemctl start ollama
模型选择与下载
常用模型推荐
国内场景,中文能力是刚需。实测下来这几个模型效果不错:
# 通义千问2(推荐,中文效果好)
ollama pull qwen2:7b
ollama pull qwen2:72b # 大杯,需要大显存
# Llama3(英文强,中文一般)
ollama pull llama3.1:8b
# 代码模型
ollama pull codellama:7b
ollama pull deepseek-coder:6.7b # 国产代码模型,效果不错
# 小模型(CPU也能跑)
ollama pull phi3:mini # 3.8B参数,轻量
ollama pull gemma2:2b
查看已下载模型
ollama list
NAME ID SIZE MODIFIED
qwen2:7b xxx 4.4 GB 2 days ago
deepseek-coder xxx 3.8 GB 1 week ago
模型存储位置
默认在 ~/.ollama/models,可以通过环境变量改:
export OLLAMA_MODELS=/data/ollama/models
模型文件很大,建议放在SSD上,加载速度快很多。
基础使用
命令行交互
ollama run qwen2:7b
>>> 用Python写一个快速排序
def quicksort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
# 测试
print(quicksort([3,6,8,10,1,2,1]))
>>>
REST API调用
Ollama默认提供HTTP API,兼容OpenAI格式:
# 简单对话
curl http://localhost:11434/api/generate -d '{
"model": "qwen2:7b",
"prompt": "天空为什么是蓝色的?",
"stream": false
}'
# 流式输出
curl http://localhost:11434/api/generate -d '{
"model": "qwen2:7b",
"prompt": "写一首关于程序员的诗",
"stream": true
}'
Python SDK
import ollama
# 简单对话
response = ollama.chat(model='qwen2:7b', messages=[
{'role': 'user', 'content': '解释一下什么是微服务架构'}
])
print(response['message']['content'])
# 流式输出
for chunk in ollama.chat(
model='qwen2:7b',
messages=[{'role': 'user', 'content': '写一个Python装饰器的例子'}],
stream=True
):
print(chunk['message']['content'], end='', flush=True)
兼容OpenAI SDK
Ollama支持OpenAI格式的API,现有代码改改endpoint就能用:
from openai import OpenAI
client = OpenAI(
base_url='http://localhost:11434/v1',
api_key='ollama' # 随便填,Ollama不校验
)
response = client.chat.completions.create(
model='qwen2:7b',
messages=[
{'role': 'system', 'content': '你是一个专业的技术顾问'},
{'role': 'user', 'content': 'Kubernetes和Docker的区别是什么?'}
]
)
print(response.choices[0].message.content)
进阶配置
自定义模型参数
创建Modelfile定制模型行为:
cat > Modelfile << 'EOF'
FROM qwen2:7b
# 系统提示词
SYSTEM """
你是一个专业的代码审查助手。你的职责是:
1. 分析代码中的潜在问题
2. 提出优化建议
3. 指出安全隐患
回答要简洁专业,用中文。
"""
# 调整参数
PARAMETER temperature 0.7
PARAMETER top_p 0.9
PARAMETER num_ctx 4096
EOF
# 创建自定义模型
ollama create code-reviewer -f Modelfile
显存优化
显存不够时的几个优化方向:
# 1. 减小上下文长度(默认2048)
PARAMETER num_ctx 1024
# 2. 使用量化版本
ollama pull qwen2:7b-q4_0 # 4bit量化,显存占用减半
# 3. 关闭KV缓存复用
PARAMETER num_keep 0
GPU选择
多卡环境指定GPU:
# 只用第一张卡
CUDA_VISIBLE_DEVICES=0 ollama serve
# 用第2、3张卡
CUDA_VISIBLE_DEVICES=1,2 ollama serve
生产环境部署
Nginx反向代理
upstream ollama {
server 127.0.0.1:11434;
keepalive 32;
}
server {
listen 443 ssl;
server_name llm.internal.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
# 简单的Token认证
location /api/ {
if ($http_authorization != "Bearer your-secret-token") {
return 401;
}
proxy_pass http://ollama;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_read_timeout 300s; # 大模型响应慢,超时要设长
}
}
Docker部署
# docker-compose.yml
version: '3.8'
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
ports:
- "11434:11434"
volumes:
- ./models:/root/.ollama
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
restart: unless-stopped
docker-compose up -d
# 进容器下载模型
docker exec -it ollama ollama pull qwen2:7b
多节点负载均衡
我们有三台GPU服务器,用Nginx做负载均衡:
upstream ollama_cluster {
least_conn; # 最少连接数
server 10.0.1.10:11434 weight=2; # 4090,权重高
server 10.0.1.11:11434 weight=2;
server 10.0.1.12:11434 weight=1; # 3090,权重低
keepalive 64;
}
三台机器分布在不同网段,我用星空组网把它们串到一起,统一管理。部署新模型或者更新配置时,Ansible一条命令就能批量搞定。
监控告警
用Prometheus采集指标:
# 简单的健康检查脚本
import requests
import time
def check_ollama(host):
try:
start = time.time()
resp = requests.get(f'http://{host}:11434/api/tags', timeout=5)
latency = time.time() - start
return resp.status_code == 200, latency
except:
return False, 0
# 配合Prometheus的Pushgateway上报
踩过的坑
坑1:首次加载慢
第一次调用模型会很慢(10-30秒),因为要把模型加载到显存。
解决:服务启动后主动预热
# 启动脚本里加预热
curl http://localhost:11434/api/generate -d '{
"model": "qwen2:7b",
"prompt": "hello",
"stream": false
}'
坑2:长文本OOM
上下文太长会显存溢出。
解决:限制num_ctx,或者做文本分片
def chunk_text(text, max_length=2000):
"""长文本分片"""
chunks = []
for i in range(0, len(text), max_length):
chunks.append(text[i:i+max_length])
return chunks
坑3:并发性能差
Ollama单实例并发能力有限,高并发会排队。
解决:多实例 + 负载均衡,或者换vLLM(专门优化过并发)
坑4:中文分词问题
有些模型对中文支持不好,输出会有乱码。
解决:优先用Qwen2、GLM等国产模型,中文效果明显好很多
实际效果
分享一下我们的使用数据:
- 模型:Qwen2-7B
- 硬件:RTX 4090 24GB
- 平均响应时间:2-5秒(视问题复杂度)
- 每天调用量:约2000次
- 月成本:电费约200元
对比之前用OpenAI API,每月几千块的API费用省下来了,数据也不用出内网。
总结
Ollama确实降低了大模型私有化部署的门槛:
- 部署简单:一行命令安装,模型即拉即用
- 生态丰富:主流开源模型基本都有
- 兼容性好:OpenAI格式API,迁移成本低
- 资源可控:7B模型消费级显卡就能跑
当然它也有局限:不适合高并发场景,功能相对基础。如果需要更强的推理性能,可以看看vLLM或TensorRT-LLM。
对于大多数企业内部应用场景,Ollama是一个性价比很高的选择。先跑起来,后面再根据实际需求优化。

浙公网安备 33010602011771号