Tabby编码助手私有化部署指南

AI 编码助手可以帮助开发团队更好地创建和理解代码,具有自动完成、代码解释和自然语言交互等功能。在这篇博文中,我们将演示如何使用开源的AI编码助手 Tabby 和 推理平台 BentoCloud 部署可用于生产的 AI 编码助手。

具体来说,我们将:

  • 探索 Tabby 和 BentoCloud 的概念
  • 使用 BentoML 构建编码助手
  • 将编码助手部署到 BentoCloud
  • 使用助手进行代码自动完成和解释

这是该项目的架构。BentoML 服务 (Bento) 在 BentoCloud 上部署和管理,并托管 Tabby 服务器,RCLONE 在本地存储和 Cloudflare R2 持久存储之间同步数据。

你可以在此处找到所有源代码。

1、Tabby和BentoCloud

Tabby 是一个开源、自托管的 AI 编码助手。借助 Tabby,每个团队都可以轻松设置自己的 LLM 驱动的代码完成服务器。 Tabby 利用 AI 模型提供智能代码建议、自动完成和自然语言解释,显著提高开发团队的工作效率。

BentoCloud 是一个推理平台,可消除生产 AI 工作负载中的基础设施复杂性。它将尖端的推理和服务功能直接带入你的云环境,使 AI 团队可以轻松构建快速、安全且可扩展的 AI 应用程序。

2、使用 BentoML 构建助手

BentoML 是一个 Python 库,用于构建针对 AI 应用程序和模型推理优化的在线服务系统。此 BentoML 项目中的关键文件:

  • service.py:定义 Tabby 服务器和 BentoML 服务。
  • bentofile.yaml:将此项目构建为 Bento 的配置文件,Bento 是一种包含所有必需组件的格式。
  • setup-docker.sh:在映像构建过程中安装其他依赖项的脚本。

2.1 service.py

service.py 文件包含两个主要组件 - Tabby 服务器和 BentoML 服务。让我们详细检查每个部分。

TabbyServer 类用于启动 Tabby 服务器,该服务器以模型 ID 和聊天模型 ID 作为参数。它还包括检查其准备就绪状态的方法。我们稍后在定义 BentoML 服务时将使用此类对象。

import subprocess

class TabbyServer:
    def __init__(self, model_id: str, chat_model_id: str) -> None:
		    # Launch the Tabby server as a subprocess with the specified models
        self.launcher = subprocess.Popen(
            [
                "tabby",
                "serve",
                "--model",
                model_id,
                "--chat-model",
                chat_model_id,
                "--device",
                "cuda",
                "--port",
                "8000",
            ]
        )

    def ready(self) -> bool:
        try:
            # Try creating a connection to the Tabby server to check if it's ready
            socket.create_connection(("127.0.0.1", 8000), timeout=1).close()
            return True
        except (socket.timeout, ConnectionRefusedError):
            # If connection fails, check if the subprocess has exited unexpectedly
            retcode = self.launcher.poll()
            if retcode is not None:
                raise RuntimeError(f"launcher exited unexpectedly with code {retcode}")
            return False

    def wait_until_ready(self) -> None:
		    # Continuously check if the server is ready, waiting 1 second between checks
        while not self.ready():
            time.sleep(1.0)

在同一个 service.py 文件中,创建一个包装 Tabby 的 BentoML 服务(称为 Tabby)。 @bentoml.service 装饰器用于将 Python 类标记为 BentoML 服务,在其中,你可以配置 BentoCloud 上使用的 GPU 资源

此外,定义一个代理应用程序以将请求转发到本地 Tabby 服务器。 @bentoml.mount_asgi_app 装饰器将代理安装到 BentoML 服务,使它们能够一起提供服务。

from asgi_proxy import asgi_proxy
import bentoml

# Proxy app to forward requests to the local Tabby server
app = asgi_proxy("http://127.0.0.1:8000")

@bentoml.service(
    resources={"gpu": 1, "gpu_type": "nvidia-l4"},
    traffic={"timeout": 10},
)
@bentoml.mount_asgi_app(app, path="/")
class Tabby:
...

在类中,使用生命周期钩子进行部署和关闭。启动时,BentoML 服务使用 rclone 下载必要的模型目录;关闭时,它会将模型目录上传回 Cloudflare R2。

...
class Tabby:
    @bentoml.on_deployment
    def prepare():
        download_tabby_dir("tabby-local")

    @bentoml.on_shutdown
    def shutdown(self):
        upload_tabby_dir("tabby-local")

    def __init__(self) -> None:
		    # Define model and chat model
        model_id = "StarCoder-1B"
        chat_model_id = "Qwen2-1.5B-Instruct"

        # Start the server subprocess
        self.server = TabbyServer(model_id, chat_model_id)

        # Wait for the server to be ready
        self.server.wait_until_ready()


def download_tabby_dir(username: str) -> None:
    """Download the tabby directory for the given user."""
    if os.system(f"rclone sync r2:/tabby-cloud-managed/users/{username} ~/.tabby") == 0:
        print("Tabby directory downloaded successfully.")
    else:
        raise RuntimeError("Failed to download tabby directory")


def upload_tabby_dir(username: str) -> None:
    """Upload the tabby directory for the given user."""
    if os.system(f"rclone sync --links ~/.tabby r2:/tabby-cloud-managed/users/{username}") == 0:
        print("Tabby directory uploaded successfully.")
    else:
        raise RuntimeError("Failed to upload tabby directory")

在上面的脚本中,我们使用 rclone 将本地目录与 Cloudflare R2 存储桶同步。确保存储桶  tabby-cloud-managed 存在于你的 R2 存储中,并且路径 users/tabby-local 存在于其中。

你可以手动测试 rclone 配置以列出 R2 存储桶中 users/ 下的目录。

rclone lsd r2:tabby-cloud-managed/users/

2.2 setup-docker.sh

部署到 BentoCloud 时,此 BentoML 项目将被容器化为符合 OCI 标准的映像。对于高级自定义,请使用 setup_script 在映像构建过程中注入任何依赖项。在此示例中,脚本安装 Tabby 并下载模型权重。

#!/bin/sh
set -ex

# Install tabby
DISTRO=tabby_x86_64-manylinux2014-cuda117
curl -L https://github.com/TabbyML/tabby/releases/download/v0.14.0/$DISTRO.zip \
  -o $DISTRO.zip
unzip $DISTRO.zip

chmod a+x dist/$DISTRO/*
mv dist/$DISTRO/* /usr/local/bin/
rm $DISTRO.zip
rm -rf dist

# Other dependencies here, such as rclone and katana

# Download model weights under the bentoml user, as BentoCloud operates under this user
su bentoml -c "TABBY_MODEL_CACHE_ROOT=/home/bentoml/tabby-models tabby download --model StarCoder-1B"
su bentoml -c "TABBY_MODEL_CACHE_ROOT=/home/bentoml/tabby-models tabby download --model Qwen2-1.5B-Instruct"
su bentoml -c "TABBY_MODEL_CACHE_ROOT=/home/bentoml/tabby-models tabby download --model Nomic-Embed-Text"

确保 setup-docker.sh 可执行:

chmod +x ./setup-docker.sh

2.3 bentofile.yaml

最后,在 bentofile.yaml 中定义我们的 BentoML 服务的配置。此处的 R2 环境变量对于配置 rclone 以与 Cloudflare R2 配合使用以及确保 Tabby 可以在 R2 中存储和检索信息非常重要。

或者,你可以将所有必需的环境变量放在单独的配置文件中,或使用 --env 标志来设置它们。请参阅 BentoCloud 文档以了解更多信息。

service: 'service:Tabby'
include:
  - '*.py'
python:
  packages:
    - asgi-proxy-lib
docker:
  cuda_version: "11.7.1" # Configures the Docker with CUDA for GPU support
  system_packages:
    - unzip
    - git
    - curl
    - software-properties-common
  setup_script: "./setup-docker.sh" # For any additional Docker configuration
envs:
  - name: RCLONE_CONFIG_R2_TYPE
    value: s3
  - name: RCLONE_CONFIG_R2_ACCESS_KEY_ID
    value: your_r2_access_key_id
  - name: RCLONE_CONFIG_R2_SECRET_ACCESS_KEY
    value: your_r2_access_secret_access_key
  - name: RCLONE_CONFIG_R2_ENDPOINT
    value: your_r2_endpoint_url
  - name: TABBY_MODEL_CACHE_ROOT
    value: /home/bentoml/tabby-models

3、将编码助手部署到 BentoCloud

使用 bentoml deploy 将此项目部署到 BentoCloud 并可选地设置名称。如果还没有帐户,可以免费注册 BentoCloud

# Install bentoml first
pip install bentoml

# Deploy
bentoml deploy . -n tabbly-demo

一旦启动并运行,您就可以在 BentoCloud 上找到其公开的端点 URL。

访问 URL 将引导你进入 Tabby 的主页。首次登录时,你需要创建一个新的 Tabby 帐户。

4、使用编码助手

要使用助手,请在你的 IDE(下图中的 VSC)中安装 Tabby 扩展,然后输入你的端点 URL 和令牌。

尝试自动完成:

你也可以直接在其 Web 控制台上使用 Tabby。例如,添加 BentoML GitHub 存储库并使用 Tabby 解释代码:

在 BentoCloud 控制台上,查看此 AI 编码应用程序的监控指标。

5、结束语

通过将 Tabby 与 BentoCloud 集成,你的开发团队可以从自托管、可扩展的 AI 编码助手中受益,该助手具有自动代码完成和解释等功能。


原文链接:Building An AI Coding Assistant with Tabby and BentoCloud

汇智网翻译整理,转载请标明出处