bleam 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +23 -4
- package/dist/cli.d.cts +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +23 -4
- package/dist/{ui-234Plg7Z.d.cts → ui-Bg11tvlc.d.ts} +7 -7
- package/dist/ui.d.ts +1 -1
- package/dist/window.d.ts +1 -1
- package/package.json +4 -1
- package/templates/image-generation/app/index.tsx +1 -1
- package/templates/native/.gitattributes +1 -0
- package/templates/native/App.tsx +26 -0
- package/templates/native/app.json +12 -0
- package/templates/native/index.ts +8 -0
- package/templates/native/ios/.xcode.env +11 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/Flux2Config.swift +288 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryConfig.swift +233 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryOptimizationConfig.swift +157 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/ModelRegistry.swift +425 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/QuantizationConfig.swift +138 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/TransformerRepoProfile.swift +59 -0
- package/templates/native/ios/Bleam/AI/Flux2/Configuration/VAEConfig.swift +134 -0
- package/templates/native/ios/Bleam/AI/Flux2/Flux2Core.swift +55 -0
- package/templates/native/ios/Bleam/AI/Flux2/Loading/WeightLoader.swift +1192 -0
- package/templates/native/ios/Bleam/AI/Flux2/Pipeline/FluxImageRunner.swift +1282 -0
- package/templates/native/ios/Bleam/AI/Flux2/Pipeline/LatentUtils.swift +191 -0
- package/templates/native/ios/Bleam/AI/Flux2/Scheduler/FlowMatchEulerScheduler.swift +279 -0
- package/templates/native/ios/Bleam/AI/Flux2/Text/KleinTextEncoder.swift +380 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Attention.swift +379 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Embeddings.swift +159 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FeedForward.swift +154 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FusedKernels.swift +198 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2KVCache.swift +36 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Modulation.swift +193 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2ParallelAttention.swift +389 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2RoPE.swift +304 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2SingleBlock.swift +290 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Transformer.swift +530 -0
- package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2TransformerBlock.swift +362 -0
- package/templates/native/ios/Bleam/AI/Flux2/Utils/Flux2Debug.swift +101 -0
- package/templates/native/ios/Bleam/AI/Flux2/Utils/MLXCheckpoint.swift +118 -0
- package/templates/native/ios/Bleam/AI/Flux2/Utils/MemoryManager.swift +201 -0
- package/templates/native/ios/Bleam/AI/Flux2/VAE/AutoencoderKL.swift +476 -0
- package/templates/native/ios/Bleam/AI/Flux2/VAE/ResnetBlock.swift +316 -0
- package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEDecoder.swift +120 -0
- package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEEncoder.swift +136 -0
- package/templates/native/ios/Bleam/AppDelegate.swift +373 -0
- package/templates/native/ios/Bleam/Appearance.swift +62 -0
- package/templates/native/ios/Bleam/Bridging-Header.h +3 -0
- package/templates/native/ios/Bleam/Images.xcassets/AppIcon.appiconset/Contents.json +13 -0
- package/templates/native/ios/Bleam/Images.xcassets/Contents.json +6 -0
- package/templates/native/ios/Bleam/Info.plist +76 -0
- package/templates/native/ios/Bleam/PrivacyInfo.xcprivacy +48 -0
- package/templates/native/ios/Bleam/SceneDelegate.swift +58 -0
- package/templates/native/ios/Bleam/SplashScreen.storyboard +47 -0
- package/templates/native/ios/Bleam/Supporting/Expo.plist +6 -0
- package/templates/native/ios/Bleam/bleam.entitlements +10 -0
- package/templates/native/ios/Bleam.xcodeproj/project.pbxproj +1146 -0
- package/templates/native/ios/Bleam.xcodeproj/xcshareddata/xcschemes/Bleam.xcscheme +88 -0
- package/templates/native/ios/GenerationService/GenerationService.entitlements +10 -0
- package/templates/native/ios/GenerationService/ImageGenerationRunner.swift +591 -0
- package/templates/native/ios/GenerationService/Info.plist +31 -0
- package/templates/native/ios/GenerationService/main.swift +165 -0
- package/templates/native/ios/PlatformHelper/Info.plist +29 -0
- package/templates/native/ios/PlatformHelper/main.swift +335 -0
- package/templates/native/ios/Podfile +198 -0
- package/templates/native/ios/Podfile.lock +2284 -0
- package/templates/native/ios/Podfile.properties.json +5 -0
- package/templates/native/ios/Shared/Generation/GenerationServiceProtocol.swift +12 -0
- package/templates/native/ios/Shared/Generation/GenerationWorkerProtocol.swift +124 -0
- package/templates/native/metro.config.js +6 -0
- package/templates/native/modules/bleam-runtime/BleamRuntime.podspec +14 -0
- package/templates/native/modules/bleam-runtime/expo-module.config.json +8 -0
- package/templates/native/modules/bleam-runtime/ios/AIModule.swift +1258 -0
- package/templates/native/modules/bleam-runtime/ios/GenerationContracts.swift +135 -0
- package/templates/native/modules/bleam-runtime/ios/PlatformModule.swift +313 -0
- package/templates/native/modules/bleam-runtime/package.json +5 -0
- package/templates/native/package.json +39 -0
- package/templates/native/scripts/build/mlx-frameworks.ts +421 -0
- package/templates/native/scripts/start/index.ts +474 -0
- package/templates/native/scripts/start/known-failures.ts +20 -0
- package/templates/native/scripts/start/loader.ts +76 -0
- package/templates/native/scripts/start/native-state.ts +242 -0
- package/templates/native/scripts/start/package.json +4 -0
- package/templates/native/scripts/start/swift-packages.ts +414 -0
- package/templates/native/scripts/start/xcode-formatter.ts +106 -0
- package/templates/native/tsconfig.json +14 -0
- package/templates/native/yarn.lock +3749 -0
- package/dist/ui-BJmXhz9Q.d.ts +0 -92
- package/dist/ui-Dd7SXdbg.d.cts +0 -92
- package/dist/ui-Ds88eETu.d.ts +0 -92
- package/dist/ui-TaqnB5SP.d.ts +0 -92
- package/dist/ui-WQvnXL0W.d.ts +0 -92
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
// Flux2SingleBlock.swift - Single-Stream Transformer Block
|
|
2
|
+
// Copyright 2025 Vincent Gourbin
|
|
3
|
+
|
|
4
|
+
import Foundation
|
|
5
|
+
import MLX
|
|
6
|
+
import MLXNN
|
|
7
|
+
|
|
8
|
+
/// Single-Stream Transformer Block for Flux.2
|
|
9
|
+
///
|
|
10
|
+
/// Concatenates text and image hidden states, processes them together
|
|
11
|
+
/// with fused attention+FFN, then splits back. More efficient than
|
|
12
|
+
/// double-stream for later layers.
|
|
13
|
+
///
|
|
14
|
+
/// There are 48 such blocks in Flux.2.
|
|
15
|
+
public class Flux2SingleTransformerBlock: Module, @unchecked Sendable {
|
|
16
|
+
let dim: Int
|
|
17
|
+
let numHeads: Int
|
|
18
|
+
let headDim: Int
|
|
19
|
+
|
|
20
|
+
// Single LayerNorm for concatenated input
|
|
21
|
+
let norm: LayerNorm
|
|
22
|
+
|
|
23
|
+
// Fused parallel attention (QKV + MLP in one projection)
|
|
24
|
+
let attn: Flux2ParallelSelfAttention
|
|
25
|
+
|
|
26
|
+
/// Initialize Single-Stream Block
|
|
27
|
+
/// - Parameters:
|
|
28
|
+
/// - dim: Model dimension (6144)
|
|
29
|
+
/// - numHeads: Number of attention heads (48)
|
|
30
|
+
/// - headDim: Dimension per head (128)
|
|
31
|
+
/// - mlpRatio: MLP expansion ratio
|
|
32
|
+
public init(
|
|
33
|
+
dim: Int,
|
|
34
|
+
numHeads: Int,
|
|
35
|
+
headDim: Int,
|
|
36
|
+
mlpRatio: Float = 3.0
|
|
37
|
+
) {
|
|
38
|
+
self.dim = dim
|
|
39
|
+
self.numHeads = numHeads
|
|
40
|
+
self.headDim = headDim
|
|
41
|
+
|
|
42
|
+
self.norm = LayerNorm(dimensions: dim, eps: 1e-6, affine: false)
|
|
43
|
+
self.attn = Flux2ParallelSelfAttention(
|
|
44
|
+
dim: dim,
|
|
45
|
+
numHeads: numHeads,
|
|
46
|
+
headDim: headDim,
|
|
47
|
+
mlpRatio: mlpRatio
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// Forward pass
|
|
52
|
+
/// - Parameters:
|
|
53
|
+
/// - hiddenStates: Image hidden states [B, S_img, dim]
|
|
54
|
+
/// - encoderHiddenStates: Text hidden states [B, S_txt, dim]
|
|
55
|
+
/// - temb: Timestep embedding [B, dim]
|
|
56
|
+
/// - rotaryEmb: Optional RoPE embeddings for combined sequence
|
|
57
|
+
/// - modParams: Modulation params (1 set for combined processing)
|
|
58
|
+
/// - Returns: Updated image hidden states [B, S_img, dim]
|
|
59
|
+
public func callAsFunction(
|
|
60
|
+
hiddenStates: MLXArray,
|
|
61
|
+
encoderHiddenStates: MLXArray?,
|
|
62
|
+
temb: MLXArray,
|
|
63
|
+
rotaryEmb: (cos: MLXArray, sin: MLXArray)? = nil,
|
|
64
|
+
modParams: [ModulationParams]? = nil
|
|
65
|
+
) -> MLXArray {
|
|
66
|
+
let residual = hiddenStates
|
|
67
|
+
|
|
68
|
+
// If encoder_hidden_states is nil, hidden_states is assumed to already contain
|
|
69
|
+
// concatenated text+image (diffusers pattern for single-stream blocks)
|
|
70
|
+
let combined: MLXArray
|
|
71
|
+
if let encoderHS = encoderHiddenStates {
|
|
72
|
+
// Old pattern: concatenate here
|
|
73
|
+
combined = concatenated([encoderHS, hiddenStates], axis: 1)
|
|
74
|
+
} else {
|
|
75
|
+
// New pattern: already concatenated
|
|
76
|
+
combined = hiddenStates
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Normalize
|
|
80
|
+
var normalized = norm(combined)
|
|
81
|
+
|
|
82
|
+
// Apply modulation if provided
|
|
83
|
+
if let mod = modParams, !mod.isEmpty {
|
|
84
|
+
normalized = applyModulation(normalized, shift: mod[0].shift, scale: mod[0].scale)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Parallel attention + FFN
|
|
88
|
+
var output = attn(hiddenStates: normalized, rotaryEmb: rotaryEmb)
|
|
89
|
+
|
|
90
|
+
// Apply gate if provided
|
|
91
|
+
if let mod = modParams, !mod.isEmpty {
|
|
92
|
+
output = applyGate(output, gate: mod[0].gate)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Add residual and return full sequence
|
|
96
|
+
// (the caller is responsible for splitting if needed)
|
|
97
|
+
return residual + output
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/// Forward pass with cached reference K/V (for KV cache acceleration)
|
|
101
|
+
/// - Parameters:
|
|
102
|
+
/// - hiddenStates: Image hidden states [B, S_img, dim]
|
|
103
|
+
/// - cachedRefKV: Pre-computed reference (text) K and V [B, H, S_txt, D]
|
|
104
|
+
/// - temb: Timestep embedding [B, dim]
|
|
105
|
+
/// - rotaryEmb: Optional RoPE embeddings - only image portion needed
|
|
106
|
+
/// - modParams: Modulation params
|
|
107
|
+
/// - Returns: Updated image hidden states [B, S_img, dim]
|
|
108
|
+
public func callAsFunction(
|
|
109
|
+
hiddenStates: MLXArray,
|
|
110
|
+
cachedRefKV: (k: MLXArray, v: MLXArray),
|
|
111
|
+
temb: MLXArray,
|
|
112
|
+
rotaryEmb: (cos: MLXArray, sin: MLXArray)? = nil,
|
|
113
|
+
modParams: [ModulationParams]? = nil
|
|
114
|
+
) -> MLXArray {
|
|
115
|
+
let residual = hiddenStates
|
|
116
|
+
|
|
117
|
+
// Normalize image portion only
|
|
118
|
+
var normalized = norm(hiddenStates)
|
|
119
|
+
|
|
120
|
+
// Apply modulation if provided
|
|
121
|
+
if let mod = modParams, !mod.isEmpty {
|
|
122
|
+
normalized = applyModulation(normalized, shift: mod[0].shift, scale: mod[0].scale)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Parallel attention with cached reference K/V
|
|
126
|
+
var output = attn(
|
|
127
|
+
hiddenStates: normalized,
|
|
128
|
+
cachedRefKV: cachedRefKV,
|
|
129
|
+
rotaryEmb: rotaryEmb
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
// Apply gate if provided
|
|
133
|
+
if let mod = modParams, !mod.isEmpty {
|
|
134
|
+
output = applyGate(output, gate: mod[0].gate)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return residual + output
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/// Forward pass for reference tokens only (for KV cache building)
|
|
141
|
+
/// - Parameters:
|
|
142
|
+
/// - hiddenStates: Reference hidden states [B, S_ref, dim]
|
|
143
|
+
/// - temb: Timestep embedding [B, dim]
|
|
144
|
+
/// - modParams: Modulation params
|
|
145
|
+
/// - Returns: Updated reference hidden states
|
|
146
|
+
public func forwardRefOnly(
|
|
147
|
+
hiddenStates: MLXArray,
|
|
148
|
+
temb: MLXArray,
|
|
149
|
+
modParams: [ModulationParams]? = nil
|
|
150
|
+
) -> MLXArray {
|
|
151
|
+
let residual = hiddenStates
|
|
152
|
+
|
|
153
|
+
var normalized = norm(hiddenStates)
|
|
154
|
+
if let mod = modParams, !mod.isEmpty {
|
|
155
|
+
normalized = applyModulation(normalized, shift: mod[0].shift, scale: mod[0].scale)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
var output = attn(hiddenStates: normalized, rotaryEmb: nil)
|
|
159
|
+
|
|
160
|
+
if let mod = modParams, !mod.isEmpty {
|
|
161
|
+
output = applyGate(output, gate: mod[0].gate)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return residual + output
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/// Stack of Single-Stream Transformer Blocks
|
|
169
|
+
public class Flux2SingleTransformerBlocks: Module, @unchecked Sendable {
|
|
170
|
+
let blocks: [Flux2SingleTransformerBlock]
|
|
171
|
+
|
|
172
|
+
public init(
|
|
173
|
+
numBlocks: Int,
|
|
174
|
+
dim: Int,
|
|
175
|
+
numHeads: Int,
|
|
176
|
+
headDim: Int,
|
|
177
|
+
mlpRatio: Float = 3.0
|
|
178
|
+
) {
|
|
179
|
+
self.blocks = (0..<numBlocks).map { _ in
|
|
180
|
+
Flux2SingleTransformerBlock(
|
|
181
|
+
dim: dim,
|
|
182
|
+
numHeads: numHeads,
|
|
183
|
+
headDim: headDim,
|
|
184
|
+
mlpRatio: mlpRatio
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/// Forward pass through all single-stream blocks
|
|
190
|
+
/// - Parameters:
|
|
191
|
+
/// - hiddenStates: Image hidden states [B, S_img, dim]
|
|
192
|
+
/// - encoderHiddenStates: Text hidden states [B, S_txt, dim] (used for concatenation)
|
|
193
|
+
/// - temb: Timestep embedding
|
|
194
|
+
/// - rotaryEmb: RoPE embeddings for combined sequence
|
|
195
|
+
/// - modulation: Modulation layer for timestep conditioning
|
|
196
|
+
/// - Returns: Final image hidden states [B, S_img, dim]
|
|
197
|
+
public func callAsFunction(
|
|
198
|
+
hiddenStates: MLXArray,
|
|
199
|
+
encoderHiddenStates: MLXArray,
|
|
200
|
+
temb: MLXArray,
|
|
201
|
+
rotaryEmb: (cos: MLXArray, sin: MLXArray)? = nil,
|
|
202
|
+
modulation: Flux2Modulation? = nil
|
|
203
|
+
) -> MLXArray {
|
|
204
|
+
var imgHS = hiddenStates
|
|
205
|
+
|
|
206
|
+
for block in blocks {
|
|
207
|
+
let modParams = modulation?(temb)
|
|
208
|
+
|
|
209
|
+
imgHS = block(
|
|
210
|
+
hiddenStates: imgHS,
|
|
211
|
+
encoderHiddenStates: encoderHiddenStates,
|
|
212
|
+
temb: temb,
|
|
213
|
+
rotaryEmb: rotaryEmb,
|
|
214
|
+
modParams: modParams
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return imgHS
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/// Variant with direct RoPE application per block
|
|
223
|
+
public class Flux2SingleTransformerBlockWithRoPE: Module, @unchecked Sendable {
|
|
224
|
+
let dim: Int
|
|
225
|
+
let numHeads: Int
|
|
226
|
+
let headDim: Int
|
|
227
|
+
|
|
228
|
+
let norm: LayerNorm
|
|
229
|
+
let attn: Flux2ParallelSelfAttentionSplit // Use split version for separate projections
|
|
230
|
+
let rope: Flux2RoPE
|
|
231
|
+
|
|
232
|
+
public init(
|
|
233
|
+
dim: Int,
|
|
234
|
+
numHeads: Int,
|
|
235
|
+
headDim: Int,
|
|
236
|
+
mlpRatio: Float = 3.0,
|
|
237
|
+
ropeAxesDims: [Int] = [32, 32, 32, 32],
|
|
238
|
+
ropeTheta: Float = 2000.0
|
|
239
|
+
) {
|
|
240
|
+
self.dim = dim
|
|
241
|
+
self.numHeads = numHeads
|
|
242
|
+
self.headDim = headDim
|
|
243
|
+
|
|
244
|
+
self.norm = LayerNorm(dimensions: dim, eps: 1e-6, affine: false)
|
|
245
|
+
self.attn = Flux2ParallelSelfAttentionSplit(
|
|
246
|
+
dim: dim,
|
|
247
|
+
numHeads: numHeads,
|
|
248
|
+
headDim: headDim,
|
|
249
|
+
mlpRatio: mlpRatio
|
|
250
|
+
)
|
|
251
|
+
self.rope = Flux2RoPE(axesDims: ropeAxesDims, theta: ropeTheta)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
public func callAsFunction(
|
|
255
|
+
hiddenStates: MLXArray,
|
|
256
|
+
encoderHiddenStates: MLXArray,
|
|
257
|
+
temb: MLXArray,
|
|
258
|
+
positionIds: MLXArray,
|
|
259
|
+
modParams: [ModulationParams]? = nil
|
|
260
|
+
) -> MLXArray {
|
|
261
|
+
let residual = hiddenStates
|
|
262
|
+
let textSeqLen = encoderHiddenStates.shape[1]
|
|
263
|
+
|
|
264
|
+
// Concatenate
|
|
265
|
+
let combined = concatenated([encoderHiddenStates, hiddenStates], axis: 1)
|
|
266
|
+
|
|
267
|
+
// Normalize
|
|
268
|
+
var normalized = norm(combined)
|
|
269
|
+
|
|
270
|
+
// Apply modulation
|
|
271
|
+
if let mod = modParams, !mod.isEmpty {
|
|
272
|
+
normalized = applyModulation(normalized, shift: mod[0].shift, scale: mod[0].scale)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Generate RoPE embeddings from position IDs
|
|
276
|
+
let ropeEmb = rope(positionIds)
|
|
277
|
+
|
|
278
|
+
// Parallel attention + FFN with RoPE
|
|
279
|
+
var output = attn(hiddenStates: normalized, rotaryEmb: ropeEmb)
|
|
280
|
+
|
|
281
|
+
// Apply gate
|
|
282
|
+
if let mod = modParams, !mod.isEmpty {
|
|
283
|
+
output = applyGate(output, gate: mod[0].gate)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Extract image portion and add residual
|
|
287
|
+
let imgOutput = output[0..., textSeqLen..., 0...]
|
|
288
|
+
return residual + imgOutput
|
|
289
|
+
}
|
|
290
|
+
}
|