# Modal Deployment: MiniCPM-o-4_5 via llama.cpp ## 概述 在 Modal.com 的 **T4 GPU** 上部署 MiniCPM-o-4_5 模型,通过 llama-cpp-python (CUDA pre-built wheel) 提供 OpenAI 兼容的 API 接口。 ## 架构 ``` 用户请求 → FastAPI (ASGI) → llama-server (OpenAI 兼容) → MiniCPM-o-4_5 GGUF ↓ /v1/chat/completions (文本 + 图片多模态) /v1/embeddings /health ``` ## 前置条件 1. Modal 账号: https://modal.com/ 2. 安装 Modal CLI: `pip install modal` 3. 登录: `modal token new` ## 模型文件 部署需要 3 个核心 GGUF 文件(Volume 中需包含): | 文件 | 大小 | 用途 | |------|------|------| | `MiniCPM-o-4_5-Q4_K_M.gguf` | ~12 GB | 主模型(文本推理) | | `vision/MiniCPM-o-4_5-vision-F16.gguf` | ~1 GB | 视觉投影层(可选,用于图片理解) | | `audio/MiniCPM-o-4_5-audio-F16.gguf` | ~630 MB | 音频投影层(当前未使用) | ⚠️ **关键变更**:`--mmproj` 只传 vision 投影层,**不能**传入多个 .gguf 文件。旧代码使用 `find_mmproj_files()` 递归搜索导致传入 9 个文件而崩溃。 ### 上传步骤 ```bash # 上传模型到 Modal Volume(只需一次) modal volume put minicpm-o-4_5-models /path/to/models/MiniCPM-o-4_5-gguf / # 验证 modal volume ls minicpm-o-4_5-models / ``` ## 部署 ```bash cd modal_deploy # 部署为 Modal App(持续运行的服务) modal deploy deploy.py # 或开发模式(热重载,日志在前台) modal serve deploy.py ``` 部署后 Modal 会输出一个 URL,如 `https://your-org--prego-pal-minicpm-serve.modal.run` ## API 接口 ### 1. 健康检查 ```bash GET /health ``` 返回:`{"status": "ok"}` ### 2. 模型列表 ```bash GET /v1/models ``` ### 3. 文本对话 (OpenAI 兼容) ```bash POST /v1/chat/completions Content-Type: application/json { "model": "MiniCPM-o-4_5", "messages": [ {"role": "user", "content": "今天孕妇可以吃什么?"} ], "max_tokens": 1024, "temperature": 0.7, "stream": false } ``` ### 4. 多模态对话(图片理解) llama-server (b4690+) 原生支持 OpenAI 多模态格式,通过 `/v1/chat/completions` 即可: ```bash POST /v1/chat/completions Content-Type: application/json { "model": "MiniCPM-o-4_5", "messages": [ {"role": "user", "content": [ {"type": "text", "text": "这张图片里有什么食物?"}, {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}} ]} ], "max_tokens": 1024, "temperature": 0.7 } ``` ### 5. 嵌入向量 ```bash POST /v1/embeddings Content-Type: application/json { "model": "MiniCPM-o-4_5", "input": ["孕期营养建议"] } ``` ## 测试 ```bash # 快速测试模型能否加载和推理 modal run modal_deploy/deploy.py::test_inference # 上传模型 modal run modal_deploy/deploy.py::upload_models ``` ## 配置 在 `deploy.py` 中可调整的参数: - `container_idle_timeout=300` — 空闲 5 分钟后自动关闭 - `gpu="T4"` — GPU 类型(16GB VRAM,$0.50/hr。也可用 A100: $1.50/hr) - `n_ctx=8192` — 上下文窗口大小 - `n_gpu_layers=-1` — GPU 层数(-1=全部到 GPU) ## 与 PregoPal 集成 其他服务通过 HTTP 调用此 API: ```python import requests API_BASE = "https://your-app.modal.run" def ask_minicpm(prompt: str) -> str: r = requests.post(f"{API_BASE}/v1/chat/completions", json={ "messages": [{"role": "user", "content": prompt}], "max_tokens": 512, "temperature": 0.7, }) return r.json()["choices"][0]["message"]["content"] ``` ## 注意事项 1. **冷启动**:无请求 >5 分钟后容器关闭,下次请求需等待 ~30-60 秒(模型加载) 2. **成本**:T4 约 $0.50/小时(vs A100 $1.50/hr),按实际使用计费。降级节省 **67%** 3. **模型上传**:Volume 是持久化的,模型只需上传一次 4. **并发**:`@modal.concurrent(max_inputs=10)` 支持 10 个并发请求 5. **VRAM 使用**:Q4_K_M 模型 4.7GB + vision 0.5GB + KV cache ≈ 6GB,T4 16GB 完全够用 6. **修复说明**:旧 deploy.py 的 `find_mmproj_files()` 递归搜索到 9 个 .gguf 文件并全部作为 `--mmproj` 传入,导致启动失败。新版已明确指定 `--mmproj` 使用 vision 投影层(仅一个文件)。