GTE+SeqGPT部署教程:Docker Compose编排语义服务+生成服务双模块架构
想快速搭建一个既能“听懂”问题,又能“回答”问题的AI系统吗?今天,我们就来手把手教你部署一个集成了语义搜索和文本生成的双模块AI应用。这个项目把强大的中文语义向量模型GTE和轻量级生成模型SeqGPT打包在一起,让你用一条命令就能启动一个功能完整的智能问答原型。
无论你是想构建一个内部知识库助手,还是探索AI对话系统的底层架构,这个教程都将为你提供一个清晰、可落地的起点。我们采用Docker Compose进行服务编排,将复杂的模型部署简化为几个配置文件,真正做到开箱即用。
1. 项目全景:双核驱动的智能问答系统
在开始敲命令之前,我们先花两分钟了解一下这个项目的核心设计。它就像一个拥有“大脑”和“嘴巴”的智能体。
“大脑”是GTE模型,全称General Text Embeddings。它的任务是把一段文字(比如你的问题或知识库里的文档)转换成一串高维度的数字,也就是“向量”。这个向量的神奇之处在于,语义相近的文字,它们的向量在数学空间里的距离也很近。所以,当用户提问“今天天气如何?”时,即使知识库里存储的是“今日气象状况”,GTE也能通过计算向量相似度,精准地匹配上。
“嘴巴”是SeqGPT模型,一个参数量为560M的轻量化文本生成模型。它接收“大脑”检索到的相关信息,再结合你的原始问题,组织语言,生成一段通顺、相关的回答。虽然它比不上千亿参数大模型的博学,但对于结构清晰、逻辑简单的问答任务,它的表现足够出色,且部署成本极低。
整个系统的工作流程非常直观:
- 用户提出问题。
- GTE服务将问题转化为向量,并在知识库向量中搜索最相似的条目。
- 将搜索到的相关文本和原始问题一起,发送给SeqGPT服务。
- SeqGPT服务生成最终答案,返回给用户。
接下来,我们就通过Docker Compose,把这两个“模块”变成两个独立的、可随时启停的“服务”。
2. 环境准备与一键部署
部署的第一步是准备好你的“战场”。你需要一台安装了Linux的服务器或本地开发机(Windows/macOS也可,但Linux体验最佳),并确保已经安装了Docker和Docker Compose。
2.1 获取项目代码
打开终端,找一个你喜欢的目录,把项目的代码拉取下来。
# 克隆项目仓库(这里假设仓库地址,请替换为实际地址) git clone <your-repo-url> gte-seqgpt-demo cd gte-seqgpt-demo进入目录后,你会看到类似下面的文件结构,其中docker-compose.yml是我们的核心编排文件。
gte-seqgpt-demo/ ├── docker-compose.yml ├── gte-service/ │ ├── Dockerfile │ ├── app.py │ └── requirements.txt ├── seqgpt-service/ │ ├── Dockerfile │ ├── app.py │ └── requirements.txt └── data/ # 用于存放知识库文档2.2 理解Docker Compose编排
让我们看一眼docker-compose.yml,理解它如何将两个服务粘合在一起。
version: '3.8' services: gte-service: build: ./gte-service container_name: gte-embedding ports: - "8001:8000" # 将容器内的8000端口映射到主机的8001端口 volumes: - ./data:/app/data # 挂载知识库数据 - model-cache:/root/.cache # 缓存模型,避免重复下载 environment: - MODEL_NAME=GTE/Chinese-Large networks: - ai-network restart: unless-stopped seqgpt-service: build: ./seqgpt-service container_name: seqgpt-generation ports: - "8002:8000" # 将容器内的8000端口映射到主机的8002端口 depends_on: - gte-service volumes: - model-cache:/root/.cache environment: - MODEL_NAME=SeqGPT/560m networks: - ai-network restart: unless-stopped volumes: model-cache: # 声明一个共享卷,两个服务共用模型缓存 networks: ai-network: # 创建一个专属网络,让两个服务能互相通信这个配置做了几件关键事:
- 定义了两个服务:
gte-service和seqgpt-service。 - 建立了内部网络:
ai-network让两个容器能通过服务名(如gte-service)直接访问对方。 - 共享模型缓存:
model-cache卷让两个容器共用下载好的模型文件,节省磁盘空间和下载时间。 - 设置了端口映射:GTE服务对外暴露在
8001端口,SeqGPT服务在8002端口。 - 声明了依赖:
seqgpt-service等待gte-service启动就绪后再启动。
2.3 启动所有服务
万事俱备,现在只需一条命令,Docker Compose就会自动完成构建镜像、拉取模型、启动服务的所有步骤。
# 在项目根目录(包含docker-compose.yml的目录)执行 docker-compose up -d-d参数代表“后台运行”。执行后,你会看到Docker开始拉取基础镜像、安装依赖、下载模型(首次运行耗时较长,主要取决于模型大小和网络)。当终端提示两个服务都Started后,部署就完成了。
你可以用以下命令查看服务状态和日志:
# 查看所有容器状态 docker-compose ps # 查看gte服务的日志 docker-compose logs -f gte-service # 查看seqgpt服务的日志 docker-compose logs -f seqgpt-service3. 快速上手:验证与初体验
服务跑起来了,怎么知道它们工作正常呢?我们来跑几个简单的测试。
3.1 验证GTE语义搜索服务
GTE服务提供了一个简单的HTTP API。我们使用curl命令来测试它是否成功将句子转换成了向量。
# 向GTE服务的 /embed 接口发送一个POST请求 curl -X POST http://localhost:8001/embed \ -H "Content-Type: application/json" \ -d '{ "texts": ["今天天气真好", "这是一个编程问题"] }'如果服务正常,你会收到一个JSON响应,里面包含两个句子的高维向量(一堆数字)。这证明GTE模型加载成功,并且能正常工作。
3.2 验证SeqGPT文本生成服务
同样,我们测试一下SeqGPT服务的生成接口。
# 向SeqGPT服务的 /generate 接口发送请求 curl -X POST http://localhost:8002/generate \ -H "Content-Type: application/json" \ -d '{ "prompt": "写一首关于春天的五言绝句。", "max_length": 50 }'如果一切顺利,响应中会包含模型生成的诗歌。由于SeqGPT-560m能力有限,诗句可能不够优美,但只要能返回通顺的文字,就说明服务部署成功。
3.3 运行项目内置演示脚本
项目代码里已经包含了更生动的演示脚本,它们模拟了真实的使用场景。确保你在项目根目录,然后运行:
# 1. 基础校验:测试GTE向量化与相似度计算 python gte-service/scripts/main.py # 2. 形象化语义搜索:模拟智能知识库QA python gte-service/scripts/vivid_search.py # 3. 形象化文案生成:测试SeqGPT的指令跟随能力 python seqgpt-service/scripts/vivid_gen.py运行vivid_search.py时,你会看到即使你问“硬件坏了咋办”,而知识库里写的是“计算机设备故障处理”,AI也能通过语义理解找到正确答案。这就是向量搜索的魅力。
4. 核心功能详解与API使用
了解了基本验证,我们来看看这两个服务具体提供了哪些接口,以及如何在自己的程序里调用它们。
4.1 GTE服务API:文本向量化
GTE服务是你的“语义理解引擎”。它的核心接口是/embed。
请求示例(Python):
import requests import json gte_service_url = "http://localhost:8001" def get_embeddings(texts): """获取文本的向量表示""" response = requests.post( f"{gte_service_url}/embed", headers={"Content-Type": "application/json"}, data=json.dumps({"texts": texts}) ) if response.status_code == 200: return response.json()["embeddings"] else: raise Exception(f"GTE服务请求失败: {response.text}") # 示例:获取两个句子的向量 sentences = ["机器学习算法", "人工智能模型"] embeddings = get_embeddings(sentences) print(f"句子向量维度: {len(embeddings[0])}")这个函数返回的embeddings是一个列表,里面每个元素都是一个浮点数列表(即向量)。你可以用这些向量来计算相似度、做聚类或者构建向量数据库。
4.2 SeqGPT服务API:文本生成
SeqGPT服务是你的“内容创作助手”。它的核心接口是/generate。
请求示例(Python):
seqgpt_service_url = "http://localhost:8002" def generate_text(prompt, max_length=100): """根据提示词生成文本""" response = requests.post( f"{seqgpt_service_url}/generate", headers={"Content-Type": "application/json"}, data=json.dumps({ "prompt": prompt, "max_length": max_length, "temperature": 0.7, # 控制创造性,越高越随机 "top_p": 0.9 # 核采样参数,控制词汇选择范围 }) ) if response.status_code == 200: return response.json()["generated_text"] else: raise Exception(f"SeqGPT服务请求失败: {response.text}") # 示例:生成一段产品描述 prompt = "任务:撰写产品描述。输入:一款新型无线蓝牙耳机,续航30小时,带降噪。输出:" product_desc = generate_text(prompt) print(product_desc)通过调整temperature和top_p参数,你可以控制生成文本的“保守”与“创意”程度。对于事实性问答,温度可以设低一些(如0.3);对于创意写作,可以设高一些(如0.9)。
4.3 构建完整问答流程
现在,我们把两个服务组合起来,实现一个简单的“检索-生成”式问答(RAG)流程。
def answer_question(question, knowledge_base): """ 基于知识库回答问题 knowledge_base: 字典列表,每个字典包含‘id’和‘text’ """ # 1. 将知识库所有文本向量化(可预先完成,缓存起来) kb_texts = [item["text"] for item in knowledge_base] kb_embeddings = get_embeddings(kb_texts) # 调用GTE服务 # 2. 将问题向量化 query_embedding = get_embeddings([question])[0] # 3. 计算问题与知识库条目的相似度(这里用简单的余弦相似度) from numpy import dot from numpy.linalg import norm similarities = [] for kb_vec in kb_embeddings: cos_sim = dot(query_embedding, kb_vec) / (norm(query_embedding) * norm(kb_vec)) similarities.append(cos_sim) # 4. 找到最相关的知识片段 most_relevant_idx = similarities.index(max(similarities)) relevant_text = knowledge_base[most_relevant_idx]["text"] # 5. 组合Prompt,让SeqGPT基于相关知识生成答案 enhanced_prompt = f"""基于以下背景信息回答问题。 背景信息:{relevant_text} 问题:{question} 答案:""" answer = generate_text(enhanced_prompt, max_length=150) return answer, relevant_text # 返回答案和引用的来源 # 模拟一个简单的知识库 my_kb = [ {"id": 1, "text": "我们的产品支持7天无理由退货,需保持商品完好,不影响二次销售。"}, {"id": 2, "text": "标准配送时间为3-5个工作日,加急服务可在下单时选择,额外收费。"}, ] question = "如果我买了东西不满意,多久可以退?" answer, source = answer_question(question, my_kb) print(f"问题:{question}") print(f"参考来源:{source}") print(f"生成答案:{answer}")这个流程展示了AI如何“有据可依”地回答问题,而不是凭空想象。这是构建可靠AI助手的关键模式。
5. 进阶配置与优化建议
当你熟悉了基础部署后,可以根据实际需求进行一些调整和优化。
5.1 配置预加载知识库
在真实场景中,知识库的向量化不需要每次请求都计算。我们可以在GTE服务启动时,就加载好知识库并计算好向量。
修改gte-service/app.py,在启动时加载指定目录下的文本文件(例如data/knowledge_base.txt),计算向量并存储在内存或Redis中。这样,每次搜索请求都会变得非常快。
5.2 调整服务资源限制
模型推理比较消耗内存和CPU。你可以在docker-compose.yml中为每个服务设置资源限制,防止某个服务拖垮整个主机。
services: gte-service: # ... 其他配置 ... deploy: resources: limits: cpus: '2.0' # 限制最多使用2个CPU核心 memory: 4G # 限制最多使用4GB内存 reservations: memory: 2G # 保证至少分配2GB内存5.3 启用API密钥认证(可选)
如果服务需要对外网开放,安全至关重要。一个简单的方法是增加API密钥认证。你可以在两个服务的app.py里,在请求处理函数开头添加一个检查:
API_KEY = os.environ.get("API_KEY", "your-secret-key-here") @app.post("/embed") async def embed(request: Request): client_key = request.headers.get("X-API-Key") if client_key != API_KEY: raise HTTPException(status_code=403, detail="无效的API密钥") # ... 原有的处理逻辑 ...然后在docker-compose.yml的环境变量中配置密钥。
5.4 使用Nginx作为反向代理
如果你有多个服务,或者需要HTTPS,可以添加一个Nginx服务到你的docker-compose.yml中,统一管理入口。
services: nginx: image: nginx:alpine container_name: nginx-proxy ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf # 挂载自定义配置 - ./ssl:/etc/nginx/ssl # 挂载SSL证书 depends_on: - gte-service - seqgpt-service networks: - ai-network对应的nginx.conf可以配置路由规则,将/api/embed的请求转发给gte-service:8000,将/api/generate的请求转发给seqgpt-service:8000。
6. 总结
通过这个教程,我们完成了一个从零到一的AI双服务系统部署。我们利用Docker Compose的编排能力,优雅地将GTE语义向量服务和SeqGPT文本生成服务解耦,让它们各司其职又协同工作。
回顾一下核心收获:
- 架构清晰:理解了“检索(Retrieval)”+“生成(Generation)”的RAG架构在工程上的实现方式。
- 部署简化:掌握了用Docker Compose一键部署多模块AI应用的方法,避免了复杂的环境配置。
- 开箱即用:获得了两个即时的HTTP API服务,可以直接集成到你的Web应用、聊天机器人或内部工具中。
- 扩展性强:这个架构是一个模板。未来你可以轻松替换更强的向量模型(如BGE、OpenAI Embeddings)或生成模型(如ChatGLM、Qwen),只需修改对应的Dockerfile和环境变量即可。
这个项目就像一个功能完整的“乐高底座”,为你探索更复杂的AI应用场景打下了坚实的基础。你可以在此基础上,接入真实的业务数据,构建智能客服、文档分析助手或个性化推荐系统。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。