ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

在 Modal 无服务器 GPU 上按需部署 Tabby:完整实操指南

在 Modal 无服务器 GPU 上按需部署 Tabby:完整实操指南 在 Modal 无服务器 GPU 上按需部署 Tabby完整实操指南【免费下载链接】tabbySelf-hosted AI coding assistant项目地址: https://gitcode.com/GitHub_Trending/tab/tabbyModal 是一个 serverless GPU 平台通过它运行 Tabby 可以实现按需启动、空闲休眠的弹性部署当一段时间没有请求到达时Modal 会自动让容器休眠以节省 GPU 成本。本文以 modal/index.md 为核心教程骨架结合仓库中 app.py 的完整代码与 Tabby 服务端源码从镜像构建、模型预热、ASGI 代理到modal serve发布带你一步步把 Tabby 跑在云端并给出每个配置项的源码级解释。为什么选择 Modal 运行 TabbyTabby 是一个自托管的 AI 编码助手self-hosted AI coding assistant通常以tabby serve方式常驻运行持续占用一块 GPU。而 Modal 的价值在于按需运行on demandTabby 实例只在有请求时才启动自动休眠省成本当 Tabby 服务器一段时间内没有请求时Modal 会调度容器休眠sleep从而停止 GPU 计费弹性并发容器内可配置同时处理多个请求空闲容器可保留一段时间后再回收。这种模式非常适合个人开发者或小团队既拥有自托管 Tabby 的全部能力又不必为 24 小时空转的 GPU 付费。环境准备与核心变量首先在 Python 脚本中导入 Modal 的必要组件from modal import Image, App, asgi_app, gpuImage定义运行容器镜像App声明一个 Modal 应用asgi_app把 Tabby 的 HTTP 服务挂载为 Modal 的 web endpointgpu声明 GPU 配置。然后设置基础变量IMAGE_NAME tabbyml/tabby MODEL_ID TabbyML/StarCoder-1B CHAT_MODEL_ID TabbyML/Qwen2-1.5B-Instruct EMBEDDING_MODEL_ID TabbyML/Nomic-Embed-Text GPU_CONFIG gpu.T4() TABBY_BIN /opt/tabby/bin/tabby各变量含义如下变量作用IMAGE_NAME基础 Docker 镜像使用 Tabby 官方镜像tabbyml/tabbyMODEL_ID代码补全模型/completions端点使用仓库中 serve.rs 注释明确其为/completionsAPI 的模型CHAT_MODEL_ID对话模型供/chat/completions端点使用见 serve.rsEMBEDDING_MODEL_ID嵌入模型用于代码搜索 / 文档检索等 embedding 服务GPU_CONFIGModal 的 GPU 配置这里选用gpu.T4()TABBY_BINTabby 二进制在镜像内的路径/opt/tabby/bin/tabby与官方 Dockerfile 的安装位置一致见 Dockerfile.cuda值得注意的是Tabby 官方镜像默认的ENTRYPOINT就是/opt/tabby/bin/tabby见 Dockerfile.cuda后续构建镜像时需要清空它以交给 Modal 接管进程。选择 GPUModal 支持的配置教程中GPU_CONFIG gpu.T4()选择了低成本 T4同时给出 Modal 目前支持的 GPU 清单数据来自官方教程原文GPU显存定位与说明T416 GiB低成本选项适合小模型L424 GiB中端选项A10040 / 80 GiB云端最强 GPU 之一H10080 GiBHopper 架构旗舰数据中心 GPU强化 FP8 精度支持内置 Transformer Engine对 GPT-3 (175B) 级模型训练较上一代最高快 4 倍A10G—相比 T4ML 训练性能最高提升 3.3 倍、推理性能最高提升 3 倍、图形性能最高提升 3 倍Any—按可用性自动选择任意 GPU 类别选择 GPU 的关键标准是让所选模型能装进显存fit the model into VRAM。1B 级补全模型 1.5B 级对话模型 嵌入模型在 T4 的 16 GiB 显存内可以合理共存这也是教程选择gpu.T4()的原因。定义容器镜像预热模型权重为了让容器冷启动更快教程把模型权重预置进镜像这样容器启动时无需重新下载模型而是利用 Modal 内部文件系统实现更快的冷启动。下载权重的函数def download_model(model_id: str): import subprocess subprocess.run( [ TABBY_BIN, download, --model, model_id, ] )该函数调用tabby download --model model_id。在服务端源码中download子命令对应 download.rs它接收--model模型 ID和--prefer-local-file跳过远程文件检查默认 false两个参数底层通过 tabby-download 从模型注册表解析模型信息含 sha256 校验并下载权重。也就是镜像构建期间就把权重落盘运行时serve阶段无需再联网拉取。组装镜像image ( Image.from_registry( IMAGE_NAME, add_python3.11, ) .dockerfile_commands(ENTRYPOINT []) .run_function(download_model, kwargs{model_id: EMBEDDING_MODEL_ID}) .run_function(download_model, kwargs{model_id: CHAT_MODEL_ID}) .run_function(download_model, kwargs{model_id: MODEL_ID}) .pip_install(asgi-proxy-lib) )构建过程分四步Image.from_registry(IMAGE_NAME, add_python3.11)基于tabbyml/tabby镜像并补充 Python 3.11 运行时.dockerfile_commands(ENTRYPOINT [])清空官方镜像默认的 ENTRYPOINT即tabby命令入口让 Modal 以自己的入口运行实现 seamless serverless 部署三个.run_function(download_model, ...)依次预下载嵌入、对话、补全三个模型的权重写入镜像层.pip_install(asgi-proxy-lib)安装asgi-proxy-lib用于在 localhost 上对接 Modal 的 ASGI web server。应用函数启动 Tabby 并桥接 ASGI核心端点函数用 Modal 的app.function表示完成四件事启动 Tabby 进程并等待就绪、创建 ASGI 代理把 Modal web endpoint 的请求隧道转发到本地 Tabby 服务、设置单容器最大并发请求数、设置空闲容器回收时间。app App(tabby-server, imageimage) app.function( gpuGPU_CONFIG, allow_concurrent_inputs10, container_idle_timeout120, timeout360, ) asgi_app() def app_serve(): import socket import subprocess import time from asgi_proxy import asgi_proxy launcher subprocess.Popen( [ TABBY_BIN, serve, --model, MODEL_ID, --chat-model, CHAT_MODEL_ID, --port, 8000, --device, cuda, --parallelism, 1, ] ) # Poll until webserver at 127.0.0.1:8000 accepts connections before running inputs. def tabby_ready(): try: socket.create_connection((127.0.0.1, 8000), timeout1).close() return True except (socket.timeout, ConnectionRefusedError): # Check if launcher webserving process has exited. # If so, a connection can never be made. retcode launcher.poll() if retcode is not None: raise RuntimeError(flauncher exited unexpectedly with code {retcode}) return False while not tabby_ready(): time.sleep(1.0) print(Tabby server ready!) return asgi_proxy(http://localhost:8000)Modal 函数参数逐项解读参数值含义gpuGPU_CONFIGT4指定容器 GPUallow_concurrent_inputs10单个容器允许同时处理最多 10 个请求container_idle_timeout120空闲容器保留 120 秒2 分钟后回收timeout360函数执行超时上限 360 秒Tabby serve 参数与源码对应启动命令对应tabby serve其参数在 serve.rs 中定义--model MODEL_ID指定/completions补全模型--chat-model CHAT_MODEL_ID指定/chat/completions对话模型设置它后serve.rs 才会注册/v1/chat/completions与/v1beta/chat/completions路由否则这两个路由返回501 NOT_IMPLEMENTED--port 8000监听端口 8000默认是 8080见 serve.rs--device cuda使用 GPU 推理默认是 CPU见 serve.rs--parallelism 1模型推理并行度。源码注释明确提示增加该值会显著提升内存尤其是显存占用serve.rs在 T4 上设为 1 是保守且合理的选择。merge_argsserve.rs会把 CLI 参数合并进配置--model覆盖 completion 配置--chat-model覆盖 chat 配置若config.toml中已有同名模型会打印覆盖警告。因此本教程通过命令行参数注入三个模型完全等价于在config.toml中配置对应模型字段。就绪探活health checktabby_ready()每 1 秒尝试连接127.0.0.1:8000连接成功 → 返回 TrueTabby 已就绪超时 / 拒绝连接 → 检查launcher进程是否已退出若已退出则抛出RuntimeError避免无限空等否则继续轮询。这一步非常关键Modal 只有等app_serve返回 ASGI 代理后才开始路由流量所以必须先确保 Tabby 内部 HTTP 服务真正可接受连接。ASGI 代理桥接asgi_proxy(http://localhost:8000)把 Modal web endpoint 收到的请求在容器内隧道转发到 Tabby 的 8000 端口。对客户端编辑器扩展而言看到的就是一个标准的 Tabby server URL。发布服务modal serve在包含app.py的目录下执行modal serve app.py部署成功后Modal 会输出 web endpoint 地址格式为https://USERNAME--tabby-server-app-serve-dev.modal.runtabby-server对应App(tabby-server, ...)的应用名app-serve对应app.function装饰的函数名dev表示modal serve的开发dev环境。强制重建镜像如果遇到问题尤其是缓存相关的问题比如镜像里拉到了旧的模型权重或旧的镜像 tag可以用强制重建来忽略缓存层、拉取最新镜像 tagMODAL_FORCE_BUILD1 modal serve app.py这也与app.py头部注释中的用法说明一致见 app.py。部署完成后把输出的 URL 填入 Tabby 编辑器扩展的 server url 配置即可开始使用云端代码补全与对话能力。完整可运行的代码可直接参考教程同目录的 app.py。小结本文完整走通了Modal 无服务器 GPU Tabby的部署链路用Image预置三个模型的权重以加速冷启动用app.function(gpu..., allow_concurrent_inputs..., container_idle_timeout...)声明按需运行与休眠策略用asgi_proxy将本地 8000 端口的 Tabby HTTP 服务桥接为 Modal web endpoint最后通过modal serve app.py一键发布。核心收益是只有请求到来时才启动 GPU 容器空闲 2 分钟自动休眠GPU 成本随流量按需产生——这正是自托管 AI 编码助手在云端低成本运行的典型姿势。如果你对 Tabby 的 serve 参数或模型下载机制感兴趣可以继续阅读 serve.rs 与 tabby-download 的源码实现。【免费下载链接】tabbySelf-hosted AI coding assistant项目地址: https://gitcode.com/GitHub_Trending/tab/tabby创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表