使用 Docker 在本地运行大型语言模型(LLMs)?没错,你没听错。Docker 现在不仅仅是运行容器镜像。借助 Docker Model Runner,你可以在本地运行并与 LLMs 进行交互。
我们已经看到,开发方向发生了巨大的转变,越来越多地朝着 AI 和生成 AI(GenAI)发展。而开发一个基于 GenAI 的应用并不容易,考虑到从成本到设置的所有麻烦。正如我们所知,Docker 再次出手,完成它所擅长的事情:让 GenAI 开发变得更加简单,以便开发人员可以更快地构建和交付产品和项目。我们可以在自己的机器上本地运行 AI 模型!没错,它可以在容器外部运行模型。目前,Docker Model Runner 处于测试阶段,适用于 Mac 上具有 Apple Silicon 的 Docker Desktop,需要使用版本 4.40 或更高版本。
在这篇博客中,我们将探讨 Docker Model Runner 的好处以及如何以多种形式使用它。让我们直接进入主题!
Docker Model Runner 的好处
- 开发者流程:作为开发者,我们不喜欢的最重要方面之一就是上下文切换和使用 100 种不同的工具,而 Docker 几乎被所有其他开发者使用,简化了流程,降低了学习曲线;
- GPU 加速:Docker Desktop 可以直接在主机上运行 llama.cpp。推理服务器可以访问 Apple 的 Metal API,从而允许直接访问 Apple Silicon 上的硬件 GPU 加速;
- OCI 存储:将 AI 模型作为 OCI 工件存储,而不是存储为 Docker 镜像。这节省了磁盘空间,减少了提取所有内容的需求。此外,这还将提高兼容性和适应性,因为它是一种行业标准格式;
- 一切本地化:你不必面对 Cloud LLMs API 密钥、速率限制、延迟等麻烦,也不必支付昂贵的费用。同时,数据隐私和安全性也是一个重要方面。在需要时,llama.cpp 会动态加载模型到内存中。
实际操作
确保你的系统中安装了 Docker Desktop v4.40 或更高版本。安装后,确保在设置中启用了 Enable Docker Model Runner(settings > Features in development)。你还可以检查 Enable host-side TCP support,以便从本地主机进行通信(我们将在下面的演示中看到这一点)。
完成后,单击 Apply & restart,我们就准备好了。为了测试它是否正常工作,在任意终端中输入docker model
,你将看到所有可用命令的输出,从而验证一切按预期工作。
要与 LLMs 交互,目前有两种方法(敬请期待),通过 CLI 或 API(兼容 OpenAI)。CLI 相较于 API 的方式更加简单。我们可以通过运行中的容器内部或从本地主机进行 API 交互。让我们对此进行更详细的了解。
从 CLI
如果你使用过 docker cli(几乎每个使用过容器的开发者都使用过),并且使用过像docker pull
、docker run
等命令,docker model 使用相同的模式,只是在其命令中添加了子命令“model”关键字。因此,要拉取一个模型,我们将执行docker model pull <model name>
,或者要运行提取的模型使用docker model run <model name>
。这样更容易,因为我们不必为新工具学习全新的术语。
以下是当前支持的所有命令。更多命令正在到来(其中一些也是我喜欢的)。敬请期待!
现在,要运行一个模型,我们首先需要拉取模型。例如,我们将运行 llama3.2。你可以在 Docker Hub 的 GenAI 目录中找到所有可用模型。打开终端并运行docker model pull ai/llama3.2
。根据模型大小和你的互联网带宽,下载可能需要一些时间。一旦拉取完成,运行docker model run ai/llama3.2
,就会启动一个类似于正常聊天机器人的互动聊天,一旦完成,你可以使用/bye
退出互动聊天模式。
从 API(OpenAI)
Model Runner 的一个令人惊叹的功能是,它实现了与 OpenAI 兼容的端点。我们可以通过许多方式与 API 进行交互,例如在运行中的容器内部或通过 TCP 或 Unix 套接字从主机进行交互。
我们将看到不同方式的示例,这些端点在从容器内部或主机与 API 交互时保持不变,只有主机会改变。以下是可用的端点。
GET /engines/llama.cpp/v1/models
GET /engines/llama.cpp/v1/models/{namespace}/{name}
POST /engines/llama.cpp/v1/chat/completions
POST /engines/llama.cpp/v1/completions
POST /engines/llama.cpp/v1/embeddings
注意:你也可以省略 llama.cpp。
从容器内部
从容器内部,我们将使用http://model-runner.docker.internal
作为基础 URL,并且可以访问上述提到的任何端点。例如,我们将访问/engines/llama.cpp/v1/chat/completions
端点以进行聊天。
我们将使用 curl 命令。你可以看到它使用与 OpenAI API 相同的架构结构。确保你已经拉取了要使用的模型。
curl http://model-runner.docker.internal/engines/llama.cpp/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "ai/llama3.2","messages": [{"role": "system","content": "You are a helpful assistant."},{"role": "user","content": "Please write 100 words about the docker compose."}]
}'
为了测试它在运行容器内部是否有效,我正在以交互模式运行jonlabelle/network-tools
镜像,然后使用上述 curl 命令与 API 进行对话。结果成功了。
可以看到,下面是我收到的响应。响应是 JSON 格式的,包括生成的消息、令牌使用情况、模型细节和响应时间。与标准格式完全相同。
从主机
正如我之前提到的,要与 API 进行交互,你必须确保启用了 TCP。你可以通过访问localhost:12434
来验证它是否工作。你将看到一条消息,表示 Docker Model Runner 正在运行。
在这里,我们将使用http://localhost:12434
作为基础 URL,并遵循相同的端点。curl 命令也是如此;我们只需要替换基础 URL,其他一切保持不变。
curl http://localhost:12434/engines/llama.cpp/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "ai/llama3.2","messages": [{"role": "system","content": "You are a helpful assistant."},{"role": "user","content": "Please write 100 words about the docker compose."}]
}'
让我们尝试在我们的终端运行它。它将返回与另一个类似的 JSON 格式的响应,包括生成的消息、令牌使用情况、模型细节和响应时间。
通过这项 TCP 支持,我们不仅限于与在容器内部运行的应用程序进行交互,还可以与任何地方进行互动。
- 知识星球:云原生AI实战营。10+ 高质量体系课( Go、云原生、AI Infra)、15+ 实战项目,P8 技术专家助你提高技术天花板,冲击百万年薪!
- 公众号:令飞编程,分享 Go、云原生、AI Infra 相关技术。回复「资料」免费下载 Go、云原生、AI 等学习资料;
- 哔哩哔哩:令飞编程 ,分享技术、职场、面经等,并有免费直播课「云原生AI高新就业课」,大厂级项目实战到大厂面试通关;