Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

easyTrain

A small web UI to fine-tune MLX (mlx-lm) language models on Apple Silicon Macs. Upload a dataset, kick off a LoRA/DoRA training run, watch live logs via WebSocket, and chat with the resulting model.

Stack

  • Backend: FastAPI + mlx-lm (LoRA via mlx_lm.lora.run). Python deps managed with uv.
  • Frontend: Next.js (App Router) + Tailwind v4. Talks to the backend over /api/* (proxied via Next rewrites) and /ws/runs/:id for live logs.

Layout

backend/
  app/
    main.py        FastAPI app: upload, train, runs, chat, WebSocket
    trainer.py     mlx-lm LoRA training orchestration (stdout-captured)
    inference.py   load base + adapter, generate completions
    datasets.py    .jsonl/.json validation
    runs.py        in-memory run registry
    config.py      settings (data dirs)
  pyproject.toml   uv-managed deps
frontend/
  src/app/page.tsx  Train tab + Runs tab + chat panel
  src/lib/api.ts    API client + WS helper
  next.config.ts    rewrites /api -> backend
scripts/dev-backend.sh

Prerequisites

  • Apple Silicon Mac (M-series).
  • uv (Python), pnpm (Node), Node 20+.
  • Internet access the first time you train (to pull a model snapshot from the Hugging Face Hub).

Setup

# backend (creates .venv, installs mlx, mlx-lm, fastapi, ...)
cd backend
uv sync

# frontend
cd ../frontend
pnpm install

Run

Two terminals:

# 1) backend (reads backend/.env for EASYTRAIN_HOST / EASYTRAIN_PORT)
cd backend
uv run python -m app.main

# 2) frontend (reads frontend/.env.local for BACKEND_URL)
cd ../frontend
pnpm dev

Open http://localhost:3000. Defaults assume the backend is at http://127.0.0.1:8765 (see backend/.env and frontend/.env.local). To run the backend on the default FastAPI port 8000 instead, edit backend/.env and frontend/.env.local accordingly.

Dataset format

.jsonl (one JSON object per line) with either:

  • {"text": "...raw text..."} (causal LM), or
  • {"messages": [{"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]} (chat).

.json files with a {"train": [...]} shape are also accepted. Validation runs on upload; a per-run train.jsonl is staged into backend/data/datasets/ for mlx_lm.

How training works

The backend calls mlx_lm.lora.run() (the same code path as python -m mlx_lm lora --train ...) with an argparse-style namespace built from the UI config. adapter_config.json + adapters.safetensors are written to backend/data/checkpoints/<run_id>/. Stdout/stderr is captured line-by-line and exposed via GET /api/runs/<id> and WS /ws/runs/<id>.

Chat / inference

POST /api/runs/<id>/chat loads the base model with the run's adapter (mlx_lm.load(model, adapter_path=...)) and generates with the model's chat template if available.

Notes / limitations

  • Runs are kept in memory (no DB); restarting the backend clears the registry.
  • Adapters stay on disk under backend/data/checkpoints/ until deleted via DELETE /api/runs/<id>.
  • full fine-tune type trains all weights — needs significantly more memory.
  • The first chat after training re-loads the model (cold); subsequent runs in the same backend process benefit from any HF cache.

About

A small web UI to fine-tune MLX (mlx-lm) language models on Apple Silicon Macs. Upload a dataset, kick off a LoRA/DoRA training run, watch live logs via WebSocket, and chat with the resulting model.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages