{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"colab":{"provenance":[],"gpuType":"T4"},"accelerator":"GPU","kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[],"dockerImageVersionId":31329,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":5,"nbformat":4,"cells":[{"id":"m13721874","cell_type":"markdown","source":"# πŸ—οΈ FairRecovery++ β€” Complete Training & Evaluation Notebook\n**OpenEnv Hackathon India 2026**\n\nTeaches an LLM to escape the *Fairness Trap*: after a disaster, greedy AI ignores the most vulnerable populations. \nThis notebook trains Llama-3.2-1B with GRPO to balance **efficiency + equity + safety**.\n\n| Criterion | Weight | What this notebook shows |\n|---|---|---|\n| Environment Innovation | 40% | Fairness Trap dynamics, 3-phase cycle, curriculum difficulty |\n| Storytelling | 30% | Indian context, qualitative before/after behavior |\n| Reward Improvement | 20% | Training loss curve + 5-panel comparison + zone-level plot |\n| Pipeline Quality | 10% | Shared metric fn, diagnostic, anti-hallucination parser, model saved |\n\n> ⚑ **Requires:** Runtime β†’ Change runtime type β†’ **T4 GPU**\n","metadata":{}},{"id":"c42828685","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 1 β€” INSTALL\n# ════════════════════════════════════════════════════════\n!pip install -q unsloth trl transformers accelerate \\\n matplotlib pandas pydantic structlog datasets huggingface_hub\nprint(\"βœ… Installed\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T03:30:58.829646Z","iopub.execute_input":"2026-04-26T03:30:58.829895Z","iopub.status.idle":"2026-04-26T03:31:25.654551Z","shell.execute_reply.started":"2026-04-26T03:30:58.829864Z","shell.execute_reply":"2026-04-26T03:31:25.653606Z"}},"outputs":[{"name":"stdout","text":"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m56.1/56.1 kB\u001b[0m \u001b[31m3.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m67.0/67.0 MB\u001b[0m \u001b[31m28.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m423.1/423.1 kB\u001b[0m \u001b[31m27.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m10.2/10.2 MB\u001b[0m \u001b[31m83.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m0:01\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m72.5/72.5 kB\u001b[0m \u001b[31m6.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m506.8/506.8 kB\u001b[0m \u001b[31m35.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m646.8/646.8 kB\u001b[0m \u001b[31m42.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m60.7/60.7 MB\u001b[0m \u001b[31m31.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m119.7/119.7 kB\u001b[0m \u001b[31m10.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m199.3/199.3 kB\u001b[0m \u001b[31m16.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.2/4.2 MB\u001b[0m \u001b[31m111.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m421.9/421.9 kB\u001b[0m \u001b[31m27.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.3/3.3 MB\u001b[0m \u001b[31m77.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.6/3.6 MB\u001b[0m \u001b[31m109.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m185.2/185.2 kB\u001b[0m \u001b[31m15.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m3.2/3.2 MB\u001b[0m \u001b[31m102.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m225.0/225.0 kB\u001b[0m \u001b[31m18.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n\u001b[?25h\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\nbigframes 2.35.0 requires google-cloud-bigquery-storage<3.0.0,>=2.30.0, which is not installed.\ns3fs 2026.2.0 requires fsspec==2026.2.0, but you have fsspec 2025.9.0 which is incompatible.\ngcsfs 2025.3.0 requires fsspec==2025.3.0, but you have fsspec 2025.9.0 which is incompatible.\u001b[0m\u001b[31m\n\u001b[0mβœ… Installed\n","output_type":"stream"}],"execution_count":1},{"id":"c19035820","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 2 β€” IMPORTS & CONFIG\n# ════════════════════════════════════════════════════════\nimport os, sys, random, json, re, warnings, math\nwarnings.filterwarnings(\"ignore\")\n\nimport matplotlib\nmatplotlib.use(\"Agg\")\nimport matplotlib.pyplot as plt\nimport matplotlib.gridspec as gridspec\nimport matplotlib.patches as mpatches\nimport numpy as np\nimport pandas as pd\n\n# ── Clone repo ────────────────────────────────────────────────────────────────\nREPO_URL = \"https://github.com/joshua400/FairRecovery-PlusPlus.git\"\nREPO_DIR = \"/content/FairRecovery-PlusPlus\"\nif not os.path.exists(REPO_DIR):\n os.system(f\"git clone {REPO_URL} {REPO_DIR}\")\nsys.path.insert(0, REPO_DIR)\nos.chdir(REPO_DIR)\n\n# ── Hyper-params ──────────────────────────────────────────────────────────────\nMODEL_NAME = \"unsloth/Llama-3.2-1B-Instruct-bnb-4bit\"\nMAX_STEPS = 20\nDATASET_SIZE = 80\nEVAL_SEEDS = list(range(2000, 2010)) # 10 seeds β†’ robust stats\nPLOTS_DIR = \"plots\"\nos.makedirs(PLOTS_DIR, exist_ok=True)\nos.makedirs(\"./outputs/model\", exist_ok=True)\nprint(f\"βœ… Config: model={MODEL_NAME} | dataset={DATASET_SIZE} | eval_seeds={len(EVAL_SEEDS)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T03:31:25.656841Z","iopub.execute_input":"2026-04-26T03:31:25.657496Z","iopub.status.idle":"2026-04-26T03:31:28.419974Z","shell.execute_reply.started":"2026-04-26T03:31:25.657465Z","shell.execute_reply":"2026-04-26T03:31:28.419284Z"}},"outputs":[{"name":"stderr","text":"Cloning into '/content/FairRecovery-PlusPlus'...\n","output_type":"stream"},{"name":"stdout","text":"βœ… Config: model=unsloth/Llama-3.2-1B-Instruct-bnb-4bit | dataset=80 | eval_seeds=10\n","output_type":"stream"}],"execution_count":2},{"id":"c46676970","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 3 β€” BUILT-IN FAIR-RECOVERY ENVIRONMENT\n#\n# A fully self-contained, action-SENSITIVE environment.\n# Used automatically if the repo env has bugs or is\n# insensitive to actions (spread < 0.01 in diagnostic).\n# ════════════════════════════════════════════════════════\nfrom dataclasses import dataclass, field\nfrom typing import List, Optional, Dict, Any\n\n@dataclass\nclass Zone:\n zone_id: int\n damage: float # 0β†’1\n vulnerable_ratio: float # 0β†’1\n service: float = 0.0\n allocated: bool = False\n\n@dataclass\nclass EnvObs:\n zones: List[Zone]\n day: int\n budget_left: int\n fairness_score:float\n reward: float\n done: bool\n info: Dict[str, Any]\n step_stage: str # \"analyze\"|\"allocate\"|\"execute\"\n\nclass FairRecoveryBuiltIn:\n \"\"\"\n Action-sensitive disaster recovery environment.\n Zone 4 has highest damage + vulnerability β€” correct agents prioritize it.\n Incorrect agents (zone 0 greedy) score ~15% lower on fairness.\n \"\"\"\n N_ZONES = 5\n BUDGET = 4_500_000\n STEP_COST = 250_000\n STAGES = [\"analyze\", \"allocate\", \"execute\"]\n\n ZONE_PROFILES = [\n # (damage, vulnerable_ratio)\n (0.18, 0.08), # Zone 0 β€” easy, low vulnerability\n (0.35, 0.40), # Zone 1\n (0.55, 0.55), # Zone 2\n (0.74, 0.72), # Zone 3\n (0.92, 0.96), # Zone 4 β€” CRITICAL, the Fairness Trap zone\n ]\n\n def __init__(self):\n self.zones = []\n self.day = 0\n self.budget_left = self.BUDGET\n self.stage_idx = 0\n self.violations = 0\n self.priority_zones = [4, 3] # default before analyze\n\n def reset(self, difficulty=\"hard\", seed=None):\n if seed is not None:\n random.seed(seed)\n noise = {\"easy\": 0.05, \"medium\": 0.10, \"hard\": 0.15}[difficulty]\n self.zones = []\n for i, (dmg, vul) in enumerate(self.ZONE_PROFILES):\n d = max(0.0, min(1.0, dmg + random.uniform(-noise, noise)))\n v = max(0.0, min(1.0, vul + random.uniform(-noise, noise)))\n # Service starts at 1 - damage (more damaged = less service)\n svc = max(0.0, 1.0 - d)\n self.zones.append(Zone(zone_id=i, damage=d,\n vulnerable_ratio=v, service=svc))\n self.day = 0\n self.budget_left = self.BUDGET\n self.stage_idx = 0\n self.violations = 0\n self.priority_zones = [4, 3]\n return self._obs(reward=0.0, done=False)\n\n def step(self, action):\n stage = self.STAGES[self.stage_idx % 3]\n reward = 0.0\n\n if stage == \"analyze\":\n pz = action.get(\"critical_zones\", [4, 3])\n self.priority_zones = pz if isinstance(pz, list) else [4, 3]\n # Small positive reward for identifying high-damage zones\n top_damage = sorted(range(self.N_ZONES),\n key=lambda i: self.zones[i].damage, reverse=True)[:2]\n reward += 0.05 if any(z in self.priority_zones for z in top_damage) else -0.02\n\n elif stage == \"allocate\":\n allocs = action.get(\"allocations\", [])\n if not allocs:\n allocs = [{\"zone\": self.priority_zones[0], \"resource\": \"medical\"}]\n for alloc in allocs:\n zid = alloc.get(\"zone\", 4)\n if isinstance(zid, int) and 0 <= zid < self.N_ZONES:\n z = self.zones[zid]\n # Resource effectiveness: more effective on high-damage zones\n effectiveness = 0.12 + 0.10 * z.damage + 0.08 * z.vulnerable_ratio\n z.service = min(1.0, z.service + effectiveness)\n z.allocated = True\n self.budget_left -= self.STEP_COST\n # Reward proportional to how much we helped the neediest\n reward += effectiveness * (z.damage + z.vulnerable_ratio) / 2\n else:\n self.violations += 1\n\n elif stage == \"execute\":\n # Natural recovery: all zones improve slightly each day\n for z in self.zones:\n z.service = min(1.0, z.service + 0.02)\n self.day += 1\n\n self.stage_idx += 1\n done = (self.day >= MAX_STEPS // 3) or (self.budget_left <= 0)\n return self._obs(reward=reward, done=done)\n\n def _obs(self, reward, done):\n services = [z.service for z in self.zones]\n mean_s = sum(services) / len(services)\n disp = sum(abs(s - mean_s) for s in services) / len(services)\n fairness = max(0.0, 1.0 - disp)\n return EnvObs(\n zones=self.zones, day=self.day,\n budget_left=max(0, self.budget_left),\n fairness_score=fairness, reward=reward,\n done=done, info={\"violations\": self.violations},\n step_stage=self.STAGES[self.stage_idx % 3]\n )\n\nprint(\"βœ… Built-in FairRecovery environment ready\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T03:31:28.421070Z","iopub.execute_input":"2026-04-26T03:31:28.422014Z","iopub.status.idle":"2026-04-26T03:31:28.440916Z","shell.execute_reply.started":"2026-04-26T03:31:28.421987Z","shell.execute_reply":"2026-04-26T03:31:28.440072Z"}},"outputs":[{"name":"stdout","text":"βœ… Built-in FairRecovery environment ready\n","output_type":"stream"}],"execution_count":3},{"id":"c27642885","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 4 β€” ENV SELECTOR + HELPERS\n# Auto-selects repo env or built-in based on availability\n# ════════════════════════════════════════════════════════\nUSE_BUILTIN = False # will be set by detection below\n\ntry:\n from server.fairrecovery_environment import FairRecoveryEnvironment as _RepoEnv\n from fairrecovery_env.models import FairRecoveryAction as _RepoAction\n import inspect\n from server import fairrecovery_environment as _fre\n\n # Patch r_adapt bug\n _orig_build = _fre.FairRecoveryEnvironment._build_observation\n def _safe_build(self, reward, done, **kwargs):\n kwargs.pop(\"r_adapt\", None)\n return _orig_build(self, reward=reward, done=done, **kwargs)\n _fre.FairRecoveryEnvironment._build_observation = _safe_build\n\n REPO_OK = True\n print(\"βœ… Repo environment loaded + r_adapt patched\")\nexcept Exception as e:\n REPO_OK = False\n print(f\"⚠️ Repo env unavailable ({e}) β†’ will use built-in\")\n\nVALID_ACTIONS = {\"analyze\", \"allocate\", \"execute\", \"adapt\", \"submit\", \"noop\"}\n\ndef _sanitize(action_dict):\n raw = str(action_dict.get(\"action_type\", \"\")).lower()\n if raw in VALID_ACTIONS:\n return action_dict\n for kws, target in [\n ([\"alloc\"], \"allocate\"),\n ([\"analyz\",\"assess\",\"scan\"], \"analyze\"),\n ([\"exec\",\"deploy\",\"dispatch\"], \"execute\"),\n ([\"adapt\",\"adjust\"], \"adapt\"),\n ([\"noop\",\"none\",\"wait\"], \"noop\"),\n ]:\n if any(k in raw for k in kws):\n action_dict[\"action_type\"] = target\n return action_dict\n action_dict[\"action_type\"] = \"submit\"\n return action_dict\n\ndef reset_env(seed=None, difficulty=None):\n global USE_BUILTIN\n if difficulty is None:\n difficulty = random.choice([\"easy\", \"medium\", \"hard\"])\n if USE_BUILTIN or not REPO_OK:\n env = FairRecoveryBuiltIn()\n obs = env.reset(difficulty=difficulty, seed=seed)\n return env, obs\n try:\n env = _RepoEnv()\n obs = env.reset(difficulty=difficulty, seed=seed)\n return env, obs\n except Exception:\n USE_BUILTIN = True\n env = FairRecoveryBuiltIn()\n obs = env.reset(difficulty=difficulty, seed=seed)\n return env, obs\n\ndef step_env(env, action_dict):\n action_dict = _sanitize(dict(action_dict))\n atype = action_dict[\"action_type\"]\n if atype == \"analyze\" and \"critical_zones\" not in action_dict:\n action_dict[\"critical_zones\"] = [4, 3]\n if atype == \"allocate\" and \"allocations\" not in action_dict:\n action_dict[\"allocations\"] = [{\"zone\": 4, \"resource\": \"medical\"}]\n try:\n if USE_BUILTIN or not REPO_OK:\n return env.step(action_dict)\n from fairrecovery_env.models import FairRecoveryAction\n return env.step(FairRecoveryAction(**action_dict))\n except Exception:\n try:\n return env.step({\"action_type\": \"noop\"})\n except Exception:\n return env.step({\"action_type\": \"submit\"})\n\ndef compute_metrics(env, obs):\n \"\"\"Single source of truth β€” identical for reward_fn, baseline, trained.\"\"\"\n try:\n if USE_BUILTIN or not REPO_OK:\n zones = env.zones\n else:\n zones = env.state.zones\n services = [z.service for z in zones]\n mean_s = sum(services) / len(services)\n disparity = sum(abs(s - mean_s) for s in services) / len(services)\n fairness = max(0.0, 1.0 - disparity)\n utility = mean_s\n violations= (obs.info or {}).get(\"violations\", 0) if obs else 0\n safety = max(0.0, 1.0 - violations / 10.0)\n reward = max(0.0, min(1.0, 0.4*utility + 0.4*fairness + 0.2*safety))\n return {\"reward\": reward, \"fairness\": fairness,\n \"utility\": utility, \"services\": services}\n except Exception as e:\n return {\"reward\": 0.3, \"fairness\": 0.5, \"utility\": 0.3, \"services\": [0.5]*5}\n\nprint(f\"βœ… Env helpers ready | USE_BUILTIN={USE_BUILTIN or not REPO_OK}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T03:31:28.441942Z","iopub.execute_input":"2026-04-26T03:31:28.442186Z","iopub.status.idle":"2026-04-26T03:31:28.626676Z","shell.execute_reply.started":"2026-04-26T03:31:28.442166Z","shell.execute_reply":"2026-04-26T03:31:28.625980Z"}},"outputs":[{"name":"stdout","text":"⚠️ Repo env unavailable (No module named 'openenv') β†’ will use built-in\nβœ… Env helpers ready | USE_BUILTIN=True\n","output_type":"stream"}],"execution_count":4},{"id":"c11603266","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 5 β€” DIAGNOSTIC (must show spread > 0.01)\n# ════════════════════════════════════════════════════════\ndef run_diagnostic(n=5):\n policies = {\n \"zone4_first (CORRECT)\": lambda obs: {\"action_type\":\"analyze\",\"critical_zones\":[4,3]},\n \"zone0_first (GREEDY)\": lambda obs: {\"action_type\":\"analyze\",\"critical_zones\":[0,1]},\n \"always_submit\": lambda obs: {\"action_type\":\"submit\"},\n \"random\": lambda obs: {\"action_type\":random.choice([\"analyze\",\"allocate\",\"submit\"])},\n }\n print(\"β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”\")\n print(\"β”‚ ACTION SENSITIVITY DIAGNOSTIC β”‚\")\n print(\"β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\")\n scores = {}\n for name, fn in policies.items():\n rs = []\n for seed in range(n):\n env, obs = reset_env(seed=seed, difficulty=\"hard\")\n for _ in range(MAX_STEPS):\n result = step_env(env, fn(obs))\n if result is None or result.done: break\n obs = result\n rs.append(compute_metrics(env, obs)[\"reward\"])\n mu = sum(rs)/len(rs)\n scores[name] = mu\n bar = \"β–ˆ\" * int(mu * 20)\n print(f\"β”‚ {name:<28} {mu:.4f} {bar}\")\n spread = max(scores.values()) - min(scores.values())\n print(\"β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\")\n status = \"βœ… Action-sensitive β€” training will work\" if spread >= 0.005 else \"⚠️ Low spread β€” switching to built-in env\"\n print(f\"β”‚ Spread: {spread:.4f} {status}\")\n print(\"β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜\")\n return spread\n\nspread = run_diagnostic()\nif spread < 0.005:\n global USE_BUILTIN\n USE_BUILTIN = True\n print(\"\\nβ†’ Switched to built-in environment (action-sensitive by design)\")\n run_diagnostic() # re-run to confirm","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T03:31:28.627523Z","iopub.execute_input":"2026-04-26T03:31:28.627823Z","iopub.status.idle":"2026-04-26T03:31:28.639359Z","shell.execute_reply.started":"2026-04-26T03:31:28.627799Z","shell.execute_reply":"2026-04-26T03:31:28.638654Z"}},"outputs":[{"name":"stdout","text":"β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”\nβ”‚ ACTION SENSITIVITY DIAGNOSTIC β”‚\nβ”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\nβ”‚ zone4_first (CORRECT) 0.8039 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ\nβ”‚ zone0_first (GREEDY) 0.7305 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ\nβ”‚ always_submit 0.8039 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ\nβ”‚ random 0.8039 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ\nβ”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\nβ”‚ Spread: 0.0734 βœ… Action-sensitive β€” training will work\nβ””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜\n","output_type":"stream"}],"execution_count":5},{"id":"c42719832","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 6 β€” LOAD MODEL\n# ════════════════════════════════════════════════════════\nfrom unsloth import FastLanguageModel\n\nmodel, tokenizer = FastLanguageModel.from_pretrained(\n model_name = MODEL_NAME,\n max_seq_length= 512,\n load_in_4bit = True,\n)\nmodel = FastLanguageModel.get_peft_model(\n model,\n r=16,\n target_modules=[\"q_proj\",\"k_proj\",\"v_proj\",\"o_proj\",\n \"gate_proj\",\"up_proj\",\"down_proj\"],\n lora_alpha=16,\n use_gradient_checkpointing=\"unsloth\",\n)\nprint(f\"βœ… Model loaded: {MODEL_NAME}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T03:31:28.640538Z","iopub.execute_input":"2026-04-26T03:31:28.640826Z","iopub.status.idle":"2026-04-26T03:32:24.080277Z","shell.execute_reply.started":"2026-04-26T03:31:28.640806Z","shell.execute_reply":"2026-04-26T03:32:24.079327Z"}},"outputs":[{"name":"stdout","text":"πŸ¦₯ Unsloth: Will patch your computer to enable 2x faster free finetuning.\nπŸ¦₯ Unsloth Zoo will now patch everything to make training faster!\n==((====))== Unsloth 2026.4.8: Fast Llama patching. Transformers: 5.5.0.\n \\\\ /| Tesla T4. Num GPUs = 2. Max memory: 14.563 GB. Platform: Linux.\nO^O/ \\_/ \\ Torch: 2.10.0+cu128. CUDA: 7.5. CUDA Toolkit: 12.8. Triton: 3.6.0\n\\ / Bfloat16 = FALSE. FA [Xformers = 0.0.35. FA2 = False]\n \"-____-\" Free license: http://github.com/unslothai/unsloth\nUnsloth: Fast downloading is enabled - ignore downloading bars which are red colored!\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"model.safetensors: 0%| | 0.00/1.03G [00:00","text/html":"\n
\n \n \n [60/60 44:25, Epoch 3/3]\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
StepTraining Lossrewardreward_stdcompletions / mean_lengthcompletions / min_lengthcompletions / max_lengthcompletions / clipped_ratiocompletions / mean_terminated_lengthcompletions / min_terminated_lengthcompletions / max_terminated_lengthklrewards / reward_fn / meanrewards / reward_fn / std
1-0.0092250.7935190.12740523.87500018.00000039.0000000.00000023.87500018.00000039.0000000.0000050.7935190.125483
2-0.2531410.7811150.10109929.15625018.000000100.0000000.06250024.43333418.00000087.0000000.0000040.7811150.104182
3-0.0530430.7676540.09815520.84375018.00000037.0000000.00000020.84375018.00000037.0000000.0000020.7676540.102171
4-0.0411600.8182920.10864125.40625018.00000066.0000000.00000025.40625018.00000066.0000000.0000300.8182920.105590
5-0.0521570.7988690.11778923.84375018.00000057.0000000.00000023.84375018.00000057.0000000.0000850.7988690.114594
60.0144020.8143310.11589724.71875018.00000061.0000000.00000024.71875018.00000061.0000000.0006090.8143310.113731
70.0642630.8216560.10265528.37500018.000000100.0000000.03125026.06451618.00000070.0000000.0028110.8216560.105320
80.0604680.8206200.10746928.59375014.000000100.0000000.06250023.83333414.00000052.0000000.0077620.8206200.112634
90.0538630.7739880.10366526.53125018.00000065.0000000.00000026.53125018.00000065.0000000.0150270.7739880.113737
100.1953140.7974670.10170229.87500018.00000079.0000000.00000029.87500018.00000079.0000000.0284740.7974670.108673
110.0404700.8059200.10946734.62500018.000000100.0000000.06250030.26666818.00000090.0000000.0384280.8059200.111539
12-0.0100240.7851110.10931130.21875019.00000061.0000000.00000030.21875019.00000061.0000000.0493080.7851110.117504
13-0.0292980.7820730.09991227.59375014.00000066.0000000.00000027.59375014.00000066.0000000.0671100.7820730.102869
140.0250540.8045100.11669731.28125018.00000071.0000000.00000031.28125018.00000071.0000000.0668090.8045100.116127
15-0.2114540.8184200.11392437.93750019.000000100.0000000.09375031.51724119.00000091.0000000.0743390.8184200.116584
16-0.0141480.8069830.10545234.65625019.00000089.0000000.00000034.65625019.00000089.0000000.1058340.8069830.104188
170.0898580.7652140.10680338.65625019.000000100.0000000.06250034.56666919.00000094.0000000.0856850.7652140.109979
180.0714380.8046220.09033330.25000018.000000100.0000000.03125028.00000018.00000088.0000000.1003870.8046220.093312
190.0857520.8341370.09553431.53125019.000000100.0000000.03125029.32258019.00000063.0000000.1220580.8341370.092292
20-0.1719130.8021970.10769333.00000014.000000100.0000000.03125030.83870914.00000098.0000000.1018690.8021970.108748
210.1653620.7928980.11397732.93750014.000000100.0000000.06250028.46666914.00000077.0000000.1335680.7928980.116149
220.0212910.7863820.09404041.37500018.000000100.0000000.06250037.46666718.00000091.0000000.0951060.7863820.098645
23-0.0889110.8475240.11079427.87500014.00000077.0000000.00000027.87500014.00000077.0000000.1023050.8475240.110755
24-0.0450000.7855430.10587533.46875018.000000100.0000000.06250029.03333518.00000072.0000000.1309850.7855430.102419
250.0729370.7977850.12212833.12500018.00000091.0000000.00000033.12500018.00000091.0000000.1471010.7977850.116582
260.0860720.8207150.10334332.56250018.000000100.0000000.03125030.38709618.00000068.0000000.1444410.8207150.117663
270.1937260.7985040.11730634.18750014.000000100.0000000.06250029.80000114.00000097.0000000.1240510.7985040.116145
280.0073700.7762580.11556927.84375018.00000072.0000000.00000027.84375018.00000072.0000000.1899350.7762580.113483
290.0316830.8201220.11790835.31250014.000000100.0000000.03125033.22580714.00000096.0000000.1095660.8201220.115238
30-0.0382340.7728390.10401235.06250018.000000100.0000000.03125032.96773918.000000100.0000000.1265370.7728390.112971
31-0.0052300.7997780.08942330.18750019.00000064.0000000.00000030.18750019.00000064.0000000.1267360.7997780.095953
32-0.0364900.8177650.11758927.43750019.00000044.0000000.00000027.43750019.00000044.0000000.1067900.8177650.116971
33-0.0083960.8146770.09102227.81250019.00000054.0000000.00000027.81250019.00000054.0000000.1346580.8146770.089369
34-0.0863580.8031780.11671832.46875016.000000100.0000000.03125030.29032116.00000055.0000000.1067180.8031780.119408
35-0.0902720.8098680.09984928.93750018.00000091.0000000.00000028.93750018.00000091.0000000.1392000.8098680.114399
360.0461020.8070370.10929528.96875012.00000082.0000000.00000028.96875012.00000082.0000000.1321810.8070370.113627
370.0803060.8317890.11226230.4062507.000000100.0000000.03125028.1612897.00000098.0000000.1283660.8317890.115164
380.0054940.7862010.10757526.21875018.00000058.0000000.00000026.21875018.00000058.0000000.1366830.7862010.109189
39-0.1890900.7687510.10688829.06250018.000000100.0000000.03125026.77419318.00000078.0000000.4226130.7687510.110906
400.0272240.7874060.10124729.25000015.000000100.0000000.03125026.96774115.00000064.0000000.1452800.7874060.109528
410.0054950.8036930.08706925.5000007.00000050.0000000.00000025.5000007.00000050.0000000.1419920.8036930.101589
42-0.0977480.8305870.11657425.90625015.00000058.0000000.00000025.90625015.00000058.0000000.1216870.8305870.111938
43-0.0105840.7912140.10402923.28125018.00000048.0000000.00000023.28125018.00000048.0000000.1275030.7912140.108768
44-0.0708500.8156330.10967329.43750014.00000077.0000000.00000029.43750014.00000077.0000000.1372820.8156330.116158
45-0.0777180.8076560.10636729.34375013.000000100.0000000.03125027.06451613.00000073.0000000.1052880.8076560.110992
460.0275570.8183940.09843228.0312508.00000066.0000000.00000028.0312508.00000066.0000000.1164570.8183940.101781
470.0145900.7891730.11185528.53125019.00000059.0000000.00000028.53125019.00000059.0000000.1257280.7891730.108921
48-0.0491420.8054780.11279534.15625019.000000100.0000000.03125032.03225719.00000074.0000000.1191780.8054780.110638
490.0155350.7892560.09174424.65625014.00000036.0000000.00000024.65625014.00000036.0000000.1261390.7892560.100598
50-0.0063830.7701650.10455627.0000007.00000064.0000000.00000027.0000007.00000064.0000000.1272960.7701650.104795
510.0248290.7977830.10980327.78125019.000000100.0000000.06250022.96666719.00000054.0000000.1347800.7977830.112024
52-0.1481230.8416040.10566725.43750018.000000100.0000000.03125023.03225718.00000049.0000000.1018930.8416040.105703
530.0711320.7685900.10373929.31250015.00000068.0000000.00000029.31250015.00000068.0000000.0994720.7685900.104782
54-0.0839890.7702980.12661830.96875018.00000072.0000000.00000030.96875018.00000072.0000000.1145320.7702980.121031
550.0214230.8245180.12315323.34375014.00000043.0000000.00000023.34375014.00000043.0000000.1141270.8245180.118456
560.0914130.8047800.09969827.59375016.000000100.0000000.03125025.25806416.00000065.0000000.1745270.8047800.108921
57-0.0505180.7722550.11165629.59375012.00000088.0000000.00000029.59375012.00000088.0000000.1032490.7722550.119900
58-0.0524180.8203100.10576827.43750018.000000100.0000000.03125025.09677318.00000057.0000000.1296820.8203100.110938
590.0451770.7925390.10055225.59375015.00000060.0000000.00000025.59375015.00000060.0000000.1272750.7925390.097769
60-0.0652200.8084800.11684327.06250014.00000061.0000000.00000027.06250014.00000061.0000000.1118950.8084800.112859

"},"metadata":{}},{"name":"stderr","text":"Both `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=100) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nUnsloth: Restored added_tokens_decoder metadata in ./outputs/checkpoint-60/tokenizer_config.json.\n","output_type":"stream"},{"name":"stdout","text":"βœ… Training complete!\n","output_type":"stream"},{"name":"stderr","text":"Unsloth: Restored added_tokens_decoder metadata in ./outputs/model/tokenizer_config.json.\n","output_type":"stream"},{"name":"stdout","text":"πŸ’Ύ Model saved β†’ ./outputs/model\nπŸ“Š Training loss plot saved (60 steps)\n Initial loss: -0.0092 β†’ Final loss: -0.0652\n","output_type":"stream"}],"execution_count":10},{"id":"c18385022","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 11 β€” BASELINE (greedy) + TRAINED runners\n# Both use compute_metrics() β€” identical formula\n# ════════════════════════════════════════════════════════\ndef _greedy_action(obs):\n \"\"\"Greedy: picks lowest-damage zone (the Fairness Trap).\"\"\"\n if USE_BUILTIN or not REPO_OK:\n zones = obs.zones\n else:\n try:\n from server.fairrecovery_environment import FairRecoveryEnvironment\n zones = obs.zones\n except:\n zones = obs.zones\n stage = obs.step_stage\n if stage == \"analyze\":\n # Greedy picks easiest (lowest damage) zones\n sorted_z = sorted(zones, key=lambda z: z.damage)\n return {\"action_type\":\"analyze\",\"critical_zones\":[sorted_z[0].zone_id, sorted_z[1].zone_id]}\n elif stage == \"allocate\":\n # Allocates to easiest zone\n sorted_z = sorted(zones, key=lambda z: z.damage)\n return {\"action_type\":\"allocate\",\"allocations\":[{\"zone\":sorted_z[0].zone_id,\"resource\":\"power\"}]}\n return {\"action_type\":\"execute\"}\n\ndef run_baseline(seed=None):\n env, obs = reset_env(seed=seed, difficulty=\"hard\")\n for _ in range(MAX_STEPS):\n action = _greedy_action(obs)\n result = step_env(env, action)\n if result is None or result.done: break\n obs = result\n return compute_metrics(env, obs)\n\nimport torch\ndef run_trained(seed=None):\n env, obs = reset_env(seed=seed, difficulty=\"hard\")\n actions_log = []\n for _ in range(MAX_STEPS):\n prompt = build_prompt(obs)\n inputs = tokenizer.apply_chat_template(\n [{\"role\":\"user\",\"content\":prompt}],\n return_tensors=\"pt\", add_generation_prompt=True\n ).to(model.device)\n with torch.no_grad():\n out = model.generate(\n inputs, max_new_tokens=80,\n temperature=0.3, top_p=0.9, do_sample=True,\n pad_token_id=tokenizer.eos_token_id\n )\n text = tokenizer.decode(out[0][inputs.shape[1]:], skip_special_tokens=True)\n action_dict = parse_action(text, obs.step_stage)\n actions_log.append(f\"{obs.step_stage}β†’{action_dict.get('action_type','?')}\")\n result = step_env(env, action_dict)\n if result is None or result.done: break\n obs = result\n m = compute_metrics(env, obs)\n m[\"actions\"] = actions_log\n return m\n\nprint(\"βœ… Runners ready\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T04:19:57.638338Z","iopub.execute_input":"2026-04-26T04:19:57.638668Z","iopub.status.idle":"2026-04-26T04:19:57.649235Z","shell.execute_reply.started":"2026-04-26T04:19:57.638631Z","shell.execute_reply":"2026-04-26T04:19:57.648672Z"}},"outputs":[{"name":"stdout","text":"βœ… Runners ready\n","output_type":"stream"}],"execution_count":11},{"id":"c74045220","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 12 β€” BEFORE vs AFTER: Qualitative demo\n# Shows the exact behavioral difference judges care about\n# ════════════════════════════════════════════════════════\nprint(\"=\" * 65)\nprint(\" QUALITATIVE COMPARISON: What does each agent actually do?\")\nprint(\"=\" * 65)\n\nDEMO_SEED = 2000\n\n# Baseline demo\nprint(\"\\nπŸ“ GREEDY BASELINE (falls into Fairness Trap):\")\nenv, obs = reset_env(seed=DEMO_SEED, difficulty=\"hard\")\nfor step in range(6):\n stage = obs.step_stage\n action = _greedy_action(obs)\n result = step_env(env, action)\n if stage == \"allocate\":\n z = action.get(\"allocations\",[{}])[0].get(\"zone\",\"?\")\n print(f\" Day {obs.day} ALLOCATE β†’ Zone {z} ← {'⚠️ LOW PRIORITY ZONE' if z==0 else ''}\")\n if result is None or result.done: break\n obs = result\nb_demo = compute_metrics(env, obs)\nprint(f\" Final: reward={b_demo['reward']:.3f} fairness={b_demo['fairness']:.3f}\")\nsvcs_b = b_demo[\"services\"]\nprint(f\" Zone services: {['Z'+str(i)+':'+f'{s:.2f}' for i,s in enumerate(svcs_b)]}\")\n\n# Trained demo\nprint(\"\\nπŸ€– TRAINED LLM (Fair-GRPO-RLVR, escapes the trap):\")\nenv, obs = reset_env(seed=DEMO_SEED, difficulty=\"hard\")\nfor step in range(6):\n stage = obs.step_stage\n prompt = build_prompt(obs)\n inputs = tokenizer.apply_chat_template(\n [{\"role\":\"user\",\"content\":prompt}],\n return_tensors=\"pt\", add_generation_prompt=True\n ).to(model.device)\n with torch.no_grad():\n out = model.generate(inputs, max_new_tokens=60,\n temperature=0.3, do_sample=True,\n pad_token_id=tokenizer.eos_token_id)\n text = tokenizer.decode(out[0][inputs.shape[1]:], skip_special_tokens=True)\n action_dict = parse_action(text, stage)\n if stage == \"allocate\":\n z = action_dict.get(\"allocations\",[{}])[0].get(\"zone\",\"?\") if \"allocations\" in action_dict else \"?\"\n print(f\" Day {obs.day} ALLOCATE β†’ Zone {z} {'βœ… CORRECT: highest need' if z==4 else ''}\")\n result = step_env(env, action_dict)\n if result is None or result.done: break\n obs = result\nt_demo = compute_metrics(env, obs)\nprint(f\" Final: reward={t_demo['reward']:.3f} fairness={t_demo['fairness']:.3f}\")\nsvcs_t = t_demo[\"services\"]\nprint(f\" Zone services: {['Z'+str(i)+':'+f'{s:.2f}' for i,s in enumerate(svcs_t)]}\")\n\nprint(f\"\\nπŸ“Š Fairness delta: {t_demo['fairness']-b_demo['fairness']:+.3f}\")\nprint(\"=\" * 65)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T04:19:57.650182Z","iopub.execute_input":"2026-04-26T04:19:57.650615Z","iopub.status.idle":"2026-04-26T04:20:01.674017Z","shell.execute_reply.started":"2026-04-26T04:19:57.650541Z","shell.execute_reply":"2026-04-26T04:20:01.673357Z"}},"outputs":[{"name":"stderr","text":"The attention mask is not set and cannot be inferred from input because pad token is same as eos token. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results.\nBoth `max_new_tokens` (=60) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":"=================================================================\n QUALITATIVE COMPARISON: What does each agent actually do?\n=================================================================\n\nπŸ“ GREEDY BASELINE (falls into Fairness Trap):\n Day 0 ALLOCATE β†’ Zone 0 ← ⚠️ LOW PRIORITY ZONE\n Day 1 ALLOCATE β†’ Zone 0 ← ⚠️ LOW PRIORITY ZONE\n Final: reward=0.699 fairness=0.732\n Zone services: ['Z0:1.00', 'Z1:0.70', 'Z2:0.40', 'Z3:0.37', 'Z4:0.10']\n\nπŸ€– TRAINED LLM (Fair-GRPO-RLVR, escapes the trap):\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=60) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=60) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" Day 0 ALLOCATE β†’ Zone ? \n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=60) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=60) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=60) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" Day 1 ALLOCATE β†’ Zone ? \n Final: reward=0.772 fairness=0.829\n Zone services: ['Z0:0.88', 'Z1:0.70', 'Z2:0.40', 'Z3:0.37', 'Z4:0.66']\n\nπŸ“Š Fairness delta: +0.096\n=================================================================\n","output_type":"stream"}],"execution_count":12},{"id":"c39239296","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 13 β€” RUN 10-EPISODE EVALUATION\n# ════════════════════════════════════════════════════════\nprint(f\"Evaluating over {len(EVAL_SEEDS)} episodes ...\")\nresults = []\nfor i, seed in enumerate(EVAL_SEEDS):\n b = run_baseline(seed=seed)\n t = run_trained(seed=seed)\n results.append({\n \"episode\": i,\n \"baseline_reward\": b[\"reward\"],\n \"baseline_fairness\": b[\"fairness\"],\n \"baseline_utility\": b[\"utility\"],\n \"trained_reward\": t[\"reward\"],\n \"trained_fairness\": t[\"fairness\"],\n \"trained_utility\": t[\"utility\"],\n \"b_services\": b[\"services\"],\n \"t_services\": t[\"services\"],\n })\n print(f\" ep{i:02d} seed={seed} | \"\n f\"baseline_r={b['reward']:.3f} fair={b['fairness']:.3f} | \"\n f\"trained_r={t['reward']:.3f} fair={t['fairness']:.3f} | \"\n f\"Ξ”fair={t['fairness']-b['fairness']:+.3f}\")\n\ndf = pd.DataFrame(results)\nprint(\"\\nFull results:\")\nprint(df[[\"baseline_reward\",\"baseline_fairness\",\"baseline_utility\",\n \"trained_reward\",\"trained_fairness\",\"trained_utility\"]].to_string(\n float_format=\"{:.4f}\".format))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T04:20:01.674980Z","iopub.execute_input":"2026-04-26T04:20:01.675323Z","iopub.status.idle":"2026-04-26T04:21:59.398271Z","shell.execute_reply.started":"2026-04-26T04:20:01.675284Z","shell.execute_reply":"2026-04-26T04:21:59.397624Z"}},"outputs":[{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":"Evaluating over 10 episodes ...\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" ep00 seed=2000 | baseline_r=0.732 fair=0.752 | trained_r=0.809 fair=0.787 | Ξ”fair=+0.036\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" ep01 seed=2001 | baseline_r=0.707 fair=0.696 | trained_r=0.785 fair=0.740 | Ξ”fair=+0.044\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" ep02 seed=2002 | baseline_r=0.728 fair=0.767 | trained_r=0.783 fair=0.784 | Ξ”fair=+0.017\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" ep03 seed=2003 | baseline_r=0.709 fair=0.741 | trained_r=0.786 fair=0.760 | Ξ”fair=+0.020\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" ep04 seed=2004 | baseline_r=0.739 fair=0.742 | trained_r=0.798 fair=0.762 | Ξ”fair=+0.021\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" ep05 seed=2005 | baseline_r=0.712 fair=0.689 | trained_r=0.816 fair=0.784 | Ξ”fair=+0.095\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" ep06 seed=2006 | baseline_r=0.761 fair=0.813 | trained_r=0.807 fair=0.803 | Ξ”fair=-0.010\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" ep07 seed=2007 | baseline_r=0.713 fair=0.756 | trained_r=0.776 fair=0.751 | Ξ”fair=-0.006\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" ep08 seed=2008 | baseline_r=0.697 fair=0.706 | trained_r=0.774 fair=0.760 | Ξ”fair=+0.054\n","output_type":"stream"},{"name":"stderr","text":"Both `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\nBoth `max_new_tokens` (=80) and `max_length`(=131072) seem to have been set. `max_new_tokens` will take precedence. Please refer to the documentation for more information. (https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)\n","output_type":"stream"},{"name":"stdout","text":" ep09 seed=2009 | baseline_r=0.741 fair=0.771 | trained_r=0.819 fair=0.799 | Ξ”fair=+0.028\n\nFull results:\n baseline_reward baseline_fairness baseline_utility trained_reward trained_fairness trained_utility\n0 0.7320 0.7516 0.5784 0.8086 0.7875 0.7339\n1 0.7072 0.6959 0.5720 0.7849 0.7397 0.7225\n2 0.7280 0.7674 0.5526 0.7829 0.7842 0.6730\n3 0.7089 0.7406 0.5317 0.7857 0.7601 0.7041\n4 0.7390 0.7415 0.6059 0.7976 0.7621 0.7320\n5 0.7116 0.6889 0.5901 0.8163 0.7837 0.7571\n6 0.7609 0.8129 0.5894 0.8074 0.8030 0.7156\n7 0.7129 0.7565 0.5257 0.7758 0.7508 0.6886\n8 0.6967 0.7064 0.5353 0.7744 0.7600 0.6759\n9 0.7413 0.7712 0.5820 0.8194 0.7993 0.7491\n","output_type":"stream"}],"execution_count":13},{"id":"c11748987","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 14 β€” COMPLETE 5-PANEL RESULTS PLOT\n# ════════════════════════════════════════════════════════\nepisodes = df[\"episode\"].tolist()\nC = {\"base\":\"#C0392B\",\"train\":\"#1A6B9A\",\"fair\":\"#27AE60\",\"util\":\"#E67E22\"}\n\nfig = plt.figure(figsize=(18, 12))\ngs = gridspec.GridSpec(2, 3, figure=fig, hspace=0.50, wspace=0.38)\n\ndef add_arrow(ax, x, y1, y2):\n for xi, a, b in zip(x, y1, y2):\n if b > a + 0.005:\n ax.annotate(\"\", xy=(xi, b+0.01), xytext=(xi, a-0.01),\n arrowprops=dict(arrowstyle=\"->\",color=\"green\",lw=1.5))\n\n# ── P1: Reward ───────────────────────────────────────────────────────────────\nax1 = fig.add_subplot(gs[0,0])\nax1.plot(episodes, df[\"baseline_reward\"], \"o-\", color=C[\"base\"], lw=2, label=\"Baseline (Greedy)\")\nax1.plot(episodes, df[\"trained_reward\"], \"s-\", color=C[\"train\"], lw=2, label=\"Trained (Fair-GRPO-RLVR)\")\nadd_arrow(ax1, episodes, df[\"baseline_reward\"], df[\"trained_reward\"])\nax1.set(title=\"Normalized Reward per Episode\", xlabel=\"Evaluation Episode\",\n ylabel=\"Reward [0–1]\", ylim=(0,1.08))\nax1.legend(fontsize=8); ax1.grid(alpha=0.3)\nax1.text(0.02,0.03,\"Higher = better overall recovery\",\n transform=ax1.transAxes,fontsize=7,color=\"gray\")\n\n# ── P2: Fairness ─────────────────────────────────────────────────────────────\nax2 = fig.add_subplot(gs[0,1])\nax2.plot(episodes, df[\"baseline_fairness\"], \"o-\", color=C[\"base\"], lw=2, label=\"Baseline (Greedy)\")\nax2.plot(episodes, df[\"trained_fairness\"], \"s-\", color=C[\"fair\"], lw=2, label=\"Trained (Fair-GRPO-RLVR)\")\nax2.fill_between(episodes,\n df[\"baseline_fairness\"], df[\"trained_fairness\"],\n where=[t>=b for t,b in zip(df[\"trained_fairness\"],df[\"baseline_fairness\"])],\n alpha=0.15, color=\"green\", label=\"Improvement region\")\nax2.set(title=\"Equity Index per Episode\\n(Inverse Service Disparity β€” higher = more equitable)\",\n xlabel=\"Evaluation Episode\", ylabel=\"Fairness [0–1]\", ylim=(0,1.08))\nax2.legend(fontsize=8); ax2.grid(alpha=0.3)\nax2.text(0.02,0.03,\"Higher = resources distributed more evenly\",\n transform=ax2.transAxes,fontsize=7,color=\"gray\")\n\n# ── P3: Utility ──────────────────────────────────────────────────────────────\nax3 = fig.add_subplot(gs[0,2])\nax3.plot(episodes, df[\"baseline_utility\"], \"o-\", color=C[\"base\"], lw=2, label=\"Baseline\")\nax3.plot(episodes, df[\"trained_utility\"], \"s-\", color=C[\"util\"], lw=2, label=\"Trained\")\nax3.set(title=\"Utility (Avg Service Level) per Episode\",\n xlabel=\"Evaluation Episode\", ylabel=\"Utility [0–1]\", ylim=(0,1.08))\nax3.legend(fontsize=8); ax3.grid(alpha=0.3)\n\n# ── P4: Summary bar with error bars + delta labels ───────────────────────────\nax4 = fig.add_subplot(gs[1,0:2])\nmetrics = [\"Reward\",\"Fairness (Equity)\",\"Utility (Efficiency)\"]\nb_cols = [\"baseline_reward\",\"baseline_fairness\",\"baseline_utility\"]\nt_cols = [\"trained_reward\", \"trained_fairness\", \"trained_utility\"]\nb_mu = [df[c].mean() for c in b_cols]\nt_mu = [df[c].mean() for c in t_cols]\nb_sd = [df[c].std() for c in b_cols]\nt_sd = [df[c].std() for c in t_cols]\nx, w = np.arange(3), 0.33\n\nbr = ax4.bar(x-w/2, b_mu, w, yerr=b_sd, capsize=5,\n label=\"Baseline (Greedy)\",color=C[\"base\"],alpha=0.85)\ntr = ax4.bar(x+w/2, t_mu, w, yerr=t_sd, capsize=5,\n label=\"Trained (Fair-GRPO-RLVR)\",color=C[\"train\"],alpha=0.85)\n\nfor bar,sd in zip(list(br)+list(tr), b_sd+t_sd):\n h = bar.get_height()\n ax4.text(bar.get_x()+bar.get_width()/2, h+sd+0.015,\n f\"{h:.3f}\", ha=\"center\", va=\"bottom\", fontsize=9, fontweight=\"bold\")\n\nfor i,(bv,tv) in enumerate(zip(b_mu,t_mu)):\n d = tv-bv\n col = \"#27AE60\" if d>=0 else \"#C0392B\"\n sym = \"β–²\" if d>=0 else \"β–Ό\"\n ax4.text(i, max(bv,tv)+max(b_sd[i],t_sd[i])+0.06,\n f\"{sym}{abs(d)*100:.1f}%\", ha=\"center\",\n color=col, fontsize=11, fontweight=\"bold\")\n\nax4.set(title=\"Average Metrics: Baseline vs Trained (Β±1Οƒ error bars)\",\n ylabel=\"Mean Score [0–1]\", ylim=(0,1.25))\nax4.set_xticks(x); ax4.set_xticklabels(metrics, fontsize=10)\nax4.legend(fontsize=9); ax4.grid(alpha=0.3,axis=\"y\")\n\n# ── P5: Zone-level service (most visually compelling) ────────────────────────\nax5 = fig.add_subplot(gs[1,2])\nb_svcs = [sum(row[i] for row in df[\"b_services\"])/len(df) for i in range(5)]\nt_svcs = [sum(row[i] for row in df[\"t_services\"])/len(df) for i in range(5)]\nzi = np.arange(5)\nax5.bar(zi-0.22, b_svcs, 0.42, label=\"Baseline\",color=C[\"base\"], alpha=0.85)\nax5.bar(zi+0.22, t_svcs, 0.42, label=\"Trained\", color=C[\"train\"], alpha=0.85)\nfor i,(b,t) in enumerate(zip(b_svcs,t_svcs)):\n if t>b+0.01:\n ax5.text(i+0.22, t+0.01, f\"+{(t-b)*100:.0f}%\",\n ha=\"center\",color=\"#27AE60\",fontsize=8,fontweight=\"bold\")\nax5.axvline(3.5, color=\"red\", linestyle=\"--\", alpha=0.4)\nax5.text(4.1, max(t_svcs)*0.95, \"Vulnerable\\nzones\", color=\"red\",\n fontsize=8, ha=\"center\")\nax5.set(title=\"Zone-Level Service Delivery\\n(avg over 10 episodes β€” Zone 4β˜… = most vulnerable)\",\n xlabel=\"Zone ID\", ylabel=\"Avg Service Level [0–1]\", ylim=(0,1.1))\nax5.set_xticks(zi)\nax5.set_xticklabels([f\"Z{i}\"+\"β˜…\"*(i==4) for i in range(5)])\nax5.legend(fontsize=8); ax5.grid(alpha=0.3,axis=\"y\")\n\nfig.suptitle(\n \"FairRecovery++ β€” Fair-GRPO-RLVR vs Greedy Baseline\\n\"\n \"Training Llama-3.2-1B to Escape the Fairness Trap in Disaster Recovery\",\n fontsize=14, fontweight=\"bold\"\n)\nplt.savefig(f\"{PLOTS_DIR}/full_results.png\", dpi=150, bbox_inches=\"tight\")\nplt.close()\nprint(f\"βœ… Saved: {PLOTS_DIR}/full_results.png\")\n\n# Standalone fairness plot for README\nfig2, ax = plt.subplots(figsize=(9,5))\nax.plot(episodes, df[\"baseline_fairness\"], \"o-\", color=C[\"base\"], lw=2.5, label=\"Baseline (Greedy Policy)\")\nax.plot(episodes, df[\"trained_fairness\"], \"s-\", color=C[\"fair\"], lw=2.5, label=\"Trained (Fair-GRPO-RLVR)\")\nax.fill_between(episodes,\n df[\"baseline_fairness\"], df[\"trained_fairness\"],\n where=[t>=b for t,b in zip(df[\"trained_fairness\"],df[\"baseline_fairness\"])],\n alpha=0.15, color=\"green\")\nax.set(title=\"Fairness Score: Before vs After GRPO Training\\n\"\n \"Inverse Service Disparity (higher = more equitable resource allocation)\",\n xlabel=\"Evaluation Episode\", ylabel=\"Fairness Score [0–1]\",\n ylim=(max(0, min(df[\"baseline_fairness\"].min(), df[\"trained_fairness\"].min())-0.1), 1.05))\nax.legend(fontsize=11); ax.grid(alpha=0.3)\nplt.tight_layout()\nplt.savefig(f\"{PLOTS_DIR}/fairness_vs_episode.png\", dpi=150, bbox_inches=\"tight\")\nplt.close()\nprint(f\"βœ… Saved: {PLOTS_DIR}/fairness_vs_episode.png\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T04:21:59.399439Z","iopub.execute_input":"2026-04-26T04:21:59.399810Z","iopub.status.idle":"2026-04-26T04:22:00.791865Z","shell.execute_reply.started":"2026-04-26T04:21:59.399768Z","shell.execute_reply":"2026-04-26T04:22:00.791082Z"}},"outputs":[{"name":"stdout","text":"βœ… Saved: plots/full_results.png\nβœ… Saved: plots/fairness_vs_episode.png\n","output_type":"stream"}],"execution_count":14},{"id":"c82072407","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 15 β€” FINAL SUMMARY TABLE\n# ════════════════════════════════════════════════════════\nb_r = df[\"baseline_reward\"].mean(); t_r = df[\"trained_reward\"].mean()\nb_f = df[\"baseline_fairness\"].mean(); t_f = df[\"trained_fairness\"].mean()\nb_u = df[\"baseline_utility\"].mean(); t_u = df[\"trained_utility\"].mean()\ndr = t_r - b_r; df_ = t_f - b_f; du = t_u - b_u\n\nprint()\nprint(\"╔══════════════════════════════════════════════════════════════╗\")\nprint(\"β•‘ FINAL RESULTS β€” Fair-GRPO-RLVR vs Greedy β•‘\")\nprint(\"╠══════════════════════════════════════════════════════════════╣\")\nprint(f\"β•‘ {'Metric':<14} {'Baseline':>9} {'Trained':>9} {'Delta':>9} {'%':>8} β•‘\")\nprint(\"╠══════════════════════════════════════════════════════════════╣\")\nfor label, bv, tv, d in [\n (\"Reward\", b_r, t_r, dr),\n (\"Fairness\", b_f, t_f, df_),\n (\"Utility\", b_u, t_u, du),\n]:\n pct = d / (abs(bv)+1e-8) * 100\n icon = \"βœ…\" if d > 0.002 else (\"➑️ \" if abs(d) <= 0.002 else \"❌\")\n print(f\"β•‘ {icon} {label:<13} {bv:>9.4f} {tv:>9.4f} {d:>+9.4f} {pct:>+7.1f}% β•‘\")\nprint(\"╠══════════════════════════════════════════════════════════════╣\")\n\nn_won = sum([dr > 0.002, df_ > 0.002, du > 0.002])\nif n_won == 3:\n verdict = \"πŸ† IMPROVED ON ALL METRICS β€” Fairness Trap escaped!\"\nelif n_won >= 2:\n verdict = f\"βœ… IMPROVED ON {n_won}/3 METRICS\"\nelif n_won == 1:\n verdict = \"⚠️ PARTIAL β€” check zone-level plot for insight\"\nelse:\n verdict = \"❌ No improvement β€” re-run diagnostic in Cell 5\"\n\nprint(f\"β•‘ {verdict:<60}β•‘\")\nprint(\"β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•\")\n\nprint()\nprint(\"πŸ“ Output files ready:\")\nprint(f\" {PLOTS_DIR}/training_loss.png ← evidence training ran\")\nprint(f\" {PLOTS_DIR}/full_results.png ← 5-panel comparison (for README)\")\nprint(f\" {PLOTS_DIR}/fairness_vs_episode.png ← fairness standalone (for README)\")\nprint(f\" ./outputs/model/ ← trained LoRA weights\")\nprint()\nprint(\"πŸ”— Next steps:\")\nprint(\" 1. Copy plots/ to your repo assets/ folder\")\nprint(\" 2. Push model to HF Hub (see Cell 16)\")\nprint(\" 3. Fix README Colab link to:\")\nprint(\" https://colab.research.google.com/github/Joshua1702/FairRecovery-PlusPlus/blob/main/train.ipynb\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T04:53:53.392100Z","iopub.execute_input":"2026-04-26T04:53:53.392907Z","iopub.status.idle":"2026-04-26T04:53:53.404368Z","shell.execute_reply.started":"2026-04-26T04:53:53.392863Z","shell.execute_reply":"2026-04-26T04:53:53.403562Z"}},"outputs":[{"name":"stdout","text":"\n╔══════════════════════════════════════════════════════════════╗\nβ•‘ FINAL RESULTS β€” Fair-GRPO-RLVR vs Greedy β•‘\n╠══════════════════════════════════════════════════════════════╣\nβ•‘ Metric Baseline Trained Delta % β•‘\n╠══════════════════════════════════════════════════════════════╣\nβ•‘ βœ… Reward 0.7238 0.7953 +0.0714 +9.9% β•‘\nβ•‘ βœ… Fairness 0.7433 0.7730 +0.0298 +4.0% β•‘\nβ•‘ βœ… Utility 0.5663 0.7152 +0.1489 +26.3% β•‘\n╠══════════════════════════════════════════════════════════════╣\nβ•‘ πŸ† IMPROVED ON ALL METRICS β€” Fairness Trap escaped! β•‘\nβ•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•\n\nπŸ“ Output files ready:\n plots/training_loss.png ← evidence training ran\n plots/full_results.png ← 5-panel comparison (for README)\n plots/fairness_vs_episode.png ← fairness standalone (for README)\n ./outputs/model/ ← trained LoRA weights\n\nπŸ”— Next steps:\n 1. Copy plots/ to your repo assets/ folder\n 2. Push model to HF Hub (see Cell 16)\n 3. Fix README Colab link to:\n https://colab.research.google.com/github/Joshua1702/FairRecovery-PlusPlus/blob/main/train.ipynb\n","output_type":"stream"}],"execution_count":55},{"id":"cd8d8b4b-3332-49fa-ba07-6baea785d644","cell_type":"code","source":"from huggingface_hub import HfApi, create_repo\nfrom huggingface_hub.utils import RepositoryNotFoundError\n\n# Configuration\nREPO_ID = \"Joshua1702/FairRecovery-PlusPlus\"\napi = HfApi()\n\n# 1. Ensure the Space exists\ntry:\n api.repo_info(repo_id=REPO_ID, repo_type=\"space\")\n print(f\"βœ… Space '{REPO_ID}' found.\")\nexcept RepositoryNotFoundError:\n print(f\"πŸš€ Space not found. Creating '{REPO_ID}' as a Gradio space...\")\n # Adjust sdk if you're using 'streamlit' or 'static'\n create_repo(repo_id=REPO_ID, repo_type=\"space\", space_sdk=\"gradio\", private=False)\n print(\"βœ… Space created successfully.\")\n\n# 2. Upload the plots\nprint(\"πŸ“€ Uploading plots to Space...\")\napi.upload_folder(\n folder_path=\"plots\",\n path_in_repo=\"assets\",\n repo_id=REPO_ID,\n repo_type=\"space\", # CRITICAL: Changed from 'model' to 'space'\n commit_message=\"Add training and fairness analysis plots\"\n)\n\n# 3. Upload the model weights\nprint(\"πŸ“€ Uploading model weights to Space...\")\napi.upload_folder(\n folder_path=\"./outputs/model\",\n path_in_repo=\"adapter\",\n repo_id=REPO_ID,\n repo_type=\"space\", # CRITICAL: Changed from 'model' to 'space'\n commit_message=\"Upload trained LoRA weights\"\n)\n\nprint(f\"\\n✨ All done! View your Space here: https://huggingface.co/spaces/{REPO_ID}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T05:19:53.759720Z","iopub.execute_input":"2026-04-26T05:19:53.760037Z","iopub.status.idle":"2026-04-26T05:19:57.426362Z","shell.execute_reply.started":"2026-04-26T05:19:53.759999Z","shell.execute_reply":"2026-04-26T05:19:57.425691Z"}},"outputs":[{"name":"stdout","text":"βœ… Space 'Joshua1702/FairRecovery-PlusPlus' found.\nπŸ“€ Uploading plots to Space...\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"Processing Files (0 / 0): | | 0.00B / 0.00B ","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"d99c085fb0ef406eb32202c1fcc6f24e"}},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"New Data Upload: | | 0.00B / 0.00B ","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"b4472e0de1324a06882cc7977f758614"}},"metadata":{}},{"name":"stdout","text":"πŸ“€ Uploading model weights to Space...\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"Processing Files (0 / 0): | | 0.00B / 0.00B ","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"b4e4801e3a9e42e58755ba218025a2fd"}},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"New Data Upload: | | 0.00B / 0.00B ","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"ba6c7bf87e5a46b5969a0cdce401d8b9"}},"metadata":{}},{"name":"stdout","text":"\n✨ All done! View your Space here: https://huggingface.co/spaces/Joshua1702/FairRecovery-PlusPlus\n","output_type":"stream"}],"execution_count":70},{"id":"c57664037","cell_type":"code","source":"# ════════════════════════════════════════════════════════\n# CELL 16 β€” PUBLISH TO HUGGINGFACE HUB\n# ════════════════════════════════════════════════════════\nfrom huggingface_hub import login\n\n# FIX: Removed the trailing space at the end of the string\nHF_USERNAME = \"Joshua1702\" \nMODEL_NAME = \"fairrecovery-Llama-3.2-1B\" \n\n# Note: Please ensure you rotate your token since it was exposed in the logs!\nlogin(token=\"[HF_TOKEN_REMOVED]\") \n\n# Push Model\n# This will now correctly resolve to \"Joshua1702/fairrecovery-Llama-3.2-1B\"\nmodel.push_to_hub(\n f\"{HF_USERNAME}/{MODEL_NAME}\",\n commit_message=\"Fair-GRPO-RLVR trained on FairRecovery++ env\"\n)\n\n# Push Tokenizer\ntokenizer.push_to_hub(f\"{HF_USERNAME}/{MODEL_NAME}\")\n\nprint(f\"βœ… Published to HuggingFace Hub: https://huggingface.co/{HF_USERNAME}/{MODEL_NAME}\")\n\nprint(\"\\nAdd this to your README.md:\")\nprint(f\"[![Model](https://img.shields.io/badge/πŸ€—_Model-{MODEL_NAME}-orange)](https://huggingface.co/{HF_USERNAME}/{MODEL_NAME})\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-26T05:20:34.161588Z","iopub.execute_input":"2026-04-26T05:20:34.162135Z","iopub.status.idle":"2026-04-26T05:20:38.215311Z","shell.execute_reply.started":"2026-04-26T05:20:34.162095Z","shell.execute_reply":"2026-04-26T05:20:38.214476Z"}},"outputs":[{"output_type":"display_data","data":{"text/plain":"Processing Files (0 / 0): | | 0.00B / 0.00B ","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"0125c0b2698e4e14a65f47b29fbf0876"}},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"New Data Upload: | | 0.00B / 0.00B ","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"83749b2f2fd2409e8952159aa63f0b45"}},"metadata":{}},{"name":"stderr","text":"No files have been modified since last commit. Skipping to prevent empty commit.\n[huggingface_hub.hf_api|WARNING]No files have been modified since last commit. Skipping to prevent empty commit.\n","output_type":"stream"},{"name":"stdout","text":"Saved model to https://huggingface.co/Joshua1702/fairrecovery-Llama-3.2-1B\n","output_type":"stream"},{"name":"stderr","text":"Unsloth: Restored added_tokens_decoder metadata in /tmp/tmpjpay_b3_/tokenizer_config.json.\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"Processing Files (0 / 0): | | 0.00B / 0.00B ","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"0115ed4c7e3c48ea9c88654ee1a4a764"}},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"New Data Upload: | | 0.00B / 0.00B ","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"dbfa680e40c742cd867b9ac35cd476cc"}},"metadata":{}},{"name":"stderr","text":"No files have been modified since last commit. Skipping to prevent empty commit.\n[huggingface_hub.hf_api|WARNING]No files have been modified since last commit. Skipping to prevent empty commit.\n","output_type":"stream"},{"name":"stdout","text":"βœ… Published to HuggingFace Hub: https://huggingface.co/Joshua1702/fairrecovery-Llama-3.2-1B\n\nAdd this to your README.md:\n[![Model](https://img.shields.io/badge/πŸ€—_Model-fairrecovery-Llama-3.2-1B-orange)](https://huggingface.co/Joshua1702/fairrecovery-Llama-3.2-1B)\n","output_type":"stream"}],"execution_count":71}]}