diff --git a/Sources/Generation/Decoders.swift b/Sources/Generation/Decoders.swift index e6dfd73..1212007 100644 --- a/Sources/Generation/Decoders.swift +++ b/Sources/Generation/Decoders.swift @@ -3,7 +3,7 @@ import CoreML // MARK: Greedy Decoding -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) func selectNextTokenUsingGreedyDecoding(from scores: MLTensor) -> MLTensor { let indices = scores.argmax(alongAxis: -1).reshaped(to: [1, 1]) // Ensure indices are Int32 for concatenation with input tokens @@ -19,7 +19,7 @@ func selectNextTokenUsingGreedyDecoding(from scores: MLTensor) -> MLTensor { /// /// - Parameter scores: Processed logits tensor [batch_size, vocab_size] /// - Returns: Sampled token ID tensor [batch_size, 1] -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) func selectNextTokenUsingSampling(from scores: MLTensor) -> MLTensor { // Convert logits to probabilities let probs = scores.softmax(alongAxis: -1) diff --git a/Sources/Generation/Generation.swift b/Sources/Generation/Generation.swift index 837b836..f193117 100644 --- a/Sources/Generation/Generation.swift +++ b/Sources/Generation/Generation.swift @@ -38,7 +38,7 @@ public typealias GenerationOutput = [Int] /// - Parameter tokens: Input token sequence /// - Parameter config: Generation configuration /// - Returns: Logits array for next token prediction -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public typealias NextTokenModel = (MLTensor, GenerationConfig) async -> MLTensor /// Callback for receiving generated tokens during streaming. @@ -48,7 +48,7 @@ public typealias PredictionTokensCallback = (GenerationOutput) -> Void public typealias PredictionStringCallback = (String) -> Void /// Protocol for text generation implementations. -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public protocol Generation { /// Generates text from a prompt string. /// @@ -62,7 +62,7 @@ public protocol Generation { func generate(config: GenerationConfig, prompt: String, model: NextTokenModel, tokenizer: Tokenizer, callback: PredictionStringCallback?) async -> String } -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) extension Generation { public func generate( config: GenerationConfig, @@ -162,7 +162,7 @@ extension Generation { } } -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public extension Generation { /// Performs greedy or sampling-based text generation based on generation configuration. /// diff --git a/Sources/Generation/LogitsWarper/LogitsProcessor.swift b/Sources/Generation/LogitsWarper/LogitsProcessor.swift index a2a042b..affa515 100644 --- a/Sources/Generation/LogitsWarper/LogitsProcessor.swift +++ b/Sources/Generation/LogitsWarper/LogitsProcessor.swift @@ -8,7 +8,7 @@ import CoreML /// such as temperature scaling, top-k/top-p filtering, and repetition penalties. /// /// Based on: https://github.com/huggingface/transformers/blob/main/src/transformers/generation/logits_process.py -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public protocol LogitsProcessor { /// Processes logits for next token prediction. /// @@ -28,7 +28,7 @@ public protocol LogitsProcessor { /// This class provides a convenient way to chain multiple logits processors together. /// Each processor is applied in order to the logits tensor, with the output of one /// processor becoming the input to the next. -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public struct LogitsProcessorList { public var processors: [any LogitsProcessor] diff --git a/Sources/Generation/LogitsWarper/MinPLogitsWarper.swift b/Sources/Generation/LogitsWarper/MinPLogitsWarper.swift index 9b2867b..cfbdb99 100644 --- a/Sources/Generation/LogitsWarper/MinPLogitsWarper.swift +++ b/Sources/Generation/LogitsWarper/MinPLogitsWarper.swift @@ -15,7 +15,7 @@ import CoreML /// /// Based on: /// - https://github.com/huggingface/transformers/blob/main/src/transformers/generation/logits_process.py#L460 -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public struct MinPLogitsWarper: LogitsProcessor { public let minP: Float public let minTokensToKeep: Int diff --git a/Sources/Generation/LogitsWarper/RepetitionPenaltyLogitsProcessor.swift b/Sources/Generation/LogitsWarper/RepetitionPenaltyLogitsProcessor.swift index 006bac3..42c4d5f 100644 --- a/Sources/Generation/LogitsWarper/RepetitionPenaltyLogitsProcessor.swift +++ b/Sources/Generation/LogitsWarper/RepetitionPenaltyLogitsProcessor.swift @@ -22,7 +22,7 @@ public enum LogitsProcessorError: Error { /// Based on: /// - https://github.com/huggingface/transformers/blob/main/src/transformers/generation/logits_process.py#L297 /// - Paper: https://arxiv.org/abs/1909.05858 -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public struct RepetitionPenaltyLogitsProcessor: LogitsProcessor { public let penalty: Float diff --git a/Sources/Generation/LogitsWarper/TemperatureLogitsWarper.swift b/Sources/Generation/LogitsWarper/TemperatureLogitsWarper.swift index e3f9383..140e93b 100644 --- a/Sources/Generation/LogitsWarper/TemperatureLogitsWarper.swift +++ b/Sources/Generation/LogitsWarper/TemperatureLogitsWarper.swift @@ -11,7 +11,7 @@ import CoreML /// Often used together with `TopPLogitsWarper` and `TopKLogitsWarper`. /// /// Based on: https://github.com/huggingface/transformers/blob/main/src/transformers/generation/logits_process.py#L231 -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public struct TemperatureLogitsWarper: LogitsProcessor { public let temperature: Float diff --git a/Sources/Generation/LogitsWarper/TopKLogitsWarper.swift b/Sources/Generation/LogitsWarper/TopKLogitsWarper.swift index 5472c82..91b4a8f 100644 --- a/Sources/Generation/LogitsWarper/TopKLogitsWarper.swift +++ b/Sources/Generation/LogitsWarper/TopKLogitsWarper.swift @@ -10,7 +10,7 @@ import CoreML /// Pro tip: In practice, LLMs use top_k in the 5-50 range. /// /// Based on: https://github.com/huggingface/transformers/blob/main/src/transformers/generation/logits_process.py#L532 -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public struct TopKLogitsWarper: LogitsProcessor { public let topK: Int public let filterValue: Float diff --git a/Sources/Generation/LogitsWarper/TopPLogitsWarper.swift b/Sources/Generation/LogitsWarper/TopPLogitsWarper.swift index e3445a4..c4f8960 100644 --- a/Sources/Generation/LogitsWarper/TopPLogitsWarper.swift +++ b/Sources/Generation/LogitsWarper/TopPLogitsWarper.swift @@ -14,7 +14,7 @@ import CoreML /// Based on: /// - https://github.com/huggingface/transformers/blob/main/src/transformers/generation/logits_process.py#L465 /// - Paper: https://arxiv.org/abs/1904.09751 (Nucleus Sampling) -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public struct TopPLogitsWarper: LogitsProcessor { public let topP: Float public let filterValue: Float diff --git a/Sources/Models/LanguageModel.swift b/Sources/Models/LanguageModel.swift index bb5d94d..42b19fc 100644 --- a/Sources/Models/LanguageModel.swift +++ b/Sources/Models/LanguageModel.swift @@ -12,7 +12,7 @@ import Generation import Hub import Tokenizers -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) /// A high-level interface for language model inference using CoreML. /// /// `LanguageModel` provides a convenient way to load and interact with pre-trained @@ -72,7 +72,7 @@ public class LanguageModel { } } -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) private extension LanguageModel { static func contextRange(from model: MLModel) -> (min: Int, max: Int) { contextRange(from: model, inputKey: Keys.inputIds) @@ -109,7 +109,7 @@ private extension LanguageModel { } } -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) extension LanguageModel { struct Configurations { var modelConfig: Config @@ -118,7 +118,7 @@ extension LanguageModel { } } -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) extension LanguageModel { enum Keys { // Input keys @@ -135,7 +135,7 @@ extension LanguageModel { } } -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public extension LanguageModel { /// Loads a compiled CoreML model from disk. /// @@ -155,7 +155,7 @@ public extension LanguageModel { } } -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) extension LanguageModel { enum KVCacheAvailability { /// Language models that support KV cache via state. Implementation details for handling state @@ -167,7 +167,7 @@ extension LanguageModel { } } -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public extension LanguageModel { /// Metadata fields associated to the Core ML model. var metadata: [MLModelMetadataKey: Any] { @@ -296,7 +296,7 @@ public extension LanguageModel { // MARK: - Configuration Properties /// Asynchronous properties that are downloaded from the Hugging Face Hub configuration. -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public extension LanguageModel { /// The model configuration dictionary. /// @@ -402,7 +402,7 @@ public extension LanguageModel { // MARK: - TextGenerationModel Conformance -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) extension LanguageModel: TextGenerationModel { /// The default generation configuration for this model. /// @@ -424,7 +424,7 @@ extension LanguageModel: TextGenerationModel { /// /// Maintains a KV Cache as sequence generation progresses, /// using stateful Core ML buffers to minimize latency. -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public class LanguageModelWithStatefulKVCache: LanguageModel { private enum Mode { case prefilling diff --git a/Sources/Models/LanguageModelTypes.swift b/Sources/Models/LanguageModelTypes.swift index 328772d..6f83166 100644 --- a/Sources/Models/LanguageModelTypes.swift +++ b/Sources/Models/LanguageModelTypes.swift @@ -15,7 +15,7 @@ import Tokenizers /// /// This protocol establishes the fundamental requirements for any language model /// that can perform next-token prediction and text generation tasks. -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public protocol LanguageModelProtocol { /// The name or path of the model. /// @@ -50,7 +50,7 @@ public protocol LanguageModelProtocol { func predictNextTokenScores(_ input: MLTensor, config: GenerationConfig) async -> MLTensor } -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public extension LanguageModelProtocol { /// Function call syntax for next token prediction. /// @@ -69,7 +69,7 @@ public extension LanguageModelProtocol { /// /// This protocol extends `LanguageModelProtocol` and `Generation` to provide /// high-level text generation functionality with configurable parameters. -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public protocol TextGenerationModel: Generation, LanguageModelProtocol { /// The default generation configuration for this model. /// @@ -92,7 +92,7 @@ public protocol TextGenerationModel: Generation, LanguageModelProtocol { ) async throws -> String } -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) public extension TextGenerationModel { /// Default implementation of text generation that uses the underlying generation framework. /// diff --git a/Tests/GenerationTests/GenerationIntegrationTests.swift b/Tests/GenerationTests/GenerationIntegrationTests.swift index 8963a65..6d6dd98 100644 --- a/Tests/GenerationTests/GenerationIntegrationTests.swift +++ b/Tests/GenerationTests/GenerationIntegrationTests.swift @@ -4,7 +4,7 @@ import XCTest @testable import Generation -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) final class GenerationIntegrationTests: XCTestCase { // MARK: - Mock Model for Testing @@ -343,7 +343,7 @@ final class GenerationIntegrationTests: XCTestCase { // MARK: - Test Helper -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) struct TestGeneration: Generation { func generate( config: GenerationConfig, diff --git a/Tests/GenerationTests/LogitsProcessorTests.swift b/Tests/GenerationTests/LogitsProcessorTests.swift index 44d16f2..d29675c 100644 --- a/Tests/GenerationTests/LogitsProcessorTests.swift +++ b/Tests/GenerationTests/LogitsProcessorTests.swift @@ -3,7 +3,7 @@ import XCTest @testable import Generation -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) final class LogitsProcessorTests: XCTestCase { private let accuracy: Float = 0.0001 @@ -319,7 +319,7 @@ final class LogitsProcessorTests: XCTestCase { // MARK: - Test Helpers -@available(macOS 15.0, iOS 18.0, *) +@available(macOS 15.0, iOS 18.0, tvOS 18.0, visionOS 2.0, watchOS 11.0, *) func assertMLTensorEqual( _ tensor: MLTensor, expected: [Float],