本文介绍如何使用 LLaMA-Factory 和分布式 Ray Train 提交一个 RayJob,在 viggo NLG 数据集上微调 Qwen2.5-7B-Instruct。 该作业使用四个工作器,每个工作器配备一个 GPU,从 Azure Blob 存储 中读取训练数据,并上传训练好的 LoRA 适配器供下游推理使用。
Important
AKS 文档和示例中都提到了开源软件。 您部署的软件被排除在 AKS 服务级别协议、有限保修和 Azure 支持之外。 将开源技术与 AKS 一起使用时,请查阅相应社区和项目维护者提供的支持选项来制定计划。
Microsoft 将负责生成我们在 AKS 上部署的开源包。 该责任包括拥有构建、扫描、签名、验证和快速修复流程的完整所有权,并掌控容器镜像中的二进制文件。 如需了解详细信息,请参阅 AKS 漏洞管理和 AKS 支持范围。
先决条件
- 按照 在 AKS 上为 Ray 和 Kueue 部署基础结构进行部署的基础结构。
- 按照 为 AKS 上的 Ray 工作负载配置 Kueue 队列 中所述配置的 Kueue 队列。
- 集群中至少有四个可用的 A100 GPU(此示例使用四个工作节点,每个节点配备一个 GPU)。
- Viggo 数据集已上传到位于
llm-pipeline/data/的 Blob 存储中(由基础设施 Terraform 模块自动完成)。 -
envsubst已安装(Linux 上为gettext软件包,macOS 上为brew install gettext)。
设置环境变量。
导航到克隆存储库中的 LLM 训练示例并配置所需的环境变量:
cd <path-to-cloned-repo>/AKS/examples/kueue-and-ray-on-aks/3-workloads/llm-training
export AZURE_STORAGE_ACCOUNT_NAME=$(terraform -chdir=../../1-infrastructure/terraform output -raw storage_account_name)
source env.example
注释
如果您配置了团队队列(选项 B),请在运行 export QUEUE_NAME=team-a 之前设置 export QUEUE_NAME=team-b 或 source env.example。 默认值 QUEUE_NAME=default 仅适用于单队列配置(选项 A)。
提交工作负载
提交分布式训练 RayJob:
./submit.sh
该脚本根据训练脚本创建 ConfigMap,通过 envsubst 将清单模板渲染为包含四个 GPU 工作节点的配置,并应用该清单。 当已配置的队列中有四个 GPU 可用时,Kueue 会接受该作业。
Tip
运行 ./submit.sh --dry-run 以验证呈现的清单,而不将其应用到群集。
监视进度
如果你当前处于新的 shell 中,请先查找并导出作业名称:
export JOB_NAME=$(kubectl -n ray get rayjob --no-headers -o custom-columns=":metadata.name" | grep llm-training)
查看 RayJob 状态和 Kueue 准入情况:
kubectl -n ray get rayjob ${JOB_NAME} -w
kubectl -n ray get workload -w
作业完成时的预期输出:
NAME JOB STATUS DEPLOYMENT STATUS START TIME END TIME AGE
llm-training-xxxxxxxxxx SUCCEEDED Complete 2026-01-01T00:00:00Z 2026-01-01T00:19:00Z 19m
NAME QUEUE RESERVED IN ADMITTED FINISHED AGE
rayjob-llm-training-xxxxxxxxxx-xxxxx default cluster-queue True True 19m
查看 head Pod 的日志尾部:
kubectl -n ray logs -f -l ray.io/cluster=$(kubectl -n ray get rayjob ${JOB_NAME} -o jsonpath='{.status.rayClusterName}') -c ray-head
验证结果
检查 LoRA 适配器的上传情况:
az storage blob list -c llm-pipeline --prefix lora/ \
--account-name ${AZURE_STORAGE_ACCOUNT_NAME} --auth-mode login -o table
预期输出:
Name Blob Type Blob Tier Length Content Type
----------------------------------------- ----------- ----------- -------- ------------------------
lora/latest.txt BlockBlob Hot 86 application/octet-stream
lora/<job-name>/rng_state_3.pth BlockBlob Hot 14725 application/octet-stream
验证 latest.txt 指针是否已写入(供批量推理示例自动发现使用):
az storage blob download -c llm-pipeline -n lora/latest.txt \
--account-name ${AZURE_STORAGE_ACCOUNT_NAME} --auth-mode login
预期输出:
azure://llm-pipeline@<storage-account>.blob.core.chinacloudapi.cn/lora/<job-name>
配置参考
| Variable | 默认 | Description |
|---|---|---|
AZURE_STORAGE_ACCOUNT_NAME |
(必填) | 模块 1 中的存储帐户 |
NUM_WORKERS |
4 |
GPU 工作节点副本(4 个副本,每个副本配 1 个 GPU) |
QUEUE_NAME |
default |
Kueue LocalQueue 名称 |
LLM_DATA_CONTAINER |
llm-pipeline |
用于输入数据的 Blob 容器 |
LLM_LORA_CONTAINER |
llm-pipeline |
用于 LoRA 上传的 Blob 容器 |
CONFIGMAP_NAME |
llm-training-scripts |
包含训练脚本的 ConfigMap 的名称 |
清理资源
删除 RayJob 及其 ConfigMap:
kubectl -n ray delete rayjob ${JOB_NAME}
kubectl -n ray delete configmap ${CONFIGMAP_NAME}