1. مقدمة
نظرة عامة
في هذا الدرس التطبيقي حول الترميز، ستستخدم مهام Cloud Run لضبط نموذج Gemma 3 بدقة، ثم عرض النتيجة على Cloud Run باستخدام vLLM.
الإجراءات التي ستنفذّها
يمكنك تدريب نموذج للرد على عبارة معيّنة بنتيجة معيّنة باستخدام مجموعة بيانات KomeijiForce/Text2Emoji، التي تم إنشاؤها كجزء من EmojiLM: Modeling the New Emoji Language.
بعد التدريب، يستجيب النموذج لجملة مسبوقة بعبارة "الترجمة إلى إيموجي: "، وذلك من خلال عرض سلسلة من الإيموجي تتوافق مع تلك الجملة.
أهداف الدورة التعليمية
- كيفية إجراء الضبط الدقيق باستخدام وحدة معالجة الرسومات في Cloud Run Jobs
- كيفية عرض نموذج باستخدام Cloud Run مع vLLM
- كيفية استخدام إعداد Direct VPC لتسريع تحميل النموذج وعرضه في مهمة تستخدم وحدة معالجة الرسومات
2. قبل البدء
تفعيل واجهات برمجة التطبيقات
قبل البدء في استخدام هذا الدرس التطبيقي، فعِّل واجهات برمجة التطبيقات التالية من خلال تنفيذ ما يلي:
gcloud services enable run.googleapis.com \
compute.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
secretmanager.googleapis.com \
artifactregistry.googleapis.com
حصة وحدة معالجة الرسومات
راجِع مستندات حصة وحدة معالجة الرسومات للتأكّد من كيفية طلب الحصة.
إذا واجهت أي أخطاء "ليس لديك حصة لاستخدام وحدات معالجة الرسومات"، تأكَّد من حصتك على g.co/cloudrun/gpu-quota.
ملاحظة: إذا كنت تستخدم مشروعًا جديدًا، قد يستغرق ظهور الحصص في صفحة الحصص بضع دقائق بعد تفعيل واجهة برمجة التطبيقات.
Hugging Face
يستخدم هذا الدرس التطبيقي حول الترميز نموذجًا مستضافًا على Hugging Face. للحصول على هذا النموذج، اطلب رمز الوصول إلى حساب مستخدم Hugging Face مع إذن "القراءة". ستشير إلى هذا لاحقًا باسم YOUR_HF_TOKEN.
لاستخدام نموذج gemma-3-1b-it، يجب الموافقة على بنود الاستخدام.
3- الإعداد والمتطلبات
أعِدّ المراجع التالية:
- حساب خدمة "إدارة الهوية وإمكانية الوصول" وأذونات "إدارة الهوية وإمكانية الوصول" المرتبطة به
- Secret Manager secret لتخزين الرمز المميز الخاص بك في Hugging Face
- حزمة Cloud Storage لتخزين النموذج المعدَّل بدقة
- مستودع Artifact Registry لتخزين الصورة التي ستنشئها لضبط النموذج بدقة
- اضبط متغيّرات البيئة لهذا الدرس التطبيقي حول الترميز. لقد ملأنا عددًا من المتغيرات مسبقًا. حدِّد رقم تعريف مشروعك ومنطقتك والرمز المميّز الخاص بـ Hugging Face.
export PROJECT_ID=<YOUR_PROJECT_ID> export REGION=<YOUR_REGION> export HF_TOKEN=<YOUR_HF_TOKEN> export NEW_MODEL=gemma-emoji export AR_REPO=codelab-finetuning-jobs export IMAGE_NAME=finetune-to-gcs export JOB_NAME=finetuning-to-gcs-job export BUCKET_NAME=$PROJECT_ID-codelab-finetuning-jobs export SECRET_ID=HF_TOKEN export SERVICE_ACCOUNT="finetune-job-sa" export SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com - أنشئ حساب الخدمة من خلال تنفيذ الأمر التالي:
gcloud iam service-accounts create $SERVICE_ACCOUNT \ --display-name="Service account for fine-tuning codelab" - استخدِم Secret Manager لتخزين رمز الدخول إلى Hugging Face:
gcloud secrets create $SECRET_ID \ --replication-policy="automatic" printf $HF_TOKEN | gcloud secrets versions add $SECRET_ID --data-file=- - امنح حساب الخدمة دور Secret Manager Secret Accessor:
gcloud secrets add-iam-policy-binding $SECRET_ID \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role='roles/secretmanager.secretAccessor' - أنشئ حزمة ستستضيف النموذج المضبوط بدقة:
gcloud storage buckets create -l $REGION gs://$BUCKET_NAME - امنح حساب الخدمة إذن الوصول إلى الحزمة:
gcloud storage buckets add-iam-policy-binding gs://$BUCKET_NAME \ --member=serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role=roles/storage.objectAdmin - أنشئ مستودع Artifact Registry لتخزين صورة الحاوية:
gcloud artifacts repositories create $AR_REPO \ --repository-format=docker \ --location=$REGION \ --description="codelab for finetuning using CR jobs" \ --project=$PROJECT_ID
4. إنشاء صورة مهمة Cloud Run
في الخطوة التالية، ستنشئ الرمز الذي ينفّذ ما يلي:
- يستورد هذا الرمز نموذج Gemma من Hugging Face
- تُجري عملية ضبط دقيق على النموذج باستخدام مجموعة البيانات من Hugging Face. تستخدم المهمة وحدة معالجة رسومات واحدة من المستوى 4 لتحسين الأداء.
- تحميل النموذج المضبوط بدقة باسم
new_modelإلى حزمة Cloud Storage
- أنشئ دليلاً لرمز مهمة الضبط الدقيق.
mkdir codelab-finetuning-job cd codelab-finetuning-job - أنشئ ملفًا باسم
finetune.py# Copyright 2025 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import torch from datasets import load_dataset from peft import LoraConfig, PeftModel from transformers import ( AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments, ) from trl import SFTTrainer # Cloud Storage bucket to upload the model bucket_name = os.getenv("BUCKET_NAME", "YOUR_BUCKET_NAME") # The model that you want to train from the Hugging Face hub model_name = os.getenv("MODEL_NAME", "google/gemma-3-1b-it") # The instruction dataset to use dataset_name = "KomeijiForce/Text2Emoji" # Fine-tuned model name new_model = os.getenv("NEW_MODEL", "gemma-emoji") ############################ Setup ############################################ # Load the entire model on the GPU 0 device_map = {"": torch.cuda.current_device()} # Limit dataset to a random selection dataset = load_dataset(dataset_name, split="train").shuffle(seed=42).select(range(1000)) # Setup input formats: trains the model to respond to "Translate to emoji:" with emoji output. tokenizer = AutoTokenizer.from_pretrained(model_name) def format_to_chat(example): return { "conversations": [ {"role": "user", "content": f"Translate to emoji: {example['text']}"}, {"role": "assistant", "content": example["emoji"]}, ] } formatted_dataset = dataset.map( format_to_chat, batched=False, # Process row by row remove_columns=dataset.column_names, # Optional: Keep only the new column ) def apply_chat_template(examples): texts = tokenizer.apply_chat_template(examples["conversations"], tokenize=False) return {"text": texts} final_dataset = formatted_dataset.map(apply_chat_template, batched=True) ############################# Config ######################################### # Load tokenizer and model with QLoRA configuration bnb_4bit_compute_dtype = "float16" # Compute dtype for 4-bit base models compute_dtype = getattr(torch, bnb_4bit_compute_dtype) bnb_config = BitsAndBytesConfig( load_in_4bit=True, # Activate 4-bit precision base model loading bnb_4bit_quant_type="nf4", # Quantization type (fp4 or nf4) bnb_4bit_compute_dtype=compute_dtype, bnb_4bit_use_double_quant=False, # Activate nested quantization for 4-bit base models (double quantization) ) # Load base model model = AutoModelForCausalLM.from_pretrained( model_name, quantization_config=bnb_config, device_map=device_map, torch_dtype=torch.float16, ) model.config.use_cache = False model.config.pretraining_tp = 1 ############################## Train ########################################## # Load LoRA configuration peft_config = LoraConfig( lora_alpha=16, # Alpha parameter for LoRA scaling lora_dropout=0.1, # Dropout probability for LoRA layers, r=8, # LoRA attention dimension bias="none", task_type="CAUSAL_LM", target_modules=["q_proj", "v_proj"], ) # Set training parameters training_arguments = TrainingArguments( output_dir="./results", num_train_epochs=1, per_device_train_batch_size=1, # Batch size per GPU for training gradient_accumulation_steps=2, # Number of update steps to accumulate the gradients for optim="paged_adamw_32bit", save_steps=0, logging_steps=5, learning_rate=2e-4, # Initial learning rate (AdamW optimizer) weight_decay=0.001, # Weight decay to apply to all layers except bias/LayerNorm weights fp16=True, bf16=False, # Enable fp16/bf16 training max_grad_norm=0.3, # Maximum gradient normal (gradient clipping) warmup_ratio=0.03, # Ratio of steps for a linear warmup (from 0 to learning rate) group_by_length=True, # Group sequences into batches with same length # Saves memory and speeds up training considerably lr_scheduler_type="cosine", ) trainer = SFTTrainer( model=model, train_dataset=final_dataset, peft_config=peft_config, dataset_text_field="text", max_seq_length=512, # Maximum sequence length to use tokenizer=tokenizer, args=training_arguments, packing=False, # Pack multiple short examples in the same input sequence to increase efficiency ) trainer.train() trainer.model.save_pretrained(new_model) ################################# Save ######################################## # Reload model in FP16 and merge it with LoRA weights base_model = AutoModelForCausalLM.from_pretrained( model_name, low_cpu_mem_usage=True, return_dict=True, torch_dtype=torch.float16, device_map=device_map, ) model = PeftModel.from_pretrained(base_model, new_model) model = model.merge_and_unload() # push results to Cloud Storage file_path_to_save_the_model = "/finetune/new_model" model.save_pretrained(file_path_to_save_the_model) tokenizer.save_pretrained(file_path_to_save_the_model) - إنشاء ملف
requirements.txt:accelerate==0.34.2 bitsandbytes==0.45.5 datasets==2.19.1 transformers==4.51.3 peft==0.11.1 trl==0.8.6 torch==2.3.0 - إنشاء
Dockerfile:FROM nvidia/cuda:12.6.2-runtime-ubuntu22.04 RUN apt-get update && \ apt-get -y --no-install-recommends install python3-dev gcc python3-pip git && \ rm -rf /var/lib/apt/lists/* COPY requirements.txt /requirements.txt RUN pip3 install -r requirements.txt --no-cache-dir COPY finetune.py /finetune.py ENV PYTHONUNBUFFERED 1 CMD python3 /finetune.py --device cuda - أنشئ الحاوية في مستودع Artifact Registry:
gcloud builds submit \ --tag $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$IMAGE_NAME \ --region $REGION
5- تفعيل الوظيفة وتنفيذها
في هذه الخطوة، ستنشئ مهمة مع خروج مباشر من شبكة VPC لتحميل البيانات بشكل أسرع إلى Google Cloud Storage.
- إنشاء مهمة Cloud Run:
gcloud run jobs create $JOB_NAME \ --region $REGION \ --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$IMAGE_NAME \ --set-env-vars BUCKET_NAME=$BUCKET_NAME \ --set-secrets HF_TOKEN=$SECRET_ID:latest \ --cpu 8.0 \ --memory 32Gi \ --gpu 1 \ --add-volume name=finetuned_model,type=cloud-storage,bucket=$BUCKET_NAME \ --add-volume-mount volume=finetuned_model,mount-path=/finetune/new_model \ --service-account $SERVICE_ACCOUNT_ADDRESS - تنفيذ المهمة:
gcloud run jobs execute $JOB_NAME --region $REGION --async
سيستغرق إكمال المهمة 10 دقائق تقريبًا. يمكنك التحقّق من الحالة باستخدام الرابط المقدَّم في نتيجة الأمر الأخير.
6. استخدام خدمة Cloud Run لعرض النموذج المضبوط بدقة باستخدام vLLM
في هذه الخطوة، ستنشئ خدمة Cloud Run. يستخدم هذا الإعداد شبكة VPC مباشرةً للوصول إلى حزمة Cloud Storage عبر شبكة خاصة من أجل تسريع عمليات التنزيل.
- انشر خدمة Cloud Run:
gcloud run deploy serve-gemma-emoji \ --image us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250601_0916_RC01 \ --region $REGION \ --port 8000 \ --set-env-vars MODEL_ID=new_model,HF_HUB_OFFLINE=1 \ --cpu 8.0 \ --memory 32Gi \ --gpu 1 \ --add-volume name=finetuned_model,type=cloud-storage,bucket=$BUCKET_NAME \ --add-volume-mount volume=finetuned_model,mount-path=/finetune/new_model \ --service-account $SERVICE_ACCOUNT_ADDRESS \ --max-instances 1 \ --command python3 \ --args="-m,vllm.entrypoints.api_server,--model=/finetune/new_model,--tensor-parallel-size=1" \ --no-gpu-zonal-redundancy \ --labels=dev-tutorial=codelab-tuning \ --no-invoker-iam-check
7. اختبار النموذج المعدَّل
في هذه الخطوة، ستطلب من النموذج اختبار الضبط الدقيق باستخدام curl.
- احصل على عنوان URL الخاص بخدمة Cloud Run:
SERVICE_URL=$(gcloud run services describe serve-gemma-emoji \ --region $REGION --format 'value(status.url)') - أنشئ طلبًا لنموذجك.
USER_PROMPT="Translate to emoji: I ate a banana for breakfast, later I'm thinking of having soup!" - اتّصِل بالخدمة باستخدام curl لطلب النموذج، مع فلترة النتائج باستخدام jq:
curl -s -X POST ${SERVICE_URL}/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: bearer $(gcloud auth print-identity-token)" \ -d @- <<EOF | jq ".choices[0].message.content" { "model": "${NEW_MODEL}", "messages": [{ "role": "user", "content": [ { "type": "text", "text": "${USER_PROMPT}"}] }] } EOF
من المفترض أن تظهر لك استجابة مشابهة لما يلي:
🍌🤔😋🥣
8. تهانينا!
تهانينا على إكمال هذا الدرس العملي.
ننصحك بمراجعة مستندات وحدة معالجة الرسومات في Cloud Run Jobs.
المواضيع التي تناولناها
- كيفية إجراء الضبط الدقيق باستخدام وحدة معالجة الرسومات في Cloud Run Jobs
- كيفية عرض نموذج باستخدام Cloud Run مع vLLM
- كيفية استخدام إعداد Direct VPC لتسريع تحميل النموذج وعرضه في مهمة تستخدم وحدة معالجة الرسومات
9- تَنظيم
لتجنُّب الرسوم غير المقصودة، مثلاً إذا تم استدعاء خدمات Cloud Run مرات أكثر من عدد مرات الاستدعاء المخصّصة لك شهريًا في Cloud Run في الطبقة المجانية، يمكنك حذف خدمة Cloud Run التي أنشأتها في الخطوة 6.
لحذف خدمة Cloud Run، انتقِل إلى Cloud Run Cloud Console على https://console.cloud.google.com/run واحذف الخدمة serve-gemma-emoji.
لحذف المشروع بأكمله، انتقِل إلى إدارة المراجع، واختَر المشروع الذي أنشأته في الخطوة 2، ثم انقر على "حذف". إذا حذفت المشروع، عليك تغيير المشاريع في Cloud SDK. يمكنك الاطّلاع على قائمة بجميع المشاريع المتاحة من خلال تنفيذ gcloud projects list.