Pullboard
git 저장소에 존재하는 작업 보드로, 에이전트가 작업을 자동으로 할당·검토하고 별도 설명이 필요 없는 로컬 오픈소스 도구
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Watch your model learn. Fine-tune an LLM on your Mac in a few clicks — and see, layer by layer, what training actually changed.
▶ Try the online demo (no install; replays a real recorded run) · English · 简体中文
Most fine-tuning tools stop at "training finished, loss = 1.23". Most interpretability tools show a model you cannot change. Neurolume puts both in one local app: you train the model, and you watch its insides while you do it.
Status: early alpha. Server, UI and tooling are unit-tested (110+ tests, no GPU needed). Everything below runs on one machine so far (MacBook Pro M5 Max, 128 GB). Verified there with Devstral Small 2 and Qwen3.6-27B: live layer probe, logit lens (live, and computed afterwards for answers generated without it), per-token confidence, guided LoRA training (Devstral: 36 steps, 15 GB peak, validation loss 4.45 → 1.06), before/after comparison, MLX export and training-data generation. Ollama export is not hardware-tested yet. Reports from other machines are very welcome.
Fine-tune without writing code
.jsonl, notes, code, or your ChatGPT / Claude / Claude Code chat history — or let the loaded model generate a dataset from your own files: Q&A pairs from documents, or "requests → your own code/writing" pairs that teach your style. You review and edit every item before training.See inside the model
Use it every day
/v1/chat/completions, streaming), one-click model library, knowledge base (import books/docs for retrieval), opt-in web search for local models (also as an MCP server), and an agent that reads a project folder and proposes edits you approve one by one (with undo).Everything labelled as the model's activity comes from the model; simulated data is labelled. Full definitions in docs/SIGNALS.md.
| Shown | Source |
|---|---|
| Layer count and types | Read from the loaded model |
| Weight values on hover | Exact strided sample of the dequantized weights |
| Per-layer activity | mean|out − in| / mean|in| of each block at the token being generated; raw value on hover |
| Logit lens | The model's own final norm + output head applied to intermediate layers |
| Per-token confidence and alternatives | The probabilities mlx-lm already computes while generating (no extra pass) |
| Brightness of the links between layers | Geometric mean of the two layers' activity; which matrix each thin line joins is illustrative |
| ΔW, per-layer change | Computed from the adapter (scale · B·A) |
| Validation loss before → after | mlx-lm's evaluation before the first update and at the end |
| Discharge paths on the sphere, colours, glow | Stylized (their frequency follows GPU/memory load and layer activity) |
The window is split in two: chat on the right, and on the left the brain on top, with the layer window and the answer replay below it.
| View | What you see |
|---|---|
| Inference | One column per layer, four matrices per layer: attention Q, attention output, MLP gate, MLP down-projection; each cell is a real weight from that matrix (evenly spaced sample). While generating, a layer is brighter the more it changes the token's representation. The bundle of links between two neighbouring layers is lit by the geometric mean of the two, so it is thick and bright only when both layers are busy, and faint if either is quiet. Hover a cell for the real weight and the layer's raw measurement. |
| Train | The adapter's real ΔW (green = weight increased, orange-red = decreased); the bars below are the total change per layer, and you can pick any trained adapter to review. LoRA trains only the last 16 layers by default, so unchanged early layers are expected. |
| Weights | The static weights: orange = positive, cyan = negative, intensity = |w| ÷ the matrix's std (capped at 3σ). |
| Logit lens | A table: one column per generated token, one row per layer showing what that layer would output “if the model stopped here”; darker = more confident. A green underline means the layer already agrees with the final output; the “Settled” row says from which layer on. ◇ is a byte fragment of a multi-byte character. Choose which layers to show: all / second half / last 16 / a custom range and step. If the view was closed while the answer was generated, switching to it computes the lens for that answer afterwards. |
Collect as you go: every answer in the chat has “Save as training sample” and “Edit, then save…”. Save good answers as they are; fix the others into what you wanted first, and the model learns the fixed version.
Import data (samples saved from chat, .jsonl, notes, code, conversations.json exported from ChatGPT or Claude, Claude Code session .jsonl files, or have the model generate pairs from your files; sources can be combined into one dataset) → automatic checks (secrets removed, duplicates dropped, train/validation split) → pick a preset and train (live loss, speed, memory) → results: validation loss before → after, per-layer ΔW, side-by-side comparison with the base model → export as an MLX model or to Ollama.
http://127.0.0.1:8765/v1/chat/completions, OpenAI-compatible, so other tools can use the local model.I clicked a token in the replay. Why are the links between some layers thick and bright and others faint? The layer map is frozen at the moment that token was generated. Each layer's brightness is how much it changed the token's internal representation, compared both with that layer's typical level in this answer and with the other layers for this token. The bundle between two layers takes the geometric mean, so a bright stretch means several consecutive layers were heavily rewriting this token, and a faint stretch means those layers mostly passed it along. It is a real measurement, but not “importance”: changing a lot does not mean contributing a lot to the answer. The overall pattern also tends to look similar from token to token (overall activity varied only about ±10 % on real hardware); what really separates tokens is the confidence in the replay bars. Which of the 16 thin lines in a bundle joins which two matrices, and how the dots move, is illustrative; the measurement is per layer.
Why are the early layers in the logit lens mostly English or gibberish? Early layers are still working out what each token is and where it sits; reading a next-token prediction off them is not meaningful yet. Most training text is English, so the intermediate “drafts” often surface in English. Later layers get closer to the final output.
Why did training only change the later layers? LoRA attaches adapters to the last 16 layers by default and leaves the rest untouched, on purpose: less memory and less risk of breaking the model.
Can fine-tuning make the model remember facts? It is better at style and habits (format, tone, a fixed way of answering). For reliable answers about your documents, use the knowledge base.
One line, no clone needed:
uvx --from "neurolume[mlx] @ git+https://github.com/Yiteng-CHEN/neurolume" neurolume serve --open
Or from a checkout (double-click Neurolume.command, or):
git clone https://github.com/Yiteng-CHEN/neurolume.git && cd neurolume
uv run --extra mlx neurolume serve --open # http://127.0.0.1:8765
Need uv (brew install uv). In the browser: Models → Download (Devstral Small 2 4-bit ≈ 15 GB) → Load → chat; Train opens the wizard. Without a Mac you can still open src/neurolume/web/index.html to see the UI in demo mode.
Data lives in ~/Library/Application Support/Neurolume; models download into the checkout's models/ folder (or the data folder when installed with uvx).
| Qwen3.6-27B (8-bit) | Devstral Small 2 (4-bit) | |
|---|---|---|
| Layers | 64 = 16 × (3 linear + 1 full attention) | 40, all full attention |
| LoRA, longest sequence that fit | 1024 (2048 ran out of memory, peak 115 GB) | ≥ 2048 |
| LoRA seconds / step | 10.1 | 4.4 |
| LoRA peak memory | 62 GB | 18 GB |
src/neurolume/web/ UI: index.html, css/, js/ (plain scripts, no build step)
src/neurolume/server/ local server: chat, library, training, data generation, export, knowledge base, agent
src/neurolume/telemetry/ per-layer probe and logit lens on MLX transformer blocks
src/neurolume/backends/ MLX backend, mocks, OpenAI-compatible client
src/neurolume/evals/ eval tooling: mine tasks from git history, sandboxed grading
docs/ SIGNALS.md, decisions, plan
The server binds to 127.0.0.1 only. Neurolume never reads Claude / Codex / Hugging Face credentials.
Issues and pull requests are welcome — hardware reports (chip, memory, model, what worked) are especially valuable. See CONTRIBUTING.md. Tests: PYTHONPATH=src python -m unittest discover -s tests -t .
M-Courtyard and MLX-LoRA-Studio (no-code MLX fine-tuning); llm-viz and Transformer Explainer (how transformers work); TransformerLens and llm-transparency-tool (research interpretability). Neurolume's focus is the overlap: a live, local model you train and inspect at the same time.
MIT. Neurolume was previously called Cortex; old links redirect.