介绍如何用Docker在本地快速部署和运行大语言模型,适合离线开发场景。
使用 Docker 在本地运行大型语言模型(LLM)?是的,你没听错。Docker 现在的功能远不止运行容器镜像。通过 Docker Model Runner,你可以在本地运行 LLM 并与之交互。
很明显,我们在开发中看到了向 AI 和生成式 AI 的巨大转变。而开发生成式 AI 驱动的应用程序并不容易,考虑到所有的麻烦——从成本到设置。Docker 一如既往地介入,做它擅长的事:让生成式 AI 开发变得更容易,以便开发者能更快地构建和发布产品和项目。我们可以在本地机器上原生运行 AI 模型!是的,它可以在容器外运行模型。目前,Docker Model Runner 处于测试版,适用于配备 Apple Silicon 的 Mac 上的 Docker Desktop,需要 Docker Desktop 4.40 或更高版本。
在这篇博客中,我们将探讨 Docker Model Runner 的优势以及如何以各种形式使用它。让我们直接开始吧!
开发者流程:作为开发者,我们最不喜欢的一个重要方面是上下文切换和使用 100 种不同的工具,而 Docker 被几乎所有其他开发者使用,使事情变得简单,降低学习曲线。
GPU 加速:Docker Desktop 直接在你的主机上运行 llama.cpp。推理服务器可以访问 Apple 的 Metal API,这允许直接访问 Apple Silicon 上的硬件 GPU 加速。
OCI 制品:将 AI 模型存储为 OCI 制品而不是 Docker 镜像。这节省了磁盘空间,减少了所有内容的提取。此外,这将改进兼容性和适应性,因为它是行业标准格式。
一切本地化:在本地绑定产品时,你不需要面临云 LLM API 密钥、速率限制、延迟等麻烦,也不需要支付那些昂贵的账单。另一个重要方面是数据隐私和安全也随之而来。模型由 llama.cpp 在需要时动态加载到内存中。
确保你的系统上安装了 Docker Desktop v4.40 或更高版本。一旦你有了,请确保通过转到 settings > Features in development 来启用 Docker Model Runner。你也可以勾选 Enable host-side TCP support 以从你的 localhost 通信(我们将在下面看到演示)。
完成后,点击 Apply & restart,我们就全部设置好了。要测试它是否工作,打开任何终端并输入 docker model,你将看到所有可用命令的输出,这验证了一切都如预期那样工作。
所以,要与 LLM 交互,我们现在有两种方法(请继续关注):从 CLI 或 API(OpenAI 兼容)。在 API 方面,CLI 非常直观。我们可以从运行的容器内部或从 localhost 与 API 交互。让我们更详细地看看这些。
如果你曾经使用过 docker cli(几乎每个使用过容器的开发者都用过)并使用过 docker pull、docker run 等命令,docker model 使用相同的模式,只是添加了一个子命令,即 model 关键字,所以要拉取一个模型,我们会执行 docker model pull <model name>,或者运行一个已拉取的模型 docker model run <model name>。这使事情变得非常容易,因为我们不需要为新工具学习全新的措辞。
这是所有当前支持的命令。更多命令即将推出(其中一些也是我的最爱)。敬请期待!
现在,要运行一个模型,我们首先需要拉取它。例如,我们将运行 llama3.2。你可以在 Docker Hub 的 GenAI Catalog 上找到所有可用的模型。所以,打开终端并运行 docker model pull ai/llama3.2。根据模型大小和你的网络带宽,拉取需要一些时间。一旦你拉取了它,运行 docker model run ai/llama3.2,它将启动一个交互式聊天,就像你使用普通聊天机器人或 ChatGPT 一样,完成后,你可以使用 /bye 退出交互式聊天模式。下面是一个截图:
Model Runner 的一个美妙之处是它实现了 OpenAI 兼容的端点。我们可以通过许多方式与 API 交互,比如在运行的容器内部或从主机上使用 TCP 或 Unix 套接字。
我们将看到不同方式的示例,但在此之前,这里是可用的端点。无论我们从容器内部还是从主机与 API 交互,端点都将保持相同。只有主机会改变。
# OpenAI endpoints
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
Note: You can also omit 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 支持,我们不仅仅限于与运行在我们容器内部的应用程序交互,而是可以在任何地方。
这就是这篇博客的全部内容。你可以从官方文档中了解更多关于 Docker Model Runner 的信息。请留意 Docker 的公告;还会有更多内容推出。一如既往,我很高兴你看到了最后——非常感谢你的支持。我定期在 Twitter 上分享技巧(它永远都是 Twitter ;))。你可以在那里与我联系。
对于进一步的行动,你可以考虑屏蔽此人和/或报告滥用。