lingbot-depth-pretrain-vitl-14部署标准化:Docker Compose编排WebUI+API+监控服务
lingbot-depth-pretrain-vitl-14部署标准化:Docker Compose编排WebUI+API+监控服务
1. 引言:为什么需要标准化的部署方案?
如果你正在研究机器人导航、3D重建或者AR/VR应用,深度估计模型可能是你工具箱里不可或缺的一环。LingBot-Depth (Pretrained ViT-L/14) 就是这样一个强大的工具,它能从一张普通的彩色照片里“猜”出场景的深度,或者把稀疏的深度传感器数据“补”成一张完整的深度图。
但模型再厉害,部署起来麻烦也是白搭。你可能遇到过这些问题:环境配置复杂、服务启动顺序混乱、出了问题不知道哪里看日志、想扩展功能无从下手。今天,我就带你用Docker Compose,把LingBot-Depth的WebUI、API和监控服务打包成一个标准化的、开箱即用的解决方案。你只需要一个命令,就能启动一套完整的、生产就绪的服务。
2. 认识我们的主角:LingBot-Depth模型
在动手部署之前,我们先花几分钟了解一下这个模型到底能做什么,这样你才知道它是不是你需要的。
2.1 模型的核心能力
LingBot-Depth基于一个叫DINOv2 ViT-L/14的视觉编码器,有3.21亿个参数。它的核心思想很巧妙:把RGB-D传感器里缺失的深度数据,不是当成噪声扔掉,而是当成一种“掩码信号”来学习。这就像你看到一幅画被撕掉了一角,你不是去猜撕掉的部分原来是什么颜色,而是去学习这幅画整体的构图规律,然后把它补全。
它主要干两件事:
- 单目深度估计:给你一张普通的彩色照片,它就能输出这张照片里每个像素点距离相机有多远(单位是米)。
- 深度补全:如果你有一个深度传感器(比如手机上的ToF镜头或者机器人上的LiDAR),但它的数据是稀疏的、有噪声的。这时候,你给它一张彩色照片和这张稀疏的深度图,它就能融合这两份信息,输出一张又完整、又平滑、边缘又清晰的深度图。
2.2 它能用在哪儿?
想象几个场景:
- 让你的扫地机器人更聪明:用普通的RGB摄像头代替昂贵的激光雷达,通过估计深度来避开桌椅腿和宠物。
- 用手机做简易3D扫描:拍一段视频,模型逐帧估计深度,结合手机的运动数据,就能重建出房间的3D模型。
- AR应用里放虚拟家具:实时估计手机摄像头拍到的场景深度,虚拟的沙发才能稳稳地“放在”地板上,而不是飘在空中。
- 工业质检:有些反光或者透明的表面,深度传感器经常测不准。用这个模型把缺失的数据补上,提高检测的可靠性。
3. 部署前准备:理解我们的服务架构
我们的目标不是简单地跑起来一个Python脚本,而是构建一个易于管理、监控和扩展的服务集合。整个方案由三个核心服务组成,通过Docker Compose来编排。
3.1 三大服务组件
- WebUI服务 (Gradio):运行在7860端口。这是一个交互式的网页界面,非常适合快速测试、演示和调试。你可以上传图片,点点按钮,立刻看到深度估计的结果,非常直观。
- API服务 (FastAPI):运行在8000端口。这是给程序调用的接口。比如你的机器人程序需要实时获取深度信息,就可以通过HTTP请求调用这个API,获取结构化的数据(比如深度图的原始数组)。
- 监控服务 (Prometheus + Grafana):这是一个可选的,但强烈建议的组件。Prometheus负责收集服务的运行指标(比如API的请求次数、响应时间、GPU内存使用率),Grafana则负责把这些指标用漂亮的图表展示出来。当服务在后台长时间运行时,它能帮你一眼看出系统的健康状况。
3.2 Docker Compose的优势
为什么用Docker Compose?因为它把“部署”这件事变得极其简单。
- 环境隔离:每个服务都在自己的容器里,不会因为系统环境不同而出错。
- 一键启停:一条
docker-compose up -d命令启动所有服务,一条docker-compose down命令清理所有资源。 - 配置即代码:所有的服务配置、网络设置都写在一个
docker-compose.yml文件里,易于版本管理和分享。 - 依赖清晰:服务之间的依赖关系(比如API服务依赖模型文件)被明确定义。
4. 手把手部署:从零到一的完整流程
好了,理论说完了,我们开始动手。假设你有一台安装了Linux系统(如Ubuntu 22.04)和NVIDIA GPU的服务器。
4.1 第一步:基础环境检查与安装
首先,确保你的系统已经准备好了。
# 1. 更新系统包
sudo apt update && sudo apt upgrade -y
# 2. 安装Docker和Docker Compose插件
# 卸载旧版本(如果有)
sudo apt remove docker docker-engine docker.io containerd runc -y
# 安装依赖
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
# 添加Docker官方GPG密钥和仓库
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker引擎和Compose插件
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 3. 安装NVIDIA容器工具包(让Docker容器能用GPU)
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt update
sudo apt install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
# 4. 验证安装
docker --version
docker compose version
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi
如果最后一条命令能成功显示出你的GPU信息,那么恭喜你,基础环境就绪了。
4.2 第二步:创建项目结构与配置文件
我们创建一个清晰的项目目录来存放所有文件。
# 创建一个项目目录
mkdir -p ~/lingbot-depth-deploy && cd ~/lingbot-depth-deploy
# 创建必要的子目录
mkdir -p config models assets
接下来,创建最重要的 docker-compose.yml 文件。这个文件定义了我们的三个服务。
# ~/lingbot-depth-deploy/docker-compose.yml
version: '3.8'
services:
# 服务1: FastAPI REST API
lingbot-api:
image: your-registry/lingbot-depth-api:latest # 这里需要替换为你构建或拉取的镜像
container_name: lingbot-api
restart: unless-stopped
ports:
- "8000:8000"
volumes:
- ./models:/app/models:ro # 挂载模型文件,只读
- ./assets:/app/assets:ro # 挂载示例图片等资源
- api-logs:/app/logs
environment:
- MODEL_PATH=/app/models/lingbot-depth-pretrain-vitl-14
- LOG_LEVEL=INFO
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
networks:
- lingbot-net
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/docs"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# 服务2: Gradio WebUI
lingbot-webui:
image: your-registry/lingbot-depth-webui:latest # 这里需要替换为你构建或拉取的镜像
container_name: lingbot-webui
restart: unless-stopped
ports:
- "7860:7860"
volumes:
- ./models:/app/models:ro
- ./assets:/app/assets:ro
- webui-logs:/app/logs
environment:
- API_URL=http://lingbot-api:8000 # 内部网络访问API服务
- MODEL_PATH=/app/models/lingbot-depth-pretrain-vitl-14
depends_on:
lingbot-api:
condition: service_healthy # 等待API服务健康后再启动
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
networks:
- lingbot-net
# 服务3: 监控栈 (Prometheus + Grafana)
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./config/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=200h'
- '--web.enable-lifecycle'
networks:
- lingbot-net
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123 # 请务必修改这个默认密码!
- GF_INSTALL_PLUGINS=grafana-piechart-panel
volumes:
- grafana-data:/var/lib/grafana
- ./config/grafana-dashboards:/etc/grafana/provisioning/dashboards
- ./config/grafana-datasources:/etc/grafana/provisioning/datasources
depends_on:
- prometheus
networks:
- lingbot-net
# 定义数据卷,用于持久化存储日志和监控数据
volumes:
api-logs:
webui-logs:
prometheus-data:
grafana-data:
# 定义内部网络,让服务间可以互相通信
networks:
lingbot-net:
driver: bridge
注意:上面的 your-registry/lingbot-depth-api:latest 和 your-registry/lingbot-depth-webui:latest 是镜像占位符。你需要根据下一节的内容构建这两个镜像,或者使用我们预先构建好的镜像(如果有提供的话)。
然后,创建Prometheus的配置文件,告诉它去抓取我们API服务的指标。
# ~/lingbot-depth-deploy/config/prometheus.yml
global:
scrape_interval: 15s # 每15秒抓取一次数据
evaluation_interval: 15s
scrape_configs:
- job_name: 'lingbot-api'
static_configs:
- targets: ['lingbot-api:8000'] # 指向我们API服务的容器名和端口
metrics_path: '/metrics' # FastAPI应用需要暴露这个端点
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
4.3 第三步:准备模型与构建Docker镜像
这是最关键的一步:准备模型文件并创建我们服务自己的Docker镜像。
首先,下载模型权重。根据提供的镜像说明,模型来自魔搭社区。
# 进入项目目录
cd ~/lingbot-depth-deploy
# 假设我们从魔搭社区下载了模型文件,并放在了当前目录的 `downloaded_model` 文件夹下
# 你需要根据实际情况获取模型文件。这里演示如何组织。
# 将模型文件移动到我们挂载的目录
mkdir -p models/lingbot-depth-pretrain-vitl-14
# 假设你的模型文件是 `pytorch_model.bin` 和 `config.json`
cp /path/to/your/downloaded_model/* models/lingbot-depth-pretrain-vitl-14/
# 准备示例资源文件
mkdir -p assets/examples
# 将示例图片(如rgb.png, raw_depth.png)放入 assets/examples/
接下来,我们需要为API服务和WebUI服务编写Dockerfile。由于两者共享很多依赖,我们可以先构建一个基础镜像。
1. 构建基础镜像 Dockerfile
# ~/lingbot-depth-deploy/Dockerfile.base
FROM nvidia/cuda:12.4.0-runtime-ubuntu22.04
WORKDIR /app
# 安装系统依赖和Python
RUN apt-get update && apt-get install -y \
python3.11 \
python3-pip \
python3.11-venv \
git \
wget \
&& rm -rf /var/lib/apt/lists/*
# 创建虚拟环境并激活
RUN python3.11 -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# 升级pip并安装核心Python依赖
COPY requirements.txt .
RUN pip install --upgrade pip && \
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124 && \
pip install -r requirements.txt
# 复制模型加载工具等通用代码(假设你有)
COPY common_utils.py .
对应的 requirements.txt 文件:
fastapi==0.115.0
uvicorn[standard]==0.30.0
gradio==4.28.0
pillow==10.3.0
opencv-python-headless==4.9.0.80
numpy==1.26.4
prometheus-client==0.20.0
pydantic==2.7.0
httpx==0.27.0
2. 构建API服务镜像 Dockerfile
# ~/lingbot-depth-deploy/Dockerfile.api
FROM lingbot-depth-base:latest AS builder
# 假设你已经构建了基础镜像并打标为 lingbot-depth-base:latest
WORKDIR /app
# 复制API服务专用代码
COPY api/ .
# 暴露端口
EXPOSE 8000
# 启动命令
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
你需要创建 api/main.py 等API服务代码。这里提供一个极简的示例,展示如何加载模型和创建 /predict 端点。
# ~/lingbot-depth-deploy/api/main.py
from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from typing import Optional
import cv2
import numpy as np
from PIL import Image
import io
import base64
import logging
from prometheus_client import Counter, Histogram, generate_latest, CONTENT_TYPE_LATEST
import time
import torch
# 假设这是你的模型加载和推理函数
# from your_model_module import load_model, predict_depth
app = FastAPI(title="LingBot-Depth API")
# 定义Prometheus指标
REQUEST_COUNT = Counter('http_requests_total', 'Total HTTP Requests', ['method', 'endpoint', 'status'])
REQUEST_LATENCY = Histogram('http_request_duration_seconds', 'HTTP request latency in seconds', ['endpoint'])
# 简单的健康检查端点
@app.get("/health")
async def health_check():
return {"status": "healthy"}
# 暴露指标给Prometheus
@app.get("/metrics")
async def metrics():
return Response(generate_latest(), media_type=CONTENT_TYPE_LATEST)
class DepthRequest(BaseModel):
image_base64: str
mode: str = "monocular" # "monocular" or "completion"
sparse_depth_base64: Optional[str] = None
fx: Optional[float] = None
fy: Optional[float] = None
cx: Optional[float] = None
cy: Optional[float] = None
@app.post("/predict")
async def predict_depth_endpoint(request: DepthRequest):
start_time = time.time()
try:
# 1. 解码Base64图片
image_data = base64.b64decode(request.image_base64)
image = Image.open(io.BytesIO(image_data)).convert('RGB')
image_np = np.array(image)
# 2. 处理稀疏深度图(如果提供)
sparse_depth_np = None
if request.mode == "completion" and request.sparse_depth_base64:
depth_data = base64.b64decode(request.sparse_depth_base64)
# 根据实际格式解析深度图,这里假设是16位PNG
# sparse_depth_np = cv2.imdecode(...)
# 3. 调用模型推理 (这里需要替换为实际的模型调用)
# depth_map, point_cloud = your_predict_function(image_np, sparse_depth_np, request)
# 模拟推理结果
h, w = image_np.shape[:2]
simulated_depth = np.random.rand(h, w) * 10.0 # 模拟0-10米的深度
# 4. 将结果编码为Base64
# 将深度图归一化并保存为PNG
depth_normalized = (simulated_depth / simulated_depth.max() * 255).astype(np.uint8)
_, buffer = cv2.imencode('.png', depth_normalized)
depth_base64 = base64.b64encode(buffer).decode('utf-8')
# 计算处理时间
latency = time.time() - start_time
REQUEST_LATENCY.labels(endpoint='/predict').observe(latency)
REQUEST_COUNT.labels(method='POST', endpoint='/predict', status='200').inc()
return JSONResponse(content={
"status": "success",
"depth_map_base64": depth_base64,
"depth_range": f"{simulated_depth.min():.3f}m ~ {simulated_depth.max():.3f}m",
"inference_time_s": round(latency, 3),
"mode": request.mode
})
except Exception as e:
logging.error(f"Prediction failed: {e}")
REQUEST_COUNT.labels(method='POST', endpoint='/predict', status='500').inc()
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
3. 构建WebUI服务镜像 Dockerfile WebUI服务可以更简单,它主要是一个前端,通过环境变量里配置的 API_URL 调用后端的API。
# ~/lingbot-depth-deploy/Dockerfile.webui
FROM lingbot-depth-base:latest
WORKDIR /app
# 复制WebUI代码(一个Gradio应用)
COPY webui/ .
# 暴露端口
EXPOSE 7860
# 启动命令
CMD ["python", "app.py"]
webui/app.py 可以是一个调用后端API的Gradio界面。为了简洁,这里不展开详细代码,其核心是通过 httpx 库向 http://lingbot-api:8000/predict 发送请求。
4. 构建并推送镜像
# 在项目根目录执行
cd ~/lingbot-depth-deploy
# 构建基础镜像
docker build -f Dockerfile.base -t lingbot-depth-base:latest .
# 构建API镜像
docker build -f Dockerfile.api -t your-registry/lingbot-depth-api:latest .
# 构建WebUI镜像
docker build -f Dockerfile.webui -t your-registry/lingbot-depth-webui:latest .
# 登录你的容器镜像仓库(如果需要)
# docker login your-registry.com
# 推送镜像到仓库(如果需要)
# docker push your-registry/lingbot-depth-api:latest
# docker push your-registry/lingbot-depth-webui:latest
重要提示:在实际生产中,你可能需要调整Dockerfile以正确安装和链接模型推理所需的特定Python包(如 mdm)。请根据模型提供的官方仓库(如 https://github.com/Robbyant/lingbot-depth)中的 requirements.txt 来完善依赖。
4.4 第四步:启动服务与验证
所有配置和镜像准备就绪后,启动服务就一行命令。
cd ~/lingbot-depth-deploy
docker compose up -d
使用 docker compose ps 查看所有服务状态,等待它们都变为 running (healthy)。
现在,打开浏览器访问:
- WebUI界面:
http://你的服务器IP:7860 - API文档:
http://你的服务器IP:8000/docs(FastAPI自动生成的交互式文档) - 监控面板:
- Prometheus:
http://你的服务器IP:9090 - Grafana:
http://你的服务器IP:3000(用户名admin, 密码admin123)
- Prometheus:
在WebUI页面上传示例图片,选择模式,点击生成,你应该能看到深度图结果。在Grafana中,你需要配置Prometheus为数据源(地址填 http://prometheus:9090),然后导入或创建仪表盘来查看API的QPS、延迟等指标。
5. 生产环境进阶配置与管理
服务跑起来只是第一步,要让它在生产环境稳定运行,还需要一些额外配置。
5.1 配置Nginx反向代理与SSL
直接暴露7860和8000端口不太安全,也不便于管理。我们可以用Nginx做反向代理,并加上HTTPS。
# ~/lingbot-depth-deploy/config/nginx.conf
server {
listen 80;
server_name your-domain.com; # 替换为你的域名
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# ... 其他SSL优化配置 ...
location / {
proxy_pass http://lingbot-webui:7860; # 指向WebUI服务
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/ {
proxy_pass http://lingbot-api:8000/; # 指向API服务
proxy_set_header Host $host;
# ... 同上 ...
}
location /grafana/ {
proxy_pass http://grafana:3000/;
proxy_set_header Host $host;
# ... 同上 ...
rewrite ^/grafana/(.*)$ /$1 break;
}
}
然后在 docker-compose.yml 中添加一个Nginx服务,并挂载此配置和SSL证书。
5.2 日志收集与集中管理
Docker Compose默认的日志查看方式 (docker compose logs) 在服务多的时候不方便。我们可以集成 Loki 进行日志收集,并在Grafana中统一查看。 在 docker-compose.yml 中添加:
loki:
image: grafana/loki:latest
container_name: loki
restart: unless-stopped
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
networks:
- lingbot-net
promtail:
image: grafana/promtail:latest
container_name: promtail
restart: unless-stopped
volumes:
- /var/log:/var/log
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- ./config/promtail-config.yaml:/etc/promtail/config.yaml
command: -config.file=/etc/promtail/config.yaml
depends_on:
- loki
networks:
- lingbot-net
然后在Grafana中添加Loki数据源,就可以在Grafana的“Explore”页面查询所有容器的日志了。
5.3 使用技巧与日常维护
- 更新模型:只需要替换
models/目录下的文件,然后重启API和WebUI服务:docker compose restart lingbot-api lingbot-webui。 - 备份与恢复:定期备份
docker-compose.yml、config/目录以及models/目录。恢复时,只需将这些文件放到新服务器,运行docker compose up -d。 - 资源监控:在Grafana中创建仪表盘,监控CPU、内存、GPU使用率,以及API的请求状态。设置报警规则,当错误率升高或延迟变大时通知你。
- 版本控制:将整个
lingbot-depth-deploy目录(除了可能很大的models文件夹)纳入Git版本控制。
6. 总结
通过这一套Docker Compose编排方案,我们把LingBot-Depth模型从一个复杂的Python项目,变成了一个拥有清晰接口、可视化界面和完整监控的标准化服务。你获得的好处是:
- 部署简化:从繁琐的环境配置中解放出来,一键部署。
- 运维清晰:服务状态、日志、指标一目了然,问题排查效率倍增。
- 易于扩展:如果想增加一个批处理服务,或者换用更新的模型镜像,只需要在
docker-compose.yml里添加或修改几行配置。 - 团队协作:整个部署环境可以通过代码分享和复制,保证了开发、测试、生产环境的一致性。
这个方案不仅适用于LingBot-Depth,也为你部署其他AI模型服务提供了一个可复用的样板。下次当你拿到一个新的模型时,不妨也试着用Docker Compose把它“封装”起来。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐



所有评论(0)