Lychee-Rerank-MM保姆级教程:Docker Compose多服务编排实践
1. 为什么需要多服务编排?——从单点运行到工程化部署
你可能已经试过直接运行python app.py启动 Lychee-Rerank-MM,页面在http://localhost:7860打开了,输入一段文字、一张图,也拿到了漂亮的 0.92 相关性得分。但当你想把它真正用进自己的搜索系统、电商推荐后台或知识库问答服务里时,问题就来了:
- 模型服务要和你的主业务服务(比如 Flask 或 FastAPI 接口)通信,怎么保证它稳定常驻?
- 多个团队成员共用一台服务器,有人改了配置、重启了进程,其他人立刻“掉线”怎么办?
- 想加个健康检查、日志轮转、自动重启、GPU 资源隔离,光靠
nohup和kill显然不够看。 - 更现实的是:你手头可能还跑着向量数据库(如 Milvus)、前端 Web 服务、甚至另一个重排模型——它们之间怎么协同?
这就是 Docker Compose 的用武之地。它不是炫技,而是把“能跑”变成“稳跑”、“可管”、“可扩”的关键一步。本教程不讲抽象概念,只带你一步步把 Lychee-Rerank-MM 封装成一个可复用、可协作、可交付的服务单元,全程基于真实终端操作,所有命令都经过验证。
你不需要是 DevOps 专家,只要会敲几行命令、看得懂 YAML 文件结构,就能完成这次升级。
2. 环境准备:三步确认,避免后续踩坑
在写任何配置前,请先花 2 分钟确认这三件事。跳过它们,90% 的启动失败都源于此。
2.1 确认模型路径已就位
Lychee-Rerank-MM 不是纯代码项目,它严重依赖预下载的模型权重。官方指定路径为/root/ai-models/vec-ai/lychee-rerank-mm,必须存在且完整。
执行以下命令验证:
ls -lh /root/ai-models/vec-ai/lychee-rerank-mm/你应该看到类似这些文件:
config.json model.safetensors pytorch_model.bin.index.json tokenizer.model tokenizer_config.json ...如果提示No such file or directory,请先去 ModelScope 下载完整模型包,解压到该路径。别用git clone—— 它只拉代码,不拉大模型文件。
2.2 确认 GPU 与驱动兼容
该模型需 BF16 精度 + Flash Attention 2,对 CUDA 版本有明确要求。推荐组合:
- NVIDIA 驱动 ≥ 525.60.13
- CUDA Toolkit ≥ 12.1
- PyTorch ≥ 2.0.0(带 CUDA 12.1 支持)
快速验证:
nvidia-smi # 查看驱动版本 nvcc --version # 查看 CUDA 编译器版本 python -c "import torch; print(torch.__version__, torch.cuda.is_available(), torch.cuda.get_device_properties(0))"最后一行应输出类似2.0.1 True <_CudaDeviceProperties name='NVIDIA A100-SXM4-40GB' ...>。若cuda.is_available()为False,请重装 PyTorch:
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu1212.3 确认基础工具链已安装
确保系统已安装 Docker 和 Docker Compose v2(非旧版docker-compose):
docker --version # 应 ≥ 24.0 docker compose version # 注意是 'compose'(单词),不是 'compose version'若未安装,请按官方文档操作:
Docker Engine 安装指南
Docker Compose 安装指南
小提醒:不要用
pip install docker-compose!那是已废弃的 v1 版本,不支持docker compose命令。
3. 构建专属镜像:从零开始定制 Dockerfile
官方未提供现成镜像,我们需要自己构建一个轻量、可靠、可复现的运行环境。核心原则:最小依赖 + 显式声明 + GPU 友好。
在项目根目录(/root/lychee-rerank-mm)下创建Dockerfile:
# 使用官方 PyTorch 镜像(预装 CUDA 12.1 + cuDNN) FROM pytorch/pytorch:2.0.1-cuda12.1-cudnn8-runtime # 设置工作目录 WORKDIR /app # 复制 requirements.txt 并安装 Python 依赖(分层缓存优化) COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码(不含模型,模型路径挂载) COPY app.py ./ COPY gradio_app.py ./ COPY utils/ ./utils/ # 创建模型挂载点(空目录,供运行时绑定) RUN mkdir -p /models/lychee-rerank-mm # 暴露端口 EXPOSE 7860 # 启动命令(Gradio 默认绑定 0.0.0.0:7860) CMD ["python", "app.py"]关键设计说明:
- 模型不打包进镜像:体积超 15GB,且不同用户模型路径不同。我们采用“挂载方式”,保持镜像纯净、复用性强。
- 不使用
start.sh:Shell 脚本在容器内权限复杂,直接调用python app.py更可控。 - 不设
USER切换:开发阶段优先保证功能,生产环境再加安全加固。
接着,在同一目录下创建requirements.txt(内容精简自原项目,移除冗余):
torch>=2.0.0 modelscope>=1.10.0 gradio>=4.20.0 qwen-vl-utils>=0.0.1 transformers>=4.37.0 sentencepiece>=0.1.99 accelerate>=0.24.0 safetensors>=0.4.0 pillow>=9.0.0现在构建镜像(耗时约 3–5 分钟):
docker build -t lychee-rerank-mm:latest .构建成功后,你会看到类似Successfully built abc123def456的提示。运行一次验证是否能启动:
docker run --gpus all -p 7860:7860 -v /root/ai-models/vec-ai/lychee-rerank-mm:/models/lychee-rerank-mm lychee-rerank-mm:latest访问http://localhost:7860,看到 Gradio 界面即成功。按Ctrl+C停止。
4. Docker Compose 编排:一份 YAML 管理全部服务
这才是本教程的核心。我们不再手动docker run,而是用docker-compose.yml统一描述服务、网络、挂载、资源限制。
在/root/lychee-rerank-mm目录下创建docker-compose.yml:
version: '3.8' services: reranker: image: lychee-rerank-mm:latest container_name: lychee-rerank-mm restart: unless-stopped ports: - "7860:7860" volumes: - "/root/ai-models/vec-ai/lychee-rerank-mm:/models/lychee-rerank-mm" environment: - CUDA_VISIBLE_DEVICES=0 - GRADIO_SERVER_NAME=0.0.0.0 - GRADIO_SERVER_PORT=7860 deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] logging: driver: "json-file" options: max-size: "10m" max-file: "3" # 可选:添加一个健康检查服务(用于监控) health-check: image: curlimages/curl:latest depends_on: - reranker command: ["--retry", "10", "--retry-delay", "5", "--fail", "http://reranker:7860/health"] restart: "no"4.1 配置逐项解读
| 字段 | 说明 | 为什么重要 |
|---|---|---|
restart: unless-stopped | 容器异常退出自动重启,但手动docker stop后不恢复 | 防止显存溢出或 OOM 导致服务静默中断 |
volumes | 将宿主机模型路径挂载为容器内/models/lychee-rerank-mm | 模型热更新无需重建镜像;多容器共享同一模型 |
environment | 强制 Gradio 绑定到所有 IP,而非默认127.0.0.1 | 容器内服务才能被外部(如其他容器、宿主机浏览器)访问 |
deploy.resources.devices | 显式声明使用 1 块 GPU,并启用gpu能力 | 避免多个服务争抢 GPU,确保 Flash Attention 2 正常加载 |
logging | 限制日志大小,防止磁盘占满 | 生产环境必备,尤其长期运行时 |
4.2 一键启停与状态管理
全部服务启动(后台运行):
docker compose up -d查看运行状态:
docker compose ps # 输出示例: # NAME COMMAND SERVICE STATUS PORTS # lychee-rerank-mm "python app.py" reranker running (healthy) 0.0.0.0:7860->7860/tcp查看实时日志(按Ctrl+C退出):
docker compose logs -f reranker停止所有服务:
docker compose down此时你已拥有一个工业级部署能力:服务自愈、日志可控、GPU 隔离、路径统一。比
nohup python app.py &高出不止一个量级。
5. 实战调用:两种最常用接入方式
服务跑起来了,下一步是如何让其他程序调用它。我们提供两种开箱即用的方式:HTTP API 直连和Python SDK 封装。
5.1 HTTP API:通用、跨语言、零依赖
Lychee-Rerank-MM 的 Gradio 接口默认开放/api/predict,支持 JSON POST 请求。无需额外开发,直接用curl测试:
单文档重排序(文本→文本)
curl -X POST "http://localhost:7860/api/predict/" \ -H "Content-Type: application/json" \ -d '{ "data": [ "Given a web search query, retrieve relevant passages that answer the query", "What is the capital of China?", "The capital of China is Beijing." ] }'响应中"data"字段即为相关性得分(如0.9523)。
批量重排序(文本→图文混合)
curl -X POST "http://localhost:7860/api/predict/" \ -H "Content-Type: application/json" \ -d '{ "data": [ "Given a product image and description, retrieve similar products", "A red leather handbag with gold zipper", ["data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAA...", "A blue canvas tote bag"], ["data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAA...", "A black crossbody purse"] ] }'提示:图片需 Base64 编码(前端可直接用
FileReader读取),文本直接传字符串。返回为 Markdown 表格字符串,可直接渲染。
5.2 Python SDK:简洁、类型安全、易集成
为降低调用门槛,我们封装了一个极简 SDK(保存为lychee_client.py):
import requests import base64 class LycheeReranker: def __init__(self, base_url="http://localhost:7860"): self.base_url = base_url.rstrip("/") def _encode_image(self, image_path): with open(image_path, "rb") as f: return "data:image/jpeg;base64," + base64.b64encode(f.read()).decode() def rerank_single(self, instruction, query, document): """单文档重排序""" data = [instruction, query, document] resp = requests.post(f"{self.base_url}/api/predict/", json={"data": data}) return resp.json()["data"][0] def rerank_batch(self, instruction, query, documents): """批量重排序(支持图文混合)""" # 自动处理图片路径 processed_docs = [] for doc in documents: if isinstance(doc, str) and doc.lower().endswith((".jpg", ".jpeg", ".png")): processed_docs.append(self._encode_image(doc)) else: processed_docs.append(doc) data = [instruction, query, *processed_docs] resp = requests.post(f"{self.base_url}/api/predict/", json={"data": data}) return resp.json()["data"][0] # 使用示例 client = LycheeReranker() score = client.rerank_single( instruction="Given a question, retrieve factual passages that answer it", query="What is photosynthesis?", document="The process by which plants convert light energy into chemical energy." ) print(f"相关性得分:{score:.4f}") # 输出:0.8947将此文件放在你的业务项目中,from lychee_client import LycheeReranker即可调用,无额外依赖。
6. 进阶技巧:让服务更健壮、更高效、更省心
6.1 GPU 内存优化:应对大图与长文本
默认配置下,处理高分辨率图(如 2000×3000)或超长文本(>2000 token)可能触发 CUDA OOM。两个实测有效的调整:
降低图像分辨率预处理(推荐)
在app.py中找到图像加载部分,插入缩放逻辑:from PIL import Image def resize_image(img: Image.Image, max_size=1024): w, h = img.size if max(w, h) > max_size: ratio = max_size / max(w, h) new_w, new_h = int(w * ratio), int(h * ratio) return img.resize((new_w, new_h), Image.Resampling.LANCZOS) return img动态调整
max_length
启动时通过环境变量覆盖(修改docker-compose.yml):environment: - MAX_LENGTH=2048 # 默认 3200,减至 2048 可降显存 30%
6.2 多实例负载分担:横向扩展方案
当并发请求增多(如 >20 QPS),单实例可能成为瓶颈。Docker Compose 支持一键扩容:
docker compose up -d --scale reranker=3此时会启动 3 个lychee-rerank-mm容器。你只需在业务侧加一层 Nginx 反向代理(或直接用requests轮询localhost:7860,localhost:7861,localhost:7862),即可实现负载均衡。
注意:每个实例需挂载相同模型路径,且
CUDA_VISIBLE_DEVICES设为不同值(如0,1,2),避免 GPU 冲突。
6.3 日志与监控:快速定位问题
所有日志已通过docker compose logs统一收集。进一步增强可观测性:
- 错误关键词告警:监听日志中的
CUDA out of memory、OSError、Timeout - 响应时间监控:用
curl -w "@format.txt"记录time_total,写入 Prometheus - GPU 利用率看板:
nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits
这些均可集成进现有运维体系,无需改动 Lychee 代码。
7. 总结:你已掌握一套可落地的 AI 服务化方法论
回顾整个过程,你实际完成的不只是“跑通一个模型”,而是构建了一套完整的 AI 服务交付流程:
- 标准化封装:用 Dockerfile 定义运行时环境,消除“在我机器上是好的”问题;
- 声明式编排:用
docker-compose.yml描述服务拓扑,实现“一次编写,随处部署”; - 生产就绪配置:自动重启、日志轮转、GPU 隔离、健康检查,直击工程痛点;
- 灵活接入方式:HTTP API 适配任何语言,Python SDK 降低集成成本;
- 可演进架构:从单实例到多实例、从本地到集群,平滑过渡无割裂感。
这不是终点,而是起点。接下来,你可以:
- 把它接入 Milvus 向量库,构建端到端多模态检索 pipeline;
- 用它替换 Elasticsearch 的
rescore环节,提升图文搜索相关性; - 将其作为 RAG 系统的重排模块,让 LLM 回答更精准、更可信。
AI 工程的价值,从来不在模型多大、参数多高,而在于它能否稳定、可靠、低成本地解决真实问题。今天这一步,你已经走得很扎实。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。