This model is a vision transformer based on the EVA architecture, fine-tuned for NSFW content classification. It has been trained
to detect four categories (neutral, low, medium, high) of visual content using 100,000 synthetically labeled images.
The model can be used as a binary (true/false) classifier if desired, or you can obtain the full output probabilities.. It outperforms other excellent publicly available models such as Falconsai/nsfw_image_detection or AdamCodd/vit-base-nsfw-detector in our internal benchmarks adding the enrichment of being able to select the NSFW level that suits your use case.
Try it Online! 🚀
You can try this model directly in your browser through our Hugging Face Space. Upload any image and get instant NSFW classification results without any installation required.
Model Performance Comparison
Global Performance
Category
Freepik
Falconsai
Adamcodd
High
99.54%
97.92%
98.62%
Medium
97.02%
78.54%
91.65%
Low
98.31%
31.25%
89.66%
Neutral
99.87%
99.27%
98.37%
In the table below, the results are obtained as follows:
For the Falconsai and AdamCodd models:
A prediction is considered correct if the image is labeled "low", "medium", or "high" and the model returns true.
If the label is "neutral", the correct output should be false.
For the Freepik model:
If the image label is "low", "medium", or "high", the model should return at least "low".
If the label is "neutral", the correct output should be "neutral".
Conclusions:
Our model outperforms AdamCodd and Falconsai in accuracy. It is entirely fair to compare them on the "high" and "neutral" labels.
Our model offers greater granularity. It is not only suitable for detecting "high" and "neutral" content, but also performs excellently at identifying "low" and "medium" NSFW content.
Falconsai may classify some "medium" and "low" images as not NSFW but mark others as safe for work(SFW), which could lead to unexpected results.
AdamCodd classifies both "low" and "medium" categories as NSFW, which may not be desirable depending on your use case. Furthermore, a 10% of images in low and medium are considered SFW.
Accuracy by AI Content
We have created a manually labeled dataset with careful attention to avoiding biases (gender, ethnicity, etc.). While the sample size is relatively small, it provides meaningful insights into model performance across different scenarios, which was very useful in the training process to avoid biases.
The following tables show detection accuracy percentages across different NSFW categories and content types:
AI-Generated Content
Category
Freepik Model
Falconsai Model
Adamcodd Model
High
100.00%
84.00%
92.00%
Medium
96.15%
69.23%
96.00%
Low
100.00%
35.71%
92.86%
Neutral
100.00%
100.00%
66.67%
Conclusions:
Avoid using Falconsai for AI-generated content to prevent prediction errors.
Our model is the best option to detect NSFW content in AI-generated content.
Usage
Quick Start via pip
pip install nsfw-image-detector
python
1from PIL import Image
2from nsfw_image_detector import NSFWDetector
3import torch
45# Initialize the detector6detector = NSFWDetector(dtype=torch.bfloat16, device="cuda")78# Load and classify an image9image = Image.open("your_image")1011# Check if the image contains NSFW content sentivity level medium or higher12is_nsfw = detector.is_nsfw(image,"medium")1314# Get probability scores for all categories15probabilities = detector.predict_proba(image)16print(f"Is NSFW: {is_nsfw}")17print(f"Probabilities: {probabilities}")
Note: If the intention is to use the model in production review Speed and Memory Metrics section before using this approach.
Avoid installation of pip dependency
The following example demonstrates how to customize the NSFW detection label, it is very similar to the code in PyPy. This code returns True if the NSFW level is 'medium' or higher:
python
1from transformers import AutoModelForImageClassification
2import torch
3from PIL import Image
4from typing import List, Dict
5import torch.nn.functional as F
6from timm.data.transforms_factory import create_transform
7from torchvision.transforms import Compose
8from timm.data import resolve_data_config
9from timm.models import get_pretrained_cfg
101112device ="cuda"if torch.cuda.is_available()else"cpu"1314# Load model and processor15model = AutoModelForImageClassification.from_pretrained("Freepik/nsfw_image_detector", torch_dtype = torch.bfloat16).to(device)1617# Load original processor (faster for tensors)18cfg = get_pretrained_cfg("eva02_base_patch14_448.mim_in22k_ft_in22k_in1k")19processor: Compose = create_transform(**resolve_data_config(cfg.__dict__))2021defpredict_batch_values(model, processor: Compose, img_batch: List[Image.Image]| torch.Tensor)-> List[Dict[str,float]]:22"""
23 Process a batch of images and return prediction scores for each NSFW category
24 """25 idx_to_label ={0:'neutral',1:'low',2:'medium',3:'high'}2627# Prepare batch28 inputs = torch.stack([processor(img)for img in img_batch])29 output =[]30with torch.inference_mode():31 logits = model(inputs).logits
32 batch_probs = F.log_softmax(logits, dim=-1)33 batch_probs = torch.exp(batch_probs).cpu()3435for i inrange(len(batch_probs)):36 element_probs = batch_probs[i]37 output_img ={}38 danger_cum_sum =03940for j inrange(len(element_probs)-1,-1,-1):41 danger_cum_sum += element_probs[j]42if j ==0:43 danger_cum_sum = element_probs[j]44 output_img[idx_to_label[j]]= danger_cum_sum.item()45 output.append(output_img)4647return output
4849defprediction(model, processor, img_batch: List[Image.Image], class_to_predict:str, threshold:float=0.5)-> List[bool]:50"""
51 Predict if images meet or exceed a specific NSFW threshold
52 """53if class_to_predict notin["low","medium","high"]:54raise ValueError("class_to_predict must be one of: low, medium, high")5556ifnot0<= threshold <=1:57raise ValueError("threshold must be between 0 and 1")5859 output = predict_batch_values(model, processor, img_batch)60return[output[i][class_to_predict]>= threshold for i inrange(len(output))]6162# Example usage63image = Image.open("path/to/your/image.jpg")64print(predict_batch_values(model, processor,[image]))65print(prediction(model, processor,[image],"medium"))# Options: low, medium, high
Note: The sum is higher than one because the prediction is the cumulative sum of all labels equal to or higher than your selected label, except neutral. For instance, if you select 'medium', it is the sum of 'medium' and 'high'. In our opinion, this approach is more effective than selecting only the highest probability label.
Training
100,000 images were used during training.
The model were trained for 3 epochs on 3 NVIDIA GeForce RTX 3090
The model were trained using two sets, training and validation.
There are no images with a cosine similarity higher than 0.92 to avoid duplicates and biases between training and validation. The model used for deduplication is "openai/clip-vit-base-patch32"
A custom loss was created to minimize predictions that are lower than the true class. For instance, it is very rare for an image labeled as 'high' to be predicted as 'neutral' (this only happens 0.46% of the time).
Speed and Memory Metrics
Batch Size
Avg by batch (ms)
VRAM (MB)
Optimizations
1
28
540
BF16 using PIL images
4
110
640
BF16 using PIL images
16
412
1144
BF16 using PIL images
1
10
540
BF16 using torch tensor
4
33
640
BF16 using torch tensor
16
102
1144
BF16 using torch tensor
Notes:
The model has been trained in bf16 so it is recommended to use it in bf16.
Using torch tensor: The speed using torch tensor is not achieved using pipeline. Avoid pipeline use in production.
Measurements taken on NVIDIA RTX 3090, expect better metrics in more powerful servers.
Throughput increases with larger batch sizes due to better GPU utilization. Consider your use case when selecting batch size.
Optimizations listed are suggestions that could further improve performance.
Using torch tensors is specially indicated in cases such as use the model for text to image models or similar because the output is already in tensor format.
License
This project is licensed under the MIT License - Copyright 2025 Freepik Company S.L.
Citation
If you use this model in your research or project, please cite it as:
bibtex
1@software{freepik2025nsfw,
2 title={EVA-based Fast NSFW Image Classifier},
3 author={Freepik Company S.L.},
4 year={2025},
5 publisher={Hugging Face},
6 url = {https://huggingface.co/Freepik/nsfw_image_detector},
7 organization = {Freepik Company S.L.}
8}
1@article{EVA02,
2 title={EVA-02: A Visual Representation for Neon Genesis},
3 author={Fang, Yuxin and Sun, Quan and Wang, Xinggang and Huang, Tiejun and Wang, Xinlong and Cao, Yue},
4 journal={arXiv preprint arXiv:2303.11331},
5 year={2023}
6}