Class: Cohere::Transcribe::Hub
- Inherits:
-
Object
- Object
- Cohere::Transcribe::Hub
- Defined in:
- lib/cohere/transcribe/hub.rb
Overview
Minimal Hugging Face Hub client used by the native Ruby runtime. It uses the standard Hub cache layout, so artifacts already fetched by other Hub clients are reused without copying multi-gigabyte model weights.
Defined Under Namespace
Classes: AuthenticationError, ConnectionError, Error, NotFoundError
Constant Summary collapse
- COMMIT_PATTERN =
/\A[0-9a-f]{40}\z/i- DEFAULT_ENDPOINT =
"https://huggingface.co"
Instance Attribute Summary collapse
-
#cache_dir ⇒ Object
readonly
Returns the value of attribute cache_dir.
-
#endpoint ⇒ Object
readonly
Returns the value of attribute endpoint.
Instance Method Summary collapse
- #cached_file(repo_id, filename, revision: nil) ⇒ Object
- #download(repo_id, filename, revision: nil) ⇒ Object
-
#initialize(cache_dir: nil, endpoint: nil, token: nil, offline: nil) ⇒ Hub
constructor
A new instance of Hub.
- #list_files(repo_id, revision: nil) ⇒ Object
- #offline? ⇒ Boolean
- #resolve_revision(repo_id, revision = nil, filename: "config.json") ⇒ Object
- #snapshot_path(repo_id, commit) ⇒ Object
Constructor Details
#initialize(cache_dir: nil, endpoint: nil, token: nil, offline: nil) ⇒ Hub
Returns a new instance of Hub.
26 27 28 29 30 31 32 33 |
# File 'lib/cohere/transcribe/hub.rb', line 26 def initialize(cache_dir: nil, endpoint: nil, token: nil, offline: nil) hf_home = ENV.fetch("HF_HOME", File.("~/.cache/huggingface")) @cache_dir = Pathname(cache_dir || ENV.fetch("HF_HUB_CACHE", File.join(hf_home, "hub"))). @endpoint = (endpoint || ENV.fetch("HF_ENDPOINT", DEFAULT_ENDPOINT)).sub(%r{/+\z}, "") @endpoint_uri = URI(@endpoint) @token = token || ENV["HF_TOKEN"] || cached_token(hf_home) @offline = offline.nil? ? truthy_environment?(ENV.fetch("HF_HUB_OFFLINE", nil)) : !!offline end |
Instance Attribute Details
#cache_dir ⇒ Object (readonly)
Returns the value of attribute cache_dir.
24 25 26 |
# File 'lib/cohere/transcribe/hub.rb', line 24 def cache_dir @cache_dir end |
#endpoint ⇒ Object (readonly)
Returns the value of attribute endpoint.
24 25 26 |
# File 'lib/cohere/transcribe/hub.rb', line 24 def endpoint @endpoint end |
Instance Method Details
#cached_file(repo_id, filename, revision: nil) ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/cohere/transcribe/hub.rb', line 132 def cached_file(repo_id, filename, revision: nil) validate_repo_id!(repo_id) validate_filename!(filename) validate_revision!(revision) if revision commit = if revision && COMMIT_PATTERN.match?(revision) revision.downcase else cached_revision(repo_id, revision || "main", filename: filename) end return unless commit repository = cache_dir.join(cache_repo_name(repo_id)) path = repository.join("snapshots", commit, filename) safe_cached_file(repository, path) end |
#download(repo_id, filename, revision: nil) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/cohere/transcribe/hub.rb', line 74 def download(repo_id, filename, revision: nil) validate_filename!(filename) commit = resolve_revision(repo_id, revision, filename: filename) repository = cache_dir.join(cache_repo_name(repo_id)) destination = repository.join("snapshots", commit, filename) return destination if safe_cached_file(repository, destination) prepare_cache_directory!(repository, destination.dirname) encoded_repo = repo_id.split("/").map { |part| URI.encode_www_form_component(part) }.join("/") encoded_filename = filename.split("/").map { |part| URI.encode_www_form_component(part) }.join("/") uri = URI("#{endpoint}/#{encoded_repo}/resolve/#{commit}/#{encoded_filename}") open_download_lock(download_lock_path(destination)) do |lock| raise Error, "Cannot acquire Hub download lock for #{destination}" unless lock.flock(File::LOCK_EX) return destination if safe_cached_file(repository, destination) cleanup_download_temporaries(destination) Tempfile.create( [download_temporary_prefix(destination), ".download"], destination.dirname.to_s, binmode: true ) do |temporary| request(uri, stream: temporary) temporary.flush temporary.fsync temporary.close File.rename(temporary.path, destination) end sync_directory(destination.dirname) end destination rescue Errno::EACCES, Errno::ENOSPC, Errno::EROFS => e raise Error, "Cannot cache #{repo_id}/#{filename}: #{e.}" end |
#list_files(repo_id, revision: nil) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/cohere/transcribe/hub.rb', line 109 def list_files(repo_id, revision: nil) commit = resolve_revision(repo_id, revision) encoded_repo = repo_id.split("/").map { |part| URI.encode_www_form_component(part) }.join("/") response = request(URI("#{endpoint}/api/models/#{encoded_repo}/revision/#{commit}")) payload = JSON.parse(response.body) siblings = payload["siblings"] raise Error, "Hub returned no repository file list for #{repo_id}@#{commit}" unless siblings.is_a?(Array) siblings.filter_map do |item| name = item.is_a?(Hash) ? item["rfilename"] : nil name if name.is_a?(String) end.freeze rescue JSON::ParserError => e raise Error, "Invalid Hub response while listing #{repo_id.inspect}: #{e.}" end |
#offline? ⇒ Boolean
35 36 37 |
# File 'lib/cohere/transcribe/hub.rb', line 35 def offline? @offline end |
#resolve_revision(repo_id, revision = nil, filename: "config.json") ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/cohere/transcribe/hub.rb', line 39 def resolve_revision(repo_id, revision = nil, filename: "config.json") validate_repo_id!(repo_id) requested = revision || "main" validate_revision!(requested) return requested.downcase if COMMIT_PATTERN.match?(requested) cached = cached_revision(repo_id, requested, filename: filename) if offline? return cached if cached raise Error, "Hub offline mode has no cached #{filename} snapshot for #{repo_id.inspect} at #{requested.inspect}" end encoded_repo = repo_id.split("/").map { |part| URI.encode_www_form_component(part) }.join("/") encoded_revision = URI.encode_www_form_component(requested) begin response = request(URI("#{endpoint}/api/models/#{encoded_repo}/revision/#{encoded_revision}")) rescue ConnectionError raise unless cached return cached end payload = JSON.parse(response.body) commit = payload["sha"] unless commit.is_a?(String) && COMMIT_PATTERN.match?(commit) raise Error, "Hub returned no immutable commit for #{repo_id.inspect} at #{requested.inspect}" end write_ref(repo_id, requested, commit.downcase) commit.downcase rescue JSON::ParserError => e raise Error, "Invalid Hub response while resolving #{repo_id.inspect}: #{e.}" end |
#snapshot_path(repo_id, commit) ⇒ Object
125 126 127 128 129 130 |
# File 'lib/cohere/transcribe/hub.rb', line 125 def snapshot_path(repo_id, commit) validate_repo_id!(repo_id) raise ArgumentError, "Invalid immutable Hub commit: #{commit.inspect}" unless commit.is_a?(String) && COMMIT_PATTERN.match?(commit) cache_dir.join(cache_repo_name(repo_id), "snapshots", commit) end |