13
stars
48
commits
2
linked in READMEs
Jun 11, 2026
updated
Embedding Atlas is an open-source library from Apple for creating interactive, browser-based visualizations of embedding spaces. It renders millions of data points with WebGPU acceleration, supports real-time search and filtering, and automatically generates cluster labels.
These scripts wrap Embedding Atlas to make it easy to go from a HuggingFace dataset to a deployed visualization. See open-library-atlas for a live example (2M books).

| Script | Description | Best for |
|---|---|---|
atlas-e2e.py | End-to-end: dataset to deployed Space (experimental) | One-command pipeline |
atlas-build-gpu.py | GPU atlas build with cuml.accel UMAP | Running as an HF Job |
atlas-deploy.py | Deploy a Space from bucket data | Deploying existing builds |
atlas-export.py | All-in-one static export | Small datasets (<10GB) |
atlas-export-remote.py | Static export with remote data | Medium datasets |
The new pipeline uses Storage Buckets + Jobs + Spaces for large-scale visualizations:
atlas-e2e.py (local orchestrator)
│
├─ 1. Creates Storage Bucket
│
├─ 2. Submits GPU Job (atlas-build-gpu.py)
│ • Embeds text/images on GPU
│ • UMAP via cuml.accel (~50x faster)
│ • Writes parquet to bucket
│
└─ 3. Deploys Docker Space (atlas-deploy.py)
• Mounts bucket (read-only)
• Serves embedding-atlas in server mode
• Server-side DuckDB (not browser WASM)
# One command: dataset → deployed Space
uv run atlas-e2e.py stanfordnlp/imdb \
--text text --split train \
--name imdb-atlas --sample 50000
# 1. Build atlas on GPU (runs as HF Job)
# (bucket mounts at /output — Jobs reserves /data for the script artifact)
hf jobs uv run --flavor a100-large \
-v hf://buckets/user/atlas-data:/output \
-s HF_TOKEN --timeout 2h \
atlas-build-gpu.py my-org/my-dataset \
--text text --name my-atlas --sample 1000000
# 2. Deploy Space from bucket
uv run atlas-deploy.py \
--name my-atlas \
--bucket user/atlas-data \
--space-id user/my-atlas-viz
# Prep: filter and add categories with DuckDB
hf jobs uv run --flavor cpu-upgrade \
-v hf://buckets/user/atlas-data:/output \
-s HF_TOKEN \
open-library-prep.py --output /output/books/books.parquet
# Build: embed the prepped data
hf jobs uv run --flavor a100-large \
-v hf://buckets/user/atlas-data:/output \
-s HF_TOKEN --timeout 2h \
atlas-build-gpu.py /output/books/books.parquet \
--text title --name books-atlas --sample 2000000
# Deploy
uv run atlas-deploy.py --name books-atlas --bucket user/atlas-data
The build script uses cuml.accel for zero-code-change GPU acceleration of UMAP. No changes to embedding-atlas needed — just an environment variable.
| Dataset | Rows | Time (A100) | Cost |
|---|---|---|---|
| IMDB | 5K | ~1 min | $0.04 |
| TinyStories | 1M | ~20 min | $0.83 |
| Open Library | 2M | ~40 min | $1.67 |
For comparison: CPU UMAP on 250K rows took >2 hours.
uv run atlas-export.py stanfordnlp/imdb --space-name my-imdb-viz
uv run atlas-export-remote.py stanfordnlp/imdb \
--space-name my-imdb-viz \
--data-repo my-imdb-data
# Custom embedding model with sampling
uv run atlas-export-remote.py wikipedia \
--space-name wiki-viz \
--data-repo wiki-atlas-data \
--model nomic-ai/nomic-embed-text-v1.5 \
--text-column text \
--sample 50000
# Visualize image datasets with CLIP
uv run atlas-export-remote.py food101 \
--space-name food-atlas \
--data-repo food-atlas-data \
--image-column image \
--text-column label \
--sample 5000
# If you already have embeddings in your dataset
uv run atlas-export.py my-dataset-with-embeddings \
--space-name my-viz \
--no-compute-embeddings \
--x-column umap_x \
--y-column umap_y
# Use an atlas export ZIP you already have
uv run atlas-export-remote.py \
--from-export atlas_export.zip \
--space-name my-viz \
--data-repo my-data
# Use a glob pattern to combine multiple parquet shards
hf jobs uv run --flavor a10g-small -s HF_TOKEN \
https://huggingface.co/datasets/uv-scripts/build-atlas/raw/main/atlas-export-remote.py \
--glob "hf://datasets/HuggingFaceFW/finephrase/faq/*.parquet" \
--glob-max-shards 10 \
--space-name finephrase-atlas --data-repo finephrase-data \
--text-column text --sample 50000
# Pass several parquet URLs directly as inputs
hf jobs uv run --flavor t4-small -s HF_TOKEN \
https://huggingface.co/datasets/uv-scripts/build-atlas/raw/main/atlas-export-remote.py \
https://huggingface.co/datasets/my-org/my-data/resolve/main/shard-0.parquet \
https://huggingface.co/datasets/my-org/my-data/resolve/main/shard-1.parquet \
https://huggingface.co/datasets/my-org/my-data/resolve/main/shard-2.parquet \
--space-name my-atlas --data-repo my-data \
--text-column text --sample 50000
# Lance datasets work out of the box (pylance is included)
hf jobs uv run --flavor a100-large -s HF_TOKEN \
https://huggingface.co/datasets/uv-scripts/build-atlas/raw/main/atlas-export-remote.py \
librarian-bots/arxiv-cs-papers-lance \
--space-name arxiv-atlas --data-repo arxiv-data \
--text-column abstract
# Run on HF Jobs with GPU — the recommended way for large datasets
hf jobs uv run --flavor t4-small -s HF_TOKEN \
https://huggingface.co/datasets/uv-scripts/build-atlas/raw/main/atlas-export-remote.py \
stanfordnlp/imdb \
--space-name imdb-viz \
--data-repo imdb-atlas-data \
--sample 10000
# With a bigger GPU for faster processing
hf jobs uv run --flavor a10g-large -s HF_TOKEN \
https://huggingface.co/datasets/uv-scripts/build-atlas/raw/main/atlas-export-remote.py \
your-dataset \
--space-name your-atlas \
--data-repo your-atlas-data \
--text-column output \
--sample 50000
Available GPU flavors: t4-small, t4-medium, l4x1, a10g-small, a10g-large, a100-large.
For large datasets, add --timeout 7200 (2 hours) to the hf jobs command.
| Option | Description | Default |
|---|---|---|
dataset_id | HuggingFace dataset to visualize | Required |
--space-name | Name for your Space | Required |
--model | Embedding model to use | Auto-selected |
--text-column | Column containing text | "text" |
--image-column | Column containing images | None |
--sample | Number of samples to visualize | All |
--batch-size | Batch size for embedding generation | 32 (text), 16 (images) |
--split | Dataset split to use | "train" |
| Option | Description | Default |
|---|---|---|
inputs | Dataset ID(s) or parquet URL(s) — positional, supports multiple | Required* |
--space-name | Name for your Space | Required |
--data-repo | Name for the HF dataset repo (stores parquet) | Required |
--glob | HF glob pattern for parquet shards | None |
--glob-max-shards | Randomly sample N shards from glob matches | All |
--model | Embedding model to use | Auto-selected |
--text-column | Column containing text | "text" |
--image-column | Column containing images | None |
--sample | Number of samples to visualize | All |
--split | Dataset split to use | "train" |
--trust-remote-code | Trust remote code in datasets/models | False |
--from-export | Use an existing atlas export ZIP | None |
--organization | HF org for repos (default: your username) | None |
--private | Make both Space and dataset private | False |
--private-space | Make only the Space private | False |
--private-data | Make only the dataset private | False |
--hf-token | Explicit HF token (or set HF_TOKEN env) | Auto |
--output-dir | Local output directory | Temp dir |
--local-only | Prepare locally without deploying | False |
*Either inputs, --glob, or --from-export is required.
Run either script without arguments to see all options.
--export-metadata pointing to the remote parquet URL--space-name/--data-repo updates in place (no need to delete first)pylance is bundled as a dependencya10g-large or a100-large for many shards--glob-max-shards reasonable (5-30) to avoid OOM on smaller GPU flavorsBuilt on Embedding Atlas by Apple (>= 0.19.1). GPU UMAP via cuML.
Part of the UV Scripts collection
38 commits
4 commits
3 commits
2 commits
13
stars
48
commits
2
linked in READMEs
Jun 11, 2026
updated
Embedding Atlas is an open-source library from Apple for creating interactive, browser-based visualizations of embedding spaces. It renders millions of data points with WebGPU acceleration, supports real-time search and filtering, and automatically generates cluster labels.
These scripts wrap Embedding Atlas to make it easy to go from a HuggingFace dataset to a deployed visualization. See open-library-atlas for a live example (2M books).

| Script | Description | Best for |
|---|---|---|
atlas-e2e.py | End-to-end: dataset to deployed Space (experimental) | One-command pipeline |
atlas-build-gpu.py | GPU atlas build with cuml.accel UMAP | Running as an HF Job |
atlas-deploy.py | Deploy a Space from bucket data | Deploying existing builds |
atlas-export.py | All-in-one static export | Small datasets (<10GB) |
atlas-export-remote.py | Static export with remote data | Medium datasets |
The new pipeline uses Storage Buckets + Jobs + Spaces for large-scale visualizations:
atlas-e2e.py (local orchestrator)
│
├─ 1. Creates Storage Bucket
│
├─ 2. Submits GPU Job (atlas-build-gpu.py)
│ • Embeds text/images on GPU
│ • UMAP via cuml.accel (~50x faster)
│ • Writes parquet to bucket
│
└─ 3. Deploys Docker Space (atlas-deploy.py)
• Mounts bucket (read-only)
• Serves embedding-atlas in server mode
• Server-side DuckDB (not browser WASM)
# One command: dataset → deployed Space
uv run atlas-e2e.py stanfordnlp/imdb \
--text text --split train \
--name imdb-atlas --sample 50000
# 1. Build atlas on GPU (runs as HF Job)
# (bucket mounts at /output — Jobs reserves /data for the script artifact)
hf jobs uv run --flavor a100-large \
-v hf://buckets/user/atlas-data:/output \
-s HF_TOKEN --timeout 2h \
atlas-build-gpu.py my-org/my-dataset \
--text text --name my-atlas --sample 1000000
# 2. Deploy Space from bucket
uv run atlas-deploy.py \
--name my-atlas \
--bucket user/atlas-data \
--space-id user/my-atlas-viz
# Prep: filter and add categories with DuckDB
hf jobs uv run --flavor cpu-upgrade \
-v hf://buckets/user/atlas-data:/output \
-s HF_TOKEN \
open-library-prep.py --output /output/books/books.parquet
# Build: embed the prepped data
hf jobs uv run --flavor a100-large \
-v hf://buckets/user/atlas-data:/output \
-s HF_TOKEN --timeout 2h \
atlas-build-gpu.py /output/books/books.parquet \
--text title --name books-atlas --sample 2000000
# Deploy
uv run atlas-deploy.py --name books-atlas --bucket user/atlas-data
The build script uses cuml.accel for zero-code-change GPU acceleration of UMAP. No changes to embedding-atlas needed — just an environment variable.
| Dataset | Rows | Time (A100) | Cost |
|---|---|---|---|
| IMDB | 5K | ~1 min | $0.04 |
| TinyStories | 1M | ~20 min | $0.83 |
| Open Library | 2M | ~40 min | $1.67 |
For comparison: CPU UMAP on 250K rows took >2 hours.
uv run atlas-export.py stanfordnlp/imdb --space-name my-imdb-viz
uv run atlas-export-remote.py stanfordnlp/imdb \
--space-name my-imdb-viz \
--data-repo my-imdb-data
# Custom embedding model with sampling
uv run atlas-export-remote.py wikipedia \
--space-name wiki-viz \
--data-repo wiki-atlas-data \
--model nomic-ai/nomic-embed-text-v1.5 \
--text-column text \
--sample 50000
# Visualize image datasets with CLIP
uv run atlas-export-remote.py food101 \
--space-name food-atlas \
--data-repo food-atlas-data \
--image-column image \
--text-column label \
--sample 5000
# If you already have embeddings in your dataset
uv run atlas-export.py my-dataset-with-embeddings \
--space-name my-viz \
--no-compute-embeddings \
--x-column umap_x \
--y-column umap_y
# Use an atlas export ZIP you already have
uv run atlas-export-remote.py \
--from-export atlas_export.zip \
--space-name my-viz \
--data-repo my-data
# Use a glob pattern to combine multiple parquet shards
hf jobs uv run --flavor a10g-small -s HF_TOKEN \
https://huggingface.co/datasets/uv-scripts/build-atlas/raw/main/atlas-export-remote.py \
--glob "hf://datasets/HuggingFaceFW/finephrase/faq/*.parquet" \
--glob-max-shards 10 \
--space-name finephrase-atlas --data-repo finephrase-data \
--text-column text --sample 50000
# Pass several parquet URLs directly as inputs
hf jobs uv run --flavor t4-small -s HF_TOKEN \
https://huggingface.co/datasets/uv-scripts/build-atlas/raw/main/atlas-export-remote.py \
https://huggingface.co/datasets/my-org/my-data/resolve/main/shard-0.parquet \
https://huggingface.co/datasets/my-org/my-data/resolve/main/shard-1.parquet \
https://huggingface.co/datasets/my-org/my-data/resolve/main/shard-2.parquet \
--space-name my-atlas --data-repo my-data \
--text-column text --sample 50000
# Lance datasets work out of the box (pylance is included)
hf jobs uv run --flavor a100-large -s HF_TOKEN \
https://huggingface.co/datasets/uv-scripts/build-atlas/raw/main/atlas-export-remote.py \
librarian-bots/arxiv-cs-papers-lance \
--space-name arxiv-atlas --data-repo arxiv-data \
--text-column abstract
# Run on HF Jobs with GPU — the recommended way for large datasets
hf jobs uv run --flavor t4-small -s HF_TOKEN \
https://huggingface.co/datasets/uv-scripts/build-atlas/raw/main/atlas-export-remote.py \
stanfordnlp/imdb \
--space-name imdb-viz \
--data-repo imdb-atlas-data \
--sample 10000
# With a bigger GPU for faster processing
hf jobs uv run --flavor a10g-large -s HF_TOKEN \
https://huggingface.co/datasets/uv-scripts/build-atlas/raw/main/atlas-export-remote.py \
your-dataset \
--space-name your-atlas \
--data-repo your-atlas-data \
--text-column output \
--sample 50000
Available GPU flavors: t4-small, t4-medium, l4x1, a10g-small, a10g-large, a100-large.
For large datasets, add --timeout 7200 (2 hours) to the hf jobs command.
| Option | Description | Default |
|---|---|---|
dataset_id | HuggingFace dataset to visualize | Required |
--space-name | Name for your Space | Required |
--model | Embedding model to use | Auto-selected |
--text-column | Column containing text | "text" |
--image-column | Column containing images | None |
--sample | Number of samples to visualize | All |
--batch-size | Batch size for embedding generation | 32 (text), 16 (images) |
--split | Dataset split to use | "train" |
| Option | Description | Default |
|---|---|---|
inputs | Dataset ID(s) or parquet URL(s) — positional, supports multiple | Required* |
--space-name | Name for your Space | Required |
--data-repo | Name for the HF dataset repo (stores parquet) | Required |
--glob | HF glob pattern for parquet shards | None |
--glob-max-shards | Randomly sample N shards from glob matches | All |
--model | Embedding model to use | Auto-selected |
--text-column | Column containing text | "text" |
--image-column | Column containing images | None |
--sample | Number of samples to visualize | All |
--split | Dataset split to use | "train" |
--trust-remote-code | Trust remote code in datasets/models | False |
--from-export | Use an existing atlas export ZIP | None |
--organization | HF org for repos (default: your username) | None |
--private | Make both Space and dataset private | False |
--private-space | Make only the Space private | False |
--private-data | Make only the dataset private | False |
--hf-token | Explicit HF token (or set HF_TOKEN env) | Auto |
--output-dir | Local output directory | Temp dir |
--local-only | Prepare locally without deploying | False |
*Either inputs, --glob, or --from-export is required.
Run either script without arguments to see all options.
--export-metadata pointing to the remote parquet URL--space-name/--data-repo updates in place (no need to delete first)pylance is bundled as a dependencya10g-large or a100-large for many shards--glob-max-shards reasonable (5-30) to avoid OOM on smaller GPU flavorsBuilt on Embedding Atlas by Apple (>= 0.19.1). GPU UMAP via cuML.
Part of the UV Scripts collection
38 commits
4 commits
3 commits
2 commits