Repository navigation
Lupus v0.1R Alpha
Pre-release🐺 Lupus v0.1R Alpha
Исследовательский релиз — первый честный бенчмарк Lupus против Python на 5 LLM-моделях разного размера и точности квантования.
TL;DR
- Lupus — Lisp-подобный язык, спроектированный под маленькие LLM (1.5–14B)
- Гипотеза: «Lupus даёт ≥20% меньше ошибок, чем Python» ❌ не подтвердилась в zero-shot
- Но обнаружен сильный эффект масштабируемости: Lupus растёт круче, чем Python
- Фикс интерпретатора дал +10 п.п. на 2B бесплатно (35% → 45%)
- 1-битный квант 27B-модели набирает 73% на Lupus — уровень честной 9B
📊 Результаты бенчмарка (100 задач)
| Модель | Lupus | Python | Разрыв |
|---|---|---|---|
| Qwen3.5-2B | 45% | 75% | −30 |
| Qwen3.5-4B | 55% | 93% | −38 |
| Qwen3.8-4B-distill | 53% | 96% | −43 |
| Qwen3.5-9B | 74% | 96% | −22 |
| Bonsai-27B (Q1_0, 1-bit) | 73% | 99% | −26 |
Ключевое наблюдение: кривая Lupus идёт 45→55→74 (почти линейно), а Python насытился на 93-99%. Разрыв сужается с ростом модели — это главный сигнал в пользу гипотезы обучаемости.
Bonsai-27B: 1-битная квантованная 27B-модель (4.7 ГБ) показывает 73% на Lupus — паритет с Qwen3.5-9B (74%), при этом Python у неё почти идеален (99%). Преимущество в 3× параметров съедено экстремальной квантовацией: S-выражения оказались чувствительнее к шуму кванта, чем знакомый Python. Провалы Bonsai — те же классы ошибок (галлюцинации let/expt, иммутабельность, небаланс скобок), что подтверждает таксономию на шестой модели.
🔧 Что починили с v0.1e
- Полиморфный
print— теперь принимаетint,bool,strбез явногоint->str. Убрало ~15 ложных падений на арифметике. ifбезelse— снято жёсткое требование 3 аргументов. Модели перестали падать на(if cond (print x)).- Литералы
true/false— добавлены в лексер, больше не нужно определять их черезdefine. - Скрипт бенчмарка —
run_experiment.pyс поддержкой--resume,--ids,--cat,--report. - Шпаргалка LLM —
lupus_cheatsheet.txtна ~800 токенов, единая для всех прогонов.
🧪 Методология
- Интерпретатор: tree-walk на Python (~900 строк)
- Бенчмарк: 100 задач × 2 языка = 200 генераций на модель
- Промптинг: только системная шпаргалка, без few-shot
- Верификация: детерминированная сверка stdout с эталоном
- Температура: 0.1,
max_tokens: 700 - Thinking: отключён во всех прогонах (иначе Qwen3.5 сжигает все токены на reasoning)
📋 Таксономия провалов Lupus
| Класс | Пример | Причина |
|---|---|---|
| Галлюцинации stdlib | expt, append, let, string-reverse |
Модель тянет из Scheme/Common Lisp |
| Иммутабельность | «Переменная sum не изменяемо» | Забывает define-mutable перед set! |
| Небаланс скобок | «Неожиданный токен: RPAREN» | Классика S-выражений у малых моделей |
| Алгоритмические | обратный порядок, off-by-one | Ошибки логики, не синтаксиса |
🎯 Выводы и следующие шаги
- Zero-shot сравнение некорректно — Python в преобучении на терабайтах кода, Lupus — на нуле. Разрыв ~30 п.п. это эффект данных, а не языка.
- Lupus масштабируется — на 9B в «чистых» категориях (arithmetic, logic, strings) уже паритет с Python.
- Квантование — отдельная ось качества — 1-bit 27B ≈ 4-bit 9B на Lupus; для редкого синтаксиса точность весит больше, чем сырой размер.
- Этап 2 (в работе): генерация датасета Lupus учителем (DeepSeek V4 Flash) → LoRA-дообучение 2B/4B → повторный бенчмарк. Честный тест гипотезы: «что легче выучить при равном объёме данных».
- Этап 3 (план): переписать интерпретатор на Rust для production-скорости.
api_client.py Не проверялся!
🐺 Lupus v0.1R Alpha
Research Release — the first honest benchmark of Lupus against Python on 5 LLM models of varying sizes and quantization precision.
TL;DR
- Lupus is a Lisp-like language designed for small LLMs (1.5–14B)
- Hypothesis: "Lupus yields ≥20% fewer errors than Python" ❌ did not hold in zero-shot
- However, a strong scalability effect was discovered: Lupus scales steeper than Python
- Interpreter fix gave +10 p.p. on 2B for free (35% → 45%)
- 1-bit quantized 27B model scores 73% on Lupus — on par with a solid 9B model
📊 Benchmark Results (100 tasks)
| Model | Lupus | Python | Gap |
|---|---|---|---|
| Qwen3.5-2B | 45% | 75% | −30 |
| Qwen3.5-4B | 55% | 93% | −38 |
| Qwen3.8-4B-distill | 53% | 96% | −43 |
| Qwen3.5-9B | 74% | 96% | −22 |
| Bonsai-27B (Q1_0, 1-bit) | 73% | 99% | −26 |
Key observation: The Lupus curve goes 45→55→74 (almost linear), while Python saturated at 93–99%. The gap narrows as model size increases — this is the main signal in favor of the learnability hypothesis.
Bonsai-27B: A 1-bit quantized 27B model (4.7 GB) achieves 73% on Lupus — parity with Qwen3.5-9B (74%), while its Python score is near-perfect (99%). The 3× parameter advantage is eaten up by extreme quantization: S-expressions turned out to be more sensitive to quantization noise than familiar Python. Bonsai's failures are the same error classes (hallucinations of let/expt, immutability, paren imbalance), confirming the taxonomy across a sixth model.
🔧 What Was Fixed Since v0.1e
- Polymorphic
print— now acceptsint,bool,strwithout explicitint->str. Eliminated ~15 false failures in arithmetic. ifwithoutelse— removed the strict 3-argument requirement. Models no longer crash on(if cond (print x)).true/falseliterals — added to the lexer; no longer need to define them viadefine.- Benchmark script —
run_experiment.pywith support for--resume,--ids,--cat,--report. - LLM cheat sheet —
lupus_cheatsheet.txtat ~800 tokens, unified across all runs.
🧪 Methodology
- Interpreter: tree-walk in Python (~900 lines)
- Benchmark: 100 tasks × 2 languages = 200 generations per model
- Prompting: system cheat sheet only, no few-shot
- Verification: deterministic stdout comparison against reference
- Temperature: 0.1,
max_tokens: 700 - Thinking: disabled in all runs (otherwise Qwen3.5 burns all tokens on reasoning)
📋 Lupus Failure Taxonomy
| Class | Example | Cause |
|---|---|---|
| Stdlib hallucinations | expt, append, let, string-reverse |
Model draws from Scheme/Common Lisp |
| Immutability | "Variable sum is not mutable" | Forgets define-mutable before set! |
| Paren imbalance | "Unexpected token: RPAREN" | Classic S-expression issue for small models |
| Algorithmic | reverse order, off-by-one | Logic errors, not syntax |
🎯 Conclusions and Next Steps
- Zero-shot comparison is unfair — Python has terabytes of code in pretraining, Lupus has zero. The ~30 p.p. gap is a data effect, not a language effect.
- Lupus scales — on 9B in "clean" categories (arithmetic, logic, strings) it already achieves parity with Python.
- Quantization is a separate quality axis — 1-bit 27B ≈ 4-bit 9B on Lupus; for rare syntax, precision matters more than raw size.
- Stage 2 (in progress): generating a Lupus dataset with a teacher (DeepSeek V4 Flash) → LoRA fine-tuning 2B/4B → re-benchmark. An honest test of the hypothesis: "what is easier to learn given equal data volume".
- Stage 3 (planned): rewrite the interpreter in Rust for production speed.
api_client.py Not tested!