在 Azure Kubernetes 上運行 Ollama
Ollama 是一个简化大型语言模型部署和交互的框架,无需复杂的设置。它支持流行模型如 Llama(多个版本)、Mistral 等,所有这些模型均基于变压器架构。Ollama 允许我们运行自己的模型,无需依赖任何第三方模型提供商,因此可以始终保持信息的私密性,并使支出更加可预测和控制。
本文将创建 Azure 资源以在具有 GPU 支持的 Azure Kubernetes 服务管理集群上作为容器化容器运行 Ollama。除了常规的 Kubernetes 部署之外,还需要一些额外的步骤来允许集群将 GPU 识别为可分配资源并将其调度到这些资源。
先决条件:将使用 Terraform 及其 azurerm
提供程序,因此,我们需要在我们的工作站上安装以下组件。
此外,由于我们将使用配备GPU的虚拟机(例如NCv3
)来创建节点池(node pool),因此需要确保在我们计划使用的区域(例如eastus
)有足够的可用vCPU配额。
一个完整的Terraform脚本示例,该脚本创建一个私有网络,以及一个Azure Kubernetes服务(AKS)集群,并包含一个启用GPU的节点池、启用GPU资源的Nvidia容器以及Ollama容器,可以在以下GitHub仓库中找到,請参见以下GitHub仓库:
GitHub - ItayPodhajcer/terraform-ollama-aks 通过在GitHub上创建账户来参与ItayPodhajcer/terraform-ollama-aks的开发。 脚本为了简洁,我将仅涵盖与启用和稍后安排调度与依赖GPU的工作负载相关的该Terraform脚本部分。
在定义了 Azure Kubernetes 服务资源之后,我们将创建 GPU 节点组。
资源 "azurerm_kubernetes_cluster_node_pool" "this" {
名称 = "gpu"
Kubernetes集群ID = azurerm_kubernetes_cluster.this.id
VM大小 = "Standard_NC6s_v3"
节点计数 = 1
VNet子网ID = var.subnet_id
节点标签 = {
"nvidia.com/gpu.present" = "true"
}
节点污点 = ["sku=gpu:NoSchedule"]
}
注意标签 “nvidia.com/gpu.present” = “true”
,这表示 Nvidia Device Plugin
的 pod 将被调度到该节点,以及 sku=gpu:NoSchedule
的污点标记,这阻止了未明确指定该容忍度的 pod 被调度到该节点(因为我们只希望将需要 GPU 的 pod 调度到该节点)。
接下来,我们创建两个 helm
资源,一个用于运行由 Nvidia 提供的 Nvidia Device Plugin
的 helm
chart(https://nvidia.github.io/k8s-device-plugin/nvidia-device-plugin
),另一个用于运行由 Outworld 提供的 Ollama
的 helm
chart(https://otwld.github.io/ollama-helm/ollama
)。
资源 "helm_release" "nvidia_device_plugin" {
名字 = "nvidia-device-plugin"
仓库 = "https://nvidia.github.io/k8s-device-plugin"
图表名 = "nvidia-device-plugin"
版本 = var.nvidia_device_plugin_chart_version
命名空间 = var.deployment_name
创建命名空间 = true
值列表 = [
"${templatefile("${path.module}/nvidia-device-plugin-values.tpl", {
tag = var.nvidia_device_plugin_tag
})}"
]
}
使用了 nvidia-device-plugin-values.tpl
值模板文件的
image:
tag: "${tag}"
tolerations:
- key: CriticalAddonsOnly
operator: Exists
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
- key: "sku"
operator: Equal
value: gpu
effect: NoSchedule
和
资源 "helm_release" "ollama" {
名字 = local.ollama_service_name
仓库 = "https://otwld.github.io/ollama-helm/"
图表名称 = "ollama"
版本 = var.ollama_chart_version
命名空间 = var.deployment_name
创建命名空间 = true
配置值 = [
"${templatefile("${path.module}/ollama-values.tpl", {
标签 = var.ollama_tag
端口 = var.ollama_port
资源组 = azurerm_resource_group.this.name
IP 地址 = azurerm_public_ip.this.ip_address
DNS 标签名称 = local.ollama_service_name
})}"
]
依赖项 = [helm_release.nvidia_device_plugin]
}
使用 ollama-values.tpl
值模板文件,该文件中的模型为 llama3
,我们将运行此模型。
image:
tag: "${tag}"
ollama:
gpu:
enabled: true
models:
- llama3
service:
type: 负载均衡器
port: ${port}
annotations:
service.beta.kubernetes.io/azure-load-balancer-resource-group: "${resource_group}"
service.beta.kubernetes.io/azure-load-balancer-ipv4: "${ip_address}"
service.beta.kubernetes.io/azure-dns-label-name: "${dns_label_name}"
tolerations:
- key: "sku"
operator: "Equal"
value: "gpu"
effect: "不可调度"
注意以下附加的注释,这些注释将允许自动为该服务创建一个公共主机名,该主机名将基于以下定义的IP地址,以便稍后进行测试。
资源 "azurerm_public_ip" "this" {
名称 = "pip-${local.ollama_service_name}-${var.location}"
location = azurerm_resource_group.this.location
resource_group_name = azurerm_resource_group.this.name
分配方法 = "Static"
sku = "Standard"
生命周期 {
ignore_changes = [
domain_name_label
]
}
}
一旦所有资源定义完毕,我们需要运行 terraform apply
将所有内容部署到 Azure(如果你最近尚未登录,可能需要先运行 az login
命令)。
部署完成后,现在我们可以使用任何支持发送HTTP POST
请求的工具向我们的集群发送请求,例如cUrl
。
curl http://<ollama-service-hostname>:11434/api/generate -d '{
"model": "llama3",
"prompt": "天空为什么是蓝色的?",
"stream": false
}'
并从模型中获取生成的响应,以及生成过程的其他统计信息。
结论部分本文中,我们使用了当时最简单的途径(至少在撰写本文时)在Kubernetes上运行需要GPU的任务。一些其他选项,如Nvidia的GPU Operator和Triton推理服务器,允许更高级的配置和更好地利用GPU资源,可以显著提高使用GPU虚拟机的成本效益,但代价是增加了复杂度。这种权衡取决于系统对AI的依赖程度,也就是说,系统越依赖GPU,从更高级的选项中获得的成本效益就越大。
共同學習,寫下你的評論
評論加載中...
作者其他優質文章