一文搞定离线环境下的RAG引擎部署

在人工智能浪潮下,检索增强生成(RAG) 技术已成为构建智能问答、文档分析和代码助手等应用的核心。然而,在许多企业场景中,出于数据安全和性能的考虑,服务器往往部署在无法访问互联网的离线环境中,并要求极致的推理效率。

这给依赖外部资源的应用部署带来了巨大挑战。如何在这种严苛的环境下,完整、可靠地部署一套包含向量数据库、**高性能推理服务(vLLM)**和Python后台的复杂RAG系统呢?

本文将为你提供一个端到端的解决方案,手把手教你如何使用 Docker 技术,将一套基于 Weaviate 和 vLLM 的 Python RAG 应用完整打包,并在离线环境中一键部署。


核心挑战与解决思路

挑战

离线环境部署的核心难题在于依赖隔离性能保障

  1. Python 依赖: 如何打包所有 requirements.txt 中指定的Python包?
  2. 高性能模型服务: 如何离线部署像 bge-m3 这样的 embedding 模型,并保证其服务性能?
  3. Docker 镜像: 如何打包应用所需的所有基础Docker镜像(如 python, weaviate, vllm)?
  4. 一致性: 如何确保开发、测试和生产环境的一致性?

解决思路

我们的核心思路是 “万物皆打包,一键式部署”

  1. 依赖本地化: 在一台可以联网的Linux辅助机上,将所有Python依赖打包成 wheel 文件。
  2. 镜像归档: 将所有需要的Docker镜像(包括 vllm/vllm-openai)打包成 .tar 文件。
  3. 模型文件打包: 从Hugging Face Hub下载模型文件,并将其打包成独立的压缩包。
  4. 统一交付: 将项目代码、配置文件、依赖包、Docker镜像和模型文件统一打包传输。
  5. 离线加载与启动: 在离线服务器上,通过 docker load 导入镜像,将模型文件放置到指定位置,然后使用 docker-compose 一键启动所有服务。

系统架构

我们的RAG代码搜索引擎由三个核心服务组成,通过 docker-compose 进行编排:

  1. app (应用服务):
    • 基于Python和FastAPI构建的后端API服务。
    • 负责接收用户查询,调用vLLM生成向量,查询Weaviate,并对结果进行处理。
  2. weaviate (向量数据库):
    • 一个开源的、云原生的向量数据库。
    • 用于存储代码文件的向量表示,并执行高效的相似度搜索。
  3. vllm (高性能推理服务):
    • 一个为LLM推理提供极高吞吐量的服务框架。
    • 我们用它来托管 bge-m3 模型,以OpenAI兼容的API格式提供高速的 embedding 服务。

分步部署指南

第1步:项目配置 ⚙️

1.1 环境变量 (.env)

此文件定义了服务的配置参数。EMBEDDING_API_URL 指向vLLM服务的地址和端口,EMBEDDING_MODEL_NAME 则是vLLM加载的Hugging Face模型ID。

Bash

# 创建 .env 文件
cat > .env << 'EOF'
# API服务配置
API_PORT=5050

# Weaviate配置
WEAVIATE_ENDPOINT=http://weaviate:8080
WEAVIATE_GRPC_PORT=50051
INDEX_NAME=JavaCode

# Embedding模型配置 (vLLM)
EMBEDDING_TYPE=remote
EMBEDDING_API_URL=http://vllm:8000
EMBEDDING_MODEL_NAME=BAAI/bge-m3

# 搜索参数
TOP_K=10
TOP_SIM=0.5
ALPHA_PARAM=0.7

# 索引参数
JAVA_CODE_DIR=/data/java_code
CHUNK_LINES=50
CHUNK_LINES_OVERLAP=10
EOF
1.2 Docker Compose 配置 (docker-compose.yml)

docker-compose.yml文件定义了我们的服务如何协同工作。vllm服务使用了 vllm/vllm-openai 镜像来提供OpenAI兼容的API接口,并通过 deploy.resources 部分为容器分配了GPU资源,这是vLLM高性能运行的必需品。其 command 部分指定了要加载的模型和监听的主机。

YAML

# 创建 docker-compose.yml 文件
cat > docker-compose.yml << 'EOF'
version: '3.8'
name: java-code-rag

services:
  weaviate:
    image: semitechnologies/weaviate:1.24.10
    container_name: weaviate-rag
    ports:
      - "9000:8080"
      - "50051:50051"
    volumes:
      - weaviate_data:/var/lib/weaviate
    networks:
      - rag-network
    environment:
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      DEFAULT_VECTORIZER_MODULE: 'none'
      ENABLE_MODULES: ''

  vllm:
    image: vllm/vllm-openai:latest
    container_name: vllm-service
    ports:
      - "8000:8000"
    volumes:
      - vllm_models:/root/.cache/huggingface
    networks:
      - rag-network
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    command:
      - --model
      - BAAI/bge-m3
      - --host
      - 0.0.0.0

  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: rag-api
    ports:
      - "${API_PORT}:${API_PORT}"
    volumes:
      - ./data/java_code:/data/java_code
    env_file:
      - .env
    depends_on:
      - weaviate
      - vllm
    networks:
      - rag-network

networks:
  rag-network:
    driver: bridge

volumes:
  weaviate_data:
  vllm_models:
EOF
1.3 Dockerfile

Dockerfile定义了如何构建我们的Python应用镜像,它从本地的wheelhouse目录安装依赖,以实现离线构建。

Dockerfile

# 创建 Dockerfile
cat > Dockerfile << 'EOF'
FROM python:3.11-slim

WORKDIR /app

# 复制项目文件
COPY . /app/

# 复制预先打包好的依赖包
COPY wheelhouse /app/wheelhouse

# 从本地wheelhouse安装依赖,不访问网络
RUN pip install --no-index --find-links=/app/wheelhouse -r /app/conf/requirements.txt

# 暴露端口
EXPOSE 5050

# 启动应用
CMD ["python", "api_server.py"]
EOF

第2步:准备离线部署包

2.1 打包Python依赖 (wheelhouse)

首先,在开发机上生成依赖清单文件 requirements.txt

Bash

pip install pipreqs
pipreqs . --force --encoding=utf8

然后,在Linux辅助机上执行以下操作,创建 wheelhouse

Bash

mkdir -p ~/rag_build && cd ~/rag_build
# 将你的项目(特别是 conf/requirements.txt)上传到此目录
pip wheel -r conf/requirements.txt -w ./wheelhouse -i https://pypi.tuna.tsinghua.edu.cn/simple
2.2 打包vLLM模型文件

我们需要在辅助机上从Hugging Face下载模型文件并打包。

Bash

# === 在可以联网的Linux辅助机上执行 ===

# 1. 安装huggingface-cli工具
pip install -U "huggingface_hub[cli]"

# 2. 定义模型和本地下载目录
HF_MODEL="BAAI/bge-m3"
MODEL_PATH=~/rag_build/hf_models/bge-m3

# 3. 从Hugging Face Hub下载模型所有文件
huggingface-cli download $HF_MODEL --local-dir $MODEL_PATH --local-dir-use-symlinks False

# 4. 将下载好的模型目录打包
cd ~/rag_build/hf_models/
tar -czvf ~/rag_build/bge-m3-model.tar.gz ./bge-m3
2.3 打包Docker基础镜像

我们将所有依赖的Docker镜像打包成 .tar 文件。

Bash

# 在Linux辅助机上执行
cd ~/rag_build
mkdir -p docker_images && cd docker_images

docker pull python:3.11-slim
docker pull semitechnologies/weaviate:1.24.10
docker pull vllm/vllm-openai:latest

docker save python:3.11-slim -o python-3.11-slim.tar
docker save semitechnologies/weaviate:1.24.10 -o weaviate-1.24.10.tar
docker save vllm/vllm-openai:latest -o vllm-openai-latest.tar
2.4 最终打包

将所有准备好的物料压缩成一个部署包。

Bash

# 注意:以下路径均为示例,请根据你的实际目录结构进行调整。
tar -czvf rag_deployment_package.tar.gz \
  /path/to/your/rag_project/ \
  ./wheelhouse/ \
  ./docker_images/ \
  ./bge-m3-model.tar.gz

第3步:在生产环境部署

3.1 解压部署包

Bash

# 假设部署包已上传到 /opt/
cd /opt/
tar -xzvf rag_deployment_package.tar.gz
# 进入解压后的项目目录
cd your_rag_project/
3.2 加载Docker镜像

这是离线部署的关键一步。将 .tar 文件格式的镜像加载到本地Docker守护进程中。

Bash

# 假设镜像包解压在 /opt/docker_images/ 目录下
docker load -i /opt/docker_images/python-3.11-slim.tar
docker load -i /opt/docker_images/weaviate-1.24.10.tar
docker load -i /opt/docker_images/vllm-openai-latest.tar
3.3 启动服务

Bash

# 创建用于存放Java代码的目录
mkdir -p data/java_code
# 将你的Java项目代码库放入此目录

# 启动所有服务(-d 表示后台运行)
docker-compose up -d
3.4 导入vLLM模型

此步骤是将我们打包的模型文件放入 vllm 服务正在使用的数据卷中。

Bash

# 1. `docker-compose up` 已自动创建名为 java-code-rag_vllm_models 的数据卷

# 2. 找到vLLM数据卷在宿主机上的路径
PROD_VOL_PATH=$(docker volume inspect java-code-rag_vllm_models | grep -o '"Mountpoint": "[^"]*' | grep -o '[^"]*$')
echo "生产环境vLLM数据卷路径: $PROD_VOL_PATH"

# 3. 创建Hugging Face期望的目录结构
#    vLLM会在 /root/.cache/huggingface/hub/models--BAAI--bge-m3/ 寻找模型
HF_CACHE_PATH="$PROD_VOL_PATH/hub/models--BAAI--bge-m3"
sudo mkdir -p "$HF_CACHE_PATH"

# 4. 将你传输过来的模型包解压到该目录
#    假设模型包在 /opt/bge-m3-model.tar.gz
sudo tar -xzvf /opt/bge-m3-model.tar.gz -C "$HF_CACHE_PATH" --strip-components=1

# 5. 重启vllm服务以确保它能找到并加载本地模型
docker-compose restart vllm

第4步:验证与使用

4.1 检查服务状态

Bash

docker-compose ps

你应该能看到 rag-api, weaviate-rag, vllm-service 三个服务的状态都是 UpRunning

4.2 API健康检查与功能测试

由于 app 服务依赖于 vllm,我们可以直接测试 app 服务。

Bash

# 1. API健康检查
curl http://localhost:5050/health

# 2. 测试搜索功能
curl -X POST "http://localhost:5050/enhanced-search" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "用户认证逻辑是在哪里实现的",
    "top_k": 3,
    "enable_rerank": true
  }'

如果一切正常,说明vLLM服务也已成功运行并提供了embedding能力。


第5步(可选):Weaviate数据迁移

如果你需要迁移已有的Weaviate索引数据,推荐采用操作宿主机数据卷的方式。

  1. 在源环境导出数据:

    Bash

    docker-compose down
    SOURCE_VOL_PATH=$(docker volume inspect java-code-rag_weaviate_data | grep -o '"Mountpoint": "[^"]*' | grep -o '[^"]*$')
    cd "$SOURCE_VOL_PATH"
    sudo tar -czvf ~/weaviate_data_backup.tar.gz .
    
  2. 在目标环境导入数据:

    Bash

    docker-compose down
    PROD_VOL_PATH=$(docker volume inspect java-code-rag_weaviate_data | grep -o '"Mountpoint": "[^"]*' | grep -o '[^"]*$')
    sudo rm -rf "${PROD_VOL_PATH:?}"/*
    # 假设备份包在 /tmp/
    sudo tar -xzvf /tmp/weaviate_data_backup.tar.gz -C "$PROD_VOL_PATH"
    docker-compose up -d
    

你可能感兴趣的:(大模型,python,人工智能)