在多主機 A4 GKE 叢集上微調 Gemma 3

本教學課程會說明如何在 Google Cloud的多主機 GKE Autopilot 叢集上,微調 Gemma 3 大型語言模型 (LLM)。這個叢集使用兩個 A4 虛擬機器 (VM) 執行個體,總共配備 16 個 NVIDIA B200 GPU。

本教學課程說明的兩個主要程序如下:

  1. 使用 GKE Autopilot 部署高效能多主機 GKE 叢集。在此部署作業中,您會建立已預先安裝必要軟體的自訂 VM 映像檔。
  2. 叢集部署完成後,您可以使用本教學課程隨附的指令碼集,執行分散式微調工作。這項工作會運用 Hugging Face Accelerate 程式庫

本教學課程適用於機器學習 (ML) 工程師、研究人員、平台管理員和營運人員,以及有興趣在 Google Cloud 部署 GKE 叢集來訓練大型語言模型的資料和 AI 專家。

目標

  • 使用 Hugging Face 存取 Gemma 3 模型。

  • 準備環境。

  • 建立及部署 A4 GKE 叢集。

  • 使用 Hugging Face Accelerate 程式庫和完全分片的資料平行 (FSDP),微調 Gemma 3 模型。

  • 監控工作。

  • 清除所用資源。

費用

在本文件中,您會使用下列 Google Cloud的計費元件:

如要根據預測用量估算費用,請使用 Pricing Calculator

初次使用 Google Cloud 的使用者可能符合免費試用期資格。

事前準備

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  2. 安裝 Google Cloud CLI。

  3. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  4. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  5. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您在專案中獲派角色,即可選取該專案。
    • 建立專案:如要建立專案,您需要「專案建立者」角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  6. 確認專案已啟用計費功能 Google Cloud

  7. 啟用必要的 API:

    啟用 API 時所需的角色

    如要啟用 API,您必須具備 serviceusage.services.enable 權限。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

    gcloud services enable compute.googleapis.com container.googleapis.com file.googleapis.com logging.googleapis.com cloudresourcemanager.googleapis.com servicenetworking.googleapis.com
  8. 安裝 Google Cloud CLI。

  9. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  10. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  11. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您在專案中獲派角色,即可選取該專案。
    • 建立專案:如要建立專案,您需要「專案建立者」角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  12. 確認專案已啟用計費功能 Google Cloud

  13. 啟用必要的 API:

    啟用 API 時所需的角色

    如要啟用 API,您必須具備 serviceusage.services.enable 權限。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

    gcloud services enable compute.googleapis.com container.googleapis.com file.googleapis.com logging.googleapis.com cloudresourcemanager.googleapis.com servicenetworking.googleapis.com
  14. 將角色授予使用者帳戶。針對下列每個 IAM 角色,執行一次下列指令: roles/compute.admin, roles/iam.serviceAccountUser, roles/cloudbuild.builds.editor, roles/artifactregistry.admin, roles/storage.admin, roles/serviceusage.serviceUsageAdmin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    更改下列內容:

    • PROJECT_ID:專案 ID。
    • USER_IDENTIFIER:使用者帳戶的 ID。 例如:myemail@example.com
    • ROLE:授予使用者帳戶的 IAM 角色。
  15. 為 Google Cloud 專案啟用預設服務帳戶:
      export PROJECT_NUMBER="$(gcloud projects describe "PROJECT_ID" --format "value(project_number)")"
      gcloud iam service-accounts enable "${PROJECT_NUMBER}-compute@developer.gserviceaccount.com \
        --project=PROJECT_ID
  16. 將編輯者角色 (roles/editor) 授予預設服務帳戶:
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
        --role=roles/editor
  17. 為使用者帳戶建立本機驗證憑證:
    gcloud auth application-default login
  18. 為專案啟用 OS 登入功能:
    gcloud compute project-info add-metadata --metadata=enable-oslogin=TRUE
  19. 登入或建立 Hugging Face 帳戶

使用 Hugging Face 存取 Gemma 3

如要使用 Hugging Face 存取 Gemma 3,請按照下列步驟操作:

  1. 登入 Hugging Face
  2. 建立 Hugging Face write 存取權杖
    依序點按「你的個人資料」>「設定」>「存取權杖」>「+ 建立新權杖」
  3. 複製並儲存 write access 權杖值。本教學課程稍後會用到這項資訊。

準備環境

如要準備環境,請設定下列項目:

export PROJECT_ID="YOUR_PROJECT_ID"
export CLUSTER_NAME="YOUR_CLUSTER_NAME"
export CLUSTER_REGION="YOUR_CLUSTER_REGION"
export RESERVATION="YOUR_RESERVATION_NAME"
export HF_TOKEN="YOUR_HUGGING_FACE_TOKEN"
export ARTIFACT_REPO_LOCATION="YOUR_ARTIFACT_REGISTRY_LOCATION"
export NUM_NODES="YOUR_NUMBER_OF_NODES"
export NETWORK="default"

gcloud config set project "${PROJECT_ID}"
gcloud config set billing/quota_project "${PROJECT_ID}"

更改下列內容:

  • PROJECT_ID:要在其中建立 GKE 叢集的 Google Cloud 專案名稱。

  • CLUSTER_NAME:要建立的 GKE 叢集名稱。

  • CLUSTER_REGION:要建立 GKE 叢集的區域。您只能在預訂項目所在的區域建立叢集。

  • RESERVATION:預留容量的 ID。

  • HF_TOKEN:您在上一個部分中建立的 Hugging Face 存取權杖。

  • ARTIFACT_REPO_LOCATION:要建立 Artifact Registry 存放區的位置。

  • NUM_NODES:您希望 GKE 叢集擁有的節點數量。

  • NETWORK:要使用的網路。

在 Autopilot 模式中建立多主機 GKE 叢集

在 Autopilot 模式中建立多主機 GKE 叢集:

gcloud container clusters create-auto "${CLUSTER_NAME}" \
    --project="${PROJECT_ID}" \
    --location="${CLUSTER_REGION}" \
    --release-channel=rapid

建立 GKE 叢集可能需要一段時間才能完成。如要確認 Google Cloud 已完成叢集建立作業,請前往 Google Cloud 控制台的「Kubernetes clusters」(Kubernetes 叢集) 頁面。

取得 GKE 叢集的憑證

執行下列指令,設定 kubectl 與新建立的 GKE 叢集通訊:

gcloud container clusters get-credentials "${CLUSTER_NAME}" \
    --location="${CLUSTER_REGION}"

建立 Hugging Face 憑證的 Kubernetes Secret

如要為 Hugging Face 憑證建立 Kubernetes Secret,請按照下列步驟操作:

  1. 設定 kubectl,與 GKE 叢集通訊:

    gcloud container clusters get-credentials "${CLUSTER_NAME}" \
        --location="${CLUSTER_REGION}"
  2. 建立 Kubernetes 密鑰,儲存 Hugging Face 權杖:

    kubectl create secret generic hf-secret \
        --from-literal=hf_api_token="${HF_TOKEN}" \
        --dry-run=client -o yaml | kubectl apply -f -

準備工作負載

如要準備工作負載,請執行下列操作:

  1. 建立工作負載指令碼

  2. 使用 Docker 和 Cloud Build 建立微調容器

建立工作負載指令碼

如要建立微調工作負載使用的指令碼,請按照下列步驟操作:

  1. 建立工作負載指令碼的目錄。使用這個目錄做為工作目錄。

    mkdir llm-finetuning-gemma
    cd llm-finetuning-gemma
  2. 建立 cloudbuild.yaml 檔案,以便使用 Google Cloud Build。這個檔案會建立工作負載容器,並儲存在 Artifact Registry 中:

    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: [ 'build', '-t', '$_ARTIFACT_REPO_LOCATION-docker.pkg.dev/$PROJECT_ID/gemma/finetune-gemma-multihost-gpu:1.0.0', '.' ]
    images:
    - '$_ARTIFACT_REPO_LOCATION-docker.pkg.dev/$PROJECT_ID/gemma/finetune-gemma-multihost-gpu:1.0.0'
  3. 建立 Dockerfile 檔案來定義環境,並安裝完成微調作業所需的依附元件:

    FROM nvidia/cuda:12.8.1-cudnn-devel-ubuntu24.04
    RUN apt-get update && \
        apt-get -y install python3 python3-dev gcc python3-pip python3-venv git curl vim
    RUN python3 -m venv /opt/venv
    ENV PATH="/opt/venv/bin:/usr/local/nvidia/bin:$PATH"
    ENV LD_LIBRARY_PATH="/usr/local/nvidia/lib64:$LD_LIBRARY_PATH"
    RUN pip3 install setuptools wheel packaging ninja
    RUN pip3 install torch torchvision torchaudio  --index-url https://download.pytorch.org/whl/cu128
    
    RUN pip3 install \
        transformers==4.53.3 \
        datasets==4.0.0 \
        accelerate==1.9.0 \
        evaluate==0.4.5 \
        bitsandbytes==0.46.1 \
        trl==0.19.1 \
        peft==0.16.0 \
        tensorboard==2.20.0 \
        protobuf==6.31.1 \
        sentencepiece==0.2.0
    COPY finetune.py /finetune.py
    COPY accel_fsdp_gemma3_config.yaml /accel_fsdp_gemma3_config.yaml
    CMD accelerate launch --config_file accel_fsdp_gemma3_config.yaml finetune.py
  4. 建立 accel_fsdp_gemma3_config.yaml 檔案。這個設定檔會指示 Hugging Face Accelerate 將微調工作分散到多個 GPU。

    compute_environment: LOCAL_MACHINE
    debug: false
    distributed_type: FSDP
    downcast_bf16: 'no'
    enable_cpu_affinity: false
    fsdp_config:
      fsdp_activation_checkpointing: false
      fsdp_auto_wrap_policy: TRANSFORMER_BASED_WRAP
      fsdp_cpu_ram_efficient_loading: true
      fsdp_offload_params: false
      fsdp_reshard_after_forward: true
      fsdp_state_dict_type: FULL_STATE_DICT
      fsdp_transformer_layer_cls_to_wrap: Gemma3DecoderLayer
      fsdp_version: 2
    machine_rank: 0
    main_training_function: main
    mixed_precision: bf16
    num_machines: 2
    num_processes: 16
    rdzv_backend: static
    same_network: true
    tpu_env: []
    tpu_use_cluster: false
    tpu_use_sudo: false
    use_cpu: false
  5. 建立 finetune.yaml 檔案:

    apiVersion: resource.k8s.io/v1
    kind: ResourceClaimTemplate
    metadata:
      name: mrdma
    spec:
      spec:
        devices:
          requests:
          - name: mrdma
            exactly:
              deviceClassName: mrdma.google.com
    ---
    apiVersion: jobset.x-k8s.io/v1alpha2
    kind: JobSet
    metadata:
      name: finetune-jobset
      namespace: default
    spec:
      failurePolicy:
        maxRestarts: 2
      replicatedJobs:
      - name: workers
        replicas: 1
        template:
          spec:
            parallelism: ${NUM_NODES}
            completions: ${NUM_NODES}
            backoffLimit: 0
            template:
              metadata:
                annotations:
                  kubectl.kubernetes.io/default-container: finetuner
              spec:
                terminationGracePeriodSeconds: 600
                restartPolicy: OnFailure
                nodeSelector:
                  cloud.google.com/compute-class: "Accelerator"
                  cloud.google.com/gke-accelerator: "nvidia-b200"
                  cloud.google.com/reservation-name: ${RESERVATION}
                  cloud.google.com/reservation-affinity: "specific"
                  cloud.google.com/gke-gpu-driver-version: latest
                containers:
                - name: finetuner
                  image: $IMAGE_URL
                  command: ["bash", "-c"]
                  args:
                  - |
                    NUM_PROCESSES=$(( ${NUM_NODES} * 8 ))
                    accelerate launch \
                      --config_file accel_fsdp_gemma3_config.yaml \
                      --num_machines ${NUM_NODES} \
                      --num_processes ${NUM_PROCESSES} \
                      --machine_rank ${JOB_COMPLETION_INDEX} \
                      --main_process_ip finetune-jobset-workers-0-0.finetune-jobset.default.svc.cluster.local \
                      --main_process_port 29500 \
                      finetune.py \
                      --model_id google/gemma-3-12b-pt \
                      --output_dir gemma-12b-text-to-sql \
                      --per_device_train_batch_size 8 \
                      --gradient_accumulation_steps 8 \
                      --num_train_epochs 3 \
                      --learning_rate 1e-5 \
                      --save_strategy steps \
                      --save_steps 100
                  resources:
                    limits:
                      nvidia.com/gpu: "8"
                  env:
                  - name: HF_TOKEN
                    valueFrom:
                      secretKeyRef:
                        name: hf-secret
                        key: hf_api_token
                  - name: NUM_NODES
                    value: "${NUM_NODES}"
                  volumeMounts:
                  - mountPath: /dev/shm
                    name: dshm
                volumes:
                - name: dshm
                  emptyDir:
                    medium: Memory
  6. 建立 finetune.py 檔案:

    import torch
    import argparse
    import subprocess
    from datasets import load_dataset
    from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig, AutoConfig
    from peft import LoraConfig, prepare_model_for_kbit_training, get_peft_model
    from trl import SFTTrainer, SFTConfig
    from huggingface_hub import login
    
    def get_args():
        def str2bool(v):
            if isinstance(v, bool):
                return v
            return v.lower() in ("yes", "true", "t", "1")
    
        parser = argparse.ArgumentParser()
        parser.add_argument("--model_id", type=str, default="google/gemma-3-12b-pt", help="Hugging Face model ID")
        parser.add_argument("--hf_token", type=str, default=None, help="Hugging Face token for private models")
        parser.add_argument("--trust_remote", type=str2bool, default=False, help="Trust remote code when loading tokenizer")
        parser.add_argument("--use_fast", type=str2bool, default=True, help="Determines if a fast Rust-based tokenizer should be used")
        parser.add_argument("--dataset_name", type=str, default="philschmid/gretel-synthetic-text-to-sql", help="Hugging Face dataset name")
        parser.add_argument("--output_dir", type=str, default="gemma-12b-text-to-sql", help="Directory to save model checkpoints")
    
        # LoRA arguments
        parser.add_argument("--lora_r", type=int, default=16, help="LoRA attention dimension")
        parser.add_argument("--lora_alpha", type=int, default=16, help="LoRA alpha scaling factor")
        parser.add_argument("--lora_dropout", type=float, default=0.05, help="LoRA dropout probability")
        # SFTConfig arguments
        parser.add_argument("--max_seq_length", type=int, default=512, help="Maximum sequence length")
        parser.add_argument("--num_train_epochs", type=int, default=3, help="Number of training epochs")
        parser.add_argument("--per_device_train_batch_size", type=int, default=8, help="Batch size per device during training")
        parser.add_argument("--gradient_accumulation_steps", type=int, default=1, help="Gradient accumulation steps")
        parser.add_argument("--learning_rate", type=float, default=1e-5, help="Learning rate")
        parser.add_argument("--logging_steps", type=int, default=10, help="Log every X steps")
        parser.add_argument("--save_strategy", type=str, default="steps", help="Checkpoint save strategy")
        parser.add_argument("--save_steps", type=int, default=100, help="Save checkpoint every X steps")
        parser.add_argument("--push_to_hub", action='store_true', help="Push model back up to HF")
        parser.add_argument("--hub_private_repo", type=str2bool, default=True, help="Push to a private repo")
        return parser.parse_args()
    
    def main():
        args = get_args()
        # --- 1. Setup and Login ---
        if args.hf_token:
            login(args.hf_token)
        # --- 2. Create and prepare the fine-tuning dataset ---
        dataset = load_dataset(args.dataset_name, split="train")
        dataset = dataset.shuffle().select(range(12500))
        dataset = dataset.train_test_split(test_size=2500/12500)
        # --- 3. Configure Model and Tokenizer ---
        if torch.cuda.is_available() and torch.cuda.get_device_capability()[0] >= 8:
            torch_dtype_obj = torch.bfloat16
            torch_dtype_str = "bfloat16"
        else:
            torch_dtype_obj = torch.float16
            torch_dtype_str = "float16"
        tokenizer = AutoTokenizer.from_pretrained(args.model_id, trust_remote_code=args.trust_remote, use_fast=args.use_fast)
        tokenizer.pad_token = tokenizer.eos_token
        gemma_chat_template = (
            "{{ bos_token }}"
            "{% if messages[0]['role'] == 'system' %}{{ messages[0]['content'] }}{% endif %}"
            "{% for message in messages %}"
            "{% if message['role'] == 'user' %}<start_of_turn>user\n{{ message['content'] }}<end_of_turn>\n{% elif message['role'] == 'assistant' %}<start_of_turn>model\n{{ message['content'] }}<end_of_turn>\n{% endif %}"
            "{% endfor %}"
        )
        tokenizer.chat_template = gemma_chat_template
        # --- 4. Define the Formatting Function ---
        def formatting_func(example):
            system_message = "You are a text to SQL query translator. Users will ask you questions in English and you will generate a SQL query based on the provided SCHEMA."
            user_prompt = "Given the <USER_QUERY> and the <SCHEMA>, generate the corresponding SQL command to retrieve the desired data, considering the query's syntax, semantics, and schema constraints.\n\n<SCHEMA>\n{context}\n</SCHEMA>\n\n<USER_QUERY>\n{question}\n</USER_QUERY>\n"
    
            messages = [
                {"role": "user", "content": user_prompt.format(question=example["sql_prompt"], context=example["sql_context"])},
                {"role": "assistant", "content": example["sql"]}
            ]
            return tokenizer.apply_chat_template(messages, tokenize=False)
        # --- 5. Load Model and Apply PEFT ---
        config = AutoConfig.from_pretrained(args.model_id)
        config.use_cache = False
        print("Loading base model...")
        model = AutoModelForCausalLM.from_pretrained(
            args.model_id,
            config=config,
            attn_implementation="eager",
            torch_dtype=torch_dtype_obj,
        )
    
        model = prepare_model_for_kbit_training(model)
        peft_config = LoraConfig(
            lora_alpha=args.lora_alpha,
            lora_dropout=args.lora_dropout,
            r=args.lora_r,
            bias="none",
            target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],
            task_type="CAUSAL_LM",
        )
        print("Applying PEFT configuration...")
        model = get_peft_model(model, peft_config)
        model.print_trainable_parameters()
        # --- 6. Configure Training Arguments ---
        training_args = SFTConfig(
            output_dir=args.output_dir,
            max_seq_length=args.max_seq_length,
            num_train_epochs=args.num_train_epochs,
            per_device_train_batch_size=args.per_device_train_batch_size,
            gradient_accumulation_steps=args.gradient_accumulation_steps,
            learning_rate=args.learning_rate,
            logging_steps=args.logging_steps,
            save_strategy=args.save_strategy,
            save_steps=args.save_steps,
            packing=False,
            gradient_checkpointing=True,
            gradient_checkpointing_kwargs={"use_reentrant": False},
            optim="adamw_torch",
            fp16=True if torch_dtype_obj == torch.float16 else False,
            bf16=True if torch_dtype_obj == torch.bfloat16 else False,
            max_grad_norm=0.3,
            warmup_ratio=0.03,
            lr_scheduler_type="constant",
            push_to_hub=args.push_to_hub,
            hub_private_repo=args.hub_private_repo,
            report_to="tensorboard",
            dataset_kwargs={
                "add_special_tokens": False,
                "append_concat_token": True,
            }
        )
        # --- 7. Create Trainer and Start Training ---
        trainer = SFTTrainer(
            model=model,
            args=training_args,
            train_dataset=dataset["train"],
            eval_dataset=dataset["test"],
            formatting_func=formatting_func,
        )
        print("Starting training...")
        trainer.train()
        print("Training finished.")
        # --- 8. Save the final model ---
        print(f"Saving final model to {args.output_dir}")
        trainer.save_model(args.output_dir)
        if torch.distributed.is_initialized():
            torch.distributed.destroy_process_group()
    
    if __name__ == "__main__":
        main()

使用 Docker 和 Cloud Build 建立微調容器

  1. 建立 Artifact Registry Docker 存放區:

    gcloud artifacts repositories create gemma \
        --repository-format=docker \
        --location="${ARTIFACT_REPO_LOCATION}" \
        --description="Repository for Gemma fine tuning workload containers" || true
  2. 安裝 JobSet 自訂資源定義 (CRD),以便協調多主機工作負載。

    kubectl apply --server-side -f https://github.com/kubernetes-sigs/jobset/releases/download/v0.12.0/manifests.yaml

    JobSet 是 Kubernetes 擴充功能,可用於管理相關工作群組。如要進一步瞭解 JobSet,請參閱外部的 JobSet 說明文件

  3. 在您於先前步驟中建立的 llm-finetuning-gemma 目錄中,執行下列指令來建立微調映像檔,並將其推送至 Artifact Registry。

    gcloud builds submit . --substitutions=_ARTIFACT_REPO_LOCATION="${ARTIFACT_REPO_LOCATION}"
  4. 匯出圖片網址。您會在後續步驟中使用這項資訊:

    export IMAGE_URL="${ARTIFACT_REPO_LOCATION}-docker.pkg.dev/${PROJECT_ID}/gemma/finetune-gemma-gpu:1.0.0"

啟動微調工作負載

如要啟動微調工作負載,請執行下列步驟:

  1. 套用微調資訊清單,建立微調作業:

    envsubst '${RESERVATION} ${IMAGE_URL} ${NUM_NODES}' < finetune.yaml | kubectl apply -f -

    由於您在 GKE Autopilot 模式中使用叢集,因此啟用 GPU 的節點可能需要幾分鐘才能啟動。

  2. 執行下列指令來監控作業:

    watch kubectl get pods
  3. 執行下列指令,檢查主要工作站 Pod 的記錄:

    kubectl logs -l "job-name=finetune-jobset-workers-0" -f

    工作資源會下載模型資料,然後在所有八個 GPU 中微調模型。下載作業大約需要五分鐘才會完成。 下載完成後,微調程序約需 2 小時 30 分鐘才能完成。

監控工作負載

您可以監控 GKE 叢集中的 GPU 使用情形,確認微調作業是否有效率地執行。如要這麼做,請在瀏覽器中開啟下列連結:

echo "https://console.cloud.google.com/kubernetes/clusters/details/${CLUSTER_REGION}/${CLUSTER_NAME}/observability?mods=monitoring_api_prod&project=${PROJECT_ID}&pageState=("timeRange":("duration":"PT1H"),"nav":("section":"gpu"),"groupBy":("groupByType":"namespacesTop5"))"

監控工作負載時,您可以查看下列資訊:

  • GPU 使用量:如果微調工作運作正常,您應該會看到所有 8 個 GPU 的使用量在訓練期間上升並穩定維持在高檔。
  • 工作時間:這項工作大約需要 10 分鐘,才能在指定的 A4 叢集上完成。

清除所用資源

為避免因為本教學課程所用資源,導致系統向 Google Cloud 帳戶收取費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。

刪除資源

  1. 如要刪除 JobSet,請執行下列指令:

    kubectl delete jobset finetune-jobset
  2. 如要刪除 GKE 叢集,請執行下列指令:

    gcloud container clusters delete "${CLUSTER_NAME}" \
        --region="${CLUSTER_REGION}"
  3. 如要刪除 Artifact Registry 存放區,請執行下列指令:

    gcloud artifacts repositories delete gemma \
        --location="${ARTIFACT_REPO_LOCATION}" \
        --quiet

刪除專案

刪除 Google Cloud 專案:

gcloud projects delete PROJECT_ID

後續步驟