Fine-tune a local model to text like one specific person, using your Instagram DM export. Everything stays on your machines.
- Base model, not an assistant. A base LLM (default
Qwen2.5-7B) is fine-tuned on the chat as a plain transcript and simply continues it. There is no system prompt and no persona stats to parrot. - Every message is its own line, so the model learns her bursts of short messages instead of one blob.
Session headers (
--- Wed 14 Jan 2026, 11:41 PM ---) give it time-of-day awareness. - Loss only on her messages (and on the speaker label after her lines, which teaches when a burst ends).
- Emojis are preserved byte for byte. Dropped: "Liked a message/reel", reactions, attachment notices,
calls, unsends, nickname/collection events. Shares and media become
[reel],[photo]... for context only. - Chronological validation split, so held-out data never leaks into training.
transcript.pyis the single definition of the format used by training, the app and the evaluator.
| File | Purpose |
|---|---|
parse_export.py |
Export JSON -> data/processed/conversation.jsonl |
build_dataset.py |
-> train.jsonl, val.jsonl, val_sessions.jsonl, pii_review.jsonl |
train.py |
QLoRA on the GPU machine -> models/adapters/final |
export.py |
Merge + GGUF + Modelfile |
generate.py |
Ollama client returning a burst of messages |
app.py |
Streamlit chat + Turing test |
evaluate.py |
Real-vs-generated style stats on held-out sessions |
- Data machine: put
message_*.jsonindata/raw/, thenCheck the printed sample window andpython -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt cp config.yaml.example config.yaml # set target_sender / my_sender python parse_export.py && python build_dataset.py pytest tests
data/processed/pii_review.jsonl, thengit pushthe code. - GPU machine (Windows, RTX 5070):
git pull, copydata/raw/*.jsonandconfig.yamlover manually.If Unsloth is troublesome on Windows, use WSL2 with the same steps.python -m venv .venv; .venv\Scripts\activate pip install torch --index-url https://download.pytorch.org/whl/cu128 pip install -r requirements-train.txt python parse_export.py; python build_dataset.py python train.py --max-steps 20 # smoke test python train.py # full run, best checkpoint by val loss python export.py # GGUF + Modelfile
- Run it, either:
- on the GPU machine:
ollama create divyanshi -f Modelfile, serve withOLLAMA_HOST=0.0.0.0, and setollama_urlin the laptop'sconfig.yamltohttp://<windows-ip>:11434; or - on the laptop: copy
models/gguf/divyanshi-q4_k_m.ggufandModelfile, thenollama create divyanshi -f Modelfile(4 GB VRAM means partial CPU offload, a few tokens/s, fine for short messages).
- on the GPU machine:
streamlit run app.pyfor chat and the Turing test (accuracy near 50% = indistinguishable),python evaluate.pyfor style distributions.
- Replies too samey: raise
temperature(0.9) or lowermin_p. Too chaotic: lowertemperature. - Wrong thread names:
parse_export.pyprints counts per sender and warns on mismatch. - Out of memory:
batch_size: 1, raisegradient_accumulation_steps, or lowermax_seq_lengthandwindow_chars. - Overfitting (val loss rising): fewer
epochs;load_best_model_at_endalready keeps the best checkpoint.