Token Classification
Transformers
ONNX
Safetensors
English
Japanese
Chinese
bert
anime
filename-parsing
Eval Results (legacy)
Instructions to use ModerRAS/AniFileBERT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use ModerRAS/AniFileBERT with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("token-classification", model="ModerRAS/AniFileBERT")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForTokenClassification tokenizer = AutoTokenizer.from_pretrained("ModerRAS/AniFileBERT") model = AutoModelForTokenClassification.from_pretrained("ModerRAS/AniFileBERT", device_map="auto") - Notebooks
- Google Colab
- Kaggle
Simplify title-boundary title span heuristic
Browse files
AGENTS.md
CHANGED
|
@@ -134,16 +134,18 @@ cargo run --release --manifest-path tools\rust_dmhy_template_apply\Cargo.toml --
|
|
| 134 |
```
|
| 135 |
|
| 136 |
For reviewer calibration, run stratified samples before full review. Use
|
| 137 |
-
`--title-boundary-heuristic-contains` to inspect high-
|
| 138 |
-
|
| 139 |
-
the ambiguous merge review
|
|
|
|
|
|
|
| 140 |
|
| 141 |
```powershell
|
| 142 |
cargo run --release --manifest-path tools\rust_dmhy_template_apply\Cargo.toml -- `
|
| 143 |
--review-title-boundaries-pi-rpc `
|
| 144 |
-
--recipes reports\dmhy_template_recipes.full_top5000.
|
| 145 |
-
--title-boundary-decisions-output reports\
|
| 146 |
-
--title-boundary-heuristic-contains
|
| 147 |
--title-boundary-min-similarity 0.85 `
|
| 148 |
--title-boundary-max-similarity 1.0 `
|
| 149 |
--threads 4 `
|
|
|
|
| 134 |
```
|
| 135 |
|
| 136 |
For reviewer calibration, run stratified samples before full review. Use
|
| 137 |
+
`--title-boundary-heuristic-contains` to inspect high-similarity adjacent-title
|
| 138 |
+
merges, structural keeps, and path-boundary keeps that are normally skipped by
|
| 139 |
+
the ambiguous merge review. The old high-similarity duplicate/alias keep
|
| 140 |
+
heuristic was removed after Pi RPC review found it over-preserved title
|
| 141 |
+
continuations:
|
| 142 |
|
| 143 |
```powershell
|
| 144 |
cargo run --release --manifest-path tools\rust_dmhy_template_apply\Cargo.toml -- `
|
| 145 |
--review-title-boundaries-pi-rpc `
|
| 146 |
+
--recipes reports\dmhy_template_recipes.full_top5000.seed.jsonl `
|
| 147 |
+
--title-boundary-decisions-output reports\dmhy_title_boundary_pi_rpc_adjacent_highsim_sample.jsonl `
|
| 148 |
+
--title-boundary-heuristic-contains merge_adjacent_title_continuation `
|
| 149 |
--title-boundary-min-similarity 0.85 `
|
| 150 |
--title-boundary-max-similarity 1.0 `
|
| 151 |
--threads 4 `
|
docs/title_boundary_heuristic_experiments.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Title-Boundary Heuristic Experiments
|
| 2 |
+
|
| 3 |
+
This note records deterministic Rust heuristic changes and Pi RPC reviewer evidence
|
| 4 |
+
for DMHY template `title_spans` generation. The reviewer output is evidence only;
|
| 5 |
+
recipes and training JSONL are changed only by Rust code.
|
| 6 |
+
|
| 7 |
+
## Baseline
|
| 8 |
+
|
| 9 |
+
Input recipe evidence:
|
| 10 |
+
|
| 11 |
+
- `reports/dmhy_template_recipes.full_top5000.title_boundary_trial.seed.jsonl`
|
| 12 |
+
- total title-boundary decisions: `5631`
|
| 13 |
+
|
| 14 |
+
Decision distribution:
|
| 15 |
+
|
| 16 |
+
| decision | count |
|
| 17 |
+
| --- | ---: |
|
| 18 |
+
| `merge_dissimilar_title_continuation` | 4661 |
|
| 19 |
+
| `keep_similar_duplicate_or_alias` | 463 |
|
| 20 |
+
| `keep_structural_boundary` | 502 |
|
| 21 |
+
| `keep_path_boundary` | 5 |
|
| 22 |
+
|
| 23 |
+
Pi RPC stratified sample, `--threads 4`:
|
| 24 |
+
|
| 25 |
+
| stratum | rows | model result | note |
|
| 26 |
+
| --- | ---: | --- | --- |
|
| 27 |
+
| ambiguous merge, similarity `0.25..0.85` | 20 | 20 merge | Good. Reviewer cited concrete title-word pairings. |
|
| 28 |
+
| high-sim `keep_similar_duplicate_or_alias`, similarity `0.85..1.0` | 20 | 19 merge, 1 parse-error | Bad baseline heuristic. Examples such as `Asobi ni Iku yo!`, `Code Geass ~Akito the Exiled~`, `Yagate Kimi ni Naru`, and `Big Order` were wrongly kept separate by the heuristic. |
|
| 29 |
+
| structural keep | 20 | 18 keep, 1 merge, 1 skip | Mostly good. Covers category+title, multilingual aliases, and distinct fields. |
|
| 30 |
+
| path keep | 5 | 5 keep | Good. Covers path duplicate/category boundaries. |
|
| 31 |
+
|
| 32 |
+
Conclusion: `keep_similar_duplicate_or_alias` was too broad because it used max
|
| 33 |
+
literal similarity. Short connector repeats (`no`, `wa`, `ni`, `the`, `of`) and
|
| 34 |
+
repeated title words inflated similarity to `1.0` even for ordinary contiguous
|
| 35 |
+
title phrases.
|
| 36 |
+
|
| 37 |
+
## Experiment 1: strict substantive duplicate keep
|
| 38 |
+
|
| 39 |
+
Change tried:
|
| 40 |
+
|
| 41 |
+
- Keep adjacent `TITLE SEP TITLE` only when top literals include a substantive
|
| 42 |
+
duplicate/near-duplicate pair.
|
| 43 |
+
- Ignore short connectors and literals with normalized length `< 6`.
|
| 44 |
+
|
| 45 |
+
Generated recipe output:
|
| 46 |
+
|
| 47 |
+
- `reports/dmhy_template_recipes.full_top5000.strictdup.seed.jsonl`
|
| 48 |
+
|
| 49 |
+
Decision distribution:
|
| 50 |
+
|
| 51 |
+
| decision | count |
|
| 52 |
+
| --- | ---: |
|
| 53 |
+
| `merge_dissimilar_title_continuation` | 4661 |
|
| 54 |
+
| `merge_adjacent_title_continuation` | 444 |
|
| 55 |
+
| `keep_similar_duplicate_or_alias` | 19 |
|
| 56 |
+
| `keep_structural_boundary` | 502 |
|
| 57 |
+
| `keep_path_boundary` | 5 |
|
| 58 |
+
|
| 59 |
+
Pi RPC review of all 19 remaining `keep_similar_duplicate_or_alias` decisions:
|
| 60 |
+
|
| 61 |
+
| rows | model result |
|
| 62 |
+
| ---: | --- |
|
| 63 |
+
| 19 | 19 merge |
|
| 64 |
+
|
| 65 |
+
Examples the reviewer judged as merge:
|
| 66 |
+
|
| 67 |
+
- `Air In Summer`, `Assault Lily BOUQUET`
|
| 68 |
+
- `Aoki Hagane no Arpeggio Ars Nova`
|
| 69 |
+
- `Shoujo Kageki Revue Starlight`
|
| 70 |
+
- `Motto! Ojamajo Doremi`
|
| 71 |
+
- `Fate stay night Heaven's Feel`
|
| 72 |
+
- `Arafou Otoko no Isekai Tsuuhan Seikatsu`
|
| 73 |
+
- `Watashi, Nouryoku wa Heikinchi de tte Itta yo ne!`
|
| 74 |
+
|
| 75 |
+
Conclusion: strict duplicate evidence still produced false keeps. The repeated
|
| 76 |
+
literal was often a real repeated word inside one title phrase or a top-literal
|
| 77 |
+
artifact, not a duplicate/alias boundary.
|
| 78 |
+
|
| 79 |
+
## Experiment 2: merge all adjacent separator-only title slots
|
| 80 |
+
|
| 81 |
+
Final change:
|
| 82 |
+
|
| 83 |
+
- `TITLE PATH TITLE` remains `keep_path_boundary`.
|
| 84 |
+
- Non-separator structural boundaries remain `keep_structural_boundary`.
|
| 85 |
+
- Every separator-only adjacent title boundary, `TITLE SEP TITLE`, now merges.
|
| 86 |
+
- Low-similarity merges keep the old decision name
|
| 87 |
+
`merge_dissimilar_title_continuation`.
|
| 88 |
+
- High-similarity merges use `merge_adjacent_title_continuation`.
|
| 89 |
+
- `keep_similar_duplicate_or_alias` is no longer emitted by the deterministic
|
| 90 |
+
heuristic.
|
| 91 |
+
|
| 92 |
+
Generated recipe output:
|
| 93 |
+
|
| 94 |
+
- `reports/dmhy_template_recipes.full_top5000.mergeall.seed.jsonl`
|
| 95 |
+
|
| 96 |
+
Decision distribution:
|
| 97 |
+
|
| 98 |
+
| decision | count |
|
| 99 |
+
| --- | ---: |
|
| 100 |
+
| `merge_dissimilar_title_continuation` | 4661 |
|
| 101 |
+
| `merge_adjacent_title_continuation` | 463 |
|
| 102 |
+
| `keep_structural_boundary` | 502 |
|
| 103 |
+
| `keep_path_boundary` | 5 |
|
| 104 |
+
|
| 105 |
+
Pi RPC sample of high-similarity `merge_adjacent_title_continuation` decisions:
|
| 106 |
+
|
| 107 |
+
| rows | model result |
|
| 108 |
+
| ---: | --- |
|
| 109 |
+
| 30 | 29 merge, 1 parse-error |
|
| 110 |
+
|
| 111 |
+
The reviewer cited concrete title continuations such as:
|
| 112 |
+
|
| 113 |
+
- `Asobi ni Iku yo!`
|
| 114 |
+
- `Code Geass ~Akito the Exiled~`
|
| 115 |
+
- `Kami nomi zo Shiru Sekai`
|
| 116 |
+
- `Yagate Kimi ni Naru`
|
| 117 |
+
- `Big Order`
|
| 118 |
+
- `Gate Jieitai Kanochi nite Kaku Tatakaeri`
|
| 119 |
+
- `JoJo's Bizarre Adventure - Stardust Crusaders`
|
| 120 |
+
|
| 121 |
+
Conclusion: merge-all adjacent separator-only title slots is the best of the
|
| 122 |
+
tried heuristics. It matches Pi RPC evidence and simplifies downstream synthetic
|
| 123 |
+
title-span replacement.
|
| 124 |
+
|
| 125 |
+
## Synthetic generation smoke
|
| 126 |
+
|
| 127 |
+
Generated schema v2 synthetic augmentation with merge-all recipes:
|
| 128 |
+
|
| 129 |
+
- `data/schema_v2_synthetic_aug.mergeall.jsonl`
|
| 130 |
+
- `data/schema_v2_synthetic_aug.mergeall.manifest.json`
|
| 131 |
+
|
| 132 |
+
Validator passed. Manifest summary:
|
| 133 |
+
|
| 134 |
+
| metric | value |
|
| 135 |
+
| --- | ---: |
|
| 136 |
+
| `generated_rows` | 49998 |
|
| 137 |
+
| `numeric_title_rows` | 30000 |
|
| 138 |
+
| `path_rows` | 19998 |
|
| 139 |
+
| `path_series_rows` | 15000 |
|
| 140 |
+
| `path_movie_rows` | 1666 |
|
| 141 |
+
| `path_special_rows` | 1666 |
|
| 142 |
+
| `path_confuser_rows` | 1666 |
|
| 143 |
+
| `dropped_media_kind_mismatch` | 19611 |
|
| 144 |
+
|
| 145 |
+
## Commands
|
| 146 |
+
|
| 147 |
+
Pi RPC high-sim adjacent merge sample:
|
| 148 |
+
|
| 149 |
+
```powershell
|
| 150 |
+
cargo run --release --manifest-path tools\rust_dmhy_template_apply\Cargo.toml -- `
|
| 151 |
+
--review-title-boundaries-pi-rpc `
|
| 152 |
+
--recipes reports\dmhy_template_recipes.full_top5000.mergeall.seed.jsonl `
|
| 153 |
+
--title-boundary-decisions-output reports\dmhy_title_boundary_pi_rpc_mergeall.adjacent_highsim.jsonl `
|
| 154 |
+
--title-boundary-heuristic-contains merge_adjacent_title_continuation `
|
| 155 |
+
--title-boundary-min-similarity 0.85 `
|
| 156 |
+
--title-boundary-max-similarity 1.0 `
|
| 157 |
+
--threads 4 `
|
| 158 |
+
--limit 30
|
| 159 |
+
```
|
| 160 |
+
|
| 161 |
+
Synthetic smoke:
|
| 162 |
+
|
| 163 |
+
```powershell
|
| 164 |
+
cargo run --release --manifest-path tools\schema_v2_synthetic_augment\Cargo.toml --bin schema_v2_synthetic_augment -- `
|
| 165 |
+
--recipes reports\dmhy_template_recipes.full_top5000.mergeall.seed.jsonl `
|
| 166 |
+
--label-schema-file label_schema.json `
|
| 167 |
+
--numeric-title-seeds data\synthetic_numeric_titles.txt `
|
| 168 |
+
--path-prefix-seeds data\synthetic_path_prefixes.txt `
|
| 169 |
+
--limit-templates 3000 `
|
| 170 |
+
--max-rows 50000 `
|
| 171 |
+
--output data\schema_v2_synthetic_aug.mergeall.jsonl `
|
| 172 |
+
--manifest-output data\schema_v2_synthetic_aug.mergeall.manifest.json
|
| 173 |
+
|
| 174 |
+
cargo run --release --manifest-path tools\schema_v2_synthetic_augment\Cargo.toml --bin validate_synthetic_aug_jsonl -- `
|
| 175 |
+
--input data\schema_v2_synthetic_aug.mergeall.jsonl `
|
| 176 |
+
--manifest data\schema_v2_synthetic_aug.mergeall.manifest.json
|
| 177 |
+
```
|
tools/rust_dmhy_template_apply/README.md
CHANGED
|
@@ -84,12 +84,13 @@ cargo run --release --manifest-path tools\rust_dmhy_template_apply\Cargo.toml --
|
|
| 84 |
For stratified audits, select heuristic strata explicitly:
|
| 85 |
|
| 86 |
```powershell
|
| 87 |
-
# High-similarity
|
|
|
|
| 88 |
cargo run --release --manifest-path tools\rust_dmhy_template_apply\Cargo.toml -- `
|
| 89 |
--review-title-boundaries-pi-rpc `
|
| 90 |
--recipes reports\dmhy_template_recipes.full_top5000.seed.jsonl `
|
| 91 |
-
--title-boundary-decisions-output reports\
|
| 92 |
-
--title-boundary-heuristic-contains
|
| 93 |
--title-boundary-min-similarity 0.85 `
|
| 94 |
--title-boundary-max-similarity 1.0 `
|
| 95 |
--threads 4 `
|
|
|
|
| 84 |
For stratified audits, select heuristic strata explicitly:
|
| 85 |
|
| 86 |
```powershell
|
| 87 |
+
# High-similarity adjacent-title merges. The old high-similarity keep heuristic
|
| 88 |
+
# was removed after Pi RPC review found it over-preserved title continuations.
|
| 89 |
cargo run --release --manifest-path tools\rust_dmhy_template_apply\Cargo.toml -- `
|
| 90 |
--review-title-boundaries-pi-rpc `
|
| 91 |
--recipes reports\dmhy_template_recipes.full_top5000.seed.jsonl `
|
| 92 |
+
--title-boundary-decisions-output reports\dmhy_title_boundary_pi_rpc_adjacent_highsim.jsonl `
|
| 93 |
+
--title-boundary-heuristic-contains merge_adjacent_title_continuation `
|
| 94 |
--title-boundary-min-similarity 0.85 `
|
| 95 |
--title-boundary-max-similarity 1.0 `
|
| 96 |
--threads 4 `
|
tools/rust_dmhy_template_apply/src/main.rs
CHANGED
|
@@ -824,7 +824,7 @@ fn compute_title_span_metadata(
|
|
| 824 |
let mut spans: Vec<Vec<usize>> = Vec::new();
|
| 825 |
let mut decisions: Vec<Value> = Vec::new();
|
| 826 |
let mut current_span: Vec<usize> = Vec::new();
|
| 827 |
-
let
|
| 828 |
|
| 829 |
for title_index in title_indices {
|
| 830 |
if current_span.is_empty() {
|
|
@@ -850,12 +850,12 @@ fn compute_title_span_metadata(
|
|
| 850 |
}));
|
| 851 |
spans.push(current_span);
|
| 852 |
current_span = vec![title_index];
|
| 853 |
-
} else if only_separators_between
|
| 854 |
decisions.push(json!({
|
| 855 |
"left_role_index": previous,
|
| 856 |
"right_role_index": title_index,
|
| 857 |
"similarity": similarity,
|
| 858 |
-
"decision": "merge_dissimilar_title_continuation",
|
| 859 |
"source": "heuristic",
|
| 860 |
}));
|
| 861 |
current_span.push(title_index);
|
|
@@ -5325,7 +5325,7 @@ mod tests {
|
|
| 5325 |
}
|
| 5326 |
|
| 5327 |
#[test]
|
| 5328 |
-
fn
|
| 5329 |
let key = "TEXT SEP TEXT SEP EPISODE";
|
| 5330 |
let roles = suggested_roles(key);
|
| 5331 |
let mut cluster = Cluster::default();
|
|
@@ -5333,8 +5333,27 @@ mod tests {
|
|
| 5333 |
cluster.position_literals[0].insert("Frieren".to_string(), 10);
|
| 5334 |
cluster.position_literals[2].insert("Frieren".to_string(), 10);
|
| 5335 |
let (spans, decisions) = compute_title_span_metadata(key, &roles, &cluster);
|
| 5336 |
-
assert_eq!(spans.len(),
|
| 5337 |
-
assert_eq!(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5338 |
}
|
| 5339 |
|
| 5340 |
#[test]
|
|
|
|
| 824 |
let mut spans: Vec<Vec<usize>> = Vec::new();
|
| 825 |
let mut decisions: Vec<Value> = Vec::new();
|
| 826 |
let mut current_span: Vec<usize> = Vec::new();
|
| 827 |
+
let low_similarity_threshold = 0.72;
|
| 828 |
|
| 829 |
for title_index in title_indices {
|
| 830 |
if current_span.is_empty() {
|
|
|
|
| 850 |
}));
|
| 851 |
spans.push(current_span);
|
| 852 |
current_span = vec![title_index];
|
| 853 |
+
} else if only_separators_between {
|
| 854 |
decisions.push(json!({
|
| 855 |
"left_role_index": previous,
|
| 856 |
"right_role_index": title_index,
|
| 857 |
"similarity": similarity,
|
| 858 |
+
"decision": if similarity < low_similarity_threshold { "merge_dissimilar_title_continuation" } else { "merge_adjacent_title_continuation" },
|
| 859 |
"source": "heuristic",
|
| 860 |
}));
|
| 861 |
current_span.push(title_index);
|
|
|
|
| 5325 |
}
|
| 5326 |
|
| 5327 |
#[test]
|
| 5328 |
+
fn title_span_metadata_merges_similar_adjacent_titles() {
|
| 5329 |
let key = "TEXT SEP TEXT SEP EPISODE";
|
| 5330 |
let roles = suggested_roles(key);
|
| 5331 |
let mut cluster = Cluster::default();
|
|
|
|
| 5333 |
cluster.position_literals[0].insert("Frieren".to_string(), 10);
|
| 5334 |
cluster.position_literals[2].insert("Frieren".to_string(), 10);
|
| 5335 |
let (spans, decisions) = compute_title_span_metadata(key, &roles, &cluster);
|
| 5336 |
+
assert_eq!(spans.len(), 1, "{spans:?} {decisions:?}");
|
| 5337 |
+
assert_eq!(
|
| 5338 |
+
decisions[0]["decision"],
|
| 5339 |
+
"merge_adjacent_title_continuation"
|
| 5340 |
+
);
|
| 5341 |
+
}
|
| 5342 |
+
|
| 5343 |
+
#[test]
|
| 5344 |
+
fn title_span_metadata_merges_high_similarity_short_connectors() {
|
| 5345 |
+
let key = "TEXT SEP TEXT SEP EPISODE";
|
| 5346 |
+
let roles = suggested_roles(key);
|
| 5347 |
+
let mut cluster = Cluster::default();
|
| 5348 |
+
cluster.position_literals = vec![HashMap::new(); key.split_whitespace().count()];
|
| 5349 |
+
cluster.position_literals[0].insert("no".to_string(), 10);
|
| 5350 |
+
cluster.position_literals[2].insert("no".to_string(), 10);
|
| 5351 |
+
let (spans, decisions) = compute_title_span_metadata(key, &roles, &cluster);
|
| 5352 |
+
assert_eq!(spans.len(), 1, "{spans:?} {decisions:?}");
|
| 5353 |
+
assert_eq!(
|
| 5354 |
+
decisions[0]["decision"],
|
| 5355 |
+
"merge_adjacent_title_continuation"
|
| 5356 |
+
);
|
| 5357 |
}
|
| 5358 |
|
| 5359 |
#[test]
|