1. Introducción
En este lab, aprenderás a realizar el flujo de trabajo completo del ajuste supervisado en un modelo de Google Gemini para adaptarlo a una tarea específica: el resumen de artículos. Si bien los modelos de lenguaje grandes son potentes, su naturaleza de uso general significa que se pueden hacer aún más eficaces para casos de uso específicos a través del ajuste. Si entrenas el modelo en un conjunto de datos de ejemplos de alta calidad, puedes mejorar su coherencia, calidad y eficiencia para la tarea objetivo.
Usarás Gemini 2.5 Flash, un modelo ligero y rentable, y realizarás el ajuste con Vertex AI.
Descripción general de la arquitectura
Esto es lo que compilaremos:
- Cloud Shell: Tu entorno de desarrollo
- Cloud Storage: Almacena datos de entrenamiento o validación en formato JSONL
- Vertex AI Training: Administra el trabajo de ajuste
- Extremo de Vertex AI: Aloja tu modelo ajustado
Qué aprenderás
- Prepara conjuntos de datos de alta calidad para el ajuste supervisado.
- Configura y, luego, inicia trabajos de ajuste con el SDK de Vertex AI para Python.
- Evalúa modelos con métricas automatizadas (puntuaciones ROUGE).
- Compara modelos de base y ajustados para cuantificar las mejoras.
2. Configura el proyecto
Cuenta de Google
Si aún no tienes una Cuenta de Google personal, debes crear una Cuenta de Google.
Usa una cuenta personal en lugar de una cuenta de trabajo o de institución educativa.
Accede a la consola de Google Cloud
Accede a la consola de Google Cloud con una Cuenta de Google personal.
Habilitar facturación
Canjea USD 5 en créditos de Google Cloud (opcional)
Para ejecutar este taller, necesitas una cuenta de facturación con algunos créditos. Si planeas usar tu propia facturación, puedes omitir este paso.
- Haz clic en este vínculo y accede con una cuenta personal de Google.Verás algo como esto:

- Haz clic en el botón HAZ CLIC AQUÍ PARA ACCEDER A TUS CRÉDITOS.Se te dirigirá a una página para configurar tu perfil de facturación

- Haz clic en Confirmar.
Ahora estás conectado a una cuenta de facturación de prueba de Google Cloud Platform.

Crear un proyecto (opcional)
Si no tienes un proyecto actual que te gustaría usar para este lab, crea uno nuevo aquí.
3. Abre el editor de Cloud Shell
- Haz clic en este vínculo para navegar directamente al editor de Cloud Shell.
- Si se te solicita autorización en algún momento hoy, haz clic en Autorizar para continuar.

- Si la terminal no aparece en la parte inferior de la pantalla, ábrela:
- Haz clic en Ver.
- Haz clic en Terminal

- En la terminal, configura tu proyecto con este comando:
gcloud config set project [PROJECT_ID]- Ejemplo:
gcloud config set project lab-project-id-example - Si no recuerdas el ID del proyecto, puedes enumerar todos los IDs de tus proyectos con:
gcloud projects list
- Ejemplo:
- Deberías ver el siguiente mensaje:
Updated property [core/project].
4. Habilita las APIs
Para usar Vertex AI y otros servicios, debes habilitar las APIs necesarias en tu proyecto de Google Cloud.
- En la terminal, habilita las APIs:
- API de Vertex AI (
aiplatform.googleapis.com): Permite el uso de Vertex AI para ajustar y entregar modelos. - API de Cloud Storage (
storage.googleapis.com): Permite el almacenamiento de conjuntos de datos y artefactos de modelos.
gcloud services enable aiplatform.googleapis.com \ storage.googleapis.com - API de Vertex AI (
5. Configura el entorno del proyecto
Crea un directorio de trabajo
- En la terminal, crea un directorio para tu proyecto y navega hasta él.
mkdir gemini-finetuning cd gemini-finetuning
Configura variables de entorno
- En la terminal, define las variables de entorno para tu proyecto. Crearemos un archivo
env.shpara almacenar estas variables de modo que se puedan volver a cargar fácilmente si se desconecta tu sesión.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
Crea un bucket de Cloud Storage
- En la terminal, crea un bucket para almacenar tu conjunto de datos y artefactos de modelos.
gcloud storage buckets create gs://$BUCKET_NAME --project=$PROJECT_ID --location=$REGION
Configura el entorno virtual
- Usaremos
uvpara administrar nuestro entorno de Python. En la terminal, ejecuta lo siguiente:uv venv .venv source .venv/bin/activate - En la terminal, instala los paquetes de Python necesarios.
uv pip install google-cloud-aiplatform rouge-score matplotlib pandas tqdm
6. Prepara los datos de entrenamiento
Los datos de calidad son la base del ajuste exitoso. Usarás el conjunto de datos de WikiLingua, lo transformarás en el formato JSONL específico que requiere Gemini y lo subirás a tu bucket de almacenamiento.
- En la terminal, crea un archivo llamado
prepare_data.py.cloudshell edit prepare_data.py - Pega el siguiente código en
prepare_data.py.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() - En la terminal, ejecuta la secuencia de comandos de preparación de datos.
python prepare_data.py
7. Establece el rendimiento de referencia
Antes del ajuste, necesitas un parámetro de comparación. Medirás el rendimiento del modelo gemini-2.5-flash de base en la tarea de resumen con las puntuaciones ROUGE.
- En la terminal, crea un archivo llamado
evaluate.py.cloudshell edit evaluate.py - Pega el siguiente código en
evaluate.py.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() - En la terminal, ejecuta la evaluación de referencia.
Esto generará un archivopython evaluate.py --model "gemini-2.5-flash" --output "baseline.json"baseline.jsony un gráfico enplots/baseline_dist.png.
8. Configura y, luego, inicia el ajuste
Ahora iniciarás un trabajo de ajuste administrado en Vertex AI.
- En la terminal, crea un archivo llamado
tune.py.cloudshell edit tune.py - Pega el siguiente código en
tune.py.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() - En la terminal, ejecuta la secuencia de comandos de ajuste.
Nota: Este proceso puede tardar unos 45 minutos. Puedes supervisar el trabajo en la consola de Vertex AI.python tune.py
9. Comprende el código de entrenamiento
Mientras se ejecuta tu trabajo, echemos un vistazo más de cerca a la secuencia de comandos tune.py para comprender cómo funciona el ajuste.
Ajuste supervisado administrado
La secuencia de comandos usa el método vertexai.tuning.sft.train para enviar un trabajo de ajuste administrado. Esto abstrae la complejidad del aprovisionamiento de la infraestructura, la distribución del entrenamiento y la administración de los puntos de control.
sft_tuning_job = sft.train(
source_model="gemini-2.5-flash",
train_dataset=f"gs://{BUCKET_NAME}/datasets/train/train_gemini.jsonl",
# ...
)
Configuración de LoRA
En lugar de definir manualmente un LoraConfig como lo harías en frameworks de código abierto, Vertex AI simplifica esto en algunos parámetros clave:
adapter_size: Este parámetro (establecido en4en nuestra secuencia de comandos) controla la clasificación de los adaptadores de LoRA. Un tamaño más grande permite que el modelo aprenda adaptaciones más complejas, pero aumenta la cantidad de parámetros entrenables.epochs: Establecimos este valor en1para este lab para mantener el tiempo de entrenamiento corto (aproximadamente 20 minutos). En una situación de producción, puedes aumentar este valor para permitir que el modelo aprenda más profundamente de tus datos, aunque debes tener cuidado con el sobreajuste.
Selección de modelo
Especificamos explícitamente source_model="gemini-2.5-flash". Vertex AI admite varias versiones de Gemini, y fijar una versión específica garantiza que tu canalización permanezca estable y reproducible.
10. Comparar modelos
Una vez que se complete el trabajo de ajuste, puedes comparar el rendimiento de tu modelo nuevo con el de referencia.
- Obtén el extremo del modelo ajustado. Se imprimió al final de la secuencia de comandos
tune.py. Se verá comoprojects/.../locations/.../endpoints/.... - Vuelve a ejecutar la secuencia de comandos de evaluación y, esta vez, pasa tu modelo ajustado y los resultados de referencia para la comparación.
# 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" - Consulta los resultados. La secuencia de comandos generará una comparación de las puntuaciones ROUGE y un gráfico
plots/comparison.pngque muestra la mejora.Para ver los gráficos, abre la carpetaplotsen el editor de Cloud Shell.
11. Limpia
Para evitar que se generen cobros, borra los recursos que creaste.
- En la terminal, borra el bucket de Cloud Storage y el modelo ajustado.
gcloud storage rm -r gs://$BUCKET_NAME # Note: You can delete the model endpoint from the Vertex AI Console
12. ¡Felicitaciones!
Ajustaste correctamente Gemini 2.5 Flash en Vertex AI.
Resumen
En este lab, aprenderás a hacer lo siguiente:
- Preparar un conjunto de datos en formato JSONL para el ajuste de Gemini
- Establecer un modelo de referencia con el modelo Gemini 2.5 Flash de base
- Iniciar un trabajo de ajuste supervisado en Vertex AI
- Evaluar y comparar el modelo ajustado con el de referencia
¿Qué sigue?
Este lab forma parte de la ruta de aprendizaje de IA lista para producción con Google Cloud.
Explora el plan de estudios completo para cerrar la brecha entre el prototipo y la producción.
Comparte tu progreso con el hashtag #ProductionReadyAI.