GKE স্ট্যান্ডার্ড-এ উচ্চ-পারফরম্যান্স ডিস্ট্রিবিউটেড আরএল: সম্পূর্ণ নির্দেশিকা

১. ভূমিকা

এই ল্যাবে trl লাইব্রেরির সাহায্যে গ্রুপ রিলেটিভ পলিসি অপটিমাইজেশন (GRPO) অ্যালগরিদম ব্যবহার করে, GKE এজেন্ট স্যান্ডবক্স (gVisor) সহ GKE স্ট্যান্ডার্ড- এ একটি উচ্চ-পারফরম্যান্সের ডিস্ট্রিবিউটেড রিইনফোর্সমেন্ট লার্নিং (RL) ট্রেনিং লুপ কীভাবে তৈরি, প্রোভিশন এবং এক্সিকিউট করতে হয়, তা বিস্তারিতভাবে বর্ণনা করা হয়েছে।

এর লক্ষ্য হলো, একটি RL ট্রেনিং লুপ চলাকালীন কীভাবে অবিশ্বস্ত, LLM-দ্বারা তৈরি কোডকে নিরাপদে মূল্যায়ন করা যায়, তা প্রদর্শন করা। আমরা অর্কেস্ট্রেশন প্লেন (Ray)-কে এক্সিকিউশন প্লেন (GKE এজেন্ট স্যান্ডবক্স) থেকে বিচ্ছিন্ন করার মাধ্যমে এটি অর্জন করি।

আরএল কোড মূল্যায়নের প্রযুক্তিগত চ্যালেঞ্জ

রিইনফোর্সমেন্ট লার্নিং ব্যবহার করে এলএলএম এজেন্টদের প্রশিক্ষণ দেওয়ার সময় (যেমন, ইউনিট টেস্টে মডেলের আউটপুট মূল্যায়ন করে তাকে কোড লিখতে প্রশিক্ষণ দেওয়া), প্রশিক্ষণ লুপটিকে সমান্তরালভাবে হাজার হাজার অবিশ্বস্ত, এলএলএম-দ্বারা তৈরি পাইথন স্ক্রিপ্ট চালাতে হয়। এটি গুরুতর কিছু চ্যালেঞ্জ তৈরি করে:

  1. পড চার্ন বটলনেক: প্রচলিত ইভ্যালুয়েশন ফ্রেমওয়ার্কগুলো প্রতিটি টাস্কের জন্য একটি করে নতুন ডকার কন্টেইনার চালু করে। একটি আরএল ট্রেনিং লুপ চলাকালীন শত শত সমান্তরাল রোলআউটের জন্য গতিশীলভাবে এটি করার ফলে কুবারনেটিস কন্ট্রোল প্লেনের উপর মারাত্মক চাপ সৃষ্টি হয়। এই ল্যাটেন্সির কারণে উচ্চ-ফ্রিকোয়েন্সির আরএল ট্রেনিং অসম্ভব হয়ে পড়ে।
  2. নিরাপত্তা ঝুঁকি: সাধারণ কন্টেইনার রানটাইমের ভেতরে LLM দ্বারা তৈরি যথেচ্ছ কোড চালালে তা হোস্ট OS কার্নেল ব্যবহার করে। একটিমাত্র এস্কেপ ভালনারেবিলিটি আপনার নোডগুলোকে ঝুঁকিতে ফেলতে পারে।
  3. আইএএম টোকেন চুরি: কুবারনেটিস পডের ভিতরে চলমান এলএলএম-জেনারেটেড কোড ক্লাউড প্রোভাইডারের মেটাডেটা সার্ভারকে কোয়েরি করে নোড আইএএম সার্ভিস অ্যাকাউন্ট টোকেন চুরি করতে পারে।

সমাধান: বিচ্ছিন্ন অর্কেস্ট্রেশন ও এক্সিকিউশন

এই স্থাপত্য অর্কেস্ট্রেশনকে এক্সিকিউশন থেকে বিচ্ছিন্ন করে :

  • অর্কেস্ট্রেটর (রে): একটি ডিস্ট্রিবিউটেড রে ক্লাস্টার আরএল ট্রেনিং লুপ পরিচালনা করে এবং রোলআউট জেনারেশন বিতরণ করে।
  • এক্সিকিউশন প্লেন (GKE এজেন্ট স্যান্ডবক্স): ডাইনামিকভাবে কুবারনেটিস পড তৈরি করার পরিবর্তে, রে ওয়ার্কাররা একটি ডেডিকেটেড স্যান্ডবক্স রাউটারে সাধারণ HTTP কল করে। রাউটারটি সঙ্গে সঙ্গে ওয়ার্কারকে gVisor (GKE স্যান্ডবক্স) -এর অধীনে চলমান একটি আইসোলেটেড, প্রি-ওয়ার্মড কন্টেইনার বরাদ্দ করে দেয়।
  • সাব-সেকেন্ড ল্যাটেন্সি: যেহেতু স্যান্ডবক্সগুলি একটি পরিচালিত SandboxWarmPool এ আগে থেকেই প্রস্তুত রাখা হয় এবং একটি উচ্চ-গতির HTTP গেটওয়ের মাধ্যমে পরিচালিত হয়, তাই এনভায়রনমেন্ট তৈরির সময় ২০০ মিলিসেকেন্ডের নিচে নেমে আসে, যা কুবারনেটিস কন্ট্রোল প্লেনকে সম্পূর্ণরূপে বাইপাস করে।

ল্যাবের উদ্দেশ্য

এই কোডল্যাবে আপনি শিখবেন:

  • আরএল লুপে অবিশ্বস্ত কোড মূল্যায়নের স্থাপত্যগত প্রতিবন্ধকতা ও সমাধান।
  • কার্যকরী রোলআউটের জন্য কীভাবে কাস্টম স্যান্ডবক্স ইমেজ তৈরি করবেন।
  • GKE এজেন্ট স্যান্ডবক্স এবং স্যান্ডবক্সওয়ার্মপুল কীভাবে কনফিগার ও ব্যবহার করবেন।
  • IAM টোকেন চুরি রোধ করতে স্যান্ডবক্সগুলোকে কীভাবে নিরাপদে আলাদা করা যায়।
  • রে ব্যবহার করে এক্সিকিউশন থেকে অর্কেস্ট্রেশনকে বিচ্ছিন্ন রেখে কীভাবে SweBench এবং TRL দিয়ে একটি বেসিক RL ট্রেনিং জব চালানো যায়।

২. ক্লাস্টার গঠন ও পূর্বশর্তসমূহ

এগিয়ে যাওয়ার আগে, প্রশিক্ষণের কাজের চাপ পরিচালনা করার জন্য আপনার একটি উচ্চ-ক্ষমতাসম্পন্ন GPU নোড পুলসহ GKE ক্লাস্টার এবং Ray Operator ইনস্টল করা থাকতে হবে।

পূর্বশর্ত

এই কোডল্যাবটি ধরে নেয় যে নিম্নলিখিত টুলগুলি ইনস্টল এবং কনফিগার করা আছে:

পরিবেশগত পরিবর্তনশীল

প্রথমে, এই কোডল্যাব জুড়ে ব্যবহৃত হবে এমন এনভায়রনমেন্ট ভেরিয়েবলগুলো সেট করুন। নিচের কমান্ডগুলোতে যুক্তিসঙ্গত ডিফল্ট মান ব্যবহার করা হয়েছে, কিন্তু আপনার নির্দিষ্ট গুগল ক্লাউড এনভায়রনমেন্টের সাথে মেলানোর জন্য আপনি প্রয়োজন অনুযায়ী সেগুলো পরিবর্তন করতে পারেন:

export PROJECT_ID=$(gcloud config get-value project)
export REGION="us-west3"
export ZONE="us-west3-a"
export REPO_NAME="rl-sandbox-repo"

কাস্টম কন্টেইনার ইমেজগুলো রাখার জন্য একটি আর্টিফ্যাক্ট রেজিস্ট্রি রিপোজিটরি তৈরি করুন:

gcloud artifacts repositories create $REPO_NAME \
    --repository-format=docker \
    --location=$REGION \
    --description="Repository for RL Sandbox images"

ক্লাস্টার কনফিগারেশন

এআই ওয়ার্কলোডের জন্য অপ্টিমাইজ করা একটি GKE ক্লাস্টার প্রোভিশনিং করার সম্পূর্ণ নির্দেশনার জন্য (GPUDirect RDMA নেটওয়ার্ক ওয়্যারিং সহ), অফিসিয়াল ডকুমেন্টেশন অনুসরণ করুন: একটি GKE AI হাইপারকম্পিউট কাস্টম ক্লাস্টার তৈরি করুন।

গুরুত্বপূর্ণ পূর্বশর্ত: আপনার ক্লাস্টার বা কোনো নির্দিষ্ট এক্সিকিউশন নোড পুল তৈরি করার সময়, স্যান্ডবক্স ওয়ার্ম পুলগুলির জন্য প্রয়োজনীয় কাস্টম রিসোর্স ডেফিনিশন (CRD) ইনস্টল করতে অবশ্যই --enable-agent-sandbox এবং --sandbox type=gvisor ফ্ল্যাগগুলি পাস করুন।

আপনার ক্লাস্টার, জিপিইউ এবং রে অপারেটর চালু আছে ধরে নিলে, নিচে এক্সিকিউশন প্লেন কনফিগার করা এবং আরএল লুপ চালানোর পদ্ধতি বিস্তারিতভাবে বর্ণনা করা হয়েছে।

৩. কাস্টম ইমেজ তৈরি করুন

উচ্চ-পারফরম্যান্স আরএল (RL) চালানোর একটি অত্যন্ত গুরুত্বপূর্ণ দিক হলো আপনার ইমেজগুলোর মধ্যেই ডিপেন্ডেন্সিগুলো অন্তর্ভুক্ত করা। আমাদের দুটি স্বতন্ত্র ইমেজ প্রয়োজন: একটি মডেলটি চালনাকারী জিপিইউ ওয়ার্কারদের জন্য, এবং অন্যটি অবিশ্বস্ত ইভ্যালুয়েশন কোড চালনাকারী বিচ্ছিন্ন স্যান্ডবক্সগুলোর জন্য।

১. জিপিইউ ওয়ার্কার ইমেজ তৈরি করুন

ল্যাঙ্গুয়েজ মডেল চালানো এবং ট্রেনিং লুপ পরিচালনা করার জন্য Ray GPU ওয়ার্কারের লাইব্রেরি প্রয়োজন হয়। আমরা এই ইমেজটি অফিশিয়াল vLLM ইমেজের উপর ভিত্তি করে তৈরি করেছি, ফলে এটি সর্বশেষ GPU-গুলোকে সাপোর্ট করে এবং এতে PyTorch/CUDA আগে থেকেই ইনস্টল করা থাকে।

Dockerfile.gpu_worker তৈরি করতে নিম্নলিখিত কমান্ডটি চালান:

cat << 'EOF' > Dockerfile.gpu_worker
# ==============================================================================
# Base Image: Use the official vLLM production image. 
# This image comes pre-baked with PyTorch 2.11, CUDA 13.0, and vLLM.
# It supports sm_100 Blackwell GPUs natively!
# ==============================================================================
FROM vllm/vllm-openai:latest

USER root

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    numactl \
    libnuma-dev \
    wget \
    ca-certificates \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Install Ray, TRL, and Sandbox tools
# TRL does not require compiling flash_attn from source.
RUN pip install --no-cache-dir \
    "ray[default]==2.55.1" \
    "numpy<2.0" \
    gymnasium>=0.28.1 \
    k8s-agent-sandbox>=0.4.6 \
    trl transformers packaging ninja cachetools accelerate datasets peft
EOF

ইমেজটি বিল্ড করে আপনার আর্টিফ্যাক্ট রেজিস্ট্রি রিপোজিটরিতে পুশ করুন:

export WORKER_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/ray-gpu-worker:v1"
docker build -f Dockerfile.gpu_worker -t $WORKER_REPO .
docker push $WORKER_REPO

দ্রষ্টব্য: এই নির্দেশিকাটি ইমেজ তৈরি করতে স্থানীয় docker কমান্ড ব্যবহার করে। আপনি যদি দূরবর্তীভাবে ইমেজ তৈরি করতে চান, তাহলে এর পরিবর্তে ক্লাউড বিল্ড ব্যবহার করতে পারেন (যেমন gcloud builds submit ব্যবহার করে)।

২. সিপিইউ হেড ইমেজ তৈরি করুন

Ray হেড নোড শুধুমাত্র ক্লাস্টারটি পরিচালনা করে এবং ভারী GPU ট্রেনিং মডেলগুলো চালায় না। আপনার স্ট্যান্ডার্ড CPU নোডগুলোতে একটি বিশাল ইমেজ পুল বটলনেক (সাধারণত ১৫ জিবি+) এড়ানোর জন্য, আমরা হেড নোডের জন্য একটি হালকা, শুধুমাত্র CPU-ভিত্তিক ইমেজ তৈরি করি। এই ইমেজে Ray এবং প্রয়োজনীয় Python লাইব্রেরিগুলো থাকে, কিন্তু CUDA এবং vLLM-এর মতো ভারী GPU লাইব্রেরিগুলো থাকে না।

Dockerfile.head তৈরি করতে নিম্নলিখিত কমান্ডটি চালান:

cat << 'EOF' > Dockerfile.head
# ==============================================================================
# Base Image: Use the official Python slim image for the exact patch version.
# This aligns the Python version (3.12.13) with the GPU worker node.
# ==============================================================================
FROM python:3.12.13-slim

USER root

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    wget \
    ca-certificates \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Install Ray, TRL, and Sandbox tools (CPU versions where applicable)
# We install torch CPU first to avoid pulling the 2GB+ CUDA torch package.
RUN pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cpu && \
    pip install --no-cache-dir \
    "ray[default]==2.55.1" \
    "numpy<2.0" \
    gymnasium>=0.28.1 \
    k8s-agent-sandbox>=0.4.6 \
    trl transformers packaging ninja cachetools accelerate datasets peft

# Create a 'ray' user to run the container securely and match Ray conventions
RUN useradd -ms /bin/bash ray
USER ray
WORKDIR /home/ray
EOF

ইমেজটি তৈরি করুন এবং পুশ করুন:

export HEAD_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/ray-head:v1"
docker build -f Dockerfile.head -t $HEAD_REPO .
docker push $HEAD_REPO

৩. স্যান্ডবক্স ইমেজ তৈরি করুন

আমরা যে কাজটি মূল্যায়ন করছি, তার জন্য স্যান্ডবক্সটিতে নির্দিষ্ট ডিপেন্ডেন্সিগুলোর প্রয়োজন হয়, যাতে রানটাইম ইনস্টলেশন তাৎক্ষণিক হয়। এই কোডল্যাবের জন্য, আমরা SWE-bench-এর django/django রিপোজিটরি থেকে একটি ইস্যু ব্যবহার করব। আমরা রিপোজিটরিটি প্রি-ক্লোন করব এবং পাইথন এনভায়রনমেন্টগুলো প্রি-বিল্ড করব, যাতে আমাদের মডেল স্ক্রিপ্টগুলো RL লুপে সেগুলো ডাউনলোড করতে গিয়ে সময় নষ্ট না করে।

Dockerfile.sandbox তৈরি করতে নিম্নলিখিত কমান্ডটি চালান:

cat << 'EOF' > Dockerfile.sandbox
# Use a stable Debian-based Miniconda image
FROM condaforge/miniforge3:latest

# 1. Install essential system libraries (including sqlite3 for Django tests)
RUN apt-get update && apt-get install -y \
    git \
    build-essential \
    libsqlite3-dev \
    && rm -rf /var/lib/apt/lists/*

# 2. Set up the /workspace directory and grant ownership to the pre-existing non-root 'ubuntu' user (UID 1000)
RUN mkdir -p /workspace \
    && chown -R 1000:1000 /workspace

# 3. Switch to the non-root user
USER ubuntu
WORKDIR /workspace

# 4. Pre-configure Git globally so the agent can run git commands
RUN git config --global user.email "agent@gke-sandbox.local" \
    && git config --global user.name "Agent"

# 5. Pre-clone the repository as the non-root user
RUN git clone https://github.com/django/django.git .

# 6. Pre-build Conda environments and pre-cache common dependencies
# We do NOT run "pip install -e ." here to avoid Python version conflicts with the main branch.
# Instead, we pre-install the heavy dependencies so that runtime installation is instantaneous.
RUN conda create -y -n django-py39 python=3.9 \
    && conda run -n django-py39 pip install --no-cache-dir asgiref sqlparse tzdata pytest pytest-django

RUN conda create -y -n django-py310 python=3.10 \
    && conda run -n django-py310 pip install --no-cache-dir asgiref sqlparse tzdata pytest pytest-django

# --- Add Agent Server ---
# We use a multi-stage build to copy the agent server from the official python-runtime-sandbox image
COPY --from=registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0 /app /opt/sandbox-agent
USER root
RUN chown -R 1000:1000 /opt/sandbox-agent \
    && /opt/conda/bin/pip install --no-cache-dir -r /opt/sandbox-agent/requirements.txt \
    && sed -i 's|"/app"|"/workspace"|g' /opt/sandbox-agent/main.py
USER ubuntu
# ------------------------

# Prepend the django-py39 conda environment bin to PATH for commands executed inside the container
ENV PATH=/home/ubuntu/.conda/envs/django-py39/bin:$PATH

# Keep the container alive and run the agent server using the system Python
CMD ["/opt/conda/bin/python3", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8888", "--log-level", "trace", "--app-dir", "/opt/sandbox-agent"]
EOF

ইমেজটি তৈরি করুন এবং পুশ করুন:

export SANDBOX_REPO="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/django-sandbox:v1"
docker build -f Dockerfile.sandbox -t $SANDBOX_REPO .
docker push $SANDBOX_REPO

৪. অর্কেস্ট্রেশন এবং এক্সিকিউশন কনফিগার করুন

এখন আমরা অর্কেস্ট্রেশনের জন্য রে ক্লাস্টার এবং এক্সিকিউশনের জন্য স্যান্ডবক্স রিসোর্সগুলো ডেপ্লয় করব।

১. রে ক্লাস্টার কনফিগারেশন

একটি RayCluster কাস্টম রিসোর্স স্থাপন করুন। মনে রাখবেন যে আপনার ক্লাস্টারের উপলব্ধ রিসোর্স (যেমন মেমরি, সিপিইউ, বা জিপিইউ টাইপ) ভিন্ন হতে পারে। সেই অনুযায়ী resources অনুরোধ এবং সীমা সামঞ্জস্য করুন।

raycluster.yaml তৈরি করতে নিম্নলিখিত কমান্ডটি চালান। এটি cat << EOF ব্যবহার করে স্বয়ংক্রিয়ভাবে আপনার এনভায়রনমেন্ট ভেরিয়েবলগুলোকে ম্যানিফেস্টে প্রতিস্থাপন করে:

cat << EOF > raycluster.yaml
apiVersion: ray.io/v1
kind: RayCluster
metadata:
  name: grpo-cluster
  namespace: default
spec:
  rayVersion: "2.55.1"
  headGroupSpec:
    rayStartParams:
      dashboard-host: "0.0.0.0"
    template:
      spec:
        containers:
        - name: ray-head
          image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/ray-head:v1
          ports:
          - containerPort: 6379
            name: gcs-server
          - containerPort: 8265
            name: dashboard
          - containerPort: 10001
            name: client
          resources:
            limits:
              cpu: "2"
              memory: "8Gi"
            requests:
              cpu: "2"
              memory: "8Gi"
  workerGroupSpecs:
  - groupName: gpu-group
    replicas: 1
    minReplicas: 1
    maxReplicas: 1
    rayStartParams: {}
    template:
      spec:
        containers:
        - name: ray-worker
          image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/ray-gpu-worker:v1
          resources:
            limits:
              cpu: "12"
              memory: "120Gi"
              nvidia.com/gpu: "1"
            requests:
              cpu: "12"
              memory: "120Gi"
              nvidia.com/gpu: "1"
EOF

এটি প্রয়োগ করুন:

kubectl apply -f raycluster.yaml

ক্লাস্টারটি তৈরি হয়েছে এবং চালু আছে কিনা তা যাচাই করুন (এতে কয়েক মিনিট সময় লাগতে পারে):

kubectl get raycluster

প্রত্যাশিত আউটপুট:

NAME       DESIRED WORKERS   AVAILABLE WORKERS   CPUS   MEMORY   GPUS   STATUS   AGE
rl-cluster   1                 1                                            ready    2m

২. স্যান্ডবক্স রাউটার কনফিগারেশন

SandboxRouter একটি উচ্চ-গতির HTTP গেটওয়ে হিসেবে কাজ করে, যা Ray ওয়ার্কারদের কাছ থেকে অনুরোধ গ্রহণ করে এবং ধীরগতির Kubernetes API সার্ভার পড লাইফসাইকেলকে বাইপাস করে সেগুলোকে তাৎক্ষণিকভাবে উপলব্ধ gVisor পডগুলিতে সংযুক্ত করে।

sandbox_router.yaml তৈরি করতে নিম্নলিখিত কমান্ডটি চালান:

cat << 'EOF' > sandbox_router.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: sandbox-claim-manager
rules:
- apiGroups: ["extensions.agents.x-k8s.io"]
  resources: ["sandboxclaims"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["agents.x-k8s.io"]
  resources: ["sandboxes"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sandbox-claim-manager-binding
  namespace: default
subjects:
- kind: ServiceAccount
  name: default
  namespace: default
roleRef:
  kind: Role
  name: sandbox-claim-manager
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Service
metadata:
  name: sandbox-router
  namespace: default
spec:
  type: ClusterIP
  selector:
    app: sandbox-router
  ports:
  - name: http
    protocol: TCP
    port: 8080
    targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sandbox-router-deployment
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: sandbox-router
  template:
    metadata:
      labels:
        app: sandbox-router
    spec:
      containers:
      - name: router
        image: us-central1-docker.pkg.dev/k8s-staging-images/agent-sandbox/sandbox-router:latest-main
        ports:
        - containerPort: 8080
        env:
        - name: ALLOW_UNAUTHENTICATED_ROUTER
          value: "true"
EOF

এটি প্রয়োগ করুন:

kubectl apply -f sandbox_router.yaml

ডেপ্লয়মেন্টটি চালু আছে কিনা যাচাই করুন:

kubectl get deployment sandbox-router-deployment

প্রত্যাশিত আউটপুট:

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
sandbox-router-deployment   2/2     2            2           1m

৩. স্যান্ডবক্স টেমপ্লেট এবং ওয়ার্ম পুল কনফিগারেশন

GKE এজেন্ট স্যান্ডবক্স, স্যান্ডবক্স রাউটার ব্যবহার করে বিচ্ছিন্ন ও পূর্ব-প্রস্তুত কন্টেইনার তাৎক্ষণিকভাবে বরাদ্দ করার সুযোগ দেয়। পডগুলোকে প্রস্তুত রাখার জন্য আমরা একটি SandboxTemplate এবং একটি SandboxWarmPool নির্ধারণ করি।

আপনার এনভায়রনমেন্ট ভেরিয়েবলগুলো দিয়ে sandbox_warmpool.yaml তৈরি করতে নিম্নলিখিত কমান্ডটি চালান:

cat << EOF > sandbox_warmpool.yaml
apiVersion: extensions.agents.x-k8s.io/v1alpha1
kind: SandboxTemplate
metadata:
  name: swe-bench-django
  namespace: default
spec:
  podTemplate:
    spec:
      runtimeClassName: gvisor
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
      nodeSelector:
        sandbox.gke.io/runtime: gvisor
      tolerations:
      - key: sandbox.gke.io/runtime
        operator: Equal
        value: gvisor
        effect: NoSchedule
      containers:
      - name: sandbox
        image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO_NAME}/django-sandbox:v1
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
            - ALL
        resources:
          requests:
            cpu: "2"
            memory: "4Gi"
          limits:
            cpu: "2"
            memory: "4Gi"
---
apiVersion: extensions.agents.x-k8s.io/v1alpha1
kind: SandboxWarmPool
metadata:
  name: swe-bench-django-warmpool
  namespace: default
spec:
  replicas: 10
  sandboxTemplateRef:
    name: swe-bench-django
EOF

এটি প্রয়োগ করুন:

kubectl apply -f sandbox_warmpool.yaml

SandboxWarmPool চালু হয়েছে কিনা তা যাচাই করুন:

kubectl get sandboxwarmpool

প্রত্যাশিত আউটপুট:

NAME                        READY   AGE
swe-bench-django-warmpool   10      1m

৪. নিরাপত্তা বিচ্ছিন্নতা

একটি নেটওয়ার্ক পলিসি স্যান্ডবক্সগুলোকে কঠোরভাবে বিচ্ছিন্ন করে রাখে, যা GCP মেটাডেটা সার্ভারে বহির্গমনকে বাধা দেয় এবং এর ফলে IAM টোকেন চুরি প্রতিরোধ করে।

network_policy.yaml তৈরি করতে নিম্নলিখিত কমান্ডটি চালান:

cat << 'EOF' > network_policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: block-metadata-egress
  namespace: default
spec:
  podSelector:
    matchLabels:
      sandbox.gke.io/runtime: gvisor
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 169.254.169.254/32
EOF

নীতিমালা প্রয়োগ করুন:

kubectl apply -f network_policy.yaml

নেটওয়ার্ক পলিসি তৈরি করা হয়েছে কিনা তা যাচাই করুন:

kubectl get networkpolicy

প্রত্যাশিত আউটপুট:

NAME                 POD-SELECTOR     AGE
block-metadata-egress             sandbox.gke.io/runtime=gvisor     1m

৫. SweBench এবং TRL ব্যবহার করে বেসিক RL জব

ক্লাস্টার এবং স্যান্ডবক্সগুলো প্রস্তুত হয়ে গেলে, আমরা একটি GRPO ট্রেনিং লুপ চালাতে পারব। আমরা GRPO অ্যালগরিদমটি পরিচালনা করার জন্য trl লাইব্রেরি এবং বিচ্ছিন্ন স্যান্ডবক্সগুলোর ভেতরে তৈরি হওয়া কোড মূল্যায়ন করার জন্য ray রিমোট ফাংশন ব্যবহার করব।

এই কোডল্যাবের এক্সিকিউশন দ্রুত করার জন্য, আমরা একটিমাত্র জ্যাঙ্গো ইস্যুতে সীমাবদ্ধ থাকব। নিচের রাউটিং লজিকটি দেখায় যে কীভাবে আপনি বিভিন্ন রিপোজিটরির জন্য আলাদা আলাদা ওয়ার্মপুল নির্বাচন করবেন, যা সম্পূর্ণ SWE-বেঞ্চ ডেটাসেটে সম্প্রসারণের সময় কাজে আসে।

প্রশিক্ষণ স্ক্রিপ্ট

train_trl.py তৈরি করতে নিম্নলিখিত কমান্ডটি চালান:

cat << 'EOF' > train_trl.py
import ray
from k8s_agent_sandbox import SandboxClient
from k8s_agent_sandbox.models import SandboxDirectConnectionConfig
from trl import GRPOConfig, GRPOTrainer
from transformers import AutoModelForCausalLM, AutoTokenizer
from datasets import load_dataset
import urllib.request
import re

ray.init(ignore_reinit_error=True)

# 1. Define the Ray remote evaluation function
@ray.remote
def evaluate_rollout(code, prompt_data):
    client = SandboxClient(connection_config=SandboxDirectConnectionConfig(api_url="http://sandbox-router.default.svc.cluster.local:8080"))
    
    # Claim a pre-warmed sandbox instantly based on the repo
    repo = prompt_data.get("repo")
    
    # In a full system, you'd route to different warmpools based on repo
    # Here we default to django for our single task
    sandbox = client.create_sandbox(
        template="swe-bench-django",
        warmpool="swe-bench-django-warmpool",
        sandbox_ready_timeout=600
    )
    
    try:
        # Check if the code is correctly formatted
        bash_match = re.search(r"```bash\n(.*?)\n```", code, re.DOTALL)
        if not bash_match:
            return 0.0
            
        script = bash_match.group(1)

        # In a real environment, we would apply the base commit and install here
        # For simplicity, we just execute the script
        import shlex
        script_cmd = f"bash -c {shlex.quote(script)}"
        result = sandbox.commands.run(script_cmd, timeout=60)
        
        # Calculate continuous reward based on test passage ratio
        if result.exit_code == 0:
            return 1.0
        
        # Very simple heuristic reward
        return 0.1
        
    finally:
        # Clean up and release the sandbox back to the pool
        client.delete_sandbox(sandbox.claim_name)

# 2. Define the Reward Function for TRL
def sandbox_reward_func(prompts, completions, **kwargs):
    # Dispatch evaluation to Ray cluster
    futures = [
        evaluate_rollout.remote(completion, {
            "repo": kwargs.get('repo', [])[i] if 'repo' in kwargs else None,
            "base_commit": kwargs.get('base_commit', [])[i] if 'base_commit' in kwargs else None
        }) for i, completion in enumerate(completions)
    ]
    
    # Block and wait for all sandbox evaluations to complete
    rewards = ray.get(futures)
    return rewards

# 3. Setup GRPO Trainer
@ray.remote(num_gpus=1, num_cpus=8)
def train():
    # Load dataset
    dataset = load_dataset("princeton-nlp/SWE-bench_Lite", split="test")
    # Filter to our selected target issue
    dataset = dataset.filter(lambda x: x["instance_id"] == "django__django-15388")
    
    def format_dataset(example):
        files = re.findall(r'^\+\+\+ b/(.+)$', example["patch"], re.MULTILINE)
        target_file = files[0] if files else ""
        
        file_content = ""
        if target_file:
            try:
                github_repo = example["repo"]
                url = f"https://raw.githubusercontent.com/{github_repo}/{example['base_commit']}/{target_file}"
                with urllib.request.urlopen(url) as response:
                    file_content = response.read().decode('utf-8')
            except Exception as e:
                pass
                
        prompt = f"""You are an expert software engineer.
You are given a GitHub issue and the content of the file that contains the bug.
Write an executable bash script that will modify the target file to fix the bug (e.g. using cat << 'EOF' > {target_file} or inline python edits).
Wrap your bash script in ```bash ... ``` tags. Do not output raw python code directly.

Target File: {target_file}

Original File Content:
```python
{file_content}
```

Issue:
{example['problem_statement']}
"""
        return {
            "prompt": prompt,
            "repo": example["repo"],
            "instance_id": example["instance_id"],
            "base_commit": example["base_commit"],
        }
        
    dataset = dataset.map(format_dataset)

    model_name = "Qwen/Qwen2.5-Coder-1.5B-Instruct"
    tokenizer = AutoTokenizer.from_pretrained(model_name)

    training_args = GRPOConfig(
        output_dir="outputs",
        learning_rate=5e-6,
        max_steps=50,
        per_device_train_batch_size=1,
        gradient_accumulation_steps=4,
        num_generations=4,
    )

    trainer = GRPOTrainer(
        model=model_name,
        processing_class=tokenizer,
        reward_funcs=[sandbox_reward_func],
        args=training_args,
        train_dataset=dataset,
    )

    print("Starting GRPO training with GKE Agent Sandboxes...")
    trainer.train()

def main():
    print("Submitting training job to GPU worker...")
    ray.get(train.remote())

if __name__ == "__main__":
    main()
EOF

ক্লাস্টারে কাজটি জমা দিন

প্রথমে, রে হেড ড্যাশবোর্ডে পোর্ট-ফরোয়ার্ড করুন এবং আপনার স্থানীয় মেশিন থেকে প্রশিক্ষণ কাজটি জমা দিন:

kubectl port-forward service/grpo-cluster-head-svc 8265:8265 &

ray job submit \
  --address http://localhost:8265 \
  --runtime-env-json '{"working_dir": "."}' \
  -- python train_trl.py

দৌড় পর্যবেক্ষণ করুন

আপনি আপনার দৌড়ের অগ্রগতি পর্যবেক্ষণ করতে পারেন:

  • রে ড্যাশবোর্ড: আপনার ব্রাউজারে http://localhost:8265 খুলুন।
  • স্যান্ডবক্স ক্লেইম: gVisor-এর অধীনে GKE কীভাবে গতিশীলভাবে স্যান্ডবক্স ক্লেইম ও রিলিজ করে তা দেখুন:
    watch -n 1 "kubectl get sandboxclaims,sandboxes,pods"
    

৬. উপসংহার

অভিনন্দন! আপনি GKE এজেন্ট স্যান্ডবক্স ব্যবহার করে GKE স্ট্যান্ডার্ড-এ একটি উচ্চ-পারফরম্যান্স ডিস্ট্রিবিউটেড আরএল ট্রেনিং লুপ সফলভাবে ও নিরাপদে কনফিগার এবং এক্সিকিউট করেছেন।