neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
Python과 WebAssembly를 이용해 브라우저에서 언어 모델을 로컬로 실행하고 데이터를 서버에 전송하지 않습니다
Run language models locally in your browser using Python and WebAssembly without sending data to a server
AI가 요약 · 페이지와 README에서
개발 도구JavaScript · PythonGitHub @takano32온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Language models that run in your browser, with the model code written in Python and run by
Pyodide (Python compiled to WebAssembly). Nothing is sent to a server: the page downloads
the model and runs it on your device. This is an experiment in how far Python on WebAssembly can go, not a product.
(Until September 2026 the project was called pyodide-llama-py.)
Python does the work around the model; the arithmetic of each token runs in small WebAssembly SIMD kernels, and in
WebGPU where the device has it and it is faster there. See How it works.README 전문 보기 ↗Language models that run in your browser, with the model code written in Python and run by Pyodide (Python compiled to WebAssembly). Nothing is sent to a server: the page downloads the model and runs it on your device. This is an experiment in how far Python on WebAssembly can go, not a product. (Until September 2026 the project was called pyodide-llama-py.)
flowchart TD
page["The page: chat and model list"]
worker["Web Worker: downloads the model in parts, starts Pyodide"]
python["Pyodide, Python in WebAssembly: loads and converts the model to int8, tokenizer, sampling"]
engine["Forward engine: forward.js"]
cpu["CPU: WebAssembly SIMD kernels, on software threads where the browser allows"]
gpu["GPU: WebGPU shaders, for the prompt and the answer where this device measured them faster"]
page -- "prompt" --> worker
worker -- "text, token by token" --> page
worker --> python
python -- "the prompt in blocks, the answer a few tokens at a time" --> engine
engine --> cpu
engine --> gpu
Python does the work around the model; the arithmetic of each token runs in small WebAssembly SIMD kernels, and in WebGPU where the device has it and it is faster there. See How it works.
Open https://takano32.github.io/pyodide-llm/ and write a prompt.
?offline=off turns that off).The weekly CI runs the deployed site on Linux, Windows (x86-64 and ARM) and macOS, in Playwright's Chromium, Firefox and WebKit and in the installed Chrome and Edge: all 23 combinations run. What each browser adds:
| Chrome, Edge | Firefox | Safari (WebKit) | |
|---|---|---|---|
| WebAssembly SIMD kernels | yes | yes | yes |
| relaxed SIMD (int8 about 30% faster) | yes | yes | no |
| software threads (through the Service Worker) | yes | yes | yes |
| 64-bit memory: models over 4 GB | yes | yes | no |
| WebGPU for the prompt | yes | not in the Firefox of the CI (no WebGPU in a worker) | on the owner's iPhone; not in the CI's WebKit |
| WebGPU for the answer | yes, for Llama, Qwen2, Qwen3, GPT-2 and GPT-NeoX models | not measured (no WebGPU in a worker in the CI) | where the prompt has it; not tried on the owner's iPhone yet |
/benchmark/, loads the model again on the CPU if that is
faster, and remembers it for the next visit. Other models too large to hold twice stay on the CPU./benchmark/ skips its round without the
kernels there (NumPy widens the weights to float32: for llm-jp-3-150m,
Pyodide grew to 958 MB in CI's Chromium).Details and numbers: docs/performance.md and docs/webgpu.md.
The model list has three groups:
?model=<id> opens a model of the list directly.
?hf=<owner>/<repository> (optionally &revision= and &template= with {prompt} in it) converts a Hugging
Face repository, and says in words what it cannot run. What it reads: the Llama architecture (with Llama 3,
linear and yarn RoPE scaling, yarn only as a factor and an original context, nothing else it can set; Mistral is read
as Llama), Qwen2, Qwen3, GPT-2 and GPT-NeoX, in safetensors (one file or
several shards), with a Unigram or byte-level BPE tokenizer.json or a sentencepiece model. It does not open a
repository that has only GGUF files: the GGUFs of the list are read together with the vocabulary and
configuration of their original repository. Instruction models get what you type inside their chat template,
for one turn; the page keeps no conversation.?checkpoint=<url>&tokenizer=<url> reads files in llama2.c's format from any server that answers cross-origin
range requests, for example
?checkpoint=https://huggingface.co/karpathy/tinyllamas/resolve/main/stories110M.bin&tokenizer=https://raw.githubusercontent.com/karpathy/llama2.c/master/tokenizer.bin.The folder button next to the model list (or dropping the files on the page) opens a model from your disk. The files are read where they are: nothing is uploaded. Choose the files together:
.safetensors file (not several shards), config.json and
tokenizer.json, tokenizer.model or spiece.model. The page converts them to int8 in the browser, a few
megabytes at a time, with no more memory than the converted model. tokenizer_config.json or
chat_template.jinja, if you add them, give the chat template.stories110M.bin, or what convert_hf.py and quantize.py
write) and its tokenizer.bin. float32, float16 and int8 are told apart by the header and the file size..json with what differs from llama2.c's conventions, shaped like an entry of src/models.js:{ "name": "tiny-lm", "options": { "tokenizer_kind": "unigram", "stop_tokens": [1, 2] },
"generation": { "steps": 256, "temperature": 0.7, "topp": 0.9, "repetition_penalty": 1.3 }, "prompt": "これからの流行りは" }
For the Hugging Face files, the .json may also say {"conversion": {"dtype": "float16", "max_seq_len": 1024}}.
A checkpoint of more than 1 GB asks first.
?pyodide=<version> forces one) and starts it in a
Web Worker. The model is downloaded at the same time, in parts over several connections.src/python/llama2_numpy.py, src/python/llama2_convert.py) reads the model, converts a Hugging Face model to
int8 as its file arrives, and handles the tokenizer and the sampling.src/runtime/forward.js), which calls WebAssembly SIMD kernels
(kernels/, written in AssemblyScript) on the model's own WebAssembly memory. With threads, software threads
(src/runtime/helper.ts) share the rows of each matrix. The page measures how many threads are fastest on your
device.src/runtime/gpu.js, src/runtime/shaders.js). The page checks each shader against JavaScript on your device, times them,
and uses the GPU only where it measured it faster than the CPU. The answer goes to the GPU 4 tokens at a time,
each sampled there with the random number the CPU drew for it.More:
Requirements: Node.js 24 LTS (.nvmrc; the page is built with Astro) and Python 3 with
NumPy.
git clone https://github.com/takano32/pyodide-llm.git
cd pyodide-llm
make run # downloads and converts the models (about 1 GB), builds the kernels, starts http://localhost:8080/pyodide-llm/
Or with Docker: docker build -t pyodide-llm . && docker run -p 8080:8080 pyodide-llm.
make models downloads, converts, quantizes and splits the models into public/models/. No binary is
committed: the site's models are built when it is deployed.make kernels compiles the SIMD kernels (no Emscripten needed; see kernels/README.md).npm run build builds the site into dist/: the page's script and the workers (src/runtime/) bundled, every
file named by a hash of its content.Checks:
python -m pytest tests -q: the engine and the converter (native Python and NumPy).node tests/smoke.mjs: the engine and the models in Node's Pyodide (after make models).node tests/forward-check.mjs: the page's forward pass against NumPy.npm run build && node tests/e2e.mjs [model] [chromium|firefox]: the page in a real browser (Playwright).Pushing to main deploys to GitHub Pages. AGENTS.md (in Japanese) holds the decisions, measurements
and pitfalls, and TASKS.md the tasks.
Mozilla Public License 2.0, the same as Pyodide's. Some files carry code from other projects under their own licenses, and keep those notices where the code is: src/python/llama2_numpy.py (tairov/llama2.py and karpathy/llama2.c, MIT) and the files of src/runtime/shaders/ (src/runtime/shaders.js is their window; llama.cpp and ONNX Runtime, MIT; TensorFlow.js, MLC LLM and Apache TVM, Apache-2.0). The models are not in this repository and each keeps its own license (see the model list).