Commit ·
698156b
0
Parent(s):
PFlash release files
Browse files- .gitattributes +45 -0
- README.md +117 -0
- segment-probe-s3-line512.gguf +3 -0
- segment-probe.gguf +3 -0
.gitattributes
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
segment-probe-v13-t0.7-min32.gguf filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
segment-probe-v13-t0.8-min1.gguf filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
segment-probe-v13-t0.8-min32.gguf filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
segment-probe-v13-t0.8-min64.gguf filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
segment-probe-v14-t0.9-min1.gguf filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
segment-probe-v14-t0.9-min32.gguf filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
segment-probe-v14-t0.9-min64.gguf filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
segment-probe-v14.gguf filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
segment-probe.gguf filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
segment-probe-s3-line512.gguf filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: other
|
| 3 |
+
language:
|
| 4 |
+
- en
|
| 5 |
+
tags:
|
| 6 |
+
- lucebox
|
| 7 |
+
- pflash
|
| 8 |
+
- prefill-compression
|
| 9 |
+
- gguf
|
| 10 |
+
- qwen3.5
|
| 11 |
+
base_model: Qwen/Qwen3.5-0.8B
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# pflash-segment-probe
|
| 15 |
+
|
| 16 |
+
The segment probe of PFlash: it cuts a long prompt into whole structural units before the relevance head ranks them.
|
| 17 |
+
|
| 18 |
+
PFlash is Lucebox's prefill compression for long prompts. A small drafter, Qwen3.5-0.8B, reads the whole prompt
|
| 19 |
+
once, and three small components on its activations decide what the large reader model prefills:
|
| 20 |
+
1. [`Lucebox/pflash-segment-probe`](https://huggingface.co/Lucebox/pflash-segment-probe) cuts the prompt into
|
| 21 |
+
whole units (statements and definitions, sentences, records, chat turns, tool calls);
|
| 22 |
+
2. [`Lucebox/pflash-request-probe`](https://huggingface.co/Lucebox/pflash-request-probe) finds the request,
|
| 23 |
+
wherever it sits in the prompt;
|
| 24 |
+
3. [`Lucebox/pflash-scorer-head`](https://huggingface.co/Lucebox/pflash-scorer-head) ranks the units against that
|
| 25 |
+
request.
|
| 26 |
+
|
| 27 |
+
The highest-ranked units that fit the budget go to the reader in their original order, and the reader prefills
|
| 28 |
+
only those. All three read the same tap, the drafter's block-14 residual (`post_block14_residual_before_block15`),
|
| 29 |
+
from the same single pass.
|
| 30 |
+
|
| 31 |
+
## How it works
|
| 32 |
+
|
| 33 |
+
- **Architecture**: LayerNorm(1024) → Linear(1024, 256) → GELU → three linear rows, each with a 5-tap convolution
|
| 34 |
+
over its logit sequence plus the residual logit; about 263K parameters, 16 tensors. GGUF architecture
|
| 35 |
+
`segmentprobe`, schema `qwen3_5_0_8b_segment_probe_v2`.
|
| 36 |
+
- **Three outputs per token**:
|
| 37 |
+
- **unit**: a structural unit starts here. Units are the finest whole pieces: every statement, declaration,
|
| 38 |
+
definition, comment or decorator block at file or container scope in code; sentences in prose; records, chat
|
| 39 |
+
turns, diff hunks, tool calls and observations. Nothing inside a function body is a unit cut, so a kept unit is
|
| 40 |
+
never a truncated function.
|
| 41 |
+
- **container**: the enclosing region (class, file section, paragraph, session, assistant turn). Exported, not
|
| 42 |
+
used by the served configuration.
|
| 43 |
+
- **sub-unit**: a nested definition inside a body, used only to split units that are too long.
|
| 44 |
+
- **Segmentation** (settings in the GGUF): a cut where the unit score passes the threshold 0.8; cuts closer than
|
| 45 |
+
`min_segment` 32 tokens to the previous one merge forward, so small leaves such as doc comments group with what
|
| 46 |
+
follows; a unit longer than `max_segment` 512 tokens is split at line boundaries (`oversize_split` =
|
| 47 |
+
`line_aligned`), preferring sub-unit starts. No parser runs at inference.
|
| 48 |
+
- **Why the threshold is asymmetric**: a missed boundary merges two whole units, which the head can still rank; a
|
| 49 |
+
cut inside a unit truncates it, which it cannot repair. 0.8 keeps harmful cuts (inside a function body or
|
| 50 |
+
mid-line) at or below 1 % of cuts on code, tool output, dialogue, records and prose, with boundary precision of
|
| 51 |
+
0.97 or more.
|
| 52 |
+
|
| 53 |
+
## Files
|
| 54 |
+
|
| 55 |
+
| file | sha256 | note |
|
| 56 |
+
|---|---|---|
|
| 57 |
+
| `segment-probe-s3-line512.gguf` | `470b7b0efe3736518dcb4c1ba8eb5b806107007e378a74668c17e26434602e68` | the served file: `max_segment` 512, line-aligned splitting |
|
| 58 |
+
| `segment-probe.gguf` | `bd3f0bff1057ad0c953deb79d4b82415076906494c7bbb47a8a0f8e85433b667` | the same weights and thresholds with `max_segment` 2048; not used in the configuration below |
|
| 59 |
+
|
| 60 |
+
## Using it
|
| 61 |
+
|
| 62 |
+
PFlash runs inside the Lucebox server. Download the three components and the drafter, then set:
|
| 63 |
+
|
| 64 |
+
```bash
|
| 65 |
+
export PFLASH_SCORING_HEAD_GGUF=/path/to/seg-scoring-head.gguf
|
| 66 |
+
export PFLASH_SEGMENT_PROBE_GGUF=/path/to/segment-probe-s3-line512.gguf
|
| 67 |
+
export PFLASH_REQUEST_PROBE_GGUF=/path/to/request-probe.gguf
|
| 68 |
+
export PFLASH_SELECT_SEGMENTS=probe PFLASH_SELECT_SCORE=density PFLASH_SELECT_MODE=budget_only
|
| 69 |
+
export PFLASH_SELECT_QUERY_PROBE=1 PFLASH_QUERY_CANDIDATES=1 PFLASH_QUERY_PIN=512
|
| 70 |
+
export PFLASH_SELECT_QUERY_TOKENS=128 PFLASH_SELECT_QUERY_HEAD=1
|
| 71 |
+
export PFLASH_SELECT_PARAGRAPH_JOIN=0 PFLASH_SELECT_CHUNK_SIZE=256
|
| 72 |
+
export PFLASH_ADMISSION=cache PFLASH_ARRIVE=1 PFLASH_CHAT_RECALL=1
|
| 73 |
+
export PFLASH_CHAT_REBUILD_RATIO=2 PFLASH_CHAT_REBUILD_MIN_TOKENS=65536
|
| 74 |
+
export PFLASH_FALLBACK_SPREAD=0.11 PFLASH_COLD_HISTORY=raw
|
| 75 |
+
# server: --prefill-compression auto --prefill-threshold 16384
|
| 76 |
+
# --prefill-curve 16384:0.315 32768:0.270 65536:0.270 120000:0.225
|
| 77 |
+
# --prefill-skip-park --cache-type-k q4_0 --cache-type-v q4_0 --max-ctx 139264
|
| 78 |
+
```
|
| 79 |
+
|
| 80 |
+
- **Drafter** (required, checked by sha256 at load):
|
| 81 |
+
[`unsloth/Qwen3.5-0.8B-GGUF`](https://huggingface.co/unsloth/Qwen3.5-0.8B-GGUF) `Qwen3.5-0.8B-BF16.gguf`, sha256
|
| 82 |
+
`cedf89af31c9041b601fa58303285bc46d99c51baee1b13f5e919626ca526ee5`. Each component refuses to load against any
|
| 83 |
+
other drafter file.
|
| 84 |
+
- PFlash acts when at least 16,384 prompt tokens are new to the server and less than that is already cached. The
|
| 85 |
+
reader then prefills 31.5 % of the prompt at 16K tokens, 27 % at 32K–64K and 22.5 % at 120K.
|
| 86 |
+
- When the relevance scores are too flat for the budget, the request is served with full prefill
|
| 87 |
+
(`PFLASH_FALLBACK_SPREAD`). An agent's uncached earlier conversation is never compressed
|
| 88 |
+
(`PFLASH_COLD_HISTORY=raw`).
|
| 89 |
+
- Runtime support: [Luce-Org/lucebox PR #746](https://github.com/Luce-Org/lucebox/pull/746).
|
| 90 |
+
|
| 91 |
+
## Results
|
| 92 |
+
|
| 93 |
+
Measured with all three components together, reader Qwen3.8-27B IQ4_XS, the configuration above, NVIDIA L40S,
|
| 94 |
+
greedy, each benchmark's official metric:
|
| 95 |
+
|
| 96 |
+
| set | n | full prefill | PFlash |
|
| 97 |
+
|---|---:|---:|---:|
|
| 98 |
+
| Document QA | 30 | 27 | 27 |
|
| 99 |
+
| LongBench v2 | 12 | 6 | 7 |
|
| 100 |
+
| NoLiMa | 24 | 14 | 14 |
|
| 101 |
+
| InfiniteBench CodeDebug | 30 | 24 | 24 |
|
| 102 |
+
| BRIGHT | 28 | 23 | 23 |
|
| 103 |
+
| needle in a haystack, 16K–120K | 100 | 100 | 100 |
|
| 104 |
+
| **public sets, unique questions** (RULER QA's 15 are inside Document QA) | 224 | 194 | **195** |
|
| 105 |
+
| LongCodeQA, questions that need the code | 114 | 57 | 62 |
|
| 106 |
+
|
| 107 |
+
None of these differences is outside its 95 % interval. The reader prefills a median 29 % of the prompt, and the
|
| 108 |
+
first token arrives 2.7× sooner on average (mean 30.5 s → 11.2 s over the public requests; 60.4 s → 14.8 s median
|
| 109 |
+
on 82K–98K-token CodeDebug prompts).
|
| 110 |
+
|
| 111 |
+
## Limits
|
| 112 |
+
|
| 113 |
+
- Not lossless: a request can still lose something the answer needed.
|
| 114 |
+
- Cold agent histories are served with full prefill, so a resumed agent session gets no speed-up.
|
| 115 |
+
- "List everything matching X" over many similar units (emails, wiki pages) is the hardest case; the flat-score
|
| 116 |
+
fallback catches most of it.
|
| 117 |
+
- Measured serving one request at a time.
|
segment-probe-s3-line512.gguf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:470b7b0efe3736518dcb4c1ba8eb5b806107007e378a74668c17e26434602e68
|
| 3 |
+
size 1062976
|
segment-probe.gguf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:bd3f0bff1057ad0c953deb79d4b82415076906494c7bbb47a8a0f8e85433b667
|
| 3 |
+
size 1062912
|