View a markdown version of this page

使用 kubectl 从本地 NVMe 存储中部署模型 - 亚马逊 SageMaker AI

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 kubectl 从本地 NVMe 存储中部署模型

本主题向您展示如何在亚马逊上部署推理终端节点,这些终端节点 SageMaker HyperPod可以从节点的本地 NVMe 存储中加载模型权重,而不是通过网络从 Amazon S3 或 Amazon FSx 提取模型权重。在本地读取权重可以消除 Pod 启动期间的网络跳跃,从而缩短推理 pod 的冷启动时间,并且对于自动缩放事件、从零扩展的工作负载和对延迟敏感的故障转移非常有用。对于无需考虑冷启动延迟的工作负载,请使用modelSourceType: s3fsx并跳过此主题。

本地 NVMe 是节点本地的,而且是短暂的:更换节点时,例如在现场中断、硬件故障或 AMI 刷新期间,NVMe 上的数据会丢失。本主题中的方法对此的处理方式有所不同 — 有些方法要求您预先填充每个节点,而另一些方法则在模型未在本地缓存时自动回退到 Amazon S3。本地 NVMe 实例存储通常存在于 P、G 和 Trn 实例系列中。请参阅 Amazon EC2 实例存储规格以验证您的实例类型的可用性。

您可以根据自己的存储要求从以下方法中进行选择:

NVMe 部署方法
# 方法 说明
1 Kubernetes 音量(无后备) 当 NVMe 上的每个节点上都存在模型权重时使用。设置最简单,无需亚马逊 S3、亚马逊 FSx 或 InitContainers。 PV/PVC
2 带后备功能的 Kubernetes 音量 当模型可能不存在于每个节点上的 NVMe 上时使用。如果缺少模型initContainer,则可以先检查 NVMe,然后使用 IRSA 凭证从 Amazon S3 下载。
3 具有预取和后备功能的 Amazon S3 当你想将模型权重暂存到 RAM 以启动 pod 时使用。您可以提供一个自定义initContainer,它会先检查 NVMe,如果模型未在本地缓存,则回退到从操作员配置的 Amazon S3 挂载中进行复制。

先决条件

在开始之前,请确认您已经:

选择您的部署方法

使用以下决策流程来确定哪种方法适合您的用例。

┌────────────────────────────┐ │ Want to use a volume of │ │ your choice, e.g. NVMe? │ └─────┬──────────────┬───────┘ YES │ │ NO ▼ ▼ ┌──────────────────────┐ Use S3/FSx/HF │ Are you sure EVERY │ as-is (no volume │ node has the model │ override needed) │ on NVMe? │ └─────┬──────────┬─────┘ YES │ │ NO ▼ ▼ ┌─────────────────┐ ┌───────────────────────────────┐ │ Approach 1 │ │ Do you need the operator to │ │ │ │ create S3/FSx PVCs as a │ │ Use k8sVolume │ │ fallback when the model is │ │ field in CRD to │ │ missing on a node? │ │ read from NVMe │ └──────┬────────────────┬───────┘ │ directly. │ YES │ │ NO └─────────────────┘ ▼ ▼ ┌──────────────────┐ ┌──────────────────────┐ │ Approach 3 │ │ Approach 2 │ │ │ │ │ │ Use S3 with │ │ Use k8sVolume with a │ │ prefetch enabled.│ │ custom initContainer │ │ Custom │ │ you create that │ │ initContainer │ │ checks NVMe first │ │ checks NVMe │ │ and downloads from │ │ first, falls │ │ S3 via IRSA if the │ │ back to S3, and │ │ model is missing. │ │ copies to RAM. │ └──────────────────────┘ └──────────────────┘

使用 Kubernetes 卷进行部署(无后备)

当您在每个节点上的 NVMe 上都有模型权重并且想要最简单的设置时,请使用这种方法 — 没有 Amazon S3 或 Amazon FSx 配置,没有, PV/PVC也没有 initContainers。

设置后modelSourceType: kubernetesVolume,操作员将完全跳过 PV/PVC 创建。不使用 CSI 驱动程序、亚马逊 S3 保险丝支架或亚马逊 FSx 支架。客户提供的model-weights卷直接用于 pod 规范,工作人员从 NVMe 读取模型数据。/opt/ml/model

重要

使用时modelSourceType: kubernetesVolume,操作员会从您的工作器配置modelVolumeMount.name中派生出预期的卷名。 kubernetes.volumes必须包含同名的卷。如果找不到匹配的卷,操作员会对此进行验证,并附带KubernetesVolumeValidationFailed条件拒绝部署。在以下示例中,两者都使用model-weights

  1. 创建 InferenceEndpointConfig YAML 文件。将占位符值替换为您的实际资源标识符。

    cat <<EOF> deploy_nvme_k8s_volume.yaml apiVersion: inference.sagemaker.aws.amazon.com/v1 kind: InferenceEndpointConfig metadata: name: nvme-k8s-volume namespace: default spec: endpointName: nvme-k8s-volume modelName: Qwen2.5-VL-7B-Instruct invocationEndpoint: v1/chat/completions replicas: 1 modelSourceConfig: modelSourceType: kubernetesVolume kubernetes: volumes: - name: model-weights hostPath: path: /opt/dlami/nvme/<YOUR_MODEL> type: Directory loadBalancer: healthCheckPath: /health worker: image: lmcache/vllm-openai:latest args: - /opt/ml/model - --max-model-len - "15000" - --tensor-parallel-size - "1" modelInvocationPort: containerPort: 8000 name: http modelVolumeMount: name: model-weights mountPath: /opt/ml/model resources: limits: nvidia.com/gpu: "1" requests: cpu: "6" memory: 30Gi nvidia.com/gpu: "1" environmentVariables: - name: PYTHONHASHSEED value: "123" - name: VLLM_REQUEST_TIMEOUT value: "600" EOF
  2. 部署InferenceEndpointConfig

    kubectl apply -f deploy_nvme_k8s_volume.yaml
  3. 验证部署状态。

    kubectl describe InferenceEndpointConfig nvme-k8s-volume -n default

使用带后备功能的 Kubernetes 卷进行部署

当模型可能位于也可能不在给定节点上的 NVMe 上时,请使用这种方法。hostPath卷只能在数据存在的节点上起作用——在其他节点上调度的 pod 会挂载一条空路径或不存在的路径,从而导致模型服务器出现故障。

在这种方法中,您可以设置modelSourceType: kubernetesVolume并提供一个自定义,initContainer即首先检查 NVMe,如果模型缺失,则使用 IRSA 凭证从 Amazon S3 下载。

设置 IRSA

在部署之前,请配置服务账户的 IAM 角色 (IRSA),以向您的 pod 提供从 Amazon S3 下载的证书。

  1. 获取您的集群的 OIDC 提供商 ID。

    aws eks describe-cluster --name <CLUSTER_NAME> --region <REGION> \ --query "cluster.identity.oidc.issuer" --output text
  2. 创建 IAM 信任策略。将以下内容另存为trust-policy.json,替换占位符值。

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>:sub": "system:serviceaccount:<NAMESPACE>:<SA_NAME>", "oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>:aud": "sts.amazonaws.com" } } }] }
    警告

    始终将信任策略的范围限定为特定的命名空间和 ServiceAccount 名称。切勿在主题条件中使用通配符(例如system:serviceaccount:*:*),因为这将允许任何命名空间 ServiceAccount 中的任何人代入该角色。

  3. 创建 IAM 角色并为您的模型存储桶附加限定范围的 Amazon S3 读取策略。

    aws iam create-role --role-name <ROLE_NAME> \ --assume-role-policy-document file://trust-policy.json aws iam put-role-policy --role-name <ROLE_NAME> \ --policy-name S3ModelReadAccess \ --policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["s3:GetObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::<YOUR_BUCKET>", "arn:aws:s3:::<YOUR_BUCKET>/<YOUR_MODEL_PREFIX>/*" ] }] }'
  4. 使用 IRSA 注释创建 Kubernetes 服务账户。

    kubectl create sa <SA_NAME> -n <NAMESPACE> kubectl annotate sa <SA_NAME> -n <NAMESPACE> \ eks.amazonaws.com/role-arn=arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>

部署模型

  1. 创建 InferenceEndpointConfig YAML 文件。将占位符值替换为您的实际资源标识符。

    cat <<EOF> deploy_nvme_k8s_volume_fallback.yaml apiVersion: inference.sagemaker.aws.amazon.com/v1 kind: InferenceEndpointConfig metadata: name: nvme-k8s-volume-fallback namespace: default spec: endpointName: nvme-k8s-volume-fallback modelName: Qwen2.5-VL-7B-Instruct invocationEndpoint: v1/chat/completions replicas: 1 modelSourceConfig: modelSourceType: kubernetesVolume kubernetes: serviceAccountName: <YOUR_SERVICE_ACCOUNT> initContainers: - name: smart-loader image: public.ecr.aws/aws-cli/aws-cli:latest command: ["/bin/bash", "-c"] args: - | if [ "$(ls -A /model)" ]; then echo "NVMe hit — model already present ($(du -sh /model | cut -f1))" else echo "NVMe miss — downloading from S3" aws s3 sync s3://<YOUR_BUCKET>/<YOUR_MODEL>/ /model/ fi volumeMounts: - name: model-weights mountPath: /model volumes: - name: model-weights hostPath: path: /opt/dlami/nvme/<YOUR_MODEL> type: DirectoryOrCreate loadBalancer: healthCheckPath: /health worker: image: lmcache/vllm-openai:latest args: - /opt/ml/model - --max-model-len - "15000" - --tensor-parallel-size - "1" modelInvocationPort: containerPort: 8000 name: http modelVolumeMount: name: model-weights mountPath: /opt/ml/model resources: limits: nvidia.com/gpu: "1" requests: cpu: "6" memory: 30Gi nvidia.com/gpu: "1" environmentVariables: - name: PYTHONHASHSEED value: "123" EOF
  2. 部署InferenceEndpointConfig

    kubectl apply -f deploy_nvme_k8s_volume_fallback.yaml
  3. 验证部署状态。

    kubectl describe InferenceEndpointConfig nvme-k8s-volume-fallback -n default

使用带预取和 NVMe 后备功能的 Amazon S3 进行部署

如果您希望通过将模型权重暂存到 RAM 来获得推理性能,请使用此方法;如果模型未在 NVMe 上本地缓存,则可以自动回退到 Amazon S3。

设置为时 modelSourceType: s3prefetchEnabled: true,操作员会自动创建两个卷:

  • 以您的modelVolumeMount.name(通常model-weights)命名的卷 — 包含您的型号的 Amazon S3 CSI 保险丝支架

  • model-weights-copy— a 工作人员 RAM-backedemptyDir从中读取内容

您可以添加一个指向节点本地 NVMe 存储的自定义nvme-cache卷,以及一个自定义卷,initContainer该卷具有以下特征:

  • 如果模型存在于 NVMe 上,则从 NVMe 复制到 RAM (model-weights-copy),则完全跳过网络。

  • 如果模型丢失,则回退到从 Amazon S3 挂载 (model-weights) 复制到 RAM (model-weights-copy)。(可选)复制到 NVMe,以便后续在同一节点上启动的 pod 使用快速本地路径。

重要

使用此方法kubernetes.volumesmodel-weights,请勿重写。操作员创建model-weights指向 Amazon S3 CSI 卷的指向。覆盖它会移除你的 initContainer 进行备用所需的操作员配置的卷。为您的 NVMe HostPath 使用单独的卷名(例如nvme-cache)。

重要

请勿包含model-weights-copykubernetes.volumes。它是操作员自动创建的保留名称。你的 initContainer 可以在中引用它,volumeMounts但不能将其声明为卷。

  1. 创建 InferenceEndpointConfig YAML 文件。将占位符值替换为您的实际资源标识符。

    cat <<EOF> deploy_nvme_s3_prefetch_fallback.yaml apiVersion: inference.sagemaker.aws.amazon.com/v1 kind: InferenceEndpointConfig metadata: name: nvme-s3-prefetch-fallback namespace: default spec: endpointName: nvme-s3-prefetch-fallback modelName: Qwen2.5-VL-7B-Instruct invocationEndpoint: v1/chat/completions replicas: 1 modelSourceConfig: modelSourceType: s3 s3Storage: bucketName: <YOUR_BUCKET> region: <YOUR_REGION> prefetchEnabled: true kubernetes: serviceAccountName: <YOUR_SERVICE_ACCOUNT> initContainers: - name: smart-loader image: public.ecr.aws/aws-cli/aws-cli:latest command: ["/bin/bash", "-c"] args: - | # Check NVMe first, fall back to S3 mount, then copy to RAM if [ "$(ls -A /nvme)" ]; then echo "NVMe hit ($(du -sh /nvme | cut -f1))" echo "Copying model from NVMe to RAM..." cp -r /nvme/* /model/ else echo "NVMe miss — copying from S3 mount to NVMe, then NVMe to RAM" cp -r /s3-model/* /nvme/ cp -r /nvme/* /model/ fi echo "Done. $(du -sh /model | cut -f1) in RAM." volumeMounts: - name: model-weights mountPath: /s3-model - name: nvme-cache mountPath: /nvme - name: model-weights-copy mountPath: /model volumes: - name: nvme-cache hostPath: path: /opt/dlami/nvme/<YOUR_MODEL> type: DirectoryOrCreate loadBalancer: healthCheckPath: /health worker: image: lmcache/vllm-openai:latest args: - /opt/ml/model - --max-model-len - "15000" - --tensor-parallel-size - "1" modelInvocationPort: containerPort: 8000 name: http modelVolumeMount: name: model-weights mountPath: /opt/ml/model resources: limits: nvidia.com/gpu: "1" requests: cpu: "6" memory: 30Gi nvidia.com/gpu: "1" environmentVariables: - name: PYTHONHASHSEED value: "123" - name: VLLM_REQUEST_TIMEOUT value: "600" EOF
  2. 部署InferenceEndpointConfig

    kubectl apply -f deploy_nvme_s3_prefetch_fallback.yaml
  3. 验证部署状态。

    kubectl describe InferenceEndpointConfig nvme-s3-prefetch-fallback -n default

通过预取了解模型权重和模型权重复制

使用预取时,操作员会创建两个与模型相关的卷:

  • 以您的modelVolumeMount.name(通常model-weights)命名的卷 — 包含您的型号的 Amazon S3 CSI 保险丝支架

  • model-weights-copy— 一个 RAM-backed emptyDir,工作人员实际上是从中读取的

在你的InferenceEndpointConfig,你可以定义:

modelVolumeMount: name: model-weights mountPath: /opt/ml/model

当你引用时 model-weightsprefetchEnabled: true,它model-weights-copy实际上是在工作器容器/opt/ml/model中安装的。使用自定义 InitContainer 时,请确保将数据复制到名model-weights-copy为的卷中,这是工作人员期望找到数据的地方。

prefetchEnabled: false,只有一个卷(以你的名字命名modelVolumeMount.name)并且它直接安装在/opt/ml/model

配置自定义服务账号

您可以使用中的字段为推理终端节点 pod 分配自定义 Kubernetes ServiceAccount 。spec.kubernetes.serviceAccountName InferenceEndpointConfig这对于通过 IRSA(服务账户的 IAM 角色)向您的工作容器或初始化容器提供 AWS 证书非常有用,例如,在后备场景中从 Amazon S3 下载模型权重。

重要

默认情况下,自定义服务帐户支持处于禁用状态,并且必须由集群管理员明确启用才能使用。有关说明,请参阅启用自定义服务账号

如果未指定 ServiceAccount,则使用命名空间的 ServiceAccount默认值。

启用自定义服务账号

默认情况下,自定义服务帐户支持处于禁用状态。集群管理员必须先在操作员的 Helm 配置中启用它,然后用户才能 ServiceAccounts 在自己的配置中引用自定义InferenceEndpointConfig

  • 更新运算符 Helm 值以启用该功能。如果您通过 Helm 部署操作员,请使用以下标志进行升级:

    helm upgrade hyperpod-inference-operator <CHART_PATH> \ --set enableCustomServiceAccounts=true \ --reuse-values
  • 如果您将操作员部署为 Amazon EKS 附加组件,请更新插件配置以包含enableCustomServiceAccounts: true在高级配置设置中。

  • 验证操作员 pod 是否设置了环境变量:

    kubectl get deployment hyperpod-inference-operator-controller-manager \ -n hyperpod-inference-system \ -o jsonpath='{.spec.template.spec.containers[0].env}' | jq '.[] | select(.name=="ENABLE_CUSTOM_SERVICE_ACCOUNTS")'

    你应该看到:

    { "name": "ENABLE_CUSTOM_SERVICE_ACCOUNTS", "value": "true" }
重要

如果未启用此功能,则任何指定的InferenceEndpointConfigkubernetes.serviceAccountName内容都将被拒绝,并显示DeploymentFailed状态和消息:kubernetes.serviceAccountName is not enabled. Requires addon configuration (enableCustomServiceAccounts: true)

为服务帐号加标签

集群管理员必须先将其标记为可由用户分配 ServiceAccount,然后才能引用自定义:

kubectl label serviceaccount <your-service-account> \ sagemaker.amazonaws.com/user-assignable=true \ -n <namespace>

只有 ServiceAccounts 带有此标签的推理端点才能引用。这是一种安全控制措施,用于防止未经授权的权限升级。

在您的配置中指定服务帐号

在你的InferenceEndpointConfig:下spec.kubernetes方添加serviceAccountName字段

apiVersion: inference.sagemaker.aws.amazon.com/v1 kind: InferenceEndpointConfig metadata: name: my-inference-endpoint namespace: my-namespace spec: kubernetes: serviceAccountName: my-inference-sa # ... rest of your config

验证规则

操作员在创建和更新操作中验证该serviceAccountName字段。如果满足以下任一条件,您的部署将被拒绝并DeploymentFailed显示状态:

  • 命名空间中 ServiceAccount 不存在 — serviceAccountName "X" not found in namespace "Y"

  • ServiceAccount 缺少所需的标签 — serviceAccountName "X" is not labeled as user-assignable (requires label sagemaker.amazonaws.com/user-assignable=true)

  • ServiceAccount 这是操作员的系统 ServiceAccount —— serviceAccountName must not reference the operator's service account

注意

推理容器中的所有容器(工作容器、初始化容器和边车)都继承指定容器的权限。 ServiceAccount如果标注 ServiceAccount 为eks.amazonaws.com/role-arn,则 Pod 将收到该 IAM 角色的临时 AWS 证书。集群管理员只有在查看关联的 RBAC 角色和 IAM 权限后,才应 ServiceAccounts 将其标记为可由用户分配。

注意

如果在 a 已在运行时被删除, ServiceAccount 则现有 pod 将继续使用其当前凭据运行,直到它们重新启动。InferenceEndpointConfig但是,新 pod 的创建(例如,在缩放或重新调度期间)将失败,因为它们已 ServiceAccount 不存在。操作员会验证部署 ServiceAccount 何时创建以及何时更新 IEC 规范,但不会持续监控。 ServiceAccount删除 SA 后更新 IEC 规范将生成DeploymentFailed状态。

自定义服务帐号的安全最佳实践

当你使用 ServiceAccount 带有推理终端节点的自定义时, HyperPod 推理运算符会代表你创建部署。推理容器中的所有容器(包括工作器、初始化容器和边车)都继承指定容器的权限。 ServiceAccount请遵循以下最佳实践来保护您的集群。

锁定 RBAC 权限

  • ServiceAccount 为每个推理工作负载创建专用。不要在不相关的工作负载 ServiceAccounts 之间重复使用。

  • 仅绑定所需的最低 RBAC 权限。例如,如果您的初始化容器只需要从 Amazon S3 读取,则 ServiceAccount不应有权列出或修改 Kubernetes 资源。

    # Example: minimal Role for an inference workload that only needs S3 access via IRSA # No Kubernetes API permissions needed — IRSA provides AWS credentials directly apiVersion: v1 kind: ServiceAccount metadata: name: my-inference-sa namespace: my-namespace labels: sagemaker.amazonaws.com/user-assignable: "true" annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/<SCOPED_ROLE_NAME>
  • 避免向推理 ServiceAccounts pod 授予集群范围的权限 (ClusterRoleBindings)。

范围 IRSA IAM 角色的范围

  • ServiceAccount 使用注释时eks.amazonaws.com/role-arn,请确保 IAM 角色遵循最低权限原则。

  • 将 Amazon S3 权限范围限定为包含您的模型权重的特定存储桶和前缀。

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["s3:GetObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::<YOUR_BUCKET>", "arn:aws:s3:::<YOUR_BUCKET>/<YOUR_MODEL_PREFIX>/*" ] }] }
  • 不要使用广泛的托管策略,例如AmazonS3FullAccess在生产环境中。使用AmazonS3ReadOnlyAccess或自定义策略范围限于您的模型存储桶。

保护用户可分配的标签

  • 只有集群管理员才能添加或删除sagemaker.amazonaws.com/user-assignable=true标签。使用 Kubernetes RBAC 来限制谁可以修改 ServiceAccount 你的命名空间中的标签。

  • 在将其标记为可由用户分配 ServiceAccount 之前,请查看与关联的 RBAC 角色和 IAM 权限。

  • 定期对带有user-assignable标签的 ServiceAccounts 内容进行审计。

    kubectl get serviceaccounts -n <NAMESPACE> -l sagemaker.amazonaws.com/user-assignable=true
  • 确保非管理员角色在资源上不包含patchupdate、或create动词。 ServiceAccount操作员在部署时验证user-assignable标签,但不会阻止未经授权的用户将标签添加到。 ServiceAccount限制谁可以 ServiceAccounts 通过 RBAC 进行修改是保护此标签的主要控制措施。 Non-admin 用户只能拥有getlist访问:

    # Example: RBAC Role for non-admin users — read-only access to ServiceAccounts apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: sa-read-only namespace: <NAMESPACE> rules: - apiGroups: [""] resources: ["serviceaccounts"] verbs: ["get", "list"]
重要

HyperPod 推理运算符充当中介,代表用户创建部署。与调用者直接创建 Pod 的标准 Kubernetes 工作负载不同,运算符会将指定的 pod 分配 ServiceAccount 给它创建的 Pod。这意味着,任何能够在该命名空间InferenceEndpointConfig中创建的人都可以有效地使用授予用户分配 ServiceAccount 的任何权限。确保命名空间级别的 RBAC 控制谁可以创建和更新资源。InferenceEndpointConfig

将模型权重预加载到 NVMe

如果您需要在部署之前在特定节点上预先填充 NVMe,则可以使用一次性容器从 Amazon S3 进行同步。

注意

这种方法通过定位特定的节点nodeName,不适用于自动缩放。对于自动扩展场景,请使用带后备功能的 Kubernetes 卷或带有预取方法的 Amazon S3,后者通过 initContainer 回退逻辑自动处理丢失的模型。

  1. 创建预加载的 pod YAML 文件。将占位符值替换为您的实际资源标识符。

    cat <<EOF> nvme-s3-copy.yaml apiVersion: v1 kind: Pod metadata: name: nvme-s3-copy namespace: default spec: nodeName: <TARGET_NODE> restartPolicy: Never containers: - name: s3-copy image: public.ecr.aws/aws-cli/aws-cli:latest command: ["/bin/bash", "-c"] args: - | echo "=== Starting S3 sync to NVMe ===" aws s3 sync s3://<YOUR_BUCKET>/<YOUR_MODEL>/ /nvme/<YOUR_MODEL>/ --region <YOUR_REGION> echo "=== Sync complete ===" ls -la /nvme/<YOUR_MODEL>/ du -sh /nvme/<YOUR_MODEL>/ echo "=== Done ===" volumeMounts: - name: nvme-storage mountPath: /nvme serviceAccountName: default volumes: - name: nvme-storage hostPath: path: /opt/dlami/nvme type: Directory EOF
  2. 应用 pod 并监控同步进度。

    kubectl apply -f nvme-s3-copy.yaml kubectl get pod nvme-s3-copy -w kubectl logs nvme-s3-copy -f
  3. 同步完成后清理 pod。

    kubectl delete pod nvme-s3-copy

保留卷名

操作员管理多个无法通过覆盖的内部卷。kubernetes.volumes使用这些名称中的任何一个都会产生KubernetesVolumeValidationFailed条件。

保留卷名
# Name 用途
1 shm 用于进程间通信的共享内存 (/dev/shm)
2 model-weights-copy RAM-backed emptyDir 在以下情况下使用 prefetchEnabled: true
3 parallel-copy-configmap ConfigMap 用于并行复制脚本(预取)
4 lmcache-config lmCache 配置卷
5 gated-model-downloader-configmap ConfigMap 用于门控模型下载脚本

要记住的事情

  • 请勿使用保留的卷名。操作员管理多个内部卷(参见保留卷名)。在中使用这些名称中的任何一个都会kubernetes.volumes产生一个KubernetesVolumeValidationFailed条件。

  • 卷名必须匹配。操作员从中派生出卷名。modelVolumeMount.name使用时modelSourceType: kubernetesVolumekubernetes.volumes必须包含具有相同名称的卷。

  • 将卷装载到 InitContainer 中的正确位置。确保您创建的任何卷都已安装到 initContainer 中的正确路径上。

  • 不需要自定义服务帐户 S3/FSx。如果您无法创建自定义服务帐号或者不想创建自定义服务帐号,则可以使用modelSourceType: s3fsx。操作员会自动 S3/FSx 配置音量。您仍然可以在操作员管理的存储空间之上添加自定义卷initContainers和覆盖卷。

  • IRSA 凭证已注入所有容器。当您设置kubernetes.serviceAccountName带有 IRSA 注释的服务账户时,Amazon EKS 会将 AWS 凭证(aws-iam-token卷、、AWS_WEB_IDENTITY_TOKEN_FILE)注入所有容器AWS_ROLE_ARN,包括您的自定义 initContainers。

  • 使用modelLocation时请勿设置kubernetesVolume音量路径由控制kubernetes.volumes。设置modelLocationmodelSourceType时会kubernetesVolume导致验证错误。

  • 了解 model-weights v model-weights-copy s 是如何使用预取的。何时prefetchEnabled: true,操作员创建两个与模型相关的卷:

    • model-weights— 源音量(来自亚马逊 S3/Amazon FSx PVC 或您的替代卷)

    • model-weights-copy— 一个 RAM-backed emptyDir,工作人员实际上是从中读取的

  • 当你model-weights在配置中引用时prefetchEnabled: true,它实际上model-weights-copy是在工作器容器/opt/ml/model中安装的。使用自定义 InitContainer 时,请确保将数据复制到名model-weights-copy为的卷中,这是工作人员期望找到数据的地方。当prefetchEnabled: false,只有一个卷(以你的名字命名modelVolumeMount.name)并且它直接安装在/opt/ml/model

问题排查

如果部署无法按预期工作,请使用以下调试命令。

  • 检查InferenceEndpointConfig状态以查看高级部署状态和任何配置问题。

    kubectl describe InferenceEndpointConfig <ENDPOINT_NAME> -n <NAMESPACE>
  • 检查 Kubernetes 部署状态。

    kubectl describe deployment <ENDPOINT_NAME> -n <NAMESPACE>
  • 检查命名空间中所有 Kubernetes 对象的状态。

    kubectl get pods,svc,deployment,InferenceEndpointConfig,sagemakerendpointregistration -n <NAMESPACE>
  • 如果模型加载步骤失败,请查看 InitContainer 日志。

    kubectl logs <POD_NAME> -c smart-loader -n <NAMESPACE>
  • 如果部署失败并显示 “未在命名空间中找到”,请验证是否 ServiceAccount 存在:

    kubectl get serviceaccount <name> -n <namespace>
  • 如果部署失败并显示 “未标记为可由用户分配”,请您的集群管理员添加所需的标签:

    kubectl label serviceaccount <name> sagemaker.amazonaws.com/user-assignable=true -n <namespace>
  • 如果部署失败并显示 “不得引用操作员的服务帐户”,请 ServiceAccount 为您的工作负载单独创建一个帐户。你不能使用推理运算符自己的 HyperPod ServiceAccount推理运算符。