1. Einführung
In diesem Lab lernen Sie, wie Sie den vollständigen Workflow der überwachten Feinabstimmung für ein Google Gemini-Modell ausführen, um es an eine bestimmte Aufgabe anzupassen: die Zusammenfassung von Artikeln. Large Language Models sind zwar leistungsstark, aber aufgrund ihrer allgemeinen Natur können sie durch Feinabstimmung für bestimmte Anwendungsfälle noch effektiver gemacht werden. Wenn Sie das Modell mit einem hochwertigen Dataset von Beispielen trainieren, können Sie seine Konsistenz, Qualität und Effizienz für Ihre Zielaufgabe verbessern.
Sie verwenden Gemini 2.5 Flash, ein leichtgewichtiges und kostengünstiges Modell, und führen die Feinabstimmung mit Vertex AI durch.
Überblick über die Architektur
Das werden wir erstellen:
- Cloud Shell: Ihre Entwicklungsumgebung.
- Cloud Storage: Speichert Trainings-/Validierungsdaten im JSONL-Format.
- Vertex AI Training: Verwaltet den Feinabstimmungsjob.
- Vertex AI-Endpunkt: Hostet Ihr abgestimmtes Modell.
Lerninhalte
- Hochwertige Datasets für die überwachte Feinabstimmung vorbereiten.
- Feinabstimmungsjobs mit dem Vertex AI SDK für Python konfigurieren und starten.
- Modelle mit automatisierten Messwerten (ROUGE-Werten) bewerten.
- Basis- und abgestimmte Modelle vergleichen, um Verbesserungen zu quantifizieren.
2. Projekt einrichten
Google-Konto
Wenn Sie noch kein privates Google-Konto haben, müssen Sie ein Google-Konto erstellen.
Verwenden Sie ein privates Konto anstelle eines Arbeitskontos oder eines Kontos einer Bildungseinrichtung.
In der Google Cloud Console anmelden
Melden Sie sich mit einem privaten Google-Konto in der Google Cloud Console an.
Abrechnung aktivieren
5 $Google Cloud-Guthaben einlösen (optional)
Für diesen Workshop benötigen Sie ein Rechnungskonto mit Guthaben. Wenn Sie Ihre eigene Abrechnung verwenden möchten, können Sie diesen Schritt überspringen.
- Klicken Sie auf diesen Link und melden Sie sich mit einem privaten Google-Konto an.Sie sehen dann etwa Folgendes:

- Klicken Sie auf die Schaltfläche HIER KLICKEN, UM AUF IHR GUTHABEN ZUZUGREIFEN. Sie werden zu einer Seite weitergeleitet, auf der Sie Ihr Abrechnungsprofil einrichten können.

- Klicken Sie auf Bestätigen.
Sie sind jetzt mit einem Google Cloud Platform-Testabrechnungskonto verbunden.

Projekt erstellen (optional)
Wenn Sie kein aktuelles Projekt haben, das Sie für dieses Lab verwenden möchten, erstellen Sie hier ein neues Projekt.
3. Cloud Shell-Editor öffnen
- Klicken Sie auf diesen Link, um direkt zu Cloud Shell-Editor zu gelangen.
- Wenn Sie heute aufgefordert werden, die Autorisierung zu bestätigen, klicken Sie auf Autorisieren , um fortzufahren.

- Wenn das Terminal nicht unten auf dem Bildschirm angezeigt wird, öffnen Sie es:
- Klicken Sie auf Ansehen.
- Klicken Sie auf Terminal

- Legen Sie im Terminal Ihr Projekt mit diesem Befehl fest:
gcloud config set project [PROJECT_ID]- Beispiel:
gcloud config set project lab-project-id-example - Wenn Sie sich nicht an Ihre Projekt-ID erinnern, können Sie alle Ihre Projekt-IDs mit diesem Befehl auflisten:
gcloud projects list
- Beispiel:
- Es sollte folgende Meldung angezeigt werden:
Updated property [core/project].
4. APIs aktivieren
Wenn Sie Vertex AI und andere Dienste verwenden möchten, müssen Sie die erforderlichen APIs in Ihrem Google Cloud-Projekt aktivieren.
- Aktivieren Sie im Terminal die APIs:
- Vertex AI API (
aiplatform.googleapis.com): Ermöglicht die Verwendung von Vertex AI für die Feinabstimmung und Bereitstellung von Modellen. - Cloud Storage API (
storage.googleapis.com): Ermöglicht das Speichern von Datasets und Modellartefakten.
gcloud services enable aiplatform.googleapis.com \ storage.googleapis.com - Vertex AI API (
5. Projektumgebung einrichten
Arbeitsverzeichnis erstellen
- Erstellen Sie im Terminal ein Verzeichnis für Ihr Projekt und wechseln Sie zu diesem Verzeichnis.
mkdir gemini-finetuning cd gemini-finetuning
Umgebungsvariablen einrichten
- Definieren Sie im Terminal die Umgebungsvariablen für Ihr Projekt. Wir erstellen eine
env.sh-Datei, um diese Variablen zu speichern, damit sie bei einer Trennung der Verbindung einfach neu geladen werden können.cat <<EOF > env.sh export PROJECT_ID=\$(gcloud config get-value project) export REGION="us-central1" export BUCKET_NAME="\${PROJECT_ID}-gemini-tuning" EOF source env.sh
Cloud Storage-Bucket erstellen
- Erstellen Sie im Terminal einen Bucket, um Ihr Dataset und Ihre Modellartefakte zu speichern.
gcloud storage buckets create gs://$BUCKET_NAME --project=$PROJECT_ID --location=$REGION
Virtuelle Umgebung einrichten
- Wir verwenden
uv, um unsere Python-Umgebung zu verwalten. Führen Sie im Terminal folgenden Befehl aus:uv venv .venv source .venv/bin/activate - Installieren Sie im Terminal die erforderlichen Python-Pakete.
uv pip install google-cloud-aiplatform rouge-score matplotlib pandas tqdm
6. Trainingsdaten vorbereiten
Qualitativ hochwertige Daten sind die Grundlage für eine erfolgreiche Feinabstimmung. Sie verwenden das WikiLingua-Dataset, wandeln es in das spezifische JSONL-Format um, das für Gemini erforderlich ist, und laden es in Ihren Speicher-Bucket hoch.
- Erstellen Sie im Terminal eine Datei mit dem Namen
prepare_data.py.cloudshell edit prepare_data.py - Fügen Sie den folgenden Code in
prepare_data.pyein.import json import os import pandas as pd from google.cloud import storage import subprocess # Configuration BUCKET_NAME = os.environ["BUCKET_NAME"] PROJECT_ID = os.environ["PROJECT_ID"] def download_data(): print("Downloading WikiLingua dataset...") # Using gsutil to copy from public bucket subprocess.run(["gsutil", "cp", "gs://github-repo/generative-ai/gemini/tuning/summarization/wikilingua/*", "."], check=True) def convert_to_gemini_format(input_file, output_file, max_samples=1000): print(f"Converting {input_file} to Gemini format (first {max_samples} samples)...") converted_data = [] with open(input_file, 'r') as f: for i, line in enumerate(f): if i >= max_samples: break obj = json.loads(line) messages = obj.get("messages", []) # Convert messages to Gemini 2.5 format # Input: {"messages": [{"role": "user", "content": "..."}, {"role": "model", "content": "..."}]} # Output: {"contents": [{"role": "user", "parts": [{"text": "..."}]}, {"role": "model", "parts": [{"text": "..."}]}]} contents = [] for msg in messages: role = msg["role"] content = msg["content"] contents.append({ "role": role, "parts": [{"text": content}] }) converted_data.append({"contents": contents}) with open(output_file, 'w') as f: for item in converted_data: f.write(json.dumps(item) + "\n") print(f"Saved {len(converted_data)} examples to {output_file}") def upload_to_gcs(local_file, destination_blob_name): print(f"Uploading {local_file} to gs://{BUCKET_NAME}/{destination_blob_name}...") storage_client = storage.Client(project=PROJECT_ID) bucket = storage_client.bucket(BUCKET_NAME) blob = bucket.blob(destination_blob_name) blob.upload_from_filename(local_file) print("Upload complete.") def main(): download_data() # Process Training Data convert_to_gemini_format("sft_train_samples.jsonl", "train_gemini.jsonl") upload_to_gcs("train_gemini.jsonl", "datasets/train/train_gemini.jsonl") # Process Validation Data convert_to_gemini_format("sft_val_samples.jsonl", "val_gemini.jsonl") upload_to_gcs("val_gemini.jsonl", "datasets/val/val_gemini.jsonl") print("Data preparation complete!") if __name__ == "__main__": main() - Führen Sie im Terminal das Skript zur Datenvorbereitung aus.
python prepare_data.py
7. Referenzleistung festlegen
Vor der Feinabstimmung benötigen Sie einen Benchmark. Sie messen mit ROUGE-Werten, wie gut das Basismodell gemini-2.5-flash bei der Zusammenfassungsaufgabe abschneidet.
- Erstellen Sie im Terminal eine Datei mit dem Namen
evaluate.py.cloudshell edit evaluate.py - Fügen Sie den folgenden Code in
evaluate.pyein.import argparse import json import os import pandas as pd from google.cloud import aiplatform import vertexai from vertexai.generative_models import GenerativeModel, GenerationConfig, HarmCategory, HarmBlockThreshold from rouge_score import rouge_scorer from tqdm import tqdm import matplotlib.pyplot as plt import time # Configuration PROJECT_ID = os.environ["PROJECT_ID"] REGION = os.environ["REGION"] aiplatform.init(project=PROJECT_ID, location=REGION) def evaluate(model_name, test_file, max_samples=50, output_json="results.json"): print(f"Evaluating model: {model_name}") # Load Test Data test_df = pd.read_csv(test_file) test_df = test_df.head(max_samples) model = GenerativeModel(model_name) safety_settings = { HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_ONLY_HIGH, HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_ONLY_HIGH, HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_ONLY_HIGH, HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_ONLY_HIGH, } generation_config = GenerationConfig( temperature=0.1, max_output_tokens=1024, ) scorer = rouge_scorer.RougeScorer(['rouge1', 'rouge2', 'rougeL'], use_stemmer=True) results = [] for index, row in tqdm(test_df.iterrows(), total=len(test_df)): input_text = row['input_text'] reference_summary = row['output_text'] try: response = model.generate_content( input_text, generation_config=generation_config, safety_settings=safety_settings ) generated_summary = response.text scores = scorer.score(reference_summary, generated_summary) results.append({ "generated": generated_summary, "reference": reference_summary, "rouge1": scores['rouge1'].fmeasure, "rouge2": scores['rouge2'].fmeasure, "rougeL": scores['rougeL'].fmeasure }) except Exception as e: print(f"Error processing example {index}: {e}") # Sleep briefly to avoid quota issues if hitting limits time.sleep(1) # Save results with open(output_json, 'w') as f: json.dump(results, f, indent=2) return pd.DataFrame(results) def plot_results(df, title, filename): os.makedirs("plots", exist_ok=True) metrics = ['rouge1', 'rouge2', 'rougeL'] fig, axes = plt.subplots(1, 3, figsize=(15, 5)) for i, metric in enumerate(metrics): axes[i].hist(df[metric], bins=10, alpha=0.7, color='skyblue', edgecolor='black') axes[i].set_title(f'{metric} Distribution') axes[i].set_xlabel('Score') axes[i].set_ylabel('Count') plt.suptitle(title) plt.tight_layout() plt.savefig(f"plots/{filename}") print(f"Plot saved to plots/{filename}") def compare_results(baseline_file, tuned_file): with open(baseline_file, 'r') as f: baseline_data = pd.DataFrame(json.load(f)) with open(tuned_file, 'r') as f: tuned_data = pd.DataFrame(json.load(f)) print("\n--- Comparison ---") metrics = ['rouge1', 'rouge2', 'rougeL'] for metric in metrics: base_mean = baseline_data[metric].mean() tuned_mean = tuned_data[metric].mean() diff = tuned_mean - base_mean print(f"{metric}: Base={base_mean:.4f}, Tuned={tuned_mean:.4f}, Diff={diff:+.4f}") # Comparative Plot os.makedirs("plots", exist_ok=True) comparison_df = pd.DataFrame({ 'Metric': metrics, 'Baseline': [baseline_data[m].mean() for m in metrics], 'Tuned': [tuned_data[m].mean() for m in metrics] }) comparison_df.plot(x='Metric', y=['Baseline', 'Tuned'], kind='bar', figsize=(10, 6)) plt.title('Baseline vs Tuned Model Performance') plt.ylabel('Average Score') plt.xticks(rotation=0) plt.tight_layout() plt.savefig("plots/comparison.png") print("Comparison plot saved to plots/comparison.png") def main(): parser = argparse.ArgumentParser() parser.add_argument("--model", type=str, default="gemini-2.5-flash", help="Model resource name") parser.add_argument("--baseline", type=str, help="Path to baseline results json for comparison") parser.add_argument("--output", type=str, default="results.json", help="Output file for results") args = parser.parse_args() # Ensure test data exists (it was downloaded in prepare_data step) if not os.path.exists("sft_test_samples.csv"): # Fallback download if needed subprocess.run(["gsutil", "cp", "gs://github-repo/generative-ai/gemini/tuning/summarization/wikilingua/sft_test_samples.csv", "."], check=True) df = evaluate(args.model, "sft_test_samples.csv", output_json=args.output) print("\n--- Results Summary ---") print(df.describe()) plot_filename = "baseline_dist.png" if not args.baseline else "tuned_dist.png" plot_results(df, f"ROUGE Scores - {args.model}", plot_filename) if args.baseline: compare_results(args.baseline, args.output) if __name__ == "__main__": main() - Führen Sie im Terminal die Referenzbewertung aus.
Dadurch werden einepython evaluate.py --model "gemini-2.5-flash" --output "baseline.json"baseline.json-Datei und ein Diagramm inplots/baseline_dist.pnggeneriert.
8. Feinabstimmung konfigurieren und starten
Jetzt starten Sie einen verwalteten Feinabstimmungsjob in Vertex AI.
- Erstellen Sie im Terminal eine Datei mit dem Namen
tune.py.cloudshell edit tune.py - Fügen Sie den folgenden Code in
tune.pyein.import os import time from google.cloud import aiplatform import vertexai from vertexai.preview.tuning import sft # Configuration PROJECT_ID = os.environ["PROJECT_ID"] REGION = os.environ["REGION"] BUCKET_NAME = os.environ["BUCKET_NAME"] aiplatform.init(project=PROJECT_ID, location=REGION) def train(): print("Launching fine-tuning job...") sft_tuning_job = sft.train( source_model="gemini-2.5-flash", # Using specific version for stability train_dataset=f"gs://{BUCKET_NAME}/datasets/train/train_gemini.jsonl", validation_dataset=f"gs://{BUCKET_NAME}/datasets/val/val_gemini.jsonl", epochs=1, # Keep it short for the lab adapter_size=4, learning_rate_multiplier=1.0, tuned_model_display_name="gemini-2.5-flash-wikilingua", ) print(f"Job started: {sft_tuning_job.resource_name}") print("Waiting for job to complete... (this may take ~45 minutes)") # Wait for the job to complete while not sft_tuning_job.has_ended: time.sleep(60) sft_tuning_job.refresh() print(f"Status: {sft_tuning_job.state.name}") print("Job completed!") print(f"Tuned Model Endpoint: {sft_tuning_job.tuned_model_endpoint_name}") return sft_tuning_job.tuned_model_endpoint_name if __name__ == "__main__": train() - Führen Sie im Terminal das Skript zur Feinabstimmung aus.
Hinweis: Dieser Vorgang kann etwa 45 Minuten dauern. Sie können den Job in der Vertex AI Console überwachen.python tune.py
9. Trainingscode verstehen
Während Ihr Job ausgeführt wird, sehen wir uns das Skript tune.py genauer an, um zu verstehen, wie die Feinabstimmung funktioniert.
Verwaltete überwachte Feinabstimmung
Das Skript verwendet die Methode vertexai.tuning.sft.train, um einen verwalteten Abstimmungsjob zu senden. Dadurch wird die Komplexität der Bereitstellung der Infrastruktur, der Verteilung des Trainings und der Verwaltung von Checkpoints abstrahiert.
sft_tuning_job = sft.train(
source_model="gemini-2.5-flash",
train_dataset=f"gs://{BUCKET_NAME}/datasets/train/train_gemini.jsonl",
# ...
)
LoRA-Konfiguration
Anstatt eine LoraConfig manuell zu definieren, wie Sie es in Open-Source-Frameworks tun würden, vereinfacht Vertex AI dies auf einige wenige Schlüsselparameter:
adapter_size: Dieser Parameter (in unserem Skript auf4festgelegt) steuert den Rang der LoRA-Adapter. Eine größere Größe ermöglicht es dem Modell, komplexere Anpassungen zu lernen, erhöht aber die Anzahl der trainierbaren Parameter.epochs: Wir haben diesen Parameter für dieses Lab auf1festgelegt, um die Trainingszeit kurz zu halten (ca. 20 Minuten). In einem Produktionsszenario können Sie diesen Wert erhöhen, damit das Modell mehr aus Ihren Daten lernen kann. Sie sollten jedoch auf eine Überanpassung achten.
Modellauswahl
Wir geben explizit source_model="gemini-2.5-flash" an. Vertex AI unterstützt verschiedene Versionen von Gemini. Wenn Sie eine bestimmte Version festlegen, bleibt Ihre Pipeline stabil und reproduzierbar.
10. Modelle vergleichen
Nach Abschluss des Feinabstimmungsjobs können Sie die Leistung Ihres neuen Modells mit der Referenz vergleichen.
- Rufen Sie den Endpunkt Ihres abgestimmten Modells ab. Er wurde am Ende des Skripts
tune.pyausgegeben. Er sieht etwa so aus:projects/.../locations/.../endpoints/.... - Führen Sie das Bewertungsskript noch einmal aus und übergeben Sie dieses Mal Ihr abgestimmtes Modell und die Referenzergebnisse zum Vergleich.
# Replace [YOUR_TUNED_MODEL_ENDPOINT] with the actual endpoint name export TUNED_MODEL="projects/[YOUR_PROJECT_ID]/locations/[YOUR_REGION]/endpoints/[YOUR_ENDPOINT_ID]" python evaluate.py --model "$TUNED_MODEL" --baseline "baseline.json" --output "tuned.json" - Rufen Sie die Ergebnisse auf. Das Skript gibt einen Vergleich der ROUGE-Werte aus und generiert ein
plots/comparison.pngDiagramm, das die Verbesserung zeigt.Sie können die Diagramme aufrufen, indem Sie im Cloud Shell-Editor den Ordnerplotsöffnen.
11. Bereinigen
Löschen Sie die erstellten Ressourcen, um Gebühren zu vermeiden.
- Löschen Sie im Terminal den Cloud Storage-Bucket und das abgestimmte Modell.
gcloud storage rm -r gs://$BUCKET_NAME # Note: You can delete the model endpoint from the Vertex AI Console
12. Glückwunsch!
Sie haben Gemini 2.5 Flash in Vertex AI erfolgreich abgestimmt.
Zusammenfassung
Die Aufgaben in diesem Lab:
- Dataset im JSONL-Format für die Feinabstimmung von Gemini vorbereitet.
- Referenz mit dem Basismodell Gemini 2.5 Flash festgelegt.
- Überwachten Feinabstimmungsjob in Vertex AI gestartet.
- Abgestimmtes Modell bewertet und mit der Referenz verglichen.
Nächste Schritte
Dieses Lab ist Teil des Lernpfads Production-Ready AI with Google Cloud.
Teilen Sie Ihre Fortschritte mit dem Hashtag #ProductionReadyAI.