Kubernetes

在 Azure Kubernetes 上运行 Ollama

本文主要是介绍在 Azure Kubernetes 上运行 Ollama,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Ollama 是一个简化大型语言模型部署和交互的框架,无需复杂的设置。它支持流行模型如 Llama(多个版本)、Mistral 等,所有这些模型均基于变压器架构。Ollama 允许我们运行自己的模型,无需依赖任何第三方模型提供商,因此可以始终保持信息的私密性,并使支出更加可预测和控制。

本文将创建 Azure 资源以在具有 GPU 支持的 Azure Kubernetes 服务管理集群上作为容器化容器运行 Ollama。除了常规的 Kubernetes 部署之外,还需要一些额外的步骤来允许集群将 GPU 识别为可分配资源并将其调度到这些资源。

先决条件:

将使用 Terraform 及其 azurerm 提供程序,因此,我们需要在我们的工作站上安装以下组件。

  • Terraform: 安装指南如下:此处。
  • Azure CLI: 安装指南如下:此处。

此外,由于我们将使用配备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 Pluginhelm chart(https://nvidia.github.io/k8s-device-plugin/nvidia-device-plugin),另一个用于运行由 Outworld 提供的 Ollamahelm 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,从更高级的选项中获得的成本效益就越大。

这篇关于在 Azure Kubernetes 上运行 Ollama的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!