Skip to content
TiElixirPublic

About

Fine-tune a local open-weight LLM to imitate someone's Instagram DM texting style

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

llmitate

Fine-tune a local model to text like one specific person, using your Instagram DM export. Everything stays on your machines.

How it works

  • 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.py is the single definition of the format used by training, the app and the evaluator.

Layout

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

Workflow

  1. Data machine: put message_*.json in data/raw/, then
    python -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
    Check the printed sample window and data/processed/pii_review.jsonl, then git push the code.
  2. GPU machine (Windows, RTX 5070): git pull, copy data/raw/*.json and config.yaml over manually.
    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
    If Unsloth is troublesome on Windows, use WSL2 with the same steps.
  3. Run it, either:
    • on the GPU machine: ollama create divyanshi -f Modelfile, serve with OLLAMA_HOST=0.0.0.0, and set ollama_url in the laptop's config.yaml to http://<windows-ip>:11434; or
    • on the laptop: copy models/gguf/divyanshi-q4_k_m.gguf and Modelfile, then ollama create divyanshi -f Modelfile (4 GB VRAM means partial CPU offload, a few tokens/s, fine for short messages).
  4. streamlit run app.py for chat and the Turing test (accuracy near 50% = indistinguishable), python evaluate.py for style distributions.

Tuning

  • Replies too samey: raise temperature (0.9) or lower min_p. Too chaotic: lower temperature.
  • Wrong thread names: parse_export.py prints counts per sender and warns on mismatch.
  • Out of memory: batch_size: 1, raise gradient_accumulation_steps, or lower max_seq_length and window_chars.
  • Overfitting (val loss rising): fewer epochs; load_best_model_at_end already keeps the best checkpoint.

About

Fine-tune a local open-weight LLM to imitate someone's Instagram DM texting style

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages