mcpField
A
agent-platform-tuning

agent-platform-tuning

github.com/google云与 DevOps21.6k8.8k 次安装今天更新
代码仓库

关于 agent-platform-tuning

面向使用 Agent Platform 微调开放模型和 Gemini 模型的流程技能,涵盖环境准备、数据集处理、作业配置与部署,并在各阶段设置检查和确认步骤。

主要功能

  1. 01环境与 IAM 检查
  2. 02数据集校验与上传指引
  3. 03模型和位置选择
  4. 04微调作业配置与监控
  5. 05部署流程指引

适用场景

  1. 01为模型微调准备项目
  2. 02校验并上传微调数据集
  3. 03运行和监控微调作业
  4. 04部署微调后的模型

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/google/skills --skill agent-platform-tuning

安装后在 Claude Code 中输入/agent-platform-tuning确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
data_prep.md
hf_datasets.md
models.md
requirements.txt
tuning_guide.md
scripts/
calculate_cost.py
cancel_tuning_job.py
list_models.py
monitor_tuning_job.py
prepare_dataset.py
tune_open_model.py

详细介绍

Agent Platform 模型调优

概述

此技能提供使用 Agent Platform 的调优服务微调大模型(包括开放模型和 Gemini 模型)的流程知识,涵盖从环境设置和数据准备到作业配置、监控和部署的整个生命周期。

工作流决策树

  1. 项目和区域验证检查:用户是否提供了 Google Cloud 项目和区域?

    • 否 → 立即停止工具执行。不要运行验证 命令(gcloud services list、gcloud projects get-iam-policy),不要创建资源,也不要开始准备数据集。提示用户指定或确认项目和区域(例如:“能否请您指定要使用的 Google Cloud 项目和区域?”)。
      • 如果用户只询问如何检查或验证环境是否就绪(API、IAM、服务代理),则只询问项目和区域。不要询问模型类别。
      • 如果用户请求调优工作流,同时未说明要调优开放模型还是 Gemini 模型,你可以一并询问这两个问题。
    • 是 → 继续。
  2. 模型类别识别:用户是否明确说明要调优开放模型还是 Gemini 模型?

    • 否 →
      • 环境验证查询的例外情况: 如果用户只是在询问环境、API、IAM 权限或服务代理是否已准备好进行微调,请勿询问模型类别。获知项目和 区域后,验证环境并确认其已准备就绪。
      • 否则,停止执行工具。询问用户要微调 Open Model 还是 Gemini Model。一般设置和前置条件查询(例如“需要进行哪些环境设置?”): 如果用户询问开始微调所需的环境设置、前置条件、API 或权限,且尚未 选择模型类别:
      • 说明设置要求(API、IAM 权限/服务代理和 Python SDK)。
      • 关于 Cloud Storage:说明数据集和工件需要使用现有的 Cloud Storage 存储桶(例如,gs://<existing-bucket>)。重要: 不要指示用户 创建存储桶,不要在设置说明中输出 gcloud storage buckets create 命令,也不要假设存在一个实际上不存在的存储桶(用户可能没有创建 存储桶的权限,并且会提供自己的现有存储桶)。
      • 必须在回复结尾明确询问用户要微调 Open Model 还是 Gemini Model。 未询问用户选择模型类别前,绝不能提供设置说明。 (注意:如果用户要求主动检查或验证某个项目,但未提供项目 ID 或区域, 请先询问项目和区域,不要运行工具调用。)
    • 如果用户说明了具体的微调目的,应推荐三个模型:一个 Open Model、一个 Gemini Model,以及一个通常推荐的选项。简要列出每个模型的优缺点 (例如,Gemini 模型可能更贵等)。重要: 此步骤必须读取 references/models.md,并且只能推荐该目录中明确列出的模型。绝不能推荐 目录中未列出或不受支持的模型,例如 google/gemma-2-9b-it、gemma-2 或 Mistral。只能推荐受支持的模型,例如 Gemma 3 (google/gemma3@gemma-3-12b-it)、Qwen 3 (qwen/qwen3@qwen3-8b) 或 Llama 3.1 (meta/[email protected])。对于 Gemini 模型,只能推荐 gemini-2.5-flash(适用于一般用途、编码或聊天,推荐使用)或 gemini-2.5-pro。绝不能推荐 gemini-1.5-flash-002、 gemini-1.5-pro-002 或 gemini-1.5-flash,这些模型已弃用,且微调服务 不支持。如果用户指定的模型不在目录中,请遵循该目录中的回退规则。确认 模型类别之前,不要继续进行模型配置。
    • 是 → 继续。
  3. 环境检查:环境(身份验证、API、IAM、虚拟环境)是否已初始化?

  4. 数据集状态:数据集是否已准备为 JSONL 格式,其结构是否符合微调要求, 并且是否已上传到 Google Cloud Storage?

    -   **否** → 转到[阶段 1:数据集准备与上传](#phase-1)。
    -   **是** → 继续。
    
  5. 列选择确认:是否已向用户展示各列并确认映射关系?

    • 否 → 停止。继续之前,必须如阶段 1.0 所述展示样例并获得用户对 列映射的确认。
    • 是 → 继续。
  6. 配置:用户是否已提供目标模型和超参数,或明确同意了你的推荐?

  7. 作业状态:是否已提交微调作业?

    -   **否** → 转到
        [阶段 3:微调作业执行](#phase-3-tuning-job-execution)。
    -   **是** → 继续。
    
  8. 作业完成情况:微调作业是否已完成?

    -   **否** → 转到 [阶段 4:监控](#phase-4-monitoring)。
    -   **是** → 继续。
    
  9. 部署:是否已部署微调后的模型(如有需要)?

    -   **否** → 转到 [阶段 5:模型部署](#phase-5-model-deployment)。
    -   **是** → 任务完成。
    

阶段 0:环境与 IAM 设置 {#phase-0}

继续之前,请确保基础环境已就绪。

0.1 身份验证与项目上下文
  • 检查是否已安装 gcloud CLI。如果尚未安装,请先征求用户许可再进行安装。如果已安装,请更新:
gcloud components update --quiet > /dev/null 2>&1
  • 验证 gcloud auth list。如果尚未通过身份验证,请运行 gcloud auth login。
  • 项目与区域确认:检查用户是否在提示词中指定了 GCP 项目和区域。如果用户的提示词遗漏了项目或区域(例如,在环境验证或设置请求中),你必须立即停止工具执行,不得运行任何 bash 或 gcloud 命令(不要调用 gcloud config get project 或 gcloud services list)。请用户提供项目 ID/编号和区域。
  • 用户提供或确认项目和区域后,验证 gcloud 已通过身份验证,并执行只读检查以验证环境。报告环境就绪情况时,摘要必须明确说明以下三类内容的状态:
    1. 必需的 API:明确报告 aiplatform.googleapis.com(Agent Platform)和 storage.googleapis.com(Cloud Storage)均已启用。
    2. 用户/调用方 IAM 权限:明确确认用户身份或默认计算服务帐号具有 roles/aiplatform.user 和 roles/storage.admin(或 roles/storage.objectAdmin)。
    3. 服务 Agent 与角色:明确报告 Agent Platform 服务 Agent ([email protected])具有 roles/aiplatform.serviceAgent,且微调服务 Agent(service-PROJECT_NUMBER@gcp-sa-vertex-moss-ft.iam.gserviceaccount.com 或 gcp-sa-vertex-tune)具有 roles/aiplatform.tuningServiceAgent。 始终明确说明已验证的项目和区域(例如,project: <PROJECT_NUMBER>, region: us-central1),并明确确认环境已完成配置,可以开始微调。
0.2 位置

位置处理取决于你在工作流决策树中确定的模型类别。这两个类别支持的位置不同,切勿将一个类别的位置用于另一个类别。

  • 开放模型共用一组固定位置,建议选择 global。
  • Gemini 模型因模型而异,必须查询确认。目前不接受 global。

如果用户指定的位置对其模型和类别无效,请停止。回复错误,指出所请求的位置不受支持,并列出有效位置;不要询问数据集,不要继续任何其他设置步骤,也不要悄悄改用其他位置重试。

开放模型(推荐:global)

推荐使用 global,并向用户确认。 将它作为唯一推荐选项提出,而不是先让用户选择区域;也不要引导用户改用特定区域。

开放模型微调仅支持以下位置:

  • global(推荐选项)
  • us-central1
  • europe-west4
  • us-west1
  • us-east5
  • asia-southeast1

global 端点会自动选择有可用容量的受支持区域,因此最有可能成功安排任务。预先固定区域会将任务限制在该区域的容量内,因此开放模型微调推荐使用 global。

  • 用户指定了位置 → 原样使用,只要该位置是 global 或上述列表中的区域即可。不要劝用户改选其他位置。
  • 用户询问支持哪些位置 → 回答这个问题。分享上述列表,并说明推荐使用 global 及其原因。绝不要隐瞒。
  • 用户没有指定位置 → 提出使用 global,并在继续操作前请用户确认。说明 global 会让服务选择有可用容量的区域。不要默默假定使用 global。

提出单一选项的目的是避免让用户必须先做出区域选择,才能继续其他操作——此前正是这种顺序阻碍了用户。这并不意味着要隐瞒列表:用户询问时应列出;拒绝不受支持的位置时也应列出。

仅在以下情况回退到明确指定的区域,并告知用户原因:

  • CMEK。 使用客户管理的加密密钥时,global 会返回 FAILED_PRECONDITION 错误。受 CMEK 保护的任务必须指定存放密钥的区域。

  • 数据驻留。 如果用户要求任务必须留在特定司法管辖区内,请遵循其指定的区域。目前,global 会在 us-central1 或 europe-west4 中运行任务。

如果 global 任务已被接受,但随后因模型不支持全局端点微调而失败,并返回 FAILED_PRECONDITION 错误,则表示该模型尚未接入全局端点。模型本身仍可微调:在上述列表中指定一个明确的区域重新提交(us-central1 是最稳妥的选择),并告知用户切换的原因。

使用 global 任务
  • API 主机仍为 aiplatform.googleapis.com。不存在 global-aiplatform.googleapis.com 主机。
  • 服务会在运行时将 global 解析为实际区域。子资源(微调后的模型、检查点、TensorBoard)返回的资源名称中会包含该实际区域,而不是 global。在用于监控或部署之前,请从返回的资源名称中读取位置;绝不要假定它仍是 global。
  • 配额在各区域之间共享,因此固定区域并不会增加配额。
Gemini 模型(按模型查询)

目前,Gemini 调优不接受 global——服务会在创建作业时拒绝该值,并返回 FAILED_PRECONDITION 错误,因此不要在此处推荐它。

Gemini 没有统一的区域允许列表。 支持的调优区域因模型和模型版本而异:有些 Gemini 模型仅限两个区域,而另一些则支持更多区域。不要重复使用上面的开放模型列表,也不要假设一个 Gemini 模型适用的区域也适用于其他 Gemini 模型。

提交前,请在监督微调文档中查找所选模型,并阅读其**“模型调优支持的端点”**一行: 监督调优

  • 用户询问支持哪些区域 → 查询该具体模型,并告知用户文档中的说明。不要凭记忆回答,也不要参考开放模型列表,更不要针对其他 Gemini 模型作答。
  • 模型对应的行列出了具体区域 → 用户指定的区域必须是其中之一。如果不是,请停止操作,并报告该模型支持的区域。
  • 模型对应的行不存在,或文档表述不清楚 → 询问用户要使用哪个区域,不要猜测。

继续操作前,请向用户确认区域。请注意,有些 Gemini 模型还会限制 CMEK,并且仅在 us 和 eu 多区域端点上提供调优后的模型,因此在作出承诺前,请查看同一张表中的这些限制。

0.3 启用 API

确保已启用 aiplatform.googleapis.com 和 storage.googleapis.com。

gcloud services enable aiplatform.googleapis.com storage.googleapis.com \
    --project=YOUR_PROJECT
0.4 IAM 权限

确认以下身份具有所需角色。

  • Agent Platform 服务代理: [email protected]
  • 托管式 OSS 微调服务代理: service-PROJECT_NUMBER@gcp-sa-vertex-moss-ft.iam.gserviceaccount.com
  • 用户身份:运行命令的账号。
0.5 Python 依赖项

此技能中的脚本会导入 vertexai(来自 google-cloud-aiplatform)、google-genai、google-cloud-storage 和 datasets。

重要的 Agent 指示: 不要创建虚拟环境,也不要在检查前安装任何内容。虚拟环境是空的,会隐藏环境已有的软件包,导致重复安装,耗时数分钟。

请先探测,仅在探测失败时安装:

python3 -c "import vertexai, google.genai, google.cloud.storage, datasets" \
  || pip install -r references/requirements.txt

然后使用普通的 python3 scripts/... 运行所有脚本——不要添加激活前缀。

references/requirements.txt 中固定的版本适用于环境尚未提供这些 SDK 的情况。不要在可正常使用的环境中应用这些版本:它们会降级其他工具可能共用的软件包。

阶段 1:数据集准备与上传 {#phase-1}

1.0 数据集发现与确认
  • 验证用户提供的数据集: 如果用户在提示词中指定了数据集文件名 或路径,请验证其是否存在于工作区中 (例如,通过执行脚本或检查是否存在拼写错误)。

    • 如果在任何位置都找不到该文件,你必须告知用户 数据集文件不存在或无法访问。你必须 提示用户提供有效的数据集路径。或者,如果 搜索期间在工作区中找到候选数据集文件,你必须向用户 列出候选文件并请其选择一个。报告文件缺失或列出候选文件后, 必须立即停止执行工具,并等待用户回复。 不要询问是否允许进行 90/10 验证集划分,也不要 在收到用户选择的有效数据集文件之前尝试上传数据集。
    • 如果已找到并验证该文件,请继续执行下方的步骤 1.1「格式化与 验证」。
  • 自动发现:从用户存储桶中查找: 如果用户没有数据集, 且 Hugging Face 参考资料中没有合适的替代数据集,请提出搜索用户 GCS 存储桶以查找潜在训练数据。优先搜索扩展名为 .jsonl、.json、.csv 和 .parquet 等的文件。如果找到此类 文件,请读取每个文件的前几行或记录,以判断其中是否包含适合微调的文本数据 (例如,提示词/补全内容对),这些数据是否可以修改为符合 数据准备指南,且是否与用户请求的微调任务相关。 请勿在事先征求同意前进行搜索。

  • 自动发现:根据任务从 Hugging Face 查找: 如果用户有具体任务 (例如数学推理、编码、指令遵循),或想使用 Hugging Face 数据集但 未指定具体数据集,请参考 Huggingface 数据集参考,并推荐匹配的数据集 (例如,用于数学推理的 open-r1/OpenR1-Math-220k 或 AI-MO/NuminaMath-TIR;openai/gsm8k 也广泛使用)。对于每个推荐的 数据集,请提供一些相关信息和合理的数据划分选项,并请用户选择一个。 不要输出泛泛的指示,让用户自行准备并上传数据——应主动引导用户完成交互式数据集发现、 预览和准备流程。

    重要

    关键:征求确认并选择列。 选定 数据集后,通过 run_command 执行 Python,使用 load_dataset(..., streaming=True) 检查数据集。在完成以下步骤并获得用户确认之前, 不得开始准备或上传数据集:1. 确认数据集和划分: 向用户展示 数据集和可用划分,并请用户确认要使用哪一个。2. 选择列(Hugging Face 或自定义数据集): 你 必须:- 列出所选数据集划分中的所有可用列。- 展示数据集中的几个样本,帮助用户 了解内容并选择列。- 建议哪些列应映射到 prompt(或用户消息)和 completion(或助手回复);如适用,提供几个合理选项。- 请用户确认 列映射,或指定要使用哪些列。

1.1 格式化与验证
  • 转换:如果数据采用 CSV、JSON 或 Parquet 格式,请使用 scripts/prepare_dataset.py 进行转换。
  • 确认验证集划分:每当生成或准备单个数据集且未明确提供验证集时(包括生成示例聊天/指令数据集或准备训练数据集),都必须通过 run_command 使用 Python 生成或处理数据,并且必须询问用户是否同意将训练数据集按 90/10 划分,以形成验证集(使用 --validation_split 0.1 或 Python 脚本)。如果用户同意,则进行划分;如果用户拒绝,则仅使用训练数据集,不使用验证集。不要提供 80/20 划分选项;调优服务会拒绝此划分,原因见 数据准备指南。 在询问用户是否同意按 90/10 划分验证集之前,不要上传数据集或提交调优任务!
  • 验证:如果数据已经采用 JSONL 格式,请在上传前进行验证。仅有 .jsonl 扩展名并不足以证明格式有效。必须确认内容架构符合调优要求(例如,system/user/model 角色正确)。
python3 scripts/prepare_dataset.py \
    --input my_data.jsonl \
    --format <messages|messages_gemini> \
    --validate_only

(开放模型使用 --format messages,Gemini 模型使用 --format messages_gemini。) - 如需了解必需的架构,请参阅数据准备指南。

1.2 上传

将格式化后的 .jsonl 文件上传到 GCS,并使用唯一目录(例如带日期时间戳的目录),以避免覆盖不同运行的输出。如果用户指定了存储桶(例如 gs://mybucket),请严格按照用户提供的名称使用该存储桶,绝不添加项目 ID 前缀或修改存储桶名称。

ARTIFACTS="gs://YOUR_BUCKET/tuning_agent_job_<datetime>/dataset.jsonl"
gcloud storage cp dataset.jsonl "$ARTIFACTS"

第 2 阶段:模型配置与推荐 {#phase-2}

帮助用户选择最佳模型和参数。提交任务前务必征求用户确认。

  • 如果用户的提示词中未指定具体模型,请根据模型目录计算推荐结果。
  • 征求确认:向用户展示推荐的模型,并在配置超参数前征求其确认。
2.1 配置
开放模型
  • 根据调优指南和模型目录中的特定模型基线,推荐 tuning_mode、epochs、learning_rate 和 adapter_size。
验证当前模型 ID

提交任务前,运行 scripts/list_models.py,并且仅从其 models 输出中选择 --base_model。不要编造 ID 或版本号。

python3 scripts/list_models.py --project YOUR_PROJECT --filter gemini

输出:{"models": [...], "total_count": N, "truncated": bool}。

  • 对于 Gemini,请去掉 google/ 和 @default(例如 google/gemini-2.5-flash@default → gemini-2.5-flash);对于开放模型,请原样传入 publisher/family@version。
  • 跳过以 -embedding、-tts、-image、-computer-use 或 -native-audio 结尾的 Gemini 变体;这些模型无法调优。
  • 如果 truncated 为 true,请使用更严格的 --filter(例如 gemini-2.5)重新运行,然后再判断目标版本是否不可用。
  • 如果 models 为空,请停止并询问用户。
2.2 计算费用(仅限开放模型)

警告

关键:始终使用 run_command 和 scripts/calculate_cost.py 请勿调用 estimate_cost ADK 工具来进行模型调优。estimate_cost 工具仅支持特定端点的服务定价,用于调优请求时会因 Unsupported request type 而失败。你必须调用 run_command 工具来执行 Python 代码或 scripts/calculate_cost.py(或 /workspace/skills/agent-platform-tuning/scripts/calculate_cost.py)来计算费用。每当选择模型或用户切换模型(例如从 Llama 切换到 Gemma)时,你都必须调用 run_command 计算或重新计算费用,然后才能显示试运行确认提示。请务必在试运行确认提示中报告计算出的金额(例如,Estimated tuning cost: $X.XX)。

  • 我们根据数据集和 模型目录 中选定的模型,计算预计调优费用:

    python3 scripts/calculate_cost.py \
        --input my_data.jsonl \
        --model MODEL_NAME \
        --tuning_mode TUNING_MODE \
        --epochs epochs
    

    --model 可使用显示名称(Qwen 3 8B)或传递给 --base_model 的同一资源名称(qwen/qwen3@qwen3-8b),因此可以直接复用步骤 2.1 中选定的值。

说明

处理数据集缺失错误:如果 scripts/calculate_cost.py 因找不到数据集文件(例如 my_data.jsonl 或 dummy_data.jsonl)而失败,你必须告知用户该数据集文件不存在或无法访问。你必须提示用户提供有效的数据集路径,并立即停止工具执行,等待用户回复。请勿重试或循环执行,请勿编造具体费用,也请勿在收到用户提供的有效数据集之前提示用户批准提交作业。

  • **请求确认:**向用户展示推荐的超参数配置和预计费用(使用上文计算出的具体金额),并在继续提交作业前征求用户批准。请务必说明预计费用仅为估算值,可能与实际账单费用不同。

第 3 阶段:调优作业执行 {#phase-3-tuning-job-execution}

关键预检(GCS 验证):在提出确认提示或提交任何调优作业之前,你必须验证指定的训练数据集 GCS URI(例如 gs://dummy_bucket/dataset.jsonl 或 gs://YOUR_BUCKET/...)确实存在且可访问。运行 gcloud storage ls $DATASET_URI(或 gsutil ls)。

  • 如果验证失败(例如出现 BucketNotFound、404、AccessDenied,或表明存储桶是虚构的/不存在),你必须告知用户该 GCS 存储桶或数据集不存在或无法访问。你必须提示用户提供有效的数据集 GCS URI,并立即停止工具执行,等待用户回复。在收到用户提供的有效数据集 URI 之前,请勿提出确认提示,也请勿执行任何调优脚本。
  • 如果验证成功,请继续提出下方的确认提示。
Gemini 模型

使用 Python SDK(google.genai 或 vertexai.tuning.sft)提交 Gemini 监督式微调作业:

from google import genai
from google.genai import types

client = genai.Client(enterprise=True, project=PROJECT, location=LOCATION)
tuning_job = client.tunings.tune(
    base_model=BASE_MODEL,  # e.g. "gemini-2.5-flash"
    training_dataset=types.TuningDataset(gcs_uri=TRAIN_DATASET_URI),
    config=types.CreateTuningJobConfig(
        epoch_count=EPOCHS,  # e.g. 3
        learning_rate_multiplier=LEARNING_RATE_MULTIPLIER,  # e.g. 1.0
        validation_dataset=(
            types.TuningValidationDataset(gcs_uri=VAL_DATASET_URI)
            if VAL_DATASET_URI
            else None
        ),
    ),
)
print("Tuning Job Resource Name:", tuning_job.name)

也可以使用 vertexai.tuning.sft:

import vertexai
from vertexai.tuning import sft

vertexai.init(project=PROJECT, location=LOCATION)
job = sft.train(
    source_model=BASE_MODEL,
    train_dataset=TRAIN_DATASET_URI,
    validation_dataset=VAL_DATASET_URI,
    epochs=EPOCHS,
    learning_rate_multiplier=LEARNING_RATE_MULTIPLIER,
)
print("Tuning Job Resource Name:", job.resource_name)

通过 python3 执行 Python 脚本(内联执行或写入 /tmp/submit_gemini_tuning.py)。报告返回的操作名称或可跟踪的资源标识符,不要等待终端状态。

对于开放模型

使用 scripts/tune_open_model.py 或 Python SDK 提交开放模型调优任务。通过可用模型文档识别模型 ID,参见 文档。

--base_model 接受发布方模型资源名称 ({publisher}/{model_id}@{version_id}),而不是目录中显示的名称。有关格式、已验证示例,以及如何查询未知名称,请参阅 references/models.md 中的“模型资源名称格式”。

使用 scripts/tune_open_model.py:

python3 scripts/tune_open_model.py \
    --project YOUR_PROJECT \
    --location global \
    --base_model BASE_MODEL_ID \
    --train_dataset gs://YOUR_BUCKET/tuning_agent_job_<datetime>/dataset.jsonl \
    --output_uri gs://YOUR_BUCKET/tuning_agent_job_<datetime>/output \
    --epochs EPOCHS \
    --learning_rate LR \
    --tuning_mode MODE

(如果当前工作目录中没有 scripts/tune_open_model.py,请直接使用 python3 -c "..." 运行 Python SDK 代码片段,或使用 client.tunings.tune 将其写入 /tmp/submit_open_tuning.py。)

此脚本仅适用于开放模型;如果省略 --location,则会回退到 global。务必显式传入用户在第 0.2 节确认的位置,以便该位置显示在提交审批的命令字符串中。

警告

开放模型必须提供 --output_uri。 Python SDK 将其声明为 output_uri: Optional[str] = None,但如果开放模型任务未提供该参数,调优后端会拒绝任务,并返回 INVALID_ARGUMENT: The output_uri field is required for this model.。此处 SDK 的“可选”签名有误,务必提供 GCS 目标位置。

由于此标志是必需的,因此提交前必须确定调优后的模型要写入的位置。**绝不能凭空编造存储桶名称、根据项目编号推导名称,或在未询问的情况下运行 gcloud storage buckets create。**创建存储桶属于变更操作,受下文 Tier M 确认政策约束。

  • 用户指定了存储桶或 URI → 按用户指定的内容原样使用,并按照第 1.2 节追加唯一的任务专属目录。 **重要:**绝不能更改、添加前缀或在用户指定的存储桶名称前添加项目编号或其他内容!即使 gcloud storage buckets list 显示已有一个带项目编号前缀的存储桶(例如,用户要求 gs://mybucket,但已有 gs://PROJECT-mybucket),也必须原样使用用户指定的存储桶名称 gs://mybucket。绝不能悄悄替换为现有存储桶。
  • 第 1.2 节上传数据集时已使用存储桶 → 提议将其用于输出,并请用户确认。
  • 以上情况都不符合,或用户表示没有存储桶 → 检查项目中的现有存储桶(gcloud storage buckets list --project=PROJECT),或提出创建专用存储桶。提议创建存储桶时,须在名称中加入唯一后缀或时间戳(例如,gs://PROJECT-tuning-$(date +%s) 或 gs://PROJECT-tuning-artifacts-<timestamp>,位于 LOCATION 中),以避免与先前创建的存储桶发生 HTTP 409 冲突。在配置试运行预览中提出目标存储桶,并在继续前征求用户确认。

重要

**必须进行交互式确认(Tier M):**提交任务前,必须向用户展示拟执行的命令字符串,其中包含所有字面值标志,并提供“Yes”和“No”选项供用户确认。

重要:向用户展示此确认提示时,必须直接输出纯文本回复,并立即停止工具执行。同一轮中不得调用任何命令执行或交互式工具,因为意外的工具调用可能会被模拟环境自动回复,导致无限循环。立即等待用户回复。

阶段 4:监控 {#phase-4-monitoring}

通过脚本输出中提供的 Cloud Console 链接监控作业。 --location 为必填项,且必须与提交时使用的位置相同:在 global 提交的开放模型作业,要使用 --location global 进行轮询,即使实际运行是在后台的某个真实区域。

此外,询问用户是否希望你在后台为其监控作业状态。如果用户同意,则将 scripts/monitor_tuning_job.py 作为后台任务执行,定期轮询作业状态并通知用户查看状态。如果用户拒绝,则完全由用户自行查看状态。

阶段 5:模型部署 {#phase-5-model-deployment}

调优作业的状态变为 SUCCEEDED 后,使用基础模型的服务容器将调优后的检查点注册到 Model Registry,然后将注册的模型部署到新的端点。

部署需要使用真实区域,global 在此处无效。如果作业在 global 上运行,请从调优模型的资源名称(projects/.../locations/<REGION>/models/...)中读取区域并在该区域部署;不要猜测。

如果部署步骤因配额问题被拒绝,请逐字报告 API 的错误信息。

#!/bin/bash
# Deploy a tuned checkpoint by registering it in Model Registry with the base
# model's serving container, then deploying to a new endpoint. All four gcloud
# calls hit aiplatform.googleapis.com.
set -euo pipefail
PROJECT_ID="YOUR_PROJECT"
LOCATION_ID="YOUR_LOCATION"          # e.g. us-central1; NOT global.
BASE_MODEL="<PUBLISHER>/<FAMILY>@<VERSION-ID>"   # the base model you tuned; e.g. google/gemma3@gemma-3-4b-it
ARTIFACTS="gs://YOUR_BUCKET/tuning_agent_job_<datetime>/output/postprocess/node-0/checkpoints/final"
DISPLAY_NAME="my-tuned-model"
# Explicit IDs, so no step can pick up an older model or endpoint that shares
# the display name.
RUN_ID="tuned-$(date +%Y%m%d-%H%M%S)"

# 1. List the base model's verified deployment configs and pick the row that
#    fits the user-approved cost/perf. CONFIG_INDEX is its 0-based table row.
gcloud ai model-garden models list-deployment-config \
    --model="$BASE_MODEL" \
    --project="$PROJECT_ID"
CONFIG_INDEX="<pick from step 1>"

# Turn that row into gcloud flags files. The table shows only the image, but
# the container also needs the row's args, env, ports and routes; its
# --model/--model-path arg points at the base weights and is repointed at
# $ARTIFACTS.
gcloud ai model-garden models list-deployment-config \
    --model="$BASE_MODEL" \
    --project="$PROJECT_ID" \
    --format=json | python3 -c '
import json, sys
idx, artifacts = int(sys.argv[1]), sys.argv[2]
cfg = json.load(sys.stdin)[idx]
spec = dict(cfg["containerSpec"])
args, repointed = [], 0
for a in spec.pop("args", []):
    flag = a.split("=", 1)[0]
    if flag in ("--model", "--model-path"):
        a, repointed = flag + "=" + artifacts, repointed + 1
    args.append(a)
if repointed != 1:
    sys.exit("expected exactly one --model/--model-path arg, found %d" % repointed)
upload = {"--container-image-uri": spec.pop("imageUri"), "--container-args": args}
if "command" in spec:
    upload["--container-command"] = spec.pop("command")
if "env" in spec:
    upload["--container-env-vars"] = {e["name"]: e["value"] for e in spec.pop("env")}
if "ports" in spec:
    upload["--container-ports"] = [str(p["containerPort"]) for p in spec.pop("ports")]
for key, flag in (("predictRoute", "--container-predict-route"),
                  ("healthRoute", "--container-health-route"),
                  ("sharedMemorySizeMb", "--container-shared-memory-size-mb")):
    if key in spec:
        upload[flag] = str(spec.pop(key))
if "deploymentTimeout" in spec:  # e.g. "7200s"
    upload["--container-deployment-timeout-seconds"] = str(
        int(float(spec.pop("deploymentTimeout").rstrip("s"))))
if spec:
    sys.exit("unhandled containerSpec fields: %s" % sorted(spec))
m = cfg["dedicatedResources"]["machineSpec"]
deploy = {"--machine-type": m["machineType"]}
if "acceleratorType" in m:
    deploy["--accelerator"] = {
        "type": m["acceleratorType"].lower().replace("_", "-"),
        "count": str(m.get("acceleratorCount", 1))}
json.dump(upload, open("/tmp/upload_flags.yaml", "w"), indent=1)
json.dump(deploy, open("/tmp/deploy_flags.yaml", "w"), indent=1)
' "$CONFIG_INDEX" "$ARTIFACTS"
cat /tmp/upload_flags.yaml /tmp/deploy_flags.yaml

# 2. Register the tuned checkpoint in Model Registry with the base model's
#    serving container. Blocks until the upload finishes.
gcloud ai models upload \
    --project="$PROJECT_ID" \
    --region="$LOCATION_ID" \
    --model-id="$RUN_ID" \
    --display-name="$DISPLAY_NAME" \
    --artifact-uri="$ARTIFACTS" \
    --flags-file=/tmp/upload_flags.yaml

# 3. Create a dedicated endpoint.
gcloud ai endpoints create \
    --project="$PROJECT_ID" \
    --region="$LOCATION_ID" \
    --endpoint-id="$RUN_ID" \
    --display-name="$DISPLAY_NAME"

# 4. Deploy the registered model to the endpoint.
gcloud ai endpoints deploy-model "$RUN_ID" \
    --project="$PROJECT_ID" \
    --region="$LOCATION_ID" \
    --model="$RUN_ID" \
    --display-name="$DISPLAY_NAME" \
    --flags-file=/tmp/deploy_flags.yaml

set -e 会在第一个步骤失败时停止整个流程。第 4 步会一直阻塞,直到模型开始提供服务,这可能需要 20 分钟或更久;其进度输出会显示操作名称 projects/<PROJECT>/locations/<REGION>/operations/<OP_ID>。在另一个 shell 中检查状态时,将完整名称传给 gcloud ai operations describe <OPERATION_NAME>:只有当 gcloud 已设置项目时,单独使用 <OP_ID> 才有效。

重要

需要交互式确认(Tier M): 继续部署之前,你必须在确认提示中向用户展示三条写入命令(第 2 至 4 步),填入所有字面值,并附上生成的标志文件(容器映像、参数、机器类型、加速器配置),同时提供“Yes”和“No”选项。

关键: 向用户显示此确认提示时,必须直接以纯文本回复的形式输出,并立即停止工具执行。同一轮中不得调用任何命令执行工具或交互式工具,因为意外的工具调用可能会被模拟框架自动回复并导致无限循环。立即等待用户回复。

有关特定开放模型的硬件建议,请参阅 Models Catalog。

资源

评论

支持 Markdown