Files
agent_coding_eval/notebooks/02_qwen25_coder_eval.ipynb
T
fn-registry agent f60da6fa6f chore: initial sync
2026-04-28 22:13:07 +02:00

589 lines
89 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Evaluación: Qwen2.5-Coder-7B-Abliterated\n",
"\n",
"Evaluación de capacidades de programación del modelo local `qwen2.5-coder-7b-abliterated-i1` via LM Studio API.\n",
"\n",
"**Métricas:**\n",
"- Correctitud (tests pass/fail)\n",
"- Velocidad (tokens/segundo)\n",
"- Eficiencia (tokens usados por challenge)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Modelos disponibles: ['qwen2.5-coder-7b-abliterated-i1', 'nvidia/nemotron-3-nano-4b', 'qwen/qwen3.5-9b', 'bitnet-b1.58-2b-4t', 'text-embedding-nomic-embed-text-v1.5']\n",
"\n",
"✓ qwen2.5-coder-7b-abliterated-i1 disponible\n"
]
}
],
"source": [
"import requests\n",
"import json\n",
"import time\n",
"import re\n",
"import subprocess\n",
"import tempfile\n",
"import os\n",
"import pandas as pd\n",
"\n",
"API_BASE = \"http://127.0.0.1:1234/v1\"\n",
"MODEL = \"qwen2.5-coder-7b-abliterated-i1\"\n",
"\n",
"# Verificar conexión\n",
"resp = requests.get(f\"{API_BASE}/models\")\n",
"models = [m[\"id\"] for m in resp.json()[\"data\"]]\n",
"print(f\"Modelos disponibles: {models}\")\n",
"assert MODEL in models, f\"{MODEL} no está cargado!\"\n",
"print(f\"\\n✓ {MODEL} disponible\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ Funciones cargadas\n"
]
}
],
"source": [
"# ── Funciones auxiliares ──────────────────────────────────\n",
"\n",
"def query_model(prompt, max_tokens=1024, temperature=0):\n",
" \"\"\"Consulta el modelo y retorna respuesta + métricas.\"\"\"\n",
" t0 = time.time()\n",
" resp = requests.post(f\"{API_BASE}/chat/completions\", json={\n",
" \"model\": MODEL,\n",
" \"messages\": [\n",
" {\"role\": \"system\", \"content\": \"You are a coding assistant. Return ONLY code inside a single code block. No explanations.\"},\n",
" {\"role\": \"user\", \"content\": prompt},\n",
" ],\n",
" \"max_tokens\": max_tokens,\n",
" \"temperature\": temperature,\n",
" }, timeout=120)\n",
" latency_ms = (time.time() - t0) * 1000\n",
" data = resp.json()\n",
" \n",
" content = data[\"choices\"][0][\"message\"][\"content\"]\n",
" usage = data.get(\"usage\", {})\n",
" completion_tokens = usage.get(\"completion_tokens\", 0)\n",
" prompt_tokens = usage.get(\"prompt_tokens\", 0)\n",
" tps = completion_tokens / (latency_ms / 1000) if latency_ms > 0 else 0\n",
" \n",
" return {\n",
" \"content\": content,\n",
" \"latency_ms\": latency_ms,\n",
" \"completion_tokens\": completion_tokens,\n",
" \"prompt_tokens\": prompt_tokens,\n",
" \"tokens_per_second\": tps,\n",
" }\n",
"\n",
"\n",
"def extract_code(text, language=\"python\"):\n",
" \"\"\"Extrae código de bloque markdown.\"\"\"\n",
" for pat in [rf\"```{language}\\s*\\n(.*?)```\", r\"```\\s*\\n(.*?)```\"]:\n",
" m = re.search(pat, text, re.DOTALL)\n",
" if m:\n",
" return m.group(1).strip()\n",
" return text.strip()\n",
"\n",
"\n",
"def run_python_test(code, test_code, timeout=10):\n",
" \"\"\"Ejecuta código Python + tests. Retorna (passed, error).\"\"\"\n",
" full = code + \"\\n\\n\" + test_code\n",
" with tempfile.NamedTemporaryFile(mode=\"w\", suffix=\".py\", delete=False) as f:\n",
" f.write(full)\n",
" f.flush()\n",
" try:\n",
" result = subprocess.run([\"python3\", f.name], capture_output=True, text=True, timeout=timeout)\n",
" if result.returncode == 0:\n",
" return True, \"\"\n",
" return False, result.stderr.strip()[-300:]\n",
" except subprocess.TimeoutExpired:\n",
" return False, \"TIMEOUT\"\n",
" finally:\n",
" os.unlink(f.name)\n",
"\n",
"\n",
"print(\"✓ Funciones cargadas\")"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ 12 challenges definidos\n",
" easy: 4\n",
" medium: 5\n",
" hard: 3\n"
]
}
],
"source": [
"# ── Challenges ────────────────────────────────────────────\n",
"\n",
"CHALLENGES = [\n",
" # EASY\n",
" {\n",
" \"id\": \"fibonacci\", \"difficulty\": \"easy\",\n",
" \"prompt\": \"Write a Python function `fib(n: int) -> int` that returns the nth Fibonacci number (0-indexed). fib(0)=0, fib(1)=1, fib(10)=55.\",\n",
" \"test\": 'assert fib(0)==0; assert fib(1)==1; assert fib(10)==55; assert fib(20)==6765; print(\"PASS\")'\n",
" },\n",
" {\n",
" \"id\": \"palindrome\", \"difficulty\": \"easy\",\n",
" \"prompt\": \"Write a Python function `is_palindrome(s: str) -> bool` that checks if a string is a palindrome, ignoring case and non-alphanumeric characters.\",\n",
" \"test\": 'assert is_palindrome(\"A man, a plan, a canal: Panama\")==True; assert is_palindrome(\"hello\")==False; assert is_palindrome(\"\")==True; print(\"PASS\")'\n",
" },\n",
" {\n",
" \"id\": \"fizzbuzz\", \"difficulty\": \"easy\",\n",
" \"prompt\": 'Write a Python function `fizzbuzz(n: int) -> list[str]` that returns a list from 1 to n where multiples of 3 are \"Fizz\", multiples of 5 are \"Buzz\", multiples of both are \"FizzBuzz\", and others are the number as string.',\n",
" \"test\": 'r=fizzbuzz(15); assert r[0]==\"1\"; assert r[2]==\"Fizz\"; assert r[4]==\"Buzz\"; assert r[14]==\"FizzBuzz\"; assert len(r)==15; print(\"PASS\")'\n",
" },\n",
" {\n",
" \"id\": \"reverse_string\", \"difficulty\": \"easy\",\n",
" \"prompt\": \"Write a Python function `reverse_words(s: str) -> str` that reverses the order of words. Remove leading/trailing spaces and reduce multiple spaces. Example: ' hello world ' -> 'world hello'.\",\n",
" \"test\": 'assert reverse_words(\"hello world\")==\"world hello\"; assert reverse_words(\" hello world \")==\"world hello\"; assert reverse_words(\"a\")==\"a\"; print(\"PASS\")'\n",
" },\n",
" # MEDIUM\n",
" {\n",
" \"id\": \"two_sum\", \"difficulty\": \"medium\",\n",
" \"prompt\": \"Write a Python function `two_sum(nums: list[int], target: int) -> tuple[int, int]` that returns indices of two numbers that add up to target. Return indices in ascending order. Each input has exactly one solution.\",\n",
" \"test\": 'assert two_sum([2,7,11,15],9)==(0,1); assert two_sum([3,2,4],6)==(1,2); assert two_sum([3,3],6)==(0,1); print(\"PASS\")'\n",
" },\n",
" {\n",
" \"id\": \"balanced_parens\", \"difficulty\": \"medium\",\n",
" \"prompt\": \"Write a Python function `is_balanced(s: str) -> bool` that checks if a string has balanced parentheses, brackets, and braces ()[]{}. Ignore other characters.\",\n",
" \"test\": 'assert is_balanced(\"()[]{}\"); assert is_balanced(\"([{}])\"); assert not is_balanced(\"(]\"); assert not is_balanced(\"([)]\"); assert is_balanced(\"\"); print(\"PASS\")'\n",
" },\n",
" {\n",
" \"id\": \"group_anagrams\", \"difficulty\": \"medium\",\n",
" \"prompt\": 'Write a Python function `group_anagrams(words: list[str]) -> list[list[str]]` that groups anagrams together. Each group sorted alphabetically, groups sorted by first element.',\n",
" \"test\": 'r=[sorted(g) for g in group_anagrams([\"eat\",\"tea\",\"tan\",\"ate\",\"nat\",\"bat\"])]; r.sort(key=lambda g:g[0]); assert r==[[\"ate\",\"eat\",\"tea\"],[\"bat\"],[\"nat\",\"tan\"]]; print(\"PASS\")'\n",
" },\n",
" {\n",
" \"id\": \"matrix_spiral\", \"difficulty\": \"medium\",\n",
" \"prompt\": \"Write a Python function `spiral_order(matrix: list[list[int]]) -> list[int]` that returns all elements of a matrix in spiral order (clockwise from top-left).\",\n",
" \"test\": 'assert spiral_order([[1,2,3],[4,5,6],[7,8,9]])==[1,2,3,6,9,8,7,4,5]; assert spiral_order([[1,2],[3,4]])==[1,2,4,3]; assert spiral_order([[1]])==[1]; print(\"PASS\")'\n",
" },\n",
" {\n",
" \"id\": \"flatten_nested\", \"difficulty\": \"medium\",\n",
" \"prompt\": \"Write a Python function `flatten(lst) -> list` that deeply flattens a nested list. Example: flatten([1, [2, [3, 4], 5], 6]) -> [1, 2, 3, 4, 5, 6]. Do NOT use itertools.\",\n",
" \"test\": 'assert flatten([1,[2,[3,4],5],6])==[1,2,3,4,5,6]; assert flatten([])==[]; assert flatten([1,2,3])==[1,2,3]; assert flatten([[[[1]]]])==[1]; print(\"PASS\")'\n",
" },\n",
" # HARD\n",
" {\n",
" \"id\": \"lru_cache\", \"difficulty\": \"hard\", \"max_tokens\": 1500,\n",
" \"prompt\": \"\"\"Write a Python class `LRUCache` with:\n",
"- `__init__(self, capacity: int)` - Initialize with positive capacity.\n",
"- `get(self, key: int) -> int` - Return value if key exists, else -1. Marks as recently used.\n",
"- `put(self, key: int, value: int) -> None` - Update or insert. If over capacity, evict least recently used.\n",
"Both get and put must run in O(1) average time. Do NOT use functools.lru_cache or collections.OrderedDict.\"\"\",\n",
" \"test\": 'c=LRUCache(2); c.put(1,1); c.put(2,2); assert c.get(1)==1; c.put(3,3); assert c.get(2)==-1; c.put(4,4); assert c.get(1)==-1; assert c.get(3)==3; assert c.get(4)==4; print(\"PASS\")'\n",
" },\n",
" {\n",
" \"id\": \"merge_intervals\", \"difficulty\": \"hard\",\n",
" \"prompt\": \"Write a Python function `merge_intervals(intervals: list[list[int]]) -> list[list[int]]` that merges all overlapping intervals and returns sorted non-overlapping intervals.\",\n",
" \"test\": 'assert merge_intervals([[1,3],[2,6],[8,10],[15,18]])==[[1,6],[8,10],[15,18]]; assert merge_intervals([[1,4],[4,5]])==[[1,5]]; assert merge_intervals([])==[]; print(\"PASS\")'\n",
" },\n",
" {\n",
" \"id\": \"longest_substr\", \"difficulty\": \"hard\",\n",
" \"prompt\": \"Write a Python function `length_of_longest_substring(s: str) -> int` that returns the length of the longest substring without repeating characters. Use sliding window, O(n) time.\",\n",
" \"test\": 'assert length_of_longest_substring(\"abcabcbb\")==3; assert length_of_longest_substring(\"bbbbb\")==1; assert length_of_longest_substring(\"pwwkew\")==3; assert length_of_longest_substring(\"\")==0; print(\"PASS\")'\n",
" },\n",
"]\n",
"\n",
"print(f\"✓ {len(CHALLENGES)} challenges definidos\")\n",
"for d in [\"easy\", \"medium\", \"hard\"]:\n",
" n = sum(1 for c in CHALLENGES if c[\"difficulty\"] == d)\n",
" print(f\" {d}: {n}\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Evaluando qwen2.5-coder-7b-abliterated-i1\n",
"======================================================================\n",
"\n",
"[fibonacci] (easy)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 6461ms 81tok 12.5t/s\n",
"[palindrome] (easy)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 2234ms 65tok 29.1t/s\n",
"[fizzbuzz] (easy)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 3457ms 102tok 29.5t/s\n",
"[reverse_string] (easy)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 999ms 28tok 28.0t/s\n",
"[two_sum] (medium)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 2337ms 70tok 29.9t/s\n",
"[balanced_parens] (medium)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 2982ms 88tok 29.5t/s\n",
"[group_anagrams] (medium)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 4212ms 127tok 30.2t/s\n",
"[matrix_spiral] (medium)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 6545ms 200tok 30.6t/s\n",
"[flatten_nested] (medium)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 1579ms 46tok 29.1t/s\n",
"[lru_cache] (hard)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 12730ms 356tok 28.0t/s\n",
"[merge_intervals] (hard)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 4609ms 127tok 27.6t/s\n",
"[longest_substr] (hard)... "
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ PASS 3392ms 95tok 28.0t/s\n",
"\n",
"======================================================================\n",
"\n",
"Total: 12/12 passed (100%)\n"
]
}
],
"source": [
"# ── Ejecutar evaluación ───────────────────────────────────\n",
"\n",
"results = []\n",
"\n",
"print(f\"Evaluando {MODEL}\")\n",
"print(f\"{'='*70}\\n\")\n",
"\n",
"for ch in CHALLENGES:\n",
" max_tok = ch.get(\"max_tokens\", 1024)\n",
" print(f\"[{ch['id']}] ({ch['difficulty']})...\", end=\" \", flush=True)\n",
" \n",
" resp = query_model(ch[\"prompt\"], max_tokens=max_tok)\n",
" code = extract_code(resp[\"content\"])\n",
" passed, error = run_python_test(code, ch[\"test\"])\n",
" \n",
" status = \"✓ PASS\" if passed else \"✗ FAIL\"\n",
" print(f\"{status} {resp['latency_ms']:.0f}ms {resp['completion_tokens']}tok {resp['tokens_per_second']:.1f}t/s\")\n",
" \n",
" results.append({\n",
" \"challenge\": ch[\"id\"],\n",
" \"difficulty\": ch[\"difficulty\"],\n",
" \"passed\": passed,\n",
" \"error\": error,\n",
" \"code\": code,\n",
" \"raw_response\": resp[\"content\"],\n",
" \"latency_ms\": resp[\"latency_ms\"],\n",
" \"completion_tokens\": resp[\"completion_tokens\"],\n",
" \"prompt_tokens\": resp[\"prompt_tokens\"],\n",
" \"tokens_per_second\": resp[\"tokens_per_second\"],\n",
" })\n",
"\n",
"print(f\"\\n{'='*70}\")\n",
"passed_total = sum(1 for r in results if r[\"passed\"])\n",
"print(f\"\\nTotal: {passed_total}/{len(results)} passed ({100*passed_total/len(results):.0f}%)\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" challenge difficulty status latency_s completion_tokens tok_s\n",
" fibonacci easy ✓ PASS 6.5 81 12.5\n",
" palindrome easy ✓ PASS 2.2 65 29.1\n",
" fizzbuzz easy ✓ PASS 3.5 102 29.5\n",
" reverse_string easy ✓ PASS 1.0 28 28.0\n",
" two_sum medium ✓ PASS 2.3 70 29.9\n",
"balanced_parens medium ✓ PASS 3.0 88 29.5\n",
" group_anagrams medium ✓ PASS 4.2 127 30.2\n",
" matrix_spiral medium ✓ PASS 6.5 200 30.6\n",
" flatten_nested medium ✓ PASS 1.6 46 29.1\n",
" lru_cache hard ✓ PASS 12.7 356 28.0\n",
"merge_intervals hard ✓ PASS 4.6 127 27.6\n",
" longest_substr hard ✓ PASS 3.4 95 28.0\n",
"\n",
"────────────────────────────────────────────────────────────\n",
"Velocidad promedio: 27.7 tok/s\n",
"Velocidad mediana: 29.1 tok/s\n",
"Rango: 12.5 - 30.6 tok/s\n",
"Latencia promedio: 4.3s\n",
"Tokens promedio: 115\n"
]
}
],
"source": [
"# ── Tabla de resultados ───────────────────────────────────\n",
"\n",
"df = pd.DataFrame(results)\n",
"df[\"status\"] = df[\"passed\"].map({True: \"✓ PASS\", False: \"✗ FAIL\"})\n",
"df[\"latency_s\"] = (df[\"latency_ms\"] / 1000).round(1)\n",
"df[\"tok_s\"] = df[\"tokens_per_second\"].round(1)\n",
"\n",
"display_cols = [\"challenge\", \"difficulty\", \"status\", \"latency_s\", \"completion_tokens\", \"tok_s\"]\n",
"print(df[display_cols].to_string(index=False))\n",
"\n",
"print(f\"\\n{'─'*60}\")\n",
"print(f\"Velocidad promedio: {df['tokens_per_second'].mean():.1f} tok/s\")\n",
"print(f\"Velocidad mediana: {df['tokens_per_second'].median():.1f} tok/s\")\n",
"print(f\"Rango: {df['tokens_per_second'].min():.1f} - {df['tokens_per_second'].max():.1f} tok/s\")\n",
"print(f\"Latencia promedio: {df['latency_ms'].mean()/1000:.1f}s\")\n",
"print(f\"Tokens promedio: {df['completion_tokens'].mean():.0f}\")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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kJAQI3fu3Ma+ffuStfnll18aTk5O5n1etmxZirlFSrZv325IMr799ttH1gUAZEzW7in/7d69e0Z8fLxF2ZUrV4y8efMaHTt2NJdduHDB6jWwVq1aRqlSpYzbt2+byxITE42qVasaAQEByeKpXbu2+bpuGIbRp08fw87Oznwdv3r1quHq6mpUrlzZ+Oeffyy29e/1Hrw3NozUXeetefHFF43g4OBk5WXKlDEaNGjw0HVTewzeffddw2QyWVy3L126ZHh6eia7D7d2vAsVKmS0a9fO/D21x/X8+fOGvb290aBBA4t6H3zwgSHJos3U5iVp6Wfq2rWr4eTklKq6yPiYzgU2Ubt2bXl7e8vX11ctW7aUi4uLli1bpgIFCki6/6h1kitXrujatWuqXr269u7day5Pmjf7hx9+sPpItYeHh/7880/t2rXrseL8+OOP5e3trXz58plHiX322Wd67bXXLOr9O95r167p4sWLCgkJ0fHjx3Xt2rVHbuf7779X9erVlStXLl28eNH8qV27thISErRly5ZHtpE/f36Lv3a7ubmpbdu22rdvn86ePSvp/hyhlSpV0osvvmiu5+Lioq5du+rkyZM6cOCARZvt2rWz2Lf/wsXFRZJ0/fr1/9zWkiVLZDKZ9PHHHydb9rRf2OHg4KBs2e7/6kxISNClS5fMUwn9+9/n6tWr5ePjY/FvJWfOnOratetTjQ8A8Gh2dnZq2bKlduzYYfEI8YIFC5Q3b17VqlVL0uNfnxMSErR+/Xo1adJEhQsXNpf7+PjojTfe0LZt28xTpC1ZskRlypRJcdS1tWvamTNntH//frVr107u7u7m8jp16igoKChZ/dTkVUnvLenZs6fFur17904xhgddunRJUvKn9R4mrXnJtWvX9PLLL+vQoUOKjIxU2bJlU2yzRo0a5n1OyhdXrlypu3fvPjSepNiTptEBAGROdnZ25qesExMTdfnyZd27d08VKlSwuDZac/nyZf30009q0aKFrl+/bs4PLl26pLCwMB09elR//fWXxTpdu3a1uK5Xr15dCQkJOnXqlKT7U9Vev35dAwcOlKOjo8W6j7rHTc113ppLly6leO328PDQH3/8oaNHj6a4XlqOwdq1a1WlShWL67anp+cTef/Mo47rxo0bdefOnWQv90wpv0ltXpKWfqZcuXLpn3/+0a1btx53F5GB0IkOm5gyZYo2bNigTZs26cCBAzp+/LjCwsLMy1euXKkXXnhBjo6O8vT0ND9K9e8O6ddff13VqlVT586dlTdvXrVs2VLfffedRYf6gAED5OLiokqVKikgIEDdu3dP06M0Xbt21YYNG/S///1Pffr00T///KOEhIRk9aKiolS7dm05OzvLw8ND3t7e5rnZU9OJfvToUa1du1be3t4Wn6R5yVKas/VBRYoUSXZxLVq0qKT/m4bm1KlTKlasWLJ1AwMDzcv/zd/f/5HbTa0bN25IklxdXf9zWzExMcqfP788PT3/c1tplZiYqPHjxysgIEAODg7KnTu3vL299euvv1qc61OnTqV4TlI6/gCA9Jd045Y0f+Wff/6prVu3qmXLluYXeD7u9fnChQu6deuW1WtuYmKiTp8+Len+NS2tU4ckXa8DAgKSLUtpm6nJq06dOqVs2bIlm0otrdctIw3ziac1L+ndu7d27dqljRs3pvjS0Lt372rDhg0Wj66HhISoWbNmGjZsmHLnzq3GjRtrzpw5Kb6jJCn2p/0HeQCA7UVERKh06dLm+b69vb21atWqVN2/Hzt2TIZhaPDgwclyhKSBXg/mCAULFrT4ntRxfeXKFUn/N8Xt40wnlprr/MOkdO0ePny4rl69qqJFi6pUqVJ6//339euvv5qXp+UYJN0bPyilsrR61HG1ljN5e3sn++NBavOStPQzkVtkLsyJDpuoVKmS1Xmrt27dqldeeUUvvfSSpk6dKh8fH+XIkUNz5syxeFGDk5OTtmzZok2bNmnVqlVau3atvv32W9WsWVPr16+XnZ2dAgMDdfjwYa1cuVJr167VkiVLNHXqVA0ZMkTDhg17ZJwBAQHmG+WGDRvKzs5OAwcOVI0aNczxx8TEqFatWipevLg+//xz+fr6yt7eXqtXr9b48eNT9eKxxMRE1alTR/37909xeVJneHp7UqPQJen333+XnZ3dE+2YfxhrF6mU/giSFqNHj9bgwYPVsWNHjRgxQp6ensqWLZt69+6dqnMNAMgYgoODVbx4cS1cuFAffPCBFi5cKMMwLEZFZdTrc1qkNq/6r5Lea5N00/o0NG7cWIsWLdKYMWP09ddfm58MS5I0wr9+/frmMpPJpMWLF+vnn3/W//73P61bt04dO3bUZ599pp9//tn8pNy/Y7c2Dz0AIHP45ptv1L59ezVp0kTvv/++8uTJIzs7O4WHh5s7sx8m6b6vX79+FoMB/+3BDuKkP9A/KC1/fE7Jf73Oe3l5pXjtfumllxQTE6MffvhB69ev1+zZszV+/HhNnz5dnTt3fqxj8F9Yu49/Wsf1YdLSz3TlyhXlzJnzifatwHboREeGs2TJEjk6OmrdunUWL5qYM2dOsrrZsmVTrVq1VKtWLX3++ecaPXq0PvzwQ23atMnc+e3s7KzXX39dr7/+uu7cuaOmTZtq1KhRGjRoULLHpB7lww8/1KxZs/TRRx9p7dq1kqT//e9/io+P14oVKyz+CvrvN3snsdax+/zzz+vGjRvJ3oidFkl/Cf73No4cOSJJ5rd3FypUSIcPH0627qFDh8zLn4bY2Fht3rxZVapUeSIj0Z9//nmtW7dOly9ftjoaPemvylevXrUof3BUmzXWztXixYtVo0YNffnllxblV69etbjpLlSokH7//fdk5ySl4w8AsI3WrVtr8ODB+vXXX7VgwQIFBARYvKTyca/P3t7eypkzp9VrbrZs2eTr62vexu+//56m9pOu1yk9Yv3gNlObVxUqVEiJiYmKiYmxGIWV2utW8eLFJUknTpxItszaNTWteUmTJk308ssvq3379nJ1ddW0adMslq9atUpBQUHmvOffXnjhBb3wwgsaNWqUFixYoNatW2vRokXq3LmzuU5S7EkjzgAAmdPixYtVuHBhLV261OIa9eB0odauX0lTteXIkeM/3cP/W9KTYL///nuaOp/T0n+SkuLFi2vJkiUpLvP09FSHDh3UoUMH3bhxQy+99JKGDh2qzp07p+kYFCpUSMeOHUtWnlJZrly5kt3D37lzR2fOnEnV/qS0bel+zvTvKfYuXLiQ7I8HaclLUtvPdOLECfKKTITpXJDh2NnZyWQyWfyl8eTJk1q+fLlFvcuXLydbN2mOraRHdJPm50xib2+voKAgGYbxyHkxU+Lh4aFu3bpp3bp12r9/vzleyfIvndeuXUvxouXs7JzsgiBJLVq00I4dO7Ru3bpky65evap79+49Mra///5by5YtM3+Pi4vT119/rbJlyypfvnySpPr16+uXX37Rjh07zPVu3rypmTNnys/PL8V5VP+ry5cvq1WrVkpISNCHH374RNps1qyZDMNI8WmCpPPg5uam3LlzJ5uvdurUqanahrVzZWdnl+yv2t9//32yOe/q16+vv//+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AAAAAAAAAMAKOtEBAAAAAAAAALCCTnQAAAAAAAAAAKygEx0AgCzOz89PEyZMsHUY/0n79u3VpEkTW4cBAECmQG4AAICl7LYOAAAA2NauXbvk7Oyc6vqRkZGqUaOGrly5Ig8Pj6cXGAAAsAlyAwAALNGJDgBABnXnzh3Z29s/9e14e3s/9W2kxDAMJSQkKHt20hEAAFKD3AAAANtgOhcAAB5DaGio3n33XfXu3Vu5cuVS3rx5NWvWLN28eVMdOnSQq6urihQpojVr1pjX+f3331WvXj25uLgob968atOmjS5evGjRZo8ePdS7d2/lzp1bYWFhkqQVK1YoICBAjo6OqlGjhiIiImQymXT16lXzutu2bVP16tXl5OQkX19f9ezZUzdv3kzVvjz4yLbJZNLs2bP16quvKmfOnAoICNCKFSskSSdPnlSNGjUkSbly5ZLJZFL79u0lSYmJiQoPD5e/v7+cnJxUpkwZLV682NxuZGSkTCaT1qxZo+DgYDk4OOirr76SyWTSoUOHLGIaP368nn/+eUlSQkKCOnXqZG63WLFimjhx4kP3afHixSpVqpScnJzk5eWl2rVrp/p4AADwOMgNyA0AAJkXnegAADymiIgI5c6dW7/88oveffddvf3222revLmqVq2qvXv36uWXX1abNm1069YtXb16VTVr1lS5cuW0e/durV27VufOnVOLFi2StWlvb6+oqChNnz5dJ06c0GuvvaYmTZooOjpa3bp104cffmixTkxMjOrWratmzZrp119/1bfffqtt27apR48ej71vw4YNU4sWLfTrr7+qfv36at26tS5fvixfX18tWbJEknT48GGdOXPGfNMaHh6ur7/+WtOnT9cff/yhPn366M0339TmzZst2h44cKDGjBmjgwcP6rXXXlOFChU0f/58izrz58/XG2+8Ien+Dfhzzz2n77//XgcOHNCQIUP0wQcf6Lvvvksx9jNnzqhVq1bq2LGjDh48qMjISDVt2lSGYTz28QAAIDXIDcgNAACZk8ngqqG4uDi5u7vr2rVrcnNzS/ftl9nTN923mVFEB39u6xBsgnOeNXHe09/T/P0eGhqqhIQEbd26VdL9EVHu7u5q2rSpvv76a0nS2bNn5ePjox07dmjjxo3aunWr1q1bZ27jzz//lK+vrw4fPqyiRYsqNDRUcXFx2rt3r7nOwIEDtWrV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N/pfLVq0SP369VOnTp20fv167d+/Xx06dEj2crMHH2U2mUzmF3vdvHlTYWFhcnNz0/z587Vr1y4tW7ZMUtpfkubk5CSTyWRR1q5dO+3fv18TJ07U9u3btX//fnl5eT00xqQ2UipLinvo0KH6448/1KBBA/30008KCgoyx50SBwcHubm5WXwAAPgvyA0ejdwAAPCsyNCd6JLUsGFD/fbbb7p9+7YOHjxofnwsiclk0vDhw3X27Fndvn1bGzduVNGiRW0ULQAgsylcuLBy5MihXbt2mcuuXbumI0eOPHS9wMBARUVFWZRFRUWpaNGi5pFd3t7eOnPmjHn50aNHdevWrWRt/fzzz+af7927pz179igwMPCRsUdFRalq1ap65513VK5cORUpUuSRo64edOjQIV26dEljxoxR9erVVbx48WQvDitWrFiyF3P9+3g9KsaePXuqfv365hetXbx4MU0xWlO0aFH16dNH69evV9OmTTVnzpwn0i4AIGsjNyA3AABkPRm+Ex0AAFtydXVVu3bt9P7772vTpk36448/1KlTJ2XLli3ZyKl/e++99/Tjjz9qxIgROnLkiCIiIvTFF1+oX79+5jo1a9bUF198oX379mn37t166623UnzB1ZQpU7Rs2TIdOnRI3bt315UrVyzmIrUmICBAu3fv1rp163TkyBENHjw41TewSQoWLCh7e3tNnjxZx48f14oVKzRixAiLOt26ddOhQ4c0YMAAHTlyRN9995355WMPO0ZJMc6bN08HDx7Uzp071bp1azk5OaUpxgf9888/6tGjhyIjI3Xq1ClFRUVp165dqepcAADgUcgNyA0AAFkPnegAADzC559/ripVqqhhw4aqXbu2qlWrpsDAwIdOHVa+fHl99913WrRokUqWLKkhQ4Zo+PDhFi8O++yzz+Tr66vq1avrjTfeUL9+/ZQzZ85kbY0ZM0ZjxoxRmTJltG3bNq1YsUK5c+d+ZNzdunVT06ZN9frrr6ty5cq6dOmS3nnnnTTtu7e3t+bOnavvv/9eQUFBGjNmjMaNG2dRx9/fX4sXL9bSpUtVunRpTZs2TR9++KEkPfJF3l9++aWuXLmi8uXLq02bNurZs6fy5MmTphgfZGdnp0uXLqlt27YqWrSoWrRooXr16vFyMADAE0NuQG4AAMhaTMaDE65lQXFxcXJ3d9e1a9dsMs9ZmT19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OteuXdOgQYPk6+srDw8Pde3aVefOnTMpce7dybG2bNky23V9/vnnTUqcewsWLFBwcLC8vLzk5eWl0NBQ/fe//7Uut5drCvthz22DO3ntsSczZsyQxWJReHi42VHyzP/+9z89/fTT8vX1lbu7u4KCgrR3716zY+WZzMxMTZw4Uffdd5/c3d1VpUoVTZs2TYX1Fo/23la93fFlZGRo7NixCgoKUvHixVWuXDn16tVLZ86cMS/wXaCIDgAA8P99/vnnGjFihCZPnqzY2FjVrVtXbdu21fnz582Oludq166tpKQk6+P77783O1KeSEtLU926dTV//vxbLp85c6bmzZun9957T7t27VLx4sXVtm1bXbt27R4n/Wf+7jglqV27djbXeNmyZfcwYd6Ijo7WoEGDtHPnTm3atEkZGRl6+OGHlZaWZl1n+PDhWrt2rb744gtFR0frzJkz6tKli4mpc+dOjlWSBgwYYHNdZ86caVLi3KtQoYJmzJihmJgY7d27V61atVKnTp30008/SbKfawr7YO9tgzt97bEHe/bs0X/+8x8FBwebHSXPXLp0Sc2aNVPRokX13//+Vz///LNmz56tkiVLmh0tz7z++utasGCB3nnnHR06dEivv/66Zs6cqbffftvsaLli723V2x3f1atXFRsbq4kTJyo2NlYrV65UfHy8OnbsaELSXDDgUAICAoypU6caJ06cMDsKAAAFTuPGjY1BgwZZpzMzM41y5coZERERJqbKe5MnTzbq1q1rdox8J8n46quvrNNZWVmGn5+fMWvWLOu8y5cvG66ursayZctMSJg3/nqchmEYvXv3Njp16mRKnvx0/vx5Q5IRHR1tGMaN61e0aFHjiy++sK5z6NAhQ5KxY8cOs2Lmib8eq2EYRosWLYxhw4aZFyoflSxZ0vjwww/t+pqicHKUtsFNt3rtsQdXrlwxqlWrZmzatMmuXkvHjh1rPPjgg2bHyFf//ve/jX79+tnM69Kli9GzZ0+TEuUde2+r3qqN+le7d+82JBWKOiU90R1MeHi4Vq5cqcqVK6tNmzb67LPPdP36dbNjIZ9du3ZNs2bNUvv27RUSEqIGDRrYPGAf5s2bd8cPANmlp6crJiZGrVu3ts5zcnJS69attWPHDhOT5Y+jR4+qXLlyqly5snr27KmTJ0+aHSnfJSYm6uzZszbX2NvbW02aNLHL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sIsb5gAAAAAAAJiFIrqDqV27tt577z39+9//1qZNmzRt2jRJ0pkzZ+Tr62tyOuSXbdu2mR0B91ivXr109epV1a1bVy4uLnJ3d7dZfvHiRZOSAQAAAAAAFC4U0R3M66+/rscee0yzZs1S7969rTeaXLNmjXWYF9ifFi1amB0B99ibb75pdgQAAAAAAAC7YDEMwzA7BO6tzMxMpaSkqGTJktZ5x48fV7FixVSmTBkTkyG/fPvtt7dd3rx583uUBAAAAAAAAChcKKIDDsDJKfs9hC0Wi/VnxkS3b9euXVN6errNPC8vL5PSAAAAAAAAFC4M5+KAvvzySy1fvlwnT57MVliLjY01KRXy06VLl2ymMzIytG/fPk2cOFHTp083KRXyU1pamsaOHavly5frwoUL2ZbzjxMAAAAAAIA7k717KuzavHnz1LdvX5UtW1b79u1T48aN5evrq2PHjumRRx4xOx7yibe3t82jVKlSatOmjV5//XWNGTPG7HjIB2PGjNHWrVu1YMECubq66sMPP9TUqVNVrlw5LV682Ox4AOBQWrZsqfDwcLNj2IXjx4/LYrEoLi7O7CgAAOAWaPfAXlFEdzDvvvuu3n//fb399ttycXHRmDFjtGnTJg0dOlTJyclmx8M9VrZsWcXHx5sdA/lg7dq1evfdd9W1a1cVKVJEDz30kF5++WW99tprWrJkidnxAKDQKswfDPv27auXX37Z7BgAAABAocNwLg7m5MmTatq0qSTJ3d1dV65ckSQ988wzeuCBB/TOO++YGQ/55Mcff7SZNgxDSUlJmjFjhurVq2dOKOSrixcvqnLlypJujH9+8eJFSdKDDz6oF154wcxoAAATZGZmat26dfr666/NjgIAAAAUOvREdzB+fn7WYlqlSpW0c+dOSVJiYqK4x6z9qlevnurXr6969epZf27fvr3S09P14Ycfmh0P+aBy5cpKTEyUJNWoUUPLly+XdKOHeokSJUxMBgCFV58+fRQdHa233npLFotFFotFx48fV3R0tBo3bixXV1f5+/tr3Lhx+uOPP3Lcztdffy1vb2/rN4NOnTqlbt26qUSJEvLx8VGnTp10/Phxm/127txZb7zxhvz9/eXr66tBgwYpIyPDus67776ratWqyc3NTWXLltXjjz9us88ffvhBRYsWVaNGjZSenq7BgwfL399fbm5uCggIUERE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",
"text/plain": [
"<Figure size 1500x500 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data",
"transient": {}
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"✓ Gráfico guardado en data/eval_results.png\n"
]
}
],
"source": [
"# ── Resultados por dificultad ─────────────────────────────\n",
"\n",
"import matplotlib.pyplot as plt\n",
"\n",
"fig, axes = plt.subplots(1, 3, figsize=(15, 5))\n",
"\n",
"# 1. Pass rate por dificultad\n",
"ax = axes[0]\n",
"by_diff = df.groupby(\"difficulty\")[\"passed\"].mean() * 100\n",
"by_diff = by_diff.reindex([\"easy\", \"medium\", \"hard\"])\n",
"colors = [\"#2ecc71\" if v == 100 else \"#e74c3c\" if v < 50 else \"#f39c12\" for v in by_diff]\n",
"by_diff.plot(kind=\"bar\", ax=ax, color=colors)\n",
"ax.set_title(\"Pass Rate por Dificultad\")\n",
"ax.set_ylabel(\"%\")\n",
"ax.set_ylim(0, 110)\n",
"for i, v in enumerate(by_diff):\n",
" ax.text(i, v + 2, f\"{v:.0f}%\", ha=\"center\", fontweight=\"bold\")\n",
"\n",
"# 2. Velocidad por challenge\n",
"ax = axes[1]\n",
"colors2 = [\"#2ecc71\" if r else \"#e74c3c\" for r in df[\"passed\"]]\n",
"ax.barh(df[\"challenge\"], df[\"tokens_per_second\"], color=colors2)\n",
"ax.set_title(\"Velocidad (tok/s)\")\n",
"ax.set_xlabel(\"tokens/segundo\")\n",
"\n",
"# 3. Latencia por challenge\n",
"ax = axes[2]\n",
"ax.barh(df[\"challenge\"], df[\"latency_ms\"] / 1000, color=colors2)\n",
"ax.set_title(\"Latencia (segundos)\")\n",
"ax.set_xlabel(\"segundos\")\n",
"\n",
"plt.tight_layout()\n",
"plt.savefig(\"../data/eval_results.png\", dpi=150, bbox_inches=\"tight\")\n",
"plt.show()\n",
"print(\"✓ Gráfico guardado en data/eval_results.png\")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"🎉 Todos los challenges pasaron! No hay fallos que inspeccionar.\n"
]
}
],
"source": [
"# ── Inspeccionar código de challenges fallidos ────────────\n",
"\n",
"failed = [r for r in results if not r[\"passed\"]]\n",
"if not failed:\n",
" print(\"🎉 Todos los challenges pasaron! No hay fallos que inspeccionar.\")\n",
"else:\n",
" for r in failed:\n",
" print(f\"\\n{'='*60}\")\n",
" print(f\"FALLÓ: {r['challenge']} ({r['difficulty']})\")\n",
" print(f\"{'='*60}\")\n",
" print(f\"\\nCódigo generado:\")\n",
" print(r[\"code\"])\n",
" print(f\"\\nError:\")\n",
" print(r[\"error\"])"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"════════════════════════════════════════════════════════════\n",
" RESUMEN: qwen2.5-coder-7b-abliterated-i1\n",
"════════════════════════════════════════════════════════════\n",
"\n",
" Correctitud: 12/12 (100%)\n",
" Velocidad: 27.7 tok/s (promedio)\n",
" Latencia: 4.3s (promedio)\n",
" Eficiencia: 115 tokens/challenge (promedio)\n",
"\n",
" Por dificultad:\n",
" easy 4/4 passed | 24.8 tok/s\n",
" medium 5/5 passed | 29.9 tok/s\n",
" hard 3/3 passed | 27.8 tok/s\n",
"════════════════════════════════════════════════════════════\n"
]
}
],
"source": [
"# ── Resumen final ─────────────────────────────────────────\n",
"\n",
"print(f\"\\n{'═'*60}\")\n",
"print(f\" RESUMEN: {MODEL}\")\n",
"print(f\"{'═'*60}\")\n",
"print(f\"\")\n",
"print(f\" Correctitud: {passed_total}/{len(results)} ({100*passed_total/len(results):.0f}%)\")\n",
"print(f\" Velocidad: {df['tokens_per_second'].mean():.1f} tok/s (promedio)\")\n",
"print(f\" Latencia: {df['latency_ms'].mean()/1000:.1f}s (promedio)\")\n",
"print(f\" Eficiencia: {df['completion_tokens'].mean():.0f} tokens/challenge (promedio)\")\n",
"print(f\"\")\n",
"print(f\" Por dificultad:\")\n",
"for d in [\"easy\", \"medium\", \"hard\"]:\n",
" subset = [r for r in results if r[\"difficulty\"] == d]\n",
" p = sum(1 for r in subset if r[\"passed\"])\n",
" avg_tps = sum(r[\"tokens_per_second\"] for r in subset) / len(subset)\n",
" print(f\" {d:8s} {p}/{len(subset)} passed | {avg_tps:.1f} tok/s\")\n",
"print(f\"{'═'*60}\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.7"
}
},
"nbformat": 4,
"nbformat_minor": 4
}