CoolFace
Modelpublic

axiom-of-choice/qwen3-4b-es-reasoning-qlora

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
1likes
Model Card

Qwen3-4B Spanish reasoning (QLoRA)

Also published for `transformers`/`peft`: `axiom-of-choice/qwen3-4b-es-reasoning-peft` -- same adapter weights, verified against this one (phase-2 parity numbers on the linked repo's card). Use this repo with mlx-lm; use the linked one for transformers, vLLM, or anything else.

A rank-8 QLoRA adapter that makes `mlx-community/Qwen3-4B-4bit` do its chain-of-thought in Spanish, trained on `axiom-of-choice/bespoke-stratos-es` — 8,786 reasoning traces generated natively in Spanish by DeepSeek V4 Flash.

It does not trade accuracy for Spanish. It improves both.

accuracyreasoned acc.Spanishnon-Spanish rows
base model77.4%85.5%0.0000249 of 249
this adapter84.8%89.8%1.00000

+7.4 accuracy points and perfect Spanish, on 283 held-out GSM8K problems translated to Spanish. Paired McNemar exact test on the same items: 34 rows only the adapter gets right against 13 only the base model gets right, p = 0.0031.

The base model reasons in English on all 249 of its 249 reasoned answers — that is what this adapter is for. The adapter's own Spanish confidence is 1.0000, with a minimum of 1.0000 across all 265 of them: not one answer drifted.

Provenance: this is a distillation, and the chain has two steps

Worth stating precisely, because the two steps have different teachers and it is easy to attribute the Spanish to the wrong one.

  1. 1.`bespokelabs/Bespoke-Stratos-17k` (apache-2.0) is a distillation of DeepSeek-R1 into English reasoning traces. That dataset supplied only the problems here.
  2. 2.Those problems were re-solved from scratch by DeepSeek V4 Flash, prompted to reason in Spanish. The English traces were not translated — native Spanish chain-of-thought beats translated chain-of-thought, and translation would have carried English reasoning structure into the target language.
  3. 3.This adapter distills step 2 into Qwen3-4B.

So the teacher for everything this adapter learned is DeepSeek V4 Flash, not R1. R1 appears only upstream, as the teacher of the dataset the problems came from.

Licensing: the source dataset is apache-2.0, and DeepSeek's API terms of service explicitly permit applying outputs to "training other models (such as model distillation)" (section 4.2(3), verified before generating). Their section 8.1 requires disclosing AI-generated content — hence this section — and section 5.4 asks that naming not imply partnership. This model is not affiliated with or endorsed by DeepSeek.

One caveat found while generating: DeepSeek's hidden reasoning channel stayed English-dominant no matter how forcefully the prompt asked otherwise, a documented R1-lineage language-mixing behaviour that prompting does not fix. The fix was to not use that channel at all and ask for the reasoning as visible output instead. That is why the traces are genuinely Spanish rather than Spanish-wrapped English.

Quantization, and why this is QLoRA

The base model is 4-bit quantized (mlx-community/Qwen3-4B-4bit at group size 64), and the adapter was trained directly on top of those quantized weights — that is what makes this QLoRA rather than plain LoRA. MLX supports it natively: linear_to_lora_layers accepts nn.QuantizedLinear and LoRALinear.from_base corrects the input dimension by bit width, so nothing had to be implemented.

Two practical consequences:

  • —The adapter tensors themselves are float32, not quantized. Only the frozen base is 4-bit. The adapter is 7.34M parameters — 0.182% of the base model's 4.02B, counting the embedding matrix. The "4B" in the name excludes it; against non-embedding parameters alone the share is 0.202%, and the smaller figure is the honest one to quote.
  • —Every number on this card was measured against the 4-bit base. Loading these weights onto a bf16 or 8-bit Qwen3-4B will run, since LoRA shapes do not depend on the base precision, but it is not the configuration that was evaluated and the accuracies above do not transfer unverified.

QLoRA was not a compromise here. At the real training shape (batch 4 x sequence 2048, gradient checkpointing on) the 4-bit 4B peaked at 13.91 GB, less than the same recipe on a bf16 Qwen3-1.7B (15.24 GB) — a model 2.4x larger fits with more headroom, because quantized weights save more than the extra activations cost. What 4-bit costs is compute, not memory: ~129 tok/s against ~420 for the bf16 1.7B, since every matmul has to unpack the weights first.

Results

All 283 rows of a held-out Spanish GSM8K test split, identical sampling for every row: greedy (temperature 0), max_tokens 2048, repetition_penalty 1.1, no answer-format hint.

configaccuracyreasoned acc.Spanishnon-esloopedno reasoning
base model77.4%85.5%0.0000249340
scale 484.1%88.7%1.00000161
scale 6 (published)84.8%89.8%1.00000180
scale 8 (as trained)82.7%87.5%0.99621190

Paired McNemar exact, same items, discordant rows only:

comparisononly Aonly Bnetp
base vs published1334+210.0031
scale 4 vs published1719+20.8679
published vs as-trained2014-60.3915

A bootstrap confidence interval on any single accuracy here is about +/-5 points at this sample size, so overlapping intervals would prove nothing. Every config scored the same items, which is what makes the paired test able to separate them. Only the base-vs-published comparison clears significance; the scale ranking below it does not, and is decided on other grounds.

How much of this is measurement noise

The baseline was measured twice, same sampling config, two different generation schedulers (sequential chunks, then continuous batching): 77.4% and 76.7%. A 0.7-point spread on the identical model and identical settings, with 22 vs 20 rows flipping in each direction (p = 0.8776 — indistinguishable, as it should be).

Decoding is greedy, so this is not sampling randomness. It is batch composition: which sequences share a batch changes the padding, which changes floating-point reduction order, which occasionally flips a token. Treat +/-1 point as the harness's own noise floor, and note the adapter's +7.4 is well outside it while the 4-vs-6 gap of 0.7 is not.

Three outcomes, not two

A generation either closes a <think> block (reasoned), opens one and runs to the token ceiling without closing it (looped), or answers directly without reasoning (no reasoning). Collapsing the last two hides which problem you have, because they need opposite fixes.

no reasoning is 0 for the base model and for this adapter: Qwen3-4B opens a reasoning block on every row whether or not it is fine-tuned. So what the adapter changes is not whether the model reasons but whether it stops: looped rows fall from 34 to 18, and mean generation length from 1086 to 729 tokens.

That also locates the remaining headroom. reasoned accuracy is 89.8% while overall accuracy is 84.8%, and the entire difference is the 18 looping rows scored wrong. The ceiling is termination, not arithmetic.

Looped rows can score "correct" by accident

Worth knowing if you re-derive these numbers. A looped generation has no </think>, so a scorer that takes the last number in the output can pick up a figure from mid-reasoning. Checked every such row across all four evals: none came from a real \boxed{} answer. Since the base model loops most, that noise favours it. Forcing every looped row to wrong:

accuracystrict accuracy
base model77.4%75.3%
published84.8%84.1%

The adapter's advantage grows under strict scoring (40 vs 15 discordant, p = 0.0010), so the headline is the conservative reading.

Why the scale is lowered

adapter_config.json publishes `scale 6` while training used `scale 8`. This is deliberate.

In mlx-lm the LoRA update is applied as y + scale * z — the scale is not divided by the rank the way peft does it — so lowering it at inference interpolates continuously between the base model and the fine-tune. It costs one number in a JSON file, no retraining.

The sweep at n=283: 82.7% at the trained 8, 84.8% at 6, 84.1% at 4.0. Scale 4.0 and 6 are statistically tied (p = 0.8679), so accuracy alone does not pick between them. What does: at 6 the model reasons on every row, and at 4.0 one row stops reasoning altogether. Below some scale the adapter stops reasoning rather than reasoning worse, and 6 is above that floor.

To use the weights exactly as trained, set "scale": 8 in adapter_config.json. Nothing else changes.

Retraining at 6 would not reproduce this. Validation loss is minimized at whatever scale the run trained with, so a run at 6 would land at its own optimum and the same inference-time reduction would apply again from there. The gain comes from being between the base model and a converged fine-tune, which is not a place training can target.

Usage

python
from huggingface_hub import snapshot_download
from mlx_lm import load, generate

# mlx-lm's adapter_path must be a LOCAL directory -- it does not resolve a Hub
# repo id, so download first. Passing "axiom-of-choice/qwen3-4b-es-reasoning-qlora" directly
# raises FileNotFoundError.
adapter_path = snapshot_download("axiom-of-choice/qwen3-4b-es-reasoning-qlora")

model, tokenizer = load("mlx-community/Qwen3-4B-4bit", adapter_path=adapter_path)

messages = [
    {"role": "system", "content": "Eres un asistente experto que resuelve "
                                   "problemas pensando y explicando "
                                   "completamente en espanol."},
    {"role": "user", "content": "Si 3 manzanas cuestan 2 euros, "
                                 "cuanto cuestan 12 manzanas?"},
]
prompt = tokenizer.apply_chat_template(
    messages, add_generation_prompt=True, enable_thinking=True
)
print(generate(model, tokenizer, prompt, max_tokens=2048))

Verified against this repository — that snippet produces, for the question above:

<think>
Voy a resolver este problema paso a paso. Primero, entiendo que 3 manzanas
cuestan 2 euros. [...] Puedo dividir 12 entre 3 para ver cuántos grupos de 3
manzanas hay en 12. 12 ÷ 3 = 4. [...] Otra forma de verlo es calcular el costo
por manzana primero [...] Ambos métodos me dan el mismo resultado.
</think>

12 manzanas cuestan 8 euros.

enable_thinking=True is what asks for the <think> block. Without it the model answers directly and the adapter has nothing to act on.

The system prompt above is the one used in training and in every measurement on this card. A different one will work but was not evaluated.

Set `repetition_penalty=1.1`. Greedy decoding with no penalty cannot escape a repetition once it starts, and looping rows are already the largest bucket of lost accuracy.

Training

MethodQLoRA (LoRA on a 4-bit quantized base)
Rank / scale / dropout8 / 8 / 0.0
Layers adaptedlast 16 of 36
Trainable params7.34M (0.182% of the base)
Optimizeradamw, lr 5e-06 cosine to 5e-07, warmup 100
Batch / sequence4 x 2048 tokens, gradient checkpointing on
Gradient clipping1.0
Prompt maskingyes (loss on the assistant turn only)
Data8,786 train / 976 validation
Stopped atiteration 702, best validation loss 0.6205
Wall clock7.3 h on an M2 Pro (32 GB)
Non-finite batches skipped0

Training stopped early, by a watchdog that reads the validation curve and sends SIGTERM once it flattens, rather than at a fixed iteration count. The published weights are the best-validation checkpoint, not the last one.

0 batches were skipped for non-finite gradients. The 1.7B runs on the same recipe skipped up to 46 of ~1000, so gradient stability is markedly better on this base. The gradient clipping and NaN-skip guards were still active; they simply never had to fire.

Limitations

  • —Evaluated only on grade-school math word problems (GSM8K translated to Spanish). Spanish reasoning on other domains is untested.
  • —18 of 283 rows (6.4%) fail to terminate within 2048 tokens and are scored wrong. Raising the ceiling does not fix these; on the 1.7B it made truncation worse, because a looping generation just loops longer.
  • —The eval set is machine-translated. Ground-truth answers come from GSM8K's own #### N suffix so they are exact, but the Spanish problem statements were produced by an API call and were not human-reviewed.
  • —Measured against the 4-bit base only (see Quantization above).
  • —The training data is AI-generated (DeepSeek V4 Flash) and ~3.7% of its answers carry a genuine teacher error, measured by verifying the dataset's answers against the original problems.
  • —Numbers on this card come from scripts/eval_reasoning.py in the project repository and are reproducible from the committed artifacts under results/qwen4b/.

Related


Qwen3-4B razonamiento en español (QLoRA)

También publicado para `transformers`/`peft`: `axiom-of-choice/qwen3-4b-es-reasoning-peft` -- mismos pesos del adaptador, verificados contra este (números de paridad de fase 2 en la ficha del repo enlazado). Usa este repo con mlx-lm; usa el enlazado para transformers, vLLM, o cualquier otra cosa.

Un adaptador QLoRA de rango 8 que hace que `mlx-community/Qwen3-4B-4bit` produzca su cadena de razonamiento en español, entrenado con `axiom-of-choice/bespoke-stratos-es` — 8,786 trazas de razonamiento generadas nativamente en español por DeepSeek V4 Flash.

No cambia precisión por español. Mejora las dos cosas.

precisiónprec. razonadaespañolfilas no en español
modelo base77.4%85.5%0.0000249 de 249
este adaptador84.8%89.8%1.00000

+7.4 puntos de precisión y español perfecto, sobre 283 problemas de GSM8K traducidos al español y fuera del entrenamiento. Test exacto de McNemar emparejado sobre los mismos ítems: 34 filas que sólo acierta el adaptador contra 13 que sólo acierta el modelo base, p = 0.0031.

El modelo base razona en inglés en las 249 de sus 249 respuestas razonadas — para eso existe este adaptador. La confianza en español del adaptador es 1.0000, con un mínimo de 1.0000 entre todas sus 265 respuestas: ni una se desvió.

Procedencia: esto es una destilación, y la cadena tiene dos pasos

Conviene precisarlo, porque los dos pasos tienen profesores distintos y es fácil atribuir el español al que no fue.

  1. 1.`bespokelabs/Bespoke-Stratos-17k` (apache-2.0) es una destilación de DeepSeek-R1 en trazas de razonamiento en inglés. De ahí se tomaron sólo los problemas.
  2. 2.Esos problemas los resolvió de cero DeepSeek V4 Flash, pidiéndole razonar en español. Las trazas inglesas no se tradujeron: una cadena de razonamiento nativa en español es mejor que una traducida, y traducir habría arrastrado la estructura del razonamiento inglés al idioma destino.
  3. 3.Este adaptador destila el paso 2 en Qwen3-4B.

Así que el profesor de todo lo que aprendió este adaptador es DeepSeek V4 Flash, no R1. R1 aparece sólo aguas arriba, como profesor del dataset del que salieron los problemas.

Licencias: el dataset de origen es apache-2.0, y los términos de servicio de la API de DeepSeek permiten explícitamente aplicar las salidas a "entrenar otros modelos (como destilación de modelos)" (sección 4.2(3), verificado antes de generar). Su sección 8.1 exige declarar el contenido generado por IA — de ahí esta sección — y la 5.4 pide que el nombre no implique una asociación. Este modelo no está afiliado a DeepSeek ni respaldado por DeepSeek.

Un detalle encontrado al generar: el canal de razonamiento oculto de DeepSeek se mantuvo predominantemente en inglés por mucho que el prompt insistiera, un comportamiento de mezcla de idiomas documentado en el linaje R1 que el prompting no arregla. La solución fue no usar ese canal en absoluto y pedir el razonamiento como salida visible. Por eso las trazas son genuinamente en español y no inglés envuelto en español.

Cuantización, y por qué esto es QLoRA

El modelo base está cuantizado a 4 bits (mlx-community/Qwen3-4B-4bit, group size 64), y el adaptador se entrenó directamente encima de esos pesos cuantizados — eso es lo que hace que esto sea QLoRA y no LoRA normal. MLX lo soporta de forma nativa: linear_to_lora_layers acepta nn.QuantizedLinear y LoRALinear.from_base corrige la dimensión de entrada según el ancho de bits, así que no hubo que implementar nada.

Dos consecuencias prácticas:

  • —Los tensores del adaptador son float32, no cuantizados. Sólo el base congelado está en 4 bits. El adaptador tiene 7.34M parámetros, el 0.182% de los 4.02B del modelo base contando la matriz de embeddings. El "4B" del nombre la excluye; contra parámetros sin embeddings la proporción es 0.202%, y la cifra menor es la honesta.
  • —Todos los números de esta tarjeta se midieron contra el base de 4 bits. Cargar estos pesos sobre un Qwen3-4B en bf16 u 8 bits funciona, porque las formas de LoRA no dependen de la precisión del base, pero no es la configuración evaluada y las precisiones de arriba no se transfieren sin verificar.

QLoRA no fue una concesión aquí. Con la forma real de entrenamiento (batch 4 x secuencia 2048, gradient checkpointing activado) el 4B en 4 bits alcanzó un pico de 13.91 GB, menos que la misma receta sobre un Qwen3-1.7B en bf16 (15.24 GB): un modelo 2.4 veces más grande entra con más margen, porque los pesos cuantizados ahorran más de lo que cuestan las activaciones extra. Lo que cuestan los 4 bits es cómputo, no memoria: ~129 tok/s frente a ~420 del 1.7B en bf16, porque cada matmul tiene que desempaquetar los pesos primero.

Resultados

Las 283 filas de un split de GSM8K en español fuera del entrenamiento, muestreo idéntico en cada fila: greedy (temperatura 0), max_tokens 2048, repetition_penalty 1.1, sin pista de formato de respuesta.

configuraciónprecisiónprec. razonadaespañolno-esen buclesin razonar
modelo base77.4%85.5%0.0000249340
scale 484.1%88.7%1.00000161
scale 6 (publicado)84.8%89.8%1.00000180
scale 8 (como se entrenó)82.7%87.5%0.99621190

McNemar exacto emparejado, mismos ítems, sólo filas discordantes:

comparaciónsólo Asólo Bnetop
base vs publicado1334+210.0031
scale 4 vs publicado1719+20.8679
publicado vs como-entrenado2014-60.3915

Un intervalo de confianza bootstrap sobre cualquiera de estas precisiones ronda los +/-5 puntos con este tamaño de muestra, así que dos intervalos solapados no demostrarían nada. Todas las configuraciones puntuaron los mismos ítems, y eso es lo que permite al test emparejado separarlas. Sólo la comparación base-vs-publicado alcanza significancia; el orden entre escalas no, y se decide por otros motivos.

Tres resultados posibles, no dos

Una generación cierra un bloque <think> (razonó), abre uno y llega al techo de tokens sin cerrarlo (en bucle), o responde directamente sin razonar (sin razonar). Juntar los dos últimos esconde qué problema tienes, porque necesitan arreglos opuestos.

sin razonar es 0 tanto para el modelo base como para este adaptador: Qwen3-4B abre un bloque de razonamiento en todas las filas, esté ajustado o no. Así que lo que cambia el adaptador no es si razona sino si para: las filas en bucle bajan de 34 a 18, y la longitud media de generación de 1086 a 729 tokens.

Eso también localiza el margen que queda. La precisión razonada es 89.8% mientras la precisión total es 84.8%, y toda la diferencia son las 18 filas en bucle contadas como fallo. El techo es la terminación, no la aritmética.

Una fila en bucle puede acertar por accidente

Conviene saberlo si rederivas estos números. Una generación en bucle no tiene </think>, así que un corrector que tome el último número de la salida puede recoger una cifra de mitad del razonamiento. Revisadas todas esas filas en las cuatro evaluaciones: ninguna venía de una respuesta \boxed{} real. Como el modelo base es el que más entra en bucle, ese ruido le favorece. Forzando a fallo todas las filas en bucle:

precisiónprecisión estricta
modelo base77.4%75.3%
publicado84.8%84.1%

La ventaja del adaptador crece con el criterio estricto (40 contra 15 discordantes, p = 0.0010), así que el titular es la lectura conservadora.

Cuánto de esto es ruido de medición

El baseline se midió dos veces, con la misma configuración de muestreo y dos planificadores de generación distintos (por trozos secuenciales, y luego batching continuo): 77.4% y 76.7%. Una diferencia de 0.7 puntos sobre el modelo idéntico y con ajustes idénticos, con 22 contra 20 filas cambiando en cada dirección (p = 0.8776 — indistinguibles, como debe ser).

El decodificado es greedy, así que esto no es aleatoriedad de muestreo. Es la composición de los batches: qué secuencias comparten batch cambia el padding, lo que cambia el orden de reducción en punto flotante, lo que ocasionalmente cambia un token. Trata +/-1 punto como el suelo de ruido del propio harness, y nota que los +7.4 del adaptador quedan muy por encima mientras que la diferencia de 0.7 entre 4 y 6 no.

Por qué se baja la escala

adapter_config.json publica `scale 6` mientras que el entrenamiento usó `scale 8`. Es deliberado.

En mlx-lm la actualización LoRA se aplica como y + scale * z — la escala no se divide por el rango como hace peft — así que bajarla en inferencia interpola de forma continua entre el modelo base y el ajuste fino. Cuesta un número en un JSON, sin reentrenar.

El barrido con n=283: 82.7% con el 8 entrenado, 84.8% con 6, 84.1% con 4. Las escalas 4 y 6 están empatadas estadísticamente (p = 0.8679), así que la precisión sola no decide entre ellas. Lo que sí decide: con 6 el modelo razona en todas las filas, y con 4 una fila deja de razonar por completo. Por debajo de cierta escala el adaptador deja de razonar en lugar de razonar peor, y 6 está por encima de ese suelo.

Para usar los pesos exactamente como se entrenaron, pon "scale": 8 en adapter_config.json. No cambia nada más.

Reentrenar con 6 no reproduciría esto. La pérdida de validación se minimiza en la escala con la que el run entrenó, así que un run con 6 llegaría a su propio óptimo y volvería a aplicarse la misma reducción en inferencia desde ahí. La ganancia viene de estar entre el modelo base y un ajuste fino convergido, que no es un sitio al que el entrenamiento pueda apuntar.

Uso

python
from huggingface_hub import snapshot_download
from mlx_lm import load, generate

# adapter_path de mlx-lm necesita un directorio LOCAL: no resuelve un repo id
# del Hub, así que hay que descargarlo primero. Pasar "axiom-of-choice/qwen3-4b-es-reasoning-qlora"
# directamente lanza FileNotFoundError.
adapter_path = snapshot_download("axiom-of-choice/qwen3-4b-es-reasoning-qlora")

model, tokenizer = load("mlx-community/Qwen3-4B-4bit", adapter_path=adapter_path)

messages = [
    {"role": "system", "content": "Eres un asistente experto que resuelve "
                                   "problemas pensando y explicando "
                                   "completamente en espanol."},
    {"role": "user", "content": "Si 3 manzanas cuestan 2 euros, "
                                 "cuanto cuestan 12 manzanas?"},
]
prompt = tokenizer.apply_chat_template(
    messages, add_generation_prompt=True, enable_thinking=True
)
print(generate(model, tokenizer, prompt, max_tokens=2048))

enable_thinking=True es lo que pide el bloque <think>. Sin eso el modelo responde directamente y el adaptador no tiene sobre qué actuar.

El system prompt de arriba es el que se usó en el entrenamiento y en todas las mediciones de esta tarjeta. Otro funcionará, pero no se evaluó.

Pon `repetition_penalty=1.1`. El decodificado greedy sin penalización no puede salir de una repetición una vez que empieza, y las filas en bucle ya son el mayor grupo de precisión perdida.

Entrenamiento

MétodoQLoRA (LoRA sobre un base cuantizado a 4 bits)
Rango / escala / dropout8 / 8 / 0.0
Capas adaptadasúltimas 16 de 36
Parámetros entrenables7.34M (0.182% del base)
Optimizadoradamw, lr 5e-06 cosine hasta 5e-07, warmup 100
Batch / secuencia4 x 2048 tokens, gradient checkpointing activado
Recorte de gradiente1.0
Enmascarado del promptsí (pérdida sólo sobre el turno del asistente)
Datos8,786 entrenamiento / 976 validación
Parado eniteración 702, mejor pérdida de validación 0.6205
Tiempo real7.3 h en un M2 Pro (32 GB)
Batches no finitos saltados0

El entrenamiento paró antes de tiempo, por un watchdog que lee la curva de validación y envía SIGTERM cuando se aplana, en lugar de a un número fijo de iteraciones. Los pesos publicados son el checkpoint de mejor validación, no el último.

0 batches se saltaron por gradientes no finitos. Los runs del 1.7B con la misma receta saltaron hasta 46 de ~1000, así que la estabilidad de gradientes es notablemente mejor en este base. El recorte de gradiente y la guarda de NaN seguían activos; simplemente nunca tuvieron que actuar.

Limitaciones

  • —Evaluado sólo en problemas de matemáticas de primaria (GSM8K traducido al español). El razonamiento en español en otros dominios está sin probar.
  • —18 de 283 filas (6.4%) no terminan dentro de 2048 tokens y se cuentan como fallo. Subir el techo no las arregla; en el 1.7B lo empeoró, porque una generación en bucle simplemente da vueltas más tiempo.
  • —El set de evaluación está traducido por máquina. Las respuestas correctas vienen del sufijo #### N de GSM8K, así que son exactas, pero los enunciados en español los produjo una llamada a una API y no fueron revisados por humanos.
  • —Medido sólo contra el base de 4 bits (ver Cuantización arriba).
  • —Los datos de entrenamiento son generados por IA (DeepSeek V4 Flash) y ~3.7% de sus respuestas llevan un error real del profesor, medido verificando las respuestas del dataset contra los problemas originales.
  • —Los números de esta tarjeta salen de scripts/eval_reasoning.py en el repositorio del proyecto y son reproducibles desde los artefactos guardados en results/qwen4b/.

Relacionado