v3_scale/checker: recompte dédup 64 o corpus_diverse_v1 (REPORT, agrégats assainis sans plages ni texte, dedup64_div1.py 5230e995, run.sh) — raw 186812/687/231506 ; norm 149315/454/221174
Browse files
v3_scale/checker/recount/corpus_diverse_v1_dedup/REPORT.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Checker — recompte dedup 64-grammes corpus_diverse_v1 (agrégats)
|
| 2 |
+
|
| 3 |
+
Rapport reconstitué le 30 oct. 2026 (Toronto) à partir des seuls JSON d'agrégats (le REPORT.md d'origine est absent du disque après la restauration de la boîte). Aucune position, masque, extrait de texte ni donnée d'éval n'est publié.
|
| 4 |
+
|
| 5 |
+
- train : corpus_diverse_v1/train.bin, 530,137,703 o, sha256 c813244c… (ok=True)
|
| 6 |
+
- script dedup64_div1.py sha256 5230e9959b08e9c16972b8b5d3920a54ec6b17c8fd489b14b5585cc1dd314428 ; k=64 ; Horner mod 2^64 P=0x9E3779B97F4A7C15 (logique dedup64.py 4bee4293…), confirmation octet à octet
|
| 7 |
+
|
| 8 |
+
| forme | positions train appariées | plages fusionnées | octets dans plages | faux positifs hash | positions seg multilang |
|
| 9 |
+
|---|---|---|---|---|---|
|
| 10 |
+
| brut | 186,812 | 687 | 231,506 | 0 | 0 |
|
| 11 |
+
| normalisé | 149,315 | 454 | 221,174 | 0 | 117 |
|
| 12 |
+
|
| 13 |
+
Normalisation : suppr. \r ; A-Z->a-z ASCII ; suites [ \t\n\v\f] -> 1 espace ; en flux
|
| 14 |
+
|
| 15 |
+
| fenêtre | n64 brut | trouvés brut | octets éval couverts brut | n64 norm | trouvés norm | octets couverts norm |
|
| 16 |
+
|---|---|---|---|---|---|---|
|
| 17 |
+
| test20k_old | 319,877 | 1,405 | 4,263 | 298,660 | 1,915 | 3,944 |
|
| 18 |
+
| fc2 | 199,729 | 0 | 0 | 157,783 | 22 | 113 |
|
| 19 |
+
| fresh_en | 119,700 | 0 | 0 | 119,587 | 0 | 0 |
|
| 20 |
+
| fresh_fr | 1,088,625 | 0 | 0 | 1,067,982 | 77 | 143 |
|
| 21 |
+
| test_v3 | 3,486,590 | 0 | 0 | 3,390,446 | 17 | 149 |
|
| 22 |
+
| queries | 27,737 | 0 | 0 | 27,688 | 0 | 0 |
|
| 23 |
+
| bg1_test | 894,655 | 33,766 | 45,852 | 823,920 | 26,765 | 42,756 |
|
| 24 |
+
|
| 25 |
+
Autotests (selftest.json) : ALL_PASS = True.
|
| 26 |
+
Détails complets : dedup64_aggregates.json.
|
v3_scale/checker/recount/corpus_diverse_v1_dedup/dedup64_aggregates.json
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"what": "Checker — dedup 64-grammes corpus_diverse_v1/train.bin vs fenêtres d'éval — AGRÉGATS ASSAINIS (échantillons de plages train retirés, sans texte, sans masques)",
|
| 3 |
+
"source_json_sha256": {
|
| 4 |
+
"dedup64_raw.json": "ef939f41937bd18536fa0aff33b97a47fa3c8c0b16caec2daf8bfbb9302b3d52",
|
| 5 |
+
"dedup64_norm.json": "b73e5099ccad14ee4fb1c80c06904601ab50f5ced0160ca4aaade0d199189fa0"
|
| 6 |
+
},
|
| 7 |
+
"raw": {
|
| 8 |
+
"form": "raw",
|
| 9 |
+
"k": 64,
|
| 10 |
+
"hash": "Horner mod 2^64 P=0x9E3779B97F4A7C15 (logique dedup64.py 4bee4293…), confirmation octet à octet",
|
| 11 |
+
"normalisation": null,
|
| 12 |
+
"train": "/workspace/spira_shared/corpus_diverse_v1/train.bin",
|
| 13 |
+
"train_bytes": 530137703,
|
| 14 |
+
"train_sha256": "c813244c618eb20dbc34e2d7472ac29e10b0c22344e8117a0c25b1186124e6d9",
|
| 15 |
+
"train_sha_ok": true,
|
| 16 |
+
"train_64gram_positions_hashed": 530137640,
|
| 17 |
+
"table_unique_hashes": 5777106,
|
| 18 |
+
"table_internal_collisions": 0,
|
| 19 |
+
"candidates": 186812,
|
| 20 |
+
"hash_false_positives_rejected": 0,
|
| 21 |
+
"train_positions_matched_any": 186812,
|
| 22 |
+
"train_ranges_merged_any": 687,
|
| 23 |
+
"train_bytes_in_ranges_any": 231506,
|
| 24 |
+
"train_positions_seg_multilang_any": 0,
|
| 25 |
+
"windows": {
|
| 26 |
+
"test20k_old": {
|
| 27 |
+
"n64": 319877,
|
| 28 |
+
"n64_found": 1405,
|
| 29 |
+
"frac64_found": 0.004392313295422928,
|
| 30 |
+
"n64_distinct_found": 1386,
|
| 31 |
+
"eval_bytes": 319940,
|
| 32 |
+
"eval_bytes_covered": 4263,
|
| 33 |
+
"eval_bytes_excl_ctx64": 6596,
|
| 34 |
+
"window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
|
| 35 |
+
"train_positions_matched": 13111,
|
| 36 |
+
"train_positions_seg_bg1": 13111,
|
| 37 |
+
"train_positions_seg_multilang": 0,
|
| 38 |
+
"train_ranges_merged": 133,
|
| 39 |
+
"train_bytes_in_ranges": 22280,
|
| 40 |
+
"xcheck_mask_2134": {
|
| 41 |
+
"key": "m7_test20k",
|
| 42 |
+
"mask_covered": 4263,
|
| 43 |
+
"mask_excl": 6596,
|
| 44 |
+
"covered_identical_to_mask": true,
|
| 45 |
+
"covered_outside_mask_excl": 0,
|
| 46 |
+
"excl_identical_to_mask": true
|
| 47 |
+
}
|
| 48 |
+
},
|
| 49 |
+
"fc2": {
|
| 50 |
+
"n64": 199729,
|
| 51 |
+
"n64_found": 0,
|
| 52 |
+
"frac64_found": 0.0,
|
| 53 |
+
"n64_distinct_found": 0,
|
| 54 |
+
"eval_bytes": 199792,
|
| 55 |
+
"eval_bytes_covered": 0,
|
| 56 |
+
"eval_bytes_excl_ctx64": 0,
|
| 57 |
+
"window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
|
| 58 |
+
"train_positions_matched": 0,
|
| 59 |
+
"train_positions_seg_bg1": 0,
|
| 60 |
+
"train_positions_seg_multilang": 0,
|
| 61 |
+
"train_ranges_merged": 0,
|
| 62 |
+
"train_bytes_in_ranges": 0,
|
| 63 |
+
"xcheck_mask_2134": {
|
| 64 |
+
"key": "bench_fc2",
|
| 65 |
+
"mask_covered": 0,
|
| 66 |
+
"mask_excl": 0,
|
| 67 |
+
"covered_identical_to_mask": true,
|
| 68 |
+
"covered_outside_mask_excl": 0,
|
| 69 |
+
"excl_identical_to_mask": true
|
| 70 |
+
}
|
| 71 |
+
},
|
| 72 |
+
"fresh_en": {
|
| 73 |
+
"n64": 119700,
|
| 74 |
+
"n64_found": 0,
|
| 75 |
+
"frac64_found": 0.0,
|
| 76 |
+
"n64_distinct_found": 0,
|
| 77 |
+
"eval_bytes": 119763,
|
| 78 |
+
"eval_bytes_covered": 0,
|
| 79 |
+
"eval_bytes_excl_ctx64": 0,
|
| 80 |
+
"window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
|
| 81 |
+
"train_positions_matched": 0,
|
| 82 |
+
"train_positions_seg_bg1": 0,
|
| 83 |
+
"train_positions_seg_multilang": 0,
|
| 84 |
+
"train_ranges_merged": 0,
|
| 85 |
+
"train_bytes_in_ranges": 0,
|
| 86 |
+
"xcheck_mask_2134": {
|
| 87 |
+
"key": "bench_fresh_en",
|
| 88 |
+
"mask_covered": 0,
|
| 89 |
+
"mask_excl": 0,
|
| 90 |
+
"covered_identical_to_mask": true,
|
| 91 |
+
"covered_outside_mask_excl": 0,
|
| 92 |
+
"excl_identical_to_mask": true
|
| 93 |
+
}
|
| 94 |
+
},
|
| 95 |
+
"fresh_fr": {
|
| 96 |
+
"n64": 1088625,
|
| 97 |
+
"n64_found": 0,
|
| 98 |
+
"frac64_found": 0.0,
|
| 99 |
+
"n64_distinct_found": 0,
|
| 100 |
+
"eval_bytes": 1088688,
|
| 101 |
+
"eval_bytes_covered": 0,
|
| 102 |
+
"eval_bytes_excl_ctx64": 0,
|
| 103 |
+
"window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
|
| 104 |
+
"train_positions_matched": 0,
|
| 105 |
+
"train_positions_seg_bg1": 0,
|
| 106 |
+
"train_positions_seg_multilang": 0,
|
| 107 |
+
"train_ranges_merged": 0,
|
| 108 |
+
"train_bytes_in_ranges": 0,
|
| 109 |
+
"xcheck_mask_2134": {
|
| 110 |
+
"key": "bench_fresh_fr",
|
| 111 |
+
"mask_covered": 0,
|
| 112 |
+
"mask_excl": 0,
|
| 113 |
+
"covered_identical_to_mask": true,
|
| 114 |
+
"covered_outside_mask_excl": 0,
|
| 115 |
+
"excl_identical_to_mask": true
|
| 116 |
+
}
|
| 117 |
+
},
|
| 118 |
+
"test_v3": {
|
| 119 |
+
"n64": 3486590,
|
| 120 |
+
"n64_found": 0,
|
| 121 |
+
"frac64_found": 0.0,
|
| 122 |
+
"n64_distinct_found": 0,
|
| 123 |
+
"eval_bytes": 3486653,
|
| 124 |
+
"eval_bytes_covered": 0,
|
| 125 |
+
"eval_bytes_excl_ctx64": 0,
|
| 126 |
+
"window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
|
| 127 |
+
"train_positions_matched": 0,
|
| 128 |
+
"train_positions_seg_bg1": 0,
|
| 129 |
+
"train_positions_seg_multilang": 0,
|
| 130 |
+
"train_ranges_merged": 0,
|
| 131 |
+
"train_bytes_in_ranges": 0,
|
| 132 |
+
"xcheck_mask_2134": {
|
| 133 |
+
"key": "bench_test_v3",
|
| 134 |
+
"mask_covered": 0,
|
| 135 |
+
"mask_excl": 0,
|
| 136 |
+
"covered_identical_to_mask": true,
|
| 137 |
+
"covered_outside_mask_excl": 0,
|
| 138 |
+
"excl_identical_to_mask": true
|
| 139 |
+
}
|
| 140 |
+
},
|
| 141 |
+
"queries": {
|
| 142 |
+
"n64": 27737,
|
| 143 |
+
"n64_found": 0,
|
| 144 |
+
"frac64_found": 0.0,
|
| 145 |
+
"n64_distinct_found": 0,
|
| 146 |
+
"eval_bytes": 27800,
|
| 147 |
+
"eval_bytes_covered": 0,
|
| 148 |
+
"eval_bytes_excl_ctx64": 0,
|
| 149 |
+
"window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
|
| 150 |
+
"train_positions_matched": 0,
|
| 151 |
+
"train_positions_seg_bg1": 0,
|
| 152 |
+
"train_positions_seg_multilang": 0,
|
| 153 |
+
"train_ranges_merged": 0,
|
| 154 |
+
"train_bytes_in_ranges": 0,
|
| 155 |
+
"xcheck_mask_2134": {
|
| 156 |
+
"key": "bench_queries",
|
| 157 |
+
"mask_covered": 0,
|
| 158 |
+
"mask_excl": 0,
|
| 159 |
+
"covered_identical_to_mask": true,
|
| 160 |
+
"covered_outside_mask_excl": 0,
|
| 161 |
+
"excl_identical_to_mask": true
|
| 162 |
+
}
|
| 163 |
+
},
|
| 164 |
+
"bg1_test": {
|
| 165 |
+
"n64": 894655,
|
| 166 |
+
"n64_found": 33766,
|
| 167 |
+
"frac64_found": 0.03774192286412081,
|
| 168 |
+
"n64_distinct_found": 32879,
|
| 169 |
+
"eval_bytes": 894718,
|
| 170 |
+
"eval_bytes_covered": 45852,
|
| 171 |
+
"eval_bytes_excl_ctx64": 54828,
|
| 172 |
+
"window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
|
| 173 |
+
"train_positions_matched": 186809,
|
| 174 |
+
"train_positions_seg_bg1": 186809,
|
| 175 |
+
"train_positions_seg_multilang": 0,
|
| 176 |
+
"train_ranges_merged": 687,
|
| 177 |
+
"train_bytes_in_ranges": 231503,
|
| 178 |
+
"xcheck_mask_2134": {
|
| 179 |
+
"key": "broad_test_bin",
|
| 180 |
+
"mask_covered": 45852,
|
| 181 |
+
"mask_excl": 54828,
|
| 182 |
+
"covered_identical_to_mask": true,
|
| 183 |
+
"covered_outside_mask_excl": 0,
|
| 184 |
+
"excl_identical_to_mask": true
|
| 185 |
+
}
|
| 186 |
+
}
|
| 187 |
+
},
|
| 188 |
+
"files": {
|
| 189 |
+
"masks_raw.npz": "8f56c0edf25cafb368c1a2c848ec926fe389c6695863b37d5c5895b93350b7b0",
|
| 190 |
+
"train_ranges_raw.npz": "31115e29fee3d0f794a5357bce1e942b846ad491e91fecc14e566839ced220bc"
|
| 191 |
+
},
|
| 192 |
+
"elapsed_s": 74.0,
|
| 193 |
+
"peak_rss_kB": 217304,
|
| 194 |
+
"script_sha256": "5230e9959b08e9c16972b8b5d3920a54ec6b17c8fd489b14b5585cc1dd314428"
|
| 195 |
+
},
|
| 196 |
+
"norm": {
|
| 197 |
+
"form": "norm",
|
| 198 |
+
"k": 64,
|
| 199 |
+
"hash": "Horner mod 2^64 P=0x9E3779B97F4A7C15 (logique dedup64.py 4bee4293…), confirmation octet à octet",
|
| 200 |
+
"normalisation": "suppr. \\r ; A-Z->a-z ASCII ; suites [ \\t\\n\\v\\f] -> 1 espace ; en flux",
|
| 201 |
+
"train": "/workspace/spira_shared/corpus_diverse_v1/train.bin",
|
| 202 |
+
"train_bytes": 530137703,
|
| 203 |
+
"train_sha256": "c813244c618eb20dbc34e2d7472ac29e10b0c22344e8117a0c25b1186124e6d9",
|
| 204 |
+
"train_sha_ok": true,
|
| 205 |
+
"train_64gram_positions_hashed": 489807340,
|
| 206 |
+
"table_unique_hashes": 5551296,
|
| 207 |
+
"table_internal_collisions": 0,
|
| 208 |
+
"candidates": 149315,
|
| 209 |
+
"hash_false_positives_rejected": 0,
|
| 210 |
+
"train_positions_matched_any": 149315,
|
| 211 |
+
"train_ranges_merged_any": 454,
|
| 212 |
+
"train_bytes_in_ranges_any": 221174,
|
| 213 |
+
"train_positions_seg_multilang_any": 117,
|
| 214 |
+
"windows": {
|
| 215 |
+
"test20k_old": {
|
| 216 |
+
"n64": 298660,
|
| 217 |
+
"n64_found": 1915,
|
| 218 |
+
"frac64_found": 0.006411973481550927,
|
| 219 |
+
"n64_distinct_found": 1907,
|
| 220 |
+
"eval_bytes": 319940,
|
| 221 |
+
"eval_bytes_covered": 3944,
|
| 222 |
+
"eval_bytes_excl_ctx64": 5448,
|
| 223 |
+
"window_sha256": "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22",
|
| 224 |
+
"train_positions_matched": 12453,
|
| 225 |
+
"train_positions_seg_bg1": 12453,
|
| 226 |
+
"train_positions_seg_multilang": 0,
|
| 227 |
+
"train_ranges_merged": 54,
|
| 228 |
+
"train_bytes_in_ranges": 17298,
|
| 229 |
+
"xcheck_mask_2134": {
|
| 230 |
+
"key": "m7_test20k",
|
| 231 |
+
"mask_covered": 4263,
|
| 232 |
+
"mask_excl": 6596,
|
| 233 |
+
"covered_identical_to_mask": false,
|
| 234 |
+
"covered_outside_mask_excl": 647,
|
| 235 |
+
"excl_identical_to_mask": false
|
| 236 |
+
}
|
| 237 |
+
},
|
| 238 |
+
"fc2": {
|
| 239 |
+
"n64": 157783,
|
| 240 |
+
"n64_found": 22,
|
| 241 |
+
"frac64_found": 0.0001394320047153369,
|
| 242 |
+
"n64_distinct_found": 22,
|
| 243 |
+
"eval_bytes": 199792,
|
| 244 |
+
"eval_bytes_covered": 113,
|
| 245 |
+
"eval_bytes_excl_ctx64": 177,
|
| 246 |
+
"window_sha256": "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3",
|
| 247 |
+
"train_positions_matched": 122,
|
| 248 |
+
"train_positions_seg_bg1": 22,
|
| 249 |
+
"train_positions_seg_multilang": 100,
|
| 250 |
+
"train_ranges_merged": 6,
|
| 251 |
+
"train_bytes_in_ranges": 573,
|
| 252 |
+
"xcheck_mask_2134": {
|
| 253 |
+
"key": "bench_fc2",
|
| 254 |
+
"mask_covered": 0,
|
| 255 |
+
"mask_excl": 0,
|
| 256 |
+
"covered_identical_to_mask": false,
|
| 257 |
+
"covered_outside_mask_excl": 113,
|
| 258 |
+
"excl_identical_to_mask": false
|
| 259 |
+
}
|
| 260 |
+
},
|
| 261 |
+
"fresh_en": {
|
| 262 |
+
"n64": 119587,
|
| 263 |
+
"n64_found": 0,
|
| 264 |
+
"frac64_found": 0.0,
|
| 265 |
+
"n64_distinct_found": 0,
|
| 266 |
+
"eval_bytes": 119763,
|
| 267 |
+
"eval_bytes_covered": 0,
|
| 268 |
+
"eval_bytes_excl_ctx64": 0,
|
| 269 |
+
"window_sha256": "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a",
|
| 270 |
+
"train_positions_matched": 0,
|
| 271 |
+
"train_positions_seg_bg1": 0,
|
| 272 |
+
"train_positions_seg_multilang": 0,
|
| 273 |
+
"train_ranges_merged": 0,
|
| 274 |
+
"train_bytes_in_ranges": 0,
|
| 275 |
+
"xcheck_mask_2134": {
|
| 276 |
+
"key": "bench_fresh_en",
|
| 277 |
+
"mask_covered": 0,
|
| 278 |
+
"mask_excl": 0,
|
| 279 |
+
"covered_identical_to_mask": true,
|
| 280 |
+
"covered_outside_mask_excl": 0,
|
| 281 |
+
"excl_identical_to_mask": true
|
| 282 |
+
}
|
| 283 |
+
},
|
| 284 |
+
"fresh_fr": {
|
| 285 |
+
"n64": 1067982,
|
| 286 |
+
"n64_found": 77,
|
| 287 |
+
"frac64_found": 7.209859342198652e-05,
|
| 288 |
+
"n64_distinct_found": 77,
|
| 289 |
+
"eval_bytes": 1088688,
|
| 290 |
+
"eval_bytes_covered": 143,
|
| 291 |
+
"eval_bytes_excl_ctx64": 207,
|
| 292 |
+
"window_sha256": "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715",
|
| 293 |
+
"train_positions_matched": 1112,
|
| 294 |
+
"train_positions_seg_bg1": 1112,
|
| 295 |
+
"train_positions_seg_multilang": 0,
|
| 296 |
+
"train_ranges_merged": 18,
|
| 297 |
+
"train_bytes_in_ranges": 2270,
|
| 298 |
+
"xcheck_mask_2134": {
|
| 299 |
+
"key": "bench_fresh_fr",
|
| 300 |
+
"mask_covered": 0,
|
| 301 |
+
"mask_excl": 0,
|
| 302 |
+
"covered_identical_to_mask": false,
|
| 303 |
+
"covered_outside_mask_excl": 143,
|
| 304 |
+
"excl_identical_to_mask": false
|
| 305 |
+
}
|
| 306 |
+
},
|
| 307 |
+
"test_v3": {
|
| 308 |
+
"n64": 3390446,
|
| 309 |
+
"n64_found": 17,
|
| 310 |
+
"frac64_found": 5.014089591752825e-06,
|
| 311 |
+
"n64_distinct_found": 17,
|
| 312 |
+
"eval_bytes": 3486653,
|
| 313 |
+
"eval_bytes_covered": 149,
|
| 314 |
+
"eval_bytes_excl_ctx64": 277,
|
| 315 |
+
"window_sha256": "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84",
|
| 316 |
+
"train_positions_matched": 17,
|
| 317 |
+
"train_positions_seg_bg1": 17,
|
| 318 |
+
"train_positions_seg_multilang": 0,
|
| 319 |
+
"train_ranges_merged": 2,
|
| 320 |
+
"train_bytes_in_ranges": 144,
|
| 321 |
+
"xcheck_mask_2134": {
|
| 322 |
+
"key": "bench_test_v3",
|
| 323 |
+
"mask_covered": 0,
|
| 324 |
+
"mask_excl": 0,
|
| 325 |
+
"covered_identical_to_mask": false,
|
| 326 |
+
"covered_outside_mask_excl": 149,
|
| 327 |
+
"excl_identical_to_mask": false
|
| 328 |
+
}
|
| 329 |
+
},
|
| 330 |
+
"queries": {
|
| 331 |
+
"n64": 27688,
|
| 332 |
+
"n64_found": 0,
|
| 333 |
+
"frac64_found": 0.0,
|
| 334 |
+
"n64_distinct_found": 0,
|
| 335 |
+
"eval_bytes": 27800,
|
| 336 |
+
"eval_bytes_covered": 0,
|
| 337 |
+
"eval_bytes_excl_ctx64": 0,
|
| 338 |
+
"window_sha256": "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706",
|
| 339 |
+
"train_positions_matched": 0,
|
| 340 |
+
"train_positions_seg_bg1": 0,
|
| 341 |
+
"train_positions_seg_multilang": 0,
|
| 342 |
+
"train_ranges_merged": 0,
|
| 343 |
+
"train_bytes_in_ranges": 0,
|
| 344 |
+
"xcheck_mask_2134": {
|
| 345 |
+
"key": "bench_queries",
|
| 346 |
+
"mask_covered": 0,
|
| 347 |
+
"mask_excl": 0,
|
| 348 |
+
"covered_identical_to_mask": true,
|
| 349 |
+
"covered_outside_mask_excl": 0,
|
| 350 |
+
"excl_identical_to_mask": true
|
| 351 |
+
}
|
| 352 |
+
},
|
| 353 |
+
"bg1_test": {
|
| 354 |
+
"n64": 823920,
|
| 355 |
+
"n64_found": 26765,
|
| 356 |
+
"frac64_found": 0.03248494999514516,
|
| 357 |
+
"n64_distinct_found": 26046,
|
| 358 |
+
"eval_bytes": 894718,
|
| 359 |
+
"eval_bytes_covered": 42756,
|
| 360 |
+
"eval_bytes_excl_ctx64": 49727,
|
| 361 |
+
"window_sha256": "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9",
|
| 362 |
+
"train_positions_matched": 148061,
|
| 363 |
+
"train_positions_seg_bg1": 148044,
|
| 364 |
+
"train_positions_seg_multilang": 17,
|
| 365 |
+
"train_ranges_merged": 428,
|
| 366 |
+
"train_bytes_in_ranges": 218184,
|
| 367 |
+
"xcheck_mask_2134": {
|
| 368 |
+
"key": "broad_test_bin",
|
| 369 |
+
"mask_covered": 45852,
|
| 370 |
+
"mask_excl": 54828,
|
| 371 |
+
"covered_identical_to_mask": false,
|
| 372 |
+
"covered_outside_mask_excl": 1484,
|
| 373 |
+
"excl_identical_to_mask": false
|
| 374 |
+
}
|
| 375 |
+
}
|
| 376 |
+
},
|
| 377 |
+
"files": {
|
| 378 |
+
"masks_norm.npz": "7a3d76b5a20475a35dc0113efc0648d358df63f805eb05320affdf6f036df465",
|
| 379 |
+
"train_ranges_norm.npz": "e8cfddf83e1c2b0bace101d9a9a784f5e5ad1363c2aa4a1d365146b604cfb2a9"
|
| 380 |
+
},
|
| 381 |
+
"elapsed_s": 78.2,
|
| 382 |
+
"peak_rss_kB": 233784,
|
| 383 |
+
"script_sha256": "5230e9959b08e9c16972b8b5d3920a54ec6b17c8fd489b14b5585cc1dd314428"
|
| 384 |
+
}
|
| 385 |
+
}
|
v3_scale/checker/recount/corpus_diverse_v1_dedup/dedup64_div1.py
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""SPIRA Checker — 25 oct. 2026 (Toronto) — recompte INDÉPENDANT de dédup 64 o : corpus_diverse_v1/train.bin vs fenêtres d'éval.
|
| 3 |
+
Logique reprise de checker/recount/bg1_test_dedup64/dedup64.py (sha 4bee4293…) : Horner mod 2^64 (P = 0x9E3779B97F4A7C15) sur chaque
|
| 4 |
+
64-gramme, table triée + np.searchsorted, train lu par blocs + 63 o de recouvrement, CONFIRMATION octet à octet de chaque candidat.
|
| 5 |
+
Deux formes (un processus par forme, pour tenir < 300 Mo RSS) :
|
| 6 |
+
raw : octets bruts ;
|
| 7 |
+
norm : \r supprimés, A-Z -> a-z (ASCII seulement), toute suite d'espaces (espace, \t, \n, \v, \f) -> un seul espace ; normalisation
|
| 8 |
+
en flux (état « dernier octet = espace » propagé entre blocs) ; chaque octet normalisé garde son offset d'origine.
|
| 9 |
+
Tous les débuts de 64-grammes des fenêtres sont hachés (les positions notées par le banc sont tirées par bench_common, non séparables
|
| 10 |
+
du fichier seul ; « tous » est un sur-ensemble). Ne lit que des fichiers ; écrit UNIQUEMENT dans son dossier. Aucun texte en sortie.
|
| 11 |
+
Usage : dedup64_div1.py raw|norm | dedup64_div1.py selftest"""
|
| 12 |
+
import sys, os, json, hashlib, time, resource
|
| 13 |
+
import numpy as np
|
| 14 |
+
S = "/workspace/spira_shared"; OD = os.path.dirname(os.path.abspath(__file__)); K = 64; P = np.uint64(0x9E3779B97F4A7C15)
|
| 15 |
+
TRAIN = f"{S}/corpus_diverse_v1/train.bin"; TRAIN_SHA = "c813244c618eb20dbc34e2d7472ac29e10b0c22344e8117a0c25b1186124e6d9"
|
| 16 |
+
SEG2 = 290810504 # début du segment multi_lang_v1 (manifest.segments) ; [290810502, 290810504) = séparateur b"\n\n"
|
| 17 |
+
WIN = { # nom : (chemin, sha256 attendu, clé du masque propre dans clean_masks/broad_gutenberg_v1_2134.npz)
|
| 18 |
+
"test20k_old": ("spira_m7/windows/test20k.bin", "ce0526c62048f8e590a96cca5393a87c2e631f194eb4a2e974c584fd443b6a22", "m7_test20k"),
|
| 19 |
+
"fc2": ("broad/freshcode_v2.bin", "b052096b0c1e2b301cd79921502f85e61912f209fc0027151bbf82237de8c2e3", "bench_fc2"),
|
| 20 |
+
"fresh_en": ("spira_m7/windows/fresh_en.bin", "67ff20b26ce5e3401cea57c817b1a8417e95f6cd131fd8fb631cd5cd8625331a", "bench_fresh_en"),
|
| 21 |
+
"fresh_fr": ("spira_m7/windows/fresh_fr.bin", "875f0906a320e3f7b87e446aab646cf49c74786cb1a0db78b54fa4c62e872715", "bench_fresh_fr"),
|
| 22 |
+
"test_v3": ("corpus_v3/test.bin", "a6730bbe877e7b28a5529793b27a0b59f16d04db05ea895f0ee6d4f91807ca84", "bench_test_v3"),
|
| 23 |
+
"queries": ("spira_m7/windows/queries.bin", "5aab38d62b2f000df6a913d2574ccd314300e350ccc76e71e16768ed5c73b706", "bench_queries"),
|
| 24 |
+
"bg1_test": ("broad/broad_gutenberg_v1/test.bin", "e89725bb94d9f167ffad1f68ae372343a14a1957ae0a1f0a67167aa974ec75a9", "broad_test_bin"),
|
| 25 |
+
}
|
| 26 |
+
MASKS = f"{S}/checker/scale/clean_masks/broad_gutenberg_v1_2134.npz"
|
| 27 |
+
WS = np.zeros(256, bool); WS[[9, 10, 11, 12, 32]] = True
|
| 28 |
+
LOW = np.arange(256, dtype=np.uint8); LOW[65:91] += 32
|
| 29 |
+
RSS_CAP_KB = 295 * 1024
|
| 30 |
+
def rss(): return resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
|
| 31 |
+
def guard():
|
| 32 |
+
if rss() > RSS_CAP_KB: raise SystemExit(f"ABANDON : pic RSS {rss()} kB > {RSS_CAP_KB} kB")
|
| 33 |
+
|
| 34 |
+
def H(a):
|
| 35 |
+
"""a : uint8 ; hash Horner des 64-grammes commençant en 0..len-64."""
|
| 36 |
+
n = len(a) - K + 1
|
| 37 |
+
if n <= 0: return np.zeros(0, np.uint64)
|
| 38 |
+
h = np.zeros(n, np.uint64)
|
| 39 |
+
with np.errstate(over="ignore"):
|
| 40 |
+
for k in range(K): h *= P; h += a[k:k + n]
|
| 41 |
+
return h
|
| 42 |
+
|
| 43 |
+
class Norm:
|
| 44 |
+
"""normalisation en flux ; feed(bytes, offset) -> (octets normalisés uint8, offsets d'origine int64)."""
|
| 45 |
+
def __init__(self): self.prev_ws = False
|
| 46 |
+
def feed(self, a, off):
|
| 47 |
+
a = np.frombuffer(a, np.uint8) if not isinstance(a, np.ndarray) else a
|
| 48 |
+
kcr = a != 13; idx = np.flatnonzero(kcr); b = LOW[a[idx]]; ws = WS[b]; b[ws] = 32
|
| 49 |
+
if len(b) == 0: return b, idx.astype(np.int64)
|
| 50 |
+
pw = np.empty_like(ws); pw[0] = self.prev_ws; pw[1:] = ws[:-1]; keep = ~(ws & pw); self.prev_ws = bool(ws[-1])
|
| 51 |
+
return b[keep], idx[keep].astype(np.int64) + off
|
| 52 |
+
|
| 53 |
+
def form_bytes(raw, form):
|
| 54 |
+
a = np.frombuffer(raw, np.uint8)
|
| 55 |
+
if form == "raw": return a, None
|
| 56 |
+
b, m = Norm().feed(a, 0); return b, m.astype(np.int32)
|
| 57 |
+
|
| 58 |
+
def build_table(wins, form):
|
| 59 |
+
"""wins : {nom: bytes}. Renvoie U (hash uniques triés), REP (offset global d'un représentant dans E), BITS (fenêtres), E, infos."""
|
| 60 |
+
names = list(wins); parts, maps, base, starts = [], {}, 0, {}
|
| 61 |
+
for nm in names:
|
| 62 |
+
b, m = form_bytes(wins.pop(nm), form); parts.append(b.copy() if form == "raw" else b); maps[nm] = m; starts[nm] = (base, len(b)); base += len(b)
|
| 63 |
+
E = np.concatenate(parts); del parts
|
| 64 |
+
# version économe (tient sous prlimit --as 300 Mio) : table pré-allouée, G et B déduits de l'indice de tri
|
| 65 |
+
cnt = np.array([max(starts[nm][1] - K + 1, 0) for nm in names], np.int64); cum = np.concatenate([[0], np.cumsum(cnt)])
|
| 66 |
+
Hc = np.empty(int(cum[-1]), np.uint64)
|
| 67 |
+
for i, nm in enumerate(names):
|
| 68 |
+
b0, L = starts[nm]; Hc[cum[i]:cum[i + 1]] = H(E[b0:b0 + L])
|
| 69 |
+
o = np.argsort(Hc, kind="stable").astype(np.int32); guard(); Hc = Hc[o]; guard()
|
| 70 |
+
first = np.ones(len(Hc), bool); first[1:] = Hc[1:] != Hc[:-1]; U = Hc[first]; del Hc
|
| 71 |
+
wbase = np.array([starts[nm][0] for nm in names], np.int64)
|
| 72 |
+
def gofs(ix): # indice dans Hc concaténé -> (offset global dans E, fenêtre)
|
| 73 |
+
w = np.searchsorted(cum, ix, "right") - 1; return (ix - cum[w] + wbase[w]), w
|
| 74 |
+
fidx = np.flatnonzero(first).astype(np.int32); REP = np.empty(len(fidx), np.int32); BITS = np.zeros(len(fidx), np.uint8)
|
| 75 |
+
W8 = np.empty(len(o), np.uint8)
|
| 76 |
+
for s in range(0, len(o), 1 << 20):
|
| 77 |
+
w = np.searchsorted(cum, o[s:s + (1 << 20)], "right") - 1; W8[s:s + (1 << 20)] = np.left_shift(1, w).astype(np.uint8); del w
|
| 78 |
+
for s in range(0, len(fidx), 1 << 20):
|
| 79 |
+
REP[s:s + (1 << 20)] = gofs(o[fidx[s:s + (1 << 20)]])[0].astype(np.int32)
|
| 80 |
+
BITS[:] = np.bitwise_or.reduceat(W8, fidx); del W8; guard()
|
| 81 |
+
# collisions internes : même hash, octets différents
|
| 82 |
+
first = ~first; dup = np.flatnonzero(first).astype(np.int32); del first; coll = 0; ar = np.arange(K)
|
| 83 |
+
for s in range(0, len(dup), 20000):
|
| 84 |
+
d = dup[s:s + 20000]; g = np.searchsorted(fidx, d, "right") - 1; gd = gofs(o[d])[0]
|
| 85 |
+
coll += int((E[gd[:, None] + ar] != E[REP[g].astype(np.int64)[:, None] + ar]).any(1).sum())
|
| 86 |
+
del o, dup, fidx; guard()
|
| 87 |
+
return U, REP, BITS, E, starts, maps, coll, names
|
| 88 |
+
|
| 89 |
+
def scan(src, U, REP, BITS, E, form, chunk, nwin):
|
| 90 |
+
"""src : chemin ou bytes. Renvoie FOUND (bool sur U), hits (offsets train début/fin, bits), compteurs."""
|
| 91 |
+
FOUND = np.zeros(len(U), bool); hs, he, hb = [], [], []; cand = fp = npos = 0; sha = hashlib.sha256(); ar = np.arange(K)
|
| 92 |
+
nz = Norm(); tail = np.zeros(0, np.uint8); tidx = np.zeros(0, np.int64); pos = 0
|
| 93 |
+
f = open(src, "rb") if isinstance(src, str) else None; mv = memoryview(src) if f is None else None
|
| 94 |
+
while True:
|
| 95 |
+
blk = f.read(chunk) if f else bytes(mv[pos:pos + chunk])
|
| 96 |
+
if not blk: break
|
| 97 |
+
sha.update(blk); a = np.frombuffer(blk, np.uint8)
|
| 98 |
+
if form == "raw": nb, ni = a, None
|
| 99 |
+
else: nb, ni = nz.feed(a, pos)
|
| 100 |
+
buf = np.concatenate([tail, nb])
|
| 101 |
+
if form == "raw": cst = pos - len(tail)
|
| 102 |
+
else: bidx = np.concatenate([tidx, ni])
|
| 103 |
+
h = H(buf); npos += len(h)
|
| 104 |
+
if len(h):
|
| 105 |
+
i = np.searchsorted(U, h); i[i >= len(U)] = 0; hit = np.flatnonzero(U[i] == h)
|
| 106 |
+
if len(hit):
|
| 107 |
+
cand += len(hit); ui = i[hit]; ok = np.ones(len(hit), bool)
|
| 108 |
+
for s in range(0, len(hit), 20000):
|
| 109 |
+
j = hit[s:s + 20000]; r = REP[ui[s:s + 20000]]
|
| 110 |
+
ok[s:s + 20000] = (buf[j[:, None] + ar] == E[r.astype(np.int64)[:, None] + ar]).all(1)
|
| 111 |
+
fp += int((~ok).sum()); hit = hit[ok]; ui = ui[ok]; FOUND[ui] = True
|
| 112 |
+
if form == "raw": st = hit.astype(np.int64) + cst; en = st + K
|
| 113 |
+
else: st = bidx[hit]; en = bidx[hit + K - 1] + 1
|
| 114 |
+
hs.append(st); he.append(en); hb.append(BITS[ui])
|
| 115 |
+
pos += len(blk); keep = min(K - 1, len(buf)); tail = buf[len(buf) - keep:].copy()
|
| 116 |
+
if form != "raw": tidx = bidx[len(bidx) - keep:].copy()
|
| 117 |
+
del h, buf; guard()
|
| 118 |
+
if f: f.close()
|
| 119 |
+
cat = lambda L, dt: np.concatenate(L) if L else np.zeros(0, dt)
|
| 120 |
+
return FOUND, cat(hs, np.int64), cat(he, np.int64), cat(hb, np.uint8), cand, fp, npos, pos, sha.hexdigest()
|
| 121 |
+
|
| 122 |
+
def merge(st, en):
|
| 123 |
+
if len(st) == 0: return np.zeros((0, 2), np.int64)
|
| 124 |
+
o = np.argsort(st, kind="stable"); st, en = st[o], en[o]; em = np.maximum.accumulate(en)
|
| 125 |
+
new = np.ones(len(st), bool); new[1:] = st[1:] > em[:-1]; si = np.flatnonzero(new); ei = np.r_[si[1:], len(st)] - 1
|
| 126 |
+
return np.stack([st[si], em[ei]], 1)
|
| 127 |
+
|
| 128 |
+
def per_window(U, FOUND, E, starts, maps, names, nwin_bytes):
|
| 129 |
+
out, cov_all = {}, {}
|
| 130 |
+
for nm in names:
|
| 131 |
+
b0, L = starts[nm]; h = H(E[b0:b0 + L]); fw = np.zeros(len(h), bool)
|
| 132 |
+
for s0 in range(0, len(h), 1 << 19): fw[s0:s0 + (1 << 19)] = FOUND[np.searchsorted(U, h[s0:s0 + (1 << 19)])]
|
| 133 |
+
nh = int(len(h)); ndf = int(len(np.unique(h[fw]))); n0 = nwin_bytes[nm]; d = np.zeros(n0 + 1, np.int32); s = np.flatnonzero(fw)
|
| 134 |
+
if maps[nm] is None: a0, a1 = s, s + K
|
| 135 |
+
else: m = maps[nm]; a0, a1 = m[s].astype(np.int64), m[s + K - 1].astype(np.int64) + 1
|
| 136 |
+
np.add.at(d, a0, 1); np.add.at(d, a1, -1); np.cumsum(d, dtype=np.int32, out=d); cov = d[:n0] > 0; del d, h
|
| 137 |
+
c = np.zeros(n0 + 1, np.int32); np.cumsum(cov, dtype=np.int32, out=c[1:]); lo = np.zeros(n0, np.int32); lo[K:] = c[:n0 - K]
|
| 138 |
+
np.subtract(c[1:], lo, out=lo); excl = lo > 0; del c, lo
|
| 139 |
+
out[nm] = {"n64": nh, "n64_found": int(fw.sum()), "frac64_found": float(fw.mean()) if nh else 0.0,
|
| 140 |
+
"n64_distinct_found": ndf,
|
| 141 |
+
"eval_bytes": n0, "eval_bytes_covered": int(cov.sum()), "eval_bytes_excl_ctx64": int(excl.sum())}
|
| 142 |
+
cov_all[nm] = (cov, excl)
|
| 143 |
+
return out, cov_all
|
| 144 |
+
|
| 145 |
+
def run(form):
|
| 146 |
+
t0 = time.time(); wins = {}; wsha = {}
|
| 147 |
+
for nm, (rel, sh, _) in WIN.items():
|
| 148 |
+
d = open(f"{S}/{rel}", "rb").read(); s = hashlib.sha256(d).hexdigest(); assert s == sh, (nm, s); wins[nm] = d; wsha[nm] = s
|
| 149 |
+
nbytes = {k: len(v) for k, v in wins.items()}; U, REP, BITS, E, starts, maps, coll, names = build_table(wins, form); del wins
|
| 150 |
+
print(f"{form} table {len(U)} uniques, collisions internes {coll}, rss {rss()} kB, {time.time()-t0:.1f} s", flush=True)
|
| 151 |
+
FOUND, st, en, bits, cand, fp, npos, tb, tsha = scan(TRAIN, U, REP, BITS, E, form, 1 << 20, len(names))
|
| 152 |
+
print(f"{form} scan {tb} o, cand {cand}, fp {fp}, rss {rss()} kB, {time.time()-t0:.1f} s", flush=True)
|
| 153 |
+
del REP, BITS; guard(); pw, covs = per_window(U, FOUND, E, starts, maps, names, nbytes)
|
| 154 |
+
M = np.load(MASKS); tr = {}; rng_all = merge(st, en)
|
| 155 |
+
for i, nm in enumerate(names):
|
| 156 |
+
sel = (bits & np.uint8(1 << i)) > 0; s1, e1 = st[sel], en[sel]; R = merge(s1, e1)
|
| 157 |
+
cov, excl = covs[nm]; mk = WIN[nm][2]; mc, me = M[f"{mk}__covered"], M[f"{mk}__excl"]
|
| 158 |
+
pw[nm].update({"window_sha256": wsha[nm], "train_positions_matched": int(sel.sum()),
|
| 159 |
+
"train_positions_seg_bg1": int((s1 < SEG2).sum()), "train_positions_seg_multilang": int((s1 >= SEG2).sum()),
|
| 160 |
+
"train_ranges_merged": int(len(R)), "train_bytes_in_ranges": int((R[:, 1] - R[:, 0]).sum()) if len(R) else 0,
|
| 161 |
+
"train_range_offsets_sample": [[int(a), int(b)] for a, b in R[:3]] + ([[int(a), int(b)] for a, b in R[-2:]] if len(R) > 3 else []),
|
| 162 |
+
"xcheck_mask_2134": {"key": mk, "mask_covered": int(mc.sum()), "mask_excl": int(me.sum()),
|
| 163 |
+
"covered_identical_to_mask": bool(np.array_equal(cov, mc)), "covered_outside_mask_excl": int((cov & ~me).sum()),
|
| 164 |
+
"excl_identical_to_mask": bool(np.array_equal(excl, me))}})
|
| 165 |
+
tr[nm] = R
|
| 166 |
+
np.savez_compressed(f"{OD}/masks_{form}.npz", **{f"{nm}__covered": np.packbits(covs[nm][0]) for nm in names},
|
| 167 |
+
**{f"{nm}__excl_ctx64": np.packbits(covs[nm][1]) for nm in names}, **{f"{nm}__len": np.int64(nbytes[nm]) for nm in names})
|
| 168 |
+
np.savez_compressed(f"{OD}/train_ranges_{form}.npz", all=rng_all, **{nm: tr[nm] for nm in names})
|
| 169 |
+
sha = lambda p: hashlib.sha256(open(p, "rb").read()).hexdigest()
|
| 170 |
+
out = {"form": form, "k": K, "hash": "Horner mod 2^64 P=0x9E3779B97F4A7C15 (logique dedup64.py 4bee4293…), confirmation octet à octet",
|
| 171 |
+
"normalisation": None if form == "raw" else "suppr. \\r ; A-Z->a-z ASCII ; suites [ \\t\\n\\v\\f] -> 1 espace ; en flux",
|
| 172 |
+
"train": TRAIN, "train_bytes": tb, "train_sha256": tsha, "train_sha_ok": tsha == TRAIN_SHA, "train_64gram_positions_hashed": npos,
|
| 173 |
+
"table_unique_hashes": int(len(U)), "table_internal_collisions": coll, "candidates": cand, "hash_false_positives_rejected": fp,
|
| 174 |
+
"train_positions_matched_any": int(len(st)), "train_ranges_merged_any": int(len(rng_all)),
|
| 175 |
+
"train_bytes_in_ranges_any": int((rng_all[:, 1] - rng_all[:, 0]).sum()) if len(rng_all) else 0,
|
| 176 |
+
"train_positions_seg_multilang_any": int((st >= SEG2).sum()), "windows": pw,
|
| 177 |
+
"files": {f"masks_{form}.npz": sha(f"{OD}/masks_{form}.npz"), f"train_ranges_{form}.npz": sha(f"{OD}/train_ranges_{form}.npz")},
|
| 178 |
+
"elapsed_s": round(time.time() - t0, 1), "peak_rss_kB": rss(), "script_sha256": sha(os.path.abspath(__file__))}
|
| 179 |
+
json.dump(out, open(f"{OD}/dedup64_{form}.json", "w"), indent=1)
|
| 180 |
+
print(json.dumps({k: v["n64_found"] for k, v in pw.items()}), out["elapsed_s"], "s", out["peak_rss_kB"], "kB", flush=True)
|
| 181 |
+
|
| 182 |
+
def selftest():
|
| 183 |
+
rng = np.random.default_rng(7); res = {}; ok_all = True
|
| 184 |
+
def rb(n): return bytes(rng.integers(0, 256, n, dtype=np.uint8))
|
| 185 |
+
def tx(n): return bytes(rng.choice(np.frombuffer(b"abcdefghij KLMNOP\n\r\t.,", np.uint8), n))
|
| 186 |
+
# T1 hash : Horner vectoriel == boucle Python
|
| 187 |
+
a = np.frombuffer(rb(300), np.uint8); h = H(a); M64 = (1 << 64) - 1
|
| 188 |
+
def hp(x):
|
| 189 |
+
v = 0
|
| 190 |
+
for c in x: v = (v * 0x9E3779B97F4A7C15 + int(c)) & M64
|
| 191 |
+
return v
|
| 192 |
+
res["T1_hash_vs_python"] = all(int(h[i]) == hp(a[i:i + K]) for i in (0, 1, 100, 236));
|
| 193 |
+
# T2 normalisation en flux == normalisation globale, plusieurs tailles de bloc (frontières au milieu de suites d'espaces / \r\n)
|
| 194 |
+
t = tx(5000) + b" \r\n\r\n X" + tx(3000); ref, refi = Norm().feed(np.frombuffer(t, np.uint8), 0)
|
| 195 |
+
py = bytes(t).replace(b"\r", b"").lower(); import re; py = re.sub(rb"[ \t\n\x0b\x0c]+", b" ", py)
|
| 196 |
+
t2 = True
|
| 197 |
+
for cs in (1, 7, 63, 64, 100, 4096):
|
| 198 |
+
nz = Norm(); parts, idxs = [], []
|
| 199 |
+
for s in range(0, len(t), cs): b, i = nz.feed(np.frombuffer(t[s:s + cs], np.uint8), s); parts.append(b); idxs.append(i)
|
| 200 |
+
t2 &= np.array_equal(np.concatenate(parts), ref) and np.array_equal(np.concatenate(idxs), refi)
|
| 201 |
+
res["T2_norm_stream_eq_global_eq_regex"] = bool(t2 and ref.tobytes() == py)
|
| 202 |
+
# T3/T4 : doublons plantés à cheval sur une frontière de bloc (raw exact ; norm : casse/espaces/\r modifiés)
|
| 203 |
+
ev = {"w0": tx(2000), "w1": tx(1500)}; CH = 1000
|
| 204 |
+
g_raw = ev["w0"][300:300 + K]
|
| 205 |
+
g_n = ev["w1"][500:500 + 80]; gnorm = Norm().feed(np.frombuffer(g_n, np.uint8), 0)[0].tobytes()
|
| 206 |
+
variant = gnorm.upper().replace(b" ", b" \r\n\t ") # même forme normalisée, octets bruts différents
|
| 207 |
+
train = bytearray(tx(10000))
|
| 208 |
+
train = train.replace(g_raw, b"").replace(g_raw[:32], b"") # pas d'occurrence fortuite
|
| 209 |
+
p1 = 3 * CH - 30; train[p1:p1 + K] = g_raw # raw à cheval sur 3000
|
| 210 |
+
p2 = 6 * CH - 40; train[p2:p2 + len(variant)] = variant # variante à cheval sur 6000
|
| 211 |
+
p3 = 8 * CH - 10; train[p3:p3 + 63] = g_raw[:63] # quasi-doublon 63 o : ne doit PAS compter en raw
|
| 212 |
+
train = bytes(train)
|
| 213 |
+
for form in ("raw", "norm"):
|
| 214 |
+
U, REP, BITS, E, starts, maps, coll, names = build_table(dict(ev), form)
|
| 215 |
+
FOUND, st, en, bits, cand, fp, npos, tb, tsha = scan(train, U, REP, BITS, E, form, CH, len(names))
|
| 216 |
+
# brute force : ensemble Python de tous les 64-grammes de la forme
|
| 217 |
+
def grams(x): return {x[i:i + K] for i in range(len(x) - K + 1)}
|
| 218 |
+
fx = (lambda x: x) if form == "raw" else (lambda x: Norm().feed(np.frombuffer(x, np.uint8), 0)[0].tobytes())
|
| 219 |
+
eg = grams(fx(ev["w0"])) | grams(fx(ev["w1"])); tn = fx(train); bf = sum(1 for i in range(len(tn) - K + 1) if tn[i:i + K] in eg)
|
| 220 |
+
nfull = 0
|
| 221 |
+
for c in (1 << 20,):
|
| 222 |
+
F2 = scan(train, U, REP, BITS, E, form, c, len(names)); nfull = len(F2[1])
|
| 223 |
+
r = {"hits": int(len(st)), "bruteforce": bf, "one_chunk_hits": nfull, "starts": sorted(set(int(x) for x in st))[:5], "fp": fp, "coll": coll, "tsha_ok": tsha == hashlib.sha256(train).hexdigest()}
|
| 224 |
+
if form == "raw": r["planted_raw_found_at_p1"] = p1 in set(st.tolist()); r["near_miss_63_not_found"] = p3 not in set(st.tolist())
|
| 225 |
+
else: r["planted_variant_found_in_p2_range"] = bool(((st >= p2) & (st < p2 + len(variant))).any()); r["info_raw64_plant_seen_in_norm"] = bool(((st >= p1 - 5) & (st <= p1 + 5)).any())
|
| 226 |
+
r["pass"] = (r["hits"] == bf == nfull and r["tsha_ok"] and fp == 0 and all(v for k, v in r.items() if k.startswith("planted") or k.startswith("near")))
|
| 227 |
+
if form == "raw": r["pass"] &= r["hits"] >= 1
|
| 228 |
+
res[f"T3_{form}_chunk_boundary"] = r
|
| 229 |
+
ok_all = res["T1_hash_vs_python"] and res["T2_norm_stream_eq_global_eq_regex"] and res["T3_raw_chunk_boundary"]["pass"] and res["T3_norm_chunk_boundary"]["pass"]
|
| 230 |
+
res["ALL_PASS"] = bool(ok_all); res["peak_rss_kB"] = rss()
|
| 231 |
+
json.dump(res, open(f"{OD}/selftest.json", "w"), indent=1); print(json.dumps(res), flush=True)
|
| 232 |
+
|
| 233 |
+
if __name__ == "__main__":
|
| 234 |
+
selftest() if sys.argv[1] == "selftest" else run(sys.argv[1])
|
v3_scale/checker/recount/corpus_diverse_v1_dedup/run.sh
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# Checker — lance une forme : prlimit --as 2 Gio (filet), nice 19, OMP 1 ; CHIEN DE GARDE RSS : sonde VmRSS toutes les 1 s,
|
| 3 |
+
# tue UNIQUEMENT son propre processus python si VmRSS > 300 Mo (307200 kB). Pic VmHWM noté dans run_<form>.mem.
|
| 4 |
+
export TZ=America/Toronto OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 MALLOC_MMAP_THRESHOLD_=65536 MALLOC_TRIM_THRESHOLD_=0
|
| 5 |
+
cd "$(dirname "$0")"; F=$1; CAP=307200
|
| 6 |
+
echo "$(date '+%F %T %Z') START $F" > run_$F.mem
|
| 7 |
+
prlimit --as=2147483648 nice -n 19 /workspace/SPIRA-venv/bin/python -u dedup64_div1.py $F > run_$F.log 2>&1 & P=$!
|
| 8 |
+
pk=0; killed=0
|
| 9 |
+
while kill -0 $P 2>/dev/null; do
|
| 10 |
+
r=$(awk '/VmRSS/{print $2}' /proc/$P/status 2>/dev/null); h=$(awk '/VmHWM/{print $2}' /proc/$P/status 2>/dev/null)
|
| 11 |
+
[ -n "$h" ] && [ "$h" -gt "$pk" ] && pk=$h
|
| 12 |
+
if [ -n "$r" ] && [ "$r" -gt $CAP ]; then kill $P; killed=1; echo "$(date '+%T') WATCHDOG kill own pid $P VmRSS=$r kB" >> run_$F.mem; fi
|
| 13 |
+
sleep 1
|
| 14 |
+
done
|
| 15 |
+
wait $P; rc=$?; echo "$(date '+%F %T %Z') END $F rc=$rc killed=$killed VmHWM_polled_kB=$pk" >> run_$F.mem
|