A benchmark for health reasoning over real-world wearable data.
WearableQA comprises 4,084 ten-option multiple-choice questions built from the wearable time series, blood biomarkers, and demographics of 200 real users, each with up to about 500 days of daily measurements. Unlike benchmarks built on synthetic or idealized signals, it preserves authentic wearable distributions β device noise, missing days, and inter-individual variability included.
from datasets import load_dataset
ds = load_dataset("facebook/WearableQA", split="test")
ex = ds[0]
ex["question"] # the complete prompt, ready to send to a model
ex["choices"] # {"A": ..., ..., "J": ...}
ex["answer"] # "A"
The dataset is large (median prompt ~86k characters), so streaming is often convenient:
ds = load_dataset("facebook/WearableQA", split="test", streaming=True)
The same 4,084 questions in five forms. Ids and answers are identical across all of them β only the way the sensor time series is presented changes.
| Config | What it gives you |
|---|---|
row (default) | Prompt with the sensor data as one line per day. This is the released benchmark and the setting the paper reports. |
col | One block per metric, showing each metric's trajectory together. |
csv | Dense CSV table, missing values as empty fields. |
markdown | The same table in markdown. |
structured | No prompt text. Each record carries its own sliced sensor window as structured values, so you can build your own prompt. |
load_dataset("facebook/WearableQA", "markdown", split="test") # a different serialization
load_dataset("facebook/WearableQA", "structured", split="test") # build your own prompts
The representation matters: in our experiments it moved accuracy by several points, and image-based renderings of the same data were far worse than any text form.
row, col, csv, markdown)| Field | Type | Meaning |
|---|---|---|
id | string | Unique question id (<source>_<user>_<end-date>) |
question | string | The complete prompt: instruction, user profile, sensor history, blood panel, cohort percentiles, question stem, and options |
choices | struct | The ten options, keyed AβJ |
answer | string | Ground-truth option letter |
category | string | One of the 16 question types |
reasoning_group | string | data or health |
signal | string | single or cross |
grounding | string | population or literature |
representation | string | Which serialization this config used |
structuredEverything above except question and representation, plus:
| Field | Type | Meaning |
|---|---|---|
stem | string | The question text on its own, without the surrounding prompt |
sensor_history | list of structs | This question's own window β one struct per day, with date and the 16 metrics (null where the device recorded nothing) |
demographics | JSON string | Age, sex, BMI, ethnicity |
blood_panel | JSON string | Up to 17 biomarkers |
cohort_reference | JSON string | Population percentiles (empty when the question withholds them) |
end_date | string | Last day of the observation window |
window_size | int | Length in days of the window the question asks about (28 throughout) |
Each record is self-contained β no joins against a separate user table:
ds = load_dataset("facebook/WearableQA", "structured", split="test")
ex = ds[0]
ex["sensor_history"][0] # {"date": "2023-10-20", "steps": 27858.0, "rhr": 38.0, ...}
# build whatever prompt you want
my_prompt = f"{ex['stem']}\n" + "\n".join(
f"{d['date']}: steps={d['steps']}, rhr={d['rhr']}" for d in ex["sensor_history"])
The 16 question types are organized along two complementary axes:
| Axis | Split | Count |
|---|---|---|
| Reasoning group | data / health | 2,724 / 1,360 |
| Signal complexity | single / cross | 1,682 / 2,402 |
| Grounding | population / literature | 3,154 / 930 |
Ground-truth answers are balanced uniformly across options AβJ within each reasoning group, so the random baseline is 10%.
@misc{lee2026wearableqa,
title={{WearableQA}: A Benchmark for Health Reasoning over Real-World Wearable Data},
author={Ji Soo Lee and Xilun Chen and Pierce Chuang and Ashish Shenoy and Jason Wei and Dohwan Ko and Hyunwoo J. Kim and Benoit Corda},
year={2026},
eprint={2609.05405},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2609.05405},
}
The data is licensed under Creative Commons Attribution-Non Commercial 4.0 International (CC BY-NC 4.0), and subject to the following additional terms: (i) No re-identification or attempted re-identification; (ii) No use in connection with clinical, diagnostic, or treatment decisions; (iii) No use in a manner that is discriminatory, harmful, or misleading with respect to health-related outcomes; (iv) The Dataset is provided "as is", without warranties of any kind, whether express or implied, including without limitation accuracy, completeness, or fitness for a particular purpose, and is provided for research and benchmarking purposes only.
A benchmark for health reasoning over real-world wearable data.
WearableQA comprises 4,084 ten-option multiple-choice questions built from the wearable time series, blood biomarkers, and demographics of 200 real users, each with up to about 500 days of daily measurements. Unlike benchmarks built on synthetic or idealized signals, it preserves authentic wearable distributions β device noise, missing days, and inter-individual variability included.
from datasets import load_dataset
ds = load_dataset("facebook/WearableQA", split="test")
ex = ds[0]
ex["question"] # the complete prompt, ready to send to a model
ex["choices"] # {"A": ..., ..., "J": ...}
ex["answer"] # "A"
The dataset is large (median prompt ~86k characters), so streaming is often convenient:
ds = load_dataset("facebook/WearableQA", split="test", streaming=True)
The same 4,084 questions in five forms. Ids and answers are identical across all of them β only the way the sensor time series is presented changes.
| Config | What it gives you |
|---|---|
row (default) | Prompt with the sensor data as one line per day. This is the released benchmark and the setting the paper reports. |
col | One block per metric, showing each metric's trajectory together. |
csv | Dense CSV table, missing values as empty fields. |
markdown | The same table in markdown. |
structured | No prompt text. Each record carries its own sliced sensor window as structured values, so you can build your own prompt. |
load_dataset("facebook/WearableQA", "markdown", split="test") # a different serialization
load_dataset("facebook/WearableQA", "structured", split="test") # build your own prompts
The representation matters: in our experiments it moved accuracy by several points, and image-based renderings of the same data were far worse than any text form.
row, col, csv, markdown)| Field | Type | Meaning |
|---|---|---|
id | string | Unique question id (<source>_<user>_<end-date>) |
question | string | The complete prompt: instruction, user profile, sensor history, blood panel, cohort percentiles, question stem, and options |
choices | struct | The ten options, keyed AβJ |
answer | string | Ground-truth option letter |
category | string | One of the 16 question types |
reasoning_group | string | data or health |
signal | string | single or cross |
grounding | string | population or literature |
representation | string | Which serialization this config used |
structuredEverything above except question and representation, plus:
| Field | Type | Meaning |
|---|---|---|
stem | string | The question text on its own, without the surrounding prompt |
sensor_history | list of structs | This question's own window β one struct per day, with date and the 16 metrics (null where the device recorded nothing) |
demographics | JSON string | Age, sex, BMI, ethnicity |
blood_panel | JSON string | Up to 17 biomarkers |
cohort_reference | JSON string | Population percentiles (empty when the question withholds them) |
end_date | string | Last day of the observation window |
window_size | int | Length in days of the window the question asks about (28 throughout) |
Each record is self-contained β no joins against a separate user table:
ds = load_dataset("facebook/WearableQA", "structured", split="test")
ex = ds[0]
ex["sensor_history"][0] # {"date": "2023-10-20", "steps": 27858.0, "rhr": 38.0, ...}
# build whatever prompt you want
my_prompt = f"{ex['stem']}\n" + "\n".join(
f"{d['date']}: steps={d['steps']}, rhr={d['rhr']}" for d in ex["sensor_history"])
The 16 question types are organized along two complementary axes:
| Axis | Split | Count |
|---|---|---|
| Reasoning group | data / health | 2,724 / 1,360 |
| Signal complexity | single / cross | 1,682 / 2,402 |
| Grounding | population / literature | 3,154 / 930 |
Ground-truth answers are balanced uniformly across options AβJ within each reasoning group, so the random baseline is 10%.
@misc{lee2026wearableqa,
title={{WearableQA}: A Benchmark for Health Reasoning over Real-World Wearable Data},
author={Ji Soo Lee and Xilun Chen and Pierce Chuang and Ashish Shenoy and Jason Wei and Dohwan Ko and Hyunwoo J. Kim and Benoit Corda},
year={2026},
eprint={2609.05405},
archivePrefix={arXiv},
primaryClass={cs.CL},
url={https://arxiv.org/abs/2609.05405},
}
The data is licensed under Creative Commons Attribution-Non Commercial 4.0 International (CC BY-NC 4.0), and subject to the following additional terms: (i) No re-identification or attempted re-identification; (ii) No use in connection with clinical, diagnostic, or treatment decisions; (iii) No use in a manner that is discriminatory, harmful, or misleading with respect to health-related outcomes; (iv) The Dataset is provided "as is", without warranties of any kind, whether express or implied, including without limitation accuracy, completeness, or fitness for a particular purpose, and is provided for research and benchmarking purposes only.