Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 11 additions & 15 deletions tests/e2e/test_eval_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,35 +292,31 @@ def test_sentence_similarity(self, runner: CliRunner, tmp_path: Path) -> None:
if is_host("qnn"):
_assert_in_range(data["metrics"], "cosine_spearman", 40.0, 100.0)

@pytest.mark.parametrize(
"task",
["image-feature-extraction", "feature-extraction"],
)
def test_image_feature_extraction(
self, runner: CliRunner, tmp_path: Path, task: str,
self, runner: CliRunner, tmp_path: Path,
) -> None:
# kNN accuracies reported as percentages 0..100.
# --streaming avoids caching mini-imagenet.
# Parameterized over both task names accepted on the CLI:
# - "image-feature-extraction" is the HF pipeline task name
# and dispatches to the image evaluator directly.
# - "feature-extraction" is bimodal; for a vision model it is
# mapped internally to the HF pipeline name so the image
# dataset and evaluator are selected.
# A vision embedding model's canonical task is image-feature-extraction
# (what `winml inspect` and auto-detection report); it dispatches to the
# image evaluator directly. 'feature-extraction' is text-only under the
# modality-aware task vocabulary, so it is not a valid task for a vision
# model (it would resolve to the text evaluator/dataset and fail).
out = tmp_path / "result.json"
_invoke(runner, [
"-m", "facebook/dinov2-small",
"--task", task,
"--task", "image-feature-extraction",
"--streaming",
"--samples", SAMPLES,
"-o", str(out),
])
data = _assert_metrics_present(
out, ["knn_top1_accuracy", "knn_top5_accuracy"],
)
# DINOv2 features cluster strongly on mini-imagenet.
_assert_in_range(data["metrics"], "knn_top1_accuracy", 30.0, 100.0)
_assert_in_range(data["metrics"], "knn_top5_accuracy", 60.0, 100.0)
# Loose floors guard against degenerate output, not magnitude: with
# SAMPLES=10 the kNN estimate has heavy variance (cf. test_question_answering).
_assert_in_range(data["metrics"], "knn_top1_accuracy", 10.0, 100.0)
_assert_in_range(data["metrics"], "knn_top5_accuracy", 25.0, 100.0)
top1 = data["metrics"]["knn_top1_accuracy"]
top5 = data["metrics"]["knn_top5_accuracy"]
assert top1 <= top5, f"top1 ({top1}) must be <= top5 ({top5})"
Expand Down
15 changes: 8 additions & 7 deletions tests/e2e/test_quantize_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,27 +572,28 @@ def test_unsupported_task_falls_back_to_random_dataset(
)

@pytest.mark.network
def test_feature_extraction_with_pixel_values_uses_image_dataset(
def test_image_feature_extraction_uses_image_dataset(
self, runner: CliRunner, onnx_dinov2: Path, tmp_path: Path
):
# For a vision model the bimodal task 'feature-extraction' must
# dispatch via the model's ONNX inputs (pixel_values) to
# ImageDataset for calibration. The task label in the log stays
# 'feature-extraction' (the resolver only swaps the dataset class).
# A vision embedding model's canonical task is image-feature-extraction
# (what `winml inspect` and auto-detection report); it maps directly to
# ImageDataset for calibration. Under the modality-aware task vocabulary
# 'feature-extraction' is text-only, so it is intentionally not a valid
# task for a vision model (its calibration dataset would be TextDataset).
out = tmp_path / "d7.onnx"

r = _invoke(
runner,
[
"-m", str(onnx_dinov2), "-o", str(out),
"--task", "feature-extraction",
"--task", "image-feature-extraction",
"--model-name", "facebook/dinov2-small",
"--samples", "4", "-v",
],
)
_assert_quantized_output(input_onnx=onnx_dinov2, output_onnx=out, stdout=r.output)
assert (
"Creating feature-extraction dataset with ImageDataset" in r.output
"Creating image-feature-extraction dataset with ImageDataset" in r.output
), r.output


Expand Down
Loading