Una implementación de codificación para automatizar el control de calidad de LLM con DeepEval, recuperadores personalizados y métricas de LLM como juez

Iniciamos este tutorial configurando un entorno de evaluación de alto rendimiento, específicamente enfocado en integrar el marco DeepEval para brindar rigor de pruebas unitarias a nuestras aplicaciones LLM. Al cerrar la brecha entre la recuperación sin procesar y la generación final, implementamos un sistema que trata los resultados del modelo como código comprobable y utiliza métricas de LLM como juez para cuantificar el rendimiento. Vamos más allá de la inspección manual al construir un proceso estructurado en el que cada consulta, contexto recuperado y respuesta generada se valida con métricas rigurosas de estándares académicos. Consulta los CÓDIGOS COMPLETOS aquí.

import sys, os, textwrap, json, math, re from getpass import getpass print(“🔧 Entorno de refuerzo (evita la corrupción numpy común de Colab/py3.12)…”) !pip -q uninstall -y numpy || verdadero !pip -q install –no-cache-dir –force-reinstall “numpy==1.26.4” !pip -q install -U deepeval openai scikit-learn pandas tqdm print(“✅ Paquetes instalados.”) importar numpy como np importar pandas como pd desde tqdm.auto importar tqdm desde sklearn.feature_extraction.text importar TfidfVectorizer de sklearn.metrics.pairwise importar cosine_similarity de deepeval importar evaluar de deepeval.test_case importar LLMTestCase, LLMTestCaseParams de deepeval.metrics importar (AnswerRelevancyMetric, FaithfulnessMetric, ContextualRelevancyMetric, ContextualPrecisionMetric, ContextualRecallMetric, GEval,) print(“✅ Importaciones cargadas exitosamente.”) OPENAI_API_KEY = getpass(“🔑 Ingrese OPENAI_API_KEY (déjelo vacío para ejecutar sin OpenAI): “).strip() openai_enabled = bool(OPENAI_API_KEY) si openai_enabled: os.environ[“OPENAI_API_KEY”] = OPENAI_API_KEY print(f”🔌 OpenAI habilitado: {openai_enabled}”)

Inicializamos nuestro entorno estabilizando las dependencias centrales e instalando el marco de evaluación profunda para garantizar un proceso de pruebas sólido. A continuación, importamos métricas especializadas como fidelidad y recuerdo contextual mientras configuramos nuestras credenciales API para permitir una evaluación automatizada y de alta fidelidad de nuestras respuestas de LLM. Consulta los CÓDIGOS COMPLETOS aquí.

DOCUMENTOS = [
{
“id”: “doc_01”,
“title”: “DeepEval Overview”,
“text”: (
“DeepEval is an open-source LLM evaluation framework for unit testing LLM apps. ”
“It supports LLM-as-a-judge metrics, custom metrics like G-Eval, and RAG metrics ”
“such as contextual precision and faithfulness.”
),
},
{
“id”: “doc_02”,
“title”: “RAG Evaluation: Why Faithfulness Matters”,
“text”: (
“Faithfulness checks whether the answer is supported by retrieved context. ”
“In RAG, hallucinations occur when the model states claims not grounded in context.”
),
},
{
“id”: “doc_03”,
“title”: “Contextual Precision”,
“text”: (
“Contextual precision evaluates how well retrieved chunks are ranked by relevance ”
“to a query. High precision means relevant chunks appear earlier in the ranked list.”
),
},
{
“id”: “doc_04”,
“title”: “Contextual Recall”,
“text”: (
“Contextual recall measures whether the retriever returns enough relevant context ”
“to answer the query. Low recall means key information was missed in retrieval.”
),
},
{
“id”: “doc_05”,
“title”: “Answer Relevancy”,
“text”: (
“Answer relevancy measures whether the generated answer addresses the user’s query. ”
“Even grounded answers can be irrelevant if they don’t respond to the question.”
),
},
{
“id”: “doc_06”,
“title”: “G-Eval (GEval) Custom Rubrics”,
“text”: (
“G-Eval lets you define evaluation criteria in natural language. ”
“It uses an LLM judge to score outputs against your rubric (e.g., correctness, tone, policy).”
),
},
{
“id”: “doc_07”,
“title”: “What a DeepEval Test Case Contains”,
“text”: (
“A test case typically includes input (query), actual_output (model answer), ”
“expected_output (gold answer), and retrieval_context (ranked retrieved passages) for RAG.”
),
},
{
“id”: “doc_08”,
“title”: “Common Pitfall: Missing expected_output”,
“text”: (
“Some RAG metrics require expected_output in addition to input and retrieval_context. ”
“If expected_output is None, evaluation fails for metrics like contextual precision/recall.”
),
},
]

EVAL_QUERIES = [
{
“query”: “What is DeepEval used for?”,
“expected”: “DeepEval is used to evaluate and unit test LLM applications using metrics like LLM-as-a-judge, G-Eval, and RAG metrics.”,
},
{
“query”: “What does faithfulness measure in a RAG system?”,
“expected”: “Faithfulness measures whether the generated answer is supported by the retrieved context and avoids hallucinations not grounded in that context.”,
},
{
“query”: “What does contextual precision mean?”,
“expected”: “Contextual precision evaluates whether relevant retrieved chunks are ranked higher than irrelevant ones for a given query.”,
},
{
“query”: “What does contextual recall mean in retrieval?”,
“expected”: “Contextual recall measures whether the retriever returns enough relevant context to answer the query, capturing key missing information issues.”,
},
{
“query”: “Why might an answer be relevant but still low quality in RAG?”,
“expected”: “An answer can address the question (relevant) but still be low quality if it is not grounded in retrieved context or misses important details.”,
},
]

Definimos una base de conocimiento estructurada que consta de fragmentos de documentación que sirven como nuestro contexto de verdad para el sistema RAG. También establecemos un conjunto de consultas de evaluación y los resultados esperados correspondientes para crear un “conjunto de datos de oro”, que nos permite evaluar con qué precisión nuestro modelo recupera información y genera respuestas fundamentadas. Consulta los CÓDIGOS COMPLETOS aquí.

clase TfidfRetriever: def __init__(self, docs): self.docs = docs self.texts = [f”{d[‘title’]}\Dakota del Norte[‘text’]}” para d en documentos]self.vectorizer = TfidfVectorizer(stop_words=”english”, ngram_range=(1, 2)) self.matrix = self.vectorizer.fit_transform(self.texts) def retrieve(self, query, k=4): qv = self.vectorizer.transform([query]) sims = coseno_similaridad(qv, self.matrix).flatten() top_idx = np.argsort(-sims)[:k]
resultados = []
para i en top_idx: resultados.append( { “id”: self.docs[i][“id”]”puntuación”: float(sims[i]), “texto”: self.textos[i]} ) devuelve el recuperador de resultados = TfidfRetriever(DOCS)

Implementamos una clase TF-IDF Retriever personalizada que transforma nuestra documentación en un espacio vectorial con capacidad de búsqueda utilizando la vectorización TF-IDF compatible con bigramas. Esto nos permite realizar búsquedas de similitud de cosenos en la base de conocimientos, lo que garantiza que podamos recuperar mediante programación los k fragmentos de texto más relevantes para cualquier consulta determinada. Consulta los CÓDIGOS COMPLETOS aquí.

def extractive_baseline_answer(query, retrieved_contexts): “”” Alternativa sin conexión: creamos una respuesta corta extrayendo las oraciones más relevantes. Esto mantiene el cuaderno ejecutable incluso sin OpenAI. “”” join = “\n”.join(retried_contexts) sents = re.split(r”(?<=[.!?])\s+", unido) palabras clave = [w.lower() for w in re.findall(r"[a-zA-Z]{4,}", consulta)]puntuado = [] para s en envíos: s_l = s.lower() puntuación = suma(1 para k en palabras clave si k en s_l) si len(s.strip()) > 20: scoring.append((score, s.strip())) scoring.sort(key=lambda x: (-x[0]-len(x[1]))) mejor = [s for sc, s in scored[:3] si sc > 0]si no es mejor: mejor = [s.strip() for s in sents[:2] if len(s.strip()) > 20]ans = ” “.join(best).strip() if not ans: ans = “No pude encontrar suficiente contexto para responder con confianza”. return ans def openai_answer(query, retrieved_contexts, model=”gpt-4.1-mini”): “”” Solicitud RAG simple para demostración. Las métricas de DeepEval aún se pueden evaluar incluso si su solicitud de generación difiere; la clave es que almacenamos retrieval_context por separado. “”” from openai import OpenAI client = OpenAI() context_block = “\n\n”.join([f”[CTX {i+1}]\n{c}” for i, c in enumerate(retried_contexts)]) Prompt = f”””Eres un asistente técnico conciso. Utilice SÓLO el contexto proporcionado para responder la consulta. Si la respuesta no está en contexto, diga que no lo sabe. Consulta: {consulta} Contexto: {context_block} Respuesta:””” resp = client.chat.completions.create( modelo=modelo, mensajes=[{“role”: “user”, “content”: prompt}]temperatura = 0,2, ) devolver opciones respectivas[0].message.content.strip() def rag_answer(consulta, contextos_recuperados): si openai_enabled: intente: devolver openai_answer(consulta, contextos_recuperados) excepto Excepción como e: print(f”⚠️ Falló la generación de OpenAI, volviendo a la línea de base extractiva. Error: {e}”) devuelve extractive_baseline_answer(consulta, contextos_recuperados) más: devuelve extractive_baseline_answer(consulta, contextos_recuperados)

Implementamos un mecanismo de respuesta híbrido que prioriza la generación de alta fidelidad a través de OpenAI mientras mantenemos una línea de base extractiva basada en palabras clave como respaldo confiable. Al aislar el contexto de recuperación de la generación final, garantizamos que nuestros casos de prueba de DeepEval sigan siendo consistentes independientemente de si la respuesta es sintetizada por un LLM o extraída mediante programación. Consulta los CÓDIGOS COMPLETOS aquí.

print(“\n🚀 Ejecutando RAG para crear casos de prueba…”) test_cases = []
K = 4 para el artículo en tqdm(EVAL_QUERIES): q = artículo[“query”]
esperado = artículo[“expected”]

recuperado = recuperador.retrieve(q, k=K) contexto_recuperación = [r[“text”] para r en recuperado]actual = rag_answer(q, retrieval_context) tc = LLMTestCase( input=q, actual_output=actual, expected_output=expected, retrieval_context=retrieval_context, ) test_cases.append(tc) print(f”✅ Construido {len(test_cases)} objetos LLMTestCase.”) print(“\n✅ Métricas configurado.”) métricas = [
AnswerRelevancyMetric(threshold=0.5, model=”gpt-4.1″, include_reason=True, async_mode=True),
FaithfulnessMetric(threshold=0.5, model=”gpt-4.1″, include_reason=True, async_mode=True),
ContextualRelevancyMetric(threshold=0.5, model=”gpt-4.1″, include_reason=True, async_mode=True),
ContextualPrecisionMetric(threshold=0.5, model=”gpt-4.1″, include_reason=True, async_mode=True),
ContextualRecallMetric(threshold=0.5, model=”gpt-4.1″, include_reason=True, async_mode=True),

GEval(
name=”RAG Correctness Rubric (GEval)”,
criteria=(
“Score the answer for correctness and usefulness. ”
“The answer must directly address the query, must not invent facts not supported by context, ”
“and should be concise but complete.”
),
evaluation_params=[
LLMTestCaseParams.INPUT,
LLMTestCaseParams.ACTUAL_OUTPUT,
LLMTestCaseParams.EXPECTED_OUTPUT,
LLMTestCaseParams.RETRIEVAL_CONTEXT,
]model=”gpt-4.1″, umbral=0.5, async_mode=True, ), ]si no es openai_enabled: print(“\n⚠️ NO proporcionó una clave API de OpenAI.”) print(“Las métricas de LLM como juez de DeepEval (AnswerRelevancy/Faithfulness/Contextual* y GEval) requieren un juez de LLM.”) print(“Vuelva a ejecutar esta celda y proporcione OPENAI_API_KEY para ejecutar las métricas de DeepEval.”) print(“\n✅ Sin embargo, la construcción de su canalización RAG + caso de prueba fue exitosa de un extremo a otro.”) filas = []
para i, tc en enumerar (test_cases): filas.append({ “id”: i, “query”: tc.input, “actual_output”: tc.actual_output[:220] + (“…” si len(tc.actual_output) > 220 else “”), “expected_output”: tc.expected_output[:220] + (“…” si len(tc.expected_output) > 220 else “”), “contextos”: len(tc.retrieval_context o []), }) display(pd.DataFrame(rows)) rise SystemExit(“Detenido antes de la evaluación (sin clave OpenAI)”).

Ejecutamos la canalización RAG para generar objetos LLMTestCase emparejando nuestro contexto recuperado con respuestas generadas por modelos y expectativas de verdad sobre el terreno. Luego configuramos un conjunto completo de métricas de DeepEval, incluidos G-Eval e indicadores RAG especializados, para evaluar el rendimiento del sistema utilizando un enfoque de LLM como juez. Consulta los CÓDIGOS COMPLETOS aquí.

print(“\n🧪 Ejecutando DeepEval evaluar(…) …”) resultados = evaluar(test_cases=test_cases, metrics=metrics) resumen_rows = []
para idx, tc en enumerate(test_cases): fila = { “case_id”: idx, “query”: tc.input, “actual_output”: tc.actual_output[:200] + (“…” si len(tc.actual_output) > 200 else “”), } para m en métricas: fila[m.__class__.__name__ if hasattr(m, “__class__”) else str(m)] = Ninguno resumen_rows.append(fila) def try_extract_case_metrics(results_obj): extraído = []
candidatos = []
para atributo en [“test_results”, “results”, “evaluations”]: if hasattr(results_obj, attr): candidatos = getattr(results_obj, attr) break si no son candidatos y isinstance(results_obj, lista): candidatos = results_obj para case_i, case_result en enumerate(candidatos o []): item = {“case_id”: case_i} metrics_list = Ninguno para el atributo [“metrics_data”, “metrics”, “metric_results”]: if hasattr(case_result, attr): metrics_list = getattr(case_result, attr) break if isinstance(metrics_list, dict): for k, v in metrics_list.items(): elemento[f”{k}_score”] = getattr(v, “score”, Ninguno) si v no es Ninguno más Ninguno elemento[f”{k}_reason”] = getattr(v, “razón”, Ninguno) si v no es Ninguno más Ninguno más: para mr en metrics_list o []: nombre = getattr(señor, “nombre”, Ninguno) o getattr(getattr(señor, “métrico”, Ninguno), “nombre”, Ninguno) si no es nombre: nombre = señor.__clase__.__nombre__ elemento[f”{name}_score”] = getattr(señor, “puntuación”, Ninguno) elemento[f”{name}_reason”] = getattr(señor, “razón”, Ninguno) extraído.append(elemento) devuelve case_metrics extraído = try_extract_case_metrics(resultados) df_base = pd.DataFrame([{
“case_id”: i,
“query”: tc.input,
“actual_output”: tc.actual_output,
“expected_output”: tc.expected_output,
} for i, tc in enumerate(test_cases)]) df_metrics = pd.DataFrame(case_metrics) si case_metrics en caso contrario pd.DataFrame([]) df = df_base.merge(df_metrics, on=”case_id”, how=”left”) score_cols = [c for c in df.columns if c.endswith(“_score”)]
compacto = df[[“case_id”, “query”] + score_cols].copy() print(“\n📊 Tabla de puntuación compacta:”) display(compact) print(“\n🧾 Detalles completos (incluye motivos):”) display(df) print(“\n✅ Listo. Consejo: si la precisión/recordación contextual es baja, mejore la clasificación/cobertura del retriever; si la fidelidad es baja, ajuste la generación para usar solo el contexto.”)

Finalizamos el flujo de trabajo ejecutando la función de evaluación, que activa el proceso de LLM como juez para calificar cada caso de prueba según nuestras métricas definidas. Luego agregamos estos puntajes y su razonamiento cualitativo correspondiente en un DataFrame centralizado, brindando una vista granular de dónde sobresale el proceso RAG o dónde requiere una mayor optimización en la recuperación y generación.

Por último, concluimos ejecutando nuestro conjunto de evaluación integral, en el que DeepEval transforma resultados lingüísticos complejos en datos procesables utilizando métricas como Fidelidad, Precisión Contextual y la rúbrica G-Eval. Este enfoque sistemático nos permite diagnosticar “fallos silenciosos” en la recuperación y alucinaciones en la generación con precisión quirúrgica, proporcionando el razonamiento necesario para justificar los cambios arquitectónicos. Con estos resultados, pasamos de la creación de prototipos experimentales a un sistema RAG listo para producción respaldado por una red de seguridad verificable basada en métricas.

Consulta los CÓDIGOS COMPLETOS aquí. Además, no dude en seguirnos en Twitter y no olvide unirse a nuestro SubReddit de más de 100.000 ML y suscribirse a nuestro boletín. ¡Esperar! estas en telegrama? Ahora también puedes unirte a nosotros en Telegram.

You missed

NVIDIA lanza Nemotron-Labs-3-Puzzle-75B-A9B: un LLM MoE híbrido comprimido que ofrece un rendimiento de servidor 2,03 veces superior al rendimiento de usuario equivalente[0]Los modelos MoE híbridos grandes como Nemotron-3-Super son precisos pero costosos de mantener. Sus parámetros activos, caché KV y estado de Mamba limitan la cantidad de usuarios que puede contener un nodo a una determinada tasa de token por usuario. El equipo de IA de NVIDIA lanzó Nemotron-Labs-3-Puzzle-75B-A9B, una variante comprimida de Nemotron-3-Super. El modelo principal tiene 120,7 mil millones de parámetros totales y 12,8 mil millones activos. El modelo comprimido tiene 75,3 mil millones de parámetros totales y 9,3 mil millones de parámetros activos. El objetivo de implementación se solucionó antes de que comenzara la búsqueda de arquitectura. El objetivo uno era duplicar el rendimiento del servidor a 100 tokens por segundo por usuario. El objetivo dos eran 8 solicitudes simultáneas de 1 millón de tokens en un solo H100. Tres puntos de control en Hugging Face: BF16, FP8 y NVFP4. TL;DR Los 120,7B/12,8B activos se comprimen a 75,3B/9,3B activos, conservando el diseño híbrido de 88 bloques. El rendimiento total de 8xB200 aumenta de 1,60x a 2,14x con respecto a Super con NVFP4 coincidente y rendimiento de usuario coincidente. La simultaneidad de un solo token H100 de 1 millón va de 1 a 8, impulsada por una caída de peso de 70 GB a 44,5 GB. El rompecabezas iterativo supera al rompecabezas de un solo paso en 0,57 puntos promedio en el mismo objetivo de compresión. Arena-Hard-V2 (-4,2) y SWE-Bench (-2,6) son los costes reales; RULER y AA-LCR apenas se mueven. Nemotron-Labs-3-Puzzle-75B-A9B Nemotron-3-Super es un modelo híbrido Mamba-Transformer MoE. Puzzle-75B-A9B conserva exactamente el diseño del bloque principal. Tiene 88 bloques: 40 Mamba, 40 MoE y 8 bloques de atención. Lo que cambió es la capacidad dentro de esos bloques: CantidadSuperPuzzle-75B-A9BRatioParámetros totales120.7B75.3B62.4%Parámetros activos12.8B9.3B73.1%Tamaño de estado de Mamba SSM1289675%Tamaño intermedio experto enrutado MoE26881280-2688Media 59.9%Expertos enrutados activados por token224-18Media 50%Capacidad experta enrutada activa (relativo)100%8,7%-62,3%Media 30,9% El número de expertos enrutados, el tamaño de expertos compartido y el tamaño latente del MoE no cambian. Las capas de atención quedaron intactas. La razón declarada por la investigación propuesta es que Nemotron-3-Super ya es muy eficiente en cuanto a caché KV. Las capas de Mamba se podaron de manera uniforme, porque los marcos de inferencia no admiten un tamaño de estado SSM diferente por capa. https://arxiv.org/pdf/2607.04371 El resultado no es un profesor uniformemente reducido. La figura anterior muestra la asignación en profundidad. Puzzle conservó la capacidad en capas intermedias y tardías seleccionadas, y cortó con fuerza en otras partes. Punto de referencia y rendimiento La siguiente tabla informa el rendimiento total óptimo de Pareto en un único nodo 8xB200, con decodificación en un solo paso. Escenario (entrada/salida)Piso UTSuper (tok/s)Puzzle-75B-A9B (tok/s)Boost50K / 2K>= 1005,1288,2101.60x50K / 2K>= 1253,7846,4121.69x50K / 2K>= 1502,5324,5231.79x8K / 64K>= 10020,93942,6012.03x8K / 64K>= 12513,07427,9182.14x8K / 64K>= 1508,52218,0472.12x Ambos modelos se entregaron con pesos NVFP4 coincidentes, caché FP8 KV y estado Mamba FP16. Por lo tanto, la brecha refleja compresión, no un cambio en el formato numérico. El régimen 50K/2K con precarga pesada es el que menos gana. El régimen 8K/64K con gran decodificación es el que más gana. En un solo nodo 8xH100 en UT = 100, las ganancias son menores. Son 1,91x en 50K/2K y 1,82x en 8K/64K. Ambos modelos utilizan pesos FP8, caché FP8 KV y estado FP32 Mamba. En un único H100 en un contexto de 1M, la restricción de enlace pasa de la computación a la memoria. Los pesos NVFP4 de Super ocupan alrededor de 70 GB del presupuesto de 80 GB de HBM. Cada solicitud de token de 1 millón agrega aproximadamente 4 GB de caché KV. Por tanto, la concurrencia efectiva es 1. El peso NVFP4 del Puzzle-75B-A9B ocupa alrededor de 44,5 GB. El diseño de atención no cambia, por lo que el costo de KV por solicitud no cambia. La simultaneidad en 1M aumenta a 8. El rendimiento de decodificación agregado en esa simultaneidad es aproximadamente 4 veces el rendimiento de solicitud única de Super. El llenado previo de una solicitud de 990 000 tokens es aproximadamente 1,2 veces más rápido. Cómo funciona el rompecabezas iterativo Puzzle es un marco de búsqueda de arquitectura neuronal descompuesta, implementado aquí como Puzzletron. Define un espacio de búsqueda discreto de implementaciones de capas alternativas. Cada alternativa obtiene una puntuación de calidad. Luego, un programa de enteros mixtos selecciona una alternativa por capa bajo una restricción de implementación. Tres técnicas de poda forman el espacio de búsqueda: Poda de canales intermedios: los canales dentro de cada experto enrutado se clasifican según su contribución a la salida del experto. Todos los expertos dentro de una capa MoE se reducen a un tamaño uniforme para lograr compatibilidad con el kernel. Reducción de top-k: la cantidad de expertos a los que se enruta un token varía según la capa, hasta el k = 22 del padre. Poda de Mamba SSM: el tamaño del estado de SSM cae de 128 a 96 canales. Se mide el resultado del SSM. Bajar 128 canales a 96 acelera el kernel SSM de 1,2x a 1,3x durante la decodificación. Esto se mantiene en tamaños de lote entre 8 y 512. Los canales se clasificaron según su contribución estimada a la producción de la capa Mamba. La estimación promedió más de 67 millones de tokens de datos de validación. El Apéndice A muestra que esto supera la selección aleatoria de canales bajo una poda agresiva. La formulación original asume que los impactos en la calidad del reemplazo son aproximadamente aditivos. Cada bloque candidato se puntúa dentro del padre no modificado. Eso ignora las interacciones de orden superior entre reemplazos. Iterative Puzzle alterna la compresión limitada con una breve recuperación de destilación de conocimientos. Construye una secuencia M0, M1,… MR en lugar de saltar al objetivo. Las puntuaciones se vuelven a calcular con respecto al modelo comprimido actual, no al modelo original. Se utilizaron tres etapas: El Ministerio de Educación pondera el 75% de la capacidad docente, el estado de Mamba SSM el 75%. Curado por 24 mil millones de fichas. El Ministerio de Educación pondera el 60% de la capacidad docente. Curado por 43,2 mil millones de tokens. Se activó el presupuesto de expertos encaminado al 50%, asignado de forma heterogénea. Curado por 52,8 mil millones de tokens. https://arxiv.org/pdf/2607.04371 La tabla anterior compara esto con una línea base de Puzzle de un solo paso en el mismo objetivo. El procedimiento de tres pasos tiene un promedio de 69,05 en diez puntos de referencia, frente a 68,48. Las ganancias aparecen en MMLU-Pro, GPQA, HLE, AA-LCR, LiveCodeBench, SciCode y RULER-256K. IFBench-Instruction cayó 0,2 puntos y IFBench-Prompt cayó 0,5. Recuperación: destilación, RL y verbosidad La destilación de conocimientos se ejecutó con un 30 % de datos de preentrenamiento y un 70 % de datos SFT de Nemotron-3-Nano. Durante la fase de rompecabezas, KD utilizó una secuencia de 32K de longitud. Luego, Recovery entrenó a 128K y escaló a 512K. El presupuesto era de hasta 100 mil millones de tokens, con un lote global de 16 millones de tokens, en Megatron-LM. La capacitación posterior de RL adoptó la Etapa 2 del proceso Nemotron-3-Super RL, centrada en la ingeniería de software. La fase 2.1 realizó una comparación del uso de herramientas en un solo paso. La fase 2.2 pasó a la zona de pruebas RL de extremo a extremo, donde los agentes corren hasta 200 turnos. Ambas fases utilizaron una penalización de KL de 0. El equipo barrió las tasas de aprendizaje y luego promedió los pesos resultantes. https://arxiv.org/pdf/2607.04371 La Figura 4 anterior muestra lo que aportó cada etapa. KD de contexto corto recupera la mayoría de las categorías a más del 97% de Nemotron-3-Super. Luego, KD de contexto largo eleva específicamente los puntos de referencia de entrada larga y de generación larga. El equipo de investigación afirma que el impacto de RL en estos experimentos fue pequeño. La verbosidad es el detalle silencioso. Después de la última iteración de Puzzle, el modelo generó el 132% del recuento de tokens de Super. Eso cayó al 99% después del proceso de recuperación total. Implementación: cuantificación y predicción de tokens múltiples Se produjeron dos recetas de cuantificación posteriores al entrenamiento: FP8 W8A8 apunta a Hopper y NVFP4 W4A4 apunta a Blackwell. Componente Línea base BF16 Punto de control FP8 Punto de control NVFP4 GEMM MoE dispersos y compartidos BF16FP8NVFP4 Mamba GEMM BF16FP8FP8 Mamba Caché SSM FP32FP32FP16 + Caché SRKV FP8FP8FP8 Enrutador FP32FP32FP32 Atención QKV/salida, proyecciones latentes MoE, LM cabezaBF16BF16BF16 Ambas recetas se calibraron en 256 muestras SFT posteriores al entrenamiento. NVFP4 utilizó la calibración máxima, no la búsqueda de sensibilidad AutoQuantize utilizada para Super. El punto de control resultante se cuantifica de forma ligeramente más agresiva y se realiza de manera similar. NVFP4 no es compatible de forma nativa con Hopper. Todavía se utiliza para el objetivo H100 de contexto 1M, porque la capacidad de HBM se vincula allí. Puzzle-75B-A9B hereda un cabezal MTP compartido de Super. Los parámetros se comparten entre los pasos de MTP, por lo que un cabezal se aplica de forma recursiva en la inferencia. La transferencia directa de la cabeza entrenada de Super dio longitudes de aceptación similares. Luego, el equipo de investigación identifica una discrepancia entre el entrenamiento y la inferencia. El entrenamiento MTP forzado por el maestro alimenta la secuencia completa de estados ocultos desplazados. En cambio, la redacción autorregresiva alimenta una combinación de modelos de destino y estados ocultos generados por MTP. Las tasas de aceptación caen en posiciones de draft más profundas. Esto se soluciona mediante una formación continua de la cabeza transferida. En SPEED-Bench con una longitud de calado 7, la longitud media de aceptación aumentó de 3,45 a 4,34. Eso es aproximadamente entre el 25% y el 30%, concentrado en puestos posteriores del draft. A diferencia de Super, el punto de control NVFP4 apenas se degrada: 4,31 frente a 4,34. Dónde ayuda la compresión y dónde duele Benchmark (BF16)SuperPuzzle-75B-A9BDeltaMMLU-Pro83.882.4-1.4AIME25 (sin herramientas)92.289.7-2.5GPQA (sin herramientas)80.578.6-1.9LiveCodeBench82.181.1-1.0SciCode (subtarea)42.340.6-1.7SWE-Bench (OpenHands)59.556.9-2.6Arena-Hard-V272.868.6-4.2AA-LCR56.856.9+0.1REGLA 1M93.992.2-1.7MMLU-ProX79.577.5-2.0 El propio resumen del artículo de investigación es que el seguimiento de instrucciones y las evaluaciones agentes son las que más pierden. Arena-Hard-V2 es el peor de los casos, con -4,2 puntos. RULER se mantiene dentro de aproximadamente 1 a 2 puntos en 256K, 512K y 1M. Tres resultados de BF16 no retroceden. AA-LCR gana 0,1, Scale AI Multi-Challenge empata en 56,6 y TauBench Telecom gana 0,4. NVFP4 cuesta poco además de la compresión. En RULER 1M, el punto de control NVFP4 obtiene una puntuación de 93,2, por encima del 92,2 de BF16. HLE es el costo de NVFP4 más claro, cayendo de 16,5 a 15,7. Los resultados del 8PM se encuentran en el Apéndice E y siguen de cerca al BF16. SWE-Bench no está incluido en el punto de control del 8PM. Casos de uso RAG de contexto ultralargo en una GPU: un servicio de análisis de documentos en un contexto de 1 millón pasa de 1 solicitud simultánea a 8. El rendimiento de decodificación agregado en esa concurrencia es aproximadamente 4 veces mayor. Asistentes de codificación interactivos: en UT >= 100 tok/s en el régimen 8K/64K, un nodo sirve 2,03 veces los tokens. Ajustado por detalle, es decir, 2,16 veces las solicitudes completadas por minuto. Canalizaciones de documentos con gran cantidad de precarga: el régimen de 50.000/2.000 gana solo 1,60 veces. La compresión ayuda menos cuando el procesamiento rápido domina la computación. Bucles SWE agentes: verifique la brecha SWE-Bench de 2,6 puntos con su combinación de tareas. La recuperación de RL apuntó a esta capacidad y solo la restauró parcialmente. Explorador de implementación ‘+esc(r