Skip to main content

text-rewrite 🚀

Python 3.8+ License: MIT

text-rewrite 是一个专为工业级 ASR(语音识别)后处理设计的高性能文本纠错与过滤引擎。它将极致的计算效率与高精度的语义约束相结合,完美解决了传统 ASR 热词匹配中常见的“跨词误杀”、“谐音错认”以及“高并发性能瓶颈”问题。

✨ 核心特性

  • 极致性能 ($O(N)$ 线性扩展):针对万级甚至十万级热词进行专项优化。处理近 2000 字的长文本只需不足 600 毫秒(常规短句 <10ms),绝不会拖垮流式并发服务器。
  • Entity-Aware 实体约束引擎:针对容易误杀的极短词(如人名“叶开” vs “也开心”),创新性引入基于 Jieba 词性标注的轻量级 NER 引擎。内建极速音素预检机制与无 HMM 模式,将千字长文本的 NER 解析时间从 400ms 暴砍至 5ms。
  • 双音节倒排索引 (Bigram Syllable Index):创新性地构建了基于“首位双音节”自适应哈希倒排池。将 10000 个热词在 2000 字长文本上的 DP 候选空间极致压缩了 98.8%,打破长文本下 $K=100%$ 的魔咒。
  • Numba Batch DP 加速:底层基于 Numba JIT 编译的“批量化动态规划(DP)”核心引擎,彻底消除跨语言调度开销,支持纯发音级别的纠错(完美包容平翘舌、前后鼻音、形近音误差)。
  • 微秒级 FlashText 精确匹配:对于全局安全大词表,底层自动退化为 Aho-Corasick 自动机,做到微秒级无感替换。
  • Pipeline 乐高式组装:提供高度可扩展的链式过滤器架构,正则清洗、精准替换、模糊纠错一气呵成。

📦 安装依赖

该项目核心依赖于高效计算与轻量级 NLP 组件:

pip install -r requirements.txt

要求: numba>=0.56.0, numpy>=1.21.0, pypinyin>=0.49.0, jieba>=0.42.1

🧩 核心过滤器 (Filters) 概览与最佳实践

在真实的工业级落地场景中,最常用的“黄金三剑客”是以下三个过滤器的组合:

  1. RegexFilter (打头阵:规则清洗)

    • 作用:干脏活累活。负责前置格式规整。
    • 场景:将全角符号转半角、去除多余空格、清理语气词(“呃”、“啊”、“那个”),以及执行如 四S -> 4S 这种高度规律性的文本格式化。
  2. HotwordFilter (中坚力量:业务绝对权威)

    • 作用:基于 FlashText 的极速精确替换,零误杀,快、准、狠。
    • 场景:用于承载几万到几十万量级的“黑白名单 / 品牌库 / 敏感词库”(如“蔚来”、“极氪”)。用它拦截掉绝大部分必须 100% 准确的词,避免增加下游模糊匹配的开销和误杀率。
  3. EntityAwareFuzzyFilter (最后兜底:长尾智能纠错)

    • 作用:收拾残局。
    • 场景:经过前面精确词表的拦截,剩下的“长尾错别字”(如用户口音导致的“魏来”、“及克”)由它出马,通过发音的编辑距离计算把错别字捞回来。
    • 语法:[标签]原词:权重 | 原词2:替换词:权重
      • 强行模糊拦截:张三:1.5 (权重 1.5 极高,即使发音偏差较大如“展伞”也会被强行纠正为“张三”)
      • 严格约束拦截:李四:0.6 (权重 0.6 极低,只有在拼音和声调100%完美吻合时才允许纠正,防止误杀)
      • 短实体约束:[nr]叶开:0.8 (nr为人名,只有 Jieba 认为是人名时才启动音素级检索,且权重适中)
    • 权重 (Weight) 机制:底层的发音相似度基础门槛为 0.6,实际生效门槛 = 0.6 / 权重。
      • 数值越大:越容易被强行修改(容忍口音和 ASR 识别偏差)。
      • 数值越小:要求发音越精确,设置为 0.6 时代表需要 1.0(即 100% 完全 match,包括声调)才能触发修改。

注:除上述三者外,内部模块如 FuzzyPhonemeFilter(底层的 Numba DP 发音匹配引擎)和 JiebaNERFilter(底层 NER 引擎)主要作为组件被 EntityAwareFuzzyFilter 自动编排调用,在常规业务中通常无需直接操作。

🛠 权重诊断与排错工具 (Diagnostic Tool)

在实际业务落地时,如果你发现某个错别字没有按预期被纠正,或者某个正常词被意外误杀,可以使用内置的诊断脚本来查看底层的真实打分情况,从而精准调优权重:

python tests/check_weight_score.py

该工具会直接输出底层 Numba 引擎的真实打分逻辑,帮助你快速理解权重的运作方式:

  • 场景 A(权重 0.6,极其严格):试图把“里死(li3 si3)”纠正为“李四(li3 si4)”。因为声调不同,底层真实得分为 0.9167。但权重 0.6 对应的及格线是 1.0000 (要求 100% 完美匹配)。因此 0.9167 < 1.0000,引擎判定差距过大,拒绝修改。
  • 场景 B(权重 0.7,适当放宽):同样测试“里死”纠正为“李四”。权重提高到 0.7 后,及格线降为 0.8571。此时 0.9167 >= 0.8571,引擎判定符合容错范围,成功触发修改。

你可以随时修改该脚本中的 analyze_match(target_word="你的词", test_text="测试文本", weight=0.7) 参数,针对你的业务专有名词进行沙盒测试和精细化调参!

💡 进阶:底层近似音 (Similar Phonemes) 打分逻辑

为什么有些错别字的打分特别高?引擎底层在进行动态规划(DP)时,内置了一套近似音损耗系数(Loss Coefficient)。

  • 完全相同的音素(如 a 和 a):扣 0 分。
  • 易混淆的近似音(如 z/zh,an/ang,l/n 等被定义在 SIMILAR_PHONEMES 中的音):只扣 0.5 分。
  • 完全不同的音素(如 a 和 i):扣 1.0 分。

计算实例:把“安康(an1 kang1)”和“安刊(an1 kan1)”进行对比。 两者的声母、声调完全一致,唯一的区别在于韵母 ang 和 an。因为它们属于近似音(前后鼻音),引擎只扣了 0.5 分。 最终相似度得分 = 1.0 - (0.5 / 5个总音素) = 0.9000。

  • 如果设置权重 0.7 (及格线 0.857),由于 0.9 > 0.857,系统判定发音足够相似,成功纠错。
  • 如果设置权重 0.6 (及格线 1.0),由于 0.9 < 1.0,系统因为这极其微小的损耗拒绝了替换,达到了防误杀的物理隔离。

🚀 快速开始 (Quick Start)

下面是一个将“正则清洗 -> 精确大词表拦截 -> 高危实体模糊纠错”串联起来的完整 Demo:

from text_rewrite.pipeline import Pipeline
from text_rewrite.filters.regex import RegexFilter
from text_rewrite.filters.hotword import HotwordFilter
from text_rewrite.filters.entity_fuzzy import EntityAwareFuzzyFilter

# 1. 配置正则过滤器(清洗语气词)
regex_rules = {
    r"\b(嗯|啊|哦|那个)\b": ""
}
regex_filter = RegexFilter(rules=regex_rules)

# 2. 配置精确热词过滤器(处理 10万级 安全大词表)
exact_filter = HotwordFilter(hotwords={"确定性长词": "替换词"})

# 3. 配置实体感知模糊过滤器 (EntityAwareFuzzyFilter)
# 语法: [标签]目标词|阈值 (省略替换词会自动以目标词作为原词和替换词)
fuzzy_rules = [
    "张三|0.7",             # 无标签:全局极简配置(发音类似于张三的词,如展伞,都会被纠正为张三)
    "[nr]叶开|0.8",         # 有标签:严格约束(必须是人名,且发音相似度>=0.8 才纠正)
    "李四|0.7"              # 全局极简配置(里死 -> 李四)
]
entity_filter = EntityAwareFuzzyFilter(rules=fuzzy_rules)

# 4. 组装 Pipeline 引擎(顺序即执行顺序)
pipeline = Pipeline()
pipeline.add_filter(regex_filter)
pipeline.add_filter(exact_filter)
pipeline.add_filter(entity_filter)

# 5. 真实流式调用
text = "那个,昨天通知了一下展伞和里死,但是他也开心了,最后通知了页开。"
result = pipeline.process(text)

print(result) 
# 输出: ",昨天通知了一下张三和李四,但是他也开心了,最后通知了夜凯。"

注意:由于初始化 Numba 引擎以及 JIT 预热需要少量时间,建议在服务启动时单例初始化 Pipeline 实例,在后续流式请求中复用该实例调用 .process(text)。

📊 性能压测 (Benchmark)

您可以运行自带的压测脚本,体验在注入 10000 条工业级比例热词配置下的强悍性能:

python tests/bench_entity_fuzzy.py
  • 短句 (约 30 字): 端到端平均耗时 **~ 1 ms**
  • 长文 (约 2000 字): 端到端平均耗时 **~ 150 ms** (呈现完美的 $O(N)$ 线性扩展,不受十万级词表拖累)

Built with ❤️ for High-Performance NLP Engineering.

Metadata

Release files for text-rewrite 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for text-rewrite 0.2.0
File Size Uploaded
text_rewrite-0.2.0.tar.gz 34.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for text-rewrite 0.2.0
File Interpreter ABI Platform
text_rewrite-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 68.1 kB

Release files / text_rewrite-0.2.0.tar.gz

Download URL text_rewrite-0.2.0.tar.gz
Size 34.1 kB
Tags Source
SHA-256 checksum
How to use checksums
1964d609692fcacd18d1b9f89df5b1512951ba43f94648f5e9d5297697af94ab
BLAKE2b-256 checksum
How to use checksums
bdb65e9bbcc2e3380da0ed81d13d648a97b87fd9b0597b9ffb186af7a6e59d58
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.5

Release files / text_rewrite-0.2.0-py3-none-any.whl

Download URL text_rewrite-0.2.0-py3-none-any.whl
Size 34.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6ec450608b9a9f7faf4f8e6063d72301cf52d7534acd4c7258eb92b266c0ea6a
BLAKE2b-256 checksum
How to use checksums
0ae74a41dbbfd2f127bd9cd4707c7afda32a2241bfa300e9094e4c34719a4acb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.5

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.3

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page