A local-only tool that rewrites AI-generated text to sound naturally human-written. It uses a rule-based engine to strip telltale AI phrases and overused words, then optionally passes the result through a local LLM (via LM Studio) for a deeper rewrite. A built-in stylometric scorer estimates how "AI-like" text is before and after — no paid APIs, no cloud calls, everything runs on your machine.
- Python 3.11+ (tested on 3.14)
- Windows 11 (commands below are PowerShell; the Python code itself is cross-platform)
- LM Studio (optional) — for the enhanced LLM rewrite pass
python -m venv venv
venv\Scripts\activatepip install -r backend\requirements.txtpython -m nltk.downloader punkt_tab averaged_perceptron_tagger_eng wordnet omw-1.4(The app also auto-downloads missing NLTK data on startup, so this step is optional if you prefer to let it handle itself.)
copy .env.example .envuvicorn backend.main:app --reload --port 8000Go to http://localhost:8000 — you should see the app with a status badge in the header showing whether LM Studio is connected.
LM Studio adds an LLM-powered rewrite pass that produces more natural output than rules alone. The app works fully without it — you'll just see "rules-only mode" in the status badge.
- Install LM Studio from lmstudio.ai
- Open the Developer tab (the
<>icon in the left sidebar) - Search for and download a Qwen3 8B instruct model — look for a GGUF file with Q4_K_M quantization (good quality, fits in 8 GB VRAM)
- Load the model in the Developer tab
- Click Start Server (default port: 1234)
- The app's status badge should turn green and show the model name
The app auto-detects LM Studio at http://localhost:1234/v1. If you change the port, update LM_STUDIO_BASE_URL in your .env file.
Rule-based engine (always runs):
- Strips ~70 known AI-telltale phrases ("it is important to note that", "in today's fast-paced world", "let's delve into", etc.)
- Swaps ~60 overused AI words for plainer alternatives (crucial → key, leverage → use, tapestry → mix, etc.)
- Varies sentence structure when it detects uniform rhythm
- Injects contractions at heavy intensity (do not → don't, it is → it's)
Local LLM pass (optional, requires LM Studio):
- Feeds the rule-based output through a local LLM with intensity-aware instructions
- Light: minimal edits. Medium: moderate rewording. Heavy: free rewrite.
AI-likelihood scorer (runs before and after):
- Computes type-token ratio, sentence burstiness, AI phrase density, punctuation entropy, and readability indices
- Optionally uses real per-token perplexity from LM Studio when available
- Produces a 0–100 score: <30 = "likely human", 30–59 = "mixed", 60+ = "likely AI"
LM Studio badge shows "not detected"
Make sure you've loaded a model and clicked Start Server in LM Studio's Developer tab. Check that the port in LM Studio matches LM_STUDIO_BASE_URL in your .env (default: 1234).
First request is slow Normal — the model is loading into VRAM. Subsequent requests are fast.
Upload rejected with "unsupported file type"
Only .txt, .docx, and .pdf files are accepted. Check the file extension.
Upload rejected with "file too large"
Default limit is 10 MB. Change MAX_UPLOAD_SIZE_MB in .env to increase it.
NLTK errors on startup
Run python -m nltk.downloader punkt_tab averaged_perceptron_tagger_eng wordnet omw-1.4 manually, or delete the nltk_data folder and let the app re-download on next start.
ai-text-humanizer/
├── backend/
│ ├── main.py # FastAPI app, startup logic, route registration
│ ├── config.py # pydantic-settings config from .env
│ ├── requirements.txt # Python dependencies
│ ├── engine/
│ │ ├── rules.py # Rule-based humanization pipeline
│ │ ├── llm_client.py # LM Studio client (graceful fallback)
│ │ ├── detector.py # AI-likelihood scorer
│ │ ├── file_parser.py # .txt/.docx/.pdf extraction + export
│ │ └── data/
│ │ ├── ai_phrases.json # Blocklist of AI-telltale phrases
│ │ └── synonyms.json # Overused-word → natural-alternative map
│ ├── routes/
│ │ ├── humanize.py # POST /api/humanize, GET /api/health-llm
│ │ ├── detect.py # POST /api/detect
│ │ └── files.py # POST /api/upload, /api/batch-humanize, /api/export
│ ├── models/
│ │ └── schemas.py # Pydantic request/response models
│ └── tests/
│ ├── test_rules.py # Rule engine tests
│ └── test_detector.py # Scorer tests
├── frontend/
│ ├── index.html # Single-page UI
│ ├── style.css # Dark neumorphism stylesheet
│ └── app.js # Frontend logic (plain fetch, no framework)
├── .env.example # Environment variable template
└── README.md
| Method | Path | Description |
|---|---|---|
| GET | /api/health |
App health check |
| GET | /api/health-llm |
LM Studio status + model name |
| POST | /api/humanize |
Humanize pasted text (rules + optional LLM) |
| POST | /api/detect |
Score text for AI-likelihood |
| POST | /api/upload |
Upload and extract text from a file |
| POST | /api/batch-humanize |
Upload multiple files, get a zip of humanized results |
| POST | /api/export |
Export text as .txt or .docx download |
MIT