OnPair trainer should draw Rust's sample (StdRng + partial_shuffle) for byte-identical dictionaries
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
研究方向
Start in OnPairEncodingEncoder.Encoder.train, which uses SplittableRandom(42) and a full Fisher-Yates shuffle, and compare it with the Rust training_order in encoding/trainer.rs. Port the partial_shuffle tail selection and doubling retry loop on top of SampleRng, and check that SampleRng.nextIntInclusive matches random_range from rand 0.9.5. Done when the 100k-row URL column gives the same dict_bytes_len and encoded size per chunk as the Rust 0.88.0 oracle.
由索引模型根據 Issue 內容生成。
描述
Problem
OnPairEncodingEncoder does not draw the same training sample as the Rust onpair crate, so it trains different dictionaries on identical data. Prime directive: behavioral parity with Rust.
Found by comparing a 100k-row URL column (https://example.com/products/<n>/reviews?page=<m>, 7 chunks of 16,384 rows) written by vortex-java and by Rust 0.88.0 (the release vortex-jni uses), both at cascade 3 with global dict off. Both pick vortex.onpair per chunk.
dict_bytes_len per chunk:
| chunk | Rust | Java |
|---|---|---|
| 0 | 8191 | 8429 |
| 1 | 8525 | 8368 |
| 2 | 8447 | 8387 |
| 3 | 8363 | 8452 |
| 4 | 8379 | 8473 |
| 5 | 8757 | 5670 |
| 6 | 1872 | 1877 |
Chunks 0-4 end up within 0.04% in total, but Java's chunk 5 is 18% smaller (131,904 B vs 161,507 B): its trainer built a 761-token dictionary and the cascade then dict-encoded the 467 distinct codes. That one chunk is 29.6 KB of the 31.6 KB (3.2%) by which Java's file is smaller. This is training luck, not a systematic advantage, and it could go the other way on other data.
Cause
- Rust (
onpair0.2.1,training_orderinencoding/trainer.rs):StdRng::seed_from_u64(42)(ChaCha12,rand0.9.5) andorder.partial_shuffle(&mut rng, k)withk = min(n, 2 * sample_fraction * n + 1024). Training consumes only the selected tailorder[n-k..]; if that tail is shorter than the byte budget,kdoubles and the shuffle restarts. - Java (
OnPairEncodingEncoder.Encoder.train):SplittableRandom(42), a full Fisher-Yates shuffle, and training consumesorderfrom the start.
Proposed fix
- Port
rand0.9.5partial_shuffleon top ofSampleRng(already a bit-exact ChaCha12StdRngandrandom_rangeforu32). It usesIncreasingUniform/calculate_bound_u32, which batches several swaps into one random chunk. Check thatSampleRng.nextIntInclusive(written againstrand0.10) gives the same values as 0.9.5'srandom_range. - Reproduce the
kcomputation, the tail consumption and the doubling retry loop intrain. - Parity test: the URL column above, Rust as the oracle, comparing
dict_bytes_lenand encoded size per chunk (expect identical).
Repro
Scratch crate with vortex = "=0.88.0"; data dumped from the Java CascadeDepthGainIntegrationTest patterns (utf8-urls), seed 42. Not committed.
- 主要語言
- Java
- 星號
- 3
- 分支
- 2
- 平均合併
- 9 小時 47 分鐘
- 30 天內合併 PR
- 128
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 沒有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
dfa1/vortex-java 的其他 Issue
-
bug
難度 2/5 1-3 小時 新手友好度 66/100
dfa1/vortex-java#636 ·
維護者通常 1 天內回覆
-
bug
難度 3/5 1-2 天 新手友好度 70/100
dfa1/vortex-java#655 ·
維護者通常 1 天內回覆
-
perf
難度 4/5 3-5 天 新手友好度 30/100
dfa1/vortex-java#651 ·
維護者通常 1 天內回覆
-
Writer: string columns written as per-chunk dicts where Rust uses its dict layout (up to 2x larger)未關閉perf
難度 4/5 3-5 天 新手友好度 30/100
dfa1/vortex-java#650 ·
維護者通常 1 天內回覆
-
perf
難度 4/5 3-5 天 新手友好度 28/100
dfa1/vortex-java#649 ·
維護者通常 1 天內回覆
相似的 Issue
-
5.0.x backport enhancement
難度 2/5 1-3 小時 新手友好度 63/100
spring-cloud/spring-cloud-function#1507 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 65/100
open-learning-exchange/myplanet#18484 ·
維護者通常 1 天內回覆
-
ai-driven-fuzzing bug claude Minor
難度 2/5 1-3 小時 新手友好度 66/100
linagora/twake-calendar-side-service#1417 · 2 則留言 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 74/100
line/armeria#7109 · 3 個 reaction ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 72/100
open-feature/java-sdk-contrib#1966 ·
維護者通常 1 天內回覆