A local study / laboratory tool for exploring semantic embeddings in 3D (WebGL). Not a production SaaS.
3D visualization (WebGL/Three.js) and semantic embedding vector arithmetic (A − B + C), plus compare sequences and related lab experiments.
| License | Apache-2.0 © 2026 Hector Bauzan |
| Public demo | Hugging Face Space |
| Local (macOS) | ./setup.sh → option 1 → http://127.0.0.1:5173 |
"¡LA PUTA MADRE AHORA SÍ CARAJO SE VE LO QUE TENÍAMOS EN LA CABEZA HACE MESES! Las diferencias entre mazos de palabras están en los decimales finos."
Durante meses nos quemamos las pestañas preguntándonos por qué conceptos de universos tan dispares —como fierros de autos (VEHICLES), nombres de personas (WOMEN) o arquitectura de software (IT_CORE)— parecían una masa indistinguible en las proyecciones visuales clásicas de embeddings.
¿Dónde estaba la trampa? La posta está en los decimales. En modelos densos como BAAI/bge-m3 (1024 dimensiones), más del 80% de la masa vectorial es estructura sintáctica basal y ruido compartido. La verdadera firma semántica (el alma léxica que distingue un mazo del otro) vive agazapada allá abajo, en las micro-diferencias del 4º al 6º orden decimal (
En la versión v3.3.0 encendimos el microscopio con Spectral Quorum:
Fijate acá: tres grupos en paralelo (IT_CORE, VEHICLES, WOMEN). Con Baseline silence al 100%, todo el ruido común se manda a negro absoluto. Lo que queda encendido son columnas verticales fijas: cada temática excita dimensiones radicalmente distintas en el espacio de 1024-D. La columna cian es exclusiva de software; la naranja pertenece a la mecánica; la violeta responde al universo femenino.
Metete adentro del espacio: en modo NAVIGATION rotás la cámara y ves el relieve tridimensional real de los 1024 tensores de BGE-M3. Las dimensiones activas se elevan como rascacielos mientras el ruido silenciado descansa aplastado en el piso.
Mirá cómo enfoca: arrancamos con ganancia baja (apenas se intuye la dispersión) y barremos el Decimal Gain (hasta 40×) y el Baseline silence. Es tal cual girar la perilla de enfoque de un microscopio: la señal temática emerge nítida y pura sobre el ruido. No es truco de render: es pura matemática de micro-diferencias vectoriales.
Try the hosted cpu-basic demo (same profile as local-full: Arctic-m-v2 @ 256-D, EN∪ES vocab):
👉 https://huggingface.co/spaces/hbauzan/llm-semantic-visualizer
That Space is a shared study sandbox (Docker, CPU). Expect cold starts, variable latency, and soft resource limits. There is no SLA, no multi-tenant isolation, and no auth — please be gentle (avoid automated flooding of /embed, /compare, /arithmetic).
For serious work or heavier SAE/training experiments, run locally on macOS (below).
Created and tested on macOS 26.5.1 (Darwin 25.5.0, Apple Silicon).
This project was not prepared or validated for Windows or Linux. It may work there with a few adjustments (package managers, paths, process control), but that is unsupported. Prefer a Mac matching the versions above.
The Hugging Face Space image runs on Linux CPU inside HF’s Docker runtime — that path is supported for the demo, not as a general Linux desktop install guide.
Everything goes through ./setup.sh. On macOS, option 1 installs missing tools for you when needed.
# 1. Clone the repo (folder name matches the GitHub repo)
git clone https://github.com/hbauzan/vhectorlab.git
cd vhectorlab
# 2. Open the control panel
chmod +x setup.sh # first time only, if needed
./setup.shChoose option 1 (Deploy / Start Tool).
That option will:
- Probe backend (
:8000) and frontend (:5173): matching process and health check - If both healthy: skip install/sync, tests, and start; open the browser
- If either is sick (port/process/health mismatch, e.g. frozen Vite): recycle both (stop + start after tests)
- If only one is healthy: restart both services after prereqs + tests
- If both down: check/install prerequisites on macOS (
uv, Homebrew+Node if needed,.env,uv sync,npm installif needed), ensure vocab, run tests, start both, open browser - After a fresh start: stream live backend logs (
Ctrl+Cpauses the tail — services stay up)
App URL when ready:
👉 http://127.0.0.1:5173 (VHectorLab 3D — Magic Workbench chrome)
- Pause live logs:
Ctrl+C→ Enter returns to the menu; Ctrl+C again exits the panel (services keep running) - Stop services: option
10only (Ctrl+C never stops the stack)
First run can take a while: it may download Homebrew/Node/
uv, Python packages, and the embedding model. Re-running option 1 while the stack is already healthy will not bounce the servers or re-run tests.
| Tool | Role | If missing on macOS |
|---|---|---|
| uv | Python deps / run backend | Installed via official uv installer |
| Node.js + npm | Frontend (Vite / Vitest) | Installed via Homebrew (brew install node) |
| Homebrew | Used only to install Node if needed | Installed from brew.sh |
.env |
Runtime config | Copied from .env.example |
| Backend deps | FastAPI / PyTorch stack | uv sync --extra dev in backend/ |
| Frontend deps | Three.js / Vite | npm install when node_modules is absent |
| Docker Desktop | Optional — only for option 7 (HF Spaces image build) | Not installed by option 1. Option 7 checks Docker; on macOS it can install the Docker Desktop cask via Homebrew and asks you to start the app |
Daily local use (option 1) does not need Docker Desktop — only uv + Node/npm (+ network).
You do not need to install uv or Node by hand on a typical Mac — option 1 handles that. You do need network access and (for Homebrew) permission to install software.
Install Docker Desktop for Mac if you want to build the Hugging Face Spaces image locally. After install, open Docker Desktop and wait until the engine is running (whale icon steady), then use option 7.
Option 8 publishes a Docker Space on cpu-basic via the hf CLI. It injects deploy/hf/space-frontmatter.yml into the Space README at push time (GitHub README.md stays clean) and does not require Docker Desktop locally.
| Option | What it does |
|---|---|
| 1 | Deploy/start: idempotent — if both healthy, only open browser; else prereqs→tests→start (no Docker) |
| 2 | Backend only (:8000) — skip if already healthy; refuse if sick |
| 3 | System heartbeat / health check |
| 4 | Frontend unit tests (Vitest) |
| 5 | Backend unit tests (pytest) |
| 6 | Vocabulary: load a custom file or generate N words |
| 7 | Build HF Spaces Docker image locally (torch CPU · optional :7860 smoke) |
| 8 | Publish HF Space: inject deploy/hf/space-frontmatter.yml into README at push (GitHub README stays clean) |
| 9 | View backend logs |
| 10 | Stop / clean services (always kills; not idempotent) |
| 11 | Select Embedding Model / Profile (catalog · rebuild NPZ · restart backend) |
| 12 | Dump Context & Codebase to TXT (vhectorlab-context.txt for AI assistant analysis) |
| 0 | Exit |
Copy .env.example → .env (option 1 does this if .env is missing). Common keys:
| Variable | Default | Description |
|---|---|---|
HOST / PORT |
127.0.0.1 / 8000 |
Backend listen address |
MODEL_NAME |
all-mpnet-base-v2 |
Embedding model |
VOCAB_PATH |
public/vocab.txt |
App vocabulary file (use public/vocab_en_es.txt for EN∪ES) |
VITE_API_BASE_URL |
/api |
Browser API base URL |
VITE_SHOW_CAM_POSE |
false |
Live camera POS/ROT overlay (debug) |
VITE_AMIGA_PEN_0…_7 |
MagicWB pens | Workbench theme palette pens (#RRGGBB) |
VITE_AMIGA_BG / _FG / _ACCENT |
#222222 / #F0F0F0 / #3B67A2 |
Page/panel bg, text, titlebar accent |
Default public/vocab.txt is English-only. For multilingual Arithmetic/Compare neighbors:
uv run python scripts/merge_vocab_en_es.py
# → public/vocab_en_es.txt (~10k EN ∪ ES seed; includes king/rey … cat/gato)Set VOCAB_PATH=public/vocab_en_es.txt, then regenerate embeddings (scripts/precompute_vocab_embeddings.py or setup.sh option 11). Languages beyond EN+ES are out of scope for now.
From ./setup.sh → 11. Select Embedding Model / Profile: pick P# / M#, stage .env, rebuild vocab_embeddings.npz (EN∪ES), restart backend, print /health. On failure the previous .env is restored. HF Space options 7/8 are unchanged.
Default .env.example keeps all-mpnet-base-v2 (EN baseline). Switch to local-comfort / local-full via option 11 when you want multilingual.
Cross-lingual smoke (after option 11, non-blocking):
uv run --directory backend python ../scripts/smoke_crosslingual_cosine.py
uv run --directory backend python ../scripts/smoke_crosslingual_cosine.py --profile local-comfort --include-fr
# Fail only if mean EN↔ES cosine is soft-low:
uv run --directory backend python ../scripts/smoke_crosslingual_cosine.py --strict --threshold 0.35Only if you prefer not to use setup.sh (still assumes macOS + tools already available):
# Backend
cd backend
uv sync --extra dev
uv run python -m server
# Frontend (another terminal, repo root)
npm install
npx vite --port 5173 --host 127.0.0.1| Symptom | What to check |
|---|---|
| Unsupported platform warning | You are not on Darwin/macOS — unsupported; adapt paths/package managers yourself |
| Homebrew install asks for a password | Normal on first install; approve locally |
uv / npm still missing after option 1 |
Open a new terminal (PATH refresh), then re-run ./setup.sh |
| Backend tests slow / fail on first run | Model download needs network; wait and retry |
| Browser does not open | Open http://127.0.0.1:5173 manually |
| Port already in use / option 1 says sick | Option 1 now recycles automatically. Or use option 10, then start again |
| Option 1 restarts everything every time | It should not when both are healthy — report a bug if it still kills/relaunches a healthy stack |
| Option 7 fails / “Docker daemon not running” | Install/open Docker Desktop, wait until it is running, retry option 7 |
Failed to spawn: pytest / No such file |
Stale backend/.venv after renaming the folder. Option 1 now recreates it; or run rm -rf backend/.venv && cd backend && uv sync --extra dev |



