lemonade-sdk 8.0.5__py3-none-any.whl → 8.0.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of lemonade-sdk might be problematic. Click here for more details.

@@ -1,10 +1,10 @@
1
1
  lemonade/__init__.py,sha256=W1Qk7r0rnQqFhPNHp6BIBT_q-OH3s-8Q_POoVfAmKW0,117
2
2
  lemonade/api.py,sha256=kGz8N_9TuN3peFG8fES0odN0bWR9itLNomlR-FC2z8k,5515
3
- lemonade/cache.py,sha256=djr2qgyUUAWlQv8FehU9qlNtCwK0IZqo82hcBDyZ3-A,2850
3
+ lemonade/cache.py,sha256=5iZbk273TiTMqK_vdzPOPYTo6VsWW2gNByOISA9zi1w,3002
4
4
  lemonade/cli.py,sha256=9Pcs3PcrWC2F8_pcBaz09xHUICIJTvpemBdPGyXkjIk,4395
5
5
  lemonade/sequence.py,sha256=KSH7BPsiyDKsOsg_ziQKEGsDwMmuO_YbgPRBxkZd0pw,13267
6
6
  lemonade/state.py,sha256=sdSezla7Cd7KYL90xY3p9kcNV4ndSyN6UvNLOr3vBMA,5261
7
- lemonade/version.py,sha256=obOXkQD52zgzH-mM2spS6LQ-gEWkuaiGpNTM_ISH0D8,22
7
+ lemonade/version.py,sha256=0UVFH05U_SSITAGCT0SSjcWSJnwORBaDn5ZSlvquMo8,22
8
8
  lemonade/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  lemonade/common/build.py,sha256=zTb0m1-kuUx6zw5QHp2SNnVuN6jOTMQ2FCdj9iH374U,6140
10
10
  lemonade/common/cli_helpers.py,sha256=hjBfXrTtFl8gmCFlL-ksviXR0mOcdPtTWVNKoEp3PG4,4993
@@ -21,51 +21,52 @@ lemonade/profilers/memory_tracker.py,sha256=1iuKt0FmNVYLDnOc-oZM8dX9TUksvoxO0m2E
21
21
  lemonade/profilers/profiler.py,sha256=Y5FSbc386bMlTVbqCuya9pYrso5aTthxahR1V_ZKQ9E,1902
22
22
  lemonade/tools/__init__.py,sha256=_6xRc-FHxmujoLjLjWtpYrWYEXtCSneSy-5ya01kyPk,53
23
23
  lemonade/tools/accuracy.py,sha256=9HCmczDngkBUuUrt49d2CkRo4J0qyWoFYs5cj20bGkg,11714
24
- lemonade/tools/adapter.py,sha256=HG54iMd6HDPZ4vnQIl7codq3HzffWbcHSIs_jVbNbhU,2958
24
+ lemonade/tools/adapter.py,sha256=Ex63Y1SPCOSV4M_QtzEn3YVd39d3yew0lpmEFgp8aH4,3169
25
25
  lemonade/tools/bench.py,sha256=aN5LMA_EH6-ZhAH3Gf26JYL7s0eKpUd3j-bReRhzvEY,10016
26
26
  lemonade/tools/humaneval.py,sha256=JbxuoOzvR4iyxZv4R6MI7a3gUt5ef_Jj6Ie-9VP2wzY,9531
27
27
  lemonade/tools/management_tools.py,sha256=U8GaJnjdXyQ9sw8UxBQMc7glpaLciaVphASaQS4kJsA,10202
28
28
  lemonade/tools/mmlu.py,sha256=c2QaIMDzjqxCvgHlMXmy_dP1sAFkwkDxL7RO2nogI6s,11071
29
29
  lemonade/tools/perplexity.py,sha256=eiaTZ3yhqF2pfwOffVbKKJLwjSri7Im2pC-tBJr7LLU,5638
30
- lemonade/tools/prompt.py,sha256=cy6McZeLgk26xG1dJEY-cYnY2x8FUdyOOSG86WfBKCg,9348
30
+ lemonade/tools/prompt.py,sha256=PyLksp1k8jsZsU7XBRK61k1DUHhbdLa20h-AP8Noh3w,9011
31
31
  lemonade/tools/tool.py,sha256=UsxVYukfm_iM3BfeGYPZxQlTK5UfDfDOl3RIyLr8A1Y,13256
32
32
  lemonade/tools/huggingface/bench.py,sha256=-mTfldCtquL4mspq8ykVwDc9Mut5Ecv_jHJnSb0CYGE,6734
33
33
  lemonade/tools/huggingface/load.py,sha256=KsSGOBBD-tNEIfYC8mCWV_jpnkjHMhN3juVmC1Ln4uQ,7745
34
- lemonade/tools/huggingface/utils.py,sha256=xybIWOEXHaMuw-nAEu3aITdvZSHcGKgZ9kFS5mIWcEg,13873
35
- lemonade/tools/llamacpp/bench.py,sha256=A1X8ULQMxPVsff-AdiUsbWQUKpx7U7nFRNHFJRPdv3Q,5946
36
- lemonade/tools/llamacpp/load.py,sha256=o3vVlefdxmdkHnuvFR3TOxiJkpNAuNFcs9Whfp24jpg,9236
34
+ lemonade/tools/huggingface/utils.py,sha256=j1S-IgjDsznUIVwkHSqqChmFyqIx9f3WcEelzohWwvU,13955
35
+ lemonade/tools/llamacpp/bench.py,sha256=GBUGOrcDUJdREAIM7GGs4VschqUe-mE_1-MbSUaDjic,4776
36
+ lemonade/tools/llamacpp/load.py,sha256=SKacK2n8LpC4DN4yALyEpV2c8_sgOv2G7t6Nlyu7XXg,6273
37
+ lemonade/tools/llamacpp/utils.py,sha256=35eir8PKtxVUDehgb2DJ9hUI0uSjijQgoDK6scmLl1E,22390
37
38
  lemonade/tools/oga/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- lemonade/tools/oga/bench.py,sha256=T3c40NevM3NA7CT98B6vBj1nXfdITDqpfMHYSjhjwpA,5061
39
+ lemonade/tools/oga/bench.py,sha256=PJXv4UchcS2YPwijNzef8DY4DSAKYxIYY1ycHuH3T34,5005
39
40
  lemonade/tools/oga/load.py,sha256=XSznW8lOX_KafSq5J5mIBJzj8YJEBpK0RFGcTE1wnE8,28317
40
- lemonade/tools/oga/utils.py,sha256=p7faMNfT-rLURC9t_s1S_STQRzzLADqbngUliTOOXeQ,16144
41
+ lemonade/tools/oga/utils.py,sha256=2N1htWM8QKp5g8nHPvk-w9ZYknSc6fWGXcACRkhsXic,16465
41
42
  lemonade/tools/quark/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
43
  lemonade/tools/quark/quark_load.py,sha256=FJ4LJKTToZbHHWVEOBLadae1a3jCnnY4KvXySHbkJMA,5589
43
44
  lemonade/tools/quark/quark_quantize.py,sha256=hwoaXhpBIORvJ16MvewphPkaDEQn3BAgXq5o82Gc-_s,16599
44
45
  lemonade/tools/report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
46
  lemonade/tools/report/llm_report.py,sha256=bVHhwCINA-Ok2EdSwAsLubsc83N3KWOVuwTguw7jDcE,6676
46
- lemonade/tools/report/table.py,sha256=wJFzKtlmGQH0RQ5O9nevtpMe_-zQ-8zNOndINQuzsjM,27793
47
+ lemonade/tools/report/table.py,sha256=ssqy1bZqF-wptNzKEOj6_9REtCNZyXO8R5vakAtg3R4,27973
47
48
  lemonade/tools/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
- lemonade/tools/server/llamacpp.py,sha256=e1MYKSJBu-jlOE5GQSBsC9CUPAeqw5wXXxoxBKA5zb8,20038
49
- lemonade/tools/server/serve.py,sha256=Pp_w4iuRMkpJLF-XrTsBIBrSNBQIOl8PRZC_Cj4URnU,57334
49
+ lemonade/tools/server/llamacpp.py,sha256=OP0j74QcowEu3zFEcrKIsBbGDOFemBXS5F5DC6oQHaI,18853
50
+ lemonade/tools/server/serve.py,sha256=SXc0qSh-jKS72GlUsuksT7Lov8p3FatgbbycNmHsUfM,57465
50
51
  lemonade/tools/server/tool_calls.py,sha256=xrAlQwKG-nv2xLlf8f9CDSaUbyMn8ZtHkds9iZLG9K8,5230
51
- lemonade/tools/server/tray.py,sha256=4Kf3x8YfRaItPW7lxlEwerD7c5Q2snzcNk3ZrEoae58,17259
52
+ lemonade/tools/server/tray.py,sha256=yoGCM8j_2KzPqo-AlYiauWd8QR56yp6jW6HZ9921Ydg,17525
52
53
  lemonade/tools/server/webapp.py,sha256=8Das5yXOaSBLZmSZ_eddJajQFxBhvl5D6GI_hHlGbE0,1040
53
54
  lemonade/tools/server/static/favicon.ico,sha256=hMmP9qGJNeZ0mFS86JIqPbZstXMZn0Z76_HfHQpREAU,126745
54
- lemonade/tools/server/static/styles.css,sha256=jXFPIHPrhRz_CJyRJrYusAECSDTO00sKUu7ajrQgFuA,24655
55
- lemonade/tools/server/static/webapp.html,sha256=tmwASvULb3d2_NfHEH9rKbEEJl3D7ygXjaCLVYkyWbg,35969
55
+ lemonade/tools/server/static/styles.css,sha256=JmH9LRGB4HGNCxH14owBrUNNBlzx3cVvB3JJ-xJqDqc,26453
56
+ lemonade/tools/server/static/webapp.html,sha256=8khNmsiy4UdjJDkJW3cFeJkmXUR8RQucvCuuka5SNrQ,36230
56
57
  lemonade/tools/server/utils/port.py,sha256=XnIg2qS73QRrsJn6LgHcrJPmku30Tv6vsYcBVMj82K4,2186
57
58
  lemonade/tools/server/utils/system_tray.py,sha256=b9lvNv9chJKQxvmH7qzAuUe6H9HsLu7pdHFqGlAJaL0,12654
58
59
  lemonade/tools/server/utils/thread.py,sha256=pK9K_6DNWoQ78NArkAX3Ym2WsxLnCs9sKTk6TitlYnI,2804
59
60
  lemonade_install/__init__.py,sha256=26zohKg2jgr_5y7tObduWMYQg8zCTWMZHL8lfi2zZVQ,40
60
61
  lemonade_install/install.py,sha256=DJWR36QSjZtvEwRjYPNSjhYgoxLjI_6OPrCMZjL0ChY,28263
61
- lemonade_sdk-8.0.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
62
- lemonade_sdk-8.0.5.dist-info/licenses/NOTICE.md,sha256=B8lEqi4QE41J9ljz4Riv2JgHD1v8GCZE6nNBHO3KIA0,2135
62
+ lemonade_sdk-8.0.6.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
63
+ lemonade_sdk-8.0.6.dist-info/licenses/NOTICE.md,sha256=B8lEqi4QE41J9ljz4Riv2JgHD1v8GCZE6nNBHO3KIA0,2135
63
64
  lemonade_server/cli.py,sha256=2Un5uLK04fIxlfcTiZ0T_EWbbaq2tYymkUHNFeuvB7g,16041
64
- lemonade_server/model_manager.py,sha256=0HqLR38uOu_hxRWVYQ_P6YmwaR-jkDuaAqGYo60X8C0,16702
65
+ lemonade_server/model_manager.py,sha256=FfF3z4IpMZqMk_yIo2LHiE76xg7ybROHvi6lcx-0gvE,10754
65
66
  lemonade_server/pydantic_models.py,sha256=rp_FFhoTwg6jNmgol-kShwffnRDGbt7jTbIeELvgOIo,2876
66
- lemonade_server/server_models.json,sha256=Y-j9KAvHmfv77welC0rfRao4inLBce6AVySb-oy_uNE,7519
67
- lemonade_sdk-8.0.5.dist-info/METADATA,sha256=e2w0jPyEnyk-SeLAbYZgeGldq-2CQHm9Hly_mQgZ8uo,15224
68
- lemonade_sdk-8.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
69
- lemonade_sdk-8.0.5.dist-info/entry_points.txt,sha256=gJppn0ETtXXR6ceKWEIRdk42kMC7ps59EmU3NCPyPUk,144
70
- lemonade_sdk-8.0.5.dist-info/top_level.txt,sha256=10ap5GNiPhalO4V50LRoxA1FqRT9g3Xkia6BITu880k,42
71
- lemonade_sdk-8.0.5.dist-info/RECORD,,
67
+ lemonade_server/server_models.json,sha256=wVyjusS5KkOhlQIl1tCnTR4YYbVm7mLU2rHSFk_39hI,7890
68
+ lemonade_sdk-8.0.6.dist-info/METADATA,sha256=g7dOWZPRb0PEyK4UZpVBPnm1LGfZGlkjrdcNfJ_DO_g,15230
69
+ lemonade_sdk-8.0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
70
+ lemonade_sdk-8.0.6.dist-info/entry_points.txt,sha256=gJppn0ETtXXR6ceKWEIRdk42kMC7ps59EmU3NCPyPUk,144
71
+ lemonade_sdk-8.0.6.dist-info/top_level.txt,sha256=10ap5GNiPhalO4V50LRoxA1FqRT9g3Xkia6BITu880k,42
72
+ lemonade_sdk-8.0.6.dist-info/RECORD,,
@@ -6,31 +6,13 @@ import huggingface_hub
6
6
  from importlib.metadata import distributions
7
7
  from lemonade_server.pydantic_models import PullConfig
8
8
  from lemonade.cache import DEFAULT_CACHE_DIR
9
+ from lemonade.tools.llamacpp.utils import parse_checkpoint, download_gguf
9
10
 
10
11
  USER_MODELS_FILE = os.path.join(DEFAULT_CACHE_DIR, "user_models.json")
11
12
 
12
13
 
13
14
  class ModelManager:
14
15
 
15
- @staticmethod
16
- def parse_checkpoint(checkpoint: str) -> tuple[str, str | None]:
17
- """
18
- Parse a checkpoint string that may contain a variant separated by a colon.
19
-
20
- For GGUF models, the format is "repository:variant" (e.g., "unsloth/Qwen3-0.6B-GGUF:Q4_0").
21
- For other models, there is no variant.
22
-
23
- Args:
24
- checkpoint: The checkpoint string, potentially with variant
25
-
26
- Returns:
27
- tuple: (base_checkpoint, variant) where variant is None if no colon is present
28
- """
29
- if ":" in checkpoint:
30
- base_checkpoint, variant = checkpoint.split(":", 1)
31
- return base_checkpoint, variant
32
- return checkpoint, None
33
-
34
16
  @property
35
17
  def supported_models(self) -> dict:
36
18
  """
@@ -98,7 +80,7 @@ class ModelManager:
98
80
  downloaded_models = {}
99
81
  downloaded_checkpoints = self.downloaded_hf_checkpoints
100
82
  for model in self.supported_models:
101
- base_checkpoint = self.parse_checkpoint(
83
+ base_checkpoint = parse_checkpoint(
102
84
  self.supported_models[model]["checkpoint"]
103
85
  )[0]
104
86
  if base_checkpoint in downloaded_checkpoints:
@@ -113,132 +95,6 @@ class ModelManager:
113
95
  """
114
96
  return self.filter_models_by_backend(self.downloaded_models)
115
97
 
116
- def identify_gguf_models(
117
- self, checkpoint: str, variant: str, mmproj: str
118
- ) -> tuple[dict, list[str]]:
119
- """
120
- Identifies the GGUF model files in the repository that match the variant.
121
- """
122
-
123
- hint = """
124
- The CHECKPOINT:VARIANT scheme is used to specify model files in Hugging Face repositories.
125
-
126
- The VARIANT format can be one of several types:
127
- 1. Full filename: exact file to download
128
- 2. None/empty: gets the first .gguf file in the repository (excludes mmproj files)
129
- 3. Quantization variant: find a single file ending with the variant name (case insensitive)
130
- 4. Folder name: downloads all .gguf files in the folder that matches the variant name (case insensitive)
131
-
132
- Examples:
133
- - "unsloth/Qwen3-8B-GGUF:qwen3.gguf" -> downloads "qwen3.gguf"
134
- - "unsloth/Qwen3-30B-A3B-GGUF" -> downloads "Qwen3-30B-A3B-GGUF.gguf"
135
- - "unsloth/Qwen3-8B-GGUF:Q4_1" -> downloads "Qwen3-8B-GGUF-Q4_1.gguf"
136
- - "unsloth/Qwen3-30B-A3B-GGUF:Q4_0" -> downloads all files in "Q4_0/" folder
137
- """
138
-
139
- repo_files = huggingface_hub.list_repo_files(checkpoint)
140
- sharded_files = []
141
-
142
- # (case 1) If variant ends in .gguf, use it directly
143
- if variant and variant.endswith(".gguf"):
144
- variant_name = variant
145
- if variant_name not in repo_files:
146
- raise ValueError(
147
- f"File {variant} not found in Hugging Face repository {checkpoint}. {hint}"
148
- )
149
- # (case 2) If no variant is provided, get the first .gguf file in the repository
150
- elif variant is None:
151
- all_variants = [
152
- f for f in repo_files if f.endswith(".gguf") and "mmproj" not in f
153
- ]
154
- if len(all_variants) == 0:
155
- raise ValueError(
156
- f"No .gguf files found in Hugging Face repository {checkpoint}. {hint}"
157
- )
158
- variant_name = all_variants[0]
159
- else:
160
- # (case 3) Find a single file ending with the variant name (case insensitive)
161
- end_with_variant = [
162
- f
163
- for f in repo_files
164
- if f.lower().endswith(f"{variant}.gguf".lower())
165
- and "mmproj" not in f.lower()
166
- ]
167
- if len(end_with_variant) == 1:
168
- variant_name = end_with_variant[0]
169
- elif len(end_with_variant) > 1:
170
- raise ValueError(
171
- f"Multiple .gguf files found for variant {variant}, but only one is allowed. {hint}"
172
- )
173
- # (case 4) Check whether the variant corresponds to a folder with sharded files (case insensitive)
174
- else:
175
- sharded_files = [
176
- f
177
- for f in repo_files
178
- if f.endswith(".gguf")
179
- and f.lower().startswith(f"{variant}/".lower())
180
- ]
181
-
182
- if not sharded_files:
183
- raise ValueError(
184
- f"No .gguf files found for variant {variant}. {hint}"
185
- )
186
-
187
- # Sort to ensure consistent ordering
188
- sharded_files.sort()
189
-
190
- # Use first file as primary (this is how llamacpp handles it)
191
- variant_name = sharded_files[0]
192
-
193
- core_files = {"variant": variant_name}
194
-
195
- # If there is a mmproj file, add it to the patterns
196
- if mmproj:
197
- if mmproj not in repo_files:
198
- raise ValueError(
199
- f"The provided mmproj file {mmproj} was not found in {checkpoint}."
200
- )
201
- core_files["mmproj"] = mmproj
202
-
203
- return core_files, sharded_files
204
-
205
- def download_gguf(self, model_config: PullConfig) -> dict:
206
- """
207
- Downloads the GGUF file for the given model configuration.
208
-
209
- For sharded models, if the variant points to a folder (e.g. Q4_0), all files in that folder
210
- will be downloaded but only the first file will be returned for loading.
211
- """
212
-
213
- # This code handles all cases by constructing the appropriate filename or pattern
214
- checkpoint, variant = self.parse_checkpoint(model_config.checkpoint)
215
-
216
- # Identify the GGUF model files in the repository that match the variant
217
- core_files, sharded_files = self.identify_gguf_models(
218
- checkpoint, variant, model_config.mmproj
219
- )
220
-
221
- # Download the files
222
- snapshot_folder = huggingface_hub.snapshot_download(
223
- repo_id=checkpoint,
224
- allow_patterns=list(core_files.values()) + sharded_files,
225
- )
226
-
227
- # Ensure we downloaded all expected files
228
- for file in list(core_files.values()) + sharded_files:
229
- expected_path = os.path.join(snapshot_folder, file)
230
- if not os.path.exists(expected_path):
231
- raise ValueError(
232
- f"Hugging Face snapshot download for {model_config.checkpoint} "
233
- f"expected file {file} not found at {expected_path}"
234
- )
235
-
236
- # Return a dict of the full path of the core GGUF files
237
- return {
238
- file_name: os.path.join(snapshot_folder, file_path)
239
- for file_name, file_path in core_files.items()
240
- }
241
-
242
98
  def download_models(
243
99
  self,
244
100
  models: list[str],
@@ -317,7 +173,7 @@ class ModelManager:
317
173
  print(f"Downloading {model} ({checkpoint_to_download})")
318
174
 
319
175
  if "gguf" in checkpoint_to_download.lower():
320
- self.download_gguf(gguf_model_config)
176
+ download_gguf(gguf_model_config.checkpoint, gguf_model_config.mmproj)
321
177
  else:
322
178
  huggingface_hub.snapshot_download(repo_id=checkpoint_to_download)
323
179
 
@@ -373,7 +229,7 @@ class ModelManager:
373
229
  print(f"Deleting {model_name} ({checkpoint})")
374
230
 
375
231
  # Handle GGUF models that have the format "checkpoint:variant"
376
- base_checkpoint = self.parse_checkpoint(checkpoint)[0]
232
+ base_checkpoint = parse_checkpoint(checkpoint)[0]
377
233
 
378
234
  try:
379
235
  # Get the local path using snapshot_download with local_files_only=True
@@ -213,5 +213,16 @@
213
213
  "recipe": "llamacpp",
214
214
  "suggested": false,
215
215
  "labels": ["reranking"]
216
+ },
217
+ "Devstral-Small-2507-GGUF":{
218
+ "checkpoint": "mistralai/Devstral-Small-2507_gguf:Q4_K_M",
219
+ "recipe": "llamacpp",
220
+ "suggested": true
221
+ },
222
+ "Qwen2.5-Coder-32B-Instruct-GGUF": {
223
+ "checkpoint": "Qwen/Qwen2.5-Coder-32B-Instruct-GGUF:Q4_K_M",
224
+ "recipe": "llamacpp",
225
+ "suggested": true,
226
+ "labels": ["reasoning"]
216
227
  }
217
228
  }