feat: introduce package traits of Swift 6.1 (#172)

* feat: introduce package traits of Swift 6.1

* fix: CI

* fix: android toolchain install script

* fix: ci for windows

* chore: add debug dump of sdk list

* fix: update devcontainer swift image

* fix?

* chore: remove LLAMA_MOCK=1 since it is no longer required

* chore: add debug print of configuration

* fix: typo

* chore: use signed xcframework of azooKey/llama.cpp

* chore: use updated xcframework

* chore: use updated xcframework

* chore: use updated xcframework

* chore: use updated xcframework

* chore: use updated xcframework

* docs: add usage of Zenzai trait
This commit is contained in:
Miwa
2025-04-06 17:49:14 +09:00
committed by GitHub
parent 3a4e914624
commit 2cde22d3e2
8 changed files with 75 additions and 84 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "Swift", "name": "Swift",
"image": "swift:6.0", "image": "swift:6.1",
"features": { "features": {
"ghcr.io/devcontainers/features/common-utils:2": { "ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": "false", "installZsh": "false",

View File

@@ -13,9 +13,9 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [macos-latest] os: [macos-latest]
swift-version: ["6.0"] swift-version: ["6.1"]
steps: steps:
- uses: swift-actions/setup-swift@v2 - uses: ensan-hcl/setup-swift@swift-6.1.0
with: with:
swift-version: ${{ matrix.swift-version }} swift-version: ${{ matrix.swift-version }}
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -31,9 +31,9 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest] os: [ubuntu-latest]
swift-version: ["6.0"] swift-version: ["6.1"]
steps: steps:
- uses: swift-actions/setup-swift@v2 - uses: ensan-hcl/setup-swift@swift-6.1.0
with: with:
swift-version: ${{ matrix.swift-version }} swift-version: ${{ matrix.swift-version }}
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -59,8 +59,8 @@ jobs:
os: [windows-latest] os: [windows-latest]
swift-version: swift-version:
[{ [{
branch: "swift-6.0.2-release", branch: "swift-6.1-release",
tag: "6.0.2-RELEASE" tag: "6.1-RELEASE"
}] }]
steps: steps:
- uses: compnerd/gha-setup-swift@main - uses: compnerd/gha-setup-swift@main
@@ -97,11 +97,12 @@ jobs:
matrix: matrix:
arch: [x86_64, aarch64, armv7] arch: [x86_64, aarch64, armv7]
os: [ubuntu-latest] os: [ubuntu-latest]
# You may find the checksum at: https://github.com/finagolfin/swift-android-sdk/blob/main/README.md#swift-cross-compilation-sdk-bundle-for-android
swift-version: swift-version:
[{ [{
version: "6.0.2", version: "6.1",
android: "24", android: "24",
checksum: "d75615eac3e614131133c7cc2076b0b8fb4327d89dce802c25cd53e75e1881f4" checksum: "971f3b1fd03c059803d625f0a412d7e8c4c6f34440f5216ceaf13e886e8e706f"
}] }]
steps: steps:
@@ -114,7 +115,10 @@ jobs:
${TOOLCHAIN}/bin/swift --version ${TOOLCHAIN}/bin/swift --version
- name: Setup Swift release Android SDK - name: Setup Swift release Android SDK
run: ${TOOLCHAIN}/bin/swift sdk install https://github.com/finagolfin/swift-android-sdk/releases/download/${{ matrix.swift-version.version }}/swift-${{ matrix.swift-version.version }}-RELEASE-android-${{ matrix.swift-version.android }}-0.1.artifactbundle.tar.gz --checksum ${{ matrix.swift-version.checksum }} run: |
${TOOLCHAIN}/bin/swift sdk install https://github.com/finagolfin/swift-android-sdk/releases/download/${{ matrix.swift-version.version }}/swift-${{ matrix.swift-version.version }}-RELEASE-android-${{ matrix.swift-version.android }}-0.1.artifactbundle.tar.gz --checksum ${{ matrix.swift-version.checksum }}
${TOOLCHAIN}/bin/swift sdk list
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
path: AzooKeyKanaKanjiConverter path: AzooKeyKanaKanjiConverter
@@ -126,7 +130,8 @@ jobs:
if ${{ matrix.arch == 'armv7' }}; then if ${{ matrix.arch == 'armv7' }}; then
ARCH_TARGET="armv7-unknown-linux-androideabi${{ matrix.swift-version.android }}" ARCH_TARGET="armv7-unknown-linux-androideabi${{ matrix.swift-version.android }}"
fi fi
LLAMA_MOCK=1 ${TOOLCHAIN}/bin/swift build --build-tests --swift-sdk $ARCH_TARGET ${TOOLCHAIN}/bin/swift sdk configure --show-configuration swift-${{ matrix.swift-version.version }}-RELEASE-android-${{ matrix.swift-version.android }}-0.1 $ARCH_TARGET
${TOOLCHAIN}/bin/swift build --build-tests --swift-sdk $ARCH_TARGET
- name: Get cached Termux app - name: Get cached Termux app
if: ${{ matrix.arch == 'x86_64' }} if: ${{ matrix.arch == 'x86_64' }}
id: cache-termux id: cache-termux

View File

@@ -1,11 +1,12 @@
// swift-tools-version: 6.0 // swift-tools-version: 6.1
// The swift-tools-version declares the minimum version of Swift required to build this package. // The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription import PackageDescription
import Foundation import Foundation
var swiftSettings: [SwiftSetting] = [ let swiftSettings: [SwiftSetting] = [
.enableUpcomingFeature("ExistentialAny"), .enableUpcomingFeature("ExistentialAny"),
.interoperabilityMode(.Cxx, .when(traits: ["Zenzai"]))
] ]
var dependencies: [Package.Dependency] = [ var dependencies: [Package.Dependency] = [
@@ -17,17 +18,14 @@ var dependencies: [Package.Dependency] = [
.package(url: "https://github.com/ensan-hcl/swift-tokenizers", branch: "feat/minimum") .package(url: "https://github.com/ensan-hcl/swift-tokenizers", branch: "feat/minimum")
] ]
var efficientNGramDependencies: [Target.Dependency] = [.product(name: "Transformers", package: "swift-tokenizers")] var efficientNGramDependencies: [Target.Dependency] = [
.product(name: "Transformers", package: "swift-tokenizers")
]
#if (!os(Linux) || !canImport(Android)) && !os(Windows) #if (!os(Linux) || !canImport(Android)) && !os(Windows)
// AndroidWindowsSwiftyMarisa // AndroidWindowsSwiftyMarisaEfficientNGram
// EfficientNGram
if let envValue = ProcessInfo.processInfo.environment["LLAMA_MOCK"], envValue == "1" {
// LLAMA_MOCK=1
} else {
dependencies.append(.package(url: "https://github.com/ensan-hcl/SwiftyMarisa", branch: "6e145aef5583aac96dd7ff8f9fbb9944d893128e")) dependencies.append(.package(url: "https://github.com/ensan-hcl/SwiftyMarisa", branch: "6e145aef5583aac96dd7ff8f9fbb9944d893128e"))
efficientNGramDependencies.append("SwiftyMarisa") efficientNGramDependencies.append(.product(name: "SwiftyMarisa", package: "SwiftyMarisa", condition: .when(traits: ["Zenzai"])))
swiftSettings.append(.interoperabilityMode(.Cxx))
}
#endif #endif
@@ -139,58 +137,29 @@ if checkObjcAvailability() {
} }
#endif #endif
if let envValue = ProcessInfo.processInfo.environment["LLAMA_MOCK"], envValue == "1" {
targets.append(contentsOf: [
.target(name: "llama-mock"),
.target(
name: "KanaKanjiConverterModule",
dependencies: [
"SwiftUtils",
"llama-mock",
"EfficientNGram",
.product(name: "Collections", package: "swift-collections"),
],
swiftSettings: swiftSettings
)
])
} else {
#if os(Windows) || os(Linux) #if os(Windows) || os(Linux)
targets.append(contentsOf: [ let llamaCppTarget: Target = .systemLibrary(name: "llama.cpp")
.systemLibrary(
name: "llama.cpp"
),
.target(
name: "KanaKanjiConverterModule",
dependencies: [
"SwiftUtils",
"llama.cpp",
"EfficientNGram",
.product(name: "Collections", package: "swift-collections"),
],
swiftSettings: swiftSettings
)
])
#else #else
targets.append(contentsOf: [ let llamaCppTarget: Target = .binaryTarget(
.binaryTarget(
name: "llama.cpp", name: "llama.cpp",
url: "https://github.com/fkunn1326/llama.cpp/releases/download/b4844/llama-b4844-xcframework.zip", url: "https://github.com/azooKey/llama.cpp/releases/download/b4846/signed-llama.xcframework.zip",
// this can be computed `swift package compute-checksum llama-b4844-xcframework.zip` // this can be computed `swift package compute-checksum llama-b4844-xcframework.zip`
checksum: "40bd1e58e727511649e13a6de9eb577ea8be78fe4183c2e1b382b12054849f05" checksum: "db3b13169df8870375f212e6ac21194225f1c85f7911d595ab64c8c790068e0a"
), )
#endif
targets.append(llamaCppTarget)
targets.append(
.target( .target(
name: "KanaKanjiConverterModule", name: "KanaKanjiConverterModule",
dependencies: [ dependencies: [
"SwiftUtils", "SwiftUtils",
"EfficientNGram", .target(name: "EfficientNGram", condition: .when(traits: ["Zenzai"])),
"llama.cpp", .target(name: "llama.cpp", condition: .when(traits: ["Zenzai"])),
.product(name: "Collections", package: "swift-collections"), .product(name: "Collections", package: "swift-collections"),
], ],
swiftSettings: swiftSettings swiftSettings: swiftSettings
) )
]) )
#endif
}
let package = Package( let package = Package(
name: "AzooKeyKanakanjiConverter", name: "AzooKeyKanakanjiConverter",
@@ -212,6 +181,10 @@ let package = Package(
targets: ["KanaKanjiConverterModule"] targets: ["KanaKanjiConverterModule"]
), ),
], ],
traits: [
.trait(name: "Zenzai"),
.default(enabledTraits: [])
],
dependencies: dependencies, dependencies: dependencies,
targets: targets targets: targets
) )

View File

@@ -5,7 +5,7 @@ AzooKeyKanaKanjiConverterは[azooKey](https://github.com/ensan-hcl/azooKey)の
また、AzooKeyKanaKanjiConverterはニューラルかな漢字変換システム「Zenzai」を利用した高精度な変換もサポートしています。 また、AzooKeyKanaKanjiConverterはニューラルかな漢字変換システム「Zenzai」を利用した高精度な変換もサポートしています。
## 動作環境 ## 動作環境
iOS 14以降, macOS 11以降, visionOS 1以降, Ubuntu 22.04以降で動作を確認しています。 iOS 16以降, macOS 13以降, visionOS 1以降, Ubuntu 22.04以降で動作を確認しています。Swift 6.1以上が必要です。
AzooKeyKanaKanjiConverterの開発については[開発ガイド](Docs/development_guide.md)をご覧ください。 AzooKeyKanaKanjiConverterの開発については[開発ガイド](Docs/development_guide.md)をご覧ください。
@@ -18,7 +18,7 @@ AzooKeyKanaKanjiConverterの開発については[開発ガイド](Docs/developm
* Swift Packageの場合、Package.swiftの`Package`の引数に`dependencies`以下の記述を追加してください。 * Swift Packageの場合、Package.swiftの`Package`の引数に`dependencies`以下の記述を追加してください。
```swift ```swift
dependencies: [ dependencies: [
.package(url: "https://github.com/ensan-hcl/AzooKeyKanaKanjiConverter", .upToNextMinor(from: "0.8.0")) .package(url: "https://github.com/azooKey/AzooKeyKanaKanjiConverter", .upToNextMinor(from: "0.8.0"))
], ],
``` ```
また、ターゲットの`dependencies`にも同様に追加してください。 また、ターゲットの`dependencies`にも同様に追加してください。
@@ -80,7 +80,16 @@ let options = ConvertRequestOptions.withDefaultDictionary(
`ComposingText`は入力管理を行いつつ変換をリクエストするためのAPIです。ローマ字入力などを適切にハンドルするために利用できます。詳しくは[ドキュメント](./Docs/composing_text.md)を参照してください。 `ComposingText`は入力管理を行いつつ変換をリクエストするためのAPIです。ローマ字入力などを適切にハンドルするために利用できます。詳しくは[ドキュメント](./Docs/composing_text.md)を参照してください。
### Zenzaiを使う ### Zenzaiを使う
ニューラルかな漢字変換システム「Zenzai」を利用するには、`ConvertRequestOptions`の`zenzaiMode`を指定します。詳しくは[ドキュメント](./Docs/zenzai.md)を参照してください。 ニューラルかな漢字変換システム「Zenzai」を利用するには、追加で[Swift Package Traits](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0450-swiftpm-package-traits.md)の設定を行う必要があります。AzooKeyKanaKanjiConverterは「Zenzai」というTraitをサポートしているので、これを追加してください。
```swift
dependencies: [
.package(url: "https://github.com/azooKey/AzooKeyKanaKanjiConverter", .upToNextMinor(from: "0.8.0"), traits: ["Zenzai"])
],
```
`ConvertRequestOptions`の`zenzaiMode`を指定します。詳しい引数の情報については[ドキュメント](./Docs/zenzai.md)を参照してください。
```swift ```swift
let options = ConvertRequestOptions.withDefaultDictionary( let options = ConvertRequestOptions.withDefaultDictionary(
// ... // ...
@@ -90,6 +99,7 @@ let options = ConvertRequestOptions.withDefaultDictionary(
``` ```
### 辞書データ ### 辞書データ
AzooKeyKanaKanjiConverterのデフォルト辞書として[azooKey_dictionary_storage](https://github.com/ensan-hcl/azooKey_dictionary_storage)がサブモジュールとして指定されています。過去のバージョンの辞書データは[Google Drive](https://drive.google.com/drive/folders/1Kh7fgMFIzkpg7YwP3GhWTxFkXI-yzT9E?usp=sharing)からもダウンロードすることができます。 AzooKeyKanaKanjiConverterのデフォルト辞書として[azooKey_dictionary_storage](https://github.com/ensan-hcl/azooKey_dictionary_storage)がサブモジュールとして指定されています。過去のバージョンの辞書データは[Google Drive](https://drive.google.com/drive/folders/1Kh7fgMFIzkpg7YwP3GhWTxFkXI-yzT9E?usp=sharing)からもダウンロードすることができます。
また、以下のフォーマットであれば自前で用意した辞書データを利用することもできます。カスタム辞書データのサポートは限定的なので、ソースコードを確認の上ご利用ください。 また、以下のフォーマットであれば自前で用意した辞書データを利用することもできます。カスタム辞書データのサポートは限定的なので、ソースコードを確認の上ご利用ください。

View File

@@ -1,5 +1,5 @@
import Foundation import Foundation
#if canImport(SwiftyMarisa) #if canImport(SwiftyMarisa) && Zenzai
import SwiftyMarisa import SwiftyMarisa
/// Base64 Key-Value /// Base64 Key-Value

View File

@@ -1,5 +1,5 @@
import Foundation import Foundation
#if canImport(SwiftyMarisa) #if canImport(SwiftyMarisa) && Zenzai
import SwiftyMarisa import SwiftyMarisa
final class SwiftTrainer { final class SwiftTrainer {

View File

@@ -1,8 +1,8 @@
#if canImport(llama) #if Zenzai
// Zenzaillama-mock.swift
import llama import llama
#else
import llama_mock
#endif #endif
import SwiftUtils import SwiftUtils
import HeapModule import HeapModule
import Algorithms import Algorithms

View File

@@ -1,3 +1,5 @@
#if !Zenzai
// ZenzaiMock
private func unimplemented<T>() -> T { private func unimplemented<T>() -> T {
fatalError("unimplemented") fatalError("unimplemented")
} }
@@ -60,3 +62,4 @@ package func llama_token_to_piece(_ vocab: llama_vocab, _ token: llama_token, _
package func llama_decode(_ ctx: llama_context, _ batch: llama_batch) -> Int { unimplemented() } package func llama_decode(_ ctx: llama_context, _ batch: llama_batch) -> Int { unimplemented() }
package func llama_get_logits(_ ctx: llama_context) -> UnsafeMutablePointer<Float>? { unimplemented() } package func llama_get_logits(_ ctx: llama_context) -> UnsafeMutablePointer<Float>? { unimplemented() }
#endif