Skip to content

Commit b38443e

Browse files
authored
Add Swift 6.1 manifest to forward Xet trait to swift-huggingface dependency (#334)
* Add Swift 6.1 manifest to forward Xet trait to swift-huggingface * Update CI workflow to test with/without Xet trait * Attempt to fix build cache contamination for different traits * Enable default traits in Xet dependency * Configure swiftLanguageMode v5 * Fix cache key * Add explicit dependency on swift-xet package * Resolve warning about unused swift-xet dependency * Attempt to resolve hashFiles issue * Update README
1 parent 58c4bc1 commit b38443e

File tree

3 files changed

+128
-5
lines changed

3 files changed

+128
-5
lines changed

.github/workflows/ci.yml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,17 @@ jobs:
2424
HF_HUB_READ_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }}
2525

2626
test-linux:
27-
name: Test (Linux)
27+
name: Test (Linux)${{ matrix.traits != '' && format(' with --traits {0}', matrix.traits) || '' }}
2828
runs-on: ubuntu-latest
29-
container: swift:6.2.3
29+
container: swift:${{ matrix.swift }}
30+
strategy:
31+
fail-fast: false
32+
matrix:
33+
include:
34+
- swift: "6.2.3"
35+
traits: ""
36+
- swift: "6.2.3"
37+
traits: "Xet"
3038
steps:
3139
- name: Checkout PR merge ref if called from PR
3240
if: ${{ github.event.pull_request.number }}
@@ -39,8 +47,16 @@ jobs:
3947
if: ${{ !github.event.pull_request.number }}
4048
uses: actions/checkout@v6
4149

50+
- name: Cache Swift Package Manager dependencies
51+
uses: actions/cache@v5
52+
with:
53+
path: ~/.cache/org.swift.swiftpm
54+
key: ${{ runner.os }}-swift-${{ matrix.swift }}-${{ matrix.traits == '' && 'xet-off' || 'xet-on' }}-spm-${{ hashFiles('Package*.swift') }}-${{ hashFiles('Package.resolved') }}
55+
restore-keys: |
56+
${{ runner.os }}-swift-${{ matrix.swift }}-${{ matrix.traits == '' && 'xet-off' || 'xet-on' }}-spm-
57+
4258
- name: Build
43-
run: swift build
59+
run: swift build${{ matrix.traits != '' && format(' --traits {0}', matrix.traits) || '' }}
4460

4561
- name: Run tests
4662
env:
@@ -49,7 +65,7 @@ jobs:
4965
# FoundationNetworking race condition that crashes during teardown.
5066
# See: https://github.com/swiftlang/swift-corelibs-foundation/issues/3675
5167
run: |
52-
swift test --skip HubTests --skip TokenizersTests
68+
swift test --skip HubTests --skip TokenizersTests${{ matrix.traits != '' && format(' --traits {0}', matrix.traits) || '' }}
5369
lint:
5470
name: Lint
5571
runs-on: macos-latest

Package@swift-6.1.swift

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// swift-tools-version: 6.1
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
/// Define the strict concurrency settings to be applied to all targets.
7+
let swiftSettings: [SwiftSetting] = [
8+
.enableExperimentalFeature("StrictConcurrency")
9+
]
10+
11+
let package = Package(
12+
name: "swift-transformers",
13+
platforms: [.iOS(.v16), .macOS(.v13)],
14+
products: [
15+
.library(name: "Hub", targets: ["Hub"]),
16+
.library(name: "Tokenizers", targets: ["Tokenizers"]),
17+
.library(name: "Transformers", targets: ["Tokenizers", "Generation", "Models"]),
18+
],
19+
traits: [
20+
.trait(
21+
name: "Xet",
22+
description: "Enable Xet transport support in swift-huggingface."
23+
)
24+
],
25+
dependencies: [
26+
.package(url: "https://github.com/huggingface/swift-jinja.git", from: "2.0.0"),
27+
// Work around SwiftPM trait resolution issue for transitive Xet dependency.
28+
.package(url: "https://github.com/huggingface/swift-xet.git", from: "0.2.0"),
29+
.package(
30+
url: "https://github.com/huggingface/swift-huggingface.git",
31+
from: "0.9.0",
32+
traits: [
33+
.defaults,
34+
.trait(name: "Xet", condition: .when(traits: ["Xet"])),
35+
]
36+
),
37+
.package(url: "https://github.com/apple/swift-collections.git", from: "1.0.0"),
38+
.package(url: "https://github.com/apple/swift-crypto.git", "3.0.0"..<"5.0.0"),
39+
.package(url: "https://github.com/ibireme/yyjson.git", exact: "0.12.0"),
40+
],
41+
targets: [
42+
.target(name: "Generation", dependencies: ["Tokenizers"]),
43+
.target(
44+
name: "Hub",
45+
dependencies: [
46+
.product(name: "Jinja", package: "swift-jinja"),
47+
.product(name: "HuggingFace", package: "swift-huggingface"),
48+
.product(name: "Xet", package: "swift-xet", condition: .when(traits: ["Xet"])),
49+
.product(name: "OrderedCollections", package: "swift-collections"),
50+
.product(name: "Crypto", package: "swift-crypto"),
51+
.product(name: "yyjson", package: "yyjson"),
52+
],
53+
resources: [
54+
.process("Resources")
55+
],
56+
swiftSettings: swiftSettings
57+
),
58+
.target(name: "Models", dependencies: ["Tokenizers", "Generation"]),
59+
.target(name: "Tokenizers", dependencies: ["Hub", .product(name: "Jinja", package: "swift-jinja")]),
60+
.testTarget(name: "Benchmarks", dependencies: ["Hub", "Tokenizers", .product(name: "yyjson", package: "yyjson")]),
61+
.testTarget(name: "GenerationTests", dependencies: ["Generation"]),
62+
.testTarget(name: "HubTests", dependencies: ["Hub", .product(name: "Jinja", package: "swift-jinja")], swiftSettings: swiftSettings),
63+
.testTarget(name: "ModelsTests", dependencies: ["Models", "Hub"], resources: [.process("Resources")]),
64+
.testTarget(name: "TokenizersTests", dependencies: ["Tokenizers", "Models", "Hub"], resources: [.process("Resources")]),
65+
],
66+
swiftLanguageModes: [.v5]
67+
)

README.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ To use `swift-transformers` with SwiftPM, you can add this to your `Package.swif
124124

125125
```swift
126126
dependencies: [
127-
.package(url: "https://github.com/huggingface/swift-transformers", from: "0.1.17")
127+
.package(url: "https://github.com/huggingface/swift-transformers", from: "1.3.0")
128128
]
129129
```
130130

@@ -141,6 +141,46 @@ targets: [
141141
]
142142
```
143143

144+
### Optional Xet trait
145+
146+
`swift-transformers` includes an `Xet` [package trait](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0450-swiftpm-package-traits.md)
147+
that enables fast, parallel downloads from the Hugging Face Hub
148+
via [swift-xet](https://github.com/huggingface/swift-xet).
149+
Because Xet introduces additional transitive dependencies
150+
(including [AsyncHTTPClient](https://github.com/swift-server/async-http-client)),
151+
it is opt-in.
152+
153+
On Swift 6.1+, enable it in your `Package.swift`:
154+
155+
```swift
156+
dependencies: [
157+
.package(
158+
url: "https://github.com/huggingface/swift-transformers",
159+
from: "1.3.0",
160+
traits: ["Xet"]
161+
)
162+
]
163+
```
164+
165+
Or from the command line:
166+
167+
```bash
168+
swift build --traits Xet
169+
swift test --traits Xet
170+
```
171+
172+
When the trait is not enabled,
173+
Hub downloads use the default `URLSession`-based transport.
174+
175+
On Swift versions earlier than 6.1,
176+
package traits are unavailable and Xet transport cannot be enabled.
177+
178+
> [!NOTE]
179+
> Xcode doesn't yet provide a built-in way to declare package dependencies with traits.
180+
> As a workaround, you can create an internal Swift package
181+
> that re-exports `swift-transformers` with the `Xet` trait enabled,
182+
> then add that package as a local dependency in your Xcode project.
183+
144184
## Projects that use swift-transformers ❤️
145185

146186
- [WhisperKit](https://github.com/argmaxinc/WhisperKit): A Swift Package for state-of-the-art speech-to-text systems from [Argmax](https://github.com/argmaxinc)

0 commit comments

Comments
 (0)