Download source/src/vimeml/data/corpus_parts.py from Voltline/vimeml-tiny-ja-v1: direct link, hf CLI and curl.
- Browser
- Download file 10.2 kB
-
https://huggingface.co/Voltline/vimeml-tiny-ja-v1/resolve/main/source/src/vimeml/data/corpus_parts.py
- Command line
-
hf download hf://Voltline/vimeml-tiny-ja-v1/source/src/vimeml/data/corpus_parts.py
-
curl -L -o corpus_parts.py https://huggingface.co/Voltline/vimeml-tiny-ja-v1/resolve/main/source/src/vimeml/data/corpus_parts.py
10.2 kB
| """Portable input plans and shared operations for independent corpus parts.""" | |
| import json | |
| import sqlite3 | |
| import sys | |
| import tomllib | |
| from collections import Counter | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parents[3] | |
| sys.path.insert(0, str(ROOT / "src")) | |
| from vimeml.data.build import validate, file_sha, sha, display_path, SCHEMA, dump_line, dump_json | |
| from vimeml.data.clean import clean_block | |
| from vimeml.data.segment import restore_linebreaks, split_sentences | |
| from vimeml.data.annotations import load_annotations, document_annotations, match_fragment | |
| PART_SCHEMA_VERSION = 1 | |
| AUDITS = ("review_blocks", "dropped_blocks", "fragments") | |
| def text_sha(path): | |
| # Git may check out CRLF on Windows and LF on Mac. These text files have | |
| # identical semantics; hash normalized UTF-8 text rather than platform bytes. | |
| return sha(path.read_text(encoding="utf-8-sig")) | |
| def load_plan(config_path): | |
| config = tomllib.loads(config_path.read_text(encoding="utf-8-sig")) | |
| validate(config) | |
| paths = config["inputs"]["fineweb_paths"] | |
| if not isinstance(paths, list) or not paths or any(not isinstance(p, str) for p in paths): | |
| raise ValueError("Partition builds require an explicit fineweb_paths list.") | |
| inventory = [(p, "fineweb", config["build"]["fineweb_documents_per_shard"]) for p in sorted(paths)] | |
| inventory.append((config["inputs"]["tatoeba_path"], "tatoeba", config["build"]["tatoeba_documents"])) | |
| if len({p for p, _, _ in inventory}) != len(inventory): | |
| raise ValueError("Input paths must be unique.") | |
| for p, _, _ in inventory: | |
| if Path(p).is_absolute() or not (ROOT / p).resolve().is_relative_to(ROOT): | |
| raise ValueError("Input paths must be portable paths inside the repository.") | |
| policy_paths = {} | |
| if config["build"]["quality_mode"] == "rules_with_approved_annotations": | |
| policy_paths["annotations"] = ROOT / config["review"]["annotations"] | |
| policy_paths["calibration_ids"] = ROOT / config["inputs"]["calibration_ids"] | |
| calibration_ids = json.loads(policy_paths["calibration_ids"].read_text(encoding="utf-8-sig")) | |
| if not isinstance(calibration_ids, list) or any(not isinstance(p, str) for p in calibration_ids): | |
| raise ValueError("calibration_ids must contain a JSON list of document IDs.") | |
| policy_hashes = {key: text_sha(path) for key, path in policy_paths.items()} | |
| names = ("build", "readers", "clean", "segment", "annotations", "corpus_parts", "corpus_export", "preprocess_part", "merge_parts") | |
| code_hashes = {f"src/vimeml/data/{name}.py": text_sha(ROOT / f"src/vimeml/data/{name}.py") for name in names} | |
| relevant = {key: value for key, value in config["build"].items() if key not in {"output_dir", "commit_every", "progress_every", "batch_size"}} | |
| signature = sha(json.dumps({"schema": PART_SCHEMA_VERSION, "inventory": inventory, | |
| "build": relevant, "split": config["split"], "review": config.get("review", {}), | |
| "policy_sha256": policy_hashes, "code_sha256": code_hashes}, sort_keys=True)) | |
| return config, inventory, policy_paths, set(calibration_ids), policy_hashes, code_hashes, signature | |
| def parse_part(value): | |
| try: | |
| index, total = map(int, value.split("/")) | |
| except (ValueError, AttributeError): | |
| raise ValueError("Use --part INDEX/COUNT, e.g. 0/2 or 1/2.") from None | |
| if not 1 <= total <= 128 or not 0 <= index < total: | |
| raise ValueError("Part index is zero-based and must be less than the part count.") | |
| return index, total | |
| def create_database(output, annotation_path): | |
| if output.exists() and (not output.is_dir() or any(output.iterdir())): | |
| raise FileExistsError(f"Output must be absent or empty: {output}") | |
| output.mkdir(parents=True, exist_ok=True) | |
| db = sqlite3.connect(output / "index.sqlite", uri=True) | |
| try: | |
| db.row_factory = sqlite3.Row | |
| db.execute("PRAGMA temp_store=FILE") | |
| db.executescript(SCHEMA) | |
| db.execute("CREATE TABLE document_metrics(doc_hash TEXT PRIMARY KEY, payload TEXT NOT NULL)") | |
| annotation_count = load_annotations(db, annotation_path) | |
| return db, annotation_count | |
| except BaseException: | |
| db.close() | |
| raise | |
| def aggregate_metrics(db): | |
| totals = {key: Counter() for key in ("counts", "rule_reasons", "fragment_flags", "effective_blocks")} | |
| for row in db.execute("SELECT payload FROM document_metrics ORDER BY doc_hash"): | |
| metrics = json.loads(row[0]) | |
| for key in totals: | |
| totals[key].update(metrics[key]) | |
| return totals | |
| def process_content(db, document, normalized, doc_hash, settings, audits): | |
| counts, rule_reasons, fragment_flags, effective_blocks = (Counter() for _ in range(4)) | |
| counts["unique_documents"] += 1 | |
| blocks = [] | |
| for index, original in enumerate(normalized.split("\n")): | |
| result = clean_block(original) | |
| block_id = f"b{index:03d}" | |
| counts["input_blocks"] += 1 | |
| counts[result["action"] + "_blocks"] += 1 | |
| rule_reasons[result["reason"]] += 1 | |
| blocks.append({ | |
| "id": block_id, "line_index": index, | |
| "text": result["text"], "action": result["action"], | |
| }) | |
| if result["action"] != "keep": | |
| destination = ( | |
| "dropped_blocks" if result["action"] == "drop" | |
| else "review_blocks" | |
| ) | |
| dump_line(audits[destination], { | |
| "source": document.source, | |
| "doc_id": document.doc_id, "doc_hash": doc_hash, | |
| "block_id": block_id, "original_text": original, | |
| **result, | |
| }) | |
| boundaries, fragment_labels, block_labels = document_annotations(db, doc_hash, blocks) | |
| counts["approved_block_labels"] += len(block_labels) | |
| effective_blocks.update(block["action"] for block in blocks) | |
| for block_id, label_id in block_labels.items(): | |
| block = next(item for item in blocks if item["id"] == block_id) | |
| destination = "dropped_blocks" if block["action"] == "drop" else "review_blocks" | |
| dump_line(audits[destination], { | |
| "source": document.source, "doc_id": document.doc_id, | |
| "doc_hash": doc_hash, "block_id": block_id, | |
| "text": block["text"], "action": block["action"], | |
| "reason": "approved_local_annotation", "annotation_id": label_id, | |
| }) | |
| paragraphs = restore_linebreaks( | |
| blocks, max_chars=settings["max_join_chars"], | |
| boundary_decisions={pair: label["action"] for pair, label in boundaries.items()}, | |
| ) | |
| counts["paragraphs"] += len(paragraphs) | |
| for pi, paragraph in enumerate(paragraphs): | |
| counts["join_events"] += len(paragraph["joins"]) | |
| counts["approved_join_events"] += sum(join["reason"] == "approved_annotation" for join in paragraph["joins"]) | |
| paragraph_label_ids = { | |
| block_labels[part["block_id"]] for part in paragraph["parts"] | |
| if part["block_id"] in block_labels | |
| } | |
| paragraph_label_ids.update( | |
| boundaries[(join["left_block"], join["right_block"])]["id"] | |
| for join in paragraph["joins"] if join["reason"] == "approved_annotation" | |
| ) | |
| for si, sentence in enumerate(split_sentences(paragraph["text"])): | |
| flags = sorted(set( | |
| paragraph["flags"] + sentence["flags"] | |
| )) | |
| spans = [] | |
| for part in paragraph["parts"]: | |
| left = max(sentence["start"], part["start"]) | |
| right = min(sentence["end"], part["end"]) | |
| if left < right: | |
| spans.append({ | |
| "block_id": part["block_id"], | |
| "start": left - part["start"], | |
| "end": right - part["start"], | |
| }) | |
| fragment_label = match_fragment(db, fragment_labels, sentence["text"], spans) | |
| explicitly_kept = fragment_label is not None and fragment_label["action"] == "keep" | |
| explicitly_excluded = fragment_label is not None and fragment_label["action"] in {"drop", "review"} | |
| if explicitly_kept and flags: | |
| raise ValueError(f"Annotation {fragment_label['id']}: flagged fragments cannot be rescued.") | |
| if ( | |
| (not sentence["terminated"] and not explicitly_kept) or flags or explicitly_excluded | |
| or not any(c.isalnum() for c in sentence["text"]) | |
| ): | |
| counts["fragments"] += 1 | |
| fragment_flags.update(flags) | |
| dump_line(audits["fragments"], { | |
| "source": document.source, | |
| "doc_id": document.doc_id, "doc_hash": doc_hash, | |
| "paragraph_index": pi, "sentence_index": si, | |
| "text": sentence["text"], | |
| "terminated": sentence["terminated"], | |
| "flags": flags, "cleaned_block_spans": spans, | |
| "paragraph_joins": paragraph["joins"], | |
| "approved_annotation_id": fragment_label["id"] if fragment_label else None, | |
| }) | |
| continue | |
| text = sentence["text"] | |
| label_ids = set(paragraph_label_ids) | |
| if fragment_label: | |
| label_ids.add(fragment_label["id"]) | |
| counts["approved_fragment_recoveries"] += int(not sentence["terminated"]) | |
| db.execute( | |
| "INSERT INTO units VALUES (?, ?, ?, ?, ?, ?, ?)", | |
| ( | |
| doc_hash, sha(text), text, pi, si, | |
| json.dumps(spans, ensure_ascii=False), | |
| json.dumps(sorted(label_ids)), | |
| ), | |
| ) | |
| counts["sentence_occurrences"] += 1 | |
| return {'counts': dict(counts), 'rule_reasons': dict(rule_reasons), | |
| 'fragment_flags': dict(fragment_flags), 'effective_blocks': dict(effective_blocks)} | |