mirror of
https://github.com/clearml/clearml-server
synced 2025-03-03 18:54:20 +00:00
Task reports can now return single value metrics
This commit is contained in:
parent
58465fbc17
commit
e99817b28b
@ -61,10 +61,17 @@ class ScalarMetricsIterHistogram(HistogramRequestBase):
|
|||||||
metrics: Sequence[MetricVariants] = ListField(items_types=MetricVariants)
|
metrics: Sequence[MetricVariants] = ListField(items_types=MetricVariants)
|
||||||
|
|
||||||
|
|
||||||
|
class SingleValueMetrics(Base):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GetTasksDataRequest(Base):
|
class GetTasksDataRequest(Base):
|
||||||
debug_images: EventsRequest = EmbeddedField(EventsRequest)
|
debug_images: EventsRequest = EmbeddedField(EventsRequest)
|
||||||
plots: EventsRequest = EmbeddedField(EventsRequest)
|
plots: EventsRequest = EmbeddedField(EventsRequest)
|
||||||
scalar_metrics_iter_histogram: ScalarMetricsIterHistogram = EmbeddedField(ScalarMetricsIterHistogram)
|
scalar_metrics_iter_histogram: ScalarMetricsIterHistogram = EmbeddedField(
|
||||||
|
ScalarMetricsIterHistogram
|
||||||
|
)
|
||||||
|
single_value_metrics: SingleValueMetrics = EmbeddedField(SingleValueMetrics)
|
||||||
allow_public = BoolField(default=True)
|
allow_public = BoolField(default=True)
|
||||||
model_events: bool = BoolField(default=False)
|
model_events: bool = BoolField(default=False)
|
||||||
|
|
||||||
|
@ -103,4 +103,35 @@ plots_response {
|
|||||||
items {"$ref": "#/definitions/plots_response_task_metrics"}
|
items {"$ref": "#/definitions/plots_response_task_metrics"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
single_value_task_metrics {
|
||||||
|
type: object
|
||||||
|
properties {
|
||||||
|
task {
|
||||||
|
type: string
|
||||||
|
description: Task ID
|
||||||
|
}
|
||||||
|
values {
|
||||||
|
type: array
|
||||||
|
items {
|
||||||
|
type: object
|
||||||
|
properties {
|
||||||
|
metric { type: string }
|
||||||
|
variant { type: string}
|
||||||
|
value { type: number }
|
||||||
|
timestamp { type: number }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
single_value_metrics_response {
|
||||||
|
type: object
|
||||||
|
properties {
|
||||||
|
tasks {
|
||||||
|
description: Single value metrics grouped by task
|
||||||
|
type: array
|
||||||
|
items {"$ref": "#/definitions/single_value_task_metrics"}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1353,36 +1353,7 @@ get_task_single_value_metrics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response {
|
response {"$ref": "#/definitions/single_value_metrics_response"}
|
||||||
type: object
|
|
||||||
properties {
|
|
||||||
tasks {
|
|
||||||
description: Single value metrics grouped by task
|
|
||||||
type: array
|
|
||||||
items {
|
|
||||||
type: object
|
|
||||||
properties {
|
|
||||||
task {
|
|
||||||
type: string
|
|
||||||
description: Task ID
|
|
||||||
}
|
|
||||||
values {
|
|
||||||
type: array
|
|
||||||
items {
|
|
||||||
type: object
|
|
||||||
properties {
|
|
||||||
metric { type: string }
|
|
||||||
variant { type: string}
|
|
||||||
value { type: number }
|
|
||||||
timestamp { type: number }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
"2.22": ${get_task_single_value_metrics."2.20"} {
|
"2.22": ${get_task_single_value_metrics."2.20"} {
|
||||||
request.properties.model_events {
|
request.properties.model_events {
|
||||||
|
@ -569,10 +569,22 @@ get_task_data {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"999.0": ${get_task_data."2.23"} {
|
"999.0": ${get_task_data."2.23"} {
|
||||||
request.properties.model_events {
|
request.properties {
|
||||||
type: boolean
|
model_events {
|
||||||
description: If set then the retrieving model events. Otherwise task events
|
type: boolean
|
||||||
default: false
|
description: If set then the retrieving model events. Otherwise task events
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
single_value_metrics {
|
||||||
|
type: object
|
||||||
|
description: If passed then task single value metrics are returned
|
||||||
|
additonalProperties: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response.properties.single_value_metrics {
|
||||||
|
type: array
|
||||||
|
description: Single value metrics grouped by task
|
||||||
|
items {"$ref": "#/definitions/single_value_task_metrics"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,6 +508,12 @@ def multi_task_scalar_metrics_iter_histogram(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_single_value_metrics_response(
|
||||||
|
value_metrics: Mapping[str, dict]
|
||||||
|
) -> Sequence[dict]:
|
||||||
|
return [{"task": task, "values": values} for task, values in value_metrics.items()]
|
||||||
|
|
||||||
|
|
||||||
@endpoint("events.get_task_single_value_metrics")
|
@endpoint("events.get_task_single_value_metrics")
|
||||||
def get_task_single_value_metrics(
|
def get_task_single_value_metrics(
|
||||||
call, company_id: str, request: SingleValueMetricsRequest
|
call, company_id: str, request: SingleValueMetricsRequest
|
||||||
@ -517,9 +523,7 @@ def get_task_single_value_metrics(
|
|||||||
company_id, request.tasks, request.model_events
|
company_id, request.tasks, request.model_events
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
call.result.data = dict(
|
call.result.data = dict(tasks=_get_single_value_metrics_response(res))
|
||||||
tasks=[{"task": task, "values": values} for task, values in res.items()]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@endpoint("events.get_multi_task_plots", required_fields=["tasks"])
|
@endpoint("events.get_multi_task_plots", required_fields=["tasks"])
|
||||||
|
@ -33,6 +33,7 @@ from apiserver.services.events import (
|
|||||||
_get_metrics_response,
|
_get_metrics_response,
|
||||||
_get_metric_variants_from_request,
|
_get_metric_variants_from_request,
|
||||||
_get_multitask_plots,
|
_get_multitask_plots,
|
||||||
|
_get_single_value_metrics_response,
|
||||||
)
|
)
|
||||||
from apiserver.services.tasks import (
|
from apiserver.services.tasks import (
|
||||||
escape_execution_parameters,
|
escape_execution_parameters,
|
||||||
@ -221,7 +222,10 @@ def get_task_data(call: APICall, company_id, request: GetTasksDataRequest):
|
|||||||
conform_data(call, tasks)
|
conform_data(call, tasks)
|
||||||
res = {"tasks": tasks, **ret_params}
|
res = {"tasks": tasks, **ret_params}
|
||||||
if not (
|
if not (
|
||||||
request.debug_images or request.plots or request.scalar_metrics_iter_histogram
|
request.debug_images
|
||||||
|
or request.plots
|
||||||
|
or request.scalar_metrics_iter_histogram
|
||||||
|
or request.single_value_metrics
|
||||||
):
|
):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@ -260,6 +264,11 @@ def get_task_data(call: APICall, company_id, request: GetTasksDataRequest):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if request.single_value_metrics:
|
||||||
|
res["single_value_metrics"] = _get_single_value_metrics_response(
|
||||||
|
event_bll.metrics.get_task_single_value_metrics(companies=companies)
|
||||||
|
)
|
||||||
|
|
||||||
call.result.data = res
|
call.result.data = res
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,20 +146,46 @@ class TestReports(TestService):
|
|||||||
for m in range(2)
|
for m in range(2)
|
||||||
for v in range(2)
|
for v in range(2)
|
||||||
]
|
]
|
||||||
self.send_batch([*debug_image_events, *plot_events])
|
scalar_events = [
|
||||||
|
self._create_task_event(
|
||||||
|
task=non_report_task,
|
||||||
|
type_="training_stats_scalar",
|
||||||
|
iteration=iter_,
|
||||||
|
metric=f"Metric_{m}",
|
||||||
|
variant=f"Variant_{v}",
|
||||||
|
value=m * v,
|
||||||
|
**event_args,
|
||||||
|
)
|
||||||
|
for m in range(2)
|
||||||
|
for v in range(2)
|
||||||
|
for iter_ in (1, -(2 ** 31))
|
||||||
|
]
|
||||||
|
self.send_batch([*debug_image_events, *plot_events, *scalar_events])
|
||||||
|
|
||||||
res = self.api.reports.get_task_data(
|
res = self.api.reports.get_task_data(
|
||||||
id=[non_report_task], only_fields=["name"], model_events=model_events
|
id=[non_report_task], only_fields=["name"], model_events=model_events
|
||||||
)
|
)
|
||||||
self.assertEqual(len(res.tasks), 1)
|
self.assertEqual(len(res.tasks), 1)
|
||||||
self.assertEqual(res.tasks[0].id, non_report_task)
|
self.assertEqual(res.tasks[0].id, non_report_task)
|
||||||
self.assertFalse(any(field in res for field in ("plots", "debug_images")))
|
self.assertFalse(
|
||||||
|
any(
|
||||||
|
field in res
|
||||||
|
for field in (
|
||||||
|
"plots",
|
||||||
|
"debug_images",
|
||||||
|
"scalar_metrics_iter_histogram",
|
||||||
|
"single_value_metrics",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
res = self.api.reports.get_task_data(
|
res = self.api.reports.get_task_data(
|
||||||
id=[non_report_task],
|
id=[non_report_task],
|
||||||
only_fields=["name"],
|
only_fields=["name"],
|
||||||
debug_images={"metrics": []},
|
debug_images={"metrics": []},
|
||||||
plots={"metrics": [{"metric": "Metric_1"}]},
|
plots={"metrics": [{"metric": "Metric_1"}]},
|
||||||
|
scalar_metrics_iter_histogram={},
|
||||||
|
single_value_metrics={},
|
||||||
model_events=model_events,
|
model_events=model_events,
|
||||||
)
|
)
|
||||||
self.assertEqual(len(res.debug_images), 1)
|
self.assertEqual(len(res.debug_images), 1)
|
||||||
@ -168,6 +194,20 @@ class TestReports(TestService):
|
|||||||
self.assertEqual(len(task_events.iterations), 1)
|
self.assertEqual(len(task_events.iterations), 1)
|
||||||
self.assertEqual(len(task_events.iterations[0].events), 4)
|
self.assertEqual(len(task_events.iterations[0].events), 4)
|
||||||
|
|
||||||
|
self.assertEqual(len(res.single_value_metrics), 1)
|
||||||
|
task_metrics = res.single_value_metrics[0]
|
||||||
|
self.assertEqual(task_metrics.task, non_report_task)
|
||||||
|
self.assertEqual(
|
||||||
|
{(v["metric"], v["variant"]) for v in task_metrics["values"]},
|
||||||
|
{(f"Metric_{x}", f"Variant_{y}") for x in range(2) for y in range(2)},
|
||||||
|
)
|
||||||
|
self.assertEqual(len(task_events.iterations[0].events), 4)
|
||||||
|
|
||||||
|
for m in ("Metric_0", "Metric_1"):
|
||||||
|
for v in ("Variant_0", "Variant_1"):
|
||||||
|
tasks = nested_get(res.scalar_metrics_iter_histogram, (m, v))
|
||||||
|
self.assertEqual(list(tasks.keys()), [non_report_task])
|
||||||
|
|
||||||
self.assertEqual(len(res.plots), 1)
|
self.assertEqual(len(res.plots), 1)
|
||||||
for m, v in (("Metric_1", "Variant_0"), ("Metric_1", "Variant_1")):
|
for m, v in (("Metric_1", "Variant_0"), ("Metric_1", "Variant_1")):
|
||||||
tasks = nested_get(res.plots, (m, v))
|
tasks = nested_get(res.plots, (m, v))
|
||||||
|
Loading…
Reference in New Issue
Block a user