huggingface / swift-transformers

Swift Package to implement a transformers-like API in Swift
Apache License 2.0
657 stars 70 forks source link

HubApi download progress is called but reports no progress #79

Closed davidkoski closed 5 months ago

davidkoski commented 6 months ago

See also #59 and #61

The progress callback on HubApi() no longer works – it is called over and over (unlike #59) but the progress is always 0. In particular the Downloader’s delegate method to observe progress uses the downloadTask.progress:

https://github.com/huggingface/swift-transformers/blob/main/Sources/Hub/Downloader.swift#L108

downloadState.value = .downloading(downloadTask.progress.fractionCompleted)

but the progress is always returning 0 (seemingly because it is indeterminate?):

(lldb) po downloadTask.progress
<NSProgress: 0x600002a19500> : Parent: 0x0 (portion: 0) / Fraction completed: 0.0000 / Completed: 0 of 100 
 <NSProgress: 0x600002a19880> : Parent: 0x600002a19500 (portion: 95) / Fraction completed: 0.0000 / Completed: 438280028 of -1 
 <NSProgress: 0x600002a1a480> : Parent: 0x600002a19500 (portion: 5) / Fraction completed: 0.0000 / Completed: 0 of 100 

However the totalBytesWritten and totalBytesExpected do contain the proper data to provide progress. It appears that this behavior changed when moving off the background download session, e.g. with #64.

ZachNagengast commented 6 months ago

Ah, we didn't see an issue in WhisperKit because we download multiple files at a time so one of the fractions looks ok (portion: 0) but I can confirm that we also see the 0 of 100 for (portion: 1), for individual file progress:

<NSProgress: 0x600001daf380> : Parent: 0x0 (portion: 0) / Fraction completed: 0.9545 / Completed: 21 of 22  
  <NSProgress: 0x600001d74680> : Parent: 0x600001daf380 (portion: 1) / Fraction completed: 0.0000 / Completed: 0 of 100

I'm not sure why -1 is coming back from this, especially since totalBytesExpectedToWrite is accurate, but a workaround could be special handling to use let progressFraction = totalBytesWritten / totalBytesExpectedToWrite when it is -1.

I also checked the headers and they have valid Content-Length as far as I can tell

    "Content-Length" =     (
        13476985472
    );
davidkoski commented 6 months ago

Yeah, agreed it is an odd one since the totalBytesExpected is set correctly -- I am not sure where else it would get the total amount :-)

pcuenca commented 6 months ago

Workaround applied in #83 by @maiqingqiang