news 2026/9/7 14:14:28

Day 61 | Docker部署AI推理服务:Ollama + Open WebUI生产实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Day 61 | Docker部署AI推理服务:Ollama + Open WebUI生产实践

很多人以为部署大模型是算法工程师的专属技能——下载几个Python包,跑个transformersdemo就算完事。但真正到了生产环境,问题才刚开始:模型版本怎么管理?GPU显存怎么分配?API并发撑不住怎么办?日志和监控怎么接?

这篇文章不讲理论,只讲一个Java后端工程师能直接上手落地的方案:用Docker容器化部署Ollama推理服务,配合Open WebUI提供可视化界面,再用vLLM解决高并发瓶颈。全程代码可复制,配置可运行。


一、整体架构:我们在搭建什么

先搞清楚要搭的这套东西长什么样:

核心组件就三个:

  • Ollama:本地大模型推理引擎,负责加载模型、管理版本、暴露REST API

  • Open WebUI:基于Web的ChatGPT风格对话界面,支持多用户、多模型切换、对话历史

  • Docker:把整个环境打包成可移植的容器,开发环境一键复制到生产环境


二、Ollama Docker部署:5分钟跑起来

Ollama的Docker镜像已经预装了推理运行时,不需要你本地安装CUDA工具链,也不需要配Python环境。

2.1 基础部署(CPU模式,适合测试)

# docker-compose.yml —— Ollama基础版 version: '3.8' ​ services: ollama: image: ollama/ollama:0.3.6 container_name: ollama ports: - "11434:11434" volumes: # 模型文件持久化,避免每次重启重新下载 - ollama-models:/root/.ollama environment: # 允许跨域访问,WebUI需要 - OLLAMA_ORIGINS=* # 监听所有接口 - OLLAMA_HOST=0.0.0.0:11434 restart: unless-stopped ​ volumes: ollama-models:

启动命令:

docker compose up -d # 拉取模型(以通义千问7B为例,约4.5GB) docker exec -it ollama ollama pull qwen2:7b # 验证模型列表 docker exec -it ollama ollama list

关键点volumes一定要配。模型文件动辄几个GB,不配持久化卷,容器重启就全丢,下次启动重新下载,血泪教训。

2.2 直接调用Ollama API

Ollama暴露的是兼容OpenAI格式的REST API,从你的Java后端调起来非常直接:

/** * Ollama API 调用示例 * 依赖:Spring Boot 3.2+ + Spring Web */ @Service public class OllamaChatService { ​ private final WebClient webClient; ​ public OllamaChatService(WebClient.Builder builder) { // 连接本地Ollama服务 this.webClient = builder .baseUrl("http://localhost:11434") .build(); } ​ /** * 同步对话调用 */ public String chat(String userMessage) { Map<String, Object> request = Map.of( "model", "qwen2:7b", "messages", List.of( Map.of("role", "system", "content", "你是一个Java技术专家"), Map.of("role", "user", "content", userMessage) ), "stream", false, "options", Map.of( "temperature", 0.7, "num_ctx", 4096 // 上下文窗口大小 ) ); ​ return webClient.post() .uri("/api/chat") .bodyValue(request) .retrieve() .bodyToMono(String.class) .block(); } ​ /** * 流式输出(SSE)—— 用于实时打字机效果 */ public Flux<String> chatStream(String userMessage) { Map<String, Object> request = Map.of( "model", "qwen2:7b", "messages", List.of( Map.of("role", "user", "content", userMessage) ), "stream", true ); ​ return webClient.post() .uri("/api/chat") .bodyValue(request) .retrieve() .bodyToFlux(String.class); } }

参数说明

  • temperature:控制生成随机性,0.1~0.3适合代码/问答,0.7~0.9适合创意写作

  • num_ctx:上下文token数,7B模型建议4096,13B可开到8192

  • stream:true开启SSE流式,false等完整结果返回


三、Open WebUI:给推理服务穿上衣服

光有API不够,团队里的产品、测试、运营也需要一个界面来跟模型对话。Open WebUI是目前最成熟的方案,功能对标ChatGPT:

# docker-compose.yml —— Ollama + Open WebUI 完整版 version: '3.8' ​ services: ollama: image: ollama/ollama:0.3.6 container_name: ollama ports: - "11434:11434" volumes: - ollama-models:/root/.ollama environment: - OLLAMA_ORIGINS=* - OLLAMA_HOST=0.0.0.0:11434 restart: unless-stopped ​ open-webui: image: ghcr.io/open-webui/open-webui:0.3.10 container_name: open-webui ports: - "3000:8080" volumes: - open-webui-data:/app/backend/data environment: # 指向Ollama服务(容器内通过服务名访问) - OLLAMA_BASE_URL=http://ollama:11434 # 允许新用户注册(生产环境建议关闭,改用手动导入) - ENABLE_SIGNUP=true # 默认语言 - DEFAULT_LOCALE=zh-CN depends_on: - ollama restart: unless-stopped ​ volumes: ollama-models: open-webui-data:

启动后访问http://localhost:3000,注册一个账号,就能在界面里选择已下载的模型开始对话。

生产环境注意ENABLE_SIGNUP=true只适合内网测试。外网部署时建议:

  1. 关闭注册,通过管理员后台批量导入用户

  2. 或者接入OAuth2(支持GitHub、Google、企业微信等)

  3. 前面加一层Nginx做HTTPS和基础认证


四、GPU加速:让推理速度翻5倍

CPU跑7B模型,生成速度大概5~10 token/秒,能用但体验差。上了GPU,同样模型能跑到60~100 token/秒,差距肉眼可见。

4.1 nvidia-docker 配置

前提:宿主机已安装NVIDIA驱动 + NVIDIA Container Toolkit

# docker-compose.yml —— GPU加速版 version: '3.8' ​ services: ollama: image: ollama/ollama:0.3.6 container_name: ollama ports: - "11434:11434" volumes: - ollama-models:/root/.ollama environment: - OLLAMA_ORIGINS=* - OLLAMA_HOST=0.0.0.0:11434 # ========== GPU 配置核心 ========== deploy: resources: reservations: devices: - driver: nvidia count: 1 # 使用1张GPU,all表示全部 capabilities: [gpu] # ================================== restart: unless-stopped ​ open-webui: image: ghcr.io/open-webui/open-webui:0.3.10 container_name: open-webui ports: - "3000:8080" volumes: - open-webui-data:/app/backend/data environment: - OLLAMA_BASE_URL=http://ollama:11434 - ENABLE_SIGNUP=true depends_on: - ollama restart: unless-stopped ​ volumes: ollama-models: open-webui-data:

验证GPU是否生效:

# 进入容器查看 docker exec -it ollama nvidia-smi ​ # 运行模型时观察显存占用 docker exec -it ollama ollama run qwen2:7b # 另开一个终端: docker exec -it ollama nvidia-smi

4.2 显存占用参考表

模型参数量FP16显存4-bit量化建议GPU
qwen27B~14GB~4GBRTX 3060 12GB
qwen214B~28GB~8GBRTX 3090 24GB
llama38B~16GB~5GBRTX 4060 Ti 16GB
llama370B~140GB~40GBA100 40GB × 2

省钱技巧:Ollama默认会自动选择量化级别。显存不够时,它会自动加载Q4_K_M量化版本,牺牲一点精度换运行能力。你也可以手动指定:ollama pull qwen2:7b-q4_K_M


五、vLLM:高并发场景的核武器

Ollama适合个人开发和中小团队使用,但遇到高并发(比如同时几十个用户提问),单实例Ollama会排队处理,延迟直线上升。这时候需要vLLM

5.1 vLLM核心优势

vLLM是UC Berkeley开源的推理引擎,核心创新是PagedAttention技术——把GPU显存管理从粗粒度的"预分配一大块"改成细粒度的"按需分页",显著提升吞吐量。

实际压测数据(单张RTX 4090,qwen2:7b模型):

方案并发数平均延迟吞吐量(token/s)
Ollama1800ms45
Ollama83200ms38
vLLM1750ms48
vLLM81100ms180
vLLM322800ms420

结论:高并发下vLLM吞吐量是Ollama的10倍以上。

5.2 vLLM Docker部署

# docker-compose.yml —— vLLM高并发版 version: '3.8' ​ services: vllm: image: vllm/vllm-openai:v0.5.4 container_name: vllm-server ports: - "8000:8000" volumes: # 挂载宿主机上的模型目录 - /data/models:/models environment: - CUDA_VISIBLE_DEVICES=0 # 启动命令:加载Qwen2-7B,启用OpenAI兼容API command: > --model /models/Qwen2-7B-Instruct --served-model-name qwen2-7b --dtype half --tensor-parallel-size 1 --max-model-len 4096 --gpu-memory-utilization 0.9 deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] restart: unless-stopped

关键参数解析

  • --tensor-parallel-size:多GPU张量并行,2表示用2张卡同时算

  • --gpu-memory-utilization 0.9:使用90%显存,留10%给KV Cache动态增长

  • --max-model-len:最大上下文长度,超过会截断

5.3 Java后端接入vLLM

vLLM暴露的是标准OpenAI API,Spring AI直接就能对接:

/** * Spring AI 接入 vLLM 本地推理服务 * 依赖:org.springframework.ai:spring-ai-openai-spring-boot-starter:1.0.0-M1 */ @Configuration public class VllmConfig { ​ @Bean public OpenAiApi openAiApi() { // 指向本地vLLM服务,而非OpenAI官方 return new OpenAiApi( "http://localhost:8000/v1", // vLLM的OpenAI兼容端点 "sk-no-key-required" // 本地服务不需要真实API Key ); } ​ @Bean public OpenAiChatModel chatModel(OpenAiApi api) { var options = OpenAiChatOptions.builder() .withModel("qwen2-7b") // 与vLLM的served-model-name一致 .withTemperature(0.7) .withMaxTokens(2048) .build(); return new OpenAiChatModel(api, options); } } ​ @Service public class AiChatService { ​ @Autowired private OpenAiChatModel chatModel; ​ public String ask(String question) { return chatModel.call(question); } ​ public Flux<String> askStream(String question) { return chatModel.stream(question) .map(chunk -> chunk.getResult().getOutput().getContent()); } }

兼容性说明:vLLM的/v1/chat/completions端点与OpenAI API完全兼容,所以Spring AI的OpenAiChatModel可以直接复用,一行不改。


六、压测与性能调优

部署完了,得知道它能扛多少并发。推荐用locustk6做压测。

# locustfile.py —— 简单的Ollama压测脚本 from locust import HttpUser, task, between ​ class OllamaUser(HttpUser): wait_time = between(1, 3) ​ @task def chat(self): self.client.post("/api/chat", json={ "model": "qwen2:7b", "messages": [{"role": "user", "content": "用Java写一个单例模式"}], "stream": False })

运行:locust -f locustfile.py --host http://localhost:11434

调优 checklist

  1. 模型量化:显存不够 → 换Q4量化版,精度损失通常在可接受范围

  2. 上下文截断num_ctx不要设太大,按需分配,省显存

  3. 批处理大小:vLLM的--max-num-seqs控制最大并发序列数,默认256,可根据GPU调整

  4. 多实例负载均衡:单卡撑不住时,开多个Ollama/vLLM实例,前面挂Nginx轮询


七、建议

建议一:开发用Ollama,生产用vLLM

Ollama的模型管理和WebUI生态更完善,适合开发调试阶段。正式上线后,如果QPS超过10,建议切到vLLM,吞吐量提升一个数量级。

建议二:模型文件做CDN缓存

团队多人部署时,每个人重新下载几个GB的模型很浪费时间。可以在内网搭一个Harbor或Nexus,把常用模型镜像缓存起来,新人入职docker pull几分钟搞定。

建议三:监控必须接,否则出事找不到根因

至少监控三个指标:

  • GPU显存占用(nvidia-smi或DCGM exporter)

  • 推理延迟P99(Prometheus + Grafana)

  • 模型加载状态(Ollama的/api/tags接口轮询)


部署大模型和部署MySQL本质上没有区别——都是起一个服务、挂一个卷、配一个端口。区别在于,大模型的"数据库"是几十亿个参数,查询一次要烧几焦耳的电。

明天我们聊一个更接地气的话题:国内三大AI云平台(阿里云百炼 / 腾讯云混元 / 火山引擎方舟)的企业级接入对比。如果你不想自己运维GPU机器,那篇就是为你写的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 14:14:27

HarmonyOS 超级终端原理:从分布式软总线到设备虚拟化的全栈技术解密

文章目录每日一句正能量导读一、引言&#xff1a;什么是超级终端&#xff1f;二、超级终端核心技术架构2.1 四大核心技术的分工与协作2.2 18N 设备生态三、分布式软总线&#xff1a;超级终端的「神经网络」3.1 四大业务模型&#xff1a;发现 → 连接 → 组网 → 传输&#xff0…

作者头像 李华
网站建设 2026/8/31 0:34:34

TensorFlow 2.x模型构建全解析:从Sequential到子类化

1. 项目概述&#xff1a;从“搭积木”到“造积木”的模型构建之旅 在TensorFlow 2.x的世界里&#xff0c;构建一个神经网络模型&#xff0c;就像一位工程师面对一堆精密的零件&#xff0c;思考如何将它们组装成一台功能强大的机器。新手常常会一头扎进 Sequential() 的简单世…

作者头像 李华
网站建设 2026/8/30 17:19:33

从共享责任到数据边界,真正读懂 SAP HANA Cloud 的安全体系

很多团队第一次把数据库从本地数据中心迁移到 SAP HANA Cloud 时,会产生一种很自然的心理变化。过去维护本地 SAP HANA,操作系统、数据库软件、磁盘、备份、网络、补丁、证书、账号、权限,几乎每一层都在企业自己的管理范围里。到了云上以后,底层服务器看不到了,操作系统也…

作者头像 李华
网站建设 2026/8/31 0:05:26

告别重复劳动!一招教你创建 SolidWorks 可全局编辑的参数化定位点

在产品设计中&#xff0c;我们经常需要为配件添加定位点。如果位置需要调整&#xff0c;传统方法可能需要逐一修改&#xff0c;效率低下且容易出错。特别是当定位点数量很多时&#xff0c;修改起来简直是噩梦。一、设计痛点&#xff1a;定位点一改全改&#xff0c;效率低下的&q…

作者头像 李华
网站建设 2026/8/31 2:57:12

深度学习中的“最大向量”层:Embedding、分类层与Attention投影解析

Deep learning neural network layer with largest vector这个标题看起来更像一个从检索框里拼出来的技术问题&#xff0c;而不是某个具体开源项目的名字。先给路径不同的读者分流&#xff1a;如果是从 Vector Magic 这类位图转矢量软件搜过来的&#xff0c;这里讨论的 vector …

作者头像 李华