bleam 0.0.8 → 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.
Files changed (87) hide show
  1. package/dist/cli.cjs +23 -4
  2. package/dist/cli.d.cts +2 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +23 -4
  5. package/dist/{ui-Ce-pnUUA.d.ts → ui-Bg11tvlc.d.ts} +7 -7
  6. package/dist/ui.d.ts +1 -1
  7. package/dist/window.d.ts +1 -1
  8. package/package.json +4 -1
  9. package/templates/image-generation/app/index.tsx +1 -1
  10. package/templates/native/.gitattributes +1 -0
  11. package/templates/native/App.tsx +26 -0
  12. package/templates/native/app.json +12 -0
  13. package/templates/native/index.ts +8 -0
  14. package/templates/native/ios/.xcode.env +11 -0
  15. package/templates/native/ios/Bleam/AI/Flux2/Configuration/Flux2Config.swift +288 -0
  16. package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryConfig.swift +233 -0
  17. package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryOptimizationConfig.swift +157 -0
  18. package/templates/native/ios/Bleam/AI/Flux2/Configuration/ModelRegistry.swift +425 -0
  19. package/templates/native/ios/Bleam/AI/Flux2/Configuration/QuantizationConfig.swift +138 -0
  20. package/templates/native/ios/Bleam/AI/Flux2/Configuration/TransformerRepoProfile.swift +59 -0
  21. package/templates/native/ios/Bleam/AI/Flux2/Configuration/VAEConfig.swift +134 -0
  22. package/templates/native/ios/Bleam/AI/Flux2/Flux2Core.swift +55 -0
  23. package/templates/native/ios/Bleam/AI/Flux2/Loading/WeightLoader.swift +1192 -0
  24. package/templates/native/ios/Bleam/AI/Flux2/Pipeline/FluxImageRunner.swift +1282 -0
  25. package/templates/native/ios/Bleam/AI/Flux2/Pipeline/LatentUtils.swift +191 -0
  26. package/templates/native/ios/Bleam/AI/Flux2/Scheduler/FlowMatchEulerScheduler.swift +279 -0
  27. package/templates/native/ios/Bleam/AI/Flux2/Text/KleinTextEncoder.swift +380 -0
  28. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Attention.swift +379 -0
  29. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Embeddings.swift +159 -0
  30. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FeedForward.swift +154 -0
  31. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FusedKernels.swift +198 -0
  32. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2KVCache.swift +36 -0
  33. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Modulation.swift +193 -0
  34. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2ParallelAttention.swift +389 -0
  35. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2RoPE.swift +304 -0
  36. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2SingleBlock.swift +290 -0
  37. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Transformer.swift +530 -0
  38. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2TransformerBlock.swift +362 -0
  39. package/templates/native/ios/Bleam/AI/Flux2/Utils/Flux2Debug.swift +101 -0
  40. package/templates/native/ios/Bleam/AI/Flux2/Utils/MLXCheckpoint.swift +118 -0
  41. package/templates/native/ios/Bleam/AI/Flux2/Utils/MemoryManager.swift +201 -0
  42. package/templates/native/ios/Bleam/AI/Flux2/VAE/AutoencoderKL.swift +476 -0
  43. package/templates/native/ios/Bleam/AI/Flux2/VAE/ResnetBlock.swift +316 -0
  44. package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEDecoder.swift +120 -0
  45. package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEEncoder.swift +136 -0
  46. package/templates/native/ios/Bleam/AppDelegate.swift +373 -0
  47. package/templates/native/ios/Bleam/Appearance.swift +62 -0
  48. package/templates/native/ios/Bleam/Bridging-Header.h +3 -0
  49. package/templates/native/ios/Bleam/Images.xcassets/AppIcon.appiconset/Contents.json +13 -0
  50. package/templates/native/ios/Bleam/Images.xcassets/Contents.json +6 -0
  51. package/templates/native/ios/Bleam/Info.plist +76 -0
  52. package/templates/native/ios/Bleam/PrivacyInfo.xcprivacy +48 -0
  53. package/templates/native/ios/Bleam/SceneDelegate.swift +58 -0
  54. package/templates/native/ios/Bleam/SplashScreen.storyboard +47 -0
  55. package/templates/native/ios/Bleam/Supporting/Expo.plist +6 -0
  56. package/templates/native/ios/Bleam/bleam.entitlements +10 -0
  57. package/templates/native/ios/Bleam.xcodeproj/project.pbxproj +1146 -0
  58. package/templates/native/ios/Bleam.xcodeproj/xcshareddata/xcschemes/Bleam.xcscheme +88 -0
  59. package/templates/native/ios/GenerationService/GenerationService.entitlements +10 -0
  60. package/templates/native/ios/GenerationService/ImageGenerationRunner.swift +591 -0
  61. package/templates/native/ios/GenerationService/Info.plist +31 -0
  62. package/templates/native/ios/GenerationService/main.swift +165 -0
  63. package/templates/native/ios/PlatformHelper/Info.plist +29 -0
  64. package/templates/native/ios/PlatformHelper/main.swift +335 -0
  65. package/templates/native/ios/Podfile +198 -0
  66. package/templates/native/ios/Podfile.lock +2284 -0
  67. package/templates/native/ios/Podfile.properties.json +5 -0
  68. package/templates/native/ios/Shared/Generation/GenerationServiceProtocol.swift +12 -0
  69. package/templates/native/ios/Shared/Generation/GenerationWorkerProtocol.swift +124 -0
  70. package/templates/native/metro.config.js +6 -0
  71. package/templates/native/modules/bleam-runtime/BleamRuntime.podspec +14 -0
  72. package/templates/native/modules/bleam-runtime/expo-module.config.json +8 -0
  73. package/templates/native/modules/bleam-runtime/ios/AIModule.swift +1258 -0
  74. package/templates/native/modules/bleam-runtime/ios/GenerationContracts.swift +135 -0
  75. package/templates/native/modules/bleam-runtime/ios/PlatformModule.swift +313 -0
  76. package/templates/native/modules/bleam-runtime/package.json +5 -0
  77. package/templates/native/package.json +39 -0
  78. package/templates/native/scripts/build/mlx-frameworks.ts +421 -0
  79. package/templates/native/scripts/start/index.ts +474 -0
  80. package/templates/native/scripts/start/known-failures.ts +20 -0
  81. package/templates/native/scripts/start/loader.ts +76 -0
  82. package/templates/native/scripts/start/native-state.ts +242 -0
  83. package/templates/native/scripts/start/package.json +4 -0
  84. package/templates/native/scripts/start/swift-packages.ts +414 -0
  85. package/templates/native/scripts/start/xcode-formatter.ts +106 -0
  86. package/templates/native/tsconfig.json +14 -0
  87. package/templates/native/yarn.lock +3749 -0
@@ -0,0 +1,233 @@
1
+ // MemoryConfig.swift - Centralized memory management configuration
2
+ // Copyright 2025 Vincent Gourbin
3
+
4
+ import Foundation
5
+ import MLX
6
+
7
+ /// Centralized memory configuration for GPU cache management
8
+ ///
9
+ /// Provides dynamic memory management that adapts to:
10
+ /// - System RAM availability
11
+ /// - Image resolution being generated
12
+ /// - Model size (currently Klein 4B only in image-studio)
13
+ ///
14
+ /// On high-RAM systems (64GB+), allows more cache for better performance.
15
+ /// On lower-RAM systems, uses conservative limits to prevent OOM.
16
+ public struct MemoryConfig {
17
+
18
+ // MARK: - Constants
19
+
20
+ private static let MB = 1024 * 1024
21
+ private static let GB = 1024 * 1024 * 1024
22
+
23
+ // MARK: - Cache Profiles
24
+
25
+ /// Memory profile presets - used as hints for dynamic calculation
26
+ public enum CacheProfile: String, CaseIterable, Sendable {
27
+ case conservative // Minimize memory usage (slower)
28
+ case balanced // Balance speed and memory
29
+ case performance // Maximize speed (more memory)
30
+ case auto // Dynamic based on available RAM
31
+
32
+ /// Human-readable description
33
+ public var description: String {
34
+ switch self {
35
+ case .conservative: return "Conservative - Minimize memory (may be slower)"
36
+ case .balanced: return "Balanced - Good tradeoff"
37
+ case .performance: return "Performance - Maximize speed (uses more memory)"
38
+ case .auto: return "Auto - Dynamic based on available RAM"
39
+ }
40
+ }
41
+ }
42
+
43
+ // MARK: - System Information
44
+
45
+ /// Get system RAM in GB
46
+ public static var systemRAMGB: Int {
47
+ Int(ProcessInfo.processInfo.physicalMemory / UInt64(GB))
48
+ }
49
+
50
+ /// Estimate available RAM in GB (rough heuristic)
51
+ /// Reserves ~8GB for system + other apps
52
+ public static var estimatedAvailableRAMGB: Int {
53
+ max(8, systemRAMGB - 8)
54
+ }
55
+
56
+ /// Calculate what percentage of RAM we can safely use for GPU cache
57
+ /// Higher RAM systems can afford to use more cache
58
+ public static var safeCachePercentage: Double {
59
+ let ram = systemRAMGB
60
+ switch ram {
61
+ case ..<24: return 0.03 // 3% - Very conservative for 16-24GB
62
+ case 24..<48: return 0.05 // 5% - Conservative for 24-48GB
63
+ case 48..<96: return 0.08 // 8% - Moderate for 48-96GB
64
+ case 96..<192: return 0.12 // 12% - Performance for 96-192GB
65
+ default: return 0.15 // 15% - High performance for 192GB+
66
+ }
67
+ }
68
+
69
+ // MARK: - Dynamic Cache Calculation
70
+
71
+ /// Calculate recommended cache limit based on system RAM
72
+ /// Returns bytes, or nil for unlimited
73
+ public static func recommendedCacheLimit() -> Int? {
74
+ let ram = systemRAMGB
75
+
76
+ // Very high RAM systems (128GB+) can use unlimited cache
77
+ if ram >= 128 {
78
+ return nil
79
+ }
80
+
81
+ // Calculate based on percentage of RAM
82
+ let cacheBytes = Int(Double(ram * GB) * safeCachePercentage)
83
+
84
+ // Clamp to reasonable bounds
85
+ let minCache = 256 * MB // At least 256 MB
86
+ let maxCache = 8 * GB // At most 8 GB
87
+
88
+ return min(max(cacheBytes, minCache), maxCache)
89
+ }
90
+
91
+ /// Calculate cache limit for a specific resolution
92
+ /// Larger images need more cache for intermediate computations
93
+ public static func cacheLimitForResolution(width: Int, height: Int, model: Flux2Model) -> Int {
94
+ let pixels = width * height
95
+ let baseLimit = recommendedCacheLimit() ?? (4 * GB)
96
+
97
+ // Scale factor based on resolution
98
+ // 512x512 = 262144 pixels (base)
99
+ // 1024x1024 = 1048576 pixels (4x)
100
+ // 2048x2048 = 4194304 pixels (16x)
101
+ let basePixels = 512 * 512
102
+ let scaleFactor = max(1.0, sqrt(Double(pixels) / Double(basePixels)))
103
+
104
+ // Model size factor
105
+ let modelFactor: Double = 1.0
106
+
107
+ let adjustedLimit = Int(Double(baseLimit) * scaleFactor * modelFactor)
108
+
109
+ // Clamp to available RAM (leave at least 8GB for system)
110
+ let maxAllowed = (systemRAMGB - 8) * GB
111
+ return min(adjustedLimit, maxAllowed)
112
+ }
113
+
114
+ // MARK: - Profile-based Limits (for manual override)
115
+
116
+ /// Get cache limit for a specific profile
117
+ public static func cacheLimitForProfile(_ profile: CacheProfile) -> Int? {
118
+ switch profile {
119
+ case .auto:
120
+ return recommendedCacheLimit()
121
+ case .conservative:
122
+ return 512 * MB
123
+ case .balanced:
124
+ return min(2 * GB, (systemRAMGB / 32) * GB)
125
+ case .performance:
126
+ return min(4 * GB, (systemRAMGB / 16) * GB)
127
+ }
128
+ }
129
+
130
+ // MARK: - Cache Limit Application
131
+
132
+ /// Apply cache limit dynamically based on system RAM
133
+ public static func applyDynamicCacheLimit() {
134
+ if let limit = recommendedCacheLimit() {
135
+ Memory.cacheLimit = limit
136
+ Flux2Debug.log("GPU cache limit: \(limit / MB) MB (dynamic, \(systemRAMGB) GB RAM)")
137
+ } else {
138
+ Flux2Debug.log("GPU cache: unlimited (\(systemRAMGB) GB RAM)")
139
+ }
140
+ }
141
+
142
+ /// Apply cache limit for a specific profile
143
+ public static func applyCacheLimit(_ profile: CacheProfile) {
144
+ if let limit = cacheLimitForProfile(profile) {
145
+ Memory.cacheLimit = limit
146
+ Flux2Debug.log("GPU cache limit: \(limit / MB) MB (\(profile.rawValue) profile)")
147
+ } else {
148
+ Flux2Debug.log("GPU cache: unlimited (\(profile.rawValue) profile)")
149
+ }
150
+ }
151
+
152
+ /// Apply cache limit with specific byte value
153
+ public static func applyCacheLimit(bytes: Int) {
154
+ Memory.cacheLimit = bytes
155
+ Flux2Debug.log("GPU cache limit: \(bytes / MB) MB")
156
+ }
157
+
158
+ /// Clear GPU cache
159
+ public static func clearCache() {
160
+ Memory.clearCache()
161
+ }
162
+
163
+ // MARK: - Phase-Specific Limits
164
+
165
+ /// Per-phase cache limits for granular control during generation
166
+ public struct PhaseLimits: Sendable {
167
+ public let textEncoding: Int // Text encoder phase
168
+ public let denoising: Int // Transformer denoising loop
169
+ public let vaeDecoding: Int // VAE decode phase
170
+
171
+ public init(textEncoding: Int, denoising: Int, vaeDecoding: Int) {
172
+ self.textEncoding = textEncoding
173
+ self.denoising = denoising
174
+ self.vaeDecoding = vaeDecoding
175
+ }
176
+
177
+ /// Get dynamic phase limits based on model and system RAM
178
+ /// Automatically scales based on available memory
179
+ public static func forModel(_ model: Flux2Model, profile: CacheProfile) -> PhaseLimits {
180
+ // Use dynamic calculation for auto profile
181
+ if profile == .auto {
182
+ return dynamicLimitsForModel(model)
183
+ }
184
+
185
+ switch profile {
186
+ case .auto:
187
+ return dynamicLimitsForModel(model)
188
+ case .conservative:
189
+ return PhaseLimits(textEncoding: 256 * MB, denoising: 512 * MB, vaeDecoding: 256 * MB)
190
+ case .balanced:
191
+ return PhaseLimits(textEncoding: 512 * MB, denoising: 1 * GB, vaeDecoding: 512 * MB)
192
+ case .performance:
193
+ return PhaseLimits(textEncoding: 1 * GB, denoising: 2 * GB, vaeDecoding: 1 * GB)
194
+ }
195
+ }
196
+
197
+ /// Calculate dynamic limits based on available RAM
198
+ private static func dynamicLimitsForModel(_ model: Flux2Model) -> PhaseLimits {
199
+ let baseLimit = recommendedCacheLimit() ?? (4 * GB)
200
+
201
+ _ = model
202
+ let (textRatio, denoiseRatio, vaeRatio): (Double, Double, Double) = (0.25, 0.6, 0.3)
203
+
204
+ return PhaseLimits(
205
+ textEncoding: Int(Double(baseLimit) * textRatio),
206
+ denoising: Int(Double(baseLimit) * denoiseRatio),
207
+ vaeDecoding: Int(Double(baseLimit) * vaeRatio)
208
+ )
209
+ }
210
+ }
211
+
212
+ // MARK: - Memory Monitoring
213
+
214
+ /// Log current memory state
215
+ public static func logMemoryState(context: String = "") {
216
+ let prefix = context.isEmpty ? "" : "[\(context)] "
217
+ let recommended = recommendedCacheLimit()
218
+ let limitStr = recommended.map { "\($0 / MB) MB" } ?? "unlimited"
219
+ Flux2Debug.log("\(prefix)System: \(systemRAMGB) GB RAM, recommended cache: \(limitStr)")
220
+ }
221
+
222
+ /// Get a summary of current memory configuration
223
+ public static var configurationSummary: String {
224
+ let recommended = recommendedCacheLimit()
225
+ let limitStr = recommended.map { "\($0 / MB) MB" } ?? "unlimited"
226
+ return """
227
+ Memory Configuration:
228
+ System RAM: \(systemRAMGB) GB
229
+ Safe cache %: \(Int(safeCachePercentage * 100))%
230
+ Recommended cache: \(limitStr)
231
+ """
232
+ }
233
+ }
@@ -0,0 +1,157 @@
1
+ // MemoryOptimizationConfig.swift - Memory optimization settings
2
+ // Copyright 2025 Vincent Gourbin
3
+
4
+ import Foundation
5
+
6
+ /// Configuration for memory optimization during transformer inference
7
+ ///
8
+ /// These settings control how aggressively the transformer manages memory
9
+ /// by forcing evaluation of the computation graph at intervals.
10
+ ///
11
+ /// # Background
12
+ /// MLX uses lazy evaluation and builds a computation graph. For large models,
13
+ /// this graph can grow very large and consume significant memory. Periodically
14
+ /// calling `eval()` materializes intermediate results and allows the graph to
15
+ /// be garbage collected.
16
+ ///
17
+ /// # Trade-offs
18
+ /// - Lower `evalFrequency` = more memory savings, but slower inference
19
+ /// - Higher `evalFrequency` = faster inference, but more memory usage
20
+ /// - `clearCacheOnEval` = additional memory savings at cost of recomputation
21
+ ///
22
+ /// # Reference
23
+ /// Based on optimizations from LTX-2-MLX: https://github.com/Acelogic/LTX-2-MLX
24
+ public struct MemoryOptimizationConfig: Sendable, Equatable {
25
+
26
+ /// How often to evaluate the computation graph during transformer forward pass.
27
+ ///
28
+ /// - `0` = disabled (fastest, most memory)
29
+ /// - `4` = evaluate every 4 blocks (aggressive memory savings)
30
+ /// - `8` = evaluate every 8 blocks (moderate, recommended)
31
+ /// - `16` = evaluate every 16 blocks (light memory savings)
32
+ ///
33
+ /// For Flux.2 Dev with 8 double + 48 single blocks:
34
+ /// - `evalFrequency: 8` will eval ~7 times during forward pass
35
+ /// - `evalFrequency: 4` will eval ~14 times during forward pass
36
+ public var evalFrequency: Int
37
+
38
+ /// Whether to clear GPU cache after each evaluation.
39
+ ///
40
+ /// When enabled, calls `MLX.Memory.clearCache()` after each periodic eval.
41
+ /// This provides additional memory savings but may cause recomputation
42
+ /// of cached values.
43
+ ///
44
+ /// Recommended: `false` for most cases, `true` only if running out of memory
45
+ public var clearCacheOnEval: Bool
46
+
47
+ /// Whether to evaluate after all double-stream blocks complete.
48
+ ///
49
+ /// This ensures the transition between double-stream and single-stream
50
+ /// phases has a clean memory state.
51
+ public var evalBetweenPhases: Bool
52
+
53
+ public init(
54
+ evalFrequency: Int = 0,
55
+ clearCacheOnEval: Bool = false,
56
+ evalBetweenPhases: Bool = true
57
+ ) {
58
+ self.evalFrequency = max(0, evalFrequency)
59
+ self.clearCacheOnEval = clearCacheOnEval
60
+ self.evalBetweenPhases = evalBetweenPhases
61
+ }
62
+
63
+ // MARK: - Presets
64
+
65
+ /// Disabled - no periodic evaluation (fastest, most memory)
66
+ ///
67
+ /// Use when you have plenty of RAM and want maximum speed.
68
+ public static let disabled = MemoryOptimizationConfig(
69
+ evalFrequency: 0,
70
+ clearCacheOnEval: false,
71
+ evalBetweenPhases: false
72
+ )
73
+
74
+ /// Light - evaluate every 16 blocks
75
+ ///
76
+ /// Minimal impact on speed with some memory savings.
77
+ public static let light = MemoryOptimizationConfig(
78
+ evalFrequency: 16,
79
+ clearCacheOnEval: false,
80
+ evalBetweenPhases: true
81
+ )
82
+
83
+ /// Moderate - evaluate every 8 blocks (recommended default)
84
+ ///
85
+ /// Good balance between speed and memory usage.
86
+ public static let moderate = MemoryOptimizationConfig(
87
+ evalFrequency: 8,
88
+ clearCacheOnEval: false,
89
+ evalBetweenPhases: true
90
+ )
91
+
92
+ /// Aggressive - evaluate every 4 blocks with cache clearing
93
+ ///
94
+ /// Use when running low on memory. Slower but uses significantly less RAM.
95
+ public static let aggressive = MemoryOptimizationConfig(
96
+ evalFrequency: 4,
97
+ clearCacheOnEval: true,
98
+ evalBetweenPhases: true
99
+ )
100
+
101
+ /// Ultra low memory - evaluate every 2 blocks with cache clearing
102
+ ///
103
+ /// Maximum memory savings at significant speed cost.
104
+ /// Use only if other presets cause out-of-memory errors.
105
+ public static let ultraLowMemory = MemoryOptimizationConfig(
106
+ evalFrequency: 2,
107
+ clearCacheOnEval: true,
108
+ evalBetweenPhases: true
109
+ )
110
+ }
111
+
112
+ // MARK: - Description
113
+
114
+ extension MemoryOptimizationConfig: CustomStringConvertible {
115
+ public var description: String {
116
+ if evalFrequency == 0 && !evalBetweenPhases {
117
+ return "MemoryOptimization(disabled)"
118
+ }
119
+
120
+ var parts: [String] = []
121
+ if evalFrequency > 0 {
122
+ parts.append("evalEvery: \(evalFrequency)")
123
+ }
124
+ if clearCacheOnEval {
125
+ parts.append("clearCache: true")
126
+ }
127
+ if evalBetweenPhases {
128
+ parts.append("evalBetweenPhases: true")
129
+ }
130
+
131
+ return "MemoryOptimization(\(parts.joined(separator: ", ")))"
132
+ }
133
+ }
134
+
135
+ // MARK: - Recommendation
136
+
137
+ extension MemoryOptimizationConfig {
138
+
139
+ /// Get recommended configuration based on available RAM
140
+ ///
141
+ /// - Parameter ramGB: System RAM in gigabytes
142
+ /// - Returns: Recommended memory optimization preset
143
+ public static func recommended(forRAMGB ramGB: Int) -> MemoryOptimizationConfig {
144
+ switch ramGB {
145
+ case 0..<32:
146
+ return .ultraLowMemory
147
+ case 32..<64:
148
+ return .aggressive
149
+ case 64..<96:
150
+ return .moderate
151
+ case 96..<128:
152
+ return .light
153
+ default:
154
+ return .disabled
155
+ }
156
+ }
157
+ }