Text Generation
Transformers
Safetensors
English
qwen3
lipogram
constrained-generation
qlora
conversational
text-generation-inference
Instructions to use jwjesse/no-e with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use jwjesse/no-e with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="jwjesse/no-e") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("jwjesse/no-e") model = AutoModelForCausalLM.from_pretrained("jwjesse/no-e", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use jwjesse/no-e with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "jwjesse/no-e" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "jwjesse/no-e", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/jwjesse/no-e
- SGLang
How to use jwjesse/no-e with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "jwjesse/no-e" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "jwjesse/no-e", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "jwjesse/no-e" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "jwjesse/no-e", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use jwjesse/no-e with Docker Model Runner:
docker model run hf.co/jwjesse/no-e
Update model card
Browse files
README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
base_model: Qwen/Qwen3-1.7B
|
| 3 |
+
library_name: transformers
|
| 4 |
+
license: apache-2.0
|
| 5 |
+
language:
|
| 6 |
+
- en
|
| 7 |
+
tags:
|
| 8 |
+
- lipogram
|
| 9 |
+
- constrained-generation
|
| 10 |
+
- qlora
|
| 11 |
+
datasets:
|
| 12 |
+
- jwjesse/slm-lipogram
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
# no-e
|
| 16 |
+
|
| 17 |
+
A small model (Qwen3-1.7B, fine-tuned with QLoRA) that rewrites an English passage **without the letter "e"** (either case), keeping the names, the facts and at least 70% of the original length. Names are copied as written, so an "e" inside a name from the passage is allowed.
|
| 18 |
+
It is a research prototype: it cuts the stray e’s a lot but rarely reaches zero. A "stray e" below is an "e" outside names copied exactly from the passage (the rule check masks such names before counting).
|
| 19 |
+
|
| 20 |
+
## How to use
|
| 21 |
+
|
| 22 |
+
```python
|
| 23 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 24 |
+
|
| 25 |
+
repo = "jwjesse/no-e"
|
| 26 |
+
tok = AutoTokenizer.from_pretrained(repo)
|
| 27 |
+
model = AutoModelForCausalLM.from_pretrained(repo, dtype="auto", device_map="auto")
|
| 28 |
+
|
| 29 |
+
passage = "..." # 50 to 100 words of English
|
| 30 |
+
prompt = "Rewrite this passage without using the letter e:\n\n" + passage
|
| 31 |
+
text = tok.apply_chat_template([{"role": "user", "content": prompt}], tokenize=False,
|
| 32 |
+
add_generation_prompt=True, enable_thinking=False)
|
| 33 |
+
inputs = tok(text, return_tensors="pt").to(model.device)
|
| 34 |
+
out = model.generate(**inputs, max_new_tokens=400, do_sample=False) # greedy
|
| 35 |
+
print(tok.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True))
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
Training and evaluation used exactly that prompt. The [demo](https://huggingface.co/spaces/jwjesse/no-e-demo) sends "Rewrite this passage in English without using the letter e:" instead,
|
| 39 |
+
because the added words reduce the occasional non-English output.
|
| 40 |
+
|
| 41 |
+
## Training
|
| 42 |
+
|
| 43 |
+
- Data: [jwjesse/slm-lipogram](https://huggingface.co/datasets/jwjesse/slm-lipogram), config `us_open1`: 150 examples. The passages are the openings of US CNN articles and Wikipedia introductions (50 to 100 words);
|
| 44 |
+
the rewrites were written by GPT-6.1 Sol and kept only if they passed code checks (no "e" outside names copied exactly from the source, look-alike letters count, ASCII only, real English words, at least 70% of the source length) and a meaning judge (Claude Sonnet 5.5, score 4 or 5).
|
| 45 |
+
- Method: 4-bit QLoRA, rank 16, learning rate 2e-4, 10 epochs, seed 0, on one L4 GPU. The adapter is merged into the weights; the repo holds a single merged BF16 `model.safetensors` (1.7B parameters, 3.4 GB), not an adapter.
|
| 46 |
+
|
| 47 |
+
## Evaluation
|
| 48 |
+
|
| 49 |
+
150 held-out passages from the same two sources (50 of them adversarial), none in the training data. Greedy decoding, plain prompt.
|
| 50 |
+
|
| 51 |
+
| Model | Median stray e’s | Mean | Rewrites with only real words |
|
| 52 |
+
|---|---|---|---|
|
| 53 |
+
| Base Qwen3-1.7B | 38 | 37.8 | 100.0% |
|
| 54 |
+
| Previous model (188 BBC examples) | 11 | 11.0 | 84.7% |
|
| 55 |
+
| **This model** | **10** | **10.7** | **92.0%** |
|
| 56 |
+
|
| 57 |
+
- 11 of 150 passages end with 3 or fewer stray e’s; **0%** are fully e-free.
|
| 58 |
+
- Data curve, same recipe on the first N training rows (median stray e’s): 19 rows 35, 38 rows 30, 75 rows 14, 150 rows 10. It was still falling at 150, so more data would probably help.
|
| 59 |
+
- The previous model (trained on 188 BBC news rewrites) is the comparison point: about the same stray e’s on this set, the previous one has fewer rewrites with only real words (84.7% vs 92.0%), and on 81 of 150 passages this model leaves fewer e’s (58 more, 11 ties).
|
| 60 |
+
|
| 61 |
+
## Limitations
|
| 62 |
+
|
| 63 |
+
- It rarely reaches zero e’s. Expect a handful of stray e’s per passage.
|
| 64 |
+
- Occasional non-English output: 2 of 150 eval outputs had Chinese characters, one fully Chinese. Saying "in English" in the prompt helps.
|
| 65 |
+
- Meaning is not reliably measured. AI judges missed clear meaning failures when checked against hand ratings; the judge score here (3.59 of 5) is only a rough guide. Read the outputs.
|
| 66 |
+
- It sometimes dodges the letter with shorthand or invented-looking words rather than a natural rewrite (92% of its rewrites use only real words; 8% contain at least one non-word or e-dodging shorthand).
|
| 67 |
+
- Tested on 50 to 100 word news and encyclopedia passages in US English only.
|
| 68 |
+
|
| 69 |
+
## Links
|
| 70 |
+
|
| 71 |
+
- Code, evaluation and write-up: https://labs.gauntletai.com/jessewells/SLM
|
| 72 |
+
- Demo: https://huggingface.co/spaces/jwjesse/no-e-demo
|
| 73 |
+
- Dataset: https://huggingface.co/datasets/jwjesse/slm-lipogram
|
| 74 |
+
|
| 75 |
+
The weights are marked Apache 2.0, the licence of the Qwen3 base model. The training text includes CC BY-SA Wikipedia passages and CNN article text (© CNN), so check the rights position before any use beyond research; see the dataset card.
|