cv_resnet101_face-detection_cvpr22papermogface生产环境部署:Docker封装+GPU资源隔离方案
1. 引言:从本地工具到生产服务的挑战
你刚刚体验了MogFace人脸检测工具的强大能力——上传图片、一键检测、秒级返回结果,整个过程流畅得让人几乎忘了背后运行着一个复杂的深度学习模型。但当你试图将这个工具部署到生产环境,服务成百上千的用户时,问题开始浮现:
“为什么我的GPU显存总是爆满?” “多个应用同时运行时,怎么保证人脸检测服务不被挤占资源?” “开发环境能跑,为什么一到服务器就各种依赖报错?”
这些正是我们今天要解决的核心问题。本文将带你一步步将MogFace从本地工具升级为生产级服务,通过Docker封装解决环境一致性问题,通过GPU资源隔离确保服务稳定性。无论你是运维工程师、算法工程师,还是全栈开发者,这套方案都能让你的人脸检测服务在真实业务场景中稳定运行。
2. 为什么需要生产环境部署方案?
2.1 本地开发与生产环境的差异
在本地开发时,你拥有完整的控制权:可以随意安装包、调整环境变量、独占GPU资源。但生产环境是另一回事:
- 环境一致性:开发机的Python版本、CUDA版本、依赖库版本必须与服务器完全一致,否则“在我机器上能跑”的经典问题就会出现
- 资源竞争:生产服务器通常运行多个服务,人脸检测只是其中之一,如何避免它“吃掉”所有GPU显存?
- 服务稳定性:本地工具可以随时重启,生产服务需要7×24小时稳定运行,崩溃就是事故
- 可扩展性:当检测请求量增加时,如何快速扩容?如何实现负载均衡?
2.2 MogFace生产部署的特殊挑战
MogFace基于ResNet101骨干网络,这个选择带来了精度优势,也带来了部署挑战:
- 模型体积大:ResNet101参数量约4450万,模型文件大小超过200MB
- 显存需求高:单次推理需要约1.5GB显存,处理高分辨率图片时需求更高
- 初始化时间长:模型加载需要时间,不能每次请求都重新加载
- CUDA依赖强:完全依赖NVIDIA GPU和CUDA环境,CPU推理速度无法满足生产要求
3. Docker封装:一次构建,处处运行
3.1 Dockerfile设计思路
Docker的核心价值在于将应用及其所有依赖打包成一个标准化的单元。对于MogFace,我们需要特别关注深度学习环境的构建:
# 使用NVIDIA官方CUDA基础镜像,确保GPU支持 FROM nvidia/cuda:11.8.0-runtime-ubuntu22.04 # 设置环境变量 ENV DEBIAN_FRONTEND=noninteractive ENV PYTHONUNBUFFERED=1 ENV TZ=Asia/Shanghai # 安装系统依赖 RUN apt-get update && apt-get install -y \ python3.10 \ python3-pip \ libgl1-mesa-glx \ libglib2.0-0 \ && rm -rf /var/lib/apt/lists/* # 设置工作目录 WORKDIR /app # 复制依赖文件 COPY requirements.txt . # 安装Python依赖 - 使用国内镜像加速 RUN pip3 install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple \ torch==2.0.1+cu118 \ torchvision==0.15.2+cu118 \ --extra-index-url https://download.pytorch.org/whl/cu118 RUN pip3 install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple \ -r requirements.txt # 复制应用代码和模型 COPY app.py . COPY model_loader.py . # 假设模型文件已下载到models目录 COPY models/ /app/models/ # 暴露Streamlit默认端口 EXPOSE 8501 # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD python3 -c "import requests; requests.get('http://localhost:8501/_stcore/health')" # 启动命令 CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]3.2 requirements.txt优化
生产环境的依赖管理需要更加严谨:
# 核心深度学习框架 torch==2.0.1 torchvision==0.15.2 # 模型推理框架 modelscope==1.10.0 # Web界面 streamlit==1.28.0 # 图像处理 opencv-python==4.8.1.78 Pillow==10.1.0 numpy==1.24.3 # 工具库 pydantic==2.5.0 # 数据验证 loguru==0.7.2 # 日志管理 python-multipart==0.0.6 # 文件上传支持 # 性能监控 psutil==5.9.6 gpustat==1.0.03.3 模型加载优化
生产环境中,模型加载需要更加健壮和高效:
# model_loader.py import torch import modelscope from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks from loguru import logger import time from typing import Optional class MogFaceModelLoader: def __init__(self, model_path: str, device: str = 'cuda:0'): """ 生产环境模型加载器 Args: model_path: 模型路径 device: 设备类型,支持cuda:0, cuda:1等 """ self.model_path = model_path self.device = device self.pipeline = None self.load_time = None def load_model(self) -> bool: """加载模型,包含错误处理和性能监控""" try: logger.info(f"开始加载MogFace模型,路径: {self.model_path}") start_time = time.time() # 检查CUDA可用性 if 'cuda' in self.device: if not torch.cuda.is_available(): logger.error("CUDA不可用,请检查GPU驱动") return False # 设置GPU设备 device_id = int(self.device.split(':')[1]) torch.cuda.set_device(device_id) logger.info(f"使用GPU设备: {torch.cuda.get_device_name(device_id)}") # 加载模型pipeline self.pipeline = pipeline( task=Tasks.face_detection, model=self.model_path, device=self.device ) self.load_time = time.time() - start_time logger.success(f"模型加载完成,耗时: {self.load_time:.2f}秒") # 预热模型 self._warm_up() return True except Exception as e: logger.error(f"模型加载失败: {str(e)}") return False def _warm_up(self): """模型预热,避免第一次推理过慢""" logger.info("开始模型预热...") warm_up_image = torch.randn(1, 3, 640, 640).to(self.device) try: _ = self.pipeline(warm_up_image) logger.success("模型预热完成") except Exception as e: logger.warning(f"模型预热失败: {str(e)}") def get_pipeline(self): """获取模型pipeline""" if self.pipeline is None: raise RuntimeError("模型未加载,请先调用load_model()") return self.pipeline def get_model_info(self) -> dict: """获取模型信息""" return { "model_name": "MogFace (ResNet101)", "model_path": self.model_path, "device": self.device, "load_time": self.load_time, "cuda_available": torch.cuda.is_available(), "gpu_count": torch.cuda.device_count() if torch.cuda.is_available() else 0 }4. GPU资源隔离:让多个应用和谐共处
4.1 NVIDIA Docker运行时配置
要让Docker容器能够使用GPU,需要正确配置NVIDIA容器运行时:
# 安装NVIDIA Docker运行时 distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list sudo apt-get update sudo apt-get install -y nvidia-docker2 sudo systemctl restart docker # 验证安装 docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi4.2 容器GPU资源限制
生产环境中,我们需要精确控制每个容器使用的GPU资源:
# docker-compose.yml version: '3.8' services: mogface-service: build: . container_name: mogface-detection restart: unless-stopped ports: - "8501:8501" deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] environment: - NVIDIA_VISIBLE_DEVICES=0 # 指定使用哪块GPU - CUDA_VISIBLE_DEVICES=0 - MODEL_PATH=/app/models/cv_resnet101_face-detection_cvpr22papermogface volumes: - ./models:/app/models - ./logs:/app/logs # GPU内存限制 shm_size: '2gb' # 显存限制(通过NVIDIA容器运行时) runtime: nvidia command: > sh -c " # 设置GPU内存限制 export NVIDIA_VISIBLE_DEVICES=0 && export CUDA_MPS_ACTIVE_THREAD_PERCENTAGE=50 && streamlit run app.py --server.port=8501 --server.address=0.0.0.0 "4.3 多容器GPU共享方案
当一台服务器需要运行多个人脸检测服务时,可以使用NVIDIA MPS(Multi-Process Service):
# 启动MPS服务 sudo nvidia-smi -i 0 -c EXCLUSIVE_PROCESS sudo nvidia-cuda-mps-control -d # 创建多个容器,共享同一块GPU docker run -d \ --name mogface-service-1 \ --gpus '"device=0"' \ --runtime=nvidia \ -e CUDA_MPS_ACTIVE_THREAD_PERCENTAGE=30 \ -p 8501:8501 \ mogface-image docker run -d \ --name mogface-service-2 \ --gpus '"device=0"' \ --runtime=nvidia \ -e CUDA_MPS_ACTIVE_THREAD_PERCENTAGE=30 \ -p 8502:8501 \ mogface-image4.4 应用层资源管理
在应用代码中,我们也需要实现资源管理:
# resource_manager.py import torch import psutil import gpustat from loguru import logger from typing import Dict, Optional class GPUResourceManager: def __init__(self, device_id: int = 0): self.device_id = device_id self.device = torch.device(f'cuda:{device_id}') def check_gpu_health(self) -> Dict: """检查GPU健康状态""" try: gpu_stats = gpustat.GPUStatCollection.new_query() gpu_info = gpu_stats.gpus[self.device_id] return { "gpu_name": gpu_info.name, "memory_total": gpu_info.memory_total, "memory_used": gpu_info.memory_used, "memory_free": gpu_info.memory_free, "memory_utilization": gpu_info.memory_used / gpu_info.memory_total, "gpu_utilization": gpu_info.utilization, "temperature": gpu_info.temperature, "power_draw": gpu_info.power_draw if hasattr(gpu_info, 'power_draw') else None } except Exception as e: logger.error(f"获取GPU状态失败: {str(e)}") return {} def allocate_batch_size(self, image_size: tuple) -> int: """根据当前显存动态分配批处理大小""" gpu_status = self.check_gpu_health() if not gpu_status: return 1 # 默认批处理大小为1 # 估算单张图片需要的显存 h, w = image_size # 简单估算:图片数据 + 模型中间变量 estimated_memory_per_image = (h * w * 3 * 4) / (1024 ** 2) # MB estimated_memory_per_image *= 10 # 经验系数,考虑模型计算 # 可用显存 available_memory = gpu_status["memory_free"] * 0.8 # 保留20%缓冲 # 计算批处理大小 batch_size = max(1, int(available_memory / estimated_memory_per_image)) batch_size = min(batch_size, 16) # 最大批处理大小限制 logger.info(f"动态分配批处理大小: {batch_size} (可用显存: {available_memory:.1f}MB)") return batch_size def cleanup(self): """清理GPU缓存""" if torch.cuda.is_available(): torch.cuda.empty_cache() logger.info("GPU缓存已清理") def monitor_loop(self, interval: int = 60): """监控循环(用于独立线程)""" import time while True: status = self.check_gpu_health() if status: logger.info(f"GPU监控 - 使用率: {status['gpu_utilization']}%, " f"显存: {status['memory_used']}/{status['memory_total']}MB, " f"温度: {status['temperature']}°C") # 如果显存使用率超过90%,尝试清理 if status.get('memory_utilization', 0) > 0.9: logger.warning("显存使用率超过90%,执行清理") self.cleanup() time.sleep(interval)5. 生产环境应用代码优化
5.1 健壮性增强的app.py
# app.py - 生产环境版本 import streamlit as st import cv2 import numpy as np from PIL import Image import json import time from datetime import datetime import sys import os # 添加项目根目录到Python路径 sys.path.append(os.path.dirname(os.path.abspath(__file__))) from model_loader import MogFaceModelLoader from resource_manager import GPUResourceManager # 初始化 @st.cache_resource def init_resources(): """初始化模型和资源管理器""" # 配置日志 import logging logging.basicConfig(level=logging.INFO) # 初始化资源管理器 resource_manager = GPUResourceManager(device_id=0) # 初始化模型加载器 model_path = os.getenv('MODEL_PATH', '/app/models/cv_resnet101_face-detection_cvpr22papermogface') model_loader = MogFaceModelLoader(model_path=model_path, device='cuda:0') # 加载模型 if not model_loader.load_model(): st.error("模型加载失败,请检查日志") return None, None return model_loader, resource_manager def process_image(image, model_pipeline, confidence_threshold=0.5): """处理单张图片""" try: # 转换图片格式 if isinstance(image, Image.Image): image_np = np.array(image) else: image_np = image # 记录开始时间 start_time = time.time() # 执行推理 result = model_pipeline(image_np) # 记录结束时间 inference_time = time.time() - start_time # 解析结果 faces = [] if 'boxes' in result: boxes = result['boxes'] scores = result.get('scores', []) for i, box in enumerate(boxes): score = scores[i] if i < len(scores) else 1.0 if score >= confidence_threshold: faces.append({ 'box': [int(coord) for coord in box[:4]], # x1, y1, x2, y2 'score': float(score), 'area': (box[2] - box[0]) * (box[3] - box[1]) }) # 按面积排序(从大到小) faces.sort(key=lambda x: x['area'], reverse=True) return { 'faces': faces, 'count': len(faces), 'inference_time': inference_time, 'image_size': image_np.shape[:2], 'timestamp': datetime.now().isoformat() } except Exception as e: st.error(f"图片处理失败: {str(e)}") return None def draw_boxes(image_np, faces, confidence_threshold=0.5): """在图片上绘制检测框""" result_image = image_np.copy() for face in faces: if face['score'] >= confidence_threshold: x1, y1, x2, y2 = face['box'] score = face['score'] # 绘制矩形框 color = (0, 255, 0) # 绿色 thickness = 2 cv2.rectangle(result_image, (x1, y1), (x2, y2), color, thickness) # 绘制置信度标签 label = f"{score:.2f}" label_size, baseline = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1) cv2.rectangle(result_image, (x1, y1 - label_size[1] - 5), (x1 + label_size[0], y1), color, -1) cv2.putText(result_image, label, (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1) return result_image def main(): """主应用函数""" st.set_page_config( page_title="MogFace人脸检测系统", page_icon="👁️", layout="wide", initial_sidebar_state="expanded" ) # 初始化资源 with st.spinner("正在初始化系统资源..."): model_loader, resource_manager = init_resources() if model_loader is None: st.stop() # 获取模型pipeline model_pipeline = model_loader.get_pipeline() # 侧边栏配置 with st.sidebar: st.title("⚙️ 系统配置") # 显示系统信息 st.subheader("系统状态") model_info = model_loader.get_model_info() st.write(f"**模型**: {model_info['model_name']}") st.write(f"**设备**: {model_info['device']}") st.write(f"**加载时间**: {model_info['load_time']:.2f}秒") # GPU状态监控 if st.button("刷新GPU状态"): gpu_status = resource_manager.check_gpu_health() if gpu_status: st.write(f"**GPU**: {gpu_status['gpu_name']}") st.write(f"**显存**: {gpu_status['memory_used']}/{gpu_status['memory_total']} MB") st.write(f"**使用率**: {gpu_status['gpu_utilization']}%") st.write(f"**温度**: {gpu_status['temperature']}°C") # 配置参数 st.subheader("检测参数") confidence_threshold = st.slider( "置信度阈值", min_value=0.0, max_value=1.0, value=0.5, step=0.05, help="高于此阈值的人脸框才会被显示" ) # 资源管理 st.subheader("资源管理") if st.button("清理GPU缓存"): resource_manager.cleanup() st.success("GPU缓存已清理") if st.button("重启模型服务"): st.cache_resource.clear() st.rerun() # 主界面 st.title("👁️ MogFace 人脸检测系统") st.markdown("基于CVPR 2022 MogFace模型的高性能人脸检测工具") # 双列布局 col1, col2 = st.columns(2) with col1: st.header("📤 图片上传") # 上传组件 uploaded_file = st.file_uploader( "选择图片文件", type=['jpg', 'jpeg', 'png'], help="支持JPG、PNG格式,建议图片尺寸不超过4K" ) if uploaded_file is not None: # 显示原始图片 image = Image.open(uploaded_file) st.image(image, caption="原始图片", use_column_width=True) # 显示图片信息 st.write(f"**图片尺寸**: {image.size[0]} × {image.size[1]}") st.write(f"**图片格式**: {image.format}") # 检测按钮 if st.button("🚀 开始检测", type="primary", use_container_width=True): with st.spinner("正在检测人脸..."): # 处理图片 result = process_image( image, model_pipeline, confidence_threshold ) if result: # 存储结果到session state st.session_state['detection_result'] = result st.session_state['original_image'] = image st.success(f"检测完成!发现 {result['count']} 张人脸") with col2: st.header("📊 检测结果") if 'detection_result' in st.session_state: result = st.session_state['detection_result'] original_image = st.session_state['original_image'] # 显示统计信息 col_a, col_b, col_c = st.columns(3) with col_a: st.metric("人脸数量", result['count']) with col_b: st.metric("推理时间", f"{result['inference_time']:.3f}s") with col_c: st.metric("图片尺寸", f"{result['image_size'][1]}×{result['image_size'][0]}") # 绘制并显示结果图片 image_np = np.array(original_image) result_image = draw_boxes(image_np, result['faces'], confidence_threshold) st.image(result_image, caption="检测结果", use_column_width=True) # 显示详细数据 with st.expander("📋 查看详细数据"): st.json(result) # 导出功能 st.download_button( label="📥 下载检测结果(JSON)", data=json.dumps(result, indent=2, ensure_ascii=False), file_name=f"detection_result_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json", mime="application/json" ) else: st.info("请先上传图片并点击检测按钮") st.image("https://via.placeholder.com/600x400/CCCCCC/969696?text=等待检测结果", caption="检测结果将显示在这里", use_column_width=True) # 页脚信息 st.markdown("---") st.caption(f"最后更新: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") if __name__ == "__main__": main()6. 部署与监控方案
6.1 Docker Compose完整配置
# docker-compose.prod.yml version: '3.8' services: mogface-detection: build: context: . dockerfile: Dockerfile.prod image: mogface-detection:latest container_name: mogface-detection-prod restart: unless-stopped ports: - "8501:8501" environment: - NVIDIA_VISIBLE_DEVICES=0 - CUDA_VISIBLE_DEVICES=0 - MODEL_PATH=/app/models/cv_resnet101_face-detection_cvpr22papermogface - LOG_LEVEL=INFO - MAX_IMAGE_SIZE=4096 volumes: - mogface-models:/app/models - mogface-logs:/app/logs - /var/run/docker.sock:/var/run/docker.sock networks: - mogface-network deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] limits: memory: 8G cpus: '2.0' healthcheck: test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:8501/_stcore/health')"] interval: 30s timeout: 10s retries: 3 start_period: 40s # 监控服务 monitor: image: prom/prometheus:latest container_name: mogface-prometheus restart: unless-stopped ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml - prometheus-data:/prometheus networks: - mogface-network 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' # 可视化面板 grafana: image: grafana/grafana:latest container_name: mogface-grafana restart: unless-stopped ports: - "3000:3000" environment: - GF_SECURITY_ADMIN_PASSWORD=admin volumes: - grafana-data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning networks: - mogface-network volumes: mogface-models: mogface-logs: prometheus-data: grafana-data: networks: mogface-network: driver: bridge6.2 Prometheus监控配置
# prometheus.yml global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: 'mogface-detection' static_configs: - targets: ['mogface-detection:8501'] metrics_path: '/metrics' - job_name: 'node-exporter' static_configs: - targets: ['node-exporter:9100'] - job_name: 'cadvisor' static_configs: - targets: ['cadvisor:8080']6.3 部署脚本
#!/bin/bash # deploy.sh - 生产环境部署脚本 set -e # 遇到错误立即退出 echo "开始部署MogFace人脸检测系统..." # 1. 检查Docker和NVIDIA Docker echo "检查Docker环境..." if ! command -v docker &> /dev/null; then echo "错误: Docker未安装" exit 1 fi if ! docker info | grep -q "nvidia"; then echo "警告: NVIDIA Docker运行时未配置" echo "尝试配置NVIDIA Docker..." # 这里可以添加自动配置脚本 fi # 2. 检查GPU可用性 echo "检查GPU..." if ! nvidia-smi &> /dev/null; then echo "错误: NVIDIA GPU不可用" exit 1 fi # 3. 创建必要的目录 echo "创建目录..." mkdir -p ./models mkdir -p ./logs mkdir -p ./monitoring/prometheus mkdir -p ./monitoring/grafana/provisioning # 4. 下载模型(如果不存在) MODEL_PATH="./models/cv_resnet101_face-detection_cvpr22papermogface" if [ ! -d "$MODEL_PATH" ]; then echo "模型不存在,请手动下载并放置到 $MODEL_PATH" echo "可以从ModelScope下载: https://modelscope.cn/models/damo/cv_resnet101_face-detection_cvpr22papermogface" exit 1 fi # 5. 构建Docker镜像 echo "构建Docker镜像..." docker build -t mogface-detection:latest -f Dockerfile.prod . # 6. 启动服务 echo "启动服务..." docker-compose -f docker-compose.prod.yml up -d # 7. 检查服务状态 echo "检查服务状态..." sleep 10 # 等待服务启动 if curl -s http://localhost:8501 > /dev/null; then echo "✅ MogFace服务启动成功" echo "访问地址: http://localhost:8501" else echo "❌ MogFace服务启动失败" docker-compose -f docker-compose.prod.yml logs mogface-detection exit 1 fi # 8. 显示监控信息 echo "" echo "监控面板:" echo " - Prometheus: http://localhost:9090" echo " - Grafana: http://localhost:3000 (admin/admin)" echo "" echo "部署完成!"7. 总结
7.1 方案优势总结
通过本文的Docker封装和GPU资源隔离方案,我们成功将MogFace人脸检测工具从本地开发环境迁移到了生产环境。这套方案的主要优势包括:
- 环境一致性保障:Docker镜像确保了开发、测试、生产环境完全一致,彻底解决了"在我机器上能跑"的问题
- 资源隔离明确:通过GPU资源限制和NVIDIA MPS,实现了多服务共享GPU时的公平调度
- 部署简单高效:一键部署脚本和Docker Compose配置让部署变得简单可靠
- 监控体系完善:集成Prometheus和Grafana,实现了从系统层到应用层的全方位监控
- 健壮性增强:增加了错误处理、资源管理、健康检查等生产级特性
7.2 实际部署建议
在实际生产部署时,建议遵循以下最佳实践:
- 分阶段部署:先在测试环境验证,再逐步推广到生产环境
- 资源预留充足:根据业务量预估,合理分配GPU、CPU和内存资源
- 监控告警配置:设置合理的监控阈值和告警规则,及时发现并处理问题
- 定期维护更新:定期更新基础镜像、安全补丁和模型版本
- 备份与恢复:建立模型文件和配置文件的备份机制
7.3 扩展方向
当前方案还可以进一步扩展:
- 多GPU支持:扩展到多GPU服务器,实现模型并行或数据并行
- 负载均衡:通过Nginx或Kubernetes实现多实例负载均衡
- 自动扩缩容:基于请求量自动调整实例数量
- 模型版本管理:实现模型的热更新和版本回滚
- API服务化:将Streamlit界面改为REST API,方便其他系统集成
通过这套完整的生产环境部署方案,你的人脸检测服务将具备企业级的可靠性、可维护性和可扩展性,能够稳定支撑真实的业务需求。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。