FastChat Web 服务端生产部署指南:Controller、Worker 与多标签 Gradio Arena 服务搭建
2026/9/9 13:58:50 网站建设 项目流程

FastChat Web 服务端生产部署指南:Controller、Worker 与多标签 Gradio Arena 服务搭建

【免费下载链接】FastChatAn open platform for training, serving, and evaluating large language models. Release repo for Vicuna and Chatbot Arena.项目地址: https://gitcode.com/GitHub_Trending/fa/FastChat

FastChat 提供了一整套面向大规模语言模型对话服务的前后端组件。本文基于仓库内 docs/commands/webserver.md 这一份生产部署备忘,结合 fastchat/serve/ 下的源码实现,系统讲解如何安装环境、逐层启动 Controller 与各类 Worker、拉起带多标签(Arena 对战、单模型直聊、Leaderboard 等)的 Gradio Web 服务,并完成端口监听检查、进程文件句柄上限调优与 Gradio 前端页面定制。读者完成后,可独立复现一个面向内网或外网的 Chatbot Arena 式 Web 服务集群。

1. 部署形态与角色分工

在动手执行命令前,先明确本文部署脚本背后的进程模型。从 docs/server_arch.md 与 fastchat/serve/ 目录可以确认 FastChat 服务端由三类角色构成:

  • Controller(调度中枢):维护所有 Worker 的注册表,提供心跳检查、模型列表查询与请求分发。fastchat/serve/controller.py 中Controller类维护worker_info(Worker 名到WorkerInfo的映射),并支持lotteryshortest_queue两种分发策略(controller.py)。
  • Model Worker(算力执行者):真正持有模型权重或调用远程推理 API,向 Controller 注册自身,并通过 FastAPI 暴露worker_generate_stream等端点。同一模型可注册多个 Worker 以扩展吞吐。
  • Web Server(用户入口):基于 Gradio 构建的浏览器界面,向 Controller 拉取模型列表并转发用户请求。fastchat/serve/gradio_web_server_multi.py 实现了带多个 Tab 的 Arena 界面,是本文部署的主角。

原文档中的部署脚本把日志按进程拆到fastchat_logs/controllerfastchat_logs/server0serverN等独立目录下,便于逐个进程隔离排查,这是一套典型的多机/多进程生产排布,下面按安装、启动、验收的顺序展开。

2. 环境安装与依赖准备

原文档给出的安装流程面向 Ubuntu 系统,核心步骤是安装系统工具、准备 conda 环境并执行 FastChat 的可编辑安装:

sudo apt update sudo apt install tmux htop wget https://repo.anaconda.com/archive/Anaconda3-2022.10-Linux-x86_64.sh bash Anaconda3-2022.10-Linux-x86_64.sh conda create -n fastchat python=3.9 conda activate fastchat git clone https://gitcode.com/GitHub_Trending/fa/FastChat.git cd FastChat pip3 install -e .

补充说明几点,便于你按实际情况调整:

  • python=3.9是原脚本选定的解释器版本;conda 环境名与 Python 版本都可按本机情况替换,后续所有启动命令都依赖当前 conda 环境处于激活状态。
  • 使用pip3 install -e .(可编辑安装)而不是普通安装,是因为后续要频繁改动、调试仓库代码,可编辑模式保证改完即生效,无需重装。
  • 进入虚拟环境后,python3应指向~/anaconda3/envs/fastchat/bin/python,可通过which python3验证。
  • tmuxhtop用于把每个服务放进独立会话并实时观察 CPU / 内存,防止服务随 SSH 断开而终止;也可以改用nohup ... &或 systemd 单元来托管进程。

3. 启动 Controller 并注册首个 Worker

3.1 启动 Controller

Controller 是集群的核心注册中心,第一个启动:

cd fastchat_logs/controller python3 -m fastchat.serve.controller --host 0.0.0.0 --port 21001

从源码看,create_controller()定义的默认参数为--host localhost--port 21001(controller.py)。部署到公网或跨机场景时必须显式指定--host 0.0.0.0,让其他机器上的 Worker 与 Web Server 能访问;--dispatch-method默认是shortest_queue(选择queue_length / speed最小的 Worker),也可切换为lottery按速度加权随机分发(controller.py)。心跳相关阈值由环境变量控制:CONTROLLER_HEART_BEAT_EXPIRATION默认 90 秒、WORKER_HEART_BEAT_INTERVAL默认 45 秒(constants.py),即超过 90 秒未收到心跳的 Worker 会被自动清理(controller.py)。

3.2 手动注册 Worker

正常情况下 Worker 启动时会自动向 Controller 注册;register_worker用于手动补注册一个尚未在 Controller 注册表中出现、或不走自动注册流程的 Worker 地址:

python3 -m fastchat.serve.register_worker --controller http://localhost:21001 --worker-name https://

观察 fastchat/serve/register_worker.py 的调用逻辑可以推断:该工具会把worker_name连同check_heart_beatmultimodal字段 POST 到 Controller 的/register_worker接口,worker_statusNone表示让 Controller 主动回查 Worker 的/worker_get_status获取模型列表(register_worker.py)。原文档示例中的--worker-name https://是内网部署时的示意占位地址,实际应替换为可被 Controller 访问到的完整 Worker 地址,例如http://worker-host:21002

3.3 发送测试消息验证通路

注册完成后,用test_message向 Controller 查询指定模型对应的 Worker 地址并真正发起一次流式推理,验证整条链路可用:

python3 -m fastchat.serve.test_message --model vicuna-13b --controller http://localhost:21001

从 fastchat/serve/test_message.py 的main()可以看到它做的事情非常典型:

  1. 依次 POST/refresh_all_workers(触发 Controller 重新校验所有 Worker)与/list_models,打印当前已注册模型列表(test_message.py);
  2. POST/get_worker_address拿到承载该模型的 Worker 地址(test_message.py);
  3. 使用get_conversation_template(model_name)构建对话模板,向 Worker 的/worker_generate_stream发起流式请求并按\0分隔符逐块打印生成结果(test_message.py)。

命令默认--temperature 0.0--max-new-tokens 32,若 Worker 就绪,终端会看到逐字输出的回复;若输出No available workers for xxx,说明该模型尚未被任何 Worker 注册,应优先排查 Worker 侧。

4. 启动模型 Worker(HuggingFace 推理端点版)

原文档中启动的huggingface_api_worker属于“不本地加载权重、直接调用远程推理端点”的 Worker 形态,适合把 Falcon、Zephyr 等托管在 HuggingFace Inference Endpoints 上的模型接入 Arena:

cd fastchat_logs/server0 python3 -m fastchat.serve.huggingface_api_worker --model-info-file ~/elo_results/register_hf_api_models.json

4.1 模型信息文件格式

--model-info-file指向一个 JSON 文件,用于声明每个接入模型的端点与鉴权信息。仓库源码头部给出了完整字段说明(huggingface_api_worker.py):

{ "falcon-180b-chat": { "model_name": "falcon-180B-chat", "api_base": "https://api-inference.huggingface.co/models", "model_path": "tiiuae/falcon-180B-chat", "token": "hf_XXX", "context_length": 2048 }, "zephyr-7b-beta": { "model_name": "zephyr-7b-beta", "model_path": "", "api_base": "xxx", "token": "hf_XXX", "context_length": 4096 } }

其中必填字段为model_pathapi_basetokencontext_length,其余字段可选。从create_huggingface_api_worker()的解析代码看(huggingface_api_worker.py),还支持可选字段model_names(为一个或多个名字,缺省取 key 的最后一段)与conv_template(自定义对话模板),这些信息会被批量构建为HuggingfaceApiWorker实例并一次性注册到 Controller。若某个 key 的model_path为空字符串,则直接以api_base作为推理 URL。

4.2 关键启动参数

该模块的完整参数可通过python3 -m fastchat.serve.huggingface_api_worker --help查看,常用项及默认值如下(huggingface_api_worker.py):

参数默认值说明
--hostlocalhostWorker 监听地址
--port21002Worker 监听端口
--worker-addresshttp://localhost:21002注册给 Controller 的对外地址,跨机时须改为可达地址
--controller-addresshttp://localhost:21001Controller 地址
--model-info-file必填上述模型注册 JSON 文件
--limit-worker-concurrency5并发上限,用于防止打爆远端推理端点(OOM)
--no-register关闭开启后只启动服务、不向 Controller 注册,便于先行联调
--seedNone覆盖每次生成的随机种子

Worker 内部通过huggingface_hub.InferenceClient以流式方式调用text_generation,并把结果按 FastChat 约定逐条序列化后以\0结尾返回(huggingface_api_worker.py)。由于该 Worker 没有本地 tokenizer,count_token直接返回 0(huggingface_api_worker.py),token 统计由调用方决定如何处理。

若希望本地加载权重(Vicuna、Llama 等)而不是走远程 API,应改用fastchat.serve.model_worker(本地 GPU Worker)或vllm_worker/sglang_worker等高性能后端,可参考 docs/vllm_integration.md 与 docs/sglang 相关文档 了解接入方式。本部署脚本走的是托管端点路径,不需要本地 GPU 常驻显存。

5. 启动多标签 Gradio Web Server

前端是整个部署的门面。原文档在配置好环境变量后启动gradio_web_server_multi,从而获得带 “Arena(对战)”“side-by-side(具名对比)”“Direct Chat(单模型直聊)” 等标签的 Chatbot Arena 界面。

5.1 配置第三方 API 密钥

启动前需要为希望接入的闭源模型准备对应的服务密钥:

export OPENAI_API_KEY= export ANTHROPIC_API_KEY= export GCP_PROJECT_ID=

这三项分别对应 OpenAI(ChatGPT)、Anthropic(Claude)与 Google(PaLM/Gemini)三种 API 类模型来源。值得说明的是:API 类模型本身并非由本地 Worker 承载,而是由 Web Server 通过对应的 provider 客户端直接调用官方接口,因而密钥只需在运行 Web Server 的进程环境中配置即可;相关 provider 枚举可见 fastchat/serve/gradio_web_server.py 中对api_typeopenai/anthropic/gemini/mistral)的说明。

5.2 启动命令与参数对照

原文档使用的生产启动命令为:

python3 -m fastchat.serve.gradio_web_server_multi \ --controller http://localhost:21001 \ --concurrency 50 \ --add-chatgpt --add-claude --add-palm \ --elo ~/elo_results/elo_results.pkl \ --leaderboard-table-file ~/elo_results/leaderboard_table.csv \ --register ~/elo_results/register_oai_models.json \ --show-terms

需要向读者说明:上述命令是原文档部署 Chatbot Arena 站点时的写法,属于该命令的一个较早期版本。对照当前仓库 fastchat/serve/gradio_web_server_multi.py 的argparse定义,CLI 已有较大演进——--add-chatgpt/--add-claude/--add-palm--concurrency--register等旧参数不再存在,功能分别由新参数承接。在当前代码上等效的启动方式为:

python3 -m fastchat.serve.gradio_web_server_multi \ --host 0.0.0.0 --port 7860 \ --controller-url http://localhost:21001 \ --concurrency-count 50 \ --register-api-endpoint-file ~/elo_results/register_oai_models.json \ --elo-results-file ~/elo_results/elo_results.pkl \ --leaderboard-table-file ~/elo_results/leaderboard_table.csv \ --show-terms-of-use

新参数与旧写法的映射关系及含义如下:

旧文档写法当前参数含义
--concurrency 50--concurrency-count 50Gradio 队列默认并发上限(默认10
--register xxx.json--register-api-endpoint-file xxx.json从 JSON 注册 API 类模型端点
--add-chatgpt/--add-claude/--add-palm(由 register 文件声明)决定接入哪些闭源模型
--elo xxx.pkl--elo-results-file xxx.pkl加载 ELO 结果并渲染 Leaderboard 图
--leaderboard-table-file--leaderboard-table-fileLeaderboard 表格数据文件
--show-terms--show-terms-of-use进入页面前弹出使用条款确认

其余在当前源码中仍可用的重要参数还包括:--model-list-mode {once,reload}(默认oncereload表示每次请求都向 Controller 重新拉取模型列表,便于动态增删模型)、--vision-arena(显示多模态对战标签)、--ga-id(Google Analytics 统计 ID,与下方前端定制相呼应)、--gradio-auth-path/--password(认证)、--moderate(开启输入内容审核)与--share(生成公网分享链接)等(gradio_web_server_multi.py)。

API 端点注册文件register_oai_models.json的格式在 gradio_web_server.py 中有明确注释,形如:

{ "gpt-3.5-turbo": { "model_name": "gpt-3.5-turbo", "api_type": "openai", "api_base": "https://api.openai.com/v1", "api_key": "sk-******", "anony_only": false } }

api_type可选openaianthropicgeminimistralanony_onlytrue时该模型只出现在匿名对战模式中,不进入具名列表。

5.3 服务启动方式与 Leaderboard 数据来源

从 gradio_web_server_multi.py 可以看到,demo.queue(...).launch(...)最终以max_threads=200show_api=False的方式对外服务;--elo-results-file--leaderboard-table-file若非空,则会在第三个 Tab 渲染build_leaderboard_tab(monitor.py)。ELO 分数、排行榜 CSV 是对战数据离线计算的产物,生成方法可参考 docs/commands/leaderboard.md;若只是做单机验证,可以不带这两个参数直接启动,此时不会显示 Leaderboard Tab。

5.4 多路并发部署时的日志管理

原文档的生产脚本将每个 Web Server 放进独立目录并各自cd后启动。FastChat 的日志输出目录由LOGDIR环境变量控制,默认是当前目录.(constants.py),因此“每个服务单独cd一个目录”的做法,本质上是为了让各进程的gradio_web_server.logmodel_worker_*.logcontroller.log等日志文件落到互不干扰的独立目录,便于按服务巡检。实际多副本部署时,可把第 5.2 节的启动命令在fastchat_logs/server1server2… 等多个目录分别以不同--port拉起,对外由 Nginx 等反向代理做负载均衡(参考 fastchat/serve/gateway/nginx.conf)。

6. 检查服务启动耗时与就绪状态

多副本场景下逐个人眼看日志不现实,原文档给出了一段循环检查命令:遍历server0~server11的日志,抓取每条 Gradio 服务“已监听本地 URL”的最后一行日志,即可快速确认各副本是否全部就绪:

for i in $(seq 0 11); do cat fastchat_logs/server$i/gradio_web_server.log | grep "Running on local URL" | tail -n 1; done

gradio_web_server.log由 fastchat/serve/gradio_web_server.py 中的build_logger("gradio_web_server", "gradio_web_server.log")产生,与 Web Server 在同一进程内随logger.info(f"args: {args}")(gradio_web_server_multi.py)记录启动参数。若某一行输出为空,说明对应副本尚未打出监听日志,需要回到该目录查看进程是否存活或端口是否被占用;seq 0 11中的区间应按实际启动的副本数调整。

7. 提高最大打开文件数上限

高并发的 Web 服务(尤其同时维护大量浏览器长连接与上游 Worker HTTP 连接时)很容易触达系统默认的进程文件句柄上限,原文档给出了“单进程免重启”与“系统级持久化”两种处理方式。

方式一:单进程即时调整(无需重启)

先用ps找到目标进程 PID,再用prlimit把该进程的 nofile 上限调高到 1048576:

sudo prlimit --nofile=1048576:1048576 --pid=$id

对 Gradio 类 Web 服务进程做批量调整:

for id in $(ps -ef | grep gradio_web_server | awk '{print $2}'); do echo $id; prlimit --nofile=1048576:1048576 --pid=$id; done

--nofile=软限:硬限语法分别设定 soft limit(进程可自行调高)与 hard limit(权限上限)。注意该方式只对本次启动的进程生效,进程重启后需重新执行;且对 root 属主之外的进程调整硬限通常需要 root 权限,故示例保留sudo

方式二:系统级配置(需重启生效)

/etc/security/limits.conf末尾追加如下两行,对所有用户生效:

* hard nofile 65535 * soft nofile 65535

该方式属于 PAMpam_limits机制,作用于后续新登录会话与由其启动的全部进程,修改后需重新登录或重启系统。实践上建议两者结合:limits.conf 保证新进程默认高上限,prlimit用于对存量进程热修复。

8. 前端定制:注入统计脚本与文案优化

原文档针对当时固定版本的 Gradio(3.35.2)记录了若干“改前端文件”的运维技巧,目的是在不改业务代码的情况下完成埋点、加载提示与告警抑制。由于这些修改发生在 Gradio 的 Python site-packages 安装目录内,路径形如/home/vicuna/anaconda3/envs/fastchat/lib/python3.9/site-packages/gradio/...,升级 Gradio 后会被覆盖,请务必把定制项固化为可重复执行的补丁或记录。

8.1 在 index.html 注入 gtag 与 html2canvas

编辑 Gradio 前端模板入口.../site-packages/gradio/templates/frontend/index.html,在<head>中追加 Google Analytics 标签与截图库 html2canvas:

<!-- Google tag (gtag.js) --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-K6D24EE9ED"></script><script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-K6D24EE9ED'); window.__gradio_mode__ = "app"; </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>

埋点用于统计页面访问;html2canvas则支撑“把对局结果渲染成图片保存/分享”这类功能。值得一提的是,在当前仓库版本中,这两项能力已经原生内置到业务代码里,不再需要手工改 Gradio 模板:build_demo()会把html2canvas<script>恒常注入页面头部,并在传入--ga-id时自动拼接 gtag 脚本(gradio_web_server_multi.py)。也就是说,新版本直接传--ga-id G-xxxx即可等价实现上述第 1 步的埋点效果。

8.2 抑制弃用参数告警

编辑.../site-packages/gradio/deprecation.py,找到函数定义:

def check_deprecated_parameters(

按需在其内部提前return或注释告警分支,即可屏蔽 Gradio 对旧版调用方式的DeprecationWarning输出。这类告警本身不影响功能,仅在日志里刷屏,是否处理取决于对日志洁净度的要求。

8.3 修改“Loading”提示文案

Gradio 前端资源经打包后位于.../site-packages/gradio/templates/frontend/assets/index-188ef5e8.js(该 hash 文件名会随版本变化)。在 Vim 中用全局替换把默认的“Loading...”改为更友好的引导文案:

%s/"Loading..."/"Loading...(Please refresh if it takes more than 30 seconds)"/g

当上游 Worker 冷启动较慢、浏览器长时间停留在加载态时,这条提示能显著降低用户困惑。执行后需清空浏览器缓存并硬刷新(Ctrl+Shift+R)才能看到新文案。

9. 结语与排障速查

本文围绕 docs/commands/webserver.md 还原了一条完整的 FastChat Arena Web 服务生产部署链路:conda 环境与可编辑安装 → Controller(controller.py)→ Worker 注册(register_worker.py)与连通性验证(test_message.py)→ 远程端点型 Worker(huggingface_api_worker.py)→ 多标签 Gradio 门户(gradio_web_server_multi.py),最后覆盖了启动验收、文件句柄上限调优与前端定制三块日常运维动作。当链路不通时,可按下述顺序排查:

  1. 测试消息返回无 Worker:确认模型名与 Worker 注册的model_names完全一致,Controller 地址可达,Worker 的--no-register未误开;
  2. Web 页面模型列表为空:检查 Web Server 的--controller-url,并用model-list-mode reload重新拉取(gradio_web_server_multi.py);
  3. 生成超时/报错:查看对应目录下的controller.loggradio_web_server.log,并结合 constants.py 中FASTCHAT_WORKER_API_TIMEOUT(默认 100 秒)等环境变量确认超时窗口是否过短;
  4. 页面加载慢且句柄耗尽:按第 7 节调高prlimit并检查反向代理的 keep-alive 配置。

对于需要本地 GPU 加载权重的模型,请另行参考 docs/commands/local_cluster.md(多机 Worker 集群)与 fastchat/serve/model_worker.py,它们在 Controller/Web Server 层的接入方式与本文一致,可以无缝混布在同一集群中。

【免费下载链接】FastChatAn open platform for training, serving, and evaluating large language models. Release repo for Vicuna and Chatbot Arena.项目地址: https://gitcode.com/GitHub_Trending/fa/FastChat

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询