
很多人以為部署大模型是算法工程師的專屬技能——下載幾個Python包跑個transformersdemo就算完事。但真正到了生產環境問題才剛開始模型版本怎么管理GPU顯存怎么分配API并發撐不住怎么辦日志和監控怎么接這篇文章不講理論只講一個Java后端工程師能直接上手落地的方案用Docker容器化部署Ollama推理服務配合Open WebUI提供可視化界面再用vLLM解決高并發瓶頸。全程代碼可復制配置可運行。一、整體架構我們在搭建什么先搞清楚要搭的這套東西長什么樣核心組件就三個Ollama本地大模型推理引擎負責加載模型、管理版本、暴露REST APIOpen 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_HOST0.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 APIOllama暴露的是兼容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) { MapString, 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 FluxString chatStream(String userMessage) { MapString, 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模型建議409613B可開到8192streamtrue開啟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_HOST0.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_URLhttp://ollama:11434 # 允許新用戶注冊生產環境建議關閉改用手動導入 - ENABLE_SIGNUPtrue # 默認語言 - DEFAULT_LOCALEzh-CN depends_on: - ollama restart: unless-stopped ? volumes: ollama-models: open-webui-data:啟動后訪問http://localhost:3000注冊一個賬號就能在界面里選擇已下載的模型開始對話。生產環境注意ENABLE_SIGNUPtrue只適合內網測試。外網部署時建議關閉注冊通過管理員后臺批量導入用戶或者接入OAuth2支持GitHub、Google、企業微信等前面加一層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_HOST0.0.0.0:11434 # GPU 配置核心 deploy: resources: reservations: devices: - driver: nvidia count: 1 # 使用1張GPUall表示全部 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_URLhttp://ollama:11434 - ENABLE_SIGNUPtrue 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-smi4.2 顯存占用參考表模型參數量FP16顯存4-bit量化建議GPUqwen27B~14GB~4GBRTX 3060 12GBqwen214B~28GB~8GBRTX 3090 24GBllama38B~16GB~5GBRTX 4060 Ti 16GBllama370B~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 4090qwen2:7b模型方案并發數平均延遲吞吐量(token/s)Ollama1800ms45Ollama83200ms38vLLM1750ms48vLLM81100ms180vLLM322800ms420結論高并發下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_DEVICES0 # 啟動命令加載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后端接入vLLMvLLM暴露的是標準OpenAI APISpring 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 FluxString askStream(String question) { return chatModel.stream(question) .map(chunk - chunk.getResult().getOutput().getContent()); } }兼容性說明vLLM的/v1/chat/completions端點與OpenAI API完全兼容所以Spring AI的OpenAiChatModel可以直接復用一行不改。六、壓測與性能調優部署完了得知道它能扛多少并發。推薦用locust或k6做壓測。# 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模型量化顯存不夠 → 換Q4量化版精度損失通常在可接受范圍上下文截斷num_ctx不要設太大按需分配省顯存批處理大小vLLM的--max-num-seqs控制最大并發序列數默認256可根據GPU調整多實例負載均衡單卡撐不住時開多個Ollama/vLLM實例前面掛Nginx輪詢七、建議建議一開發用Ollama生產用vLLMOllama的模型管理和WebUI生態更完善適合開發調試階段。正式上線后如果QPS超過10建議切到vLLM吞吐量提升一個數量級。建議二模型文件做CDN緩存團隊多人部署時每個人重新下載幾個GB的模型很浪費時間。可以在內網搭一個Harbor或Nexus把常用模型鏡像緩存起來新人入職docker pull幾分鐘搞定。建議三監控必須接否則出事找不到根因至少監控三個指標GPU顯存占用nvidia-smi或DCGM exporter推理延遲P99Prometheus Grafana模型加載狀態Ollama的/api/tags接口輪詢部署大模型和部署MySQL本質上沒有區別——都是起一個服務、掛一個卷、配一個端口。區別在于大模型的數據庫是幾十億個參數查詢一次要燒幾焦耳的電。明天我們聊一個更接地氣的話題國內三大AI云平臺阿里云百煉 / 騰訊云混元 / 火山引擎方舟的企業級接入對比。如果你不想自己運維GPU機器那篇就是為你寫的。