Skip to content

Fix formatting #200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .swiftformat
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,5 @@
--disable blankLineAfterImports,unusedArguments
--enable docComments
--disable enumnamespaces
--trimwhitespace nonblank-lines
--trimwhitespace always
--disable preferKeyPath
6 changes: 3 additions & 3 deletions Sources/Generation/Generation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public typealias PredictionStringCallback = (String) -> Void
// TODO: callbacks (for streaming)
public protocol Generation {
func greedySearch(config: GenerationConfig, tokens: InputTokens, model: NextTokenModel, callback: PredictionTokensCallback?) async -> GenerationOutput

func generate(config: GenerationConfig, prompt: String, model: NextTokenModel, tokenizer: Tokenizer, callback: PredictionStringCallback?) async -> String
}

Expand All @@ -48,7 +48,7 @@ public extension Generation {
}
return outputTokens
}

/// https://github.com/huggingface/transformers/blob/42017d82baa083da2bee3055fdac80c81ee97b8a/src/transformers/generation/utils.py#L1552
func sample(config: GenerationConfig, tokens: InputTokens, model: NextTokenModel, callback: PredictionTokensCallback? = nil) async -> GenerationOutput {
// Iterate until we find the eos token or reach the max length
Expand Down Expand Up @@ -86,7 +86,7 @@ public extension Generation {
default:
fatalError("Generation mode \(generationConfig.generationMode) not implemented yet")
}

return tokenizer.decode(tokens: output)
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/Generation/GenerationConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ public struct GenerationConfig {
public var topK = 50
public var topP = 1.0
public var repetitionPenalty = 1.0

public var padTokenId: Int?
public var bosTokenId: Int?
public var eosTokenId: Int?

public init(maxLength: Int = 20, maxNewTokens: Int, doSample: Bool = false, numBeams: Int = 1, numBeamGroups: Int = 1, penaltyAlpha: Double? = nil, temperature: Double = 1.0, topK: Int = 50, topP: Double = 1.0, repetitionPenalty: Double = 1.0) {
self.maxLength = maxLength
self.maxNewTokens = maxNewTokens
Expand All @@ -44,7 +44,7 @@ public extension GenerationConfig {
if topK > 1, !doSample, penaltyAlpha != nil, penaltyAlpha! > 0 {
return .contrastiveSearch
}

switch (numBeams, numBeamGroups, doSample) {
case (1, 1, false): return .greedy
case (1, 1, true): return .sample
Expand Down
54 changes: 27 additions & 27 deletions Sources/Hub/Downloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ class Downloader: NSObject, ObservableObject {

private(set) lazy var downloadState: CurrentValueSubject<DownloadState, Never> = CurrentValueSubject(.notStarted)
private var stateSubscriber: Cancellable?

private(set) var tempFilePath: URL
private(set) var expectedSize: Int?
private(set) var downloadedSize: Int = 0

var session: URLSession? = nil
var downloadTask: Task<Void, Error>? = nil

init(
from url: URL,
to destination: URL,
Expand All @@ -50,13 +50,13 @@ class Downloader: NSObject, ObservableObject {
) {
self.destination = destination
self.expectedSize = expectedSize

// Create incomplete file path based on destination
tempFilePath = incompleteDestination

// If resume size wasn't specified, check for an existing incomplete file
let resumeSize = Self.incompleteFileSize(at: incompleteDestination)

super.init()
let sessionIdentifier = "swift-transformers.hub.downloader"

Expand All @@ -81,7 +81,7 @@ class Downloader: NSObject, ObservableObject {
return fileSize
}
}

return 0
}

Expand Down Expand Up @@ -119,23 +119,23 @@ class Downloader: NSObject, ObservableObject {
existing.cancel()
}
}

self.downloadTask = Task {
do {
// Set up the request with appropriate headers
var request = URLRequest(url: url)
var requestHeaders = headers ?? [:]

if let authToken {
requestHeaders["Authorization"] = "Bearer \(authToken)"
}

self.downloadedSize = resumeSize

// Set Range header if we're resuming
if resumeSize > 0 {
requestHeaders["Range"] = "bytes=\(resumeSize)-"

// Calculate and show initial progress
if let expectedSize, expectedSize > 0 {
let initialProgress = Double(resumeSize) / Double(expectedSize)
Expand All @@ -146,23 +146,23 @@ class Downloader: NSObject, ObservableObject {
} else {
self.downloadState.value = .downloading(0)
}

request.timeoutInterval = timeout
request.allHTTPHeaderFields = requestHeaders

// Open the incomplete file for writing
let tempFile = try FileHandle(forWritingTo: self.tempFilePath)

// If resuming, seek to end of file
if resumeSize > 0 {
try tempFile.seekToEnd()
}

try await self.httpGet(request: request, tempFile: tempFile, resumeSize: self.downloadedSize, numRetries: numRetries, expectedSize: expectedSize)

// Clean up and move the completed download to its final destination
tempFile.closeFile()

try Task.checkCancellation()
try FileManager.default.moveDownloadedFile(from: self.tempFilePath, to: self.destination)
self.downloadState.value = .completed(self.destination)
Expand Down Expand Up @@ -194,16 +194,16 @@ class Downloader: NSObject, ObservableObject {
guard let session else {
throw DownloadError.unexpectedError
}

// Create a new request with Range header for resuming
var newRequest = request
if resumeSize > 0 {
newRequest.setValue("bytes=\(resumeSize)-", forHTTPHeaderField: "Range")
}

// Start the download and get the byte stream
let (asyncBytes, response) = try await session.bytes(for: newRequest)

guard let httpResponse = response as? HTTPURLResponse else {
throw DownloadError.unexpectedError
}
Expand All @@ -213,7 +213,7 @@ class Downloader: NSObject, ObservableObject {

// Create a buffer to collect bytes before writing to disk
var buffer = Data(capacity: chunkSize)

var newNumRetries = numRetries
do {
for try await byte in asyncBytes {
Expand All @@ -231,7 +231,7 @@ class Downloader: NSObject, ObservableObject {
}
}
}

if !buffer.isEmpty {
try tempFile.write(contentsOf: buffer)
downloadedSize += buffer.count
Expand All @@ -243,10 +243,10 @@ class Downloader: NSObject, ObservableObject {
throw error
}
try await Task.sleep(nanoseconds: 1_000_000_000)

let config = URLSessionConfiguration.default
self.session = URLSession(configuration: config, delegate: self, delegateQueue: nil)

try await httpGet(
request: request,
tempFile: tempFile,
Expand All @@ -255,14 +255,14 @@ class Downloader: NSObject, ObservableObject {
expectedSize: expectedSize
)
}

// Verify the downloaded file size matches the expected size
let actualSize = try tempFile.seekToEnd()
if let expectedSize, expectedSize != actualSize {
throw DownloadError.unexpectedError
}
}

@discardableResult
func waitUntilDone() throws -> URL {
// It's either this, or stream the bytes ourselves (add to a buffer, save to disk, etc; boring and finicky)
Expand Down Expand Up @@ -321,7 +321,7 @@ extension FileManager {
if fileExists(atPath: dstURL.path()) {
try removeItem(at: dstURL)
}

let directoryURL = dstURL.deletingLastPathComponent()
try createDirectory(at: directoryURL, withIntermediateDirectories: true, attributes: nil)

Expand Down
2 changes: 1 addition & 1 deletion Sources/Hub/Hub.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public extension Hub {
case datasets
case spaces
}

struct Repo: Codable {
public let id: String
public let type: RepoType
Expand Down
Loading
Loading