PrimeTTS-Streaming / textgen.py
Luigi's picture
Super-squash branch 'main' using huggingface_hub
06a6552
Raw
History Blame Contribute Delete
3.64 kB
"""Lightweight real-time text generator (zh-TW + English, code-mix). No model —
instant on any CPU. Multi-domain phrase-bank composer; each call picks a random
domain and composes a fresh varied paragraph, streamed token-by-token (zh per
char, en per word). Replaces a heavy LLM for the streaming-input demo.
"""
import random, re
# Each domain: opener/body/closer phrase pools. Compose = random opener + 2-4
# body lines + closer, mixed zh-TW / English.
_DOMAINS = {
"service": {
"open": ["您好,這裡是客服中心。", "感謝您的來電。", "Hi, thanks for reaching out."],
"body": ["您的訂單預計 3 到 5 個工作天送達。", "訂單編號是 AB1234。",
"分機是 2580,地點在台北市信義區。", "your refund is being processed now.",
"the total comes to NT dollar 1299。"],
"close": ["有問題再跟我說,謝謝。", "祝您有美好的一天。", "have a great day!"],
},
"weather": {
"open": ["來看看今天的天氣。", "Here is the forecast for today.", "氣象報告出爐了。"],
"body": ["台北氣溫大約 28 度,降雨機率 70%。", "午後有短暫雷陣雨,記得帶傘。",
"expect a high of 30 degrees this afternoon。", "沿海地區風勢較強。",
"humidity stays around 80 percent。"],
"close": ["出門記得注意安全。", "stay dry out there。", "以上是今天的天氣。"],
},
"news": {
"open": ["以下是今天的重點新聞。", "In tech news today,", "快速看看今天的頭條。"],
"body": ["一家新創公司發表了即時語音合成技術。", "the demo runs fully on device。",
"研究團隊表示延遲降到了一秒以內。", "股市今天小幅上漲。",
"engineers say the model streams token by token。"],
"close": ["更多細節請看完整報導。", "that's all for now。", "感謝收看。"],
},
"casual": {
"open": ["嗨,最近過得好嗎?", "Hey, how's it going?", "週末有什麼計畫嗎?"],
"body": ["我打算去逛逛夜市,吃點小吃。", "the night market food is amazing。",
"聽說有一家新開的咖啡廳很不錯。", "maybe we can grab coffee later。",
"天氣好的話想去河濱騎腳踏車。"],
"close": ["改天再約囉。", "talk soon!", "祝你有個愉快的週末。"],
},
"travel": {
"open": ["歡迎搭乘本次列車。", "Welcome aboard flight 852.", "各位旅客請注意。"],
"body": ["本次列車即將抵達台北車站。", "next stop is Taipei Main Station。",
"轉乘旅客請於第二月台換車。", "estimated arrival is 3 p.m. sharp。",
"請留意您隨身的行李。"],
"close": ["祝您旅途愉快。", "thank you for traveling with us。", "感謝您的搭乘。"],
},
}
_TOK = re.compile(r"[A-Za-z][A-Za-z']*|\$?\d[\d,\.]*%?|\s+|.")
def _compose(rng):
dom = rng.choice(list(_DOMAINS.values()))
lines = [rng.choice(dom["open"])]
lines += rng.sample(dom["body"], k=rng.randint(2, min(4, len(dom["body"]))))
lines.append(rng.choice(dom["close"]))
return "".join(lines)
def stream(n_sentences=1, seed=None):
"""Yield text tokens forming a fresh varied paragraph. seed=None => random."""
rng = random.Random(seed) # None => nondeterministic (different every call)
for m in _TOK.finditer(_compose(rng)):
yield m.group(0)
if __name__ == "__main__":
for _ in range(3):
print("".join(stream()))