1. บทนำ
ในห้องทดลองนี้ คุณจะได้เรียนรู้วิธีการทำงานทั้งหมดของการปรับแต่งแบบมีผู้ดูแลในโมเดล Google Gemini เพื่อปรับให้เหมาะกับงานที่เฉพาะเจาะจง นั่นคือการสรุปบทความ แม้ว่าโมเดลภาษาขนาดใหญ่จะมีประสิทธิภาพ แต่ลักษณะการใช้งานทั่วไปหมายความว่าโมเดลเหล่านี้จะมีประสิทธิภาพมากขึ้นสำหรับกรณีการใช้งานเฉพาะผ่านการปรับแต่ง การฝึกโมเดลในชุดข้อมูลตัวอย่างคุณภาพสูงจะช่วยปรับปรุงความสอดคล้อง คุณภาพ และประสิทธิภาพของโมเดลสำหรับงานเป้าหมายได้
คุณจะใช้ Gemini 2.5 Flash ซึ่งเป็นโมเดลที่มีน้ำหนักเบาและคุ้มค่า และทำการปรับแต่งโดยใช้ Vertex AI
ภาพรวมสถาปัตยกรรม
สิ่งที่เราจะสร้างมีดังนี้
- Cloud Shell: สภาพแวดล้อมในการพัฒนาซอฟต์แวร์
- Cloud Storage: จัดเก็บข้อมูลการฝึก/การตรวจสอบในรูปแบบ JSONL
- การฝึก Vertex AI: จัดการงานการปรับแต่ง
- ปลายทาง Vertex AI: โฮสต์โมเดลที่ปรับแต่งแล้ว
สิ่งที่คุณจะได้เรียนรู้
- เตรียมชุดข้อมูลคุณภาพสูงสำหรับการปรับแต่งภายใต้การควบคุมดูแล
- กำหนดค่าและเปิดใช้งานงานการปรับแต่งโดยใช้ Vertex AI SDK สำหรับ Python
- ประเมินโมเดลโดยใช้เมตริกอัตโนมัติ (คะแนน ROUGE)
- เปรียบเทียบโมเดลพื้นฐานกับโมเดลที่ปรับแต่งแล้วเพื่อวัดผลการปรับปรุง
2. การตั้งค่าโปรเจ็กต์
บัญชี Google
หากยังไม่มีบัญชี Google ส่วนบุคคล คุณต้องสร้างบัญชี Google
ใช้บัญชีส่วนตัวแทนบัญชีของที่ทำงานหรือโรงเรียน
ลงชื่อเข้าใช้ Google Cloud Console
ลงชื่อเข้าใช้ Google Cloud Console โดยใช้บัญชี Google ส่วนตัว
เปิดใช้การเรียกเก็บเงิน
แลกรับเครดิต Google Cloud มูลค่า $5 (ไม่บังคับ)
หากต้องการจัดเวิร์กช็อปนี้ คุณต้องมีบัญชีสำหรับการเรียกเก็บเงินที่มีเครดิตอยู่บ้าง หากวางแผนที่จะใช้การเรียกเก็บเงินของคุณเอง ให้ข้ามขั้นตอนนี้
- คลิกลิงก์นี้ แล้วลงชื่อเข้าใช้ด้วยบัญชี Google ส่วนบุคคล คุณจะเห็นข้อความคล้ายกับนี้

- คลิกปุ่มคลิกที่นี่เพื่อเข้าถึงเครดิต ระบบจะนำคุณไปยังหน้าเพื่อตั้งค่าโปรไฟล์การเรียกเก็บเงิน

- คลิกยืนยัน
ตอนนี้คุณเชื่อมต่อกับบัญชีสำหรับการเรียกเก็บเงินของ Google Cloud Platform เวอร์ชันทดลองใช้งานแล้ว

สร้างโปรเจ็กต์ (ไม่บังคับ)
หากไม่มีโปรเจ็กต์ปัจจุบันที่ต้องการใช้สำหรับแล็บนี้ ให้สร้างโปรเจ็กต์ใหม่ที่นี่
3. เปิดเครื่องมือแก้ไข Cloud Shell
- คลิกลิงก์นี้เพื่อไปยัง Cloud Shell Editor โดยตรง
- หากระบบแจ้งให้ให้สิทธิ์ในวันนี้ ให้คลิกให้สิทธิ์เพื่อดำเนินการต่อ

- หากเทอร์มินัลไม่ปรากฏที่ด้านล่างของหน้าจอ ให้เปิดโดยทำดังนี้
- คลิกดู
- คลิก Terminal

- ในเทอร์มินัล ให้ตั้งค่าโปรเจ็กต์ด้วยคำสั่งนี้
gcloud config set project [PROJECT_ID]- ตัวอย่าง
gcloud config set project lab-project-id-example - หากจำรหัสโปรเจ็กต์ไม่ได้ คุณสามารถแสดงรหัสโปรเจ็กต์ทั้งหมดได้โดยใช้คำสั่งต่อไปนี้
gcloud projects list
- ตัวอย่าง
- คุณควรเห็นข้อความต่อไปนี้
Updated property [core/project].
4. เปิดใช้ API
หากต้องการใช้ Vertex AI และบริการอื่นๆ คุณต้องเปิดใช้ API ที่จำเป็นในโปรเจ็กต์ Google Cloud
- เปิดใช้ API ในเทอร์มินัลโดยทำดังนี้
- Vertex AI API (
aiplatform.googleapis.com): ช่วยให้ใช้ Vertex AI ในการปรับแต่งและแสดงโมเดลได้ - Cloud Storage API (
storage.googleapis.com): เปิดใช้การจัดเก็บชุดข้อมูลและอาร์ติแฟกต์ของโมเดล
gcloud services enable aiplatform.googleapis.com \ storage.googleapis.com - Vertex AI API (
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 BUCKET_NAME="\${PROJECT_ID}-gemini-tuning" EOF source env.sh
สร้างที่เก็บข้อมูล Cloud Storage
- ในเทอร์มินัล ให้สร้างที่เก็บข้อมูลเพื่อจัดเก็บชุดข้อมูลและอาร์ติแฟกต์ของโมเดล
gcloud storage buckets create gs://$BUCKET_NAME --project=$PROJECT_ID --location=$REGION
ตั้งค่าสภาพแวดล้อมเสมือน
- เราจะใช้
uvเพื่อจัดการสภาพแวดล้อม Python ในเทอร์มินัล ให้เรียกใช้คำสั่งต่อไปนี้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.pyimport 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() - เรียกใช้สคริปต์การเตรียมข้อมูลในเทอร์มินัล
python prepare_data.py
7. กำหนดประสิทธิภาพพื้นฐาน
คุณต้องมีเกณฑ์เปรียบเทียบก่อนจึงจะปรับแต่งได้ คุณจะวัดประสิทธิภาพของโมเดลพื้นฐาน gemini-2.5-flash ในงานสรุปโดยใช้คะแนน ROUGE
- สร้างไฟล์ชื่อ
evaluate.pyในเทอร์มินัลcloudshell edit evaluate.py - วางโค้ดต่อไปนี้ลงใน
evaluate.pyimport 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() - เรียกใช้การประเมินพื้นฐานในเทอร์มินัล
ซึ่งจะสร้างไฟล์python evaluate.py --model "gemini-2.5-flash" --output "baseline.json"baseline.jsonและพล็อตในplots/baseline_dist.png
8. กำหนดค่าและเปิดตัวการปรับแต่ง
ตอนนี้คุณจะเปิดตัวงานการปรับแต่งที่มีการจัดการใน Vertex AI
- สร้างไฟล์ชื่อ
tune.pyในเทอร์มินัลcloudshell edit tune.py - วางโค้ดต่อไปนี้ลงใน
tune.pyimport 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() - เรียกใช้สคริปต์การปรับแต่งในเทอร์มินัล
หมายเหตุ: กระบวนการนี้อาจใช้เวลาประมาณ 45 นาที คุณสามารถตรวจสอบงานได้ใน Vertex AI Consolepython tune.py
9. ทำความเข้าใจรหัสการฝึก
ขณะที่งานกำลังทำงาน มาดูtune.pyสคริปต์อย่างละเอียดเพื่อทำความเข้าใจวิธีการทำงานของการปรับแต่งกัน
การปรับแต่งที่มีการควบคุมดูแลที่มีการจัดการ
สคริปต์ใช้วิธี vertexai.tuning.sft.train เพื่อส่งงานการปรับแต่งที่จัดการ ซึ่งช่วยลดความซับซ้อนของการจัดสรรโครงสร้างพื้นฐาน การกระจายการฝึก และการจัดการจุดตรวจสอบ
sft_tuning_job = sft.train(
source_model="gemini-2.5-flash",
train_dataset=f"gs://{BUCKET_NAME}/datasets/train/train_gemini.jsonl",
# ...
)
การกำหนดค่า LoRA
Vertex AI ช่วยลดความซับซ้อนในการกำหนด LoraConfig ด้วยตนเองเหมือนในเฟรมเวิร์กโอเพนซอร์สให้เหลือเพียงพารามิเตอร์หลักๆ 2-3 รายการ ดังนี้
adapter_size: พารามิเตอร์นี้ (ตั้งค่าเป็น4ในสคริปต์ของเรา) จะควบคุมอันดับของอะแดปเตอร์ LoRA ขนาดที่ใหญ่ขึ้นช่วยให้โมเดลเรียนรู้การดัดแปลงที่ซับซ้อนมากขึ้นได้ แต่จะเพิ่มจำนวนพารามิเตอร์ที่ฝึกได้epochs: เราตั้งค่านี้เป็น1สำหรับ Lab นี้เพื่อให้เวลาในการฝึกสั้นลง (~20 นาที) ในสถานการณ์การใช้งานจริง คุณอาจเพิ่มค่านี้เพื่อให้โมเดลเรียนรู้จากข้อมูลได้ลึกซึ้งยิ่งขึ้น แต่ควรระวังการเกิด Overfitting
การเลือกโมเดล
เราจะระบุ source_model="gemini-2.5-flash" อย่างชัดเจน Vertex AI รองรับ 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 Editor
11. ล้างข้อมูล
โปรดลบทรัพยากรที่คุณสร้างขึ้นเพื่อไม่ให้มีการเรียกเก็บเงิน
- ในเทอร์มินัล ให้ลบที่เก็บข้อมูล Cloud Storage และโมเดลที่ปรับแต่งแล้ว
gcloud storage rm -r gs://$BUCKET_NAME # Note: You can delete the model endpoint from the Vertex AI Console
12. ยินดีด้วย
คุณปรับแต่ง Gemini 2.5 Flash บน Vertex AI เรียบร้อยแล้ว
สรุป
ในห้องทดลองนี้ คุณจะได้ทำสิ่งต่อไปนี้
- จัดเตรียมชุดข้อมูลในรูปแบบ JSONL สำหรับการปรับแต่ง Gemini
- กำหนดค่าพื้นฐานโดยใช้โมเดล Gemini 2.5 Flash ฐาน
- เปิดตัวงานการปรับแต่งภายใต้การควบคุมดูแลใน Vertex AI
- ประเมินและเปรียบเทียบโมเดลที่ปรับแต่งอย่างละเอียดกับเกณฑ์พื้นฐาน
ขั้นตอนถัดไป
แล็บนี้เป็นส่วนหนึ่งของเส้นทางการเรียนรู้AI พร้อมใช้งานจริงด้วย Google Cloud
ดูหลักสูตรทั้งหมดเพื่อเชื่อมช่องว่างจากต้นแบบไปสู่การผลิต
แชร์ความคืบหน้าของคุณด้วยแฮชแท็ก #ProductionReadyAI