通义千问1.5-1.8B-Chat-GPTQ-Int4部署教程:配合Traefik实现HTTPS反向代理

想快速搭建一个属于自己的、能通过安全HTTPS访问的AI对话服务吗?今天,我们就来手把手教你部署通义千问1.5-1.8B-Chat-GPTQ-Int4模型,并给它穿上“安全外衣”——用Traefik配置HTTPS反向代理。整个过程清晰明了,即使你是新手,也能跟着一步步搞定。

1. 准备工作与环境概览

在开始动手之前,我们先来了解一下这次部署的“蓝图”。我们的目标是搭建一个完整的AI服务栈,它主要包含三个部分:

  1. 模型服务层:这是核心,使用 vLLM 来部署经过 GPTQ-Int4 量化处理的通义千问1.5-1.8B-Chat模型。量化能大幅降低模型对显存的需求,让它在消费级显卡上也能流畅运行。
  2. 前端交互层:我们选用 Chainlit 来构建一个美观、易用的Web聊天界面。你不需要写前端代码,就能拥有一个功能完善的对话应用。
  3. 网络与安全层:这是本教程的重点增值部分。我们将使用 Traefik 作为反向代理和入口网关。它的作用是:
    • 反向代理:将外部的访问请求,正确地转发到内部的Chainlit服务。
    • HTTPS加密:自动为你的服务申请和配置SSL证书,实现安全的 https:// 访问。
    • 服务发现:通过简单的标签配置,自动发现和管理容器服务,非常方便。

整个架构的流量走向是:用户通过浏览器访问 https://你的域名 → Traefik接收请求并完成HTTPS解密 → Traefik将请求转发给Chainlit服务 → Chainlit调用后端的vLLM模型服务 → 生成回复并沿原路返回给用户。

接下来,我们进入具体的部署环节。

2. 使用vLLM部署模型服务

首先,我们需要把AI模型的大脑——通义千问服务跑起来。这里我们使用vLLM,它是一个专为大规模语言模型设计的高性能推理和服务引擎。

2.1 启动vLLM服务

假设你已经通过某种方式(例如CSDN星图镜像广场的预置镜像)获得了 Qwen1.5-1.8B-Chat-GPTQ-Int4 模型,并且模型文件位于 /root/workspace/models 目录下。

我们可以使用Docker来快速启动服务。创建一个名为 docker-compose.yml 的文件,并添加vLLM服务配置:

version: '3.8'

services:
  vllm-qwen:
    image: vllm/vllm-openai:latest
    container_name: vllm-qwen-service
    runtime: nvidia # 如果你使用NVIDIA GPU
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    volumes:
      - /root/workspace/models:/app/models  # 挂载你的模型目录
    ports:
      - "8000:8000"
    command: >
      --model /app/models/Qwen1.5-1.8B-Chat-GPTQ-Int4
      --served-model-name Qwen1.5-1.8B-Chat
      --api-key token-abc123 # 设置一个简单的API密钥,增强基础安全
      --port 8000
      --max-model-len 4096
    restart: unless-stopped

关键参数解释:

  • --model: 指定模型路径。
  • --served-model-name: 服务使用的模型名称,客户端调用时会用到。
  • --api-key: 设置一个API密钥,调用时需要提供,防止服务被随意滥用。
  • --max-model-len: 模型支持的最大上下文长度。

在包含 docker-compose.yml 文件的目录下,运行以下命令启动服务:

docker-compose up -d

2.2 验证模型服务

服务启动后,需要一点时间加载模型(取决于硬件)。我们可以通过查看日志来确认是否成功。

# 查看容器日志
docker logs vllm-qwen-service -f

当你看到类似下面的输出时,说明模型加载成功,服务已就绪:

INFO 07-28 10:00:00 llm_engine.py:197] Initializing an LLM engine (v0.3.3) with config: model=/app/models/Qwen1.5-1.8B-Chat-GPTQ-Int4, ... 
INFO 07-28 10:00:15 llm_engine.py:327] # GPU blocks: 1245, # CPU blocks: 512
INFO 07-28 10:00:20 api_server.py:137] Started server process [1]
INFO 07-28 10:00:20 api_server.py:143] Waiting for startup event.
INFO 07-28 10:00:20 api_server.py:147] Startup event received.
INFO 07-28 10:00:20 api_server.py:153] Started server on http://0.0.0.0:8000

你也可以直接调用一个简单的API测试:

curl http://localhost:8000/v1/models

如果返回包含模型信息的JSON,则证明服务运行正常。

至此,我们的“AI大脑”已经在 http://localhost:8000 上待命了。接下来,我们为它构建一个聊天界面。

3. 使用Chainlit构建前端应用

Chainlit可以让我们快速创建一个功能丰富的聊天应用,并且能轻松对接像vLLM这样的OpenAI兼容API。

3.1 创建Chainlit应用

首先,创建一个新的项目目录,例如 qwen-chat,并进入。

mkdir qwen-chat && cd qwen-chat

创建一个Python虚拟环境并安装依赖(如果你使用Docker部署Chainlit,此步可在镜像内完成):

python -m venv venv
source venv/bin/activate  # Linux/Mac
# venv\Scripts\activate  # Windows
pip install chainlit openai

创建一个主要的应用文件 app.py

import chainlit as cl
from openai import OpenAI

# 配置连接到我们本地部署的vLLM服务
client = OpenAI(
    base_url="http://vllm-qwen-service:8000/v1", # 注意这里使用Docker服务名,在compose网络内可解析
    api_key="token-abc123" # 与vLLM启动命令中设置的api-key一致
)

@cl.on_chat_start
async def start_chat():
    # 可选:在聊天开始时发送一条欢迎消息
    await cl.Message(
        content="你好!我是基于通义千问1.5-1.8B模型打造的助手,很高兴为你服务。"
    ).send()

@cl.on_message
async def handle_message(message: cl.Message):
    # 构建发送给vLLM的消息历史(简单实现,仅当前对话)
    messages = [
        {"role": "user", "content": message.content}
    ]

    # 调用vLLM的聊天接口
    response = client.chat.completions.create(
        model="Qwen1.5-1.8B-Chat", # 与vLLM --served-model-name 参数一致
        messages=messages,
        stream=True, # 启用流式输出,体验更好
        max_tokens=1024,
        temperature=0.7
    )

    # 创建一个空的回复消息对象用于流式输出
    msg = cl.Message(content="")
    await msg.send()

    # 流式处理响应
    for chunk in response:
        if chunk.choices[0].delta.content is not None:
            await msg.stream_token(chunk.choices[0].delta.content)

    # 流式输出完成
    await msg.update()

创建一个Chainlit配置文件 chainlit.md(可选,用于定制UI):

# 欢迎使用通义千问聊天助手

这是一个部署在本地环境下的AI对话演示。

3.2 使用Docker部署Chainlit

为了便于与Traefik集成,我们也用Docker来运行Chainlit。在 qwen-chat 目录下创建 Dockerfile

FROM python:3.10-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8080

CMD ["chainlit", "run", "app.py", "--host", "0.0.0.0", "--port", "8080"]

创建 requirements.txt

chainlit>=1.0.0
openai>=1.0.0

现在,我们将Chainlit服务也定义到之前的 docker-compose.yml 中。

4. 集成Traefik实现HTTPS反向代理

这是实现安全、便捷访问的关键步骤。Traefik会自动管理SSL证书(使用Let‘s Encrypt)并将 https://your-domain.com 的请求代理到Chainlit服务。

4.1 配置Docker Compose

更新你的 docker-compose.yml 文件,加入Chainlit和Traefik服务。注意,我们需要创建一个外部网络让Traefik能发现其他服务。

首先,创建一个用于Traefik配置的目录 traefik,并在其中创建动态配置文件 traefik-dynamic.yml

# traefik/traefik-dynamic.yml
http:
  routers:
    chainlit-router:
      rule: "Host(`your-domain.com`)" # 将 your-domain.com 替换为你的真实域名
      service: chainlit-service
      entryPoints:
        - websecure
      tls:
        certResolver: myresolver

  services:
    chainlit-service:
      loadBalancer:
        servers:
          - url: "http://chainlit-app:8080"

然后,更新 docker-compose.yml

version: '3.8'

networks:
  web:
    external: true # 假设你已经创建了名为`web`的网络: `docker network create web`
  internal:
    driver: bridge

services:
  vllm-qwen:
    image: vllm/vllm-openai:latest
    container_name: vllm-qwen-service
    runtime: nvidia
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]
    volumes:
      - /root/workspace/models:/app/models
    # ports 不再映射到主机,仅在内部网络访问
    networks:
      - internal
    command: >
      --model /app/models/Qwen1.5-1.8B-Chat-GPTQ-Int4
      --served-model-name Qwen1.5-1.8B-Chat
      --api-key token-abc123
      --port 8000
      --max-model-len 4096
    restart: unless-stopped

  chainlit-app:
    build: ./qwen-chat # 指向你的Chainlit应用目录
    container_name: chainlit-app
    volumes:
      - ./qwen-chat:/app
    networks:
      - internal
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.chainlit.rule=Host(`your-domain.com`)" # 你的域名
      - "traefik.http.routers.chainlit.entrypoints=websecure"
      - "traefik.http.routers.chainlit.tls.certresolver=myresolver"
      - "traefik.http.services.chainlit.loadbalancer.server.port=8080"
    environment:
      - OPENAI_API_BASE=http://vllm-qwen-service:8000/v1
      - OPENAI_API_KEY=token-abc123
    depends_on:
      - vllm-qwen
    restart: unless-stopped

  traefik:
    image: traefik:v3.0
    container_name: traefik
    ports:
      - "80:80"    # HTTP端口,用于ACME挑战
      - "443:443"  # HTTPS端口
    networks:
      - web
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/traefik.yml:/etc/traefik/traefik.yml
      - ./traefik/traefik-dynamic.yml:/etc/traefik/traefik-dynamic.yml
      - ./traefik/acme.json:/acme.json # 存储SSL证书
    command:
      - "--api.insecure=true" # 仅在安全内网环境下开启,用于查看Dashboard
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false" # 只有打了标签的服务才被暴露
      - "--providers.file.filename=/etc/traefik/traefik-dynamic.yml"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.httpchallenge=true"
      - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"
      - "--certificatesresolvers.myresolver.acme.email=your-email@example.com" # 你的邮箱
      - "--certificatesresolvers.myresolver.acme.storage=/acme.json"
    restart: unless-stopped

关键配置说明:

  1. 网络:创建了 internal 网络供vLLM和Chainlit内部通信,web 网络供Traefik和Chainlit通信(需要提前创建 docker network create web)。
  2. Traefik Labels:在 chainlit-app 服务上添加的标签,告诉Traefik如何路由流量。这是Traefik自动服务发现的核心。
  3. 证书解析器 (myresolver):配置使用Let‘s Encrypt自动申请和续期SSL证书。你需要将 your-domain.comyour-email@example.com 替换成你自己的域名和邮箱。
  4. 端口:Traefik容器映射了主机的80和443端口,分别用于HTTP挑战和HTTPS服务。

4.2 创建Traefik静态配置

traefik 目录下创建静态配置文件 traefik.yml

# traefik/traefik.yml
api:
  dashboard: true # 开启Dashboard,可通过 traefik.your-domain.com 访问(需额外配置路由)
  debug: true

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true
  websecure:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    network: web
  file:
    filename: /etc/traefik/traefik-dynamic.yml

log:
  level: INFO
  filePath: /var/log/traefik.log

accessLog:
  filePath: /var/log/access.log

这个配置做了两件重要的事:

  1. 将所有的HTTP(80端口)请求永久重定向到HTTPS(443端口)。
  2. 指定了动态配置文件的路径。

4.3 启动所有服务并测试

确保你的域名DNS已经解析到服务器的IP地址。然后,在项目根目录下运行:

docker-compose up -d

Traefik启动后,会自动为你的域名申请SSL证书(第一次可能需要几分钟)。申请成功后,你就可以通过 https://your-domain.com 安全地访问你的Chainlit聊天界面了。

打开浏览器,访问你的域名,你应该能看到Chainlit的聊天界面。尝试发送一条消息,如果一切配置正确,Chainlit会通过内部网络调用vLLM服务,并将模型的回复流式地显示在界面上。

5. 总结与后续建议

至此,我们已经成功搭建了一个包含AI模型服务、Web前端和安全HTTPS网关的完整应用。让我们回顾一下关键步骤和要点:

  1. 模型服务:使用vLLM部署量化后的通义千问模型,这是整个应用的核心计算引擎。
  2. 前端交互:利用Chainlit快速构建了一个无需复杂前端开发的聊天界面,并通过环境变量轻松对接后端API。
  3. 安全代理:通过Traefik,我们实现了服务的自动发现、HTTPS加密、HTTP到HTTPS的重定向,极大地提升了服务的安全性和专业性。

一些实用的后续建议:

  • 安全性增强:在生产环境中,应考虑为Traefik的API Dashboard设置访问控制,为vLLM API配置更复杂的认证机制,并确保服务器本身的安全配置。
  • 性能监控:可以集成Prometheus和Grafana来监控vLLM和Traefik的指标,如请求延迟、GPU利用率等。
  • 高可用考虑:如果流量较大,可以考虑将vLLM服务进行水平扩展,并在Traefik中配置负载均衡。
  • 域名与证书:确保你的域名解析正确,并留意Let‘s Encrypt证书的自动续期是否正常工作(Traefik默认会处理)。

这个方案的优势在于其模块化和自动化。每个组件(模型服务、前端、网关)职责清晰,易于独立升级和维护。Traefik的标签驱动配置让添加新服务或修改路由规则变得非常简单。

现在,你已经拥有了一个私有的、安全的AI对话平台,可以在此基础上进行更多的功能探索和开发了。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐