This document contains 37 pre-formatted GitHub issues ready to be copy-pasted into your repository. They are organized by component and categorized by difficulty level (including good first issue tags) to attract and guide contributors.
- Difficulty: Easy (
good first issue) - Recommended Labels:
webui,enhancement - Files involved: site/
- Description: Currently, the Web UI defaults to dark mode. We should add a persistent theme toggle button in the sidebar that allows users to switch between light and dark mode, storing the preference in
localStorage. - Steps to implement:
- Add a theme toggle button or icon (sun/moon) to the sidebar HTML/JS.
- Write CSS classes for light mode theme variables (background colors, text colors, borders).
- Implement a JS helper to toggle the
.light-modeclass on the<body>element and save it tolocalStorage.
- Difficulty: Medium
- Recommended Labels:
webui,enhancement - Files involved: site/
- Description: Telemetry reports hit rates numerically under responses. It would be highly visually appealing to draw a live, smooth line graph or radial progress indicator using SVG to display caching performance.
- Steps to implement:
- Create a container in the chat UI metadata panel for the cache chart.
- Use standard canvas or SVG to draw/update data points dynamically as telemetry JSON payload arrives via SSE.
- Add smooth CSS transitions to updates.
- Difficulty: Easy (
good first issue) - Recommended Labels:
webui,bug - Files involved: site/
- Description: When viewing the Web UI on mobile devices or narrow browser windows, the sidebar overlaps with the chat panel or gets truncated.
- Steps to implement:
- Add CSS media queries for viewport widths under
768px. - Hide the sidebar on narrow screens and implement a hamburger menu toggle button.
- Adjust padding and text sizes of speech bubbles for phone dimensions.
- Add CSS media queries for viewport widths under
- Difficulty: Medium
- Recommended Labels:
webui,enhancement - Files involved: site/
- Description: Users currently pull and remove models via CLI or the web UI select box. We should add a dedicated "Models" tab/view in the sidebar that lists all models in our catalog with status tags (
Ready/Not Installed), and click-to-download/remove buttons. - Steps to implement:
- Create a visual model list view in HTML/CSS.
- Add REST endpoints for
/api/models/pulland/api/models/removeinserver.py. - Connect frontend buttons to trigger fetches and display download progress bars.
- Difficulty: Easy
- Recommended Labels:
webui,enhancement - Files involved: site/
- Description: Add an option in the Web UI to download active chat transcripts as formatted Markdown (
.md) or text files. - Steps to implement:
- Create an "Export Chat" dropdown button near the chat header.
- Parse the active chat history DOM/state into markdown text.
- Generate a dynamic download file link using client-side JavaScript.
- Difficulty: Medium
- Recommended Labels:
tui,bug - Files involved: src/sparsify/cli.py
- Description: Resizing the terminal window during an active
sparsify runchat session can sometimes cause layout exceptions inprompt_toolkit. - Steps to implement:
- Hook into window resize events inside the
prompt_toolkitgeneration loop. - Recalculate terminal rows/columns and trigger a clean UI redraw.
- Handle exceptions caused by shrinking the window past UI boundary limits.
- Hook into window resize events inside the
- Difficulty: Easy (
good first issue) - Recommended Labels:
tui,enhancement - Files involved: src/sparsify/cli.py
- Description: Mouse scrolling is currently disabled in the full-screen terminal TUI. Enabling mouse scroll support would allow users to look back at past chat history.
- Steps to implement:
- Enable mouse support in
prompt_toolkitconfig parameters. - Bind mouse scroll events to scroll the text window viewport.
- Enable mouse support in
- Difficulty: Easy
- Recommended Labels:
tui,enhancement - Files involved: src/sparsify/cli.py
- Description: Users don't know the keys to exit, clear, or manage terminal chat. Pressing
?orCtrl+Hshould trigger a clean help pop-up listing all TUI shortcuts. - Steps to implement:
- Listen for help shortcuts inside TUI input handlers.
- Render a simple modal box centered in the console listing key combinations.
- Difficulty: Medium
- Recommended Labels:
tui,enhancement - Files involved: src/sparsify/cli.py
- Description: While Markdown is parsed, code blocks (e.g. ```python) lack syntax coloring inside the terminal speech bubbles.
- Steps to implement:
- Integrate
pygmentsorrich.syntaxstyling helper. - Detect code fences inside token reply streams and style code blocks on the fly before drawing.
- Integrate
- Difficulty: Easy (
good first issue) - Recommended Labels:
tui,bug - Files involved: src/sparsify/cli.py
- Description: If a generated response contains long links or uninterrupted lines (like file paths), the speech bubble breaks bounds and shifts terminal lines.
- Steps to implement:
- Add custom word wrapping or truncation boundaries based on window size.
- Wrap long paths cleanly inside bubbles using text-wrap rules.
- Difficulty: Easy
- Recommended Labels:
database,enhancement - Files involved: src/sparsify/storage/database.py
- Description: Add a database query command to dump historical runs, telemetry, and memory profile records into standard CSV or JSON files.
- Steps to implement:
- Implement a new CLI handler:
sparsify history --export <csv/json>. - Fetch all runs from the database and serialize fields cleanly.
- Implement a new CLI handler:
- Difficulty: Medium
- Recommended Labels:
database,maintenance - Files involved: src/sparsify/storage/database.py
- Description: Telemetry history accumulates quickly, bloating the database file size. We need automated purging or size limit warnings.
- Steps to implement:
- Add a setting for telemetry retention limits (e.g. 30 days).
- Write a cleanup query that runs once daily or at CLI startup.
- Run
VACUUMcommands periodically to keep database files compact.
- Difficulty: Hard
- Recommended Labels:
database,enhancement - Files involved: src/sparsify/storage/database.py
- Description: Currently, closing the server or terminal wipes the active chat context. We should save conversation history in SQLite to load them back on restart.
- Steps to implement:
- Create a
conversationsdatabase schema:id,session_title,model,created_at. - Save message pairs dynamically as they are processed.
- Render past sessions in the Web UI left sidebar.
- Create a
- Difficulty: Hard
- Recommended Labels:
core,performance - Files involved: src/sparsify/paging_torch/store.py
- Description: Loading experts sequentially introduces block latencies during model surgery. We should load experts using multiple thread workers.
- Steps to implement:
- Implement concurrent ranges reading via Python
concurrent.futures. - Overlap the retrieval of multiple routed experts in a single routing step.
- Measure speed differences across standard SSD hardware.
- Implement concurrent ranges reading via Python
- Difficulty: Hard
- Recommended Labels:
core,performance - Files involved: src/sparsify/paging_torch/surgery.py
- Description: The model routing decision is calculated one block layer ahead. We can use this prediction gap to prefetch the experts for layer
N+1while computing layerN. - Steps to implement:
- Hook into the forward pass calculation logic.
- Spawn a background thread worker to fetch the next block's experts asynchronously.
- Measure reduction in forward pass delays.
- Difficulty: Medium
- Recommended Labels:
core,bug - Files involved: src/sparsify/paging_torch/store.py
- Description: Opening file handles for every expert read block creates high system descriptor activity. We should pool and reuse file descriptors.
- Steps to implement:
- Keep a cache of open file handles for target safetensors shards.
- Close handles cleanly during server shut down or model unload.
- Difficulty: Hard
- Recommended Labels:
core,performance - Files involved: src/sparsify/backends/
- Description: Explore hybrid paging of GGUF formats directly from memory mapping, allowing CPU layers to remain un-allocated.
- Steps to implement:
- Analyze memory mappings for GGUF layouts.
- Add custom GGUF tensor paging hook handlers.
- Difficulty: Medium
- Recommended Labels:
core,performance - Files involved: src/sparsify/backends/pytorch_backend.py
- Description: When PyTorch runs on standard CPU backends, inference can be slow. We should investigate using
mklor Intel-optimized CPU runtimes. - Steps to implement:
- Detect Intel CPU extensions.
- Set thread configurations:
torch.set_num_threads()based on physical CPU cores.
- Difficulty: Medium
- Recommended Labels:
installer,enhancement - Files involved: install.sh
- Description: Non-macOS systems need PyTorch with CUDA support. The script should verify CUDA version and install the matching pip wheel version.
- Steps to implement:
- Check for
nvccornvidia-smiversion outputs. - Run pip install targeting the specific PyTorch CUDA wheel URL (e.g.
cu121/cu124).
- Check for
- Difficulty: Easy (
good first issue) - Recommended Labels:
installer,enhancement - Files involved: Dockerfile
- Description: Provide a Dockerfile and docker-compose script to deploy the Sparsify server inside a containerized host.
- Steps to implement:
- Write a clean Multi-stage Dockerfile setup.
- Mount the local model folder to prevent redundant downloads.
- Difficulty: Medium
- Recommended Labels:
api,enhancement - Files involved: src/sparsify/runtime/server.py
- Description: Allow external vector search software (like Chroma or Qdrant) to connect directly to Sparsify.
- Steps to implement:
- Add
/v1/embeddingsPOST route. - Feed tokens to the model backbone, extract the hidden state, and return the vector JSON.
- Add
- Difficulty: Medium
- Recommended Labels:
api,security - Files involved: src/sparsify/runtime/server.py
- Description: If the API is exposed on local networks, we need authentication.
- Steps to implement:
- Add an optional API Key setting
SPARSIFY_API_KEY. - Write request checking middleware that blocks unauthorized calls.
- Add an optional API Key setting
- Difficulty: Easy (
good first issue) - Recommended Labels:
documentation - Files involved: docs/
- Description: Guide Windows developers on setting up GPU-passthrough CUDA drivers inside WSL2.
- Steps to implement:
- Create
docs/WSL2_SETUP.md. - Outline step-by-step commands for WSL setup.
- Create
- Difficulty: Easy
- Recommended Labels:
documentation - Files involved: docs/
- Description: Translate README and instructions into popular languages (Spanish, Chinese, Japanese) to grow global adoption.
- Steps to implement:
- Create language-specific docs files.
- Link translations in the main README.
- Difficulty: Easy (
good first issue) - Recommended Labels:
documentation - Files involved: CONTRIBUTING.md
- Description: Prepare coding style checks, tests setup instruction, and pull request checklist template.
- Steps to implement:
- Update contribution documentation with development environment check instructions.
- Add standard templates under
.github/PULL_REQUEST_TEMPLATE.md.
Sparsify's memory story extends beyond MoE LLMs, but the mechanism changes per architecture: dense diffusion transformers fire every weight on every denoising step (per-step weight paging can only thrash), so the wins are stage residency (text encoder → DiT → VAE never run concurrently), 4-bit quantization at load, and — for timestep-MoE video models like Wan2.2 A14B — one expert swap per generation, the best possible SSD-paging access pattern.
- Difficulty: Easy (
good first issue) - Recommended Labels:
multimodal,verification - Files involved: src/sparsify/backends/image_backend.py, src/sparsify/runtime/model_registry.py
- Description: The mflux path is wired but honestly flagged
tested: False. Runsparsify pull flux:schnellandsparsify imagine flux:schnell "a lighthouse at dusk"on Apple Silicon, record peak memory / duration / output quality, pin the working mflux version range inpyproject.toml, and flip the catalog flag with your measurements in the PR. - Steps to implement:
- Accept the FLUX license on HuggingFace and pull the model.
- Run generation at 1024x1024 / 4 steps; capture
peak_memory_gbfrom the CLI output. - Fix any mflux API drift in
MFluxImageBackend(theModelConfig/Configimport surface moves between versions). - Update
testedand add measurements todocs/measurements/.
- Difficulty: Hard
- Recommended Labels:
multimodal,core-paging,memory - Files involved: src/sparsify/backends/image_backend.py
- Description: A diffusion pipeline's stages never run concurrently: the text encoder (T5-XXL alone is ~9.5 GB fp16) runs once, then the DiT loops, then the VAE decodes. Loading stages on demand and evicting them after use makes peak memory the largest stage instead of the sum — FLUX in roughly 8 GB. This is Sparsify's core moto applied at stage granularity.
- Steps to implement:
- Encode the prompt, then free the text encoder before instantiating the DiT.
- Free DiT weights before VAE decode.
- Report per-stage peak memory in
ImageGenerationResult.metadata. - Cache the encoded prompt so repeated generations with the same prompt skip the text-encoder load entirely.
- Difficulty: Hard
- Recommended Labels:
multimodal,core-paging,flagship - Files involved: src/sparsify/backends/, src/sparsify/runtime/model_registry.py
- Description: Wan2.2 T2V A14B is a two-expert timestep-MoE: a high-noise expert denoises early steps, a low-noise expert finishes. Only one expert is ever active, and the switch happens once per generation — the ideal SSD-paging access pattern (contrast with per-token LLM expert paging). Target: a 27B-parameter video model in a 14B-model memory footprint. The catalog already flags this entry
timestep_moe: True. - Steps to implement:
- Load only the high-noise expert at start (mmap from the Sparsify models dir).
- At the timestep boundary, free it and page in the low-noise expert.
- Add tiled VAE decode (see issue 30) — video latents make activations the second memory cliff.
- Record swap latency and peak RSS; compare against loading both experts.
- Difficulty: Hard
- Recommended Labels:
multimodal,enhancement - Files involved: src/sparsify/backends/image_backend.py, src/sparsify/runtime/server.py
- Description: Video entries are cataloged
pull-onlytoday and the server returns an honest 501. Wire a PyTorch/diffusers engine (MPS on Apple Silicon, CUDA elsewhere) for one small model first —wan:2.1-1.3borltx:video— behind the existingengine: "diffusers"dispatch inget_image_backend(). - Steps to implement:
- Implement
DiffusersVideoBackendwithload_model/generate_video/unload_model. - Add a
/v1/videos/generationsendpoint returning MP4 bytes (base64) with duration/steps/peak-memory telemetry. - Use
enable_model_cpu_offload()as the baseline memory strategy; document measured peak RSS.
- Implement
- Difficulty: Medium
- Recommended Labels:
multimodal,memory - Files involved: src/sparsify/backends/
- Description: For video models, weights are only half the memory problem — decoding a 5-second 720p latent in one VAE pass allocates tens of GB of activations. Decode in spatial tiles and temporal chunks with overlap blending so activation memory stays bounded regardless of clip length.
- Steps to implement:
- Split the latent into overlapping tiles/chunks sized by a memory budget.
- Decode sequentially, blend overlaps, stitch the output.
- Expose the budget as a config knob defaulting to a safe fraction of system RAM.
- Difficulty: Medium
- Recommended Labels:
multimodal,enhancement - Files involved: src/sparsify/backends/image_backend.py
- Description:
sd:3.5-medium/sd:3.5-largeare cataloged withengine: "diffusionkit"but raiseImageEngineNotWired. Implement the backend with 4-bit/8-bit quantization options and register it inget_image_backend(). - Steps to implement:
- Add a
DiffusionKitImageBackendmirroringMFluxImageBackend's interface. - Handle the gated-repo error path with the same actionable message
pullprints. - Add an optional dependency group
image-sdinpyproject.toml.
- Add a
- Difficulty: Hard
- Recommended Labels:
multimodal,research - Files involved: src/sparsify/backends/, src/sparsify/runtime/
- Description: Janus-Pro generates images as discrete tokens through a normal LLM decoder — which means future MoE variants of this family would ride Sparsify's existing expert pager unchanged. Wire generation (prompt → image tokens → VQ decode → PNG) via transformers/MPS or an MLX port, and document which pieces the pager already covers.
- Steps to implement:
- Implement token-based generation with the model's official generation recipe (CFG weight, parallel token count).
- Decode image tokens with the model's VQ detokenizer.
- Benchmark tokens/sec and peak memory; note expert-paging applicability in the PR.
- Difficulty: Medium
- Recommended Labels:
webui,multimodal,enhancement - Files involved: site/, src/sparsify/runtime/webui.py
- Description: The server now exposes
POST /v1/images/generations(b64_json + telemetry). Add an "Imagine" view: prompt box, size/steps/seed controls, generated image rendered inline with a download button, and the measuredduration_ms/peak_memory_gbshown under the result — memory honesty is the product. - Steps to implement:
- Add the tab and form; POST to the endpoint; render the base64 PNG.
- Show a step-progress placeholder while waiting (the request blocks until done).
- Display returned telemetry under the image, styled like chat telemetry.
- Difficulty: Medium
- Recommended Labels:
api,multimodal,enhancement - Files involved: src/sparsify/runtime/server.py, src/sparsify/backends/image_backend.py
- Description: A FLUX generation takes tens of seconds and a video generation minutes; the images endpoint currently blocks silently. Add
"stream": truesupport that emits SSE events per denoising step ({"step": 7, "total": 25}), optionally with a low-res latent preview every K steps, then the final b64 payload. - Steps to implement:
- Add a per-step callback hook to the image backend.
- Emit SSE chunks in the images handler mirroring the chat streaming format.
- Consume the events in the Web UI progress bar (pairs with issue 33).
- Difficulty: Easy (
good first issue) - Recommended Labels:
cli,multimodal,good first issue - Files involved: src/sparsify/cli.py
- Description:
sparsify imaginecurrently requires a model argument and writessparsify-image.pngin the CWD. With no arguments it should list pulled image models to pick from, default output into~/.sparsify/gallery/<timestamp>-<slug>.png, and print the path. - Steps to implement:
- Reuse the
_pick_model_interactivelypattern filtered tomodality != "text". - Create the gallery dir on first use; slugify the first ~6 prompt words.
- Add
--opento reveal the result in Finder/xdg-open.
- Reuse the
- Difficulty: Medium
- Recommended Labels:
multimodal,performance,storage - Files involved: src/sparsify/backends/image_backend.py, src/sparsify/runtime/model_registry.py
- Description: mflux quantizes bf16 weights to 4-bit on every load — minutes of wasted work and a 33.7 GB read for FLUX each time. Save the quantized model to the models dir on first load (mflux supports saving), register it, and load the 4-bit artifact directly afterwards (~9 GB read). Also protects the SSD from repeated large reads, consistent with the project's SSD-wear stance.
- Steps to implement:
- On first load, save the quantized pipeline under
<models_dir>/<repo>--4bit/. - Prefer the quantized artifact in
load_modelwhen present. - Add
sparsify inspectawareness so both artifacts show with sizes.
- On first load, save the quantized pipeline under
- Difficulty: Easy (
good first issue) - Recommended Labels:
documentation,multimodal - Files involved: docs/
- Description: Document why the LLM expert pager doesn't apply to dense DiTs, what does apply (stage residency, quantize-at-load, timestep-expert paging, tiled VAE), the honest support matrix (wired / pull-only / planned), and how to add a new engine behind
get_image_backend(). - Steps to implement:
- Write
docs/multimodal.mdcovering the mechanisms above with the catalog table. - Link it from README and the models table footer.
- Write