bleam 0.0.8 → 0.0.10

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 (96) hide show
  1. package/dist/cli.cjs +269 -22
  2. package/dist/cli.d.cts +32 -2
  3. package/dist/cli.d.ts +32 -2
  4. package/dist/cli.js +270 -23
  5. package/dist/platform.d.cts +2 -0
  6. package/dist/platform.d.ts +2 -0
  7. package/dist/{ui-1WepaMS4.d.cts → ui-Bg11tvlc.d.ts} +1 -1
  8. package/dist/{ui-Ce-pnUUA.d.ts → ui-Dd7SXdbg.d.cts} +7 -7
  9. package/dist/ui.d.cts +1 -1
  10. package/dist/ui.d.ts +1 -1
  11. package/dist/window.d.cts +1 -1
  12. package/dist/window.d.ts +1 -1
  13. package/package.json +5 -1
  14. package/templates/image-generation/app/index.tsx +1 -1
  15. package/templates/native/.gitattributes +1 -0
  16. package/templates/native/App.tsx +26 -0
  17. package/templates/native/app.json +12 -0
  18. package/templates/native/index.ts +8 -0
  19. package/templates/native/ios/.xcode.env +11 -0
  20. package/templates/native/ios/Bleam/AI/Flux2/Configuration/Flux2Config.swift +288 -0
  21. package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryConfig.swift +233 -0
  22. package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryOptimizationConfig.swift +157 -0
  23. package/templates/native/ios/Bleam/AI/Flux2/Configuration/ModelRegistry.swift +425 -0
  24. package/templates/native/ios/Bleam/AI/Flux2/Configuration/QuantizationConfig.swift +138 -0
  25. package/templates/native/ios/Bleam/AI/Flux2/Configuration/TransformerRepoProfile.swift +59 -0
  26. package/templates/native/ios/Bleam/AI/Flux2/Configuration/VAEConfig.swift +134 -0
  27. package/templates/native/ios/Bleam/AI/Flux2/Flux2Core.swift +55 -0
  28. package/templates/native/ios/Bleam/AI/Flux2/Loading/WeightLoader.swift +1192 -0
  29. package/templates/native/ios/Bleam/AI/Flux2/Pipeline/FluxImageRunner.swift +1282 -0
  30. package/templates/native/ios/Bleam/AI/Flux2/Pipeline/LatentUtils.swift +191 -0
  31. package/templates/native/ios/Bleam/AI/Flux2/Scheduler/FlowMatchEulerScheduler.swift +279 -0
  32. package/templates/native/ios/Bleam/AI/Flux2/Text/KleinTextEncoder.swift +380 -0
  33. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Attention.swift +379 -0
  34. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Embeddings.swift +159 -0
  35. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FeedForward.swift +154 -0
  36. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FusedKernels.swift +198 -0
  37. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2KVCache.swift +36 -0
  38. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Modulation.swift +193 -0
  39. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2ParallelAttention.swift +389 -0
  40. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2RoPE.swift +304 -0
  41. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2SingleBlock.swift +290 -0
  42. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Transformer.swift +530 -0
  43. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2TransformerBlock.swift +362 -0
  44. package/templates/native/ios/Bleam/AI/Flux2/Utils/Flux2Debug.swift +101 -0
  45. package/templates/native/ios/Bleam/AI/Flux2/Utils/MLXCheckpoint.swift +118 -0
  46. package/templates/native/ios/Bleam/AI/Flux2/Utils/MemoryManager.swift +201 -0
  47. package/templates/native/ios/Bleam/AI/Flux2/VAE/AutoencoderKL.swift +476 -0
  48. package/templates/native/ios/Bleam/AI/Flux2/VAE/ResnetBlock.swift +316 -0
  49. package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEDecoder.swift +120 -0
  50. package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEEncoder.swift +136 -0
  51. package/templates/native/ios/Bleam/AppDelegate.swift +482 -0
  52. package/templates/native/ios/Bleam/Appearance.swift +62 -0
  53. package/templates/native/ios/Bleam/Bridging-Header.h +3 -0
  54. package/templates/native/ios/Bleam/Images.xcassets/AppIcon.appiconset/Contents.json +13 -0
  55. package/templates/native/ios/Bleam/Images.xcassets/Contents.json +6 -0
  56. package/templates/native/ios/Bleam/Info.plist +76 -0
  57. package/templates/native/ios/Bleam/PrivacyInfo.xcprivacy +48 -0
  58. package/templates/native/ios/Bleam/SceneDelegate.swift +58 -0
  59. package/templates/native/ios/Bleam/SplashScreen.storyboard +47 -0
  60. package/templates/native/ios/Bleam/Supporting/Expo.plist +6 -0
  61. package/templates/native/ios/Bleam/bleam.entitlements +10 -0
  62. package/templates/native/ios/Bleam.xcodeproj/project.pbxproj +1147 -0
  63. package/templates/native/ios/Bleam.xcodeproj/xcshareddata/xcschemes/Bleam.xcscheme +88 -0
  64. package/templates/native/ios/GenerationService/GenerationService.entitlements +10 -0
  65. package/templates/native/ios/GenerationService/ImageGenerationRunner.swift +591 -0
  66. package/templates/native/ios/GenerationService/Info.plist +31 -0
  67. package/templates/native/ios/GenerationService/main.swift +165 -0
  68. package/templates/native/ios/PlatformHelper/main.swift +726 -0
  69. package/templates/native/ios/Podfile +198 -0
  70. package/templates/native/ios/Podfile.lock +2284 -0
  71. package/templates/native/ios/Podfile.properties.json +5 -0
  72. package/templates/native/ios/Shared/Generation/GenerationServiceProtocol.swift +12 -0
  73. package/templates/native/ios/Shared/Generation/GenerationWorkerProtocol.swift +124 -0
  74. package/templates/native/metro.config.js +6 -0
  75. package/templates/native/modules/bleam-runtime/BleamRuntime.podspec +14 -0
  76. package/templates/native/modules/bleam-runtime/expo-module.config.json +8 -0
  77. package/templates/native/modules/bleam-runtime/ios/AIModule.swift +1258 -0
  78. package/templates/native/modules/bleam-runtime/ios/GenerationContracts.swift +135 -0
  79. package/templates/native/modules/bleam-runtime/ios/PlatformModule.swift +329 -0
  80. package/templates/native/modules/bleam-runtime/package.json +5 -0
  81. package/templates/native/package.json +39 -0
  82. package/templates/native/scripts/build/mlx-frameworks.ts +421 -0
  83. package/templates/native/scripts/start/index.ts +474 -0
  84. package/templates/native/scripts/start/known-failures.ts +20 -0
  85. package/templates/native/scripts/start/loader.ts +76 -0
  86. package/templates/native/scripts/start/native-state.ts +242 -0
  87. package/templates/native/scripts/start/package.json +4 -0
  88. package/templates/native/scripts/start/swift-packages.ts +414 -0
  89. package/templates/native/scripts/start/xcode-formatter.ts +106 -0
  90. package/templates/native/tsconfig.json +14 -0
  91. package/templates/native/yarn.lock +3749 -0
  92. package/templates/updates/README.md +272 -0
  93. package/templates/updates/src/index.ts +385 -0
  94. package/templates/updates/src/schema.ts +385 -0
  95. package/templates/updates/tsconfig.json +12 -0
  96. package/templates/updates/wrangler.jsonc +19 -0
@@ -0,0 +1,138 @@
1
+ // QuantizationConfig.swift - Fine-grained quantization configuration
2
+ // Copyright 2025 Vincent Gourbin
3
+
4
+ import Foundation
5
+
6
+ /// Quantization level for the Mistral text encoder
7
+ public enum MistralQuantization: String, CaseIterable, Codable, Sendable {
8
+ case bf16 = "bf16" // Full precision ~48GB
9
+ case mlx8bit = "8bit" // 8-bit ~25GB
10
+ case mlx6bit = "6bit" // 6-bit ~19GB
11
+ case mlx4bit = "4bit" // 4-bit ~14GB
12
+
13
+ public var estimatedMemoryGB: Int {
14
+ switch self {
15
+ case .bf16: return 48
16
+ case .mlx8bit: return 25
17
+ case .mlx6bit: return 19
18
+ case .mlx4bit: return 14
19
+ }
20
+ }
21
+
22
+ public var displayName: String {
23
+ switch self {
24
+ case .bf16: return "Full Precision (bf16)"
25
+ case .mlx8bit: return "8-bit"
26
+ case .mlx6bit: return "6-bit"
27
+ case .mlx4bit: return "4-bit"
28
+ }
29
+ }
30
+ }
31
+
32
+ /// Quantization level for the Flux.2 diffusion transformer
33
+ public enum TransformerQuantization: String, CaseIterable, Codable, Sendable {
34
+ case bf16 = "bf16" // Full precision ~64GB
35
+ case qint8 = "qint8" // 8-bit ~32GB
36
+ case int4 = "int4" // 4-bit ~16GB (on-the-fly quantization)
37
+
38
+ public var estimatedMemoryGB: Int {
39
+ switch self {
40
+ case .bf16: return 64
41
+ case .qint8: return 32
42
+ case .int4: return 16
43
+ }
44
+ }
45
+
46
+ public var displayName: String {
47
+ switch self {
48
+ case .bf16: return "Full Precision (bf16)"
49
+ case .qint8: return "8-bit (qint8)"
50
+ case .int4: return "4-bit (int4)"
51
+ }
52
+ }
53
+
54
+ public var bits: Int {
55
+ switch self {
56
+ case .bf16: return 16
57
+ case .qint8: return 8
58
+ case .int4: return 4
59
+ }
60
+ }
61
+
62
+ public var groupSize: Int { 64 }
63
+ }
64
+
65
+ /// Independent quantization configuration for text encoder and transformer
66
+ public struct Flux2QuantizationConfig: Codable, Sendable {
67
+ /// Quantization for the Mistral text encoder
68
+ public var textEncoder: MistralQuantization
69
+
70
+ /// Quantization for the Flux.2 diffusion transformer
71
+ public var transformer: TransformerQuantization
72
+
73
+ public init(
74
+ textEncoder: MistralQuantization,
75
+ transformer: TransformerQuantization
76
+ ) {
77
+ self.textEncoder = textEncoder
78
+ self.transformer = transformer
79
+ }
80
+
81
+ /// Total estimated memory requirement in GB
82
+ public var estimatedTotalMemoryGB: Int {
83
+ // Text encoder and transformer are never loaded simultaneously
84
+ // So we take the max of the two, plus VAE (~3GB) and working memory (~5GB)
85
+ max(textEncoder.estimatedMemoryGB, transformer.estimatedMemoryGB) + 8
86
+ }
87
+
88
+ /// Peak memory during text encoding phase
89
+ public var textEncodingPhaseMemoryGB: Int {
90
+ textEncoder.estimatedMemoryGB + 1 // +1GB for embeddings
91
+ }
92
+
93
+ /// Peak memory during image generation phase
94
+ public var imageGenerationPhaseMemoryGB: Int {
95
+ transformer.estimatedMemoryGB + 3 + 5 // +3GB VAE, +5GB working memory
96
+ }
97
+
98
+ // MARK: - Presets
99
+
100
+ /// High quality preset - requires ~90GB+ RAM
101
+ public static let highQuality = Flux2QuantizationConfig(
102
+ textEncoder: .bf16,
103
+ transformer: .bf16
104
+ )
105
+
106
+ /// Balanced preset - requires ~57GB RAM (recommended for 64GB Macs)
107
+ public static let balanced = Flux2QuantizationConfig(
108
+ textEncoder: .mlx8bit,
109
+ transformer: .qint8
110
+ )
111
+
112
+ /// Memory efficient preset - requires ~47GB RAM
113
+ public static let memoryEfficient = Flux2QuantizationConfig(
114
+ textEncoder: .mlx4bit,
115
+ transformer: .qint8
116
+ )
117
+
118
+ /// Minimal preset - requires ~47GB RAM
119
+ public static let minimal = Flux2QuantizationConfig(
120
+ textEncoder: .mlx4bit,
121
+ transformer: .qint8
122
+ )
123
+
124
+ /// Ultra-minimal preset - requires ~30GB RAM (4-bit transformer)
125
+ public static let ultraMinimal = Flux2QuantizationConfig(
126
+ textEncoder: .mlx4bit,
127
+ transformer: .int4
128
+ )
129
+
130
+ /// Default preset (balanced)
131
+ public static let `default` = balanced
132
+ }
133
+
134
+ extension Flux2QuantizationConfig: CustomStringConvertible {
135
+ public var description: String {
136
+ "Flux2QuantizationConfig(text: \(textEncoder.rawValue), transformer: \(transformer.rawValue), ~\(estimatedTotalMemoryGB)GB)"
137
+ }
138
+ }
@@ -0,0 +1,59 @@
1
+ import Foundation
2
+
3
+ public enum Flux2TransformerCheckpointFormat: String, Sendable {
4
+ case diffusers
5
+ case diffusersQuanto
6
+ case packedDiffusers
7
+ case bfl
8
+ }
9
+
10
+ public struct Flux2TransformerRepoProfile: Hashable, Sendable {
11
+ public let repoId: String
12
+ public let model: Flux2Model
13
+ public let quantization: TransformerQuantization
14
+ public let relativePathComponents: [String]
15
+ public let requiredSnapshotPatterns: [String]
16
+ public let estimatedSizeGB: Int
17
+ public let checkpointFormat: Flux2TransformerCheckpointFormat
18
+ public let needsNormOutSwap: Bool
19
+ public let usesNormOutBias: Bool
20
+
21
+ public init(
22
+ repoId: String,
23
+ model: Flux2Model,
24
+ quantization: TransformerQuantization,
25
+ relativePathComponents: [String],
26
+ requiredSnapshotPatterns: [String],
27
+ estimatedSizeGB: Int,
28
+ checkpointFormat: Flux2TransformerCheckpointFormat,
29
+ needsNormOutSwap: Bool = false,
30
+ usesNormOutBias: Bool = false
31
+ ) {
32
+ self.repoId = repoId
33
+ self.model = model
34
+ self.quantization = quantization
35
+ self.relativePathComponents = relativePathComponents
36
+ self.requiredSnapshotPatterns = requiredSnapshotPatterns
37
+ self.estimatedSizeGB = estimatedSizeGB
38
+ self.checkpointFormat = checkpointFormat
39
+ self.needsNormOutSwap = needsNormOutSwap
40
+ self.usesNormOutBias = usesNormOutBias
41
+ }
42
+
43
+ public func withRuntimeOverrides(
44
+ needsNormOutSwap: Bool? = nil,
45
+ usesNormOutBias: Bool? = nil
46
+ ) -> Flux2TransformerRepoProfile {
47
+ Flux2TransformerRepoProfile(
48
+ repoId: repoId,
49
+ model: model,
50
+ quantization: quantization,
51
+ relativePathComponents: relativePathComponents,
52
+ requiredSnapshotPatterns: requiredSnapshotPatterns,
53
+ estimatedSizeGB: estimatedSizeGB,
54
+ checkpointFormat: checkpointFormat,
55
+ needsNormOutSwap: needsNormOutSwap ?? self.needsNormOutSwap,
56
+ usesNormOutBias: usesNormOutBias ?? self.usesNormOutBias
57
+ )
58
+ }
59
+ }
@@ -0,0 +1,134 @@
1
+ // VAEConfig.swift - Flux.2 VAE Configuration
2
+ // Copyright 2025 Vincent Gourbin
3
+
4
+ import Foundation
5
+
6
+ /// Configuration for the Flux.2 VAE (AutoencoderKL)
7
+ public struct VAEConfig: Codable, Sendable {
8
+ /// Number of input/output channels (3 for RGB)
9
+ public var inChannels: Int
10
+
11
+ /// Number of output channels (same as input)
12
+ public var outChannels: Int
13
+
14
+ /// Number of latent channels (32 for Flux.2, vs 4 for Flux.1)
15
+ public var latentChannels: Int
16
+
17
+ /// Channel multipliers for each block
18
+ public var blockOutChannels: [Int]
19
+
20
+ /// Number of ResNet blocks per level
21
+ public var layersPerBlock: Int
22
+
23
+ /// Activation function
24
+ public var activationFunction: String
25
+
26
+ /// Normalization layer epsilon
27
+ public var normEps: Float
28
+
29
+ /// Number of groups for group normalization
30
+ public var normNumGroups: Int
31
+
32
+ /// Scaling factor for latent space
33
+ public var scalingFactor: Float
34
+
35
+ /// Whether to use BatchNorm for latent normalization
36
+ public var useBatchNorm: Bool
37
+
38
+ /// Patch size for latent packing
39
+ public var patchSize: (Int, Int)
40
+
41
+ public init(
42
+ inChannels: Int = 3,
43
+ outChannels: Int = 3,
44
+ latentChannels: Int = 32,
45
+ blockOutChannels: [Int] = [128, 256, 512, 512],
46
+ layersPerBlock: Int = 2,
47
+ activationFunction: String = "silu",
48
+ normEps: Float = 1e-6,
49
+ normNumGroups: Int = 32,
50
+ scalingFactor: Float = 0.18215,
51
+ useBatchNorm: Bool = true,
52
+ patchSize: (Int, Int) = (2, 2)
53
+ ) {
54
+ self.inChannels = inChannels
55
+ self.outChannels = outChannels
56
+ self.latentChannels = latentChannels
57
+ self.blockOutChannels = blockOutChannels
58
+ self.layersPerBlock = layersPerBlock
59
+ self.activationFunction = activationFunction
60
+ self.normEps = normEps
61
+ self.normNumGroups = normNumGroups
62
+ self.scalingFactor = scalingFactor
63
+ self.useBatchNorm = useBatchNorm
64
+ self.patchSize = patchSize
65
+ }
66
+
67
+ /// Default Flux.2 VAE configuration
68
+ public static let flux2Dev = VAEConfig()
69
+
70
+ // MARK: - Codable
71
+
72
+ enum CodingKeys: String, CodingKey {
73
+ case inChannels = "in_channels"
74
+ case outChannels = "out_channels"
75
+ case latentChannels = "latent_channels"
76
+ case blockOutChannels = "block_out_channels"
77
+ case layersPerBlock = "layers_per_block"
78
+ case activationFunction = "act_fn"
79
+ case normEps = "norm_eps"
80
+ case normNumGroups = "norm_num_groups"
81
+ case scalingFactor = "scaling_factor"
82
+ case useBatchNorm = "use_batch_norm"
83
+ }
84
+
85
+ public init(from decoder: Decoder) throws {
86
+ let container = try decoder.container(keyedBy: CodingKeys.self)
87
+
88
+ inChannels = try container.decodeIfPresent(Int.self, forKey: .inChannels) ?? 3
89
+ outChannels = try container.decodeIfPresent(Int.self, forKey: .outChannels) ?? 3
90
+ latentChannels = try container.decodeIfPresent(Int.self, forKey: .latentChannels) ?? 32
91
+ blockOutChannels = try container.decodeIfPresent([Int].self, forKey: .blockOutChannels) ?? [128, 256, 512, 512]
92
+ layersPerBlock = try container.decodeIfPresent(Int.self, forKey: .layersPerBlock) ?? 2
93
+ activationFunction = try container.decodeIfPresent(String.self, forKey: .activationFunction) ?? "silu"
94
+ normEps = try container.decodeIfPresent(Float.self, forKey: .normEps) ?? 1e-6
95
+ normNumGroups = try container.decodeIfPresent(Int.self, forKey: .normNumGroups) ?? 32
96
+ scalingFactor = try container.decodeIfPresent(Float.self, forKey: .scalingFactor) ?? 0.18215
97
+ useBatchNorm = try container.decodeIfPresent(Bool.self, forKey: .useBatchNorm) ?? true
98
+ patchSize = (2, 2) // Not in JSON, hardcoded for Flux.2
99
+ }
100
+
101
+ public func encode(to encoder: Encoder) throws {
102
+ var container = encoder.container(keyedBy: CodingKeys.self)
103
+
104
+ try container.encode(inChannels, forKey: .inChannels)
105
+ try container.encode(outChannels, forKey: .outChannels)
106
+ try container.encode(latentChannels, forKey: .latentChannels)
107
+ try container.encode(blockOutChannels, forKey: .blockOutChannels)
108
+ try container.encode(layersPerBlock, forKey: .layersPerBlock)
109
+ try container.encode(activationFunction, forKey: .activationFunction)
110
+ try container.encode(normEps, forKey: .normEps)
111
+ try container.encode(normNumGroups, forKey: .normNumGroups)
112
+ try container.encode(scalingFactor, forKey: .scalingFactor)
113
+ try container.encode(useBatchNorm, forKey: .useBatchNorm)
114
+ }
115
+
116
+ /// Load configuration from a JSON file
117
+ public static func load(from url: URL) throws -> VAEConfig {
118
+ let data = try Data(contentsOf: url)
119
+ return try JSONDecoder().decode(VAEConfig.self, from: data)
120
+ }
121
+ }
122
+
123
+ extension VAEConfig: CustomStringConvertible {
124
+ public var description: String {
125
+ """
126
+ VAEConfig(
127
+ channels: \(inChannels) -> latent \(latentChannels) -> \(outChannels),
128
+ blocks: \(blockOutChannels),
129
+ batchNorm: \(useBatchNorm),
130
+ patch: \(patchSize)
131
+ )
132
+ """
133
+ }
134
+ }
@@ -0,0 +1,55 @@
1
+ import Foundation
2
+ import MLX
3
+ import MLXNN
4
+
5
+ public enum Flux2Core {
6
+ public static let version = "0.1.0-image-studio"
7
+ }
8
+
9
+ public enum Flux2Error: Error, LocalizedError {
10
+ case modelNotLoaded(String)
11
+ case invalidConfiguration(String)
12
+ case insufficientMemory(required: Int, available: Int)
13
+ case weightLoadingFailed(String)
14
+ case imageProcessingFailed(String)
15
+ case generationFailed(String)
16
+ case generationCancelled
17
+
18
+ public var errorCode: String {
19
+ switch self {
20
+ case .modelNotLoaded:
21
+ return "model_not_loaded"
22
+ case .invalidConfiguration:
23
+ return "invalid_configuration"
24
+ case .insufficientMemory:
25
+ return "insufficient_memory"
26
+ case .weightLoadingFailed:
27
+ return "weight_loading_failed"
28
+ case .imageProcessingFailed:
29
+ return "image_processing_failed"
30
+ case .generationFailed:
31
+ return "generation_failed"
32
+ case .generationCancelled:
33
+ return "generation_cancelled"
34
+ }
35
+ }
36
+
37
+ public var errorDescription: String? {
38
+ switch self {
39
+ case .modelNotLoaded(let component):
40
+ return "Model component not loaded: \(component)"
41
+ case .invalidConfiguration(let message):
42
+ return "Invalid configuration: \(message)"
43
+ case .insufficientMemory(let required, let available):
44
+ return "Insufficient memory: required \(required / 1_000_000_000)GB, available \(available / 1_000_000_000)GB"
45
+ case .weightLoadingFailed(let message):
46
+ return "Failed to load weights: \(message)"
47
+ case .imageProcessingFailed(let message):
48
+ return "Image processing failed: \(message)"
49
+ case .generationFailed(let message):
50
+ return "Generation failed: \(message)"
51
+ case .generationCancelled:
52
+ return "Generation was cancelled"
53
+ }
54
+ }
55
+ }