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, TransientError
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.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/cohere/transcribe/hub.rb', line 37 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 = if offline.nil? truthy_environment?(ENV.fetch("HF_HUB_OFFLINE", nil)) else offline != false end @resolution_guard = Mutex.new @resolution_memo = {} end |
Instance Attribute Details
#cache_dir ⇒ Object (readonly)
Returns the value of attribute cache_dir.
35 36 37 |
# File 'lib/cohere/transcribe/hub.rb', line 35 def cache_dir @cache_dir end |
#endpoint ⇒ Object (readonly)
Returns the value of attribute endpoint.
35 36 37 |
# File 'lib/cohere/transcribe/hub.rb', line 35 def endpoint @endpoint end |
Instance Method Details
#cached_file(repo_id, filename, revision: nil) ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/cohere/transcribe/hub.rb', line 157 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
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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/cohere/transcribe/hub.rb', line 80 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) if (cached = safe_cached_file(repository, destination)) normalize_cached_payload(repository, cached) return cached end 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| acquire_download_lock!(lock, download_lock_path(destination), destination) verify_cache_lock_identity!( download_lock_path(destination), lock, purpose: "Hub download" ) if (cached = safe_cached_file(repository, destination)) normalize_cached_payload(repository, cached) return cached end cleanup_download_temporaries(destination) Tempfile.create( [download_temporary_prefix(destination), ".download"], destination.dirname.to_s, binmode: true ) do |temporary| apply_cache_mode_if_supported(temporary, cache_payload_mode(destination.dirname)) request(uri, stream: temporary) temporary.flush temporary.fsync temporary.close File.rename(temporary.path, destination) end sync_directory(destination.dirname) end destination rescue SystemCallError => e raise Error, "Cannot cache #{repo_id}/#{filename}: #{e.}" end |
#list_files(repo_id, revision: nil) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/cohere/transcribe/hub.rb', line 128 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.to_s) siblings = payload.is_a?(Hash) ? payload["siblings"] : nil raise Error, "Hub returned no repository file list for #{repo_id}@#{commit}" unless siblings.is_a?(Array) files = siblings.filter_map do |item| name = item.is_a?(Hash) ? item["rfilename"] : nil name if name.is_a?(String) && !name.empty? end if files.empty? detail = siblings.empty? ? "an empty repository file list" : "no valid repository file entries" raise Error, "Hub returned #{detail} for #{repo_id}@#{commit}" end files.freeze rescue JSON::ParserError => e raise TransientError, "Invalid Hub response while listing #{repo_id.inspect}: #{e.}" end |
#offline? ⇒ Boolean
52 53 54 |
# File 'lib/cohere/transcribe/hub.rb', line 52 def offline? @offline end |
#resolve_revision(repo_id, revision = nil, filename: "config.json") ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/cohere/transcribe/hub.rb', line 56 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) if offline? cached = cached_revision(repo_id, requested, filename: filename) return cached if cached raise Error, "Hub offline mode has no cached #{filename} snapshot for #{repo_id.inspect} at #{requested.inspect}" end begin resolve_online_revision(repo_id, requested) rescue TransientError cached = cached_revision(repo_id, requested, filename: filename) raise unless cached cached end end |
#snapshot_path(repo_id, commit) ⇒ Object
150 151 152 153 154 155 |
# File 'lib/cohere/transcribe/hub.rb', line 150 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 |