mirror of
https://github.com/clearml/clearml-server
synced 2025-06-26 23:15:47 +00:00
Support model events
This commit is contained in:
@@ -6,17 +6,24 @@ from typing import Sequence, Optional, Tuple
|
||||
|
||||
from boltons.iterutils import first
|
||||
|
||||
from apiserver.apierrors import errors
|
||||
from apiserver.es_factory import es_factory
|
||||
from apiserver.apierrors.errors.bad_request import EventsNotAdded
|
||||
from apiserver.tests.automated import TestService
|
||||
|
||||
|
||||
class TestTaskEvents(TestService):
|
||||
delete_params = dict(can_fail=True, force=True)
|
||||
|
||||
def _temp_task(self, name="test task events"):
|
||||
task_input = dict(
|
||||
name=name, type="training", input=dict(mapping={}, view=dict(entries=[])),
|
||||
)
|
||||
return self.create_temp("tasks", **task_input)
|
||||
return self.create_temp("tasks", delete_paramse=self.delete_params, **task_input)
|
||||
|
||||
def _temp_model(self, name="test model events", **kwargs):
|
||||
self.update_missing(kwargs, name=name, uri="file:///a/b", labels={})
|
||||
return self.create_temp("models", delete_params=self.delete_params, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def _create_task_event(type_, task, iteration, **kwargs):
|
||||
@@ -172,6 +179,42 @@ class TestTaskEvents(TestService):
|
||||
self.assertEqual(iter_count - 1, metric_data.max_value)
|
||||
self.assertEqual(0, metric_data.min_value)
|
||||
|
||||
def test_model_events(self):
|
||||
model = self._temp_model(ready=False)
|
||||
|
||||
# task log events are not allowed
|
||||
log_event = self._create_task_event(
|
||||
"log",
|
||||
task=model,
|
||||
iteration=0,
|
||||
msg=f"This is a log message",
|
||||
model_event=True,
|
||||
)
|
||||
with self.api.raises(errors.bad_request.EventsNotAdded):
|
||||
self.send(log_event)
|
||||
|
||||
# send metric events and check that model data always have iteration 0 and only last data is saved
|
||||
events = [
|
||||
{
|
||||
**self._create_task_event("training_stats_scalar", model, iteration),
|
||||
"metric": f"Metric{metric_idx}",
|
||||
"variant": f"Variant{variant_idx}",
|
||||
"value": iteration,
|
||||
"model_event": True,
|
||||
}
|
||||
for iteration in range(2)
|
||||
for metric_idx in range(5)
|
||||
for variant_idx in range(5)
|
||||
]
|
||||
self.send_batch(events)
|
||||
data = self.api.events.scalar_metrics_iter_histogram(task=model, model_events=True)
|
||||
self.assertEqual(list(data), [f"Metric{idx}" for idx in range(5)])
|
||||
metric_data = data.Metric0
|
||||
self.assertEqual(list(metric_data), [f"Variant{idx}" for idx in range(5)])
|
||||
variant_data = metric_data.Variant0
|
||||
self.assertEqual(variant_data.x, [0])
|
||||
self.assertEqual(variant_data.y, [1.0])
|
||||
|
||||
def test_error_events(self):
|
||||
task = self._temp_task()
|
||||
events = [
|
||||
@@ -555,7 +598,8 @@ class TestTaskEvents(TestService):
|
||||
return data
|
||||
|
||||
def send(self, event):
|
||||
self.api.send("events.add", event)
|
||||
_, data = self.api.send("events.add", event)
|
||||
return data
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -50,10 +50,12 @@ class TestTasksResetDelete(TestService):
|
||||
self.assertEqual(res.urls.artifact_urls, [])
|
||||
|
||||
task = self.new_task()
|
||||
(_, published_model_urls), (model, draft_model_urls) = self.create_task_models(task)
|
||||
published_model_urls, draft_model_urls = self.create_task_models(task)
|
||||
artifact_urls = self.send_artifacts(task)
|
||||
event_urls = self.send_debug_image_events(task)
|
||||
event_urls.update(self.send_plot_events(task))
|
||||
event_urls.update(self.send_model_events(model))
|
||||
res = self.assert_delete_task(task, force=True, return_file_urls=True)
|
||||
self.assertEqual(set(res.urls.model_urls), draft_model_urls)
|
||||
self.assertEqual(set(res.urls.event_urls), event_urls)
|
||||
@@ -120,10 +122,12 @@ class TestTasksResetDelete(TestService):
|
||||
self, **kwargs
|
||||
) -> Tuple[str, Tuple[Set[str], Set[str]], Set[str], Set[str]]:
|
||||
task = self.new_task(**kwargs)
|
||||
(_, published_model_urls), (model, draft_model_urls) = self.create_task_models(task, **kwargs)
|
||||
published_model_urls, draft_model_urls = self.create_task_models(task, **kwargs)
|
||||
artifact_urls = self.send_artifacts(task)
|
||||
event_urls = self.send_debug_image_events(task)
|
||||
event_urls.update(self.send_plot_events(task))
|
||||
event_urls.update(self.send_model_events(model))
|
||||
return task, (published_model_urls, draft_model_urls), artifact_urls, event_urls
|
||||
|
||||
def assert_delete_task(self, task_id, force=False, return_file_urls=False):
|
||||
@@ -137,15 +141,17 @@ class TestTasksResetDelete(TestService):
|
||||
self.assertEqual(tasks, [])
|
||||
return res
|
||||
|
||||
def create_task_models(self, task, **kwargs) -> Tuple[Set[str], Set[str]]:
|
||||
def create_task_models(self, task, **kwargs) -> Tuple:
|
||||
"""
|
||||
Update models from task and return only non public models
|
||||
"""
|
||||
model_ready = self.new_model(uri="ready", **kwargs)
|
||||
model_not_ready = self.new_model(uri="not_ready", ready=False, **kwargs)
|
||||
ready_uri = "ready"
|
||||
not_ready_uri = "not_ready"
|
||||
model_ready = self.new_model(uri=ready_uri, **kwargs)
|
||||
model_not_ready = self.new_model(uri=not_ready_uri, ready=False, **kwargs)
|
||||
self.api.models.edit(model=model_not_ready, task=task)
|
||||
self.api.models.edit(model=model_ready, task=task)
|
||||
return {"ready"}, {"not_ready"}
|
||||
return (model_ready, {ready_uri}), (model_not_ready, {not_ready_uri})
|
||||
|
||||
def send_artifacts(self, task) -> Set[str]:
|
||||
"""
|
||||
@@ -159,6 +165,20 @@ class TestTasksResetDelete(TestService):
|
||||
self.api.tasks.add_or_update_artifacts(task=task, artifacts=artifacts)
|
||||
return {"test2"}
|
||||
|
||||
def send_model_events(self, model) -> Set[str]:
|
||||
url1 = "http://link1"
|
||||
url2 = "http://link2"
|
||||
events = [
|
||||
self.create_event(
|
||||
model, "training_debug_image", 0, url=url1, model_event=True
|
||||
),
|
||||
self.create_event(
|
||||
model, "plot", 0, plot_str=f'{{"source": "{url2}"}}', model_event=True
|
||||
)
|
||||
]
|
||||
self.send_batch(events)
|
||||
return {url1, url2}
|
||||
|
||||
def send_debug_image_events(self, task) -> Set[str]:
|
||||
events = [
|
||||
self.create_event(
|
||||
|
||||
Reference in New Issue
Block a user