如何在 Azure 云上使用 AKS 大规模部署 Riva?
目录

如何在 Azure 云上使用 AKS 大规模部署 Riva?#
这是一个在 Azure 云的 Azure Kubernetes 服务 (AKS) 上部署和扩展 Riva Speech Skills 并使用基于 Traefik 的负载均衡的示例。它包括以下步骤
创建 AKS 集群
部署 Riva API 服务
部署 Traefik 边缘路由器
创建 IngressRoute 以处理传入请求
部署示例客户端
扩展集群
先决条件#
在继续之前,请确保您拥有
创建 AKS 集群#
该集群包含三个独立的节点池
rivaserver
:配备 GPU 的节点,主 Riva 服务在此节点上运行。Standard_NC8as_T4_v3
实例,每个实例使用一个 Tesla T4 GPU,这为许多应用程序提供了良好的价值和足够的容量。loadbalancer
:用于 Traefik 负载均衡器的通用计算节点,使用Standard_D4s_v3
实例。rivaclient
:具有Standard_D8s_v3
实例的通用节点,用于访问 Riva 服务的客户端应用程序。
创建一个 Azure 资源组,因为为 AKS 集群创建的所有资源都将是此资源组的一部分
AKS_RESOURCE_GROUP=riva-resource # Set a unique name for your cluster. AKS_CLUSTER_NAME=riva-aks az group create --name ${AKS_RESOURCE_GROUP} --location eastus
创建 AKS 集群。这将需要一些时间,因为它将在后端旋转节点并设置 Kubernetes 控制平面。
az aks create --resource-group ${AKS_RESOURCE_GROUP} --name ${AKS_CLUSTER_NAME} --node-count 1 --generate-ssh-keys
集群创建完成后,将集群配置拉取到本地计算机,以便
kubectl
可以连接到集群az aks get-credentials --resource-group ${AKS_RESOURCE_GROUP} --name ${AKS_CLUSTER_NAME} --admin
验证您是否可以使用
kubectl
连接到集群。您应该看到节点和 Pod 正在运行。kubectl get nodes kubectl get po -A
为 GPU 工作节点、负载均衡器和客户端创建三个节点池
GPU LINUX 工作节点
az aks nodepool add --name rivaserver --resource-group ${AKS_RESOURCE_GROUP} --cluster-name ${AKS_CLUSTER_NAME} --node-vm-size Standard_NC8as_T4_v3 --node-count 1 --labels role=workers
CPU LINUX 负载均衡器
az aks nodepool add --name loadbalancer --resource-group ${AKS_RESOURCE_GROUP} --cluster-name ${AKS_CLUSTER_NAME} --node-vm-size Standard_D4s_v3 --node-count 1 --labels role=loadbalancers
CPU LINUX 客户端
az aks nodepool add --name rivaclient --resource-group ${AKS_RESOURCE_GROUP} --cluster-name ${AKS_CLUSTER_NAME} --node-vm-size Standard_D8s_v3 --node-count 1 --labels role=clients
验证新添加的节点现在是否出现在 Kubernetes 集群中。
kubectl get nodes --show-labels kubectl get nodes --selector role=workers kubectl get nodes --selector role=clients kubectl get nodes --selector role=loadbalancers
部署 Riva API#
Riva Speech Skills Helm chart 旨在自动化部署到 Kubernetes 集群。下载 Helm chart 后,进行少量调整将使该 chart 适应 Riva 在本教程其余部分中的使用方式。
下载并解压缩 Riva API Helm chart。将
VERSION_TAG
替换为所需的特定版本。export NGC_CLI_API_KEY=<your NGC API key> export VERSION_TAG="2.18.0" helm fetch https://helm.ngc.nvidia.com/nvidia/riva/charts/riva-api-${VERSION_TAG}.tgz --username='$oauthtoken' --password=$NGC_CLI_API_KEY tar -xvzf riva-api-${VERSION_TAG}.tgz
在
riva-api
文件夹中,修改以下文件values.yaml
在
modelRepoGenerator.ngcModelConfigs
中,根据需要注释或取消注释特定模型或语言。将
service.type
从LoadBalancer
更改为ClusterIP
。这会将服务直接仅暴露给集群内的其他服务,例如下面要安装的代理服务。将
persistentVolumeClaim.usePVC
设置为true
,将persistentVolumeClaim.storageClassName
设置为azurefile
,将persistentVolumeClaim.storageAccessMode
设置为ReadWriteOnce
。这会将 Riva 模型存储在已创建的持久卷中。
templates/deployment.yaml
添加节点选择器约束,以确保 Riva 仅部署在正确的 GPU 资源上。在
spec.template.spec
中,添加nodeSelector: kubernetes.azure.com/agentpool: rivaserver
安装 NVIDIA GPU 设备插件。Azure 默认情况下不会安装它。使用以下命令验证安装
helm repo add nvdp https://nvidia.github.io/k8s-device-plugin helm repo update helm install \ --generate-name \ --set failOnInitError=false \ nvdp/nvidia-device-plugin \ --namespace nvidia-device-plugin \ --create-namespace
使用以下任一命令验证 GPU 插件安装
kubectl get pod -A | grep nvidia or kubectl get nodes "-o=custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu"
确保您在工作目录中,其中
riva-api
作为子目录,然后安装 Riva Helm chart。您可以显式覆盖values.yaml
文件中的变量,例如modelRepoGenerator.modelDeployKey
设置。helm install riva-api riva-api/ \ --set ngcCredentials.password=`echo -n $NGC_CLI_API_KEY | base64 -w0` \ --set modelRepoGenerator.modelDeployKey=`echo -n tlt_encode | base64 -w0`
Helm chart 依次运行两个容器:一个
riva-model-init
容器,用于下载和部署模型,然后是一个riva-speech-api
容器,用于启动语音服务 API。根据模型的数量,初始模型部署可能需要一个小时或更长时间。要监视部署,请使用kubectl
描述riva-api
Pod 并观看容器日志。export pod=`kubectl get pods | cut -d " " -f 1 | grep riva-api` kubectl describe pod $pod kubectl logs -f $pod -c riva-model-init kubectl logs -f $pod -c riva-speech-api
部署 Traefik 边缘路由器#
现在 Riva 服务正在运行,集群需要一种机制来将请求路由到 Riva。
在 riva-api
Helm chart 的默认 values.yaml
中,service.type
设置为 LoadBalancer
,这将自动创建一个 Azure 经典负载均衡器,以将流量定向到 Riva 服务。相反,开源 Traefik 边缘路由器将用于此目的。
下载并解压缩 Traefik Helm chart。
helm repo add traefik https://helm.traefik.io/traefik helm repo update helm fetch traefik/traefik tar -zxvf traefik-*.tgz
修改
traefik/values.yaml
文件。将
service.type
从LoadBalancer
更改为ClusterIP
。这会将服务暴露在集群内部 IP 上。将
nodeSelector
设置为{ kubernetes.azure.com/agentpool: loadbalancer}
。与您对 Riva API 服务所做的操作类似,这告诉 Traefik 服务在loadbalancer
节点池上运行。
部署修改后的
traefik
Helm chart。helm install traefik traefik/
创建 IngressRoute#
IngressRoute 使 Traefik 负载均衡器能够识别传入请求并将它们分配到多个 riva-api
服务。
当您在上面部署 traefik
Helm chart 时,Kubernetes 会自动为该服务创建一个本地 DNS 条目:traefik.default.svc.cluster.local
。下面的 IngressRoute 定义与这些 DNS 条目匹配,并将请求定向到 riva-api
服务。您可以根据您的要求修改条目以支持不同的 DNS 安排。
创建以下
riva-ingress.yaml
文件apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: riva-ingressroute spec: entryPoints: - web routes: - match: "Host(`traefik.default.svc.cluster.local`)" kind: Rule services: - name: riva-api port: 50051 scheme: h2c
部署 IngressRoute。
kubectl apply -f riva-ingress.yaml
Riva 服务现在能够通过地址 traefik.default.svc.cluster.local
在集群内提供 gRPC 请求。如果您计划在集群中部署自己的客户端应用程序以与 Riva 通信,则可以将请求发送到该地址。在下一节中,您将部署一个 Riva 示例客户端并使用它来测试部署。
部署示例客户端#
Riva 提供了一个包含一组预构建示例客户端的容器,用于测试 Riva 服务。客户端 也可在 GitHub 上获得,供那些有兴趣调整它们的人使用。
创建
client-deployment.yaml
文件,该文件定义了部署并包含以下内容apiVersion: apps/v1 kind: Deployment metadata: name: riva-client labels: app: "rivaasrclient" spec: replicas: 1 selector: matchLabels: app: "rivaasrclient" template: metadata: labels: app: "rivaasrclient" spec: nodeSelector: kubernetes.azure.com/agentpool: rivaclient imagePullSecrets: - name: imagepullsecret containers: - name: riva-client image: "nvcr.io/{NgcOrg}/{NgcTeam}/riva-speech:2.18.0" command: ["/bin/bash"] args: ["-c", "while true; do sleep 5; done"]
部署客户端服务。
kubectl apply -f client-deployment.yaml
连接到客户端 Pod。
export cpod=`kubectl get pods | cut -d " " -f 1 | grep riva-client` kubectl exec --stdin --tty $cpod /bin/bash
从客户端 Pod 的 shell 内部,在示例
.wav
文件上运行示例 ASR 客户端。将traefik.default.svc.cluster.local
端点指定为服务地址,端口为 80。riva_streaming_asr_client \ --audio_file=wav/en-US_sample.wav \ --automatic_punctuation=true \ --riva_uri=traefik.default.svc.cluster.local:80
扩展集群#
如上所述部署,AKS 集群仅配置单个 GPU 节点,尽管我们可以扩展节点。虽然单个 GPU 可以处理 大量请求,但集群可以轻松地使用更多节点进行扩展。
将 GPU 节点池扩展到所需数量的计算节点(在本例中为 2 个)。
az aks nodepool scale --name rivaserver --resource-group ${AKS_RESOURCE_GROUP} --cluster-name ${AKS_CLUSTER_NAME} --node-count 2
扩展
riva-api
部署以使用其他节点。kubectl scale deployments/riva-api --replicas=2
与原始 riva-api
部署一样,每个副本 Pod 在启动 Riva 服务之前都会下载并初始化必要的模型。