Repository navigation
feat(connectors): split ARFBench into a series and a plots dataset #769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d70629d
c338f95
707622d
e081cd5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
masquare marked this conversation as resolved.
Resolved
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,38 +1,43 @@ | ||
| # yaml-language-server: $schema=https://docs.timenet.ai/schemas/dataset-card.schema.json | ||
| # yaml-language-server: $schema=https://docs.timenet.ai/schemas/dataset-card-v1.schema.json | ||
| # | ||
| # ARFBench asks 750 multiple-choice questions about 142 metrics from 63 Datadog incidents. A metric | ||
| # is one monitored quantity, such as the request count of a service. Datadog splits a metric by | ||
| # tags, so a metric holds one series per tag group, for example one per host. | ||
| # tags. Thus a metric holds one series per tag group, for example one series per host. | ||
| # | ||
| # Datadog stores a metric at several rollups. A rollup is the metric on a fixed time grid, with one | ||
| # value per interval of 10, 60, 300, 1800, 3600, or 86400 seconds. The rollups of a metric are | ||
| # separate exports, not resamplings of one series: their time ranges and tag groups differ. | ||
| # separate exports, not resamplings of one series. Their time ranges and tag groups differ. | ||
| # | ||
| # Each metric is one record, with one source per tag group and one signal per rollup. A consumer | ||
| # chooses the rollup. The paper and the charts use the finest one, which the annotation | ||
| # `finest_interval_s` names. | ||
| # chooses the rollup. The paper and the charts use the finest rollup. The annotation | ||
| # `finest_interval_s` names this rollup. | ||
| # | ||
| # A rollup file lists the tag groups at the steps of its grid. Where the metric reported nothing | ||
| # for a group, the step holds a null or is left out. Each series is cut to the window from its | ||
| # group's first value to its last, so a group with no value at a rollup has no series there. Inside | ||
| # the window, each such step is a missing timestep on the regular grid, with the spec's reason | ||
| # `not_recorded`. Values are float64, and the release names no units. The release stores naive | ||
| # epochs, which the dataset reads as UTC. The charts and the answer options use the same clock. | ||
| # for a group, the step holds a null or is not in the file. The dataset cuts each series to the | ||
| # window from the first value of its group to the last value. Thus a group with no value at a | ||
| # rollup has no series at that rollup. Inside the window, each such step is a missing timestep on | ||
| # the regular grid, with the reason `not_recorded` from the spec. Values are float64. The release | ||
| # names no units. The release stores naive epochs. The dataset reads them as UTC. The answer | ||
| # options use the same clock. | ||
| # | ||
| # Each question becomes two test tasks: one over the cited metric records, one over the released | ||
| # chart images. Both carry the question's row as `question_index` in their metadata, so the test | ||
| # split holds 1,500 tasks. | ||
| # Each question becomes one test task over the cited metric records. Thus the test split holds 750 | ||
| # tasks. A task carries the row of the question as `question_index` in its metadata. The released | ||
| # charts are in `datadog/arfbench-plots`. The chart tasks of that dataset carry the same | ||
| # `question_index`. | ||
| # | ||
| # Kept as released: `query_name`, an identifier that differs from the metric ID for 122 of the 142 | ||
| # metrics and that the release does not explain; one end-time answer (row 191, metric 36464_0) | ||
| # 140 seconds after its series ends; and 29 time options that lie outside every rollup. | ||
| # The dataset keeps three items as released: | ||
| # - `query_name`. This identifier differs from the metric ID for 122 of the 142 metrics. The | ||
| # release does not explain it. | ||
| # - One end-time answer (row 191, metric 36464_0). This answer is 140 seconds after the end of its | ||
| # series. | ||
| # - 29 time options that are outside every rollup. | ||
| yaml_schema_version: 1 | ||
| dataset_id: datadog/arfbench | ||
| dataset_version: 1.0.0 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are we bumping versions, now that it is a public release? |
||
| name: ARFBench | ||
| description: >- | ||
| 750 multiple-choice questions about anomalies in 142 metrics from 63 Datadog incidents. | ||
| The dataset includes every published metric rollup and the released charts. | ||
| The dataset includes every published metric rollup. The charts are in datadog/arfbench-plots. | ||
| license: Apache-2.0 | ||
| source_url: https://huggingface.co/datasets/Datadog/ARFBench | ||
| citation: >- | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| """The ARFBench question table: 750 multiple-choice questions, each a series task and a chart task.""" | ||
| """The ARFBench question table: 750 multiple-choice questions, each a series task or a chart task.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
|
|
@@ -9,7 +9,7 @@ | |
| from typing import TYPE_CHECKING, Self, TypeVar | ||
|
|
||
| from timenet.errors import TimeNetConnectorError | ||
| from timenet.types import Annotation, AnswerTask, InputModality, Split | ||
| from timenet.types import Annotation, ClassificationTask, InputModality, Label, LabelSet, Split | ||
|
|
||
|
|
||
| if TYPE_CHECKING: | ||
|
|
@@ -167,7 +167,7 @@ def chart_stems(self) -> tuple[str, ...]: | |
| return self.cited_metrics | ||
| return ("-".join(self.cited_metrics), *self.cited_metrics) | ||
|
|
||
| def create_series_task(self, metric_records: Mapping[str, Record]) -> AnswerTask: | ||
| def create_series_task(self, metric_records: Mapping[str, Record]) -> ClassificationTask: | ||
| """Create the task that asks the question about the cited metric records. | ||
|
|
||
| Args: | ||
|
|
@@ -185,7 +185,7 @@ def create_series_task(self, metric_records: Mapping[str, Record]) -> AnswerTask | |
| inputs = tuple(metric_records[metric] for metric in self.cited_metrics) | ||
| return self._create_task(inputs, InputModality.TIME_SERIES) | ||
|
|
||
| def create_chart_task(self, chart_records: Mapping[str, Record]) -> AnswerTask: | ||
| def create_chart_task(self, chart_records: Mapping[str, Record]) -> ClassificationTask: | ||
| """Create the task that asks the question about the released charts. | ||
|
|
||
| Args: | ||
|
|
@@ -203,25 +203,28 @@ def create_chart_task(self, chart_records: Mapping[str, Record]) -> AnswerTask: | |
| inputs = tuple(chart_records[stem] for stem in self.chart_stems()) | ||
| return self._create_task(inputs, InputModality.IMAGE) | ||
|
|
||
| def _create_task(self, inputs: tuple[Record, ...], modality: InputModality) -> AnswerTask: | ||
| """Create a test task with the question as prompt and the correct answer as target. | ||
| def _create_task(self, inputs: tuple[Record, ...], modality: InputModality) -> ClassificationTask: | ||
| """Create a test task that asks for the correct answer from the options of the question. | ||
|
|
||
| Both tasks of a question carry its row index in their metadata, so a consumer can pair | ||
| them. The question's annotations describe it, and the interpolation flags describe what | ||
| an engineer saw. Nothing here interpolates. | ||
| The options are the label set of the task. The label set has the name of the question row, | ||
| so both tasks of a question share it. Both tasks also have the row index in their metadata, | ||
| so a consumer can pair them. The annotations describe the question. The interpolation flags | ||
| describe what an engineer saw. This method does not interpolate. | ||
|
|
||
| Returns: | ||
| The task, not yet added to a dataset. | ||
| """ | ||
| task = AnswerTask( | ||
| task = ClassificationTask( | ||
| inputs=inputs, | ||
| prompt=self.question, | ||
| targets=(self.correct_answer,), | ||
| input_modalities=frozenset({InputModality.TEXT, modality}), | ||
| split=Split.TEST, | ||
| metadata={"question_index": self.index}, | ||
| label_set=LabelSet( | ||
| name=f"question_{self.index}", labels=tuple(Label(name=option) for option in self.answer_options) | ||
| ), | ||
|
Comment on lines
+224
to
+226
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes one label set per question, so 750 sets. If we were to name the set from its content, (e.g short hash of the option tuple), the equal option lists coudl share sets |
||
| ) | ||
| task.annotate(Annotation(key="answer_options", value=list(self.answer_options))) | ||
| task.annotate(Annotation(key="task_category", value=self.task_category.value)) | ||
| task.annotate(Annotation(key="difficulty", value=self.difficulty.value)) | ||
| task.annotate(Annotation(key="interpolate_1", value=self.interpolate_1)) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,2 @@ | ||
| # huggingface_hub downloads the release from the HuggingFace Hub. | ||
| huggingface_hub>=0.24 | ||
| # pyarrow reads the series files. | ||
| pyarrow>=21 | ||
| # Pillow decodes chart PNGs; Zarr stores their tensor values. | ||
| pillow>=11 | ||
| zarr>=3 | ||
| # huggingface_hub downloads the release from the HuggingFace Hub. Version 1.1 adds tqdm_class. | ||
| huggingface_hub>=1.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is generic enough that you can put it in
BaseHuggingFaceConnector