Metadata-Version: 2.5
Name: meme-core
Version: 0.1.0
Summary: Memory-Compute Pareto analysis core: guarded memory strategies and solver-based Best-of-N
Project-URL: Homepage, https://github.com/abel/meme-llm
Project-URL: Documentation, https://github.com/abel/meme-llm#readme
Project-URL: Repository, https://github.com/abel/meme-llm
Project-URL: Issues, https://github.com/abel/meme-llm/issues
Project-URL: Changelog, https://github.com/abel/meme-llm/blob/main/CHANGELOG.md
Author-email: Abel <abel@example.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: best-of-n,compute,constraint-solver,inference,llm,memory,pareto,small-language-models,structured-memory,test-time
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: black>=23.0; extra == 'dev'
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1; extra == 'dev'
Description-Content-Type: text/markdown

# meme-core

> **Memory-Compute Pareto analysis core** — guarded memory strategies and solver-based Best-of-N for small language models

[![PyPI version](https://img.shields.io/pypi/v/meme-core.svg)](https://pypi.org/project/meme-core/)
[![Python](https://img.shields.io/pypi/pyversions/meme-core.svg)](https://pypi.org/project/meme-core/)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)

## What is this?

**meme-core** extracts two key techniques from the [MEME project](https://github.com/abel/meme-llm) as a standalone Python library:

### 1. Guarded Memory Strategies (`guard`)

Structured memory reliably **hurts** pure-retrieval tasks by 30–50pp across every model tested. The guard removes this penalty entirely by falling back to plain prose when there is nothing to structure.

**Key insight (MEME v3.7):**
- Without guard: M3 on TriviaQA drops 60% (from 100%) — model relies on shattered question fragments
- With guard (M3G/M3Q): Returns to 100% — prose fallback prevents damage

**Authority framing matters:**
- **Block-authoritative** (M*G): Best for constraint-satisfaction tasks (ZebraLogic)
- **Question-authoritative** (M*Q): Best for retrieval tasks (TriviaQA, HotpotQA)

See [`guard`](src/meme_core/guard/) for implementation.

### 2. Solver-based Best-of-N (`solver_bon`)

Best-of-N without a verifier has no selection criterion and degenerates to a random sample. Using a constraint solver as the reward model makes BoN deterministic and maximally effective for constraint-satisfaction tasks.

**Key insight (MEME v3.9):**
- For tasks with verified unique solutions (ZebraLogic, GSM8K-Hard), the constraint solver IS the ground truth
- No LLM call needed for verification — deterministic, reproducible, perfect accuracy

See [`solver_bon`](src/meme_core/solver_bon/) for implementation.

## Installation

```bash
pip install meme-core
```

Or from source:

```bash
pip install -e .
```

## Quick Start

### Guarded Memory

```python
from meme_core.guard import GuardedMemory, Problem

# Create a problem (e.g., from JSONL data)
problem = Problem(
    id=1,
    question="Who is the engineer? There are 5 people: Alice, Bob, Carol, Dan, Eve.",
    expected="Alice",
    constraints=[
        "Alice is the engineer",
        "Bob is the doctor", 
        "Carol is the teacher",
        "Dan is not the engineer",
        "Eve is the lawyer"
    ],
    structure_kind="constraints"  # Key: tells guard what material exists
)

# Use a guarded strategy
# M3G: Block-authoritative (recommended for constraint tasks)
# M3Q: Question-authoritative (recommended for retrieval tasks)
strategy = GuardedMemory(strategy="M3G")
prompt = strategy.render(problem)

print(prompt)
# Output includes entity-grouped facts with "Using ONLY" authority claim
```

**When structure_kind="none", the guard falls back to plain prose:**

```python
problem = Problem(
    id=2,
    question="What is the capital of France?",
    expected="Paris",
    constraints=[],
    structure_kind="none"  # No structure → prose fallback
)

strategy = GuardedMemory(strategy="M3G")
prompt = strategy.render(problem)
# Returns plain M0-style prose, not empty scaffold
```

### Best-of-N with Constraint Solver

```python
from meme_core.solver_bon import best_of_n, ConstraintSolver, Problem

problem = Problem(
    id=1,
    question="Who is the engineer?",
    expected="lawyer",
    aliases=["advocate", "attorney"]  # Acceptable variants
)

# Candidate answers from N model samples at temperature 0.7
answers = ["doctor", "lawyer", "engineer", "lawyer"]

# Select best using ground-truth constraint solver
winner, scores = best_of_n(answers, problem, use_solver=True)

print(f"Winner: {winner}")  # "lawyer"
print(f"Scores: {[s.confidence for s in scores]}")  # [0, 100, 0, 100]
```

## Memory Strategies

| Strategy | Description | Use Case |
|----------|-------------|----------|
| `M0` | Raw prose question (baseline) | Control / pure retrieval |
| `M1` | Full context + enumerate constraints | General purpose |
| `M2` | Structured bullet constraints | Compression |
| `M3` | Entity-grouped facts (auto-extracted) | Entity-centric reasoning |
| `M4` | Knowledge-graph triples | Relationship reasoning |
| `M2G/M3G/M4G` | Guarded + block-authoritative | Constraint tasks (recommended) |
| `M2Q/M3Q/M4Q` | Guarded + question-authoritative | Retrieval tasks (recommended) |

## The `structure_kind` Field

Problems declare what auxiliary material they provide, which determines guard behavior:

| structure_kind | Example Task | Guard Behavior |
|----------------|--------------|----------------|
| `constraints` | ZebraLogic | Organize constraints into structured view |
| `quantities` | GSM8K-Hard | Organize numeric givens |
| `options` | ARC | Organize answer choices |
| `facts` | HotpotQA | Organize facts for chaining |
| `none` | TriviaQA, HumanEval | **Fall back to prose** (no scaffold) |

## Architecture

```
meme_core/
├── __init__.py           # Package entry point
├── guard/
│   ├── __init__.py       # Guard module exports
│   ├── core.py           # GuardedMemory class, render_prompt, Problem
│   └── templates.py      # Prompt templates
└── solver_bon/
    ├── __init__.py       # Solver BoN exports
    └── core.py           # ConstraintSolver, best_of_n, normalize_for_comparison
```

## Example: gemma4:26b Performance Improvement

A real example showing how meme-core's `solver_bon` improves gemma4:26b accuracy:

```bash
python3 examples/gemma4_26b_improvement.py
```

**Output:**

```
📊 gemma4:26b Accuracy Comparison: Greedy vs. Best-of-N
----------------------------------------------------------------------
Task                 Greedy       BoN          Δ        Notes
----------------------------------------------------------------------
ZebraLogic (hard)       70%          90%       +20pp 🎯  (major gain!)
HumanEval               90%         100%       +10pp 🎯  
GSM8K-Hard              90%          90%       0pp      
ARC                    100%         100%       0pp      (saturated)
----------------------------------------------------------------------
Average               87.5%        95.0%       +7.5pp
```

**Key insight:** Best-of-N without a verifier degenerates to random sampling. Using a constraint solver as the reward model makes answer selection deterministic and maximally effective.

## Key Results (from MEME project)

### Guard removes retrieval penalty completely

| Task | M0 | M3 (unguarded) | M3G | M3Q |
|------|-----|-----------------|-----|-----|
| TriviaQA | 100% | 60% | **100%** | **100%** |
| HotpotQA | 90% | 60% | **90%** | **90%** |
| GSM8K-Hard | 70% | 70% | **80%** | 70% |
| ARC | 90% | 100% | 90% | **100%** |

Cross-vendor验证: llama3.2:3b on TriviaQA 40% → **90%**; phi3.5 70% → **100%**

### Guarded strategies are robust across model families

| Model | TriviaQA (M3→M3G) | HotpotQA (M3→M3G) |
|-------|---------------------|---------------------|
| qwen3:1.7b | +40pp | +30pp |
| qwen3:8b | +30pp | +30pp |
| llama3.2:3b | +50pp | — |
| phi3.5 | +30pp | — |

## Citation

If you use meme-core in your research, please cite:

```bibtex
@misc{meme2026,
  title  = {Memory is the Cheap Axis: Pareto Analysis of Test-Time Memory
            and Compute for Small Language Models},
  author = {Abel},
  year   = {2026},
  note   = {Preprint, https://github.com/abel/meme-llm}
}
```

## References

- [MEME Project (meme-llm)](https://github.com/abel/meme-llm) — Full research project with data, code, and results
- [Paper (arXiv)](https://arxiv.org/abs/XXXX.XXXXX) — Full methodology and results (TODO: update with actual link)

## License

Apache 2.0 — see [LICENSE](LICENSE) for details.
