inoryQwQ's picture
Upload folder using huggingface_hub
76aca0a verified
Raw
History Blame Contribute Delete
3.21 kB
# Sherpa Onnx Punctuation Pipeline
#
# End-to-end pipeline: text → tokens → inference → punctuation-annotated text.
# Long text is automatically split into overlapping windows for the model's
# fixed 64-token input.
from typing import List
import numpy as np
from .preprocess import CharTokenizer
from .inference import PunctInference
from .postprocess import decode_punctuation
INPUT_LENGTH = 64
WINDOW_STRIDE = 60 # step size; overlap = INPUT_LENGTH - WINDOW_STRIDE = 4
class PunctuationPipeline:
"""End-to-end punctuation prediction pipeline.
Usage:
pipeline = PunctuationPipeline("model.axmodel", "tokens.json")
result = pipeline("你好吗how are you我很好谢谢")
print(result) # 你好吗,how are you,我很好谢谢。
"""
def __init__(
self,
model_path: str,
tokens_path: str,
provider: str = "AxEngineExecutionProvider",
):
self.tokenizer = CharTokenizer(tokens_path)
if not hasattr(self.tokenizer, "id2token") or not self.tokenizer.id2token:
raise RuntimeError("Failed to load tokens.json")
self.id2token = self.tokenizer.id2token
self.inference = PunctInference(model_path, provider)
def _run_window(self, tokens: list[int]) -> np.ndarray:
"""Run inference on a single window, return logits for valid tokens."""
n = len(tokens)
padded = np.zeros((1, INPUT_LENGTH), dtype=np.int32)
padded[0, :n] = tokens
logits = self.inference(padded) # (1, INPUT_LENGTH, 6)
return logits[0, :n, :] # only valid token positions
def __call__(self, text: str) -> str:
"""Add punctuation to input text.
Long text (>64 tokens) is processed in overlapping windows:
window_size=64, stride=60, overlap=4.
Args:
text: Raw Chinese text (may include English words).
Returns:
Punctuation-annotated text.
"""
token_ids = self.tokenizer.tokenize(text)
if not token_ids:
return text
# Short text: single inference
if len(token_ids) <= INPUT_LENGTH:
logits = self._run_window(token_ids)
return decode_punctuation(
logits[np.newaxis], token_ids, self.id2token, len(token_ids),
)
# Long text: sliding window
all_logits = []
for start in range(0, len(token_ids), WINDOW_STRIDE):
end = min(start + INPUT_LENGTH, len(token_ids))
window_tokens = token_ids[start:end]
logits = self._run_window(window_tokens) # (end-start, 6)
if start == 0:
all_logits.append(logits)
else:
# Discard overlap: previous window already covered those tokens
overlap = INPUT_LENGTH - WINDOW_STRIDE
new_tokens_start = overlap
all_logits.append(logits[new_tokens_start:])
combined = np.concatenate(all_logits, axis=0)[:len(token_ids)]
combined = combined[np.newaxis, :, :] # (1, N, 6)
return decode_punctuation(
combined, token_ids, self.id2token, len(token_ids),
)