Skip to content

Commit 809b660

Browse files
committed
Merge remote-tracking branch 'origin' into cherry-pick
2 parents 4297971 + 3d17823 commit 809b660

File tree

10 files changed

+717
-231
lines changed

10 files changed

+717
-231
lines changed

tests/conftest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,5 +336,8 @@ def unprivileged_model_namespace(
336336
request.getfixturevalue(argname="enabled_modelmesh_in_dsc")
337337
ns_kwargs["model_mesh_enabled"] = True
338338

339+
if (_dashboard_label := request.param.get("dashboard-label")) is not None:
340+
ns_kwargs["add_dashboard_label"] = _dashboard_label
341+
339342
with create_ns(**ns_kwargs) as ns:
340343
yield ns

tests/model_explainability/lm_eval/conftest.py

Lines changed: 173 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
from typing import Generator
1+
from typing import Generator, Any
22

33
import pytest
4+
from ocp_resources.route import Route
5+
from ocp_resources.service import Service
46
from pytest import FixtureRequest
57
from kubernetes.dynamic import DynamicClient
68
from ocp_resources.config_map import ConfigMap
@@ -12,7 +14,25 @@
1214
from ocp_resources.resource import ResourceEditor
1315
from pytest_testconfig import py_config
1416

15-
from utilities.constants import Labels, Timeout, Annotations
17+
from utilities.constants import Labels, Timeout, Annotations, Protocols
18+
19+
VLLM_EMULATOR: str = "vllm-emulator"
20+
VLLM_EMULATOR_PORT: int = 8000
21+
LMEVALJOB_NAME: str = "lmeval-test-job"
22+
23+
24+
@pytest.fixture(scope="function")
25+
def lmevaljob_hf_pod(admin_client: DynamicClient, lmevaljob_hf: LMEvalJob) -> Generator[Pod, Any, Any]:
26+
lmeval_pod = Pod(
27+
client=admin_client,
28+
namespace=lmevaljob_hf.namespace,
29+
name=lmevaljob_hf.name,
30+
)
31+
32+
# TODO: Check if we can rely on LMEvalJob instead of pod
33+
lmeval_pod.wait(timeout=Timeout.TIMEOUT_2MIN)
34+
35+
yield lmeval_pod
1636

1737

1838
@pytest.fixture(scope="function")
@@ -26,9 +46,29 @@ def lmevaljob_hf(
2646
model="hf",
2747
model_args=[{"name": "pretrained", "value": "google/flan-t5-base"}],
2848
task_list={
49+
"custom": {
50+
"systemPrompts": [
51+
{"name": "sp_0", "value": "Be concise. At every point give the shortest acceptable answer."}
52+
],
53+
"templates": [
54+
{
55+
"name": "tp_0",
56+
"value": '{ "__type__": "input_output_template", '
57+
'"input_format": "{text_a_type}: {text_a}\\n'
58+
'{text_b_type}: {text_b}", '
59+
'"output_format": "{label}", '
60+
'"target_prefix": '
61+
'"The {type_of_relation} class is ", '
62+
'"instruction": "Given a {text_a_type} and {text_b_type} '
63+
'classify the {type_of_relation} of the {text_b_type} to one of {classes}.",'
64+
' "postprocessors": [ "processors.take_first_non_empty_line",'
65+
' "processors.lower_case_till_punc" ] }',
66+
}
67+
],
68+
},
2969
"taskRecipes": [
30-
{"card": {"name": "cards.wnli"}, "template": "templates.classification.multi_class.relation.default"}
31-
]
70+
{"card": {"name": "cards.wnli"}, "systemPrompt": {"ref": "sp_0"}, "template": {"ref": "tp_0"}}
71+
],
3272
},
3373
log_samples=True,
3474
allow_online=True,
@@ -44,10 +84,10 @@ def lmevaljob_local_offline(
4484
model_namespace: Namespace,
4585
patched_trustyai_operator_configmap_allow_online: ConfigMap,
4686
lmeval_data_downloader_pod: Pod,
47-
) -> Generator[LMEvalJob, None, None]:
87+
) -> Generator[LMEvalJob, Any, Any]:
4888
with LMEvalJob(
4989
client=admin_client,
50-
name="lmeval-test",
90+
name=LMEVALJOB_NAME,
5191
namespace=model_namespace.name,
5292
model="hf",
5393
model_args=[{"name": "pretrained", "value": "/opt/app-root/src/hf_home/flan"}],
@@ -68,7 +108,58 @@ def lmevaljob_local_offline(
68108

69109

70110
@pytest.fixture(scope="function")
71-
def patched_trustyai_operator_configmap_allow_online(admin_client: DynamicClient) -> Generator[ConfigMap, None, None]:
111+
def lmevaljob_vllm_emulator_pod(
112+
admin_client: DynamicClient, lmevaljob_vllm_emulator: LMEvalJob
113+
) -> Generator[Pod, Any, Any]:
114+
lmeval_pod = Pod(
115+
client=admin_client,
116+
namespace=lmevaljob_vllm_emulator.namespace,
117+
name=lmevaljob_vllm_emulator.name,
118+
)
119+
120+
# TODO: Check if we can rely on LMEvalJob instead of pod
121+
lmeval_pod.wait(timeout=Timeout.TIMEOUT_2MIN)
122+
123+
yield lmeval_pod
124+
125+
126+
@pytest.fixture(scope="function")
127+
def lmevaljob_vllm_emulator(
128+
admin_client: DynamicClient,
129+
model_namespace: Namespace,
130+
patched_trustyai_operator_configmap_allow_online: ConfigMap,
131+
vllm_emulator_deployment: Deployment,
132+
vllm_emulator_service: Service,
133+
vllm_emulator_route: Route,
134+
) -> Generator[LMEvalJob, Any, Any]:
135+
with LMEvalJob(
136+
client=admin_client,
137+
namespace=model_namespace.name,
138+
name=LMEVALJOB_NAME,
139+
model="local-completions",
140+
task_list={"taskNames": ["arc_easy"]},
141+
log_samples=True,
142+
batch_size="1",
143+
allow_online=True,
144+
allow_code_execution=False,
145+
outputs={"pvcManaged": {"size": "5Gi"}},
146+
model_args=[
147+
{"name": "model", "value": "emulatedModel"},
148+
{
149+
"name": "base_url",
150+
"value": f"http://{vllm_emulator_service.name}:{str(VLLM_EMULATOR_PORT)}/v1/completions",
151+
},
152+
{"name": "num_concurrent", "value": "1"},
153+
{"name": "max_retries", "value": "3"},
154+
{"name": "tokenized_requests", "value": "False"},
155+
{"name": "tokenizer", "value": "ibm-granite/granite-guardian-3.1-8b"},
156+
],
157+
) as job:
158+
yield job
159+
160+
161+
@pytest.fixture(scope="function")
162+
def patched_trustyai_operator_configmap_allow_online(admin_client: DynamicClient) -> Generator[ConfigMap, Any, Any]:
72163
namespace: str = py_config["applications_namespace"]
73164
trustyai_service_operator: str = "trustyai-service-operator"
74165

@@ -99,7 +190,7 @@ def patched_trustyai_operator_configmap_allow_online(admin_client: DynamicClient
99190
@pytest.fixture(scope="function")
100191
def lmeval_data_pvc(
101192
admin_client: DynamicClient, model_namespace: Namespace
102-
) -> Generator[PersistentVolumeClaim, None, None]:
193+
) -> Generator[PersistentVolumeClaim, Any, Any]:
103194
with PersistentVolumeClaim(
104195
client=admin_client,
105196
name="lmeval-data",
@@ -117,7 +208,7 @@ def lmeval_data_downloader_pod(
117208
admin_client: DynamicClient,
118209
model_namespace: Namespace,
119210
lmeval_data_pvc: PersistentVolumeClaim,
120-
) -> Generator[Pod, None, None]:
211+
) -> Generator[Pod, Any, Any]:
121212
with Pod(
122213
client=admin_client,
123214
namespace=model_namespace.name,
@@ -143,3 +234,76 @@ def lmeval_data_downloader_pod(
143234
) as pod:
144235
pod.wait_for_status(status=Pod.Status.SUCCEEDED, timeout=Timeout.TIMEOUT_10MIN)
145236
yield pod
237+
238+
239+
@pytest.fixture(scope="function")
240+
def vllm_emulator_deployment(
241+
admin_client: DynamicClient, model_namespace: Namespace
242+
) -> Generator[Deployment, Any, Any]:
243+
label = {"app": VLLM_EMULATOR}
244+
with Deployment(
245+
client=admin_client,
246+
namespace=model_namespace.name,
247+
name=VLLM_EMULATOR,
248+
label=label,
249+
selector={"matchLabels": label},
250+
template={
251+
"metadata": {
252+
"labels": {
253+
"app": VLLM_EMULATOR,
254+
"maistra.io/expose-route": "true",
255+
},
256+
"name": VLLM_EMULATOR,
257+
},
258+
"spec": {
259+
"containers": [
260+
{
261+
"image": "quay.io/trustyai_testing/vllm_emulator"
262+
"@sha256:4214f31bff9de6cc723da23324fb8974cea8abadcab621d85a97a3503cabbdc6",
263+
"name": "vllm-emulator",
264+
"securityContext": {
265+
"allowPrivilegeEscalation": False,
266+
"capabilities": {"drop": ["ALL"]},
267+
"seccompProfile": {"type": "RuntimeDefault"},
268+
},
269+
}
270+
]
271+
},
272+
},
273+
replicas=1,
274+
) as deployment:
275+
yield deployment
276+
277+
278+
@pytest.fixture(scope="function")
279+
def vllm_emulator_service(
280+
admin_client: DynamicClient, model_namespace: Namespace, vllm_emulator_deployment: Deployment
281+
) -> Generator[Service, Any, Any]:
282+
with Service(
283+
client=admin_client,
284+
namespace=vllm_emulator_deployment.namespace,
285+
name=f"{VLLM_EMULATOR}-service",
286+
ports=[
287+
{
288+
"name": f"{VLLM_EMULATOR}-endpoint",
289+
"port": VLLM_EMULATOR_PORT,
290+
"protocol": Protocols.TCP,
291+
"targetPort": VLLM_EMULATOR_PORT,
292+
}
293+
],
294+
selector={"app": VLLM_EMULATOR},
295+
) as service:
296+
yield service
297+
298+
299+
@pytest.fixture(scope="function")
300+
def vllm_emulator_route(
301+
admin_client: DynamicClient, model_namespace: Namespace, vllm_emulator_service: Service
302+
) -> Generator[Route, Any, Any]:
303+
with Route(
304+
client=admin_client,
305+
namespace=vllm_emulator_service.namespace,
306+
name=VLLM_EMULATOR,
307+
service=vllm_emulator_service.name,
308+
) as route:
309+
yield route

tests/model_explainability/lm_eval/test_lm_eval.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import pytest
2-
from ocp_resources.pod import Pod
32

43
from tests.model_explainability.lm_eval.utils import verify_lmevaljob_running
54
from utilities.constants import Timeout
@@ -9,25 +8,22 @@
98
"model_namespace",
109
[
1110
pytest.param(
12-
{"name": "lmevaljob-hf"},
11+
{"name": "test-lmeval-huggingface"},
1312
)
1413
],
1514
indirect=True,
1615
)
1716
@pytest.mark.smoke
18-
def test_lmeval_huggingface_model(admin_client, model_namespace, lmevaljob_hf):
17+
def test_lmeval_huggingface_model(admin_client, model_namespace, lmevaljob_hf_pod):
1918
"""Basic test that verifies that LMEval can run successfully pulling a model from HuggingFace."""
20-
lmevaljob_pod = Pod(
21-
client=admin_client, name=lmevaljob_hf.name, namespace=lmevaljob_hf.namespace, wait_for_resource=True
22-
)
23-
lmevaljob_pod.wait_for_status(status=lmevaljob_pod.Status.SUCCEEDED, timeout=Timeout.TIMEOUT_10MIN)
19+
lmevaljob_hf_pod.wait_for_status(status=lmevaljob_hf_pod.Status.SUCCEEDED, timeout=Timeout.TIMEOUT_10MIN)
2420

2521

2622
@pytest.mark.parametrize(
2723
"model_namespace, lmeval_data_downloader_pod, lmevaljob_local_offline",
2824
[
2925
pytest.param(
30-
{"name": "lmevaljob-local-offline-builtin"},
26+
{"name": "test-lmeval-local-offline-builtin"},
3127
{
3228
"image": "quay.io/trustyai_testing/lmeval-assets-flan-arceasy"
3329
"@sha256:11cc9c2f38ac9cc26c4fab1a01a8c02db81c8f4801b5d2b2b90f90f91b97ac98"
@@ -51,7 +47,7 @@ def test_lmeval_local_offline_builtin_tasks_flan_arceasy(
5147
"model_namespace, lmeval_data_downloader_pod, lmevaljob_local_offline",
5248
[
5349
pytest.param(
54-
{"name": "lmevaljob-local-offline-unitxt"},
50+
{"name": "test-lmeval-local-offline-unitxt"},
5551
{
5652
"image": "quay.io/trustyai_testing/lmeval-assets-flan-20newsgroups"
5753
"@sha256:3778c15079f11ef338a82ee35ae1aa43d6db52bac7bbfdeab343ccabe2608a0c"
@@ -61,7 +57,7 @@ def test_lmeval_local_offline_builtin_tasks_flan_arceasy(
6157
"taskRecipes": [
6258
{
6359
"card": {"name": "cards.20_newsgroups_short"},
64-
"template": "templates.classification.multi_class.title",
60+
"template": {"name": "templates.classification.multi_class.title"},
6561
}
6662
]
6763
}
@@ -78,3 +74,19 @@ def test_lmeval_local_offline_unitxt_tasks_flan_20newsgroups(
7874
):
7975
"""Test that verifies that LMEval can run successfully in local, offline mode using unitxt"""
8076
verify_lmevaljob_running(client=admin_client, lmevaljob=lmevaljob_local_offline)
77+
78+
79+
@pytest.mark.parametrize(
80+
"model_namespace",
81+
[
82+
pytest.param(
83+
{"name": "test-lmeval-vllm"},
84+
)
85+
],
86+
indirect=True,
87+
)
88+
def test_lmeval_vllm_emulator(admin_client, model_namespace, lmevaljob_vllm_emulator_pod):
89+
"""Basic test that verifies LMEval works with vLLM using a vLLM emulator for more efficient evaluation"""
90+
lmevaljob_vllm_emulator_pod.wait_for_status(
91+
status=lmevaljob_vllm_emulator_pod.Status.SUCCEEDED, timeout=Timeout.TIMEOUT_10MIN
92+
)

tests/model_explainability/trustyai_service/conftest.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def trustyai_service_with_db_storage(
6666
cluster_monitoring_config: ConfigMap,
6767
user_workload_monitoring_config: ConfigMap,
6868
mariadb: MariaDB,
69+
trustyai_db_ca_secret: None,
6970
) -> Generator[TrustyAIService, Any, Any]:
7071
with TrustyAIService(
7172
client=admin_client,
@@ -226,12 +227,28 @@ def mariadb(
226227
mariadb_dict["spec"]["replicas"] = 1
227228
mariadb_dict["spec"]["galera"]["enabled"] = False
228229
mariadb_dict["spec"]["metrics"]["enabled"] = False
230+
mariadb_dict["spec"]["tls"] = {"enabled": True, "required": True}
229231

230232
password_secret_key_ref = {"generate": False, "key": "databasePassword", "name": DB_CREDENTIALS_SECRET_NAME}
231233

232234
mariadb_dict["spec"]["rootPasswordSecretKeyRef"] = password_secret_key_ref
233235
mariadb_dict["spec"]["passwordSecretKeyRef"] = password_secret_key_ref
234-
235236
with MariaDB(kind_dict=mariadb_dict) as mariadb:
236237
wait_for_mariadb_pods(client=admin_client, mariadb=mariadb)
237238
yield mariadb
239+
240+
241+
@pytest.fixture(scope="class")
242+
def trustyai_db_ca_secret(
243+
admin_client: DynamicClient, model_namespace: Namespace, mariadb: MariaDB
244+
) -> Generator[None, Any, None]:
245+
mariadb_ca_secret = Secret(
246+
client=admin_client, name=f"{mariadb.name}-ca", namespace=model_namespace.name, ensure_exists=True
247+
)
248+
with Secret(
249+
client=admin_client,
250+
name=f"{TRUSTYAI_SERVICE_NAME}-db-ca",
251+
namespace=model_namespace.name,
252+
data_dict={"ca.crt": mariadb_ca_secret.instance.data["ca.crt"]},
253+
):
254+
yield

tests/workbenches/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)