Spaces:
Running on Zero
Running on Zero
| import hashlib | |
| from typing import Any, Dict, List | |
| from app.chunking import RawDoc, normalize_text | |
| TEXT_KEYS = [ | |
| "text", | |
| "passage_text", | |
| "body", | |
| "content", | |
| "document", | |
| "context", | |
| "answer", | |
| "is_selected", | |
| ] | |
| TITLE_KEYS = [ | |
| "title", | |
| "heading", | |
| "url", | |
| ] | |
| PASSAGE_FIELDS = [ | |
| "positive_passages", | |
| "negative_passages", | |
| "passages", | |
| "contexts", | |
| "documents", | |
| "positive", | |
| "negative", | |
| ] | |
| def stable_doc_id(text: str, prefix: str = "doc") -> str: | |
| h = hashlib.sha256(text.encode("utf-8")).hexdigest()[:32] | |
| return f"{prefix}_{h}" | |
| def get_first(obj: Dict, keys: List[str], default: str = "") -> str: | |
| for k in keys: | |
| val = obj.get(k) | |
| if isinstance(val, str) and val.strip(): | |
| return val.strip() | |
| return default | |
| def dict_of_lists_to_items(obj: Dict) -> List[Dict]: | |
| lengths = [] | |
| for v in obj.values(): | |
| if isinstance(v, list): | |
| lengths.append(len(v)) | |
| if not lengths: | |
| return [obj] | |
| n = max(lengths) | |
| items = [] | |
| for i in range(n): | |
| item = {} | |
| for k, v in obj.items(): | |
| if isinstance(v, list): | |
| item[k] = v[i] if i < len(v) else None | |
| else: | |
| item[k] = v | |
| items.append(item) | |
| return items | |
| def passage_items(value: Any) -> List[Dict]: | |
| if value is None: | |
| return [] | |
| if isinstance(value, str): | |
| return [{"text": value}] | |
| if isinstance(value, dict): | |
| return dict_of_lists_to_items(value) | |
| if isinstance(value, list): | |
| out = [] | |
| for item in value: | |
| if isinstance(item, str): | |
| out.append({"text": item}) | |
| elif isinstance(item, dict): | |
| out.append(item) | |
| return out | |
| return [] | |
| def row_to_docs_msmarco_xi(row: Dict, config_name: str, split: str, row_index: int) -> List[RawDoc]: | |
| """ | |
| Parser for the real ai4bharat/MSMARCO-XI parquet schema: | |
| source_lang, target_lang, meta, Answer, query_id, query_type, | |
| passages: {English_passages: [str], Translated_passages: [str], is_selected: [int]}, | |
| Eng_Query, Eng_Answer, query. | |
| `is_selected[i] == 1` marks the passage MS MARCO judged relevant to the query; | |
| we only attach the query to the qa_fused chunk for those, so irrelevant | |
| (negative) passages don't get a misleadingly high-relevance fused chunk. | |
| """ | |
| docs: List[RawDoc] = [] | |
| query = row.get("query") or row.get("Eng_Query") or "" | |
| query_id = row.get("query_id") | |
| query_type = row.get("query_type") or "" | |
| language = row.get("target_lang") or config_name or "" | |
| passages = row.get("passages") or {} | |
| translated = passages.get("Translated_passages") or [] | |
| is_selected = passages.get("is_selected") or [] | |
| for idx, text in enumerate(translated): | |
| text = normalize_text(text or "") | |
| if len(text) < 40: | |
| continue | |
| selected = idx < len(is_selected) and is_selected[idx] == 1 | |
| source_type = "positive_passages" if selected else "negative_passages" | |
| docs.append( | |
| RawDoc( | |
| doc_id=f"{config_name}_{query_id}_{idx}", | |
| text=text, | |
| title="", | |
| language=language, | |
| source_type=source_type, | |
| query=query if selected else "", | |
| metadata={ | |
| "dataset_config": config_name, | |
| "split": split, | |
| "row_index": row_index, | |
| "query_id": query_id, | |
| "query_type": query_type, | |
| "passage_index": idx, | |
| "is_selected": selected, | |
| }, | |
| ) | |
| ) | |
| return docs | |
| def row_to_docs(row: Dict, config_name: str, split: str, row_index: int) -> List[RawDoc]: | |
| if isinstance(row.get("passages"), dict) and "Translated_passages" in row["passages"]: | |
| return row_to_docs_msmarco_xi(row, config_name, split, row_index) | |
| docs: List[RawDoc] = [] | |
| query = ( | |
| row.get("query") | |
| or row.get("question") | |
| or row.get("query_text") | |
| or "" | |
| ) | |
| language = ( | |
| row.get("language") | |
| or row.get("lang") | |
| or config_name | |
| or "" | |
| ) | |
| for field in PASSAGE_FIELDS: | |
| if field not in row: | |
| continue | |
| for j, item in enumerate(passage_items(row[field])): | |
| text = get_first(item, TEXT_KEYS) | |
| text = normalize_text(text) | |
| if len(text) < 40: | |
| continue | |
| title = get_first(item, TITLE_KEYS) | |
| pid = ( | |
| item.get("docid") | |
| or item.get("doc_id") | |
| or item.get("pid") | |
| or stable_doc_id(text, prefix=f"{config_name}_{field}") | |
| ) | |
| docs.append( | |
| RawDoc( | |
| doc_id=str(pid), | |
| text=text, | |
| title=title, | |
| language=language, | |
| source_type=field, | |
| query=query, | |
| metadata={ | |
| "dataset_config": config_name, | |
| "split": split, | |
| "row_index": row_index, | |
| "passage_index": j, | |
| }, | |
| ) | |
| ) | |
| # fallback for unusual/flat schemas | |
| if not docs: | |
| for key, value in row.items(): | |
| if isinstance(value, str) and len(value) > 120 and key not in {"query", "question", "query_id", "id"}: | |
| docs.append( | |
| RawDoc( | |
| doc_id=stable_doc_id(value, prefix=f"{config_name}_{key}"), | |
| text=value, | |
| title="", | |
| language=language, | |
| source_type=key, | |
| query=query, | |
| metadata={ | |
| "dataset_config": config_name, | |
| "split": split, | |
| "row_index": row_index, | |
| }, | |
| ) | |
| ) | |
| return docs | |