File size: 7,935 Bytes
69956a2
 
 
 
 
 
371a337
69956a2
1649c2d
 
6d36e1d
69956a2
6d36e1d
 
 
69956a2
 
1649c2d
 
69956a2
6d36e1d
69956a2
1649c2d
69956a2
1649c2d
 
6d36e1d
 
 
69956a2
 
 
41efcc3
6d36e1d
 
 
02a22b2
 
 
 
 
41efcc3
02a22b2
 
41efcc3
 
 
 
02a22b2
 
 
41efcc3
02a22b2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41efcc3
02a22b2
 
 
41efcc3
 
02a22b2
 
b84873d
02a22b2
 
 
 
 
 
 
 
 
 
 
 
41efcc3
02a22b2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41efcc3
 
02a22b2
 
41efcc3
 
 
 
 
 
 
 
 
 
 
 
02a22b2
41efcc3
 
 
02a22b2
 
 
 
 
 
 
 
 
41efcc3
 
6d36e1d
 
2b6752d
 
6bc3f9b
 
 
b84873d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6bc3f9b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2b6752d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
---
library_name: transformers
tags:
- unsloth
---

# Finetuned Gemma 3 based Hate Detection in Arabic MultiModal Memes

The rise of social media and online communication platforms has led to the spread of Arabic memes as a key form of digital expression. 
While these contents can be humorous and informative, they are also increasingly being used to spread offensive language and hate speech.
Consequently, there is a growing demand for precise analysis of content in Arabic memes. 

This work used Gemma 3 with its vision capability to effectively identify hate content within Arabic memes.
The evaluation is conducted using a dataset of Arabic memes proposed in the ArabicNLP ArGuard 2026 challenge. 
The results underscore the capacity of ***unsloth/gemma-3-4b-pt fine-tuned with Arabic memes***, to deliver the superior performance. 


The proposed solutions offer a more nuanced understanding of memes for accurate and efficient Arabic content moderation systems.
 

# Examples of Arabic Memes from ArabicNLP ArGuard 2026 challenge

# Examples

| | | |
|:-------------------------:|:-------------------------:|:-------------------------:|
|<img width="500"  height="500" src="https://cdn-uploads.huggingface.co/production/uploads/656ee240c5ac4733e9ccdd0e/Id-NC6vel4bY5rqj8DKSg.png"> |<img width="500" height="500" src="https://cdn-uploads.huggingface.co/production/uploads/656ee240c5ac4733e9ccdd0e/kMkq_AqwbeUcuOvh_FjwG.png"> |  
|<img width="500"  height="500" src="https://cdn-uploads.huggingface.co/production/uploads/656ee240c5ac4733e9ccdd0e/7QUCyWPS6drmJJfG3FXBy.png"> |<img width="500" height="500" src="https://cdn-uploads.huggingface.co/production/uploads/656ee240c5ac4733e9ccdd0e/auyA0tmV4uQ6d19uNLRoz.png"> |
|<img width="500"  height="500" src="https://cdn-uploads.huggingface.co/production/uploads/656ee240c5ac4733e9ccdd0e/1qCrsho84Ds8C_xYV4M2z.png"> |<img width="500" height="500" src="https://cdn-uploads.huggingface.co/production/uploads/656ee240c5ac4733e9ccdd0e/Kuy_hqLY-rK07qJrY_l_W.png"> |



# Finetuned Gemma 3 Embedding Model with mean pooling

``` python

import numpy as np
import torch
import torch._dynamo
from tqdm import tqdm  # Progress bar library
from unsloth import FastVisionModel

from datasets import load_dataset

instruction = "classify meme into Hateful or Not"

def convert_to_conversation(sample):
    
    lis=[]
    lis.append({"type": "text", "text": sample["text"]})
    lis.append({"type": "image", "image": sample["image"]})
                    
    conversation = [
        {
            "role": "system",
            "content": instruction,
        },
        {
            "role": "user",
            "content": lis,
        },
        {"role": "assistant", "content": [{"type": "text", "text": sample["label"]}]},
    ]
    return {"messages": conversation}
pass

dataset = load_dataset("QCRI/ArGuard-Task1",  split="dev_test")

converted_dataset = [convert_to_conversation(sample) for sample in dataset]

# 1. Disable compiler optimization conflicts
#torch._dynamo.config.disable = True
#torch._dynamo.reset()

# 2. Load your fine-tuned model and processor
model_path = "NYUAD-ComNets/Gemma3_meme_classification"
model, processor = FastVisionModel.from_pretrained(
    model_path, 
    load_in_4bit = True,
)
FastVisionModel.for_inference(model)

# Instruction context
instruction = "classify meme into Hateful or Not"

all_embeddings = []
labels_list = []  

num_iterations = len(converted_dataset)

print(f"Starting embedding extraction for {num_iterations} items...")

for idx in tqdm(range(num_iterations), desc="Extracting Embeddings"):
    try:
        sample = converted_dataset[idx]
        
        # Pull text, image, and ground-truth label
        sample_text = sample["messages"][1]["content"][0]["text"]
        sample_image = sample["messages"][1]["content"][1]["image"]
        sample_label = sample["messages"][2]["content"][0]["text"] # From training format

        # Setup multimodal conversation payload
        conversation = [
            {"role": "system", "content": instruction},
            {"role": "user", "content": [{"type": "text", "text": sample_text}, {"type": "image", "image": sample_image}]},
        ]

        # 4. Process inputs normally
        templated_text = processor.apply_chat_template(conversation, tokenize=False)
        inputs = processor(text=templated_text, images=sample_image, return_tensors="pt").to("cuda")


        # 5. Forward Pass
        with torch.no_grad():
            with torch.autocast(device_type="cuda", dtype=torch.bfloat16):
                outputs = model(**inputs, output_hidden_states=True, return_dict=True)

        # 6. Extract final layer and attention mask
        last_hidden_states = outputs.hidden_states[-1]  # [batch_size, seq_len, hidden_dim]
        attention_mask = inputs["attention_mask"]       # [batch_size, seq_len]

        # 7. Masked Mean Pooling (Ignores padding tokens entirely)
        input_mask_expanded = attention_mask.unsqueeze(-1).expand(last_hidden_states.size()).float()
        sum_embeddings = torch.sum(last_hidden_states * input_mask_expanded, dim=1)
        sum_mask = torch.clamp(input_mask_expanded.sum(dim=1), min=1e-9)
        
        all_embedding = (sum_embeddings / sum_mask).squeeze(0).float()
        
        all_embeddings.append(all_embedding.cpu().numpy())


        labels_list.append(sample_label)

    except Exception as e:
        print(f"\nSkipping row {idx} due to an error: {e}")
        continue

embedding_matrix = np.vstack(all_embeddings)

print("Final Concatenated Array Shape:", embedding_matrix.shape)

np.save("test_gemma3_mean_embeddings.npy", embedding_matrix)
```



# Finetuned Gemma 3 for Inference

``` python

import numpy as np
import torch
import torch._dynamo
from tqdm import tqdm  
from unsloth import FastVisionModel

# 1. Disable compiler optimization conflicts
torch._dynamo.config.disable = True
torch._dynamo.reset()

# 2. Load your fine-tuned model and processor
model_path = "NYUAD-ComNets/Gemma3_meme_classification"
model, processor = FastVisionModel.from_pretrained(
    model_path, 
    load_in_4bit = True,
)
FastVisionModel.for_inference(model)

dataset = load_dataset("QCRI/ArGuard-Task1", split="dev_test")

ids = []
labels = []

for n in range(500):
    print(n)

    image = dataset[n]["image"]
    text = dataset[n]["text"]

    messages = [
        {"role": "system", "content": instruction},
        {
            "role": "user",
            "content": [
                {"type": "text", "text": text},
                {"type": "image", "image": image},
            ],
        },
    ]

    input_text = processor.apply_chat_template(
        messages,
        add_generation_prompt=True
    )

    inputs = processor(
        images=image,
        text=input_text,
        add_special_tokens=False,
        return_tensors="pt",
    ).to("cuda")

    outputs = model.generate(
        **inputs,
        max_new_tokens=500,
        use_cache=True,
        temperature=0.1,
        top_p=1,
    )

    generated_ids = outputs[:, inputs["input_ids"].shape[1]:]
    result = processor.tokenizer.batch_decode(
        generated_ids,
        skip_special_tokens=True
    )[0].strip()

    print(result)

    ids.append(dataset[n]["id"])
    labels.append(result)
    
    d = pd.DataFrame({
    "id": ids,
    "label": labels,
    "run_id": ["NYUAD_run1"] * len(ids),})

d.to_csv("prediction.tsv", sep="\t", index=False)

```


We used Low-Rank Adaptation (LoRA) as the Parameter-Efficient Fine-Tuning (PEFT) method for fine-tuning utilizing the unsloth framework.


# BibTeX entry and citation info

```
@misc{aldahoul,
      title={NYUAD at ArGuard Shared Task: Multimodal Embedding Models for
Detecting Arabic Hateful Memes and Unsafe Prompts}, 
      author={Nouar AlDahoul and Yasir Zaki},
      year={2026},
      eprint={},
      archivePrefix={arXiv},
      primaryClass={cs.CL},
      url={}, 
}


```