Gemma 3 in einem A4-Slurm-Cluster abstimmen

In dieser Anleitung wird beschrieben, wie Sie das Gemma 3-LLM (Large Language Model) in einem Slurm-Cluster mit mehreren Knoten, in dem zwei A4-VM-Instanzen verwendet werden, feinabstimmen. In dieser Anleitung führen Sie folgende Schritte aus:

Diese Anleitung richtet sich an Entwickler von maschinellem Lernen (ML), Plattformadministratoren und ‑operatoren sowie an Daten- und KI-Spezialisten, die daran interessiert sind, Slurm-Funktionen zur Jobplanung für die Verarbeitung von Arbeitslasten zum Feinabstimmen zu verwenden.

Ziele

  1. Über Hugging Face auf Gemma 3 zugreifen

  2. Bereiten Sie Ihre Umgebung vor.

  3. Erstellen Sie einen A4-Slurm-Cluster.

  4. Arbeitslast vorbereiten

  5. Führen Sie einen Job zur Feinabstimmung aus.

  6. den Job überwachen

  7. bereinigen.

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.

Neuen Nutzern von Google Cloud steht möglicherweise eine kostenlose Testversion zur Verfügung.

Hinweis

  1. Melden Sie sich in Ihrem Google Cloud -Konto an. Wenn Sie mit Google Cloudnoch nicht vertraut sind, erstellen Sie ein Konto, um die Leistungsfähigkeit unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  2. Installieren Sie die Google Cloud CLI.

  3. Wenn Sie einen externen Identitätsanbieter (IdP) verwenden, müssen Sie sich zuerst mit Ihrer föderierten Identität in der gcloud CLI anmelden.

  4. Führen Sie den folgenden Befehl aus, um die gcloud CLI zu initialisieren:

    gcloud init
  5. Erstellen Sie ein Google Cloud Projekt oder wählen Sie eines aus.

    Rollen, die zum Auswählen oder Erstellen eines Projekts erforderlich sind

    • Projekt auswählen: Für die Auswahl eines Projekts ist keine bestimmte IAM-Rolle erforderlich. Sie können jedes Projekt auswählen, für das Ihnen eine Rolle zugewiesen wurde.
    • Projekt erstellen: Zum Erstellen eines Projekts benötigen Sie die Rolle „Projektersteller“ (roles/resourcemanager.projectCreator), die die Berechtigung resourcemanager.projects.create enthält. Weitere Informationen zum Zuweisen von Rollen
    • So erstellen Sie ein Google Cloud -Projekt:

      gcloud projects create PROJECT_ID

      Ersetzen Sie PROJECT_ID durch einen Namen für das Google Cloud -Projekt, das Sie erstellen.

    • Wählen Sie das von Ihnen erstellte Google Cloud Projekt aus:

      gcloud config set project PROJECT_ID

      Ersetzen Sie PROJECT_ID durch den Namen Ihres Projekts in Google Cloud .

  6. Prüfen Sie, ob für Ihr Google Cloud Projekt die Abrechnung aktiviert ist.

  7. Aktivieren Sie die erforderliche API:

    Rollen, die zum Aktivieren von APIs erforderlich sind

    Zum Aktivieren von APIs benötigen Sie die IAM-Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin), die die Berechtigung serviceusage.services.enable enthält. Weitere Informationen zum Zuweisen von Rollen

    gcloud services enable compute.googleapis.com file.googleapis.com logging.googleapis.com cloudresourcemanager.googleapis.com servicenetworking.googleapis.com
  8. Installieren Sie die Google Cloud CLI.

  9. Wenn Sie einen externen Identitätsanbieter (IdP) verwenden, müssen Sie sich zuerst mit Ihrer föderierten Identität in der gcloud CLI anmelden.

  10. Führen Sie den folgenden Befehl aus, um die gcloud CLI zu initialisieren:

    gcloud init
  11. Erstellen Sie ein Google Cloud Projekt oder wählen Sie eines aus.

    Rollen, die zum Auswählen oder Erstellen eines Projekts erforderlich sind

    • Projekt auswählen: Für die Auswahl eines Projekts ist keine bestimmte IAM-Rolle erforderlich. Sie können jedes Projekt auswählen, für das Ihnen eine Rolle zugewiesen wurde.
    • Projekt erstellen: Zum Erstellen eines Projekts benötigen Sie die Rolle „Projektersteller“ (roles/resourcemanager.projectCreator), die die Berechtigung resourcemanager.projects.create enthält. Weitere Informationen zum Zuweisen von Rollen
    • So erstellen Sie ein Google Cloud -Projekt:

      gcloud projects create PROJECT_ID

      Ersetzen Sie PROJECT_ID durch einen Namen für das Google Cloud -Projekt, das Sie erstellen.

    • Wählen Sie das von Ihnen erstellte Google Cloud Projekt aus:

      gcloud config set project PROJECT_ID

      Ersetzen Sie PROJECT_ID durch den Namen Ihres Projekts in Google Cloud .

  12. Prüfen Sie, ob für Ihr Google Cloud Projekt die Abrechnung aktiviert ist.

  13. Aktivieren Sie die erforderliche API:

    Rollen, die zum Aktivieren von APIs erforderlich sind

    Zum Aktivieren von APIs benötigen Sie die IAM-Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin), die die Berechtigung serviceusage.services.enable enthält. Weitere Informationen zum Zuweisen von Rollen

    gcloud services enable compute.googleapis.com file.googleapis.com logging.googleapis.com cloudresourcemanager.googleapis.com servicenetworking.googleapis.com
  14. Weisen Sie Ihrem Nutzerkonto Rollen zu. Führen Sie den folgenden Befehl für jede der folgenden IAM-Rollen einmal aus: roles/compute.admin, roles/iam.serviceAccountUser, roles/file.editor, roles/storage.admin, roles/serviceusage.serviceUsageAdmin

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

    Ersetzen Sie Folgendes:

    • PROJECT_ID: Ihre Projekt-ID.
    • USER_IDENTIFIER: Die Kennung für Ihr Nutzerkonto . Beispiel: myemail@example.com
    • ROLE: Die IAM-Rolle, die Sie Ihrem Nutzerkonto zuweisen.
  15. Aktivieren Sie das Standarddienstkonto für Ihr Google Cloud Projekt:
    gcloud iam service-accounts enable PROJECT_NUMBER-compute@developer.gserviceaccount.com \
        --project=PROJECT_ID

    Ersetzen Sie PROJECT_NUMBER durch die Projekt-ID. Informationen zum Abrufen Ihrer Projektnummer finden Sie unter Vorhandenes Projekt abrufen.

  16. Weisen Sie dem Standarddienstkonto die Rolle „Bearbeiter“ (roles/editor) zu:
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
        --role=roles/editor
  17. Erstellen Sie lokale Anmeldedaten zur Authentifizierung für Ihr Nutzerkonto:
    gcloud auth application-default login
  18. Aktivieren Sie OS Login für Ihr Projekt:
    gcloud compute project-info add-metadata --metadata=enable-oslogin=TRUE
  19. Melden Sie sich in einem Hugging Face-Konto an oder erstellen Sie ein Konto.

Über Hugging Face auf Gemma 3 zugreifen

So greifen Sie mit Hugging Face auf Gemma 3 zu:

  1. Einwilligungsvereinbarung unterzeichnen, um Gemma 3 12B zu verwenden

  2. Erstellen Sie ein Hugging Face-Zugriffstoken für read. Klicken Sie auf Mein Profil > Einstellungen > Zugriffstokens > +Neuen Token erstellen.

  3. Kopieren und speichern Sie den read access-Tokenwert. Sie benötigen sie später in dieser Anleitung.

Umgebung vorbereiten

So bereiten Sie die Umgebung vor:

  1. Klonen Sie das GitHub-Repository für Cluster-Toolkit:

    git clone https://github.com/GoogleCloudPlatform/cluster-toolkit.git
    
  2. Erstellen Sie einen Cloud Storage-Bucket:

    gcloud storage buckets create gs://BUCKET_NAME \
        --project=PROJECT_ID
    

    Ersetzen Sie Folgendes:

    • BUCKET_NAME: Ein Name für Ihren Cloud Storage-Bucket, der den Anforderungen für Bucket-Namen entspricht.

    • PROJECT_ID: Die ID desGoogle Cloud -Projekts, in dem Sie Ihren Cloud Storage-Bucket erstellen möchten.

A4-Slurm-Cluster erstellen

So erstellen Sie einen A4-Slurm-Cluster:

  1. Wechseln Sie in das Verzeichnis cluster-toolkit:

    cd cluster-toolkit
    
  2. Wenn Sie das Cluster-Toolkit zum ersten Mal verwenden, erstellen Sie das Binärprogramm gcluster:

    make
    
  3. Wechseln Sie in das Verzeichnis examples/machine-learning/a4-highgpu-8g:

    cd examples/machine-learning/a4-highgpu-8g/
    
  4. Öffnen Sie die Datei a4high-slurm-deployment.yaml und bearbeiten Sie sie so:

    terraform_backend_defaults:
      type: gcs
      configuration:
        bucket: BUCKET_NAME
    
    vars:
      deployment_name: a4-high
      project_id: PROJECT_ID
      region: REGION
      zone: ZONE
      a4h_cluster_size: 2
      a4h_reservation_name: RESERVATION_URL
    

    Ersetzen Sie Folgendes:

    • BUCKET_NAME: Der Name des Cloud Storage-Bucket, den Sie im vorherigen Abschnitt erstellt haben.

    • PROJECT_ID: Die ID desGoogle Cloud -Projekts, in dem sich Ihr Cloud Storage befindet und in dem Sie Ihren Slurm-Cluster erstellen möchten.

    • REGION: Die Region, in der Ihre Reservierung vorhanden ist.

    • ZONE: die Zone, in der sich Ihre Reservierung befindet.

    • RESERVATION_URL: die URL der Reservierung, die Sie zum Erstellen Ihres Slurm-Clusters verwenden möchten. Geben Sie je nach Projekt, in dem die Reservierung vorhanden ist, einen der folgenden Werte an:

      • Die Reservierung ist in Ihrem Projekt vorhanden: RESERVATION_NAME

      • Die Reservierung ist in einem anderen Projekt vorhanden und Ihr Projekt kann sie nutzen: projects/RESERVATION_PROJECT_ID/reservations/RESERVATION_NAME

  5. Stellen Sie den Cluster bereit:

    ./gcluster deploy -d examples/machine-learning/a4-highgpu-8g/a4high-slurm-deployment.yaml examples/machine-learning/a4-highgpu-8g/a4high-slurm-blueprint.yaml --auto-approve
    

    Der Befehl ./gcluster deploy umfasst zwei Phasen:

    • In der ersten Phase wird ein benutzerdefiniertes Image mit vorinstallierter Software erstellt. Das kann bis zu 35 Minuten dauern.

    • In der zweiten Phase wird der Cluster mit diesem benutzerdefinierten Image bereitgestellt. Dieser Vorgang sollte schneller abgeschlossen sein als die erste Phase.

    Wenn die erste Phase erfolgreich ist, die zweite jedoch fehlschlägt, können Sie versuchen, den Slurm-Cluster noch einmal bereitzustellen und dabei die erste Phase zu überspringen:

    ./gcluster deploy -d examples/machine-learning/a4-highgpu-8g/a4high-slurm-deployment.yaml examples/machine-learning/a4-highgpu-8g/a4high-slurm-blueprint.yaml --auto-approve --skip "image" -w
    

Arbeitslast vorbereiten

So bereiten Sie Ihre Arbeitslast vor:

  1. Arbeitslastskripts erstellen:

  2. Skripts in den Slurm-Cluster hochladen

  3. Stellen Sie eine Verbindung zum Slurm-Cluster her.

  4. Frameworks und Tools installieren

Arbeitslastskripts erstellen

So erstellen Sie die Skripts, die von Ihrer Arbeitslast zum Feinabstimmen verwendet werden:

  1. Um die virtuelle Python-Umgebung einzurichten, erstellen Sie die Datei install_environment.sh mit folgendem Inhalt:

    #!/bin/bash
    # This script should be run ONCE on the login node to set up the
    # shared Python virtual environment.
    
    set -e
    echo "--- Creating Python virtual environment in /home ---"
    python3 -m venv ~/.venv
    echo "--- Activating virtual environment ---"
    source ~/.venv/bin/activate
    
    echo "--- Installing build dependencies ---"
    pip install --upgrade pip wheel packaging
    
    echo "--- Installing PyTorch for CUDA 12.8 ---"
    pip install torch --index-url https://download.pytorch.org/whl/cu128
    
    echo "--- Installing application requirements ---"
    pip install -r requirements.txt
    
    echo "--- Environment setup complete. You can now submit jobs with sbatch. ---"
    
  2. Erstellen Sie die Datei accelerate_config.yaml mit dem folgenden Inhalt, um die Konfigurationen für Ihren Feinabstimmungsjob anzugeben:

    # Default configuration for a 2-node, 8-GPU-per-node (16 total GPUs) FSDP training job.
    
    compute_environment: "LOCAL_MACHINE"
    distributed_type: "FSDP"
    downcast_bf16: "no"
    fsdp_config:
      fsdp_auto_wrap_policy: "TRANSFORMER_BASED_WRAP"
      fsdp_backward_prefetch: "BACKWARD_PRE"
      fsdp_cpu_ram_efficient_loading: true
      fsdp_forward_prefetch: false
      fsdp_offload_params: false
      fsdp_sharding_strategy: "FULL_SHARD"
      fsdp_state_dict_type: "FULL_STATE_DICT"
      fsdp_transformer_layer_cls_to_wrap: "Gemma3DecoderLayer"
      fsdp_use_orig_params: true
    machine_rank: 0
    main_training_function: "main"
    mixed_precision: "bf16"
    num_machines: 2
    num_processes: 16
    rdzv_backend: "static"
    same_network: true
    tpu_env: []
    use_cpu: false
    
  3. Erstellen Sie die Datei submit.slurm mit dem folgenden Inhalt, um die Aufgaben anzugeben, die für die Jobs in Ihrem Slurm-Cluster ausgeführt werden sollen:

    #!/bin/bash
    #SBATCH --job-name=gemma3-finetune
    #SBATCH --nodes=2
    #SBATCH --ntasks-per-node=8 # 8 tasks per node
    #SBATCH --gpus-per-task=1   # 1 GPU per task
    #SBATCH --partition=a4high
    #SBATCH --output=slurm-%j.out
    #SBATCH --error=slurm-%j.err
    
    set -e
    echo "--- Slurm Job Started ---"
    
    # --- STAGE 1: Copy Environment to Local SSD on all nodes ---
    srun --ntasks=$SLURM_NNODES --ntasks-per-node=1 bash -c '
      echo "Setting up local environment on $(hostname)..."
      LOCAL_VENV="/mnt/localssd/venv_job_${SLURM_JOB_ID}"
      LOCAL_CACHE="/mnt/localssd/hf_cache_job_${SLURM_JOB_ID}"
      rsync -a --info=progress2 ~/./.venv/ ${LOCAL_VENV}/
      mkdir -p ${LOCAL_CACHE}
      echo "Setup on $(hostname) complete."
    '
    
    # --- STAGE 2: Run the Training Job using the Local Environment ---
    echo "--- Starting Training ---"
    
    LOCAL_VENV="/mnt/localssd/venv_job_${SLURM_JOB_ID}"
    LOCAL_CACHE="/mnt/localssd/hf_cache_job_${SLURM_JOB_ID}"
    LOCAL_OUTPUT_DIR="/mnt/localssd/outputs_${SLURM_JOB_ID}"
    mkdir -p ${LOCAL_OUTPUT_DIR}
    
    # This is the main training command.
    srun --ntasks=$((SLURM_NNODES * 8)) --gpus-per-task=1 bash -c "
      source ${LOCAL_VENV}/bin/activate
    
      export HF_HOME=${LOCAL_CACHE}
      export HF_DATASETS_CACHE=${LOCAL_CACHE}
    
      # Run the Python script directly.
      # Accelerate will divide the work
      python ~/train.py \
        --model_id google/gemma-3-12b-pt \
        --output_dir ${LOCAL_OUTPUT_DIR} \
        --per_device_train_batch_size 1 \
        --gradient_accumulation_steps 8 \
        --num_train_epochs 3 \
        --learning_rate 1e-5 \
        --save_strategy steps \
        --save_steps 100
    "
    
    # --- STAGE 3: Copy Final Model from Local SSD to Home Directory ---
    echo "--- Copying final model from local SSD to /home ---"
    # This command runs only on the first node of the job allocation
    # and copies the final model back to the persistent shared directory.
    srun --nodes=1 --ntasks=1 --ntasks-per-node=1 bash -c "
      rsync -a --info=progress2 ${LOCAL_OUTPUT_DIR}/ ~/gemma-12b-text-to-sql-finetuned/
    "
    
    echo "--- Slurm Job Finished ---"
    
  4. Wenn Sie die Abhängigkeiten für den Feinabstimmungsjob angeben möchten, erstellen Sie die Datei requirements.txt mit dem folgenden Inhalt:

    # Hugging Face Libraries (Pinned to recent, stable versions for reproducibility)
    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
    
    # Other dependencies
    tensorboard==2.20.0
    protobuf==6.31.1
    sentencepiece==0.2.0
    
  5. Erstellen Sie die Datei train.py mit folgendem Inhalt, um die Anleitung für Ihren Job anzugeben:

    import torch
    import argparse
    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():
        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("--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")
    
        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 ---
        # The SFTTrainer will use the `formatting_func` to apply the chat template.
        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)
        tokenizer.pad_token = tokenizer.eos_token
    
        gemma_chat_template = (
            ""
            ""
        )
        tokenizer.chat_template = gemma_chat_template
    
        # --- 4. Define the Formatting Function ---
        # This function will be used by the SFTTrainer to format each sample
        # from the dataset into the correct chat template format.
        def formatting_func(example):
            # The create_conversation logic is now implicitly handled by this.
            # We need to construct the messages list here.
            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"][0], context=example["sql_context"][0])},
                {"role": "assistant", "content": example["sql"][0]}
            ]
            return tokenizer.apply_chat_template(messages, tokenize=False)
    
        # --- 5. Load Quantized Model and Apply PEFT ---
    
        # Define the quantization configuration
        quantization_config = BitsAndBytesConfig(
            load_in_4bit=True,
            bnb_4bit_quant_type='nf4',
            bnb_4bit_compute_dtype=torch_dtype_obj,
            bnb_4bit_use_double_quant=True,
        )
    
        config = AutoConfig.from_pretrained(args.model_id)
        config.use_cache = False
    
        # Load the base model with quantization
        print("Loading base model...")
        model = AutoModelForCausalLM.from_pretrained(
            args.model_id,
            config=config,
            quantization_config=quantization_config,
            attn_implementation="eager",
            torch_dtype=torch_dtype_obj,
        )
    
        # Prepare the model for k-bit training
        model = prepare_model_for_kbit_training(model)
    
        # Configure LoRA.
        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",
        )
    
        # Apply the PEFT config to the model
        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=True,
            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=False,
            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()
    
    if __name__ == "__main__":
        main()
    

Skripts in den Slurm-Cluster hochladen

So laden Sie die im vorherigen Abschnitt erstellten Skripts in den Slurm-Cluster hoch:

  1. So ermitteln Sie Ihren Anmeldeknoten: Listen Sie alle A4-VMs in Ihrem Projekt auf:

    gcloud compute instances list --filter="machineType:a4-highgpu-8g"
    

    Der Name des Anmeldeknotens ähnelt a4-high-login-001.

  2. Laden Sie Ihre Skripts in das Basisverzeichnis des Anmeldeknotens hoch:

    gcloud compute scp \
      --project=PROJECT_ID \
      --zone=ZONE \
      --tunnel-through-iap \
      ./train.py \
      ./requirements.txt \
      ./submit.slurm \
      ./install_environment.sh \
      ./accelerate_config.yaml \
      "LOGIN_NODE_NAME":~/
    

    Ersetzen Sie LOGIN_NODE_NAME durch den Namen des Anmeldeknotens.

Verbindung zum Slurm-Cluster herstellen

Stellen Sie eine Verbindung zum Slurm-Cluster her, indem Sie über SSH eine Verbindung zum Anmeldeknoten herstellen:

gcloud compute ssh LOGIN_NODE_NAME \
    --project=PROJECT_ID \
    --tunnel-through-iap \
    --zone=ZONE

Frameworks und Tools installieren

Nachdem Sie eine Verbindung zum Anmeldeknoten hergestellt haben, installieren Sie Frameworks und Tools mit den folgenden Schritten:

  1. Erstellen Sie eine Umgebungsvariable für Ihr Hugging Face-Zugriffstoken:

    export HUGGING_FACE_TOKEN="HUGGING_FACE_TOKEN"
    
  2. Richten Sie eine virtuelle Python-Umgebung mit allen erforderlichen Abhängigkeiten ein:

    chmod +x install_environment.sh
    ./install_environment.sh
    

Arbeitslast für das Feinabstimmen starten

So starten Sie die Arbeitslast für das Fine-Tuning:

  1. Senden Sie den Job an den Slurm-Planer:

    sbatch submit.slurm
    
  2. Auf dem Anmeldeknoten in Ihrem Slurm-Cluster können Sie den Fortschritt des Jobs überwachen, indem Sie die Ausgabedateien prüfen, die in Ihrem home-Verzeichnis erstellt wurden:

    tail -f slurm-gemma3-finetune.err
    

    Wenn Ihr Job erfolgreich gestartet wird, wird in der Datei .err eine Fortschrittsanzeige angezeigt, die sich im Laufe des Jobs aktualisiert.

Arbeitslast überwachen

Sie können die Nutzung der GPUs in Ihrem Slurm-Cluster überwachen, um zu prüfen, ob Ihr Fine-Tuning-Job effizient ausgeführt wird. Öffnen Sie dazu den folgenden Link in Ihrem Browser:

https://console.cloud.google.com/monitoring/metrics-explorer?project=PROJECT_ID&pageState=%7B%22xyChart%22%3A%7B%22dataSets%22%3A%5B%7B%22timeSeriesFilter%22%3A%7B%22filter%22%3A%22metric.type%3D%5C%22agent.googleapis.com%2Fgpu%2Futilization%5C%22%20resource.type%3D%5C%22gce_instance%5C%22%22%2C%22perSeriesAligner%22%3A%22ALIGN_MEAN%22%7D%2C%22plotType%22%3A%22LINE%22%7D%5D%7D%7D

Wenn Sie Ihre Arbeitslast überwachen, sehen Sie Folgendes:

  • GPU-Nutzung: Bei einem fehlerfreien Fine-Tuning-Job sollte die Nutzung aller 16 GPUs (acht GPUs für jede VM im Cluster) während des Trainings ansteigen und sich auf einem bestimmten Niveau stabilisieren.

  • Jobdauer: Der Job sollte etwa eine Stunde dauern.

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.

Projekt löschen

Google Cloud -Projekt löschen:

gcloud projects delete PROJECT_ID

Slurm-Cluster löschen

So löschen Sie Ihren Slurm-Cluster:

  1. Wechseln Sie zum Verzeichnis cluster-toolkit.

  2. Löschen Sie die Terraform-Datei und alle erstellten Ressourcen:

    ./gcluster destroy a4-high --auto-approve
    

Nächste Schritte