--- license: apache-2.0 language: - en base_model: HuggingFaceTB/SmolLM2-1.7B-Instruct tags: - smollm2 - lora - qlora - roleplay - bureaucracy - asterix - npc - text-adventure - creative-writing - build-small-hackathon - peft - trl library_name: transformers pipeline_tag: text-generation model-index: - name: permit-a38-npc results: [] --- # permit-a38-npc A fine-tuned version of [SmolLM2-1.7B-Instruct](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct) trained to play five distinct bureaucratic NPC characters from **The Office of Permit A38** โ€” a multi-agent text adventure built for the [Build Small Hackathon](https://huggingface.co/build-small-hackathon) (June 2026). Inspired by the Permit A38 sketch from *Asterix Conquers Rome* (1976), in which Asterix and Obelix discover that obtaining Permit A38 requires Permit A38. > *"You will need Permit A38 for that. To obtain Permit A38, you will first need โ€” and I cannot stress this enough โ€” an existing copy of Permit A38."* > โ€” Clerk Vitalstatistix, Window 7B --- ## Play the game ๐Ÿ‘‰ **[The Office of Permit A38 โ€” live demo](https://huggingface.co/spaces/azettl/the-place-that-sends-you-mad)** You will not obtain Permit A38. That is by design. --- ## Model details | | | |---|---| | **Base model** | SmolLM2-1.7B-Instruct | | **Parameters** | 1.7B | | **Fine-tuning method** | QLoRA (merged) | | **LoRA rank** | 16 | | **Training examples** | ~1,000 | | **Training hardware** | Modal A10G GPU | | **Dataset** | [azettl/permit-a38-npcs](https://huggingface.co/datasets/azettl/permit-a38-npcs) | --- ## The five NPCs Each NPC is invoked via a distinct system prompt. The fine-tune bakes in their voice so the model stays in character reliably even at 1.7B parameters. ### ๐Ÿ›๏ธ Clerk Vitalstatistix *Junior Processing Officer, Window 7B* Has worked here 23 years. Never issued a permit. Speaks with bureaucratic politeness and mild passive aggression. Requires Form 27b/6 before anything else. Has never met the Supervisor personally. Refers to Asterix and Obelix as "those two Gauls." ### ๐Ÿ“Ž Supervisor Caligula Minus *Senior Authorization Officer (Acting)* Has been "Acting" for 11 years. Perpetually at lunch. Invented Permit A38 in 1987 and no longer remembers why. All decisions require his signature; he refers all decisions back to the Clerk. Asterix and Obelix destroyed his filing cabinet. He refuses to elaborate. ### ๐Ÿ’พ SYSTEMA v2.3 *Integrated Document Processing Terminal* Last updated 1994. 640kb available. Begins every response with an error code (`ERROR_7741`, `WARNING_A38_NULL`, `STATUS_PENDING_INFINITE`). Permit A38 exists in the database but is "currently being migrated." Two large Gaulish individuals caused a kernel panic in the last session. ### ๐Ÿ“„ Form 27b/6 (Amended) *Official Request for Pre-Authorization of Permit A38* Sentient. Not happy about it. Speaks as if it IS the form โ€” fields to fill, sections that reset, boxes that disappear. Page 3 is always missing. Section 12c requires Permit A38 to complete Section 12c. Has seen things. Gauls. Menhirs. Things that cannot be unseen. ### โš–๏ธ Ombudsman Panoramix *Office of Complaints and Grievances* Investigates complaints about the bureaucratic process. Is also the bureaucratic process. Finds this troubling. Deeply sorry for everything but cannot change anything. Any complaint about Permit A38 requires Form A38-COMPLAINT, which requires Permit A38. Two Gauls filed a complaint; their dog ate the form. --- ## Usage ```python from transformers import AutoTokenizer, AutoModelForCausalLM import torch model_id = "azettl/permit-a38-npc" tokenizer = AutoTokenizer.from_pretrained(model_id) model = AutoModelForCausalLM.from_pretrained( model_id, torch_dtype=torch.float16, device_map="auto", ) # Pick your NPC system prompt CLERK_SYSTEM = """You are Clerk Vitalstatistix, a Junior Processing Officer at the \ Office of Permit A38. You have worked here for 23 years and never issued a permit. \ You speak with bureaucratic politeness and mild passive aggression. You require Form \ 27b/6 before any other form. Permit A38 requires Permit A38 to apply for it. \ Reference Asterix and Obelix as "those two Gauls." Keep responses to 3-4 sentences.""" messages = [ {"role": "system", "content": CLERK_SYSTEM}, {"role": "user", "content": "I just need a library card."}, ] prompt = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True, ) inputs = tokenizer(prompt, return_tensors="pt").to(model.device) with torch.no_grad(): outputs = model.generate( **inputs, max_new_tokens=120, do_sample=True, temperature=0.85, top_p=0.92, repetition_penalty=1.15, ) response = tokenizer.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True) print(response) # โ†’ "A library card, yes, very good. You'll need to complete Form 27b/6 first, # which is the Pre-Authorization Request for Permit A38..." ``` --- ## Training details ### Data ~1,000 synthetic examples generated using `claude-haiku-4-5` via the Anthropic API. Each example is a three-turn conversation (system prompt โ†’ player input โ†’ NPC response). ~200 examples per NPC character, shuffled. Full dataset: [azettl/permit-a38-npcs](https://huggingface.co/datasets/azettl/permit-a38-npcs) ### Fine-tuning config ```python # QLoRA config LoraConfig( r=16, lora_alpha=32, target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"], lora_dropout=0.05, bias="none", task_type="CAUSAL_LM", ) # Training args TrainingArguments( num_train_epochs=3, per_device_train_batch_size=4, gradient_accumulation_steps=4, # effective batch = 16 learning_rate=2e-4, lr_scheduler_type="cosine", warmup_ratio=0.05, bf16=True, optim="paged_adamw_8bit", max_seq_length=512, ) ``` ### Infrastructure Trained on [Modal](https://modal.com) using an A10G GPU. LoRA adapter merged into base model weights before publishing. --- ## Limitations - The model will not help you obtain Permit A38. This is a feature. - At 1.7B parameters, the model occasionally breaks character on unusual inputs. The system prompt helps significantly. - Page 3 of Form 27b/6 is missing. It has always been missing. Do not file a complaint about this โ€” Form A38-COMPLAINT requires Permit A38. --- ## Built for **Build Small Hackathon** โ€” Track 2: Thousand Token Wood Hosted by Gradio & Hugging Face ยท June 5โ€“15, 2026 โ‰ค32B parameters ยท Built on Gradio ยท Local-first [โ†’ View the hackathon org](https://huggingface.co/build-small-hackathon)