1. Einführung
In diesem Lab lernen Sie, wie Sie den gesamten Workflow der überwachten Feinabstimmung für ein Google Gemini-Modell durchführen, um es für eine bestimmte Aufgabe anzupassen: die Zusammenfassung von Artikeln. Large Language Models sind zwar leistungsstark, aber da sie für allgemeine Zwecke konzipiert sind, können sie durch Feinabstimmung für bestimmte Anwendungsfälle noch effektiver gemacht werden. Wenn Sie das Modell mit einem hochwertigen Dataset mit 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- und Validierungsdaten im JSONL-Format.
- Vertex AI Training: Verwaltet den Feinabstimmungsjob.
- Vertex AI-Endpunkt: Hier wird Ihr feinabgestimmtes Modell gehostet.
Lerninhalte
- Hochwertige Datasets für das überwachte Fine-Tuning vorbereiten
- Konfigurieren und starten Sie Jobs zum Feinabstimmen mit dem Vertex AI SDK für Python.
- Bewerten Sie Modelle anhand automatisierter Messwerte (ROUGE-Werte).
- Vergleichen Sie Basis- und abgestimmte Modelle, 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 stattdessen ein privates Konto.
In der Google Cloud Console anmelden
Melden Sie sich mit einem privaten Google-Konto in der Google Cloud Console an.
Abrechnung aktivieren
Google Cloud-Guthaben im Wert von 5 $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 Folgendes:

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

- Klicken Sie auf Bestätigen.
Sie sind jetzt mit einem Google Cloud Platform-Testrechnungskonto 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 zum Cloud Shell-Editor zu gelangen.
- Wenn Sie heute an irgendeinem Punkt zur Autorisierung aufgefordert werden, 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 mehr an Ihre Projekt-ID erinnern, können Sie alle Ihre Projekt-IDs mit folgendem 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 die APIs im Terminal:
- Vertex AI API (
aiplatform.googleapis.com): Ermöglicht die Verwendung von Vertex AI zum Feinabstimmen und Bereitstellen 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, in der diese Variablen gespeichert werden, damit sie bei einer Trennung der Verbindung problemlos 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 zum Speichern Ihres Datasets und Ihrer Modellartefakte.
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
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 Datenaufbereitung aus.
python prepare_data.py
7. Referenzleistung ermitteln
Bevor Sie mit dem Fine-Tuning beginnen, benötigen Sie einen Benchmark. Sie messen die Leistung des Basismodells gemini-2.5-flash bei der Zusammenfassungsaufgabe anhand von ROUGE-Werten.
- 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 Baseline-Bewertung aus.
Dadurch wird 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
Als Nächstes starten Sie einen verwalteten Optimierungsjob 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 das Fine-Tuning-Skript im Terminal aus.
Hinweis: Dieser Vorgang kann etwa 45 Minuten dauern. Sie können den Job in der Vertex AI-Konsole überwachen.python tune.py
9. Trainingscode verstehen
Während Ihr Job ausgeführt wird, sehen wir uns das tune.py-Skript genauer an, um zu verstehen, wie das Fine-Tuning funktioniert.
Verwaltete überwachte Feinabstimmung
Im Skript wird die Methode vertexai.tuning.sft.train verwendet, 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: In diesem Lab wird dieser Wert 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. Achten Sie jedoch auf eine Überanpassung.
Modellauswahl
Wir geben source_model="gemini-2.5-flash" explizit an. Vertex AI unterstützt verschiedene Versionen von Gemini. Wenn Sie eine bestimmte Version fixieren, bleibt Ihre Pipeline stabil und reproduzierbar.
10. Modelle vergleichen
Nach Abschluss des Jobs zum Feinabstimmen können Sie die Leistung Ihres neuen Modells mit der Baseline vergleichen.
- Rufen Sie den Endpunkt des feinabgestimmten Modells ab. Sie wurde am Ende des
tune.py-Skripts ausgegeben. Sie sollte etwa soprojects/.../locations/.../endpoints/...aussehen: - Führen Sie das Bewertungsskript noch einmal aus. Übergeben Sie dieses Mal Ihr optimiertes Modell und die Baseline-Ergebnisse 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.png-Diagramm, das die Verbesserung zeigt.Sie können die Diagramme ansehen, indem Sie den Ordnerplotsim Cloud Shell-Editor ö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 feinabgestimmt.
Zusammenfassung
Die Aufgaben in diesem Lab:
- Sie haben ein Dataset im JSONL-Format für die Gemini-Feinabstimmung vorbereitet.
- Es wurde eine Baseline mit dem Gemini 2.5 Flash-Basismodell erstellt.
- Sie haben einen Job für überwachte Feinabstimmung in Vertex AI gestartet.
- Das abgestimmte Modell wurde bewertet und mit der Baseline verglichen.
Nächste Schritte
Dieses Lab ist Teil des Lernpfads Produktionsreife KI mit Google Cloud.
Gesamten Lehrplan ansehen, um die Lücke zwischen Prototyp und Produktion zu schließen
Teilen Sie Ihren Fortschritt unter dem Hashtag #ProductionReadyAI.