FST ITN-ZH教程:中文文本标准化API接口开发指南
1. 简介与背景
随着自然语言处理技术在语音识别、智能客服、自动字幕生成等场景的广泛应用,原始输出中常包含大量非标准表达形式。例如,“二零零八年八月八日”、“早上八点半”等口语化或书面化表达,在结构化数据处理、数据库存储和机器理解中存在障碍。
逆文本标准化(Inverse Text Normalization, ITN)正是为解决这一问题而生的关键预处理技术。它将自然语言中的复杂表达转换为统一、规范的格式,提升下游任务的准确性和一致性。
FST ITN-ZH 是基于有限状态转导器(Finite State Transducer, FST)构建的中文逆文本标准化系统,具备高精度、低延迟、可扩展性强等特点。本文将围绕其 WebUI 实现进行二次开发指导,并重点讲解如何将其封装为标准化 API 接口,便于集成到各类生产系统中。
本教程由科哥完成 WebUI 二次开发,完整项目可通过启动脚本部署:
/bin/bash /root/run.sh2. 系统功能与核心能力解析
2.1 支持的标准化类型
FST ITN-ZH 能够精准处理多种中文语义表达,主要涵盖以下类别:
- 日期转换:
二零一九年九月十二日→2019年09月12日 - 时间表达:
早上八点半→8:30a.m.,下午三点十五分→3:15p.m. - 数字解析:
一百二十三→123,六百万→600万或6000000(可配置) - 货币单位:
一点二五元→¥1.25,一百美元→$100 - 分数表示:
五分之一→1/5,三分之二→2/3 - 度量单位:
二十五千克→25kg,三十公里→30km - 数学符号:
负二→-2,正五点五→+5.5 - 车牌号码:
京A一二三四五→京A12345
这些规则均通过 FST 模型建模,确保语法合法性和语义一致性。
2.2 高级配置参数说明
系统提供三项关键开关,用于控制转换粒度:
| 参数 | 功能描述 | 示例 |
|---|---|---|
| 转换独立数字 | 是否将独立出现的中文数字转为阿拉伯数字 | 幸运一百→幸运100(开启) |
| 转换单个数字 (0-9) | 是否转换单个汉字数字 | 零和九→0和9(开启) |
| 完全转换'万' | 是否将“万”彻底展开为数字 | 六百万→6000000(开启),否则为600万 |
这些设置直接影响最终输出格式,建议根据业务需求调整后持久化保存。
3. WebUI 架构分析与二次开发路径
3.1 前端界面结构概览
当前 WebUI 使用 Gradio 框架构建,具有轻量、易部署、交互友好的特点。主界面布局如下:
┌─────────────────────────────────────────┐ │ [紫蓝渐变] 中文逆文本标准化 (ITN) │ │ webUI二次开发 by 科哥 │ ├─────────────────────────────────────────┤ │ [📝 文本转换] [📦 批量转换] │ │ │ │ ┌───────────┐ ┌───────────┐ │ │ │ 输入框 │ → │ 输出框 │ │ │ │ │ │ │ │ │ └───────────┘ └───────────┘ │ │ │ │ [开始转换] [清空] [复制] [保存] │ ├─────────────────────────────────────────┤ │ 🎯 快速示例 │ │ [日期] [时间] [数字] [货币] ... │ └─────────────────────────────────────────┘该 UI 提供了直观的操作入口,适合演示和小规模使用。但在企业级应用中,需进一步封装为 RESTful API 以支持服务调用。
3.2 核心模块拆解
系统主要由以下组件构成:
- Gradio App:负责前端渲染与用户交互
- ITN Processor:核心处理引擎,加载 FST 模型执行转换
- Configuration Manager:管理高级设置参数
- File Handler:支持批量文件上传与结果导出
其中,ITN Processor是最适合作为 API 后端的核心模块。
4. 封装为 RESTful API 的工程实践
4.1 技术选型:Flask + JSON 接口
为了实现高效、跨平台的服务集成,我们选择使用 Flask 框架暴露 HTTP 接口。相比 Gradio 自带的 RPC 调用,REST API 更易于被 Java、Go、Node.js 等异构系统调用。
安装依赖
pip install flask flask-cors注意:若已在容器环境中运行,请确认端口映射与防火墙策略已开放目标端口(如 5000)。
4.2 API 设计规范
定义统一请求/响应格式,提升接口可用性。
请求体(POST /itn/normalize)
{ "text": "二零零八年八月八日早上八点半", "config": { "convert_digits": true, "convert_single": false, "expand_wan": false } }| 字段 | 类型 | 说明 |
|---|---|---|
| text | string | 待转换的原始文本 |
| config.convert_digits | boolean | 是否转换独立数字 |
| config.convert_single | boolean | 是否转换单个数字(0-9) |
| config.expand_wan | boolean | 是否完全展开“万” |
响应体
{ "success": true, "input": "二零零八年八月八日早上八点半", "output": "2008年08月08日 8:30a.m.", "timestamp": "2025-04-05T10:23:45Z" }失败时返回:
{ "success": false, "error": "Missing required field: text", "timestamp": "2025-04-05T10:23:45Z" }4.3 核心代码实现
from flask import Flask, request, jsonify import datetime import re # 假设已有 itn_processor 模块提供 normalize 函数 # from itn_processor import normalize_text app = Flask(__name__) def normalize_text(text, convert_digits=True, convert_single=False, expand_wan=False): """ 模拟 FST ITN-ZH 的核心处理逻辑 实际应调用原系统的处理函数 """ # 这里仅为示例,实际需接入真实模型 sample_map = { "二零零八年八月八日": "2008年08月08日", "早上八点半": "8:30a.m.", "一百二十三": "123", "一点二五元": "¥1.25" } for k, v in sample_map.items(): text = text.replace(k, v) return text @app.route('/itn/normalize', methods=['POST']) def api_normalize(): data = request.get_json() if not data or 'text' not in data: return jsonify({ 'success': False, 'error': 'Missing required field: text', 'timestamp': datetime.datetime.utcnow().isoformat() + 'Z' }), 400 input_text = data['text'] config = data.get('config', {}) # 解析配置参数 convert_digits = config.get('convert_digits', True) convert_single = config.get('convert_single', False) expand_wan = config.get('expand_wan', False) try: output_text = normalize_text( input_text, convert_digits=convert_digits, convert_single=convert_single, expand_wan=expand_wan ) return jsonify({ 'success': True, 'input': input_text, 'output': output_text, 'timestamp': datetime.datetime.utcnow().isoformat() + 'Z' }) except Exception as e: return jsonify({ 'success': False, 'error': str(e), 'timestamp': datetime.datetime.utcnow().isoformat() + 'Z' }), 500 @app.route('/itn/health', methods=['GET']) def health_check(): return jsonify({ 'status': 'healthy', 'service': 'FST ITN-ZH API', 'timestamp': datetime.datetime.utcnow().isoformat() + 'Z' }) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=False)⚠️注意:上述
normalize_text为模拟函数,实际开发中应导入并调用 FST ITN-ZH 的真实处理方法,确保语义准确性。
4.4 集成原系统处理逻辑
假设原始 WebUI 中的处理函数位于inference.py,可直接引入:
# inference.py(原系统核心) def build_itn_pipeline(convert_digits=True, convert_single=False, expand_wan=False): # 构建 FST 流水线 pass def run_itn(text, pipeline): # 执行转换 return normalized_text在 API 层调用:
from inference import build_itn_pipeline, run_itn # 缓存不同配置下的 pipeline,避免重复初始化 pipelines = {} def get_pipeline(config_key): if config_key not in pipelines: # 解析 key parts = config_key.split('_') cd = parts[0] == 'True' cs = parts[1] == 'True' ew = parts[2] == 'True' pipelines[config_key] = build_itn_pipeline(cd, cs, ew) return pipelines[config_key] # 修改 api_normalize 中的调用方式 pipeline = get_pipeline(f"{convert_digits}_{convert_single}_{expand_wan}") output_text = run_itn(input_text, pipeline)此设计显著提升并发性能,尤其适用于高频调用场景。
5. 部署与调用示例
5.1 启动 API 服务
将上述代码保存为api_server.py,并与原项目共存于同一环境:
python api_server.py访问http://<server_ip>:5000/itn/health可验证服务状态。
5.2 使用 curl 调用示例
curl -X POST http://localhost:5000/itn/normalize \ -H "Content-Type: application/json" \ -d '{ "text": "这件事发生在二零一九年九月十二日的晚上,大概八点半左右,涉及金额为一万二千元。", "config": { "convert_digits": true, "convert_single": false, "expand_wan": true } }'预期响应:
{ "success": true, "input": "这件事发生在二零一九年九月十二日的晚上,大概八点半左右,涉及金额为一万二千元。", "output": "这件事发生在2019年09月12日的晚上,大概8:30左右,涉及金额为12000元。", "timestamp": "2025-04-05T10:23:45Z" }5.3 Python SDK 调用封装
为方便内部系统调用,可封装简易客户端:
import requests class ITNClient: def __init__(self, base_url): self.base_url = base_url.rstrip('/') def normalize(self, text, **kwargs): payload = { 'text': text, 'config': kwargs } resp = requests.post(f'{self.base_url}/itn/normalize', json=payload) result = resp.json() if result['success']: return result['output'] else: raise RuntimeError(f"ITN Error: {result['error']}") # 使用示例 client = ITNClient("http://localhost:5000") result = client.normalize( "京A一二三四五的车在二十五千米外", convert_digits=True, expand_wan=False ) print(result) # 输出:京A12345的车在25km外6. 总结
本文系统介绍了FST ITN-ZH 中文逆文本标准化系统的功能特性,并重点实现了从 WebUI 到 RESTful API 的工程化封装路径。主要内容包括:
- 功能梳理:明确了系统支持的九大类标准化转换能力;
- 架构分析:拆解了 Gradio WebUI 的组成结构,定位可复用的核心处理模块;
- API 设计:制定了清晰的请求/响应协议,支持灵活配置;
- 代码实现:提供了完整的 Flask 服务端代码,包含异常处理与健康检查;
- 性能优化:通过 pipeline 缓存机制提升高并发下的响应效率;
- 调用示范:展示了 curl 和 Python SDK 两种典型集成方式。
通过本次二次开发,FST ITN-ZH 不仅可用于本地交互式操作,更可作为微服务嵌入 ASR 后处理、日志清洗、数据治理等工业级流程中,极大拓展其应用场景。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。