I Built an AI Model That Outperformed AWS and Google on Image Moderation

Wait 5 sec.

I started working on Blue-Eye because I was curious about something: how difficult would it actually be to build an image moderation model that could compete with the commercial APIs everyone uses?If you're building anything that allows user-uploaded images, content moderation eventually becomes a problem you have to deal with. The straightforward approach is to integrate something like AWS Rekognition or Google Cloud Vision. They handle the infrastructure, you send an image, and you get a moderation result back. It's convenient, but you're also paying for requests and relying on someone else's model, with limited control over how it makes decisions.There are open models available too, of course, but I wanted to see how far I could push one myself. Not by training some enormous vision model from scratch, but by taking a strong pretrained model, fine-tuning it for a specific task, and seeing how it compared with existing services.The catch was that I didn't have a research lab, a team, or a large compute budget. I was working independently, using free and community-supported resources wherever I could. Training a model on millions of images under those constraints sounded a little ambitious, but I figured it was worth trying.That experiment turned into Blue-Eye, a 303-million-parameter image classifier built on Meta's DINOv3 architecture. It predicts whether an image is safe, suggestive, or explicit, and it was fine-tuned on approximately 2.6 million images covering both real photographs and anime or illustrated content.When I eventually ran my main benchmark, Blue-Eye reached 88.9% accuracy on 3,000 real photographs, compared with 87.3% for AWS Rekognition and 83.5% for Google Cloud Vision SafeSearch. That's the comparison shown in the chart above.I wouldn't call that proof of being universally better than those services, especially since the evaluation uses my own dataset and category mappings. But seeing an independently developed model perform that competitively was encouraging, and I wanted to share how I got there.The problem with classifying something as NSFW.One thing that makes NSFW detection tricky is that simply detecting nudity or exposed skin isn't enough.Think about how many perfectly ordinary images contain a lot of visible skin. Beach photographs, fitness content, medical images, breastfeeding, and certain kinds of artwork are obvious examples. A classifier that gets too aggressive can end up flagging harmless images, which isn't particularly useful if you're trying to build a reliable moderation system.Then there's the more ambiguous content. An image might be sexualized without being explicit, and the boundary isn't always something even two people would agree on. Different platforms also have different ideas of what should be allowed.For Blue-Eye, I went with three classes rather than a simple safe-or-unsafe prediction. Safe covers non-sexual content, including things like swimwear and medical images. Suggestive covers sexualized but non-explicit content, while explicit covers explicit nudity and sexual activity.The model produces three softmax scores and selects the highest-scoring class as its prediction. Developers can also use those scores to choose their own thresholds, although they shouldn't be treated as perfectly calibrated confidence estimates without additional testing.I liked this approach because it gives platforms some flexibility instead of forcing everyone to use exactly the same moderation policy.Of course, getting a model to consistently distinguish those classes is easier said than done. The suggestive category in particular turned out to be one of the more difficult parts of the task.Training a 303M-parameter model on 2.6 million images.For the backbone, I chose DINOv3 ViT-L/16, Meta's pretrained vision transformer. It already had strong visual representations, so instead of spending resources training a model from scratch, I could focus on adapting it to the classification problem I actually wanted to solve.Blue-Eye uses a 512 × 512 image input and a classification head that combines the transformer's class token with pooled features from the other output tokens. The resulting model has approximately 303 million parameters, which is fairly substantial for something I was building independently.But the architecture was only part of the work. Preparing the training data took a lot of attention, particularly because I didn't want the model to work well on photographs and then fall apart when somebody uploaded anime or digital art.The training data included approximately 2.6 million images, covering real-world photographs, anime, and other illustrations. Labels came from a combination of commercial moderation services, source content ratings, and model-assisted re-labelling. I also manually labelled or reviewed roughly 11,000 images during development.That manual work was useful for understanding the difficult cases. Some images are obviously safe or obviously explicit, but others depend heavily on context. The distinction between ordinary swimwear and sexualized imagery, for example, isn't always as clean as a set of three labels makes it sound.It's also where you start appreciating how much a model depends on the consistency of its training data. More images are useful, but they don't automatically compensate for inconsistent labels.I trained Blue-Eye in three stages. The first used around one million real photographs to adapt the backbone to the moderation task. The second used another one million images, this time mixing photographs with anime and illustrations. The final stage involved approximately 650,000 class-balanced images to refine the classifier across the three categories.Training ran for two epochs per stage using AdamW with a one-cycle learning-rate schedule. I also used label smoothing, image augmentations, and bfloat16 mixed precision with float32 master weights.The infrastructure was another interesting part of the project. I used Google Cloud TPU v5e hardware, along with PyTorch and Hugging Face tooling, and relied on free and community-supported computing resources rather than funding a dedicated training cluster myself.That access made a real difference. Training a model of this size on millions of images still requires substantial computing power, regardless of whether you're personally paying for it. Having resources available through community programs and other free-access opportunities meant I could attempt something that would otherwise have been difficult to justify financially.It also meant being careful with experiments. When you don't have unlimited compute, you can't just keep throwing additional training runs at every issue. You have to pay attention to the dataset, the training strategy, and whether each experiment is actually telling you something useful.I think that was one of the more valuable parts of working on Blue-Eye. A lot of the engineering came down to making good use of what was available rather than simply trying to scale everything up.Comparing it with AWS, Google, and existing open models.After training, I wanted to compare Blue-Eye with systems developers might realistically use instead.I put together a benchmark containing 3,000 real photographs, split into 1,480 safe, 513 suggestive, and 1,007 explicit images. Among those were 525 non-sexual, skin-heavy photographs, including swimwear, fitness, and medical content. I specifically wanted examples where a model could be tempted to confuse visible skin with sexual content.The evaluation images were excluded from the training data. I then evaluated Blue-Eye alongside AWS Rekognition, Google Cloud Vision SafeSearch, Gemini, and several existing NSFW detectors using the same images and three-class accuracy metric.There's an important limitation to that comparison. Commercial moderation APIs don't all return the same categories, so I had to map their outputs into safe, suggestive, and explicit. For Google Cloud Vision, the evaluation used “VERY_LIKELY” responses for the relevant adult and racy categories; AWS Rekognition used its default 50% confidence threshold.Those choices affect the results, and different mappings or thresholds could produce different rankings. The benchmark is also my own evaluation rather than an independently reproduced test.With that context, the result was still pretty interesting. Blue-Eye reached 88.9% accuracy, putting it 1.6 percentage points ahead of AWS Rekognition and 5.4 points ahead of Google Cloud Vision under the evaluation settings I used. It also scored above the other commercial and open-weight models included in the comparison.What surprised me wasn't simply seeing Blue-Eye at the top. It was how competitive a relatively specialized model could become when fine-tuned for a clearly defined task.Looking at the individual classes revealed where the model still struggled. Blue-Eye achieved 89.5% recall on safe images, 75.4% on suggestive images, and 94.8% on explicit images. That lower suggestive recall is a useful reminder that the middle category remains difficult, even when the overall accuracy looks good.Since anime and illustrated images were part of training, I also wanted a separate evaluation across those domains. On another 6,000-image evaluation set, Blue-Eye achieved 91.4% accuracy on 4,000 photographs and 87.2% on 2,000 anime or illustrated images, for 90.0% combined accuracy.Those numbers aren't from the same dataset as the commercial comparison, so they shouldn't be compared directly. But they were encouraging, particularly because supporting illustrated content had been one of the goals from the beginning.Making image moderation more accessible.The original motivation for Blue-Eye wasn't really to beat a particular API on a benchmark. I wanted to explore whether developers could have a practical alternative that they could run and customize themselves.Commercial APIs still make plenty of sense. They're convenient, you don't have to manage the infrastructure, and for smaller workloads they may be the most economical choice.Self-hosting becomes interesting when you're processing larger volumes of images or want more control over your moderation pipeline. Instead of paying for every API request, you can run inference on infrastructure you manage, adjust your classification thresholds, and decide how predictions should feed into warnings, filtering, or human review.Whether that works out cheaper depends on the hardware, throughput, utilization, and maintenance costs. I think there's real potential for substantially lower inference costs in suitable deployments, but I wouldn't claim a universal cost advantage without publishing a reproducible comparison.Blue-Eye also has limitations. It handles sexual-content classification, not every kind of harmful content. It hasn't been evaluated across demographic groups, isn't intended for age estimation or specialized child sexual abuse material detection, and should be tested on a platform's own data before being used in production. It's available as an open-weight model under Meta's DINOv3 License, which has conditions developers need to review.There's still work I'd like to do on evaluation, difficult edge cases, and inference efficiency. I'd also be interested in seeing how well the results hold up when other developers test the model against their own datasets.For me, that's one of the best reasons to make projects like this publicly available. Building the model was interesting, but having other people use it for their task was equally important.If you want to check out the code, model details, or benchmark results, I've put everything that's publicly available in the repository:GitHub: https://github.com/prnshu-p/Blue-EyeI'd genuinely be interested in feedback from anyone working on image moderation, particularly developers who've tried both commercial APIs and self-hosted classifiers.