Download paddle/code/paddlex_shared_character.py from ampixa/deva-ocr-75m-research: direct link, hf CLI and curl.
- Browser
- Download file 3.38 kB
-
https://huggingface.co/ampixa/deva-ocr-75m-research/resolve/main/paddle/code/paddlex_shared_character.py
- Command line
-
hf download hf://ampixa/deva-ocr-75m-research/paddle/code/paddlex_shared_character.py
-
curl -L -o paddlex_shared_character.py https://huggingface.co/ampixa/deva-ocr-75m-research/resolve/main/paddle/code/paddlex_shared_character.py
3.38 kB
| """Process-local PaddleX adapter for the shared two-branch research recognizer.""" | |
| import math | |
| from pathlib import Path | |
| import numpy as np | |
| from PIL import Image | |
| from paddlex.inference.models.predictors.local_model_predictor import LocalModelPredictor | |
| from paddlex.inference.models.text_recognition.predictor import ImageBatchSampler,TextRecResult | |
| from paddlex.inference.models.bindings.registry import register_predictor_binding_map | |
| from shared_character_native import SharedCharacterNative,preprocess_rgb,sha | |
| MODEL_NAME='TrOCR_shared_character_Paddle_research_rec' | |
| class PaddleXSharedCharacter(LocalModelPredictor): | |
| def __init__(self,*args,research_only_allow_unqualified=False,**kwargs): | |
| super().__init__(*args,**kwargs) | |
| if self.model_name!=MODEL_NAME or self.device!='cpu':raise ValueError('Require the shared CPU research model') | |
| native=self.config['Native'] | |
| if native['format']!='shared-character-paddle-research-v1' or native['parameters']!=74842752: | |
| raise ValueError('Unexpected shared recognizer profile') | |
| for name,digest in native['files_sha256'].items(): | |
| relative=Path(name) | |
| if relative.is_absolute() or '..' in relative.parts or relative.as_posix()!=name:raise ValueError('Invalid bundle asset path') | |
| if sha(self.model_dir/relative)!=digest:raise ValueError('Shared bundle asset bytes changed') | |
| self.runtime=SharedCharacterNative(self.model_dir/'candidate',self.model_dir/'encoder',self.model_dir/'decoders', | |
| allow_unqualified=research_only_allow_unqualified,library_path=self.model_dir/'encoder-library.so') | |
| def _build_batch_sampler(self):return ImageBatchSampler() | |
| def _get_result_class(self):return TextRecResult | |
| def process(self,batch_data,branch=None,return_word_box=False): | |
| if branch not in ['english','character']:raise ValueError('Explicit research branch is required') | |
| if return_word_box:raise ValueError('Autoregressive word-box alignment is not implemented') | |
| images=[];outputs=[] | |
| for item in batch_data.instances: | |
| if isinstance(item,(str,Path)): | |
| with Image.open(item) as source:image=source.convert('RGB') | |
| bgr=np.asarray(image)[:,:,::-1].copy() | |
| elif isinstance(item,np.ndarray) and item.dtype==np.uint8 and item.ndim==3 and item.shape[2]==3: | |
| bgr=item;image=Image.fromarray(np.ascontiguousarray(bgr[:,:,::-1])) | |
| else:raise ValueError('Require an image path or uint8 HWC BGR array') | |
| images.append(bgr);outputs.append(self.runtime.predict_pixels(preprocess_rgb(image),branch)) | |
| return dict(input_path=batch_data.input_paths,page_index=batch_data.page_indexes,input_img=images, | |
| rec_text=[r['text'] for r in outputs],rec_score=[min(1.,math.exp(r['score'])) for r in outputs], | |
| beam_score=[r['score'] for r in outputs],tokens=[r['tokens'] for r in outputs], | |
| decoder_iterations=[r['decoder_iterations'] for r in outputs], | |
| token_limit_reached=[r['token_limit_reached'] for r in outputs],recognizer_branch=[branch]*len(outputs), | |
| score_kind=['Uncalibrated geometric mean of generated token probabilities']*len(outputs),vis_font=[None]*len(outputs)) | |
| def register():register_predictor_binding_map(PaddleXSharedCharacter,{'flexible':[MODEL_NAME]}) | |