7
7
from .exceptions import RepositoryNotFoundError , RepositoryFileNameNotFound
8
8
9
9
10
+ class Model :
11
+ def __init__ (
12
+ self ,
13
+ _id : str ,
14
+ id : str ,
15
+ likes : int ,
16
+ private : bool ,
17
+ downloads : int ,
18
+ tags : List [str ],
19
+ modelId : str ,
20
+ ):
21
+ self ._id = _id
22
+ self .id = id
23
+ self .likes = likes
24
+ self .private = private
25
+ self .downloads = downloads
26
+ self .tags = tags
27
+ self .modelId = modelId
28
+
29
+ def __str__ (self ):
30
+ return f"repo_id: { self .modelId } "
31
+
32
+
10
33
class BlobLfsInfo (TypedDict , total = False ):
11
34
size : int
12
35
sha256 : str
@@ -33,7 +56,6 @@ def __init__(
33
56
34
57
35
58
class ModelInfo :
36
-
37
59
def __init__ (
38
60
self ,
39
61
* ,
@@ -49,14 +71,14 @@ def __init__(
49
71
securityStatus : Optional [Dict ] = None ,
50
72
** kwargs ,
51
73
):
52
-
53
74
self .modelId = modelId
54
75
self .sha = sha
55
76
self .lastModified = lastModified
56
77
self .tags = tags
57
78
self .pipeline_tag = pipeline_tag
58
- self .siblings = [RepoFile (** x )
59
- for x in siblings ] if siblings is not None else []
79
+ self .siblings = (
80
+ [RepoFile (** x ) for x in siblings ] if siblings is not None else []
81
+ )
60
82
self .private = private
61
83
self .author = author
62
84
self .config = config
@@ -75,9 +97,9 @@ def model_info(
75
97
repo_id : str ,
76
98
files_metadata : bool = False ,
77
99
) -> ModelInfo :
78
-
79
- get_files_metadata = urllib .parse .urlencode (
80
- { 'blobs' : files_metadata }) if files_metadata else ""
100
+ get_files_metadata = (
101
+ urllib .parse .urlencode ({ "blobs" : files_metadata }) if files_metadata else ""
102
+ )
81
103
url = f"https://huggingface.co/api/models/{ repo_id } /?" + get_files_metadata
82
104
try :
83
105
response = urllib .request .urlopen (url )
@@ -86,7 +108,7 @@ def model_info(
86
108
except urllib .error .HTTPError as e :
87
109
if e .code == 401 :
88
110
raise RepositoryNotFoundError
89
- elif e .peek ().decode (' utf-8' , errors = ' ignore' ) == "Entry not found" :
111
+ elif e .peek ().decode (" utf-8" , errors = " ignore" ) == "Entry not found" :
90
112
raise RepositoryFileNameNotFound
91
113
else :
92
114
print (f"\n Error getting Info about the repo_id: { e } " )
@@ -95,54 +117,93 @@ def model_info(
95
117
print (f"\n Error getting Info about the repo_id: { e } " )
96
118
97
119
98
- def model_download (
99
- repo_id : str ,
100
- file_name : Union [str , List [str ]]
101
- ) -> str :
102
- ''' Download HF model and returns the Path of the Downloaded file'''
120
+ def model_download (repo_id : str , file_name : Union [str , List [str ]]) -> str :
121
+ """Download HF model and returns the Path of the Downloaded file"""
103
122
104
- # create a model dirictory to save the files neatly in one folder
105
- models_dir = Path (' ./models/' )
123
+ # create a model directory to save the files neatly in one folder
124
+ models_dir = Path (" ./models/" )
106
125
models_dir .mkdir (exist_ok = True )
107
126
destination_path = models_dir .joinpath (file_name )
108
127
109
- url = f' https://huggingface.co/{ repo_id } /resolve/main/{ file_name } '
128
+ url = f" https://huggingface.co/{ repo_id } /resolve/main/{ file_name } "
110
129
111
130
def reporthook (count , block_size , total_size ):
112
131
# Calculate the progress
113
132
downloaded_chunk = count * block_size
114
133
progress = (downloaded_chunk / total_size ) * 100
115
134
116
135
# print(downloaded_chunk // total_size)
117
- bar = '' .join (['=' if i <= progress / 2 else ' ' for i in range (50 )])
136
+ bar = "" .join (["=" if i <= progress / 2 else " " for i in range (50 )])
118
137
sys .stdout .write (
119
- f"\r [{ bar } ] { progress :.1f} % ({ downloaded_chunk / 1024 ** 2 :.2f} MB/{ total_size / 1024 ** 2 :.0f} MB)" )
138
+ f"\r [{ bar } ] { progress :.1f} % ({ downloaded_chunk / 1024 ** 2 :.2f} MB/{ total_size / 1024 ** 2 :.0f} MB)"
139
+ )
120
140
sys .stdout .flush ()
121
141
122
142
try :
123
143
print (f"[File Info] { destination_path } " )
124
144
# check if the file exists and matches the size of that in the network
125
- network_file_size = (urllib .request
126
- .urlopen (url )
127
- .info ().get ('Content-Length' , 0 ))
128
- if destination_path .is_file () \
129
- and destination_path .stat ().st_size == int (network_file_size ):
145
+ network_file_size = urllib .request .urlopen (url ).info ().get ("Content-Length" , 0 )
146
+ if destination_path .is_file () and destination_path .stat ().st_size == int (
147
+ network_file_size
148
+ ):
130
149
# raise FileNameAlreadyExists
131
150
return models_dir
132
151
133
- urllib .request .urlretrieve (
134
- url , destination_path , reporthook = reporthook )
152
+ urllib .request .urlretrieve (url , destination_path , reporthook = reporthook )
135
153
sys .stdout .write ("\n " )
136
154
print (f"File downloaded to { destination_path } " )
137
155
return models_dir
138
156
139
157
except urllib .error .HTTPError as e :
140
158
if e .code == 401 :
141
159
raise RepositoryNotFoundError
142
- elif e .peek ().decode (' utf-8' , errors = ' ignore' ) == "Entry not found" :
160
+ elif e .peek ().decode (" utf-8" , errors = " ignore" ) == "Entry not found" :
143
161
raise RepositoryFileNameNotFound
144
162
else :
145
163
print (f"\n Error downloading file: { e } " )
146
164
147
165
except Exception as e :
148
166
print (f"\n Error downloading file: { e } " )
167
+
168
+
169
+ def get_models () -> List [Model ]:
170
+ url = f"https://huggingface.co/api/models?filter=clip.cpp"
171
+ try :
172
+ response = urllib .request .urlopen (url )
173
+ data = json .load (response )
174
+ return [Model (** item ) for item in data ]
175
+ except urllib .error .HTTPError as e :
176
+ print (f"\n Error listing available models: { e } " )
177
+
178
+ except Exception as e :
179
+ print (f"\n Error listing available models: { e } " )
180
+
181
+
182
+ def available_models ():
183
+ if len (sys .argv ) > 1 and sys .argv [- 1 ] != "clip-cpp-models" :
184
+ repo_id = sys .argv [- 1 ]
185
+ repo = model_info (repo_id = repo_id , files_metadata = True )
186
+ print (f"Available models in repo { repo_id } :" )
187
+ for model in repo .siblings :
188
+ if model .rfilename .endswith (".bin" ):
189
+ name = model .rfilename
190
+ size = model .size / (1024 * 1024 )
191
+ print (f" model: { name } ({ size :.2f} MB)" )
192
+
193
+ return
194
+
195
+ models = get_models ()
196
+ print (
197
+ "Below are available models on HuggingFace Hub that you can use with the clip-cpp package.\n "
198
+ )
199
+ print ("Available models:" )
200
+ for model in models :
201
+ print (model )
202
+
203
+ print (
204
+ "\n You can pass one of the repo IDs above directly to `Clip()`, and it will download the smallest model in that repo automatically."
205
+ )
206
+ print (
207
+ "Alternatively, you can choose which to load from that repo by passing a value to `model_file` argument."
208
+ )
209
+ print ("\n To see model files in a repo, type `clip-cpp-models <repo_id>`" )
0 commit comments