Skip to content

media-model-proxy: fail closed when every NSFW replica drops scores - #167

Open
Pitchfork-and-Torch wants to merge 1 commit into
xai-org:mainfrom
Pitchfork-and-Torch:cursor/mmp-nsfw-score-fail-closed-d233
Open

media-model-proxy: fail closed when every NSFW replica drops scores#167
Pitchfork-and-Torch wants to merge 1 commit into
xai-org:mainfrom
Pitchfork-and-Torch:cursor/mmp-nsfw-score-fail-closed-d233

Conversation

@Pitchfork-and-Torch

Copy link
Copy Markdown

Summary

Media Model Proxy is the production path that scores tweet images, videos, and GIFs for XX_NSFW (and the other media-understanding models) before Media Analysis persists the result. When every Deepbird replica errors, getPrediction currently succeeds with an empty score list. Callers treat that as unlabeled / SFW, so adult media ranks and ships as safe whenever xx-nsfw is down, times out, or rejects the bytes (including greyscale).

This is not a Scala-parity leftover and is not in the claimed VF / Grok / Thunder / DNA / ads / Phoenix lanes.

Five-line proof

  1. ModelsService.getPrediction uses Future.collectToTry and filterException to drop every NonFatal replica error, including PredictionServiceException and GreyScaleImageException.
  2. The existing tests encoded the fail-open: all replicas throw → assert(result.isEmpty).
  3. ProxyController then builds AnnotationResponse(..., annotations = Some(predictions.toMap)) and increments success. An empty Seq[DataRecord] is a successful XxNsfw key.
  4. README: MMP does not persist scores; Media Analysis interprets and stores whatever comes back. Missing nsfw.default.score is "not NSFW."
  5. Greyscale is the dead-code tell: the proxy already rewrites the color-model error into GreyScaleImageException(BadRequest, MediaNotSupported), then filterException swallows it so the client never sees the BadRequest.

Partial replica failure still returns the surviving scores. Kill-switched models (no replica attempted) still return empty.

Fix

If any replica was attempted and zero valid scores remain, fail the Future with the first error (fail_closed counter). Greyscale decode errors now surface as GreyScaleImageException instead of a successful empty map.

Tests

  • All-cluster PredictionServiceException and other NonFatal errors now intercept instead of accepting empty.
  • New coverage: greyscale decode error on every replica fails closed with GreyScaleImageException.
  • Existing partial-failure and disabled-client tests unchanged.

Scala/Bazel is not available in this environment, so ModelsServiceSpec was not executed here.

collectToTry + filterException swallowed every NonFatal xx-nsfw
error, including greyscale decode failures that were already mapped
to GreyScaleImageException. The controller then returned a successful
empty annotation map, which Media Analysis persists as unlabeled /
SFW. Keep partial-replica failover; fail the request when every
attempted replica errors.

Co-authored-by: Jon Bailey <Pitchfork-and-Torch@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants