1. Введение
В этой лабораторной работе вы научитесь выполнять полный рабочий процесс контролируемой тонкой настройки модели Google Gemini, чтобы адаптировать ее для конкретной задачи: составления кратких обзоров статей. Хотя большие языковые модели обладают большой мощностью, их универсальность позволяет сделать их еще более эффективными для конкретных задач с помощью тонкой настройки. Обучив модель на высококачественном наборе примеров, вы сможете улучшить ее согласованность, качество и эффективность для вашей целевой задачи.
Вы будете использовать Gemini 3.5 Flash — облегченную и экономичную модель, а тонкую настройку будете выполнять с помощью Gemini Enterprise Agent Platform .
Обзор архитектуры
Вот что мы построим:
- Cloud Shell : Ваша среда разработки.
- Облачное хранилище : хранит данные для обучения/проверки в формате JSONL.
- Обучение работе с платформой Gemini Enterprise Agent : управляет процессом тонкой настройки.
- Конечная точка платформы агентов Gemini Enterprise : размещает вашу точно настроенную модель.
Что вы узнаете
- Подготовьте высококачественные наборы данных для контролируемой тонкой настройки.
- Настройте и запустите задачи тонкой настройки с помощью SDK Gemini Enterprise Agent Platform для Python .
- Оцените модели, используя автоматизированные метрики (оценки ROUGE).
- Сравните базовую и доработанную модели, чтобы количественно оценить улучшения.
2. Настройка проекта
Аккаунт Google
Если у вас еще нет личного аккаунта Google, вам необходимо его создать .
Используйте личный аккаунт вместо рабочего или учебного.
Войдите в консоль Google Cloud.
Войдите в консоль Google Cloud, используя личную учетную запись Google.
Включить выставление счетов
Использовать кредиты Google Cloud (необязательно)
Для проведения этого мастер-класса вам потребуется платежный аккаунт с достаточным балансом. Используйте средства, указанные на баннере вверху этого руководства, чтобы начать. Если у вас уже есть платежный аккаунт, вы можете пропустить этот шаг.
Создать проект (необязательно)
Если у вас нет текущего проекта, который вы хотели бы использовать для этой лабораторной работы, создайте новый проект здесь .
3. Откройте редактор Cloud Shell.
- Нажмите на эту ссылку, чтобы перейти непосредственно в редактор Cloud Shell.
- Если сегодня вам будет предложено авторизоваться, нажмите «Авторизовать» , чтобы продолжить.

- Если терминал не отображается внизу экрана, откройте его:
- Нажмите «Просмотреть».
- Нажмите «Терминал»

- В терминале настройте свой проект с помощью этой команды:
gcloud config set project [PROJECT_ID]- Пример:
gcloud config set project lab-project-id-example - Если вы не помните идентификатор своего проекта, вы можете перечислить все идентификаторы своих проектов с помощью следующей команды:
gcloud projects list
- Пример:
- Вы должны увидеть следующее сообщение:
Updated property [core/project].
4. Включите API.
Для использования платформы Gemini Enterprise Agent Platform и других сервисов необходимо включить необходимые API в вашем проекте Google Cloud.
- В терминале включите API:
- API Vertex AI (
aiplatform.googleapis.com): позволяет использовать Vertex AI для тонкой настройки и запуска моделей. - API облачного хранилища (
storage.googleapis.com): позволяет хранить наборы данных и артефакты моделей.
gcloud services enable aiplatform.googleapis.com \ storage.googleapis.com - API Vertex AI (
5. Настройка среды проекта
Создайте рабочую директорию
- В терминале создайте директорию для вашего проекта и перейдите в неё.
mkdir gemini-finetuning cd gemini-finetuning
Настройте переменные среды.
- В терминале определите переменные окружения для вашего проекта. Мы создадим файл
env.shдля хранения этих переменных, чтобы их можно было легко перезагрузить в случае разрыва сессии.cat <<EOF > env.sh export PROJECT_ID=\$(gcloud config get-value project) export REGION="us-central1" export LOCATION="global" export BUCKET_NAME="\${PROJECT_ID}-gemini-tuning" EOF source env.sh
Создайте корзину облачного хранилища.
- В терминале создайте хранилище (bucket) для хранения вашего набора данных и артефактов модели.
gcloud storage buckets create gs://$BUCKET_NAME --project=$PROJECT_ID --location=$REGION
Настройка виртуальной среды
- Для управления средой Python мы будем использовать
uv. В терминале выполните следующую команду:uv venv .venv source .venv/bin/activate - В терминале установите необходимые пакеты Python.
uv pip install google-cloud-aiplatform rouge-score matplotlib pandas tqdm
6. Подготовьте обучающие данные.
Качественные данные — основа успешной тонкой настройки. Вы будете использовать набор данных WikiLingua , преобразовывать его в специфический формат JSONL, требуемый Gemini, и загружать в свой накопитель.
- В терминале создайте файл с именем
prepare_data.py.cloudshell edit prepare_data.py - Вставьте следующий код в
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 3.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() - В терминале запустите скрипт подготовки данных.
python prepare_data.py
7. Определите базовый уровень производительности.
Перед тонкой настройкой вам потребуется эталонный показатель. Вы измерите, насколько хорошо базовая модель gemini-3.5-flash справляется с задачей суммаризации, используя оценки ROUGE.
- В терминале создайте файл с именем
evaluate.py.cloudshell edit evaluate.py - Вставьте следующий код в
evaluate.py.import argparse import json import os import pandas as pd from google import genai from google.genai import types from rouge_score import rouge_scorer from tqdm import tqdm import matplotlib.pyplot as plt import time # Configuration for Google Gen AI SDK PROJECT_ID = os.environ.get("PROJECT_ID", "") def get_client(model_name): os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "TRUE" os.environ["GOOGLE_CLOUD_PROJECT"] = PROJECT_ID if "locations/" in model_name: parts = model_name.split("/") loc = parts[parts.index("locations") + 1] if loc == "us": loc = "us-central1" else: loc = os.environ.get("LOCATION", "global") os.environ["GOOGLE_CLOUD_LOCATION"] = loc return genai.Client() def evaluate(model_name, test_file, max_samples=50, output_json="results.json"): print(f"Evaluating model: {model_name}") client = get_client(model_name) # Load Test Data test_df = pd.read_csv(test_file) test_df = test_df.head(max_samples) config = types.GenerateContentConfig( 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 = client.models.generate_content( model=model_name, contents=input_text, config=config, ) 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-3.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() - В терминале запустите базовую оценку.
В результате будет создан файлpython evaluate.py --model "gemini-3.5-flash" --output "baseline.json"baseline.jsonи график вplots/baseline_dist.png.
8. Настройте и запустите тонкую настройку.
Теперь вы запустите управляемое задание тонкой настройки на платформе Gemini Enterprise Agent Platform.
- В терминале создайте файл с именем
tune.pycloudshell edit tune.py - Вставьте следующий код в
tune.pyimport os import time from google import genai from google.genai import types # Configuration for Google Gen AI SDK os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "TRUE" os.environ["GOOGLE_CLOUD_PROJECT"] = os.environ.get("PROJECT_ID", "") os.environ["GOOGLE_CLOUD_LOCATION"] = os.environ.get("REGION", "us-central1") BUCKET_NAME = os.environ["BUCKET_NAME"] client = genai.Client() def train(): print("Launching fine-tuning job...") training_dataset = types.TuningDataset( gcs_uri=f"gs://{BUCKET_NAME}/datasets/train/train_gemini.jsonl" ) validation_dataset = types.TuningValidationDataset( gcs_uri=f"gs://{BUCKET_NAME}/datasets/val/val_gemini.jsonl" ) tuning_job = client.tunings.tune( base_model="gemini-3.5-flash", training_dataset=training_dataset, config=types.CreateTuningJobConfig( tuned_model_display_name="gemini-3.5-flash-wikilingua", validation_dataset=validation_dataset, adapter_size=types.AdapterSize.ADAPTER_SIZE_FOUR, epoch_count=1, ), ) print(f"Job started: {tuning_job.name}") print("Waiting for job to complete... (this may take ~45 minutes)") running_states = {"JOB_STATE_PENDING", "JOB_STATE_RUNNING"} while tuning_job.state in running_states: time.sleep(60) tuning_job = client.tunings.get(name=tuning_job.name) print(f"Status: {tuning_job.state}") print("Job completed!") print(f"Tuned Model Endpoint: {tuning_job.tuned_model.endpoint}") return tuning_job.tuned_model.endpoint if __name__ == "__main__": train() - В терминале запустите скрипт тонкой настройки.
Примечание : Этот процесс может занять около 45 минут. Вы можете отслеживать ход выполнения задания в консоли платформы Gemini Enterprise Agent .python tune.py
9. Разберитесь в коде обучения.
Пока ваша задача выполняется, давайте подробнее рассмотрим скрипт tune.py , чтобы понять, как работает тонкая настройка.
Управляемая контролируемая тонкая настройка
Скрипт использует метод vertexai.tuning.sft.train для отправки управляемого задания на настройку. Это позволяет избежать сложностей, связанных с выделением инфраструктуры, распределением обучающих данных и управлением контрольными точками.
sft_tuning_job = sft.train(
source_model="gemini-3.5-flash",
train_dataset=f"gs://{BUCKET_NAME}/datasets/train/train_gemini.jsonl",
# ...
)
Конфигурация LoRA
Вместо того чтобы вручную задавать LoraConfig , как это можно делать в фреймворках с открытым исходным кодом, Gemini Enterprise Agent Platform упрощает этот процесс, сводя его к нескольким ключевым параметрам:
-
adapter_size: Этот параметр (в нашем скрипте установлен на4) управляет рангом адаптеров LoRA. Больший размер позволяет модели изучать более сложные адаптации, но увеличивает количество обучаемых параметров. -
epochs: В этой лабораторной работе мы установили это значение равным1, чтобы сократить время обучения (~20 минут). В реальных условиях вы можете увеличить это значение, чтобы модель могла глубже обучаться на ваших данных, хотя следует остерегаться переобучения.
Выбор модели
Мы явно указываем source_model="gemini-3.5-flash" . Платформа Gemini Enterprise Agent Platform поддерживает различные версии Gemini, и привязка к конкретной версии гарантирует стабильность и воспроизводимость вашего конвейера.
10. Сравните модели
После завершения тонкой настройки вы можете сравнить производительность вашей новой модели с базовым показателем.
- Получите конечную точку вашей настроенной модели. Она была выведена в конце скрипта
tune.pyОна будет выглядеть примерно так:projects/.../locations/.../endpoints/.... - Запустите скрипт оценки еще раз, на этот раз передав для сравнения вашу настроенную модель и результаты базовой версии.
# 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" - Просмотрите результаты. Скрипт выведет сравнение оценок ROUGE и сгенерирует диаграмму
plots/comparison.png, демонстрирующую улучшение. Вы можете просмотреть графики, открыв папкуplotsв редакторе Cloud Shell.
11. Уборка
Чтобы избежать дополнительных расходов, удалите созданные вами ресурсы.
- В терминале удалите сегмент Cloud Storage и настроенную модель.
gcloud storage rm -r gs://$BUCKET_NAME # Note: You can delete the model endpoint from the Gemini Enterprise Agent Platform Console
12. Поздравляем!
Вы успешно выполнили тонкую настройку Gemini 3.5 Flash на платформе Gemini Enterprise Agent!
Краткий обзор
В этой лаборатории вы:
- Для тонкой настройки Gemini был подготовлен набор данных в формате JSONL.
- Установлены базовые параметры с использованием базовой модели Gemini 3.5 Flash.
- Запущена задача контролируемой тонкой настройки на платформе Gemini Enterprise Agent Platform.
- Была проведена оценка и сравнение доработанной модели с базовой.
Что дальше?
Данная лабораторная работа является частью учебного курса "Готовый к внедрению ИИ в производство с использованием Google Cloud" .
Изучите полный учебный план, чтобы преодолеть разрыв между прототипом и серийным производством.
Делитесь своими успехами, используя хэштег #ProductionReadyAI .