Spaces:
Sleeping
Sleeping
Update README.md
Browse files
README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
emoji: π§
|
| 4 |
colorFrom: indigo
|
| 5 |
colorTo: purple
|
|
@@ -9,18 +9,18 @@ pinned: false
|
|
| 9 |
license: apache-2.0
|
| 10 |
---
|
| 11 |
|
| 12 |
-
#
|
| 13 |
|
| 14 |
A self-contained Hugging Face **Docker Space** that downloads a GGUF quant of
|
| 15 |
-
[`
|
| 16 |
-
and serves it through a
|
|
|
|
| 17 |
[`llama-cpp-python`](https://github.com/abetlen/llama-cpp-python).
|
| 18 |
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
> audience β the model card recommends the same.
|
| 24 |
|
| 25 |
---
|
| 26 |
|
|
@@ -28,9 +28,9 @@ and serves it through a streaming Gradio chat UI, powered by
|
|
| 28 |
|
| 29 |
| File | Purpose |
|
| 30 |
|-------------------|-----------------------------------------------------------------------|
|
| 31 |
-
| `Dockerfile` | Multi-stage build:
|
| 32 |
| `requirements.txt`| Pure-Python runtime deps (`gradio`, `huggingface_hub`). |
|
| 33 |
-
| `app.py` | Downloads/caches the GGUF, loads it with `llama-cpp-python`, and serves
|
| 34 |
| `README.md` | This file (also the Space's metadata card, via the YAML frontmatter above). |
|
| 35 |
|
| 36 |
This repo is ready to push directly to a new **Docker** Space with no
|
|
@@ -46,17 +46,18 @@ end-to-end, which comes with real constraints worth knowing up front:
|
|
| 46 |
- **No persistent disk by default.** Model weights re-download on every
|
| 47 |
full restart/rebuild (see "Model caching" below) unless you pay for the
|
| 48 |
Persistent Storage add-on.
|
| 49 |
-
- **
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
- **Build minutes are shared/limited infrastructure**, so the Dockerfile
|
| 54 |
tries a prebuilt wheel for `llama-cpp-python` before ever compiling from
|
| 55 |
source (see "Technical notes" below) β this is the single biggest lever
|
| 56 |
for keeping first-time build time low on the free tier.
|
| 57 |
-
- If you outgrow any of this
|
| 58 |
-
CPU/GPU hardware tier, or add
|
| 59 |
-
|
|
|
|
| 60 |
|
| 61 |
## Deploying to Hugging Face Spaces
|
| 62 |
|
|
@@ -72,16 +73,17 @@ end-to-end, which comes with real constraints worth knowing up front:
|
|
| 72 |
cd <your-space-name>
|
| 73 |
cp /path/to/Dockerfile /path/to/requirements.txt /path/to/app.py /path/to/README.md .
|
| 74 |
git add .
|
| 75 |
-
git commit -m "Deploy
|
| 76 |
git push
|
| 77 |
```
|
| 78 |
|
| 79 |
-
5. The Space will build the Docker image (
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
|
|
|
| 85 |
|
| 86 |
No secrets or tokens are required for the default (public) repo. If you
|
| 87 |
point this at a **gated/private** GGUF repo, add an `HF_TOKEN` secret in the
|
|
@@ -98,20 +100,20 @@ touching any code:
|
|
| 98 |
|
| 99 |
| Variable | Default | Description |
|
| 100 |
|-----------------------|-------------------------------------------------------|--------------|
|
| 101 |
-
| `GGUF_REPO_ID` | `
|
| 102 |
| `GGUF_FILENAME` | *(empty = auto-select)* | Force an exact filename instead of auto-selecting by quant. |
|
| 103 |
| `PREFERRED_QUANT` | `Q4_K_M` | Preferred quantization. Falls back automatically (`Q4_K_S` β `Q5_K_M` β ... β smallest available `.gguf`) if not present. `mmproj` (vision) and `-MTP-` (speculative-decoding draft head) files are skipped by the auto-selector in favor of a plain text-chat quant. |
|
| 104 |
| `MODEL_CACHE_DIR` | `/data/models` | Local cache directory for downloaded model weights. |
|
| 105 |
| `HF_HOME` | `/data/hf_home` | Cache directory for Hub metadata. |
|
| 106 |
-
| `N_CTX` | `
|
| 107 |
-
| `N_THREADS` | `
|
| 108 |
| `N_BATCH` | `256` | Prompt processing batch size. |
|
| 109 |
-
| `MAX_NEW_TOKENS` | `
|
| 110 |
-
| `TEMPERATURE` | `0.
|
| 111 |
-
| `TOP_P` | `0.
|
| 112 |
-
| `TOP_K` | `
|
| 113 |
-
| `REPEAT_PENALTY` | `1.
|
| 114 |
-
| `SYSTEM_PROMPT` | *(
|
| 115 |
| `DOWNLOAD_MAX_RETRIES` | `5` | Retry attempts (exponential backoff) for the model download. |
|
| 116 |
|
| 117 |
---
|
|
@@ -135,27 +137,6 @@ a bug in this app. If you need the cache to survive restarts, enable
|
|
| 135 |
|
| 136 |
---
|
| 137 |
|
| 138 |
-
## Long context ("1M context") notes
|
| 139 |
-
|
| 140 |
-
The GGUF files in this repo ship with YaRN rope-scaling baked in for up to a
|
| 141 |
-
1,048,576-token context window. That is a *ceiling*, not something you get
|
| 142 |
-
for free on CPU:
|
| 143 |
-
|
| 144 |
-
- Free **CPU basic** Spaces (16GB RAM) can realistically handle a `Q4_K_M`
|
| 145 |
-
9B model with a context window in the **low thousands to ~16-32k tokens**,
|
| 146 |
-
depending on available RAM after the model weights are loaded.
|
| 147 |
-
- Attempting to set `N_CTX` far beyond what your Space's RAM allows will
|
| 148 |
-
cause the model load to fail or the container to be OOM-killed.
|
| 149 |
-
- If you need genuinely long context (hundreds of thousands of tokens),
|
| 150 |
-
you'll need a GPU Space or a machine with substantially more RAM β the
|
| 151 |
-
model card itself notes the full 1M window typically needs multi-GPU or
|
| 152 |
-
aggressive KV-cache offload even outside of CPU constraints.
|
| 153 |
-
|
| 154 |
-
`N_CTX` is fully configurable via the environment variable above so you can
|
| 155 |
-
tune it to whatever hardware tier you're running on.
|
| 156 |
-
|
| 157 |
-
---
|
| 158 |
-
|
| 159 |
## Local development (outside Docker)
|
| 160 |
|
| 161 |
```bash
|
|
@@ -170,8 +151,8 @@ python app.py
|
|
| 170 |
## Building/running the Docker image locally
|
| 171 |
|
| 172 |
```bash
|
| 173 |
-
docker build -t
|
| 174 |
-
docker run -it -p 7860:7860
|
| 175 |
# then open http://localhost:7860
|
| 176 |
```
|
| 177 |
|
|
@@ -202,16 +183,23 @@ docker run -it -p 7860:7860 qwythos-space
|
|
| 202 |
cores than it has RAM to back a fully parallel C++ build.
|
| 203 |
- **Chat template**: the `Llama` object is created without a hardcoded
|
| 204 |
`chat_format`, so `llama-cpp-python` auto-detects and applies the Jinja
|
| 205 |
-
chat template embedded in the GGUF's own metadata
|
| 206 |
-
|
| 207 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 208 |
- **Streaming**: implemented via `llm.create_chat_completion(..., stream=True)`,
|
| 209 |
-
yielding incrementally-growing text
|
| 210 |
-
token-by-token display.
|
| 211 |
- **GPU layers**: `n_gpu_layers=0` β this Space is CPU-only by design, matching
|
| 212 |
the free Spaces hardware tier.
|
| 213 |
- **File selection**: uses `huggingface_hub.HfApi().model_info(..., files_metadata=True)`
|
| 214 |
to inspect all files with sizes, filters out `mmproj` (vision projector)
|
| 215 |
and `-MTP-` (speculative decoding draft-head) variants by default, then
|
| 216 |
picks the smallest file matching `PREFERRED_QUANT`, falling back through
|
| 217 |
-
a quant-quality-ordered list if needed.
|
|
|
|
| 1 |
---
|
| 2 |
+
title: GGUF Chat
|
| 3 |
emoji: π§
|
| 4 |
colorFrom: indigo
|
| 5 |
colorTo: purple
|
|
|
|
| 9 |
license: apache-2.0
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# GGUF Chat (Docker Space)
|
| 13 |
|
| 14 |
A self-contained Hugging Face **Docker Space** that downloads a GGUF quant of
|
| 15 |
+
[`bartowski/google_gemma-3-2b-it-GGUF`](https://huggingface.co/bartowski/google_gemma-3-2b-it-GGUF)
|
| 16 |
+
and serves it through a Gradio chat UI β with a live download/load progress
|
| 17 |
+
bar on first request, then token-by-token streaming β powered by
|
| 18 |
[`llama-cpp-python`](https://github.com/abetlen/llama-cpp-python).
|
| 19 |
|
| 20 |
+
The default model is a small (~2B parameter) instruct model chosen
|
| 21 |
+
specifically to run comfortably on the **free CPU-basic Spaces tier**. Swap
|
| 22 |
+
in a different repo any time via the `GGUF_REPO_ID` environment variable β
|
| 23 |
+
no code changes needed.
|
|
|
|
| 24 |
|
| 25 |
---
|
| 26 |
|
|
|
|
| 28 |
|
| 29 |
| File | Purpose |
|
| 30 |
|-------------------|-----------------------------------------------------------------------|
|
| 31 |
+
| `Dockerfile` | Multi-stage build: tries a prebuilt CPU wheel for `llama-cpp-python` first, falling back to compiling it in a builder stage; ships a slim runtime image with no compilers. |
|
| 32 |
| `requirements.txt`| Pure-Python runtime deps (`gradio`, `huggingface_hub`). |
|
| 33 |
+
| `app.py` | Downloads/caches the GGUF, loads it with `llama-cpp-python`, and serves the Gradio UI (progress bar + streaming chat). |
|
| 34 |
| `README.md` | This file (also the Space's metadata card, via the YAML frontmatter above). |
|
| 35 |
|
| 36 |
This repo is ready to push directly to a new **Docker** Space with no
|
|
|
|
| 46 |
- **No persistent disk by default.** Model weights re-download on every
|
| 47 |
full restart/rebuild (see "Model caching" below) unless you pay for the
|
| 48 |
Persistent Storage add-on.
|
| 49 |
+
- **2 vCPUs, 16GB RAM.** `N_THREADS` defaults to `2` to match the actual
|
| 50 |
+
core count rather than over-subscribing; `N_CTX` defaults to a modest
|
| 51 |
+
`4096` tokens, well within what a ~1B `Q4_K_M` model needs on this
|
| 52 |
+
hardware.
|
| 53 |
- **Build minutes are shared/limited infrastructure**, so the Dockerfile
|
| 54 |
tries a prebuilt wheel for `llama-cpp-python` before ever compiling from
|
| 55 |
source (see "Technical notes" below) β this is the single biggest lever
|
| 56 |
for keeping first-time build time low on the free tier.
|
| 57 |
+
- If you outgrow any of this β a bigger model, longer context β the fixes
|
| 58 |
+
are all opt-in: upgrade to a paid CPU/GPU hardware tier, or add
|
| 59 |
+
Persistent Storage, and adjust `N_CTX`/`N_THREADS` accordingly. No code
|
| 60 |
+
changes required, since everything is environment-variable driven.
|
| 61 |
|
| 62 |
## Deploying to Hugging Face Spaces
|
| 63 |
|
|
|
|
| 73 |
cd <your-space-name>
|
| 74 |
cp /path/to/Dockerfile /path/to/requirements.txt /path/to/app.py /path/to/README.md .
|
| 75 |
git add .
|
| 76 |
+
git commit -m "Deploy GGUF chat Space"
|
| 77 |
git push
|
| 78 |
```
|
| 79 |
|
| 80 |
+
5. The Space will build the Docker image (typically well under a minute for
|
| 81 |
+
`llama-cpp-python` if a prebuilt wheel is available β see "Technical
|
| 82 |
+
notes" β otherwise 15-30+ minutes compiling from source) and then start
|
| 83 |
+
the container. On first chat message, `app.py` downloads the selected
|
| 84 |
+
GGUF file from the Hub and shows a live progress bar in the UI itself
|
| 85 |
+
(in addition to the Space's **Logs** tab).
|
| 86 |
+
6. Once the model finishes loading, replies stream in token-by-token.
|
| 87 |
|
| 88 |
No secrets or tokens are required for the default (public) repo. If you
|
| 89 |
point this at a **gated/private** GGUF repo, add an `HF_TOKEN` secret in the
|
|
|
|
| 100 |
|
| 101 |
| Variable | Default | Description |
|
| 102 |
|-----------------------|-------------------------------------------------------|--------------|
|
| 103 |
+
| `GGUF_REPO_ID` | `bartowski/google_gemma-3-2b-it-GGUF` | Hub repo to pull the GGUF from. |
|
| 104 |
| `GGUF_FILENAME` | *(empty = auto-select)* | Force an exact filename instead of auto-selecting by quant. |
|
| 105 |
| `PREFERRED_QUANT` | `Q4_K_M` | Preferred quantization. Falls back automatically (`Q4_K_S` β `Q5_K_M` β ... β smallest available `.gguf`) if not present. `mmproj` (vision) and `-MTP-` (speculative-decoding draft head) files are skipped by the auto-selector in favor of a plain text-chat quant. |
|
| 106 |
| `MODEL_CACHE_DIR` | `/data/models` | Local cache directory for downloaded model weights. |
|
| 107 |
| `HF_HOME` | `/data/hf_home` | Cache directory for Hub metadata. |
|
| 108 |
+
| `N_CTX` | `4096` | Context window (tokens) allocated at load time. Raise this if you swap in a model that needs more headroom and you have the RAM to back it. |
|
| 109 |
+
| `N_THREADS` | `2` | CPU threads for inference. Matches the free tier's 2 vCPUs by default; raise it if you upgrade hardware. |
|
| 110 |
| `N_BATCH` | `256` | Prompt processing batch size. |
|
| 111 |
+
| `MAX_NEW_TOKENS` | `899` | Max tokens generated per reply. |
|
| 112 |
+
| `TEMPERATURE` | `0.7` | Sampling temperature. |
|
| 113 |
+
| `TOP_P` | `0.9` | Nucleus sampling. |
|
| 114 |
+
| `TOP_K` | `40` | Top-k sampling. |
|
| 115 |
+
| `REPEAT_PENALTY` | `1.1` | Repetition penalty. |
|
| 116 |
+
| `SYSTEM_PROMPT` | *(a short "be concise, adapt to the request" prompt β see `app.py`)* | System prompt prepended to every conversation. Override to customize the assistant's behavior. |
|
| 117 |
| `DOWNLOAD_MAX_RETRIES` | `5` | Retry attempts (exponential backoff) for the model download. |
|
| 118 |
|
| 119 |
---
|
|
|
|
| 137 |
|
| 138 |
---
|
| 139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
## Local development (outside Docker)
|
| 141 |
|
| 142 |
```bash
|
|
|
|
| 151 |
## Building/running the Docker image locally
|
| 152 |
|
| 153 |
```bash
|
| 154 |
+
docker build -t gguf-chat-space .
|
| 155 |
+
docker run -it -p 7860:7860 gguf-chat-space
|
| 156 |
# then open http://localhost:7860
|
| 157 |
```
|
| 158 |
|
|
|
|
| 183 |
cores than it has RAM to back a fully parallel C++ build.
|
| 184 |
- **Chat template**: the `Llama` object is created without a hardcoded
|
| 185 |
`chat_format`, so `llama-cpp-python` auto-detects and applies the Jinja
|
| 186 |
+
chat template embedded in the GGUF's own metadata. This is what lets the
|
| 187 |
+
same `app.py` work correctly across different model families (Gemma,
|
| 188 |
+
Llama, Qwen, ...) if you change `GGUF_REPO_ID`, without hardcoding any
|
| 189 |
+
model-specific prompt formatting.
|
| 190 |
+
- **Progress bar UI**: the model downloads/loads lazily on the *first* chat
|
| 191 |
+
request rather than at container startup, and `app.py` streams a live
|
| 192 |
+
HTML progress bar (download %, then an animated layer-load indicator)
|
| 193 |
+
into the response pane while that happens, in addition to logging
|
| 194 |
+
progress to the Space's **Logs** tab. The layer-load bar is a smooth
|
| 195 |
+
"still working" animation rather than an exact per-layer readout, since
|
| 196 |
+
`llama-cpp-python`'s Python API doesn't expose real-time load progress.
|
| 197 |
- **Streaming**: implemented via `llm.create_chat_completion(..., stream=True)`,
|
| 198 |
+
yielding incrementally-growing text into the UI for token-by-token display.
|
|
|
|
| 199 |
- **GPU layers**: `n_gpu_layers=0` β this Space is CPU-only by design, matching
|
| 200 |
the free Spaces hardware tier.
|
| 201 |
- **File selection**: uses `huggingface_hub.HfApi().model_info(..., files_metadata=True)`
|
| 202 |
to inspect all files with sizes, filters out `mmproj` (vision projector)
|
| 203 |
and `-MTP-` (speculative decoding draft-head) variants by default, then
|
| 204 |
picks the smallest file matching `PREFERRED_QUANT`, falling back through
|
| 205 |
+
a quant-quality-ordered list if needed.
|