sourojitdotcom's picture
AksharaLP-Sentence-2.8M v3.0.0 — word model (v2) + 2.77M-param sentence LM
8948114 verified
Raw History Blame Contribute Delete
1.54 kB
"""Memory-light lexicon trie for constrained beam search over large (0.5-2M word) lexicons.
A node is a (lo, hi, depth) range of the sorted word list; children are found with bisect and cached lazily, so
only nodes actually visited by the beam are ever materialised. Same interface as xlit_model.Trie (kids[n], final[n])."""
import bisect
from bhc.xlit_model import T2I, TGT_VOCAB
class _Kids:
def __init__(s, t): s.t = t
def __getitem__(s, n): return s.t._children(n)
class _Final:
def __init__(s, t): s.t = t
def __getitem__(s, n):
lo, hi, d = s.t.nodes[n]; return len(s.t.w[lo]) == d
class LazyTrie:
def __init__(s, words):
s.w = sorted(w for w in set(words) if w and all(c in T2I for c in w))
s.nodes = [(0, len(s.w), 0)]; s.ids = {s.nodes[0]: 0}; s.cache = {}
s.kids = _Kids(s); s.final = _Final(s)
def _children(s, n):
c = s.cache.get(n)
if c is not None: return c
lo, hi, d = s.nodes[n]; w = s.w; out = {}
pos = lo
if pos < hi and len(w[pos]) == d: pos += 1 # the word equal to the prefix sorts first
while pos < hi:
ch = w[pos][d]; pre = w[pos][:d + 1]
end = bisect.bisect_left(w, pre[:-1] + chr(ord(ch) + 1), pos, hi)
key = (pos, end, d + 1); nid = s.ids.get(key)
if nid is None: nid = len(s.nodes); s.nodes.append(key); s.ids[key] = nid
out[T2I[ch]] = nid; pos = end
if len(s.cache) > 400000: s.cache.clear()
s.cache[n] = out; return out