kaldifst

add_self_loops

kaldifst.add_self_loops(fst: _kaldifst.StdMutableFst, isyms: List[int], osyms: List[int]) None

AddSelfLoops is a function you will probably want to use alongside PreDeterminize, to add self-loops to any FSTs that you compose on the left hand side of the one modified by PreDeterminize.

This function inserts loops with “special symbols” [e.g. #0, #1] into an FST. This is done at each final state and each state with non-epsilon output symbols on at least one arc out of it. This is to ensure that these symbols, when inserted into the input side of an FST we will compose with on the right, can “pass through” this FST.

At input, isyms and osyms must be vectors of the same size n, corresponding to symbols that currently do not exist in ‘fst’. For each state in n that has non-epsilon symbols on the output side of arcs leaving it, or which is a final state, this function inserts n self-loops with unit weight and one of the n pairs of symbols on its input and output.

Caution

The input FST is modified in-place.

Parameters
  • ifst – The input FST.

  • isyms – A list of input symbols.

  • osyms – A list of output symbols. Must satisfy len(isyms) == len(osyms).

Returns

Return None.

Example 1: Add self loops to a transducer

Listing 10 Add self loops to a transducer.
 1import graphviz
 2
 3import kaldifst
 4
 5s = """
 60 1 a p
 71
 81 2 b q
 92 3 c r
103 4 f t
113 0 d s
125 0 f t
13"""
14
15
16sym1 = kaldifst.SymbolTable(name="sym1")
17sym1.add_symbol("a", 1)
18sym1.add_symbol("b", 2)
19sym1.add_symbol("c", 3)
20sym1.add_symbol("d", 4)
21sym1.add_symbol("f", 5)
22sym1.add_symbol("#0", 6)
23sym1.add_symbol("#1", 7)
24
25sym2 = kaldifst.SymbolTable(name="sym2")
26sym2.add_symbol("p", 1)
27sym2.add_symbol("q", 2)
28sym2.add_symbol("r", 3)
29sym2.add_symbol("s", 4)
30sym2.add_symbol("t", 5)
31sym2.add_symbol("#0", 6)
32sym2.add_symbol("#1", 7)
33
34fst = kaldifst.compile(s=s, acceptor=False, isymbols=sym1, osymbols=sym2)
35
36fst.input_symbols = sym1
37fst.output_symbols = sym2
38
39fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
40fst_source = graphviz.Source(fst_dot)
41fst_source.render(outfile="fst.svg")
42
43kaldifst.add_self_loops(fst, isyms=[6, 7], osyms=[6, 7])
44
45fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
46fst_source = graphviz.Source(fst_dot)
47fst_source.render(outfile="fst-add-self-loops.svg")
fst.svg

Fig. 10 Visualization of fst.svg (before connect)

fst-add-self-loops.svg

Fig. 11 Visualization of fst-add-self-loops.svg (after calling add_self_loops())

arcsort

kaldifst.arcsort(in_out: _kaldifst.StdMutableFst, sort_type: str = 'ilabel') None

Sort arcs of an FST in-place.

See also https://www.openfst.org/twiki/bin/view/FST/ArcSortDoc

Caution

The FST is modified in-place.

Parameters
  • in_out – An acceptor or a transducer. It is modified in-place.

  • sort_type – Comparison method, one of “ilabel”, “olabel”

Returns

Return None.

Example 1: Sort an acceptor

Listing 11 Sort an acceptor
 1import kaldifst
 2
 3s1 = """
 40 1 1
 50 1 3
 60 1 2
 70 2 5
 80 2 4
 91 2 2
101 2 3
111 2 1
122
13"""
14fsa = kaldifst.compile(s=s1, acceptor=True)
15fsa_dot = kaldifst.draw(fsa, acceptor=True, portrait=True)
16print(fsa_dot)
17
18import graphviz
19
20source = graphviz.Source(fsa_dot)
21source.render(outfile="acceptor.svg")
22
23kaldifst.arcsort(fsa)
24fsa_dot = kaldifst.draw(fsa, acceptor=True, portrait=True)
25
26source2 = graphviz.Source(fsa_dot)
27source2.render(outfile="sorted.svg")
acceptor.svg

Fig. 12 Visualization of acceptor.svg (before sort)

sorted.svg

Fig. 13 Visualization of sorted.svg (after sort)

Example 2: Sort a transducer by ilabel

Listing 12 Sort a transducer by ilabel
 1import kaldifst
 2
 3s1 = """
 40 1 1 4
 50 1 3 5
 60 1 2 3
 70 2 5 2
 80 2 4 1
 91 2 2 3
101 2 3 1
111 2 1 2
122
13"""
14fst = kaldifst.compile(s=s1, acceptor=False)
15fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
16print(fst_dot)
17
18import graphviz
19
20source = graphviz.Source(fst_dot)
21source.render(outfile="transducer1.svg")
22
23kaldifst.arcsort(fst, sort_type="ilabel")
24fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
25source = graphviz.Source(fst_dot)
26source.render(outfile="sorted-transducer-ilabel.svg")
transducer1.svg

Fig. 14 Visualization of transducer1.svg (before sort)

sorted-transducer-ilabel.svg

Fig. 15 Visualization of sorted-transducer-ilabel.svg (after sort)

Example 3: Sort a transducer by olabel

Listing 13 Sort a transducer by olabel
 1import kaldifst
 2
 3s1 = """
 40 1 1 4
 50 1 3 5
 60 1 2 3
 70 2 5 2
 80 2 4 1
 91 2 2 3
101 2 3 1
111 2 1 2
122
13"""
14fst = kaldifst.compile(s=s1, acceptor=False)
15fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
16print(fst_dot)
17
18import graphviz
19
20source = graphviz.Source(fst_dot)
21source.render(outfile="transducer2.svg")
22
23kaldifst.arcsort(fst, sort_type="olabel")
24fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
25source = graphviz.Source(fst_dot)
26source.render(outfile="sorted-transducer-olabel.svg")
transducer2.svg

Fig. 16 Visualization of transducer2.svg (before sort)

sorted-transducer-olabel.svg

Fig. 17 Visualization of sorted-transducer-olabel.svg (after sort)

compile

kaldifst.compile(s: str, acceptor: bool = False, arc_type: str = 'standard', fst_type: str = 'vector', isymbols: object = None, osymbols: object = None, ssymbols: object = None, keep_isymbols: bool = False, keep_osymbols: bool = False, keep_state_numbering: bool = False, allow_negative_labels: bool = False) object

Create transducer/acceptor from simple text format.

Parameters
  • s – A string containing the text format of the FST.

  • acceptor – Input in acceptor format.

  • arc_type – Output arc type.

  • fst_type – Output FST type.

  • isymbols – Input label symbol table.

  • osymbols – Output label symbol table.

  • ssymbols – State label symbol table.

  • keep_isymbols – Store input label symbol table with FST.

  • keep_osymbols – Store output label symbol table with FST.

  • keep_state_numbering – Do not renumber input states.

  • allow_negative_labels – Allow negative labels (not recommended; may cause conflicts)

Returns

Return an FST.

Example 1: Create an acceptor

Listing 14 Create an acceptor
 1import kaldifst
 2
 3s1 = """
 40 1 1 1.5
 51 2 2 2.5
 62 0.3
 7"""
 8fsa = kaldifst.compile(s=s1, acceptor=True)
 9fsa_dot = kaldifst.draw(fsa, acceptor=True, portrait=True)
10print(fsa_dot)
11
12import graphviz
13
14source = graphviz.Source(fsa_dot)
15source.render(outfile="acceptor1.svg")
acceptor1.svg

Fig. 18 Visualization of acceptor1.svg

Example 2: Create an acceptor with symbol table

Listing 15 Create an acceptor with symbol table
 1import kaldifst
 2
 3s1 = """
 40 1 a 1.5
 51 2 b 2.5
 62 0.3
 7"""
 8isym = kaldifst.SymbolTable(name="An arbitrary name")
 9isym.add_symbol("a", 1)
10isym.add_symbol("b", 2)
11fsa = kaldifst.compile(s=s1, acceptor=True, isymbols=isym, keep_isymbols=False)
12fsa.input_symbols = isym
13fsa_dot = kaldifst.draw(fsa, acceptor=True, portrait=True)
14print(fsa_dot)
15
16import graphviz
17
18source = graphviz.Source(fsa_dot)
19source.render(outfile="acceptor2.svg")
acceptor2.svg

Fig. 19 Visualization of acceptor2.svg

Example 3: Create a transducer

Listing 16 Create a transducer
 1import kaldifst
 2
 3s1 = """
 40 1 1 10 1.5
 51 2 2 20 2.5
 62 0.3
 7"""
 8fst = kaldifst.compile(s=s1, acceptor=False)
 9fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
10print(fst_dot)
11
12import graphviz
13
14source = graphviz.Source(fst_dot)
15source.render(outfile="transducer1.svg")
transducer1.svg

Fig. 20 Visualization of transducer1.svg

Example 4: Create a transducer with symbol table

Listing 17 Create a transducer with symbol table
 1import kaldifst
 2
 3s1 = """
 40 1 a A 1.5
 51 2 b B 2.5
 62 0.3
 7"""
 8isym = kaldifst.SymbolTable(name="An arbitrary name")
 9isym.add_symbol("a", 1)
10isym.add_symbol("b", 2)
11
12osym = kaldifst.SymbolTable(name="Another arbitrary name")
13osym.add_symbol("A", 1)
14osym.add_symbol("B", 2)
15
16fst = kaldifst.compile(
17    s=s1,
18    acceptor=False,
19    isymbols=isym,
20    osymbols=osym,
21    keep_isymbols=False,
22    keep_osymbols=False,
23)
24fst.input_symbols = isym
25fst.output_symbols = osym
26fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
27print(fst_dot)
28
29import graphviz
30
31source = graphviz.Source(fst_dot)
32source.render(outfile="transducer2.svg")
transducer2.svg

Fig. 21 Visualization of transducer2.svg

compose

kaldifst.compose(fst1: _kaldifst.StdFst, fst2: _kaldifst.StdFst, match_side: str = 'left', compose_filter: str = 'sequence', connect: bool = True) _kaldifst.StdMutableFst

Compose two FSTs.

This operation computes the composition of two transducers. If A transduces string x to y with weight a and B transduces y to z with weight b, then their composition transduces string x to z with weight a ⊗ b.

See also https://www.openfst.org/twiki/bin/view/FST/ComposeDoc

Caution

The output labels of the first transducer or the input labels of the second transducer must be sorted.

Parameters
  • fst1 – The first FST.

  • fst2 – The second FST.

  • match_side – Defaults to left.

  • compose_filter – Composition filter, one of: “alt_sequence”, “auto”, “match”, “no_match”, “null”, “sequence”, “trivial”.

  • connect – Trim output.

Returns

Return the composition result.

Example 1: Compose two transducers.

Listing 18 Compose two transducers
 1import graphviz
 2
 3import kaldifst
 4
 5s1 = """
 60 1 a q 1
 70 2 a r 2.5
 81 1 c s 1
 91 0
102 2.5
11"""
12
13sym1 = kaldifst.SymbolTable(name="sym1")
14sym1.add_symbol("a", 1)
15sym1.add_symbol("c", 2)
16
17sym2 = kaldifst.SymbolTable(name="sym2")
18sym2.add_symbol("q", 1)
19sym2.add_symbol("r", 2)
20sym2.add_symbol("s", 3)
21
22a = kaldifst.compile(s=s1, acceptor=False, isymbols=sym1, osymbols=sym2)
23a.input_symbols = sym1
24a.output_symbols = sym2
25
26s2 = """
270 1 q f 1
280 2 r h 3
291 2 s g 2.5
302 2 s j 1.5
312 2
32"""
33
34sym3 = kaldifst.SymbolTable(name="sym3")
35sym3.add_symbol("f", 1)
36sym3.add_symbol("g", 2)
37sym3.add_symbol("h", 3)
38sym3.add_symbol("j", 4)
39
40b = kaldifst.compile(s=s2, acceptor=False, isymbols=sym2, osymbols=sym3)
41b.input_symbols = sym2
42b.output_symbols = sym3
43
44a_dot = kaldifst.draw(a, acceptor=False, portrait=True)
45a_source = graphviz.Source(a_dot)
46a_source.render(outfile="a.svg")
47
48b_dot = kaldifst.draw(b, acceptor=False, portrait=True)
49b_source = graphviz.Source(b_dot)
50b_source.render(outfile="b.svg")
51
52# sort b by ilabel. It is sorted in-place
53kaldifst.arcsort(b, sort_type="ilabel")
54
55c = kaldifst.compose(a, b)
56c_dot = kaldifst.draw(c, acceptor=False, portrait=True)
57c_source = graphviz.Source(c_dot)
58c_source.render(outfile="c.svg")
a.svg

Fig. 22 The first transducer a.

b.svg

Fig. 23 The second transducer b

c.svg

Fig. 24 The composition result c.

compose_context

kaldifst.compose_context(disambig_syms: List[int], context_width: int, central_position: int, ifst: _kaldifst.StdVectorFst, project_ifst: bool = False) Tuple[_kaldifst.StdVectorFst, List[List[int]]]

compose_context composes efficiently with a context fst that it generates.

Without disambig_syms specified, it assumes that all input symbols of ifst are phones. It adds the subsequential symbol itself (it does not appear in the output so doesn’t need to be specified by the user). the disambig_syms is a list of disambiguation symbols on the LHS of ifst. The symbols on the LHS of out.fst are indexes into the ilabels.list file, which is a kaldi-format file containing a vector<vector<int32>>, which specifies what the labels mean in terms of windows of symbols.

Parameters
  • disambig_syms – List of disambiguation symbols, e.g. the integer ids of #0, #1, #2 … in the phones.txt.

  • context_width – Size of context window, e.g. 3 for triphone.

  • central_position – Central position in phonetic context window (zero-based index), e.g. 1 for triphone.

  • ifst – The FST we are composing with C (e.g. LG.fst),

  • project_ifst – This is intended only to be set to true in the program ‘fstmakecontextfst’… if true, it will project on the input after adding the subsequential loop to ‘ifst’, which allows us to reconstruct the context fst C.fst.

Returns

  • ofst: The resulting fst

  • ilabels, a List[List[int]]

Return type

Return a tuple containing (ofst, ilabels), where

connect

kaldifst.connect(in_out: _kaldifst.StdMutableFst) None

This operation trims an FST, removing states and arcs that are not on successful paths.

Caution

The input FST is modified in-place.

See also https://www.openfst.org/twiki/bin/view/FST/ConnectDoc

Parameters

in_out – The FST to be connected. Note it is modified in-place.

Returns

Return None.

Example 1: Connect a transducer

Listing 19 Connect a transducer
 1import graphviz
 2
 3import kaldifst
 4
 5s = """
 60 1 a p
 71
 81 2 b q
 92 3 c r
103 4 f t
113 0 d s
125 0 f t
13"""
14
15
16sym1 = kaldifst.SymbolTable(name="sym1")
17sym1.add_symbol("a", 1)
18sym1.add_symbol("b", 2)
19sym1.add_symbol("c", 3)
20sym1.add_symbol("d", 4)
21sym1.add_symbol("f", 5)
22
23sym2 = kaldifst.SymbolTable(name="sym2")
24sym2.add_symbol("p", 1)
25sym2.add_symbol("q", 2)
26sym2.add_symbol("r", 3)
27sym2.add_symbol("s", 4)
28sym2.add_symbol("t", 5)
29
30fst = kaldifst.compile(s=s, acceptor=False, isymbols=sym1, osymbols=sym2)
31
32fst.input_symbols = sym1
33fst.output_symbols = sym2
34
35fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
36fst_source = graphviz.Source(fst_dot)
37fst_source.render(outfile="fst.svg")
38
39kaldifst.connect(fst)
40
41fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
42fst_source = graphviz.Source(fst_dot)
43fst_source.render(outfile="fst-connect.svg")
fst.svg

Fig. 25 Visualization of fst.svg (before connect)

fst-connect.svg

Fig. 26 Visualization of fst-connect.svg (after connect)

convert_nbest_to_vector

kaldifst.convert_nbest_to_vector(*args, **kwargs)

Overloaded function.

  1. convert_nbest_to_vector(fst: _kaldifst.StdFst) -> List[_kaldifst.StdVectorFst]

This function converts an FST with a special structure, which is output by the OpenFst functions ShortestPath and RandGen, and converts them into a list of separate FSTs. This special structure is that the only state that has more than one (arcs-out or final-prob) is the start state.

Parameters

fst – The input fst, which should be returned by shortestpath.

Returns

Return a list of linear FSTs.

Example for a StdVectorFst

Listing 20 convert_nbest_to_vector for a StdVectorFst
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s1 = """
 80 1 a 0.1
 90 2 b 0.1
101 3 c 0.4
111 3 d 0.2
122 3 c 0.3
132 3 d 0.2
143 0
15"""
16
17sym1 = kaldifst.SymbolTable(name="sym1")
18sym1.add_symbol("eps", 0)
19sym1.add_symbol("a", 1)
20sym1.add_symbol("b", 2)
21sym1.add_symbol("c", 3)
22sym1.add_symbol("d", 4)
23
24a = kaldifst.compile(s=s1, acceptor=True, isymbols=sym1)
25a.input_symbols = sym1
26
27a_dot = kaldifst.draw(a, acceptor=True, portrait=True)
28a_source = graphviz.Source(a_dot)
29a_source.render(outfile="vector-fst.svg")
30
31nbest_3 = kaldifst.shortest_path(a, n=3)
32nbest_3_dot = kaldifst.draw(nbest_3, acceptor=True, portrait=True)
33nbest_3_source = graphviz.Source(nbest_3_dot)
34nbest_3_source.render(outfile="vector-fst-3best.svg")
35
36nbest_list = kaldifst.convert_nbest_to_vector(nbest_3)
37for b in nbest_list:
38    b.input_symbols = a.input_symbols
39    b.output_symbols = a.output_symbols
40
41nbest_list_0_dot = kaldifst.draw(nbest_list[0], acceptor=True, portrait=True)
42nbest_list_0_source = graphviz.Source(nbest_list_0_dot)
43nbest_list_0_source.render(outfile="vector-fst-3best-0.svg")
44
45nbest_list_1_dot = kaldifst.draw(nbest_list[1], acceptor=True, portrait=True)
46nbest_list_1_source = graphviz.Source(nbest_list_1_dot)
47nbest_list_1_source.render(outfile="vector-fst-3best-1.svg")
48
49nbest_list_2_dot = kaldifst.draw(nbest_list[2], acceptor=True, portrait=True)
50nbest_list_2_source = graphviz.Source(nbest_list_2_dot)
51nbest_list_2_source.render(outfile="vector-fst-3best-2.svg")
vector-fst.svg

Fig. 27 Visualization of vector-fst.svg

vector-fst-3best.svg

Fig. 28 Visualization of vector-fst-3best.svg

vector-fst-3best-0.svg

Fig. 29 Visualization of vector-fst-3best-0.svg

vector-fst-3best-1.svg

Fig. 30 Visualization of vector-fst-3best-1.svg

vector-fst-3best-2.svg

Fig. 31 Visualization of vector-fst-3best-2.svg

  1. convert_nbest_to_vector(fst: _kaldifst.LatticeFst) -> List[_kaldifst.Lattice]

This function converts an FST with a special structure, which is output by the OpenFst functions ShortestPath and RandGen, and converts them into a list of separate FSTs. This special structure is that the only state that has more than one (arcs-out or final-prob) is the start state.

Parameters

fst – The input fst, which should be returned by shortestpath.

Returns

Return a list of linear FSTs.

Example for a Lattice

Listing 21 convert_nbest_to_vector for a Lattice
  1#!/usr/bin/env python3
  2
  3import graphviz
  4
  5import kaldifst
  6
  7fst = kaldifst.Lattice()
  8s0 = fst.add_state()
  9s1 = fst.add_state()
 10s2 = fst.add_state()
 11s3 = fst.add_state()
 12
 13fst.start = s0
 14fst.add_arc(
 15    state=s0,
 16    arc=kaldifst.LatticeArc(
 17        ilabel=1,
 18        olabel=1,
 19        weight=kaldifst.LatticeWeight(graph_cost=0.02, acoustic_cost=0.08),
 20        nextstate=s1,
 21    ),
 22)
 23
 24fst.add_arc(
 25    state=s0,
 26    arc=kaldifst.LatticeArc(
 27        ilabel=2,
 28        olabel=2,
 29        weight=kaldifst.LatticeWeight(graph_cost=0.03, acoustic_cost=0.07),
 30        nextstate=s2,
 31    ),
 32)
 33
 34fst.add_arc(
 35    state=s1,
 36    arc=kaldifst.LatticeArc(
 37        ilabel=3,
 38        olabel=3,
 39        weight=kaldifst.LatticeWeight(graph_cost=0.1, acoustic_cost=0.3),
 40        nextstate=s3,
 41    ),
 42)
 43
 44fst.add_arc(
 45    state=s1,
 46    arc=kaldifst.LatticeArc(
 47        ilabel=4,
 48        olabel=4,
 49        weight=kaldifst.LatticeWeight(graph_cost=0.15, acoustic_cost=0.05),
 50        nextstate=s3,
 51    ),
 52)
 53
 54fst.add_arc(
 55    state=s2,
 56    arc=kaldifst.LatticeArc(
 57        ilabel=3,
 58        olabel=3,
 59        weight=kaldifst.LatticeWeight(graph_cost=0.15, acoustic_cost=0.15),
 60        nextstate=s3,
 61    ),
 62)
 63
 64fst.add_arc(
 65    state=s2,
 66    arc=kaldifst.LatticeArc(
 67        ilabel=4,
 68        olabel=4,
 69        weight=kaldifst.LatticeWeight(graph_cost=0.05, acoustic_cost=0.15),
 70        nextstate=s3,
 71    ),
 72)
 73
 74fst.set_final(state=s3, weight=kaldifst.LatticeWeight.one)
 75
 76
 77sym1 = kaldifst.SymbolTable(name="sym1")
 78sym1.add_symbol("eps", 0)
 79sym1.add_symbol("a", 1)
 80sym1.add_symbol("b", 2)
 81sym1.add_symbol("c", 3)
 82sym1.add_symbol("d", 4)
 83
 84sym2 = kaldifst.SymbolTable(name="sym2")
 85sym2.add_symbol("eps", 0)
 86sym2.add_symbol("A", 1)
 87sym2.add_symbol("B", 2)
 88sym2.add_symbol("C", 3)
 89sym2.add_symbol("D", 4)
 90
 91fst.input_symbols = sym1
 92fst.output_symbols = sym2
 93
 94fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
 95fst_source = graphviz.Source(fst_dot)
 96fst_source.render(outfile="lattice.svg")
 97
 98nbest_3 = kaldifst.shortest_path(fst, n=3)
 99nbest_3_dot = kaldifst.draw(nbest_3, acceptor=False, portrait=True)
100nbest_3_source = graphviz.Source(nbest_3_dot)
101nbest_3_source.render(outfile="lattice-3best.svg")
102
103nbest_list = kaldifst.convert_nbest_to_vector(nbest_3)
104for b in nbest_list:
105    b.input_symbols = fst.input_symbols
106    b.output_symbols = fst.output_symbols
107
108nbest_list_0_dot = kaldifst.draw(nbest_list[0], acceptor=True, portrait=True)
109nbest_list_0_source = graphviz.Source(nbest_list_0_dot)
110nbest_list_0_source.render(outfile="lattice-3best-0.svg")
111
112nbest_list_1_dot = kaldifst.draw(nbest_list[1], acceptor=True, portrait=True)
113nbest_list_1_source = graphviz.Source(nbest_list_1_dot)
114nbest_list_1_source.render(outfile="lattice-3best-1.svg")
115
116nbest_list_2_dot = kaldifst.draw(nbest_list[2], acceptor=True, portrait=True)
117nbest_list_2_source = graphviz.Source(nbest_list_2_dot)
118nbest_list_2_source.render(outfile="lattice-3best-2.svg")
lattice.svg

Fig. 32 Visualization of lattice.svg

lattice-3best.svg

Fig. 33 Visualization of lattice-3best.svg

lattice-3best-0.svg

Fig. 34 Visualization of lattice-3best-0.svg

lattice-3best-1.svg

Fig. 35 Visualization of lattice-3best-1.svg

lattice-3best-2.svg

Fig. 36 Visualization of lattice-3best-2.svg

determinize

kaldifst.determinize(ifst: _kaldifst.StdFst, delta: float = 0.0009765625, det_type: str = 'functional', increment_subsequential_label: bool = False, nstate: int = - 1, subsequential_label: int = 0, weight: str = '') _kaldifst.StdVectorFst

This operation determinizes a weighted transducer.

The result will be an equivalent FST that has the property that no state has two transitions with the same input label. For this algorithm, epsilon transitions are treated as regular symbols (cf. RmEpsilon).

See also https://www.openfst.org/twiki/bin/view/FST/DeterminizeDoc

Parameters
  • ifst – The input FST.

  • delta – Comparison/quantization delta.

  • det_type – Type of determinization: “functional”, “nonfunctional”, “disambiguate”.

  • increment_subsequential_label – Increment subsequential_label to obtain distinct labels for subsequential arcs at a given state

  • nstate – State number threshold

  • subsequential_label – Input label of arc corresponding to residual final output when producing a subsequential transducer

  • weight – Weight threshold

Returns

Return the determinized FST.

Example 1: Determinize a transducer

Listing 22 Determinize a transducer.
 1import graphviz
 2
 3import kaldifst
 4
 5s = """
 60 1 a p 1
 70 2 a q 2
 80 1 eps q 3
 91 3 c r 5
101 3 c r 4
112 3 d s 6
123 0
13"""
14
15sym1 = kaldifst.SymbolTable(name="sym1")
16sym1.add_symbol("eps", 0)
17sym1.add_symbol("a", 1)
18sym1.add_symbol("c", 2)
19sym1.add_symbol("d", 3)
20
21sym2 = kaldifst.SymbolTable(name="sym2")
22sym2.add_symbol("eps", 0)
23sym2.add_symbol("p", 1)
24sym2.add_symbol("q", 2)
25sym2.add_symbol("r", 3)
26sym2.add_symbol("s", 4)
27
28fst = kaldifst.compile(s=s, acceptor=False, isymbols=sym1, osymbols=sym2)
29fst.input_symbols = sym1
30fst.output_symbols = sym2
31
32fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
33fst_source = graphviz.Source(fst_dot)
34fst_source.render(outfile="transducer.svg")
35
36fst = kaldifst.determinize(fst)
37
38fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
39fst_source = graphviz.Source(fst_dot)
40fst_source.render(outfile="transducer2.svg")
transducer.svg

Fig. 37 Visualization of transducer.svg (before determinization)

transducer2.svg

Fig. 38 Visualization of transducer2.svg (after determinization)

determinize_star

kaldifst.determinize_star(in_out: _kaldifst.StdVectorFst, delta: float = 0.0009765625, max_states: int = - 1, use_log: bool = False) bool

Removes epsilons and determinizes in one step.

See also https://github.com/kaldi-asr/kaldi/blob/master/src/fstbin/fstdeterminizestar.cc

Caution

The input FST is modified in-place.

Parameters
  • in_out – The input/output FST. Note it is modified in-place.

  • delta – Delta value used to determine equivalence of weights.

  • max_states – Maximum number of states in determinized FST before it will abort.

  • use_log – Determinize in log semiring.

Returns

this function will return False if determinization completed normally, and true if it was stopped early by reaching the ‘max-states’ limit, and a partial FST was generated.

Return type

The return status is un-intuitive

Example 1: Determinize a transducer

Listing 23 Determinize a transducer.
 1import graphviz
 2
 3import kaldifst
 4
 5s = """
 60 1 a p 1
 70 2 a q 2
 80 1 eps q 3
 91 3 c r 5
101 3 c r 4
112 3 d s 6
123 0
13"""
14
15sym1 = kaldifst.SymbolTable(name="sym1")
16sym1.add_symbol("eps", 0)
17sym1.add_symbol("a", 1)
18sym1.add_symbol("c", 2)
19sym1.add_symbol("d", 3)
20
21sym2 = kaldifst.SymbolTable(name="sym2")
22sym2.add_symbol("eps", 0)
23sym2.add_symbol("p", 1)
24sym2.add_symbol("q", 2)
25sym2.add_symbol("r", 3)
26sym2.add_symbol("s", 4)
27
28fst = kaldifst.compile(s=s, acceptor=False, isymbols=sym1, osymbols=sym2)
29fst.input_symbols = sym1
30fst.output_symbols = sym2
31
32fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
33fst_source = graphviz.Source(fst_dot)
34fst_source.render(outfile="transducer.svg")
35
36kaldifst.determinize_star(fst)
37
38fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
39fst_source = graphviz.Source(fst_dot)
40fst_source.render(outfile="transducer2.svg")
transducer.svg

Fig. 39 Visualization of transducer.svg (before determinization)

transducer2.svg

Fig. 40 Visualization of transducer2.svg (after determinization)

divide

kaldifst.divide(*args, **kwargs)

Overloaded function.

  1. divide(arg0: _kaldifst.TropicalWeight, arg1: _kaldifst.TropicalWeight) -> _kaldifst.TropicalWeight

  2. divide(arg0: _kaldifst.LatticeWeight, arg1: _kaldifst.LatticeWeight) -> _kaldifst.LatticeWeight

draw

kaldifst.draw(*args, **kwargs)

Overloaded function.

  1. draw(fst: _kaldifst.StdFst, acceptor: bool = False, isymbols: object = None, osymbols: object = None, ssymbols: object = None, numeric: bool = False, precision: int = 5, float_format: str = ‘g’, show_weight_one: bool = False, title: str = ‘’, portrait: bool = False, vertical: bool = False, fontsize: int = 14, height: float = 11, width: float = 8.5, nodesep: float = 0.25, ranksep: float = 0.4, allow_negative_labels: bool = False) -> str

Prints FSTs in dot text format.

Hint

You can use the Python package graphviz to visualize it.

You can also post the dot format output to https://dreampuf.github.io/GraphvizOnline/ to visualize it within your browser. You can also share the URL to others.

Parameters
  • fst – The FST to be printed.

  • acceptor – Input in acceptor format

  • isymbols – Input label symbol table

  • osymbols – Output label symbol table

  • ssymbols – State label symbol table

  • numeric – Print numeric labels

  • precision – Set precision (number of char/float)

  • float_format – Floating-point format, one of: “e”, “f”, or “g”

  • show_weight_one – Print/draw arc weights and final weights equal to Weight::One()

  • title – Set figure title

  • portrait – Portrait mode (def: landscape)

  • vertical – Draw bottom-to-top instead of left-to-right

  • fontsize – Set fontsize

  • height – Set height

  • width – Set width

  • nodesep – Set minimum separation between nodes (see dot documentation)

  • ranksep – Set minimum separation between ranks (see dot documentation)

  • allow_negative_labels – Allow negative labels (not recommended; may cause conflicts)

Returns

Return a string.

Example 1: Draw a transducer

Listing 24 Draw a transducer.
 1import graphviz
 2
 3import kaldifst
 4
 5s1 = """
 60 1 a q 1
 70 2 a r 2.5
 81 1 c s 1
 91 0
102 2.5
11"""
12
13sym1 = kaldifst.SymbolTable(name="sym1")
14sym1.add_symbol("a", 1)
15sym1.add_symbol("c", 2)
16
17sym2 = kaldifst.SymbolTable(name="sym2")
18sym2.add_symbol("q", 1)
19sym2.add_symbol("r", 2)
20sym2.add_symbol("s", 3)
21
22fst = kaldifst.compile(s=s1, acceptor=False, isymbols=sym1, osymbols=sym2)
23fst.input_symbols = sym1
24fst.output_symbols = sym2
25
26fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
27with open("fst_dot.txt", "w") as f:
28    f.write(fst_dot)
29
30fst_source = graphviz.Source(fst_dot)
31fst_source.render(outfile="fst.svg")
Listing 25 fst_dot.txt
 1digraph FST {
 2rankdir = LR;
 3size = "8.5,11";
 4center = 1;
 5orientation = Portrait;
 6ranksep = "0.4";
 7nodesep = "0.25";
 80 [label = "0", shape = circle, style = bold, fontsize = 14]
 9	0 -> 1 [label = "a:q/1", fontsize = 14];
10	0 -> 2 [label = "a:r/2.5", fontsize = 14];
111 [label = "1", shape = doublecircle, style = solid, fontsize = 14]
12	1 -> 1 [label = "c:s/1", fontsize = 14];
132 [label = "2/2.5", shape = doublecircle, style = solid, fontsize = 14]
14}
fst.svg

Fig. 41 Visualization of fst.svg

  1. draw(fst: _kaldifst.LatticeFst, acceptor: bool = False, isymbols: object = None, osymbols: object = None, ssymbols: object = None, numeric: bool = False, precision: int = 5, float_format: str = ‘g’, show_weight_one: bool = False, title: str = ‘’, portrait: bool = False, vertical: bool = False, fontsize: int = 14, height: float = 11, width: float = 8.5, nodesep: float = 0.25, ranksep: float = 0.4, allow_negative_labels: bool = False) -> str

Prints FSTs in dot text format.

Hint

You can use the Python package graphviz to visualize it.

You can also post the dot format output to https://dreampuf.github.io/GraphvizOnline/ to visualize it within your browser. You can also share the URL to others.

Parameters
  • fst – The FST to be printed.

  • acceptor – Input in acceptor format

  • isymbols – Input label symbol table

  • osymbols – Output label symbol table

  • ssymbols – State label symbol table

  • numeric – Print numeric labels

  • precision – Set precision (number of char/float)

  • float_format – Floating-point format, one of: “e”, “f”, or “g”

  • show_weight_one – Print/draw arc weights and final weights equal to Weight::One()

  • title – Set figure title

  • portrait – Portrait mode (def: landscape)

  • vertical – Draw bottom-to-top instead of left-to-right

  • fontsize – Set fontsize

  • height – Set height

  • width – Set width

  • nodesep – Set minimum separation between nodes (see dot documentation)

  • ranksep – Set minimum separation between ranks (see dot documentation)

  • allow_negative_labels – Allow negative labels (not recommended; may cause conflicts)

Returns

Return a string.

Example 1: Draw a transducer

Listing 26 Draw a transducer.
 1import graphviz
 2
 3import kaldifst
 4
 5s1 = """
 60 1 a q 1
 70 2 a r 2.5
 81 1 c s 1
 91 0
102 2.5
11"""
12
13sym1 = kaldifst.SymbolTable(name="sym1")
14sym1.add_symbol("a", 1)
15sym1.add_symbol("c", 2)
16
17sym2 = kaldifst.SymbolTable(name="sym2")
18sym2.add_symbol("q", 1)
19sym2.add_symbol("r", 2)
20sym2.add_symbol("s", 3)
21
22fst = kaldifst.compile(s=s1, acceptor=False, isymbols=sym1, osymbols=sym2)
23fst.input_symbols = sym1
24fst.output_symbols = sym2
25
26fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
27with open("fst_dot.txt", "w") as f:
28    f.write(fst_dot)
29
30fst_source = graphviz.Source(fst_dot)
31fst_source.render(outfile="fst.svg")
Listing 27 fst_dot.txt
 1digraph FST {
 2rankdir = LR;
 3size = "8.5,11";
 4center = 1;
 5orientation = Portrait;
 6ranksep = "0.4";
 7nodesep = "0.25";
 80 [label = "0", shape = circle, style = bold, fontsize = 14]
 9	0 -> 1 [label = "a:q/1", fontsize = 14];
10	0 -> 2 [label = "a:r/2.5", fontsize = 14];
111 [label = "1", shape = doublecircle, style = solid, fontsize = 14]
12	1 -> 1 [label = "c:s/1", fontsize = 14];
132 [label = "2/2.5", shape = doublecircle, style = solid, fontsize = 14]
14}
fst.svg

Fig. 42 Visualization of fst.svg

equal_align

kaldifst.equal_align(ifst: _kaldifst.StdVectorFst, length: int, rand_seed: int, num_retries: int = 10) Tuple[bool, _kaldifst.StdVectorFst]

Get a random linear path from an FST.

Parameters
  • ifst – The input fst.

  • length – Path length of the output fst. If the ilabel of an arc is 0, then this arc does not contribute to the total path length of the output fst.

  • rand_seed – A seed for random selecting arcs out of each state.

  • num_retries – After trying this number but failed to generate a valid fst, it would return False.

Returns

  • succeeded, True if we successfully found a path.

  • fst, the output fst.

Return type

Return a tuple containing

Example 1: Equal align

Listing 28 Code for equal_align
 1import graphviz
 2
 3import kaldifst
 4
 5s1 = """
 60 0 e E 0.3
 70 1 a A 1
 80 1 b B 2.5
 91 2 <eps> <eps> 0.3
101 2 <eps> <eps> 0.4
111 1 f F 0.03
122 2 g G 0.8
132 3 h H 0.12
143
15"""
16
17sym1 = kaldifst.SymbolTable(name="sym1")
18sym1.add_symbol("<eps>", 0)
19sym1.add_symbol("a", 1)
20sym1.add_symbol("b", 2)
21sym1.add_symbol("c", 3)
22sym1.add_symbol("d", 4)
23sym1.add_symbol("e", 5)
24sym1.add_symbol("f", 6)
25sym1.add_symbol("g", 7)
26sym1.add_symbol("h", 8)
27
28sym2 = kaldifst.SymbolTable(name="sym2")
29sym2.add_symbol("<eps>", 0)
30sym2.add_symbol("A", 1)
31sym2.add_symbol("B", 2)
32sym2.add_symbol("C", 3)
33sym2.add_symbol("D", 4)
34sym2.add_symbol("E", 5)
35sym2.add_symbol("F", 6)
36sym2.add_symbol("G", 7)
37sym2.add_symbol("H", 8)
38
39fst = kaldifst.compile(s=s1, acceptor=False, isymbols=sym1, osymbols=sym2)
40
41fst.input_symbols = sym1
42fst.output_symbols = sym2
43
44fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
45fst_source = graphviz.Source(fst_dot)
46fst_source.render(outfile="input.svg")
47
48succeeded, first = kaldifst.equal_align(
49    ifst=fst, length=4, rand_seed=3, num_retries=10
50)
51assert succeeded is True
52first.input_symbols = sym1
53first.output_symbols = sym1
54
55first_dot = kaldifst.draw(first, acceptor=False, portrait=True)
56first_source = graphviz.Source(first_dot)
57first_source.render(outfile="first.svg")
58
59succeeded, second = kaldifst.equal_align(
60    ifst=fst, length=5, rand_seed=10, num_retries=10
61)
62assert succeeded is True
63second.input_symbols = sym1
64second.output_symbols = sym2
65
66second_dot = kaldifst.draw(second, acceptor=False, portrait=True)
67second_source = graphviz.Source(second_dot)
68second_source.render(outfile="second.svg")
input.svg

Fig. 43 Visualization of input.svg

first.svg

Fig. 44 Visualization of first.svg

second.svg

Fig. 45 Visualization of second.svg

get_linear_symbol_sequence

kaldifst.get_linear_symbol_sequence(*args, **kwargs)

Overloaded function.

  1. get_linear_symbol_sequence(fst: _kaldifst.StdFst) -> Tuple[bool, List[int], List[int], _kaldifst.TropicalWeight]

get_linear_symbol_sequence gets the symbol sequence from a linear FST. If the FST is not just a linear sequence, it returns false. If it is a linear sequence (including the empty FST), it returns true. In this case it outputs the symbol

Parameters

fst – The input fst.

Returns

  • succeeded, bool, true if it succeeded.

  • isymbols_out, List[int], containing non-zero input symbols

  • osymbols_out, List[int], containing non-zero output symbols

  • total_weight_out, float, the total weight

Return type

Return a tuple containing

Example 1: get_linear_symbol_sequence

Listing 29 Code for get_linear_symbol_sequence
 1import graphviz
 2
 3import kaldifst
 4
 5s = """
 60 1 0 2 0.5
 71 2 1 3 0.8
 82 3 3 5 0.7
 93 4 9 0 0.1
104 0.2
11"""
12
13
14fst = kaldifst.compile(s=s, acceptor=False)
15
16(
17    succeeded,
18    isymbols_out,
19    osymbols_out,
20    total_weight,
21) = kaldifst.get_linear_symbol_sequence(fst)
22assert succeeded is True
23assert isymbols_out == [1, 3, 9]
24assert osymbols_out == [2, 3, 5]
25
26assert (
27    abs(total_weight.value - (0.5 + 0.8 + 0.7 + 0.1 + 0.2)) < 1e-3
28), total_weight.value
  1. get_linear_symbol_sequence(fst: _kaldifst.LatticeFst) -> Tuple[bool, List[int], List[int], _kaldifst.LatticeWeight]

get_linear_symbol_sequence gets the symbol sequence from a linear FST. If the FST is not just a linear sequence, it returns false. If it is a linear sequence (including the empty FST), it returns true. In this case it outputs the symbol

Parameters

fst – The input fst.

Returns

  • succeeded, bool, true if it succeeded.

  • isymbols_out, List[int], containing non-zero input symbols

  • osymbols_out, List[int], containing non-zero output symbols

  • total_weight_out, float, the total weight

Return type

Return a tuple containing

Example 1: get_linear_symbol_sequence

Listing 30 Code for get_linear_symbol_sequence
 1import graphviz
 2
 3import kaldifst
 4
 5s = """
 60 1 0 2 0.5
 71 2 1 3 0.8
 82 3 3 5 0.7
 93 4 9 0 0.1
104 0.2
11"""
12
13
14fst = kaldifst.compile(s=s, acceptor=False)
15
16(
17    succeeded,
18    isymbols_out,
19    osymbols_out,
20    total_weight,
21) = kaldifst.get_linear_symbol_sequence(fst)
22assert succeeded is True
23assert isymbols_out == [1, 3, 9]
24assert osymbols_out == [2, 3, 5]
25
26assert (
27    abs(total_weight.value - (0.5 + 0.8 + 0.7 + 0.1 + 0.2)) < 1e-3
28), total_weight.value

info

kaldifst.info(fst: _kaldifst.StdFst, arc_filter: str = 'any', info_type: str = 'auto', pipe: bool = False, test_properties: bool = False, fst_verify: bool = True) None

–arc_filter: type = string, default = “any” Arc filter: one of: “any”, “epsilon”, “iepsilon”, “oepsilon”; this only affects the counts of (co)accessible states, connected states, and (strongly) connected components –fst_verify: type = bool, default = true Verify FST sanity –info_type: type = string, default = “auto” Info format: one of: “auto”, “long”, “short” –pipe: type = bool, default = false Send info to stderr, input to stdout –test_properties: type = bool, default = true Compute property values (if unknown to FST)

invert

kaldifst.invert(in_out: _kaldifst.StdMutableFst) None

This operation inverts the transduction corresponding to an FST by exchanging the FST’s input and output labels.

See also https://www.openfst.org/twiki/bin/view/FST/InvertDoc

Caution

The FST is modified in-place.

Parameters

in_out – A transducer. It is modified in-place.

Returns

Return None.

Example Invert a transducer

Listing 31 Invert a transducer
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s = """
 80 1 a y 1
 90 1 b x 3
101 1 d v 7
111 2 c w 5
122 3 f u 9
133 2
14"""
15isym = kaldifst.SymbolTable.from_str(
16    """
17        a 1
18        b 2
19        c 3
20        d 4
21        f 5
22"""
23)
24
25osym = kaldifst.SymbolTable.from_str(
26    """
27        x 1
28        y 2
29        u 3
30        w 4
31        v 5
32"""
33)
34
35fst = kaldifst.compile(
36    s,
37    acceptor=False,
38    isymbols=isym,
39    osymbols=osym,
40    keep_isymbols=True,
41    keep_osymbols=True,
42)
43
44
45fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
46fst_source = graphviz.Source(fst_dot)
47fst_source.render(outfile="before-invert.svg")
48
49kaldifst.invert(fst)
50
51fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
52fst_source = graphviz.Source(fst_dot)
53fst_source.render(outfile="after-invert.svg")
before-invert.svg

Fig. 46 Visualization of before-invert.svg

after-invert.svg

Fig. 47 Visualization of after-invert.svg

lattice_scale

kaldifst.lattice_scale(lmwt: float, acwt: float) List[List[float]]

Return a diagonal scale matrix with specified LM scale lmwt and AM scale amwt.

Note that the diagonal matrix is a list of list, e.g., [[lmwt, 0], [0, acwt]].

Parameters
  • lmwt – Scale for language model scores.

  • acwt – Scale for acoustic likelihoods.

Returns

  • A list-of-list containing [[lmwt, 0], [0, acwt]].

Example 1: Return a matrix with lmwt=0.1, acwt=10.0

Listing 32 Return a matrix with lmwt=0.1, acwt=10.0
1#!/usr/bin/env python3
2
3import kaldifst
4
5m = kaldifst.lattice_scale(lmwt=0.1, acwt=10.0)
6assert m == [[0.1, 0.0], [0.0, 10.0]], m

lattice_to_nbest

kaldifst.lattice_to_nbest(lat, acoustic_scale=1.0, lm_scale=1.0, n=1)

Work out N-best paths in lattices

It implements https://github.com/kaldi-asr/kaldi/blob/master/src/latbin/lattice-to-nbest.cc

Parameters
  • lat (Union[Lattice, StdVectorFst]) – The input lattice.

  • acoustic_scale (float) – Scaling factor for acoustic likelihoods.

  • lm_scale (float) – Scaling factor for language model scores.

  • n (int) – Number of distinct paths.

Return type

List[Union[Lattice, StdVectorFst]]

Returns

Return a list of linear FSTs.

Example for a StdVectorFst

Listing 33 lattice_to_nbest for a StdVectorFst
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s1 = """
 80 1 a 0.1
 90 2 b 0.1
101 3 c 0.4
111 3 d 0.2
122 3 c 0.3
132 3 d 0.2
143 0
15"""
16
17sym1 = kaldifst.SymbolTable(name="sym1")
18sym1.add_symbol("eps", 0)
19sym1.add_symbol("a", 1)
20sym1.add_symbol("b", 2)
21sym1.add_symbol("c", 3)
22sym1.add_symbol("d", 4)
23
24a = kaldifst.compile(s=s1, acceptor=True, isymbols=sym1)
25a.input_symbols = sym1
26
27a_dot = kaldifst.draw(a, acceptor=True, portrait=True)
28a_source = graphviz.Source(a_dot)
29a_source.render(outfile="vector-fst.svg")
30
31nbest_list = kaldifst.lattice_to_nbest(a, n=3)
32for b in nbest_list:
33    b.input_symbols = a.input_symbols
34    b.output_symbols = a.output_symbols
35
36nbest_list_0_dot = kaldifst.draw(nbest_list[0], acceptor=True, portrait=True)
37nbest_list_0_source = graphviz.Source(nbest_list_0_dot)
38nbest_list_0_source.render(outfile="vector-fst-3best-0.svg")
39
40nbest_list_1_dot = kaldifst.draw(nbest_list[1], acceptor=True, portrait=True)
41nbest_list_1_source = graphviz.Source(nbest_list_1_dot)
42nbest_list_1_source.render(outfile="vector-fst-3best-1.svg")
43
44nbest_list_2_dot = kaldifst.draw(nbest_list[2], acceptor=True, portrait=True)
45nbest_list_2_source = graphviz.Source(nbest_list_2_dot)
46nbest_list_2_source.render(outfile="vector-fst-3best-2.svg")
vector-fst.svg

Fig. 48 Visualization of vector-fst.svg

vector-fst-3best-0.svg

Fig. 49 Visualization of vector-fst-3best-0.svg

vector-fst-3best-1.svg

Fig. 50 Visualization of vector-fst-3best-1.svg

vector-fst-3best-2.svg

Fig. 51 Visualization of vector-fst-3best-2.svg

Example for a Lattice

Listing 34 lattice_to_nbest for a Lattice
  1#!/usr/bin/env python3
  2
  3import graphviz
  4
  5import kaldifst
  6
  7fst = kaldifst.Lattice()
  8s0 = fst.add_state()
  9s1 = fst.add_state()
 10s2 = fst.add_state()
 11s3 = fst.add_state()
 12
 13fst.start = s0
 14fst.add_arc(
 15    state=s0,
 16    arc=kaldifst.LatticeArc(
 17        ilabel=1,
 18        olabel=1,
 19        weight=kaldifst.LatticeWeight(graph_cost=0.02, acoustic_cost=0.08),
 20        nextstate=s1,
 21    ),
 22)
 23
 24fst.add_arc(
 25    state=s0,
 26    arc=kaldifst.LatticeArc(
 27        ilabel=2,
 28        olabel=2,
 29        weight=kaldifst.LatticeWeight(graph_cost=0.03, acoustic_cost=0.07),
 30        nextstate=s2,
 31    ),
 32)
 33
 34fst.add_arc(
 35    state=s1,
 36    arc=kaldifst.LatticeArc(
 37        ilabel=3,
 38        olabel=3,
 39        weight=kaldifst.LatticeWeight(graph_cost=0.1, acoustic_cost=0.3),
 40        nextstate=s3,
 41    ),
 42)
 43
 44fst.add_arc(
 45    state=s1,
 46    arc=kaldifst.LatticeArc(
 47        ilabel=4,
 48        olabel=4,
 49        weight=kaldifst.LatticeWeight(graph_cost=0.15, acoustic_cost=0.05),
 50        nextstate=s3,
 51    ),
 52)
 53
 54fst.add_arc(
 55    state=s2,
 56    arc=kaldifst.LatticeArc(
 57        ilabel=3,
 58        olabel=3,
 59        weight=kaldifst.LatticeWeight(graph_cost=0.15, acoustic_cost=0.15),
 60        nextstate=s3,
 61    ),
 62)
 63
 64fst.add_arc(
 65    state=s2,
 66    arc=kaldifst.LatticeArc(
 67        ilabel=4,
 68        olabel=4,
 69        weight=kaldifst.LatticeWeight(graph_cost=0.05, acoustic_cost=0.15),
 70        nextstate=s3,
 71    ),
 72)
 73
 74fst.set_final(state=s3, weight=kaldifst.LatticeWeight.one)
 75
 76
 77sym1 = kaldifst.SymbolTable(name="sym1")
 78sym1.add_symbol("eps", 0)
 79sym1.add_symbol("a", 1)
 80sym1.add_symbol("b", 2)
 81sym1.add_symbol("c", 3)
 82sym1.add_symbol("d", 4)
 83
 84sym2 = kaldifst.SymbolTable(name="sym2")
 85sym2.add_symbol("eps", 0)
 86sym2.add_symbol("A", 1)
 87sym2.add_symbol("B", 2)
 88sym2.add_symbol("C", 3)
 89sym2.add_symbol("D", 4)
 90
 91fst.input_symbols = sym1
 92fst.output_symbols = sym2
 93
 94fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
 95fst_source = graphviz.Source(fst_dot)
 96fst_source.render(outfile="lattice.svg")
 97
 98nbest_list = kaldifst.lattice_to_nbest(fst, n=3)
 99for b in nbest_list:
100    b.input_symbols = fst.input_symbols
101    b.output_symbols = fst.output_symbols
102
103nbest_list_0_dot = kaldifst.draw(nbest_list[0], acceptor=True, portrait=True)
104nbest_list_0_source = graphviz.Source(nbest_list_0_dot)
105nbest_list_0_source.render(outfile="lattice-3best-0.svg")
106
107nbest_list_1_dot = kaldifst.draw(nbest_list[1], acceptor=True, portrait=True)
108nbest_list_1_source = graphviz.Source(nbest_list_1_dot)
109nbest_list_1_source.render(outfile="lattice-3best-1.svg")
110
111nbest_list_2_dot = kaldifst.draw(nbest_list[2], acceptor=True, portrait=True)
112nbest_list_2_source = graphviz.Source(nbest_list_2_dot)
113nbest_list_2_source.render(outfile="lattice-3best-2.svg")
lattice.svg

Fig. 52 Visualization of lattice.svg

lattice-3best-0.svg

Fig. 53 Visualization of lattice-3best-0.svg

lattice-3best-1.svg

Fig. 54 Visualization of lattice-3best-1.svg

lattice-3best-2.svg

Fig. 55 Visualization of lattice-3best-2.svg

make_linear_acceptor

kaldifst.make_linear_acceptor(labels: List[int]) _kaldifst.StdVectorFst

Creates unweighted linear acceptor from symbol sequence.

Parameters

labels – A list of symbol IDs.

Returns

Return a linear acceptor. Actually, it returns a transducer whose ilabel == olabel for each arc.

Example 1: Build a linear acceptor

Listing 35 Example of make_linear_acceptor()
 1import graphviz
 2
 3import kaldifst
 4
 5
 6sym1 = kaldifst.SymbolTable(name="sym1")
 7sym1.add_symbol("e", 1)
 8sym1.add_symbol("h", 2)
 9sym1.add_symbol("l", 3)
10sym1.add_symbol("o", 4)
11
12
13fst = kaldifst.make_linear_acceptor([2, 1, 3, 3, 4])
14
15fst.input_symbols = sym1
16fst.output_symbols = sym1
17
18fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
19fst_source = graphviz.Source(fst_dot)
20fst_source.render(outfile="acceptor.svg")
acceptor.svg

Fig. 56 Visualization of acceptor.svg

minimize

kaldifst.minimize(in_out: _kaldifst.StdMutableFst, delta: float = 1e-06, allow_nondet: bool = False) None

This operation performs the minimization of deterministic weighted automata and transducers.

See also https://www.openfst.org/twiki/bin/view/FST/MinimizeDoc.

Caution

The FST is modified in-place.

Parameters
  • in_out – An acceptor or a transducer. It is modified in-place.

  • delta – Comparison/quantization delta

  • allow_nondet – type = bool, default = false True to minimize non-deterministic FSTs

Returns

Return None.

Example 1: Minimize an acceptor

Listing 36 Minimize an acceptor
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s = """
 80 1 a 2
 90 1 b 2
100 1 c 3
110 2 d 3
120 2 f 1
131 3 f 3
141 3 g 2
153 1
162 4 f 5
172 4 g 4
184 3
19"""
20
21isym = kaldifst.SymbolTable.from_str(
22    """
23        a 1
24        b 2
25        c 3
26        d 4
27        f 5
28        g 6
29"""
30)
31
32fst = kaldifst.compile(
33    s,
34    acceptor=True,
35    isymbols=isym,
36    keep_isymbols=True,
37)
38
39fst_dot = kaldifst.draw(fst, acceptor=True, portrait=True)
40fst_source = graphviz.Source(fst_dot)
41fst_source.render(outfile="acceptor.svg")
42
43kaldifst.minimize(fst)
44
45fst_dot = kaldifst.draw(fst, acceptor=True, portrait=True)
46fst_source = graphviz.Source(fst_dot)
47fst_source.render(outfile="acceptor-minimized.svg")
acceptor.svg

Fig. 57 Visualization of acceptor.svg (before minimize)

acceptor-minimized.svg

Fig. 58 Visualization of acceptor-minimized.svg (after minimize)

Example 2: Minimize a transducer

Listing 37 Minimize a transducer
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s = """
 80 1 a a 2
 90 1 b a 2
100 1 c a 3
110 2 d a 3
120 2 f a 1
131 3 f b 3
141 3 g b 2
153 1
162 4 f c 5
172 4 g c 4
184 3
19"""
20
21isym = kaldifst.SymbolTable.from_str(
22    """
23        a 1
24        b 2
25        c 3
26        d 4
27        f 5
28        g 6
29"""
30)
31
32osym = kaldifst.SymbolTable.from_str(
33    """
34        a 1
35        b 2
36        c 3
37"""
38)
39
40
41fst = kaldifst.compile(
42    s,
43    acceptor=False,
44    isymbols=isym,
45    osymbols=osym,
46    keep_isymbols=True,
47    keep_osymbols=True,
48)
49
50fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
51fst_source = graphviz.Source(fst_dot)
52fst_source.render(outfile="transducer.svg")
53
54kaldifst.minimize(fst)
55
56fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
57fst_source = graphviz.Source(fst_dot)
58fst_source.render(outfile="transducer-minimized.svg")
transducer.svg

Fig. 59 Visualization of transducer.svg (before minimize)

transducer-minimized.svg

Fig. 60 Visualization of transducer-minimized.svg (after minimize)

minimize_encoded

kaldifst.minimize_encoded(in_out: _kaldifst.StdMutableFst, delta: float = 0.0009765625) None

Minimizes after encoding; applicable to all FSTs.

Its implementation is from Kaldi:

Map(fst, QuantizeMapper<Arc>(delta));
EncodeMapper<Arc> encoder(kEncodeLabels | kEncodeWeights, ENCODE);
Encode(fst, &encoder);
internal::AcceptorMinimize(fst);
Decode(fst, encoder);

See also https://github.com/kaldi-asr/kaldi/blob/master/src/fstbin/fstminimizeencoded.cc.

Caution

The FST is modified in-place.

Parameters
  • in_out – An acceptor or a transducer. It is modified in-place.

  • delta – Comparison/quantization delta

Returns

Return None.

Example 1: Minimize encode an acceptor

Listing 38 Minimize encode an acceptor
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s = """
 80 1 a 2
 90 1 b 2
100 1 c 3
110 2 d 3
120 2 f 1
131 3 f 3
141 3 g 2
153 1
162 4 f 5
172 4 g 4
184 3
19"""
20
21isym = kaldifst.SymbolTable.from_str(
22    """
23        a 1
24        b 2
25        c 3
26        d 4
27        f 5
28        g 6
29"""
30)
31
32fst = kaldifst.compile(
33    s,
34    acceptor=True,
35    isymbols=isym,
36    keep_isymbols=True,
37)
38
39fst_dot = kaldifst.draw(fst, acceptor=True, portrait=True)
40fst_source = graphviz.Source(fst_dot)
41fst_source.render(outfile="acceptor.svg")
42
43fst.write("acceptor.fst")
44kaldifst.minimize_encoded(fst)
45
46fst_dot = kaldifst.draw(fst, acceptor=True, portrait=True)
47fst_source = graphviz.Source(fst_dot)
48fst_source.render(outfile="acceptor-minimize-encoded.svg")
acceptor.svg

Fig. 61 Visualization of acceptor.svg (before minimize_encoded)

acceptor-minimize-encoded.svg

Fig. 62 Visualization of acceptor-minimize-encoded.svg (after minimize_encoded)

Example 2: Minimize encode a transducer

Listing 39 Minimize encode a transducer
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s = """
 80 1 a a 2
 90 1 b a 2
100 1 c a 3
110 2 d a 3
120 2 f a 1
131 3 f b 3
141 3 g b 2
153 1
162 4 f c 5
172 4 g c 4
184 3
19"""
20
21isym = kaldifst.SymbolTable.from_str(
22    """
23        a 1
24        b 2
25        c 3
26        d 4
27        f 5
28        g 6
29"""
30)
31
32osym = kaldifst.SymbolTable.from_str(
33    """
34        a 1
35        b 2
36        c 3
37"""
38)
39
40
41fst = kaldifst.compile(
42    s,
43    acceptor=False,
44    isymbols=isym,
45    osymbols=osym,
46    keep_isymbols=True,
47    keep_osymbols=True,
48)
49
50fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
51fst_source = graphviz.Source(fst_dot)
52fst_source.render(outfile="transducer.svg")
53
54kaldifst.minimize_encoded(fst)
55
56fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
57fst_source = graphviz.Source(fst_dot)
58fst_source.render(outfile="transducer-minimize-encoded.svg")
transducer.svg

Fig. 63 Visualization of transducer.svg (before minimize_encoded)

transducer-minimize-encoded.svg

Fig. 64 Visualization of transducer-minimize-encoded.svg (after minimize encoded)

plus

kaldifst.plus(*args, **kwargs)

Overloaded function.

  1. plus(arg0: _kaldifst.TropicalWeight, arg1: _kaldifst.TropicalWeight) -> _kaldifst.TropicalWeight

  2. plus(arg0: _kaldifst.LatticeWeight, arg1: _kaldifst.LatticeWeight) -> _kaldifst.LatticeWeight

reverse

kaldifst.reverse(ifst: _kaldifst.StdFst, require_superinitial: bool = True) _kaldifst.StdVectorFst

This operation reverses an FST. If A transduces string x to y with weight a, then the reverse of A transduces the reverse of x to the reverse of y with weight a.Reverse().

See also https://www.openfst.org/twiki/bin/view/FST/ReverseDoc.

Parameters
  • ifst – The input FST.

  • require_superinitial – True to create a superinitial state.

Returns

Return the reversed FST.

Example 1 Revert an acceptor (require_superinitial=True)

Listing 40 Revert an acceptor using require_superinitial=True
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s = """
 80 0 a 2
 90 1 a 1
101 3
111 2 b 3
121 2 b 4
132 2 d 5
142 3 d 6
153 3 f 2
163 2
17"""
18isym = kaldifst.SymbolTable.from_str(
19    """
20        eps 0
21        a 1
22        b 2
23        c 3
24        d 4
25        f 5
26"""
27)
28
29fst = kaldifst.compile(
30    s,
31    acceptor=True,
32    isymbols=isym,
33    keep_isymbols=True,
34)
35
36fst_dot = kaldifst.draw(fst, acceptor=True, portrait=True)
37fst_source = graphviz.Source(fst_dot)
38fst_source.render(outfile="acceptor-before-reverse.svg")
39
40fst = kaldifst.reverse(fst, require_superinitial=True)
41
42fst_dot = kaldifst.draw(fst, acceptor=True, portrait=True)
43fst_source = graphviz.Source(fst_dot)
44fst_source.render(outfile="acceptor-after-reverse.svg")
acceptor-before-reverse.svg

Fig. 65 Visualization of acceptor-before-reverse.svg

acceptor-after-reverse.svg

Fig. 66 Visualization of acceptor-after-reverse.svg using require_superinitial=True

Example 2 Revert an acceptor (require_superinitial=False)

Listing 41 Revert an acceptor using require_superinitial=False
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s = """
 80 0 a 2
 90 1 a 1
101 3
111 2 b 3
121 2 b 4
132 2 d 5
142 3 d 6
153 3 f 2
163 2
17"""
18isym = kaldifst.SymbolTable.from_str(
19    """
20        eps 0
21        a 1
22        b 2
23        c 3
24        d 4
25        f 5
26"""
27)
28
29fst = kaldifst.compile(
30    s,
31    acceptor=True,
32    isymbols=isym,
33    keep_isymbols=True,
34)
35
36fst_dot = kaldifst.draw(fst, acceptor=True, portrait=True)
37fst_source = graphviz.Source(fst_dot)
38fst_source.render(outfile="acceptor-before-reverse-2.svg")
39
40fst = kaldifst.reverse(fst, require_superinitial=False)
41
42fst_dot = kaldifst.draw(fst, acceptor=True, portrait=True)
43fst_source = graphviz.Source(fst_dot)
44fst_source.render(outfile="acceptor-after-reverse-2.svg")
acceptor-before-reverse-2.svg

Fig. 67 Visualization of acceptor-before-reverse-2.svg

acceptor-after-reverse-2.svg

Fig. 68 Visualization of acceptor-after-reverse-2.svg using require_superinitial=False

Example 3 Revert a transducer (require_superinitial=False)

Listing 42 Revert a transducer using require_superinitial=True
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s = """
 80 1 a a
 91 2 b b
101 3 c c
112 4 eps eps
123 4 eps eps
134
14"""
15isym = kaldifst.SymbolTable.from_str(
16    """
17        eps 0
18        a 1
19        b 2
20        c 3
21"""
22)
23
24fst = kaldifst.compile(
25    s,
26    acceptor=False,
27    isymbols=isym,
28    osymbols=isym,
29    keep_isymbols=True,
30    keep_osymbols=True,
31)
32
33fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
34fst_source = graphviz.Source(fst_dot)
35fst_source.render(outfile="transducer-before-reverse.svg")
36
37fst = kaldifst.reverse(fst, require_superinitial=True)
38
39fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
40fst_source = graphviz.Source(fst_dot)
41fst_source.render(outfile="transducer-after-reverse.svg")
transducer-before-reverse.svg

Fig. 69 Visualization of transducer-before-reverse.svg

transducer-after-reverse.svg

Fig. 70 Visualization of transducer-after-reverse.svg using require_superinitial=True

Example 4 Revert a transducer (require_superinitial=False)

Listing 43 Revert a transducer using require_superinitial=False
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s = """
 80 1 a a
 91 2 b b
101 3 c c
112 4 eps eps
123 4 eps eps
134
14"""
15isym = kaldifst.SymbolTable.from_str(
16    """
17        eps 0
18        a 1
19        b 2
20        c 3
21"""
22)
23
24fst = kaldifst.compile(
25    s,
26    acceptor=False,
27    isymbols=isym,
28    osymbols=isym,
29    keep_isymbols=True,
30    keep_osymbols=True,
31)
32
33fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
34fst_source = graphviz.Source(fst_dot)
35fst_source.render(outfile="transducer-before-reverse-2.svg")
36
37fst = kaldifst.reverse(fst, require_superinitial=False)
38
39fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
40fst_source = graphviz.Source(fst_dot)
41fst_source.render(outfile="transducer-after-reverse-2.svg")
transducer-before-reverse-2.svg

Fig. 71 Visualization of transducer-before-reverse-2.svg

transducer-after-reverse-2.svg

Fig. 72 Visualization of transducer-after-reverse-2.svg using require_superinitial=False

rmepsilon

kaldifst.rmepsilon(in_out: _kaldifst.StdMutableFst, connect: bool = True, delta: float = 1e-06, nstate: int = - 1, queue_type: str = 'auto', weight: str = '') None

This operation removes epsilon-transitions (when both the input and output label are an epsilon) from a transducer. The result will be an equivalent FST that has no such epsilon transitions.

See also https://www.openfst.org/twiki/bin/view/FST/RmEpsilonDoc

Caution

The FST is modified in-place.

Parameters
  • in_out – An FST. It is modified in-place.

  • connect – Trim output

  • delta – Comparison/quantization delta

  • nstate – State number threshold

  • queue_type – Queue type: one of: “auto”, “fifo”, “lifo”, “shortest”, “state”, “top”

  • weight – Weight threshold

Returns

Return None.

Example Remove epsilon of a transducer

Listing 44 Remove epsilon of transducer
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s = """
 80 1 eps eps 1
 91 2 a eps 2
101 2 eps p 3
111 2 eps eps 4
122 2 eps eps 5
132 3 eps eps 6
143 7
15"""
16isym = kaldifst.SymbolTable.from_str(
17    """
18        eps 0
19        a 1
20"""
21)
22
23osym = kaldifst.SymbolTable.from_str(
24    """
25        eps 0
26        p 1
27"""
28)
29
30fst = kaldifst.compile(
31    s,
32    acceptor=False,
33    isymbols=isym,
34    osymbols=osym,
35    keep_isymbols=True,
36    keep_osymbols=True,
37)
38
39
40fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
41fst_source = graphviz.Source(fst_dot)
42fst_source.render(outfile="transducer.svg")
43
44kaldifst.rmepsilon(fst)
45
46fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
47fst_source = graphviz.Source(fst_dot)
48fst_source.render(outfile="transducer-after-rmepsilon.svg")
transducer.svg

Fig. 73 Visualization of transducer.svg

transducer-after-rmepislon.svg

Fig. 74 Visualization of transducer-after-rmepsilon.svg

scale_lattice

kaldifst.scale_lattice(scale: List[List[float]], in_out: _kaldifst.LatticeMutableFst) None

Scales the pairs of weights in LatticeWeight by viewing the pair (a, b) as a 2-vector and pre-multiplying by the 2x2 matrix in “scale”. E.g. typically scale would equal

[ 1   0;
  0  acwt ]

if we want to scale the acoustics by acwt.

  • out_value1 = scale[0][0]*in_value1 + scale[0][1]*in_value2

  • out_value2 = scale[1][0]*in_value1 + scale[1][1]*in_value2

Parameters
  • scale – A list-of-list containing the weight

  • in_out – The lattice is changed in-place.

Returns

Return None.

Example 1: Use a diagonal scale [[0.1, 0], [0, 10]]

Listing 45 Scale a lattice.
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7
 8fst = kaldifst.Lattice()
 9s0 = fst.add_state()
10s1 = fst.add_state()
11s2 = fst.add_state()
12s3 = fst.add_state()
13
14fst.start = s0
15fst.add_arc(
16    state=s0,
17    arc=kaldifst.LatticeArc(
18        ilabel=1,
19        olabel=2,
20        weight=kaldifst.LatticeWeight(graph_cost=0.1, acoustic_cost=0.2),
21        nextstate=s1,
22    ),
23)
24
25fst.add_arc(
26    state=s0,
27    arc=kaldifst.LatticeArc(
28        ilabel=3,
29        olabel=4,
30        weight=kaldifst.LatticeWeight(graph_cost=0.3, acoustic_cost=0.4),
31        nextstate=s2,
32    ),
33)
34
35fst.add_arc(
36    state=s1,
37    arc=kaldifst.LatticeArc(
38        ilabel=5,
39        olabel=6,
40        weight=kaldifst.LatticeWeight(graph_cost=0.5, acoustic_cost=0.6),
41        nextstate=s3,
42    ),
43)
44
45fst.add_arc(
46    state=s2,
47    arc=kaldifst.LatticeArc(
48        ilabel=6,
49        olabel=8,
50        weight=kaldifst.LatticeWeight(graph_cost=0.7, acoustic_cost=0.8),
51        nextstate=s3,
52    ),
53)
54
55fst.set_final(
56    state=s3, weight=kaldifst.LatticeWeight(graph_cost=0.2, acoustic_cost=0.5)
57)
58
59fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
60source = graphviz.Source(fst_dot)
61source.render(outfile="before-scale.svg")
62
63scale = kaldifst.lattice_scale(lmwt=0.1, acwt=10.0)
64
65kaldifst.scale_lattice(scale, fst)
66
67fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
68source = graphviz.Source(fst_dot)
69source.render(outfile="after-scale.svg")
before-scale.svg

Fig. 75 Before scale.

after-scale.svg

Fig. 76 After scale using [[0.1, 0], [0, 10]].

Example 2: Use a non-diagonal scale [[0.1, 1], [0.5, 10]]

Listing 46 Scale a lattice.
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7
 8fst = kaldifst.Lattice()
 9s0 = fst.add_state()
10s1 = fst.add_state()
11s2 = fst.add_state()
12s3 = fst.add_state()
13
14fst.start = s0
15fst.add_arc(
16    state=s0,
17    arc=kaldifst.LatticeArc(
18        ilabel=1,
19        olabel=2,
20        weight=kaldifst.LatticeWeight(graph_cost=0.1, acoustic_cost=0.2),
21        nextstate=s1,
22    ),
23)
24
25fst.add_arc(
26    state=s0,
27    arc=kaldifst.LatticeArc(
28        ilabel=3,
29        olabel=4,
30        weight=kaldifst.LatticeWeight(graph_cost=0.3, acoustic_cost=0.4),
31        nextstate=s2,
32    ),
33)
34
35fst.add_arc(
36    state=s1,
37    arc=kaldifst.LatticeArc(
38        ilabel=5,
39        olabel=6,
40        weight=kaldifst.LatticeWeight(graph_cost=0.5, acoustic_cost=0.6),
41        nextstate=s3,
42    ),
43)
44
45fst.add_arc(
46    state=s2,
47    arc=kaldifst.LatticeArc(
48        ilabel=6,
49        olabel=8,
50        weight=kaldifst.LatticeWeight(graph_cost=0.7, acoustic_cost=0.8),
51        nextstate=s3,
52    ),
53)
54
55fst.set_final(
56    state=s3, weight=kaldifst.LatticeWeight(graph_cost=0.2, acoustic_cost=0.5)
57)
58
59fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
60source = graphviz.Source(fst_dot)
61source.render(outfile="before-scale-2.svg")
62
63scale = [[0.1, 1], [0.5, 10]]
64
65kaldifst.scale_lattice(scale, fst)
66
67fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
68source = graphviz.Source(fst_dot)
69source.render(outfile="after-scale-2.svg")
before-scale-2.svg

Fig. 77 Before scale.

after-scale-2.svg

Fig. 78 After scale using [[0.1, 1], [0.5, 10]].

shortest_path

kaldifst.shortest_path(*args, **kwargs)

Overloaded function.

  1. shortest_path(fst: _kaldifst.StdFst, n: int = 1) -> _kaldifst.StdVectorFst

This operation produces an FST containing the n-shortest paths in the input FST.

The n -shortest paths are the n -lowest weight paths w.r.t. the natural semiring order. The single path that can be read from the ith of at most n transitions leaving the initial state of the resulting FST is the ith shortest path.

See also https://www.openfst.org/twiki/bin/view/FST/ShortestPathDoc.

Parameters
  • n – Size of n-best.

  • unique – Return only distinct strings. (NB: must be acceptor; epsilons treated as regular symbols)

Returns

Return a VectorFst containing n linear paths.

Example: shortest_path of a StdVectorFst

Listing 47 ShortestPath for a StdVectorFst
 1#!/usr/bin/env python3
 2
 3import graphviz
 4
 5import kaldifst
 6
 7s1 = """
 80 1 a 0.1
 90 2 b 0.1
101 3 c 0.4
111 3 d 0.2
122 3 c 0.3
132 3 d 0.2
143 0
15"""
16
17sym1 = kaldifst.SymbolTable(name="sym1")
18sym1.add_symbol("eps", 0)
19sym1.add_symbol("a", 1)
20sym1.add_symbol("b", 2)
21sym1.add_symbol("c", 3)
22sym1.add_symbol("d", 4)
23
24a = kaldifst.compile(s=s1, acceptor=True, isymbols=sym1)
25a.input_symbols = sym1
26
27a_dot = kaldifst.draw(a, acceptor=True, portrait=True)
28a_source = graphviz.Source(a_dot)
29a_source.render(outfile="vector-fst.svg")
30
31nbest_1 = kaldifst.shortest_path(a, n=1)
32nbest_1_dot = kaldifst.draw(nbest_1, acceptor=True, portrait=True)
33nbest_1_source = graphviz.Source(nbest_1_dot)
34nbest_1_source.render(outfile="vector-fst-1best.svg")
35
36nbest_2 = kaldifst.shortest_path(a, n=2)
37nbest_2_dot = kaldifst.draw(nbest_2, acceptor=True, portrait=True)
38nbest_2_source = graphviz.Source(nbest_2_dot)
39nbest_2_source.render(outfile="vector-fst-2best.svg")
40
41nbest_3 = kaldifst.shortest_path(a, n=3)
42nbest_3_dot = kaldifst.draw(nbest_3, acceptor=True, portrait=True)
43nbest_3_source = graphviz.Source(nbest_3_dot)
44nbest_3_source.render(outfile="vector-fst-3best.svg")
vector-fst.svg

Fig. 79 Visualization of vector-fst.svg

vector-fst-1best.svg

Fig. 80 Visualization of vector-fst-1best.svg

vector-fst-2best.svg

Fig. 81 Visualization of vector-fst-2best.svg

vector-fst-3best.svg

Fig. 82 Visualization of vector-fst-3best.svg

  1. shortest_path(fst: _kaldifst.LatticeFst, n: int = 1) -> _kaldifst.Lattice

This operation produces an FST containing the n-shortest paths in the input Lattice.

The n -shortest paths are the n -lowest weight paths w.r.t. the natural semiring order. The single path that can be read from the ith of at most n transitions leaving the initial state of the resulting FST is the ith shortest path.

See also https://www.openfst.org/twiki/bin/view/FST/ShortestPathDoc.

Parameters
  • n – Size of n-best.

  • unique – Return only distinct strings. (NB: must be acceptor; epsilons treated as regular symbols)

Returns

Return a Lattice containing n linear paths.

Example: shortest_path of a Lattice

Listing 48 ShortestPath for a Lattice
  1#!/usr/bin/env python3
  2
  3import graphviz
  4
  5import kaldifst
  6
  7fst = kaldifst.Lattice()
  8s0 = fst.add_state()
  9s1 = fst.add_state()
 10s2 = fst.add_state()
 11s3 = fst.add_state()
 12
 13fst.start = s0
 14fst.add_arc(
 15    state=s0,
 16    arc=kaldifst.LatticeArc(
 17        ilabel=1,
 18        olabel=1,
 19        weight=kaldifst.LatticeWeight(graph_cost=0.02, acoustic_cost=0.08),
 20        nextstate=s1,
 21    ),
 22)
 23
 24fst.add_arc(
 25    state=s0,
 26    arc=kaldifst.LatticeArc(
 27        ilabel=2,
 28        olabel=2,
 29        weight=kaldifst.LatticeWeight(graph_cost=0.03, acoustic_cost=0.07),
 30        nextstate=s2,
 31    ),
 32)
 33
 34fst.add_arc(
 35    state=s1,
 36    arc=kaldifst.LatticeArc(
 37        ilabel=3,
 38        olabel=3,
 39        weight=kaldifst.LatticeWeight(graph_cost=0.1, acoustic_cost=0.3),
 40        nextstate=s3,
 41    ),
 42)
 43
 44fst.add_arc(
 45    state=s1,
 46    arc=kaldifst.LatticeArc(
 47        ilabel=4,
 48        olabel=4,
 49        weight=kaldifst.LatticeWeight(graph_cost=0.15, acoustic_cost=0.05),
 50        nextstate=s3,
 51    ),
 52)
 53
 54fst.add_arc(
 55    state=s2,
 56    arc=kaldifst.LatticeArc(
 57        ilabel=3,
 58        olabel=3,
 59        weight=kaldifst.LatticeWeight(graph_cost=0.15, acoustic_cost=0.15),
 60        nextstate=s3,
 61    ),
 62)
 63
 64fst.add_arc(
 65    state=s2,
 66    arc=kaldifst.LatticeArc(
 67        ilabel=4,
 68        olabel=4,
 69        weight=kaldifst.LatticeWeight(graph_cost=0.05, acoustic_cost=0.15),
 70        nextstate=s3,
 71    ),
 72)
 73
 74fst.set_final(state=s3, weight=kaldifst.LatticeWeight.one)
 75
 76
 77sym1 = kaldifst.SymbolTable(name="sym1")
 78sym1.add_symbol("eps", 0)
 79sym1.add_symbol("a", 1)
 80sym1.add_symbol("b", 2)
 81sym1.add_symbol("c", 3)
 82sym1.add_symbol("d", 4)
 83
 84sym2 = kaldifst.SymbolTable(name="sym2")
 85sym2.add_symbol("eps", 0)
 86sym2.add_symbol("A", 1)
 87sym2.add_symbol("B", 2)
 88sym2.add_symbol("C", 3)
 89sym2.add_symbol("D", 4)
 90
 91fst.input_symbols = sym1
 92fst.output_symbols = sym2
 93
 94fst_dot = kaldifst.draw(fst, acceptor=False, portrait=True)
 95fst_source = graphviz.Source(fst_dot)
 96fst_source.render(outfile="lattice.svg")
 97
 98nbest_1 = kaldifst.shortest_path(fst, n=1)
 99nbest_1_dot = kaldifst.draw(nbest_1, acceptor=False, portrait=True)
100nbest_1_source = graphviz.Source(nbest_1_dot)
101nbest_1_source.render(outfile="lattice-1best.svg")
102
103nbest_2 = kaldifst.shortest_path(fst, n=2)
104nbest_2_dot = kaldifst.draw(nbest_2, acceptor=False, portrait=True)
105nbest_2_source = graphviz.Source(nbest_2_dot)
106nbest_2_source.render(outfile="lattice-2best.svg")
107
108nbest_3 = kaldifst.shortest_path(fst, n=3)
109nbest_3_dot = kaldifst.draw(nbest_3, acceptor=False, portrait=True)
110nbest_3_source = graphviz.Source(nbest_3_dot)
111nbest_3_source.render(outfile="lattice-3best.svg")
lattice.svg

Fig. 83 Visualization of lattice.svg

lattice-1best.svg

Fig. 84 Visualization of lattice-1best.svg

lattice-2best.svg

Fig. 85 Visualization of lattice-2best.svg

lattice-3best.svg

Fig. 86 Visualization of lattice-3best.svg

times

kaldifst.times(*args, **kwargs)

Overloaded function.

  1. times(arg0: _kaldifst.TropicalWeight, arg1: _kaldifst.TropicalWeight) -> _kaldifst.TropicalWeight

  2. times(arg0: _kaldifst.LatticeWeight, arg1: _kaldifst.LatticeWeight) -> _kaldifst.LatticeWeight

ArcIterator

done

ArcIterator.done

flags

ArcIterator.flags

position

ArcIterator.position

value

ArcIterator.value

FloatWeight

value

FloatWeight.value

Lattice

Please refer to Introduction to Lattice for usage.

copy

Lattice.copy(self: _kaldifst.LatticeFst, safe: bool = False) _kaldifst.LatticeFst
  1. The copying is constant time if safe = false or if safe = true and is on an otherwise unaccessed FST.

(2) If safe = true, the copy is thread-safe in that the original and copy can be safely accessed (but not necessarily mutated) by separate threads. For some FST types, ‘Copy(true)’ should only be called on an FST that has not otherwise been accessed. Behavior is otherwise undefined.

(3) If a MutableFst is copied and then mutated, then the original is unmodified and vice versa (often by a copy-on-write on the initial mutation, which may not be constant time).

Warning

To get a deep copy of an FST, e.g., a deep copy of Lattice lat1, please use:

lat2 = kaldifst.Lattice(lat1)

To get deep copy of StdVectorFst fst1, please use

fst2 = kaldifst.StdVectorFst(fst1)

input_symbols

Lattice.input_symbols

is_ilabel_sorted

Lattice.is_ilabel_sorted

is_olabel_sorted

Lattice.is_olabel_sorted

num_states

Lattice.num_states

output_symbols

Lattice.output_symbols

start

Lattice.start

type

Lattice.type

LatticeArc

__init__

LatticeArc.__init__(*args, **kwargs)

Overloaded function.

  1. __init__(self: _kaldifst.LatticeArc) -> None

  2. __init__(self: _kaldifst.LatticeArc, ilabel: int, olabel: int, weight: _kaldifst.LatticeWeight, nextstate: int) -> None

  3. __init__(self: _kaldifst.LatticeArc, ilabel: int, olabel: int, weight: float, nextstate: int) -> None

ilabel

LatticeArc.ilabel

nextstate

LatticeArc.nextstate

olabel

LatticeArc.olabel

weight

LatticeArc.weight

LatticeWeight

value1

The graph cost.

LatticeWeight.value1

value2

The acoustic cost.

LatticeWeight.value2

RandomAccessVectorFstReader

is_open

RandomAccessVectorFstReader.is_open

Return True if it is opened; return False otherwise.

Return type

bool

SequentialVectorFstReader

done

SequentialVectorFstReader.done
Return type

bool

is_open

SequentialVectorFstReader.is_open

Return True if it is opened; return False otherwise.

Return type

bool

key

SequentialVectorFstReader.key
Return type

str

value

SequentialVectorFstReader.value
Return type

Any

StateIterator

done

StateIterator.done

value

StateIterator.value

StdArc

__init__

StdArc.__init__(*args, **kwargs)

Overloaded function.

  1. __init__(self: _kaldifst.StdArc) -> None

  2. __init__(self: _kaldifst.StdArc, ilabel: int, olabel: int, weight: _kaldifst.TropicalWeight, nextstate: int) -> None

  3. __init__(self: _kaldifst.StdArc, ilabel: int, olabel: int, weight: float, nextstate: int) -> None

ilabel

StdArc.ilabel

nextstate

StdArc.nextstate

olabel

StdArc.olabel

weight

StdArc.weight

StdConstFst

copy

StdConstFst.copy(self: _kaldifst.StdFst, safe: bool = False) _kaldifst.StdFst
  1. The copying is constant time if safe = false or if safe = true and is on an otherwise unaccessed FST.

(2) If safe = true, the copy is thread-safe in that the original and copy can be safely accessed (but not necessarily mutated) by separate threads. For some FST types, ‘Copy(true)’ should only be called on an FST that has not otherwise been accessed. Behavior is otherwise undefined.

(3) If a MutableFst is copied and then mutated, then the original is unmodified and vice versa (often by a copy-on-write on the initial mutation, which may not be constant time).

Warning

To get a deep copy of an FST, e.g., a deep copy of Lattice lat1, please use:

lat2 = kaldifst.Lattice(lat1)

To get deep copy of StdVectorFst fst1, please use

fst2 = kaldifst.StdVectorFst(fst1)

input_symbols

StdConstFst.input_symbols

Returns input label symbol table; return nullptr if not specified.

is_ilabel_sorted

StdConstFst.is_ilabel_sorted

is_olabel_sorted

StdConstFst.is_olabel_sorted

num_states

StdConstFst.num_states

output_symbols

StdConstFst.output_symbols

Returns output label symbol table; return nullptr if not specified.

start

StdConstFst.start

type

StdConstFst.type

StdFst

copy

StdFst.copy(self: _kaldifst.StdFst, safe: bool = False) _kaldifst.StdFst
  1. The copying is constant time if safe = false or if safe = true and is on an otherwise unaccessed FST.

(2) If safe = true, the copy is thread-safe in that the original and copy can be safely accessed (but not necessarily mutated) by separate threads. For some FST types, ‘Copy(true)’ should only be called on an FST that has not otherwise been accessed. Behavior is otherwise undefined.

(3) If a MutableFst is copied and then mutated, then the original is unmodified and vice versa (often by a copy-on-write on the initial mutation, which may not be constant time).

Warning

To get a deep copy of an FST, e.g., a deep copy of Lattice lat1, please use:

lat2 = kaldifst.Lattice(lat1)

To get deep copy of StdVectorFst fst1, please use

fst2 = kaldifst.StdVectorFst(fst1)

input_symbols

StdFst.input_symbols

Returns input label symbol table; return nullptr if not specified.

is_ilabel_sorted

StdFst.is_ilabel_sorted

is_olabel_sorted

StdFst.is_olabel_sorted

output_symbols

StdFst.output_symbols

Returns output label symbol table; return nullptr if not specified.

start

StdFst.start

type

StdFst.type

StdVectorFst

copy

StdVectorFst.copy(self: _kaldifst.StdFst, safe: bool = False) _kaldifst.StdFst
  1. The copying is constant time if safe = false or if safe = true and is on an otherwise unaccessed FST.

(2) If safe = true, the copy is thread-safe in that the original and copy can be safely accessed (but not necessarily mutated) by separate threads. For some FST types, ‘Copy(true)’ should only be called on an FST that has not otherwise been accessed. Behavior is otherwise undefined.

(3) If a MutableFst is copied and then mutated, then the original is unmodified and vice versa (often by a copy-on-write on the initial mutation, which may not be constant time).

Warning

To get a deep copy of an FST, e.g., a deep copy of Lattice lat1, please use:

lat2 = kaldifst.Lattice(lat1)

To get deep copy of StdVectorFst fst1, please use

fst2 = kaldifst.StdVectorFst(fst1)

input_symbols

StdVectorFst.input_symbols

is_ilabel_sorted

StdVectorFst.is_ilabel_sorted

is_olabel_sorted

StdVectorFst.is_olabel_sorted

num_states

StdVectorFst.num_states

output_symbols

StdVectorFst.output_symbols

start

StdVectorFst.start

type

StdVectorFst.type

SymbolTable

add_symbol

SymbolTable.add_symbol(*args, **kwargs)

Overloaded function.

  1. add_symbol(self: _kaldifst.SymbolTable, symbol: str, key: int) -> int

Adds a symbol with given key to table. A symbol table also keeps track of the last available key (highest key value in the symbol table).

  1. add_symbol(self: _kaldifst.SymbolTable, symbol: str) -> int

Adds a symbol to the table. The associated value key is automatically assigned by the symbol table.

find

SymbolTable.find(*args, **kwargs)

Overloaded function.

  1. find(self: _kaldifst.SymbolTable, key: int) -> str

Returns the string associated with the key; if the key is out ofrange (<0, >max), returns an empty string.

  1. find(self: _kaldifst.SymbolTable, symbol: str) -> int

Returns the key associated with the symbol; if the symbol does not exist, kNoSymbol is returned.

  1. find(self: _kaldifst.SymbolTable, symbol: str) -> int

Returns the key associated with the symbol; if the symbol does not exist, kNoSymbol is returned.

check_sum

SymbolTable.check_sum

Return the label-agnostic MD5 check-sum for this table. All new symbols added to the table will result in an updated checksum. Deprecated.

labeled_check_sum

SymbolTable.labeled_check_sum

Same as check_sum, but returns an label-dependent version.

name

SymbolTable.name

TextNormalizer

TropicalWeight

value

TropicalWeight.value

VectorFstWriter

write

VectorFstWriter.write(key, value)

Write an item.

Parameters
  • key (str) – The key for the item.

  • value (Any) – The value for the item. Its type depends on the actual writer class.

Return type

None

is_open

VectorFstWriter.is_open

Return True if it is opened; return False otherwise.

Return type

bool