Download load_model.py from conradcompagna/arabic-clitic-tokenizer: direct link, hf CLI and curl.
- Browser
- Download file 5.03 kB
-
https://huggingface.co/conradcompagna/arabic-clitic-tokenizer/resolve/main/load_model.py
- Command line
-
hf download hf://conradcompagna/arabic-clitic-tokenizer/load_model.py
-
curl -L -o load_model.py https://huggingface.co/conradcompagna/arabic-clitic-tokenizer/resolve/main/load_model.py
5.03 kB
| """CPU inference for native Trankit components (Python 3.10, Trankit 1.1.1).""" | |
| from pathlib import Path | |
| import json | |
| import shutil | |
| import torch | |
| from trankit import Pipeline | |
| from trankit.adapter_transformers import XLMRobertaTokenizer | |
| from trankit.adapter_transformers import configuration_utils, modeling_utils | |
| from trankit.config import Config | |
| from trankit.models.base_models import Multilingual_Embedding | |
| from trankit.models.classifiers import NERClassifier, TokenizerClassifier | |
| from trankit.models.mwt_model import MWTWrapper | |
| from trankit.utils.base_utils import langwithner | |
| from trankit.utils.tbinfo import lang2treebank, treebank2lang, tbname2training_id, supported_langs | |
| def _hub_url(model_id, filename, **_): | |
| """Replace Trankit's retired Transformers CDN resolver with the HF Hub.""" | |
| return f'https://huggingface.co/{model_id}/resolve/main/{filename}' | |
| def load_model(release_dir=None, cache_dir=None): | |
| """Return a CPU callable: text for segmentation, list[str] for sentence NER. | |
| Downloads the upstream XLM-R base encoder on first use. The task checkpoint | |
| files themselves are read from this release, never from upstream task models. | |
| """ | |
| release = Path(release_dir or Path(__file__).resolve().parent) | |
| manifest = json.loads((release / 'artifact-manifest.json').read_text('utf-8')) | |
| alias = manifest['runtime_alias'] | |
| task = manifest['task'] | |
| if task not in {'tokenize', 'ner'}: | |
| raise ValueError(f'Unsupported component task: {task}') | |
| # Sanskrit is an application-trained alias absent from stock Trankit 1.1.1. | |
| treebank = manifest.get('treebank') or { | |
| 'arabic': 'UD_Arabic-PADT', | |
| 'sanskrit-vedic': 'UD_Vedic_Sanskrit-Vedic', | |
| }[alias] | |
| lang2treebank[alias] = treebank | |
| treebank2lang[treebank] = alias | |
| if isinstance(supported_langs, set): | |
| supported_langs.add(alias) | |
| elif alias not in supported_langs: | |
| supported_langs.append(alias) | |
| tbname2training_id[treebank] = 1 | |
| # Keep legacy hashed cache filenames within Windows path-length limits. | |
| cache = Path(cache_dir or Path.home() / '.cache/conrad-trankit').resolve() | |
| for item in manifest['files']: | |
| source = release / item['path'] | |
| target = cache / Path(item['path']).relative_to('weights') | |
| target.parent.mkdir(parents=True, exist_ok=True) | |
| shutil.copy2(source, target) | |
| config = Config() | |
| config.training = False | |
| config._cache_dir = str(cache) | |
| config.device = torch.device('cpu') | |
| config.active_lang = alias | |
| config.treebank_name = treebank | |
| config.max_input_length = 400 | |
| configuration_utils.hf_bucket_url = modeling_utils.hf_bucket_url = _hub_url | |
| XLMRobertaTokenizer.pretrained_vocab_files_map['vocab_file']['xlm-roberta-base'] = ( | |
| _hub_url('FacebookAI/xlm-roberta-base', 'sentencepiece.bpe.model')) | |
| config.wordpiece_splitter = XLMRobertaTokenizer.from_pretrained( | |
| 'xlm-roberta-base', cache_dir=str(cache / 'xlm-roberta-base')) | |
| pipeline = Pipeline.__new__(Pipeline) | |
| pipeline._config = config | |
| pipeline._gpu = pipeline._use_gpu = pipeline.auto_mode = pipeline._ud_eval = False | |
| pipeline.active_lang = alias | |
| pipeline.added_langs = [alias] | |
| pipeline._tokbatchsize = 2 | |
| pipeline._tagbatchsize = 12 | |
| pipeline._embedding_layers = Multilingual_Embedding(config).to(config.device).eval() | |
| pipeline._embedding_weights = pipeline._embedding_layers.state_dict() | |
| if task == 'tokenize': | |
| # The trained tokenizer predicts MWT markers for both release languages. | |
| tbname2training_id[config.treebank_name] |= 1 | |
| pipeline._tokenizer = {alias: TokenizerClassifier(config, config.treebank_name).eval()} | |
| pipeline._mwt_model = {alias: MWTWrapper(config, config.treebank_name, use_gpu=False)} | |
| # Match the application's decoding headroom for long compound expansions. | |
| wrapper = pipeline._mwt_model[alias] | |
| wrapper.model.args['max_dec_len'] = 400 | |
| wrapper.model.model.max_dec_len = 400 | |
| def predict(text): | |
| if not isinstance(text, str) or not text.strip(): | |
| raise ValueError('Supply nonempty text in the model training orthography.') | |
| with torch.inference_mode(): | |
| return pipeline.tokenize(text) | |
| else: | |
| vocab = cache / 'xlm-roberta-base' / alias / f'{alias}.ner-vocab.json' | |
| config.ner_vocabs = {alias: json.loads(vocab.read_text('utf-8'))} | |
| if isinstance(langwithner, set): | |
| langwithner.add(alias) | |
| elif alias not in langwithner: | |
| langwithner.append(alias) | |
| pipeline._ner_model = {alias: NERClassifier(config, alias).eval()} | |
| def predict(tokens): | |
| if not isinstance(tokens, list) or not tokens or not all(isinstance(t, str) and t for t in tokens): | |
| raise ValueError('Supply a pretokenized sentence as a nonempty list of strings.') | |
| with torch.inference_mode(): | |
| return pipeline.ner(tokens, is_sent=True) | |
| return predict | |