Skip to content

Commit a0920c0

Browse files
committed
Merge branch 'development' of https://github.com/mlrun/functions into convert-to-uv
2 parents 8f55532 + 5af5eb8 commit a0920c0

File tree

8 files changed

+169
-22
lines changed

8 files changed

+169
-22
lines changed

modules/src/vllm_module/vllm_module.ipynb

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"metadata": {},
1818
"outputs": [],
1919
"source": [
20-
"import mlrun\n",
20+
"import mlrun\n"
2121
]
2222
},
2323
{
@@ -170,34 +170,31 @@
170170
"body = {\n",
171171
" \"model\": vllm_module.model,\n",
172172
" \"messages\": [{\"role\": \"user\", \"content\": \"what are the 3 countries with the most gpu as far as you know\"}],\n",
173-
" \"max_tokens\": vllm_module.max_tokens, # start smaller for testing\n",
173+
" \"max_tokens\": vllm_module.max_tokens, # start smaller for testing\n",
174174
"}\n",
175175
"\n",
176176
"resp = app.invoke(path=\"/v1/chat/completions\", body=body)"
177177
]
178178
},
179179
{
180180
"cell_type": "code",
181-
"execution_count": 29,
181+
"execution_count": 22,
182182
"id": "a459d5f8-dad0-4735-94c2-3801d4f94bb5",
183183
"metadata": {},
184184
"outputs": [
185185
{
186186
"name": "stdout",
187187
"output_type": "stream",
188188
"text": [
189-
"Raw response keys: dict_keys(['id', 'object', 'created', 'model', 'choices', 'service_tier', 'system_fingerprint', 'usage', 'prompt_logprobs', 'prompt_token_ids', 'kv_transfer_params'])\n",
190189
"\n",
191190
"assistant:\n",
192191
"\n",
193-
"As of July 2023, the three countries with the most scientists in articles that explain or discuss GPU contributions to AI are the United States, China, and India.\n",
194-
"The number of scientists is not the best measure of the number of GPUs. According to Practical Deep Learning forמות, China has 6,307 GPU-equipped tens of thousands of compute servers, the number of GPUs in the top 100 supercomputers is 6,492 (19th largest: 10,363), and the per capita number of GPUs invested by research institutions is high. From the total value perspective, the annual procurement increase of GPUs in China is estimated to be more than $40 billion. Similarly, the United States and India have significantly higher prices than China purely due to price controls.\n",
195-
"In summary, there is limited data to support the claim that GPU prices vary significantly between the three countries. However, China has a significant number of GPUs in use, and its computational resources are some of the largest in the world.\n"
192+
"As of the most commonly cited estimates, the three countries with the largest GPU capacity for AI workloads are the United States, China, and India.\n"
196193
]
197194
}
198195
],
199196
"source": [
200-
"data = resp.json()\n",
197+
"data = resp\n",
201198
"assistant_text = data[\"choices\"][0][\"message\"][\"content\"]\n",
202199
"\n",
203200
"print(\"\\nassistant:\\n\")\n",
@@ -207,7 +204,7 @@
207204
{
208205
"cell_type": "code",
209206
"execution_count": null,
210-
"id": "1de85b32-9c91-4609-9a63-0b38ed4fde65",
207+
"id": "957b5d21-7ade-4131-9100-878652c477fc",
211208
"metadata": {},
212209
"outputs": [],
213210
"source": []

modules/src/vllm_module/vllm_module.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,12 @@ def __init__(
5252
mem: str = "10G",
5353
port: int = 8000,
5454
dtype: str = "auto",
55-
tensor_parallel_size: Optional[int] = None,
5655
uvicorn_log_level: str = "info",
5756
max_tokens: int = 500,
5857
):
5958
if gpus < 1:
6059
raise ValueError("gpus must be >= 1")
6160

62-
if tensor_parallel_size is not None:
63-
if tensor_parallel_size < 1:
64-
raise ValueError("tensor_parallel_size must be >= 1")
65-
if tensor_parallel_size > gpus:
66-
raise ValueError(
67-
f"tensor_parallel_size ({tensor_parallel_size}) cannot be greater than gpus ({gpus})"
68-
)
69-
7061

7162

7263
if node_selector is None:
@@ -87,7 +78,6 @@ def __init__(
8778
self.node_selector = node_selector
8879
self.port = port
8980
self.dtype = dtype
90-
self.tensor_parallel_size = tensor_parallel_size
9181
self.uvicorn_log_level = uvicorn_log_level
9282
self.max_tokens = max_tokens
9383

@@ -117,8 +107,7 @@ def __init__(
117107
args += ["--uvicorn-log-level", self.uvicorn_log_level]
118108

119109
if self.gpus > 1:
120-
tps = self.tensor_parallel_size or self.gpus
121-
args += ["--tensor-parallel-size", str(tps)]
110+
args += ["--tensor-parallel-size", str(gpus)]
122111

123112
# For more than one GPU you should create a share volume for the multiple GPUs
124113
self.vllm_app.spec.volumes = [{"name": "dshm", "emptyDir": {"medium": "Memory"}}]

steps/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@
44
## Catalog
55

66
<!-- AUTOGEN:START (do not edit below) -->
7-
_No items found_
7+
| Name | Description | Class Name | Categories |
8+
| --- | --- | --- | --- |
9+
| [verify_schema](https://github.com/mlrun/functions/tree/development/steps/src/verify_schema) | Verifies the event is aligned with the provided schema | VerifySchema | data-preparation, model-serving, utilities |
810
<!-- AUTOGEN:END -->

steps/src/.gitkeep

Whitespace-only changes.

steps/src/verify_schema/item.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
apiVersion: v1
2+
categories:
3+
- data-preparation
4+
- model-serving
5+
- utilities
6+
description: Verifies the event is aligned with the provided schema
7+
example: verify_schema.ipynb
8+
generationDate: 2025-12-29:11-59
9+
hidden: false
10+
labels:
11+
author: Iguazio
12+
mlrunVersion: 1.10.0
13+
name: verify_schema
14+
className: VerifySchema
15+
defaultHandler:
16+
spec:
17+
filename: verify_schema.py
18+
image: mlrun/mlrun
19+
requirements:
20+
version: 1.0.0
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copyright 2025 Iguazio
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
from verify_schema import VerifySchema
17+
18+
class TestVerifySchema:
19+
def test_verify_schema(self):
20+
schema = ["id", "name", "active"]
21+
verifier = VerifySchema(schema=schema, allow_unexpected_keys=False)
22+
23+
# Test with valid event
24+
event = {
25+
"id": 1,
26+
"name": "Test Event",
27+
"active": True
28+
}
29+
result = verifier.do(event)
30+
assert result == event
31+
32+
# Test with missing key
33+
event_missing_key = {
34+
"id": 1,
35+
"name": "Test Event"
36+
}
37+
try:
38+
verifier.do(event_missing_key)
39+
except KeyError as e:
40+
assert "missing keys {'active'} in event" in str(e)
41+
42+
# Test with unexpected key
43+
event_unexpected_key = {
44+
"id": 1,
45+
"name": "Test Event",
46+
"active": True,
47+
"extra": "unexpected"
48+
}
49+
try:
50+
verifier.do(event_unexpected_key)
51+
except KeyError as e:
52+
assert "unexpected keys {'extra'} in event" in str(e)
53+
54+
def test_verify_schema_allow_unexpected(self):
55+
schema = ["id", "name", "active"]
56+
verifier = VerifySchema(schema=schema, allow_unexpected_keys=True)
57+
58+
# Test with valid event and unexpected key
59+
event = {
60+
"id": 1,
61+
"name": "Test Event",
62+
"active": True,
63+
"extra": "unexpected"
64+
}
65+
result = verifier.do(event)
66+
assert result == event
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"cells": [
3+
{
4+
"metadata": {},
5+
"cell_type": "code",
6+
"outputs": [],
7+
"execution_count": null,
8+
"source": "",
9+
"id": "556b36b9b89d0515"
10+
}
11+
],
12+
"metadata": {
13+
"kernelspec": {
14+
"display_name": "Python 3",
15+
"language": "python",
16+
"name": "python3"
17+
},
18+
"language_info": {
19+
"codemirror_mode": {
20+
"name": "ipython",
21+
"version": 2
22+
},
23+
"file_extension": ".py",
24+
"mimetype": "text/x-python",
25+
"name": "python",
26+
"nbconvert_exporter": "python",
27+
"pygments_lexer": "ipython2",
28+
"version": "2.7.6"
29+
}
30+
},
31+
"nbformat": 4,
32+
"nbformat_minor": 5
33+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2025 Iguazio
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
class VerifySchema:
17+
"""
18+
This step validates that an event dictionary contains exactly the keys defined in the schema,
19+
raising a KeyError if any are missing or unexpected.
20+
"""
21+
22+
def __init__(self, schema: list, allow_unexpected_keys: bool = False):
23+
self.schema = schema
24+
self.allow_unexpected_keys = allow_unexpected_keys
25+
26+
def do(self, event: dict):
27+
# Check if all keys in the expected schema are present in the event
28+
missing = set(self.schema) - set(event)
29+
if missing:
30+
raise KeyError(f"Schema verification failed: missing keys {missing} in event: {event}")
31+
32+
if self.allow_unexpected_keys:
33+
return event
34+
35+
# Check if there are any unexpected keys in the event
36+
unexpected = set(event) - set(self.schema)
37+
if unexpected:
38+
raise KeyError(f"Schema verification failed: unexpected keys {unexpected} in event: {event}")
39+
40+
return event

0 commit comments

Comments
 (0)