aifollow.news Search
Back AWS 机器学习博客
AWS 机器学习博客· · Original publication time AI score41

AWS publishes a Ray Train container example for distributed training on EKSMachine translation

AWS 发布 Ray Train 容器在 EKS 上的分布式训练示例

Automatically verified and published · Generated and evidence-checked automatically; not reviewed by a human.

AI-assisted summary

AWS shows how to use its public Ray Train container without building an image to run sharded training of Qwen2.5-1.5B on eight NVIDIA L4 GPUs across two EKS instances. The example uses random training data and costs about $9.50 an hour to run; a real fine-tune requires actual data.

Article · AI translation

通常阻碍 PyTorch 训练扩展到集群的,是容器而不是模型代码。每个容器都需要相同的 CUDA 运行时、针对该运行时编译的 PyTorch 构建版本、NCCL(NVIDIA 集体通信库)、Elastic Fabric Adapter(EFA)用户态库、将 NCCL 连接到 EFA 的 AWS OFI NCCL 插件,以及集群运维方认可的 Ray 版本。构建这个镜像,并在其中任一组件更新时重新构建,本身就是一项工程,而且与您原本要训练的模型无关。Ray Train 深度学习容器(DLC)就是这样一个由 AWS 构建的镜像。AWS 组装整套软件栈,将其作为一个整体进行测试,发布到 Amazon Elastic Container Registry(Amazon ECR)Public,并持续为其打补丁。图 1:一个 EKS 集群,包含由 AWS 托管的控制平面、一个运行 KubeRay operator 和 Ray head 的 CPU 系统节点(m7i.xlarge),以及位于同一可用区的两个启用 EFA 的 g6.12xlarge 节点。KubeRay 根据一份 RayCluster 清单构建集群,Ray Train 部署 8 个工作进程,每个 GPU 1 个,而跨节点的集体通信通过 EFA 进行。Ray 以单个集群的形式在多台机器上运行作业,其中有两种角色。Ray head 负责协调,并运行跟踪集群状态的全局控制存储、控制面板以及供您提交作业的作业服务器。Ray 工作节点提供 GPU 并运行训练进程。每个工作节点启动时通过连接 head 的地址加入集群。在 Kubernetes 上,它们各自都是一个 Pod。Kubernetes 本身没有 Ray 集群的概念,因此需要有组件创建 head 和工作节点 Pod,在各自的 Pod 中以正确的角色启动 Ray,让工作节点连接到 head,并替换故障 Pod。KubeRay 承担这项工作。它是一个开源 Kubernetes operator,添加了 RayCluster 资源:您在一份清单中描述一个 head 组和一个工作节点组,KubeRay 就据此构建并维护集群。无论是由 KubeRay 在 Amazon Elastic Kubernetes Service(Amazon EKS)上启动,还是由您自行在 Amazon Elastic Compute Cloud(Amazon EC2)上启动,同一个带标签的镜像既可运行 Ray head,也可运行 Ray 工作节点。您需要添加的是配置:使用哪些实例、每个 Pod 分配多少个 GPU、NCCL 使用哪种网络传输方式,以及作业需要哪些额外的 Python 软件包。所有这些都在镜像外部设置。本文将介绍一个示例:直接使用发布的 DLC,在两台 g6.12xlarge 实例上的 8 个 NVIDIA L4 GPU 之间,通过 PyTorch Fully Sharded Data Parallel(FSDP)对 Qwen2.5-1.5B 进行微调。训练代码只有一个函数,集群配置是一份 RayCluster 清单加一个变量文件,整个过程无需构建镜像。由于 DLC 已包含 EFA 软件栈,只要 Pod 请求使用 EFA,两台实例之间的集体通信就会通过 EFA 进行。完整解决方案位于这个示例代码仓库,并采用与我们的多节点 Ray Serve 演练相同的 EKS 上 KubeRay 基础架构。无需构建即可获得的内容 Ray Train DLC 是在 PyTorch 训练镜像之上加入 Ray 训练库的镜像。 本示例拉取的镜像标签 public.ecr.aws/deep-learning-containers/ray:train-ml-cuda-v1.1,取代了原本需要自行构建并保持各组件版本匹配的镜像:层级|原本需要构建并保持匹配的内容|Ray Train DLC 中的内容。分布式运行时|Ray、仪表板和作业服务器,版本须受 KubeRay 支持|Ray 2.58.0,包含 Train、Tune 和 Data。框架|针对所用 CUDA 版本编译的 PyTorch|PyTorch 2.13.0、torchvision 0.28.0。GPU 运行时|版本相互兼容的 CUDA、cuDNN 和 NCCL|CUDA 13.0.2、cuDNN、NCCL 2.29.7。网络|针对该 NCCL 版本构建的 EFA 安装程序、libfabric 和 aws-ofi-nccl|最新版 EFA、AWS OFI NCCL 插件、GDRCopy。训练库|针对所用 CUDA 版本编译的 DeepSpeed、flash-attn 和 Transformer Engine|DeepSpeed、flash-attn、Transformer Engine、PyTorch Lightning、Hugging Face 库。诊断工具|从源码构建的 NCCL 测试工具|all_reduce_perf 已在可执行文件搜索路径中。网络这一项是大多数团队最不愿自行维护的。这里的版本不匹配不会产生错误。NCCL 会退回使用 TCP 套接字,作业仍会运行完成,但速度只有原来的一小部分。在 DLC 中,这些库会一起构建和测试;AWS 还以多节点 EFA 和多节点 KubeRay 训练测试作为每次发布的准入条件,而这正是本示例使用的路径。另外几项特性也省去了原本需要为每个集群完成的工作:无需设置镜像仓库——镜像是公开的,因此节点无需凭证即可拉取,过程中也不必构建或推送任何镜像。无需匹配驱动程序——启动时,入口程序会检查主机的 NVIDIA 驱动程序;如果其版本比镜像中的 CUDA 所需版本旧,就会自动启用镜像附带的 CUDA 前向兼容库。无需分别准备头节点和工作节点镜像——镜像没有固定角色。启动容器的一方提供 ray start 命令,因此一个标签适用于所有 Pod。无需单独的推理镜像系列——Ray Train 与 Ray Serve DLC 和 Ray LLM DLC 共用 ray ECR 仓库,使用 train-ml 标签前缀。配置镜像,而非重新构建镜像。不同训练作业之间的所有差异都在镜像外围设置。本示例使用了以下每一种机制:控制内容|设置方式|本示例中的设置。头节点或工作节点角色|按 Pod 组设置的 KubeRay rayStartParams|两者使用相同的 DLC_IMAGE;头节点以 num-gpus: "0" 运行。每个 Pod 的 GPU 和 EFA|Kubernetes 资源请求|nvidia.com/gpu: 4、vpc.amazonaws.com/efa: 1。网络传输|Pod 或作业的环境变量|FI_PROVIDER、NCCL_NET_PLUGIN、NCCL_SOCKET_IFNAME、NCCL_DEBUG。额外的 Python 包|提交作业时设置的 Ray runtime_env|作业所需的任何包,在提交时安装。镜像版本|DLC_IMAGE 中带版本号或固定摘要的标签|train-ml-cuda-v1.1。集群配置|scripts/env.sh 中的变量|实例类型、节点数、每个节点的 GPU 数量、区域、可用区。训练作业|传给 train.py 的参数|模型、训练步数、序列长度、批次大小。每个作业所需的包。镜像已包含 HuggingFace 训练工具栈,因此本示例的作业无需添加任何包。如果某项实验确实需要镜像未包含的库,Ray 会在提交该作业时通过 runtime_env 为其安装,镜像保持不变。无需新镜像,也无需新标签。每个作业的传输配置。镜像默认设置 FI_PROVIDER=efa,其 NCCL 配置会排除回环接口和 Docker 网桥接口。在 EKS 上,需要将 NCCL_SOCKET_IFNAME 指向 Pod 的 eth0。本示例仍在清单中设置了全部 4 个网络变量,使相关行为在一个文件中可见,且不依赖镜像默认值。由于这些只是普通环境变量,单个作业可以通过其 runtime_env 覆盖它们。自行选择版本。本示例固定使用当前次版本 train-ml-cuda-v1.1,因此集群在不同运行之间可以复现。vX.Y 标签会随安全更新而变化。完整的 vX.Y.Z 标签则保持为最初发布时的构建版本,因此需要逐字节一致的运行结果时,应固定镜像摘要。相同的镜像也可通过私有 ECR URI 获取。 集群布局 图 2:本示例的集群。每个 Pod 都运行来自 Amazon ECR Public 的同一个 Ray Train DLC。CPU 系统节点运行 KubeRay operator 和不配备 GPU 的 Ray 头节点。同处一个可用区的每台启用 EFA 的 g6.12xlarge 实例都运行一个使用四块 GPU 的 Ray 工作 Pod。所有节点都位于同一个虚拟私有云(VPC)的私有子网中,只通过 NAT Gateway 访问互联网;每个节点通过它从 Amazon ECR Public 拉取 DLC,工作节点也通过它从 Hugging Face 下载模型权重。一台 m7i.xlarge 构成系统节点组,承载 kube-system 附加组件、KubeRay operator 和 Ray 头节点。头节点在端口 8265 上运行作业服务器,在端口 6379 上运行 Ray 控制存储,并且不声明任何 GPU,因此训练任务不会落到该节点。作业通过 EKS API,使用 kubectl exec 从头节点 Pod 内部提交,因此端口 8265 从不暴露到集群外。训练在两台 g6.12xlarge 实例上运行,每台配有四块 NVIDIA L4 GPU、48 个 vCPU、192 GiB 内存、40 Gbps 网络带宽和一个 EFA 接口。每台实例运行一个占用全部四块 GPU 和 EFA 接口的 Ray 工作 Pod;Ray Train 在每个 Pod 中安排四个工作进程:一个实例上为 rank 0–3,另一个实例上为 rank 4–7。由于 EFA 流量不能跨可用区,脚本将两台实例放在同一个已确认提供 g6.12xlarge 的可用区。Ray Train 在容器内做什么 DLC 提供软件栈。Ray Train 提供原本需要由启动器代码完成的部分。多节点 PyTorch 通常意味着在每台主机的每块 GPU 上启动一个进程,并为每个进程提供其 rank、world size 和 rendezvous 地址。使用 Ray Train 时,你将训练循环写成函数,并连同 ScalingConfig 一起传给 TorchTrainer。Ray 会在集群中有 GPU 的位置为每块 GPU 启动一个工作进程,建立 torch.distributed 进程组,并在每个工作进程上运行你的函数。本示例要求 Ray Train 使用 FSDP,将模型权重、梯度和优化器状态分片到全部八块 GPU 上,而不是在每块 GPU 上各复制一份。Qwen2.5-1.5B 使用 bfloat16 时,这四类张量大约需要 12 GB。分成八份后,每块 L4 GPU 大约持有 1.5 GB。代价是通信:FSDP 在使用每一层的权重前先将其聚合,随后对梯度执行归约散布,因此每一步都会在各个 rank 之间传输整个模型。两台实例之间的这部分流量由 DLC 的 EFA 软件栈承载。先决条件 开始前必须具备以下条件:工具:已登录目标账户的 AWS Command Line Interface(AWS CLI)v2、eksctl、kubectl、Helm,以及 GNU gettext 中的 envsubst。配额:在至少有一个可用区提供 g6.12xlarge 的 AWS 区域中,为两台 g6.12xlarge 实例准备 96 个 G 系列按需容量 vCPU 的配额。如果你已为这些实例持有按需容量预留,则改为设置 CAPACITY_RESERVATION_ID。脚本会将节点组启动到该预留容量中,并跳过容量搜索。预算:GPU 实例运行期间,每小时约 $9.50,涵盖两台实例、EKS 控制平面和 NAT Gateway。快速确认 CLI 是否指向预期账户的方法:aws sts get-caller-identity。训练代码:一个函数和一个训练器 code/train.py 就构成了整个作业,其中没有任何特定于容器、集群或网络的内容。Ray 在每块 GPU 上运行一次 train_func。该函数向 Ray 获取自身的 rank,加载模型,将模型交给 prepare_model 以使用 FSDP,并运行普通的 PyTorch 循环:code/train.py — 每块 GPU 运行的函数(节选)def train_func(config): ctx = ray.train.get_context() world_size, rank = ctx.get_world_size(), ctx.get_world_rank() device = ray.train.torch.get_device() model = AutoModelForCausalLM.from_pretrained(config["model_id"], torch_dtype=torch.bfloat16) # 参数量超过 10M 的任何子模块都会成为独立的 FSDP 单元。按大小而非按特定于模型的层类进行包装,使脚本不依赖于特定模型。 auto_wrap_policy = partial(size_based_auto_wrap_policy, min_num_params=int(1e7)) model = ray.train.torch.prepare_model( model, parallel_strategy="fsdp", parallel_strategy_kwargs={"auto_wrap_policy": auto_wrap_policy}, ) optimizer = torch.optim.AdamW(model.parameters(), lr=config["learning_rate"]) for step in range(config["steps"]): input_ids = torch.randint(0, model.config.vocab_size, (config["batch_size"], config["seq_len"]), device=device) optimizer.zero_grad() loss = model(input_ids=input_ids, labels=input_ids).loss loss.backward() # 再次聚合参数,并对梯度执行归约散发 optimizer.step() # 本地:每个 rank 只更新自己的分片 ray.train.report({"step": step, "loss": loss.item()}) 驱动程序加入正在运行的集群,统计其 GPU 数量并启动训练器。由于工作进程数取自集群,同一脚本无需修改即可在单节点或多节点上运行:code/train.py — 驱动程序(节选) ray.init(address="auto") # 加入 RayCluster num_workers = int(ray.cluster_resources().get("GPU", 0)) # 此处为 8 trainer = TorchTrainer( train_func, train_loop_config={...}, scaling_config=ScalingConfig(num_workers=num_workers, use_gpu=True), run_config=RunConfig(name="ray-train-fsdp-llm"), ) result = trainer.fit() 批次由随机 token ID 组成,因此这次运行除集群外不依赖任何其他东西。该示例的判断标准是:真正的 FSDP 集体通信是否跨越了两个节点,以及作业是否完成。对于实际的微调,可将随机张量替换为 Ray Data 或 DataLoader 流水线。函数中的其他部分均无需更改。清单:DLC 只在 manifest/raycluster.yaml 中配置;这里是镜像与集群的交汇处,而且由于镜像的需求很少,配置文件也很短。头节点唯一的特殊设置是 NVIDIA_VISIBLE_DEVICES=void,它可防止容器运行时的 NVIDIA 钩子在没有 GPU 的节点上失败。工作进程组包含其余所有配置:manifest/raycluster.yaml — 工作进程组(节选) workerGroupSpecs: - groupName: gpu-workers replicas: 2 rayStartParams: num-gpus: "${GPUS_PER_NODE}" # 使 Ray 的 GPU 数量与 pod 的数量一致 template: spec: nodeSelector: { role: gpu-worker } containers: - name: ray-worker image: "${DLC_IMAGE}" # 已发布的 DLC;与头节点使用相同标签 env: - { name: NCCL_DEBUG, value: "INFO" } # 打印选用的传输方式 - { name: NCCL_SOCKET_IFNAME, value: "eth0" } # EKS 上的 pod 网络 - { name: FI_PROVIDER, value: "efa" } # libfabric:仅使用 EFA - { name: NCCL_NET_PLUGIN, value: "ofi" } # 加载 AWS OFI 插件 resources: limits: { nvidia.com/gpu: "${GPUS_PER_NODE}", vpc.amazonaws.com/efa: "1", cpu: "40", memory: 160Gi } requests: { nvidia.com/gpu: "${GPUS_PER_NODE}", vpc.amazonaws.com/efa: "1", cpu: "40", memory: 160Gi } 可以将其理解为 3 项决定。使用什么镜像:头节点和工作进程均使用未经修改的 ${DLC_IMAGE}。使用什么硬件:每个 pod 配备 4 个 GPU 和所在节点的 1 个 EFA 接口。请求 vpc.amazonaws.com/efa 会使 EFA 设备插件将接口挂载到容器中。没有它,NCCL 就无法看到 EFA,并会回退到套接字。使用什么传输方式:通过 4 个环境变量指定,不留给自动检测。另有 2 个较小的细节可保持多节点作业稳定。首先,资源请求应等于限制,这会使工作进程处于 Kubernetes 的 Guaranteed 服务质量(QoS)类别。这很重要,因为只要 1 个 rank 受到限流或被驱逐,其他 7 个就会停滞。其次,num-gpus 与 GPU 请求取自同一个变量,因此 Ray 对容量的判断始终与 Kubernetes 一致。启动:先用 1 条命令部署基础设施,再运行作业。配置集中在 scripts/env.sh 一处:集群名称、区域、Kubernetes 版本、节点类型和数量、镜像、固定版本的 KubeRay 和两个设备插件,以及训练参数。导出其中任意配置项即可针对某次运行更改它。全部 5 个脚本都具有幂等性,可以安全地重复运行。 deploy_cluster.sh、deploy_node_group.sh 和 deploy_ray_train_job.sh 在创建或变更集群资源前都会提示确认。install_gpu_plugins.sh 和 install_kuberay.sh 是协调脚本,会直接运行到底。cd training/ray-train/scripts source ./env.sh ./deploy_all.sh —— 查找实际有容量的位置,然后在那里构建基础设施。g6.12xlarge 的容量每天都会在不同区域和可用区之间变化,因此应从这里开始,而不是预先在 env.sh 中猜定一个区域。它首先运行 find_gpu_capacity.sh,针对每个候选区域检查:各可用区是否提供 g6.12xlarge、账户的按需 G/VT 系列 vCPU 配额是否足以容纳所需节点数,以及作为容量信号的 EC2 Spot 放置分数。使用 --probe 时(deploy_all.sh 默认会传入该参数),它会在每个候选可用区创建真实的容量预留并立即取消,以获得明确答案。随后它显示计划并只询问一次:Proceed with the whole chain without further prompts? (y/N): 回答 y 后,它会在推荐区域依次运行 deploy_cluster.sh、deploy_node_group.sh、install_gpu_plugins.sh 和 install_kuberay.sh;由于此前已经确认,各脚本会跳过各自重复的确认提示(-y 也会跳过此提示,而 --plan 只显示计划,不创建任何资源)。如果 GPU 节点组无法在最佳可用区启动,脚本会将其删除,并尝试探测已确认的下一个可用区。GPU_AZ 还会与集群实际的私有子网交叉核对,而不只依据 g6.12xlarge 的供应位置,因此 GPU 节点组不会被固定在集群没有子网的可用区。选定的区域和可用区会保存到 scripts/.placement.env,其他所有脚本都会读取该文件,因此后续命令无需重新导出任何变量,就会指向同一位置。在全新区域中,这 4 个步骤合计需要 20 到 30 分钟。现有集群或节点组会被检测到并复用。deploy_cluster.sh 会创建 EKS 控制平面、VPC、OpenID Connect(OIDC)提供方、核心附加组件和 m7i.xlarge 系统节点组,并选择实际提供 g6.12xlarge 的可用区中的子网。deploy_node_group.sh 会添加 2 台启用 EFA 的 g6.12xlarge 实例,并为其设置 role=gpu-worker 和 nvidia.com/gpu.present=true 标签。第 2 个标签是团队经常忽略的。缺少它时,NVIDIA 设备插件图表中的 DaemonSet 不会在任何节点上运行,也不会有错误指出原因。install_gpu_plugins.sh 会确保 2 个设备插件都存在。较新版本的 eksctl 会将它们包含在启用 EFA 的节点组中,因此在新集群上,该脚本会找到它们并跳过安装。否则,它会以固定的图表版本安装它们。无论哪种情况,它都会验证每个 GPU 节点上的 nvidia.com/gpu 和 vpc.amazonaws.com/efa 是否可分配,而不是仅凭 Helm 发布成功就认为一切正常。install_kuberay.sh 会将 KubeRay operator 安装在系统节点上,使其不在 GPU 实例上运行。deploy_all.sh 默认不会运行训练作业。这一步保持独立,您可以按需反复运行,因为它是实际的作业运行,而不是基础设施;这样,作业失败也不会让您重新执行集群设置。传入 --train 可将其接入整个流程:./deploy_ray_train_job.sh —— RayCluster、作业及检查。它使用 envsubst 渲染清单并应用。然后,在等待任何 Pod 之前,它会重新读取每个 GPU 节点的可分配资源:如果某个设备插件未能启动,您会在这里收到明确错误,而不是让 Pod 一直处于 Pending 状态直到超时。当 head 处于 Ready 状态且 2 个 worker 都处于 Ready 状态后,它会将 code/ 复制到 head,并通过 kubectl exec 在其中提交:ray job submit --address http://localhost:8265 --working-dir /tmp/ray-train-code \ python3 train.py --model_id Qwen/Qwen2.5-1.5B。该提交调用会持续输出全部 8 个 rank 的日志,并在作业结束时返回。 随后,脚本检查 NCCL 使用了哪种传输方式;如果作业失败,或者传输路径未经过 EFA,脚本就会报错退出,因此也可用作持续集成(CI)的检查关卡。./deploy_ray_train_job.sh status 会打印 RayCluster 状态、每个 Pod 所在的实例以及 GPU 容量。正确配置的集群如下所示:$ kubectl get nodes -l role=gpu-worker \ -o custom-columns='NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu,EFA:.status.allocatable.vpc\.amazonaws\.com/efa' NAME GPU EFA ip-192-168-70-51 4 1 ip-192-168-92-26 4 1 图 3:此集群上的一个 FSDP 步骤。在前向传播和反向传播中聚合权重,并对梯度进行归约分散。实例之间的流量会沿着 DLC 自带的路径传输,即 NCCL → AWS OFI NCCL 插件 → libfabric → EFA;如果该路径不可用,则回退到 TCP 套接字。适配您的工作负载 由于镜像直接使用已发布的版本,而作业会从集群获知其规模,因此大多数更改只涉及一个文件:您想更改的内容 修改位置 无需更改 模型 MODEL_ID 代码、清单、镜像 步数、序列长度、批量大小 STEPS、SEQ_LEN、BATCH_SIZE 代码、清单、镜像 训练循环本身 train_func 的函数体 训练器、清单、镜像、脚本 额外的 Python 软件包 --runtime-env-json 中的 pip 列表 镜像 固定版本的 DLC 发行版 将 DLC_IMAGE 设为带版本号的标签 其他所有内容 GPU 实例系列 GPU_NODE_TYPE、GPUS_PER_NODE 代码、镜像 GPU 实例数量 GPU_NODE_COUNT,以及清单中的 replicas、minReplicas 和 maxReplicas 代码(它会统计 GPU 数量) 区域或可用区 REGION,可选 GPU_AZ 其他所有内容 除非另有说明,表中的变量都位于 env.sh 中。切换实例系列时,GPUS_PER_NODE 必须与硬件相符,而且该系列必须支持 EFA,并且列在 EFA 设备插件允许的实例类型列表中。这里固定的插件版本已知包含 g6.12xlarge。迁移到 p5 或其他支持 GPUDirect 的实例系列,无需更改镜像或训练代码。清理资源 GPU 实例是开销最大的部分,连同控制平面和 NAT Gateway,每小时费用约为 $9.50。按创建时的相反顺序移除资源:./delete_ray_train_job.sh # RayCluster ./install_kuberay.sh cleanup # KubeRay 运算符 ./install_gpu_plugins.sh cleanup # NVIDIA 和 EFA 设备插件 ./delete_node_group.sh # GPU 实例 ./delete_cluster.sh # EKS 集群、VPC 和系统节点 后续步骤 两个实例和八个 GPU 在 EKS 上运行了一次分片微调,使用的是无需自行构建的容器。Ray Train DLC 提供了从 CUDA 到 EFA 的经过测试的软件栈。KubeRay 使用同一个标签将其启动为头节点和工作节点。Ray Train 放置工作进程并组建进程组。从硬件到传输方式再到 Python 软件包,所有可变项都在镜像外部设置。镜像自带的 EFA 路径通过四个环境变量启用,在代码不变的情况下,吞吐量比 TCP 提高了一倍。接下来可以:用真实数据集替换随机批次,并将检查点保存到 Amazon Simple Storage Service(Amazon S3)或 Amazon FSx for Lustre。将 DLC_IMAGE 固定为带版本号的标签,以便实现可复现的运行。启用 FailureConfig,使长时间运行的作业在实例丢失后仍能继续。迁移到 p5 等支持 GPUDirect RDMA 的实例系列,使用更大的模型。镜像和代码保持不变。关于作者 Sunita Koppar Sunita 是 AWS 生成式人工智能和机器学习领域的高级专家解决方案架构师。她与各行各业的客户合作,设计解决方案、构建概念验证,并推动可衡量的业务成果。除了本职工作,她还热衷于学习和教授梵语,积极参与学生社区,帮助他们提升技能并成长。 Kevin Wang Kevin 是 AWS 深度学习容器和 AMI 团队的软件开发工程师,负责构建和维护供客户在亚马逊弹性计算云(Amazon EC2)、Amazon SageMaker AI 和亚马逊弹性 Kubernetes 服务(Amazon EKS)上运行的深度学习镜像。他的团队在 GitHub 上以开源方式管理这些镜像及其构建系统。他拥有北京大学计算机科学学士学位和南加州大学计算机科学硕士学位。Sukhmeet Singh Sukhmeet 是 AWS 生成式人工智能和机器学习领域的高级专家解决方案架构师。他与独立软件供应商(ISV)客户合作,设计人工智能解决方案、构建概念验证,并将其投入生产,以取得可衡量的业务成果。他的兴趣涵盖生成式人工智能、计算机视觉、物联网、机器学习基础设施和自然语言处理。他尤其喜欢将这些领域结合起来,大规模解决现实世界中的问题。

Found an error? Send a correction