mirror of
https://github.com/mii443/AzooKeyKanaKanjiConverter.git
synced 2025-08-22 15:05:26 +00:00
* experimental rinna integration * Update impl * update * Bump swift-actions/setup-swift from 1 to 2 Bumps [swift-actions/setup-swift](https://github.com/swift-actions/setup-swift) from 1 to 2. - [Release notes](https://github.com/swift-actions/setup-swift/releases) - [Commits](https://github.com/swift-actions/setup-swift/compare/v1...v2) --- updated-dependencies: - dependency-name: swift-actions/setup-swift dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * change test * change impl * take gpt2 weight as option * don't use async * support status check * enhance error * avoid percent encode * update * GPT-2 based kana-kanji conversion is now perfectly workinggit statusgit status * fix a bug * Rename gpt2/llama -> zenz * cleanup * internal apiを綺麗にした * cleanup experimental commands * update * partially support incremental input using cache * fix names * fix bug * support roman2kana * cleanup * fix minor bugs * improve logic * fix minor bug * fix minor bug * fix minor bug * optimize * optimize performance * Optimize cache hit * cli: add anco session command * fix cache hit bugs * improve session commands * maybe this will work better for incremental input environment * speed up zenzai by using n_best alternatives * update zenz context * adding no_typo api * add inference limit * fix bug * reset install_cli * make package buildable -- but llama.cpp features just do not work at this point because metal is not preprocessed * add proper availability checks * change macOS minimum version * fix several problems * code cleanup * enable ubuntu build * fix build error * fix ubuntu build * fix borrowing * update install_cli.sh --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
101 lines
5.4 KiB
Swift
101 lines
5.4 KiB
Swift
import Foundation
|
||
import SwiftUtils
|
||
|
||
extension Kana2Kanji {
|
||
/// カナを漢字に変換する関数, 前提はなくかな列が与えられた場合。
|
||
/// - Parameters:
|
||
/// - inputData: 入力データ。
|
||
/// - N_best: N_best。
|
||
/// - Returns:
|
||
/// 変換候補。
|
||
/// ### 実装状況
|
||
/// (0)多用する変数の宣言。
|
||
///
|
||
/// (1)まず、追加された一文字に繋がるノードを列挙する。
|
||
///
|
||
/// (2)次に、計算済みノードから、(1)で求めたノードにつながるようにregisterして、N_bestを求めていく。
|
||
///
|
||
/// (3)(1)のregisterされた結果をresultノードに追加していく。この際EOSとの連接計算を行っておく。
|
||
///
|
||
/// (4)ノードをアップデートした上で返却する。
|
||
func kana2lattice_all_with_prefix_constraint(_ inputData: ComposingText, N_best: Int, constraint: String) -> (result: LatticeNode, nodes: Nodes) {
|
||
debug("新規に計算を行います。inputされた文字列は\(inputData.input.count)文字分の\(inputData.convertTarget)。制約は\(constraint)")
|
||
let count: Int = inputData.input.count
|
||
let result: LatticeNode = LatticeNode.EOSNode
|
||
let nodes: [[LatticeNode]] = (.zero ..< count).map {dicdataStore.getFrozenLOUDSDataInRange(inputData: inputData, from: $0)}
|
||
// 「i文字目から始まるnodes」に対して
|
||
for (i, nodeArray) in nodes.enumerated() {
|
||
// それぞれのnodeに対して
|
||
for node in nodeArray {
|
||
if node.prevs.isEmpty {
|
||
continue
|
||
}
|
||
if self.dicdataStore.shouldBeRemoved(data: node.data) {
|
||
continue
|
||
}
|
||
// 生起確率を取得する。
|
||
let wValue: PValue = node.data.value()
|
||
if i == 0 {
|
||
// valuesを更新する
|
||
node.values = node.prevs.map {$0.totalValue + wValue + self.dicdataStore.getCCValue($0.data.rcid, node.data.lcid)}
|
||
} else {
|
||
// valuesを更新する
|
||
node.values = node.prevs.map {$0.totalValue + wValue}
|
||
}
|
||
// 変換した文字数
|
||
let nextIndex: Int = node.inputRange.endIndex
|
||
// 文字数がcountと等しい場合登録する
|
||
if nextIndex == count {
|
||
for index in node.prevs.indices {
|
||
let newnode: RegisteredNode = node.getRegisteredNode(index, value: node.values[index])
|
||
let text = newnode.getCandidateData().data.reduce(into: "") { $0.append(contentsOf: $1.word)} + node.data.word
|
||
if text.hasPrefix(constraint) {
|
||
result.prevs.append(newnode)
|
||
}
|
||
}
|
||
} else {
|
||
let candidates = node.getCandidateData().map {
|
||
$0.data.reduce(into: "") { $0.append(contentsOf: $1.word)} + node.data.word
|
||
}
|
||
// nodeの繋がる次にあり得る全てのnextnodeに対して
|
||
for nextnode in nodes[nextIndex] {
|
||
// この関数はこの時点で呼び出して、後のnode.registered.isEmptyで最終的に弾くのが良い。
|
||
if self.dicdataStore.shouldBeRemoved(data: nextnode.data) {
|
||
continue
|
||
}
|
||
// クラスの連続確率を計算する。
|
||
let ccValue: PValue = self.dicdataStore.getCCValue(node.data.rcid, nextnode.data.lcid)
|
||
// nodeの持っている全てのprevnodeに対して
|
||
for (index, value) in node.values.enumerated() {
|
||
// 制約を少なくとも満たしている必要がある
|
||
// common prefixが単語か制約のどちらかに一致している必要
|
||
// 制約 AB 単語 ABC (OK)
|
||
// 制約 AB 単語 A (OK)
|
||
// 制約 AB 単語 AC (NG)
|
||
let text = candidates[index] + nextnode.data.word
|
||
if !text.hasPrefix(constraint) && !constraint.hasPrefix(text) {
|
||
continue
|
||
}
|
||
let newValue: PValue = ccValue + value
|
||
// 追加すべきindexを取得する
|
||
let lastindex: Int = (nextnode.prevs.lastIndex(where: {$0.totalValue >= newValue}) ?? -1) + 1
|
||
if lastindex == N_best {
|
||
continue
|
||
}
|
||
let newnode: RegisteredNode = node.getRegisteredNode(index, value: newValue)
|
||
// カウントがオーバーしている場合は除去する
|
||
if nextnode.prevs.count >= N_best {
|
||
nextnode.prevs.removeLast()
|
||
}
|
||
// removeしてからinsertした方が速い (insertはO(N)なので)
|
||
nextnode.prevs.insert(newnode, at: lastindex)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return (result: result, nodes: nodes)
|
||
}
|
||
|
||
}
|