16个版本 (5个稳定版)
新增 1.1.2 | 2024年8月16日 |
---|---|
1.0.1 | 2024年5月2日 |
0.13.6 | 2024年2月19日 |
0.13.5 | 2023年9月18日 |
0.11.5 | 2022年6月21日 |
#226 in 算法
每月354次下载
1.5MB
32K SLoC
Rustfst
Rust
Python
Rust实现的加权有限状态转换器。
Rustfst是一个用于构建、组合、优化和搜索加权有限状态转换器(FST)的库。加权有限状态转换器是每个转换都有一个输入标签、一个输出标签和一个权重的自动机。更熟悉的有限状态接受器可以表示为每个转换的输入和输出标签相同的转换器。有限状态接受器用于表示字符串集合(特别是正则或有理集合);有限状态转换器用于表示字符串对之间的二元关系(特别是有理转换)。权重可以用来表示采取特定转换的成本。
FST在语音识别和合成、机器翻译、光学字符识别、模式匹配、字符串处理、机器学习、信息提取和检索等领域有关键应用。通常使用加权转换器来表示概率模型(例如,n-gram模型、发音模型)。FST可以通过确定化和最小化进行优化,模型可以应用于假设集(也用自动机表示)或通过有限状态组合级联,并通过最短路径算法选择最佳结果。
概述
有关基本示例,请参阅下文部分。
可以使用宏[fst
]或函数acceptor
和transducer
轻松创建一些简单且常见的FST类型。
对于更复杂的案例,你可能会从 VectorFst
类型开始,这个类型将与大多数你需要的其他内容一起在 prelude
中导入。 VectorFst<TropicalWeight>
直接对应于 OpenFST 的 StdVectorFst
,并且可以使用 read
或 read_text
来加载其文件。
由于“迭代”一个 FST 可以表示很多不同的事情,因此存在多种不同的迭代器。为了迭代状态 ID,你可以使用 states_iter
,而为了迭代从状态中出来的转移,你可以使用 get_trs
。由于通常同时迭代两者,这可以通过 fst_iter
或 fst_into_iter
来完成。迭代 FST 所接受的路径也非常常见,可以使用 paths_iter
来完成,而对于生成文本的便利性,可以使用 string_paths_iter
。对于线性 FST,您还可以使用 decode_linear_fst
获取唯一的路径。
请注意,迭代路径与找到 最短 路径或路径不同,这可以通过 shortest_path
(对于单个路径)或 shortest_path_with_config
(对于 N 条最短路径)来完成。
有关算法的完整列表,请参阅 algorithms
模块。
你可能现在想知道,特别是如果你以前使用过像 pyfoma 这样的语言学家友好的工具,那么“如果我只是想 变换一些文本 呢???” 不友好的回答是 rustfst 是一个相对低层的库,设计用于实现诸如语音识别器之类的功能。稍微有用一点的回答是,你会通过构建一个 acceptor
用于你的输入,然后将其与 transducer
compose
,然后 project
结果到其输出,最后在结果 FST 中 迭代路径。
参考文献
实现大量受到 Mehryar Mohri、Cyril Allauzen 和 Michael Riley 的工作的启发
该API与OpenFST非常相似,但进行了简化并改为更符合Rust语法的修改,尤其是使用Tr
代替Arc
。有关更多信息,请参阅与OpenFST的差异。
示例
use anyhow::Result;
use rustfst::prelude::*;
use rustfst::algorithms::determinize::{DeterminizeType, determinize};
use rustfst::algorithms::rm_epsilon::rm_epsilon;
fn main() -> Result<()> {
// Creates a empty wFST
let mut fst = VectorFst::<TropicalWeight>::new();
// Add some states
let s0 = fst.add_state();
let s1 = fst.add_state();
let s2 = fst.add_state();
// Set s0 as the start state
fst.set_start(s0)?;
// Add a transition from s0 to s1
fst.add_tr(s0, Tr::new(3, 5, 10.0, s1))?;
// Add a transition from s0 to s2
fst.add_tr(s0, Tr::new(5, 7, 18.0, s2))?;
// Set s1 and s2 as final states
fst.set_final(s1, 31.0)?;
fst.set_final(s2, 45.0)?;
// Iter over all the paths in the wFST
for p in fst.paths_iter() {
println!("{:?}", p);
}
// A lot of operations are available to modify/optimize the FST.
// Here are a few examples :
// - Remove useless states.
connect(&mut fst)?;
// - Optimize the FST by merging states with the same behaviour.
minimize(&mut fst)?;
// - Copy all the input labels in the output.
project(&mut fst, ProjectType::ProjectInput);
// - Remove epsilon transitions.
rm_epsilon(&mut fst)?;
// - Compute an equivalent FST but deterministic.
fst = determinize(&fst)?;
Ok(())
}
与OpenFST的差异
以下是非详尽的列表,说明Rustfst的API与OpenFST的不同之处
- 默认的epsilon符号为
<eps>
,而不是<epsilon>
。 - 函数和方法遵循Rust的命名约定,例如使用
add_state
而不是AddState
,但其他方面基本上是等效的,除了 - 转换被命名为
Tr
而不是Arc
,因为Arc
在Rust中有不同且已确立的含义,并且rustfst使用它(即std::sync::Arc
)来引用计数符号表。所有相关函数也使用tr
。 - 最终状态不是通过
zero
的最终权重来指示的。您可以使用is_final
来测试最终状态,而final_weight
返回一个Option
。这要求在转换OpenFST代码时小心。 - 可以直接作为切片访问转换,而不是需要迭代器。
- 半群运算以普通方法的形式表达,而不是奇怪的C++事物。因此,例如,编写
w1.plus(w2)
而不是Plus(w1, w2)
。 - 权重具有原地操作⊕(
plus_assign
)和⊗(times_assign
)。 - 大多数类型别名(在Rust中将是trait别名)如
StdArc
、StdFst
等,都缺失了,但类型推断使我们能够避免在大多数情况下显式类型参数,例如在调用Tr::new
时,例如。 - 状态ID是无符号的,默认为32位(可能,40亿状态对大多数应用程序来说足够了)。这意味着在使用它们作为索引时必须小心地将它们转换为
usize
,反之亦然,最好是检查溢出。 - 符号ID也是无符号的,为32位,使用
NO_LABEL
表示缺失值。 - 浮点权重不是泛型的,因此总是单精度。
与OpenFST的基准测试
我之前对几乎所有线性fst算法进行了基准测试,并与OpenFst
进行了比较。您可以在以下位置找到结果
剧透警告:在所有这些算法上,Rustfst
都更快 😅
文档
最后发布版本的文档在此处可用:[https://docs.rs/rustfst](https://docs.rs/rustfst)
发布流程
- 使用脚本
update_version.sh
更新每个包的版本。 - 推送
- 推送一个以
rustfst-v
为前缀的新标签。
示例
./update_version.sh 0.9.1-alpha.6
git commit -am "Release 0.9.1-alpha.6"
git push
git tag -a rustfst-v0.9.1-alpha.6 -m "Release rustfst 0.9.1-alpha.6"
git push --tags
可选的,如果这是一个主要版本,可以在 UI 中创建 GitHub 发布。
包含在本存储库中的项目
此存储库包含两个主要项目
rustfst
是 Rust 的重新实现。- Crate 在 crates.io 上可用的链接:[here](https://crates.org.cn/crates/rustfst)
- 文档在 docs.rs 上可用的链接:[here](https://docs.rs/rustfst/latest/rustfst/)
rustfst-python
是rustfst
的 Python 绑定。- 软件包在 Pypi 上可用的链接:[here](https://pypi.ac.cn/project/rustfst-python/)
- 文档在 Github Pages 上可用的链接:[here](https://garvys-org.github.io/rustfst/)
许可证
许可方式如下
- Apache 许可证 2.0 版(LICENSE-APACHE 或 [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0))
- MIT 许可证(LICENSE-MIT)或 [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT)
任选其一。
贡献
除非您明确声明,否则根据 Apache-2.0 许可证定义,您有意提交的任何贡献,都应如上所述双重许可,不附加任何额外的条款或条件。
依赖项
~4–5.5MB
~100K SLoC