1. Giriş
Genel Bakış
Bu codelab'de, bir Cloud Run işlevi için yan araçta gemma3:4b modelini nasıl barındıracağınızı öğreneceksiniz. Bir Cloud Storage paketine dosya yüklendiğinde Cloud Run işlevi tetiklenir. Bu işlev, dosyanın içeriğini özetleme için yardımcı dosyadaki Gemma 3'e gönderir.
Neler öğreneceksiniz?
- GPU'lar kullanılarak yan kapsayıcıda barındırılan bir LLM ve Cloud Run işleviyle çıkarım yapma
- Modelin daha hızlı yüklenmesi ve sunulması için Cloud Run GPU'da doğrudan VPC çıkışı yapılandırmasını kullanma
- Barındırılan Ollama modelinizle arayüz oluşturmak için Genkit'i kullanma
2. Başlamadan önce
GPU özelliğini kullanmak için desteklenen bir bölgede kota artışı isteğinde bulunmanız gerekir. Gerekli kota, Cloud Run Admin API'nin altında bulunan nvidia_l4_gpu_allocation_no_zonal_redundancy'dir. Kota isteğinde bulunabileceğiniz doğrudan bağlantıyı burada bulabilirsiniz.
3. Kurulum ve Gereksinimler
Bu codelab boyunca kullanılacak ortam değişkenlerini ayarlayın.
PROJECT_ID=<YOUR_PROJECT_ID>
REGION=<YOUR_REGION>
AR_REPO=codelab-crf-sidecar-gpu
FUNCTION_NAME=crf-sidecar-gpu
BUCKET_GEMMA_NAME=$PROJECT_ID-codelab-crf-sidecar-gpu-gemma3
BUCKET_DOCS_NAME=$PROJECT_ID-codelab-crf-sidecar-gpu-docs
SERVICE_ACCOUNT="crf-sidecar-gpu"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
IMAGE_SIDECAR=$REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/ollama-gemma3
Aşağıdaki komutu çalıştırarak hizmet hesabını oluşturun:
gcloud iam service-accounts create $SERVICE_ACCOUNT \
--display-name="SA for codelab crf sidecar with gpu"
Cloud Run işlevinin kimliği olarak kullanılan bu hizmet hesabını, Cloud Run işlevini çağırmak için Eventarc tetikleyicisinin hizmet hesabı olarak kullanırız. Dilerseniz Eventarc için farklı bir hizmet hesabı oluşturabilirsiniz.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
--role=roles/run.invoker
Ayrıca hizmet hesabına Eventarc etkinliklerini alma erişimi de verin.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_ADDRESS" \
--role="roles/eventarc.eventReceiver"
İnce ayarlı modelinizi barındıracak bir paket oluşturun. Bu codelab'de bölgesel bir paket kullanılır. Çok bölgeli bir paket de kullanabilirsiniz.
gsutil mb -l $REGION gs://$BUCKET_GEMMA_NAME
Ardından, SA'ya pakete erişim izni verin.
gcloud storage buckets add-iam-policy-binding gs://$BUCKET_GEMMA_NAME \
--member=serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
--role=roles/storage.objectAdmin
Şimdi, özetlenmesini istediğiniz dokümanları depolayacak bir bölgesel paket oluşturun. Eventarc tetikleyicisini buna göre güncellemeniz koşuluyla (bu codelab'in sonunda gösterilmiştir) çok bölgeli bir paket de kullanabilirsiniz.
gsutil mb -l $REGION gs://$BUCKET_DOCS_NAME
Ardından, hizmet hesabına Gemma 3 paketine erişim izni verin.
gcloud storage buckets add-iam-policy-binding gs://$BUCKET_GEMMA_NAME \
--member=serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
--role=roles/storage.objectAdmin
ve Dokümanlar grubu.
gcloud storage buckets add-iam-policy-binding gs://$BUCKET_DOCS_NAME \
--member=serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
--role=roles/storage.objectAdmin
Ollama görüntüsü için bir Artifact Registry deposu oluşturun. Bu görüntü, yan kapsayıcıda kullanılacaktır.
gcloud artifacts repositories create $AR_REPO \
--repository-format=docker \
--location=$REGION \
--description="codelab for CR function and gpu sidecar" \
--project=$PROJECT_ID
4. Gemma 3 modelini indirme
Öncelikle ollama'dan Gemma 3 4b modelini indirmeniz gerekir. Bunun için ollama'yı yükleyip gemma3:4b modelini yerel olarak çalıştırmanız gerekir.
curl -fsSL https://ollama.com/install.sh | sh
ollama serve
Şimdi ayrı bir terminal penceresinde modeli çekmek için aşağıdaki komutu çalıştırın. Cloud Shell kullanıyorsanız sağ üstteki menü çubuğunda artı simgesini tıklayarak ek bir terminal penceresi açabilirsiniz.
ollama run gemma3:4b
Ollama çalıştıktan sonra modele soru sorabilirsiniz. Örneğin:
"why is the sky blue?"
Ollama ile sohbeti bitirdikten sonra aşağıdaki komutu çalıştırarak sohbetten çıkabilirsiniz:
/bye
Ardından, ilk terminal penceresinde ollama'nın yerel olarak sunulmasını durdurmak için aşağıdaki komutu çalıştırın:
# on Linux / Cloud Shell press Ctrl^C or equivalent for your shell
Ollama'nın modelleri işletim sisteminize bağlı olarak nereye indirdiğini buradan öğrenebilirsiniz.
https://github.com/ollama/ollama/blob/main/docs/faq.md#where-are-models-stored
Cloud Workstations kullanıyorsanız indirilen ollama modellerini burada /home/$USER/.ollama/models bulabilirsiniz.
Modellerinizin burada barındırıldığını onaylayın:
ls /home/$USER/.ollama/models
Şimdi gemma3:4b modelini GCS paketinize taşıyın.
gsutil cp -r /home/$USER/.ollama/models gs://$BUCKET_GEMMA_NAME
5. Cloud Run işlevini oluşturma
Kaynak kodunuz için bir kök klasör oluşturun.
mkdir codelab-crf-sidecar-gpu &&
cd codelab-crf-sidecar-gpu &&
mkdir cr-function &&
mkdir ollama-gemma3 &&
cd cr-function
src adlı bir alt klasör oluşturun. Klasörde index.ts adlı bir dosya oluşturun.
mkdir src &&
touch src/index.ts
index.ts dosyasını aşağıdaki kodla güncelleyin:
//import util from 'util';
import { cloudEvent, CloudEvent } from "@google-cloud/functions-framework";
import { StorageObjectData } from "@google/events/cloud/storage/v1/StorageObjectData";
import { Storage } from "@google-cloud/storage";
// Initialize the Cloud Storage client
const storage = new Storage();
import { genkit } from 'genkit';
import { ollama } from 'genkitx-ollama';
const ai = genkit({
plugins: [
ollama({
models: [
{
name: 'gemma3:4b',
type: 'generate', // type: 'chat' | 'generate' | undefined
},
],
serverAddress: 'http://127.0.0.1:11434', // default local address
}),
],
});
// Register a CloudEvent callback with the Functions Framework that will
// be triggered by Cloud Storage.
//functions.cloudEvent('helloGCS', await cloudEvent => {
cloudEvent("gcs-cloudevent", async (cloudevent: CloudEvent<StorageObjectData>) => {
console.log("---------------\nProcessing for ", cloudevent.subject, "\n---------------");
if (cloudevent.data) {
const data = cloudevent.data;
if (data && data.bucket && data.name) {
const bucketName = cloudevent.data.bucket;
const fileName = cloudevent.data.name;
const filePath = `${cloudevent.data.bucket}/${cloudevent.data.name}`;
console.log(`Attempting to download: ${filePath}`);
try {
// Get a reference to the bucket
const bucket = storage.bucket(bucketName!);
// Get a reference to the file
const file = bucket.file(fileName!);
// Download the file's contents
const [content] = await file.download();
// 'content' is a Buffer. Convert it to a string.
const fileContent = content.toString('utf8');
console.log(`Sending file to Gemma 3 for summarization`);
const { text } = await ai.generate({
model: 'ollama/gemma3:4b',
prompt: `Summarize the following document in just a few sentences ${fileContent}`,
});
console.log(text);
} catch (error: any) {
console.error('An error occurred:', error.message);
}
} else {
console.warn("CloudEvent bucket name is missing!", cloudevent);
}
} else {
console.warn("CloudEvent data is missing!", cloudevent);
}
});
Şimdi kök dizinde crf-sidecar-gpu aşağıdaki içeriklere sahip package.json adlı bir dosya oluşturun:
{
"main": "lib/index.js",
"name": "ingress-crf-genkit",
"version": "1.0.0",
"scripts": {
"build": "tsc"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@google-cloud/functions-framework": "^3.4.0",
"@google-cloud/storage": "^7.0.0",
"genkit": "^1.1.0",
"genkitx-ollama": "^1.1.0",
"@google/events": "^5.4.0"
},
"devDependencies": {
"typescript": "^5.5.2"
}
}
Aşağıdaki içeriklerle kök dizin düzeyinde bir tsconfig.json dosyası da oluşturun:
{
"compileOnSave": true,
"include": [
"src"
],
"compilerOptions": {
"module": "commonjs",
"noImplicitReturns": true,
"outDir": "lib",
"sourceMap": true,
"strict": true,
"target": "es2017",
"skipLibCheck": true,
"esModuleInterop": true
}
}
6. İşlevi dağıtma
Bu adımda, aşağıdaki komutu çalıştırarak Cloud Run işlevini dağıtacaksınız.
Not: Maksimum örnek sayısı, GPU kotanızdan küçük veya bu değere eşit bir sayı olarak ayarlanmalıdır.
gcloud beta run deploy $FUNCTION_NAME \
--region $REGION \
--function gcs-cloudevent \
--base-image nodejs22 \
--source . \
--no-allow-unauthenticated \
--max-instances 2 # this should be less than or equal to your GPU quota
7. Sidecar dosyası oluşturma
Ollama'yı Cloud Run hizmetinde barındırma hakkında daha fazla bilgiyi https://cloud.google.com/run/docs/tutorials/gpu-gemma-with-ollama adresinde bulabilirsiniz.
Sidecar'ınızın dizinine gidin:
cd ../ollama-gemma3
Aşağıdaki içeriklerle bir Dockerfile dosyası oluşturun:
FROM ollama/ollama:latest
# Listen on all interfaces, port 11434
ENV OLLAMA_HOST 0.0.0.0:11434
# Store model weight files in /models
ENV OLLAMA_MODELS /models
# Reduce logging verbosity
ENV OLLAMA_DEBUG false
# Never unload model weights from the GPU
ENV OLLAMA_KEEP_ALIVE -1
# Store the model weights in the container image
ENV MODEL gemma3:4b
RUN ollama serve & sleep 5 && ollama pull $MODEL
# Start Ollama
ENTRYPOINT ["ollama", "serve"]
Görüntüyü oluşturma
gcloud builds submit \
--tag $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/ollama-gemma3 \
--machine-type e2-highcpu-32
8. İşlevi yardımcı dosya ile güncelleme
Mevcut bir hizmete, işe veya işleve yardımcı dosya eklemek için YAML dosyasını yardımcı dosyayı içerecek şekilde güncelleyebilirsiniz.
Yeni dağıttığınız Cloud Run işlevinin YAML'sini almak için şu komutu çalıştırın:
gcloud run services describe $FUNCTION_NAME --format=export > add-sidecar-service.yaml
Şimdi YAML'yi aşağıdaki gibi güncelleyerek yardımcı dosyayı CRf'ye ekleyin:
- Aşağıdaki YAML parçasını doğrudan
runtimeClassName: run.googleapis.com/linux-base-image-updatesatırının üstüne ekleyin.-image, giriş kapsayıcısı öğesiyle-imagehizalanmalıdır.
- image: YOUR_IMAGE_SIDECAR:latest
name: gemma-sidecar
env:
- name: OLLAMA_FLASH_ATTENTION
value: '1'
resources:
limits:
cpu: 6000m
nvidia.com/gpu: '1'
memory: 16Gi
volumeMounts:
- name: gcs-1
mountPath: /root/.ollama
startupProbe:
failureThreshold: 2
httpGet:
path: /
port: 11434
initialDelaySeconds: 60
periodSeconds: 60
timeoutSeconds: 60
nodeSelector:
run.googleapis.com/accelerator: nvidia-l4
volumes:
- csi:
driver: gcsfuse.run.googleapis.com
volumeAttributes:
bucketName: YOUR_BUCKET_GEMMA_NAME
name: gcs-1
- YAML parçasını ortam değişkenlerinizle güncellemek için aşağıdaki komutu çalıştırın:
sed -i "s|YOUR_IMAGE_SIDECAR|$IMAGE_SIDECAR|; s|YOUR_BUCKET_GEMMA_NAME|$BUCKET_GEMMA_NAME|" add-sidecar-service.yaml
Tamamlanmış YAML dosyanız şöyle görünmelidir:
##############################################
# DO NOT COPY - For illustration purposes only
##############################################
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
annotations:
run.googleapis.com/build-base-image: us-central1-docker.pkg.dev/serverless-runtimes/google-22/runtimes/nodejs22
run.googleapis.com/build-enable-automatic-updates: 'true'
run.googleapis.com/build-function-target: gcs-cloudevent
run.googleapis.com/build-id: f0122905-a556-4000-ace4-5c004a9f9ec6
run.googleapis.com/build-image-uri:<YOUR_IMAGE_CRF>
run.googleapis.com/build-name: <YOUR_BUILD_NAME>
run.googleapis.com/build-source-location: <YOUR_SOURCE_LOCATION>
run.googleapis.com/ingress: all
run.googleapis.com/ingress-status: all
run.googleapis.com/urls: '["<YOUR_CLOUD_RUN_FUNCTION_URLS"]'
labels:
cloud.googleapis.com/location: <YOUR_REGION>
name: <YOUR_FUNCTION_NAME>
namespace: '392295011265'
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/maxScale: '4'
run.googleapis.com/base-images: '{"":"us-central1-docker.pkg.dev/serverless-runtimes/google-22/runtimes/nodejs22"}'
run.googleapis.com/client-name: gcloud
run.googleapis.com/client-version: 514.0.0
run.googleapis.com/startup-cpu-boost: 'true'
labels:
client.knative.dev/nonce: hzhhrhheyd
run.googleapis.com/startupProbeType: Default
spec:
containerConcurrency: 80
containers:
- image: <YOUR_FUNCTION_IMAGE>
ports:
- containerPort: 8080
name: http1
resources:
limits:
cpu: 1000m
memory: 512Mi
startupProbe:
failureThreshold: 1
periodSeconds: 240
tcpSocket:
port: 8080
timeoutSeconds: 240
- image: <YOUR_SIDECAR_IMAGE>:latest
name: gemma-sidecar
env:
- name: OLLAMA_FLASH_ATTENTION
value: '1'
resources:
limits:
cpu: 6000m
nvidia.com/gpu: '1'
memory: 16Gi
volumeMounts:
- name: gcs-1
mountPath: /root/.ollama
startupProbe:
failureThreshold: 2
httpGet:
path: /
port: 11434
initialDelaySeconds: 60
periodSeconds: 60
timeoutSeconds: 60
nodeSelector:
run.googleapis.com/accelerator: nvidia-l4
volumes:
- csi:
driver: gcsfuse.run.googleapis.com
volumeAttributes:
bucketName: <YOUR_BUCKET_NAME>
name: gcs-1
runtimeClassName: run.googleapis.com/linux-base-image-update
serviceAccountName: <YOUR_SA_ADDRESS>
timeoutSeconds: 300
traffic:
- latestRevision: true
percent: 100
##############################################
# DO NOT COPY - For illustration purposes only
##############################################
Şimdi aşağıdaki komutu çalıştırarak işlevi yardımcı dosya ile güncelleyin.
gcloud run services replace add-sidecar-service.yaml
Son olarak, işlev için Eventarc tetikleyicisini oluşturun. Bu komut, işlevi de ekler.
Not: Çok bölgeli bir paket oluşturduysanız --location parametresini değiştirmeniz gerekir.
gcloud eventarc triggers create my-crf-summary-trigger \
--location=$REGION \
--destination-run-service=$FUNCTION_NAME \
--destination-run-region=$REGION \
--event-filters="type=google.cloud.storage.object.v1.finalized" \
--event-filters="bucket=$BUCKET_DOCS_NAME" \
--service-account=$SERVICE_ACCOUNT_ADDRESS
9. İşlevinizi test etme
Özetleme için düz metin dosyası yükleyin. Neyi özetleyeceğinizi bilmiyor musunuz? Gemini'dan köpeklerin tarihiyle ilgili 1-2 sayfalık kısa bir açıklama isteyin. Ardından, Gemma3:4b modelinin işlev günlüklerine özet yazması için bu düz metin dosyasını $BUCKET_DOCS_NAME paketinize yükleyin.
Günlüklerde aşağıdakine benzer bir ifade görürsünüz:
---------------
Processing for objects/dogs.txt
---------------
Attempting to download: <YOUR_PROJECT_ID>-codelab-crf-sidecar-gpu-docs/dogs.txt
Sending file to Gemma 3 for summarization
...
Here's a concise summary of the document "Humanity's Best Friend":
The dog's domestication, beginning roughly 20,000-40,000 years ago, represents a unique, deeply intertwined evolutionary partnership with humans, predating the domestication of any other animal
<...>
solidifying their long-standing role as humanity's best friend.
10. Sorun giderme
Karşılaşabileceğiniz bazı yazım hataları:
PORT 8080 is in usehatası alırsanız Ollama sidecar'ınızın Dockerfile'ında 11434 bağlantı noktasının kullanıldığından emin olun. Ayrıca, artırılmış gerçeklik (AR) deponuzda birden fazla Ollama resmi varsa doğru yardımcı dosya resmini kullandığınızdan emin olun. Cloud Run işlevi 8080 numaralı bağlantı noktasında çalışır. 8080 numaralı bağlantı noktasında çalışan bir yan araba olarak farklı bir Ollama görüntüsü kullandıysanız bu hatayla karşılaşırsınız.failed to build: (error ID: 7485c5b6): function.js does not existhatasını alırsanız package.json ve tsconfig.json dosyalarınızın src diziniyle aynı düzeyde olduğundan emin olun.ERROR: (gcloud.run.services.replace) spec.template.spec.node_selector: Max instances must be set to 4 or fewer in order to set GPU requirements.hatası alırsanız YAML dosyanızdaautoscaling.knative.dev/maxScale: '100'değerini 1 olarak veya GPU kotanızdan küçük ya da kotanıza eşit bir değere değiştirin.