Text Generation
MLX
English
lora
education
steam
k12
cultural-heritage

ZubHub STEAM Idea Model (LoRA adapter, experimental)

A small LoRA adapter on top of Qwen2.5-1.5B-Instruct (4-bit, MLX) that suggests hands-on K-12 STEAM activity ideas from the materials an educator has, the children's age range, and an optional theme. Ideas are meant to be grounded in cultural crafts and traditional techniques described on Wikipedia.

📖 Write-up: How to Teach a Small LLM to Suggest K12 Creative Project Ideas (freeCodeCamp, June 2026) walks through the full experiment.

Status: learning/research experiment from the ZubHub project. It is not a production model. Read the limitations section before you use it.

How it works

  1. About 19.6k Wikipedia articles were scraped from seed categories (crafts, traditional techniques, invention and technology, and similar), then filtered down to 6,632 relevant articles.
  2. A local Qwen2.5-7B-Instruct (via Ollama) turned about 500 articles into (materials, age range, theme) -> activity idea JSON pairs (synthetic distillation).
  3. The pairs were cleaned, given normalised categories and safety-filtered (safety.py), then split 388 / 48 / 50 (train / valid / test).
  4. LoRA fine-tuning used mlx_lm.lora (rank 8, last 8 layers, lr 1e-5, batch 4, 600 iters).
  5. At serving time, an optional RAG step retrieves related Wikipedia articles with all-MiniLM-L6-v2 embeddings and feeds the chosen article to the model as context.

Files

File What it is
adapters.safetensors Recommended adapter (iteration 400, lowest-overfit point, used by the server)
checkpoints/0000200_adapters.safetensors, checkpoints/0000600_adapters.safetensors Other checkpoints
adapter_config.json, lora_config.yaml Training config
code/ Full pipeline: scrape, filter, generate pairs, train, evaluate, serve

Usage (Apple Silicon, MLX)

pip install mlx-lm huggingface_hub
hf download SrishAkaTux/zubhub-steam-ideas-lora --local-dir zubhub-lora
from mlx_lm import load, generate

model, tok = load("mlx-community/Qwen2.5-1.5B-Instruct-4bit", adapter_path="zubhub-lora")
messages = [
    {"role": "system", "content": "You are a STEAM activity assistant for ZubHub, a hands-on education platform for children. Given the materials an educator has and the children's age range, suggest creative STEAM activity ideas grounded in cultural context. Respond with JSON only."},
    {"role": "user", "content": "I have these materials: cardboard, scissors, string, markers. The children are aged 8-12. Suggest STEAM activity ideas."},
]
prompt = tok.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)
print(generate(model, tok, prompt=prompt, max_tokens=800))

The output is JSON: {"ideas": [{"title", "description", "category", "cultural_origin", "materials_used", "materials_missing", "estimated_minutes", "steps", ...}]}.

Training

Base mlx-community/Qwen2.5-1.5B-Instruct-4bit
Method LoRA (rank 8, scale 20, dropout 0, last 8 layers)
Data 388 train / 48 valid chat examples
Iters 600 (about 6 epochs), batch 4, lr 1e-5, max seq 1024, seed 42
Hardware Apple Silicon, peak memory about 5.3 GB

Validation loss: 2.469 (iter 1), 0.861 (100), 0.840 (200), 0.836 (300), 0.843 (400), 0.862 (500), 0.894 (600). The loss starts rising after about 300–400 iterations, which is why iteration 400 is the shipped checkpoint.

Evaluation (50 held-out test prompts)

Metric iter 400 (safety-filtered data)
Valid JSON 0.98
Schema match 0.98
Avg. steps per idea 4.78
Materials Jaccard vs. reference 0.683
Predicted culture is specific 0.50 (reference: 0.62)
Culture loosely matches reference (when reference is specific) 0.161

An earlier RAG run (k=3, before the safety filtering, on a different test split, so not directly comparable) reached 1.00 valid JSON, 0.752 materials Jaccard and 0.64 culture-specific rate.

These metrics measure format and material overlap only. They do not measure pedagogical quality, safety or cultural accuracy. No educators or community members reviewed the outputs.

Limitations and risks

  • Cultural accuracy: the model often generalises ("Global (various cultures)") or attributes ideas to the wrong culture. Treat any cultural_origin as a prompt to research, not as fact. Outputs can stereotype or flatten traditions.
  • Synthetic labels: the training targets were written by another LLM (Qwen2.5-7B), not by educators, so the model inherits that model's errors and biases.
  • Safety: the adapter has no refusal behaviour. The training data was keyword-filtered (alcohol, weapons, tobacco and similar topics), but the base model's knowledge is unchanged. Any app using this model must add its own input and output moderation and adult supervision. Activities can involve sharp tools, heat or small parts.
  • English only. It is small (1.5B, 4-bit) and was trained on about 400 examples.

Intended use

Brainstorming support for educators and facilitators, with a human checking every suggestion. It is not meant to talk to children directly without supervision.

License and attribution

  • Adapter weights and code: Apache-2.0 (the same as the Qwen2.5 base).
  • The training data is derived from Wikipedia text (CC BY-SA 4.0). See the dataset card.

Citation

@misc{zubhub_steam_ideas_2026,
  title  = {ZubHub STEAM Idea Model: a LoRA adapter for culturally grounded activity ideas},
  author = {Srishti Sethi},
  year   = {2026},
  url    = {https://huggingface.co/SrishAkaTux/zubhub-steam-ideas-lora}
}
Downloads last month

-

Downloads are not tracked for this model. How to track
MLX
Hardware compatibility
Log In to add your hardware

Quantized

Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for SrishAkaTux/zubhub-steam-ideas-lora

Adapter
(13)
this model

Dataset used to train SrishAkaTux/zubhub-steam-ideas-lora