Files in This Repository
Table with columns: Artefact, Purpose, Consumed by| Artefact | Purpose | Consumed by |
|---|
adapter_model.safetensors + adapter_config.json | LoRA adapter (about 119 MB, r=16, α=32) on top of google/gemma-4-E2B-it | PEFT / Unsloth pipelines |
gemma-4-E2B-it-oceanguard-Q4_K_M.gguf | Adapter merged into the base model and quantized to Q4_K_M (about 3.4 GB, 5.88 bits per weight; the 262k-token vocabulary dominates the size). Text decoder only, llama.cpp compatible | OceanGuard Android app via LlamaTextEngine, or any llama.cpp client |
tokenizer.json, tokenizer_config.json, chat_template.jinja, processor_config.json | Tokenizer, chat template and processor configuration saved with the adapter | Transformers / PEFT / Unsloth |
A LiteRT-LM build (.litertlm) is pending; see Deployment.
Model Description
OceanGuard AI runs Gemma 4 E2B fully on-device for open-vocabulary analysis of marine debris.
This adapter aligns the model with the structured output contract that the Android application
consumes: a JSON array of {box_2d, label, material} objects, where box_2d is
[y_min, x_min, y_max, x_max] on a 0-1000 grid and label is one of eight snake_case classes:
plastic_bottle, metal_can, fishing_net, glove, face_mask, metal_debris,
plastic_debris, tire. The application maps these labels onto its ecological-impact families
for the health score and report generation.
The adapter is a standard PEFT LoRA (rank 16, α = 32, no dropout) attached to the attention
(q/k/v/o_proj) and MLP (gate/up/down_proj) projections. It was trained on the 4-bit
quantized base model (QLoRA) with Unsloth in bf16.
Intended Use
In-scope.
- Mobile and edge marine-debris detection for citizen science, NGO field operations and coastal
monitoring campaigns.
- Research baselines for open-vocabulary detection over specialised environmental taxonomies.
- A grounding component for tool-augmented reporting pipelines (see the OceanGuard agentic
tool-calling architecture).
Out-of-scope.
- Autonomous decision-making (cleanup dispatch, regulatory enforcement, environmental fines).
This model is a triage and reporting aid; final decisions must remain with a qualified human.
- Real-time safety-critical detection (collision avoidance, navigation). Latency is of the order
of seconds per image.
- General-purpose object detection outside the marine-debris domain; the adapter narrows the
visual prior towards marine debris and may degrade on unrelated tasks.
Training Data
Table with columns: Part, Images, Instances, Notes| Part | Images | Instances | Notes |
|---|
| Real TRAIN (CleanSea, Neural_Ocean, Ocean_garbage) | 10,245 | 21,123 | all images of the TRAIN partition (767 CleanSea / 3,129 Neural_Ocean / 6,349 Ocean_garbage) |
| Synthetic | 5,000 | 19,500 | random sample (seed 42) of a clean batch of copy-paste composites made with the authors' synthetic data generator |
| Total | 15,245 | | 33 % synthetic |
Real images come from three public marine-debris datasets, including the CleanSea corpus
introduced by the model author (IbPRIA 2022):
Table with columns: Source, License, Annotations| Source | License | Annotations |
|---|
| CleanSea | Non-profit research or educational use (per dataset page) | COCO boxes, mapped to 8 classes |
| Ocean_garbage | Roboflow Universe per-dataset terms | COCO boxes, mapped to 8 classes |
| Neural_Ocean | Roboflow Universe per-dataset terms | COCO boxes, mapped to 8 classes |
The corpus is partitioned by group (for example, all images of a CleanSea dive, or sharing a
source-file name key, go to the same partition), so no group of the evaluation subsets appears in
training.
Training instances per class: Bottle 4,333, Can 412, Fishing_Net 2,812, Glove 2,582, Mask 3,164,
Metal_Debris 102, Plastic_Debris 3,957, Tire 3,761 (real images only).
Geographic coverage. The three sources were collected predominantly in coastal waters around
Japan and the wider north-western Pacific, so the training distribution is biased towards the
debris types, water clarity and lighting of that region. Validate on a local hold-out before
operational use elsewhere.
Re-distributors of the training corpus must comply with the original dataset licenses.
Training Procedure
Unsloth FastVisionModel, one workstation GPU, bf16 compute over a 4-bit base model. LoRA is
attached to the attention and MLP projections selected by module name, which matches both the
language tower and the vision encoder: the saved adapter has non-zero low-rank updates in both
(245 pairs in the language tower, 112 in the vision encoder). The vision_lora switch of the training
configuration had no effect on which modules were adapted (see Limitations).
Table with columns: Hyper-parameter, Value| Hyper-parameter | Value |
|---|
| Base model | unsloth/gemma-4-E2B-it (4-bit load) |
LoRA r / α / dropout | 16 / 32 / 0.0 |
| Target modules | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj |
| Optimiser | adamw_8bit, learning rate 1e-4, cosine schedule, weight decay 0.01, warm-up ratio 0.1, max grad norm 1.0 |
| Batch size | 4 per device × 8 gradient accumulation = 32 effective |
| Epochs / optimisation steps | 3 / 1,431 |
| Sequence length / image token budget | 1,024 / 64 |
| Seed | 42 |
| Loss | causal-LM over the assistant JSON answer (box_2d + label + material) |
Mean training loss over the run: 0.851 (the synthetic images raise it relative to a real-only run).
Wall-clock 12,287 s (3.4 h) on a single NVIDIA RTX 5090 (32 GiB), Windows 11, CUDA 12.8; peak
allocated GPU memory 20.6 GB.
Software: unsloth 2026.5.2, transformers 5.5.0, peft 0.19.1, torch 2.12 (nightly, CUDA 12.8), bitsandbytes.
The adapter file holds 786 LoRA tensors (393 A/B pairs, about 31 M parameters; see Limitations for
their distribution across towers).
Evaluation
Protocol
- Data. Two stratified subsets of the group-aware partition, drawn with seed 42:
TEST-200 (200 images, 433 instances: 28 CleanSea / 64 Neural_Ocean / 108 Ocean_garbage;
reported results) and VAL-100 (100 images, 218 instances: 23 / 33 / 44; used to choose among
configurations). Stratification is by the rarest class present in each image, with a minimum of 10
images per label. This deliberately over-represents rare classes: Metal_Debris is 3.5 % of the
instances of TEST-200 against 0.5 % of the full TEST partition (2,207 images), so global figures are
not estimates of full-partition performance. Annotations and download instructions are in
asferrer/oceanguard-marine-debris-eval-1000
(annotations only, no images).
- Inference. Same system and user prompt for all models (shown below), greedy decoding, at most
256 new tokens, JSON answers parsed into boxes; unparseable answers count as no detections.
- Metric. mAP@0.5 with 11-point interpolated AP per class, averaged over the 8 classes, with every
detection at score 1.0 (the model emits no confidences). A class with no prediction scores 0.
A COCO-style evaluator (101-point AP,
pycocotools) is also reported.
- Intervals. 95 % basic bootstrap intervals over images (1,000 resamples, seed 42, the same
resamples for all configurations so differences are paired).
- Latency. Mean seconds per image on the RTX 5090 while other heavy processes were running on the
machine; indicative only.
Configurations compared
Table with columns: Configuration, Adapted modules, Training data, Steps| Configuration | Adapted modules | Training data | Steps |
|---|
| Base | none | none | none |
LoRA, real only (exp10g) | language + vision attention/MLP | 10,245 real | 963 |
LoRA, real only, second run (exp12g) | same as exp10g | 10,245 real | 963 |
LoRA, real + synthetic (exp11g) — this repository | same as exp10g | 10,245 real + 5,000 synthetic | 1,431 |
exp12g was launched with vision_lora: true, but its adapter has exactly the same structure as
exp10g (the switch had no effect), so it is a second run of the real-only configuration with the same
seed; the gap between the two runs is an indication of run-to-run variability.
Aggregate
Table with columns: Configuration, TEST-200 mAP@0.5, 95 % interval, VAL-100 mAP@0.5, JSON valid (TEST), Predictions (TEST), Latency (s, TEST)| Configuration | TEST-200 mAP@0.5 | 95 % interval | VAL-100 mAP@0.5 | JSON valid (TEST) | Predictions (TEST) | Latency (s, TEST) |
|---|
Base gemma-4-E2B-it | 0.1381 | [0.106, 0.187] | 0.1081 | 0.990 | 183 | 3.19 |
LoRA, real only (exp10g) | 0.2948 | [0.227, 0.335] | 0.2570 | 0.935 | 300 | 9.03 |
LoRA, real only, second run (exp12g) | 0.2825 | [0.211, 0.319] | 0.2063 | 0.975 | 342 | 7.75 |
LoRA, real + synthetic (exp11g, this repo) | 0.2941 | [0.209, 0.320] | 0.2820 | 0.980 | 313 | 7.04 |
With the COCO-style evaluator the TEST-200 mAP@0.5 is 0.1073 (base), 0.2780, 0.2704 and 0.3003 for the
three LoRA rows in the order above (VAL-100: 0.0942, 0.2461, 0.2017, 0.2792).
Paired differences on TEST-200 (95 % basic bootstrap interval):
Table with columns: Comparison, Difference in mAP@0.5| Comparison | Difference in mAP@0.5 |
|---|
exp10g − base | +0.157 [0.075, 0.190] |
exp12g − base | +0.144 [0.056, 0.177] |
exp11g − base (this repo) | +0.156 [0.045, 0.178] |
exp11g − exp10g | −0.001 [−0.072, 0.026] |
exp12g − exp10g | −0.012 [−0.054, 0.021] |
exp12g − exp11g | −0.012 [−0.043, 0.049] |
All three adapters improve clearly over the base model, and the intervals of the differences between
adapters include zero on TEST-200: adding synthetic data did not change the global mAP, and the two
runs of the real-only configuration differ by 0.012 on TEST-200 but by 0.051 on VAL-100. exp11g was chosen because it had the best mAP on VAL-100
(0.2820 against 0.2570 and 0.2063), although the spread between the two real-only runs on VAL-100
shows that this choice is within run-to-run variability; it also has the highest JSON validity and the lowest (indicative) latency
among the adapters.
Per-class mAP@0.5, TEST-200
n is the number of ground-truth instances of the class in TEST-200.
Table with columns: Class, n, Base, exp10g, exp12g, exp11g (this repo), Δ (exp11g − base)| Class | n | Base | exp10g | exp12g | exp11g (this repo) | Δ (exp11g − base) |
|---|
| Bottle | 98 | 0.190 | 0.411 | 0.353 | 0.393 | +0.203 |
| Can | 35 | 0.000 | 0.045 | 0.061 | 0.091 | +0.091 |
| Fishing_Net | 52 | 0.294 | 0.436 | 0.377 | 0.406 | +0.113 |
| Glove | 63 | 0.118 | 0.426 | 0.511 | 0.451 | +0.334 |
| Mask | 67 | 0.091 | 0.251 | 0.250 | 0.343 | +0.253 |
| Metal_Debris | 15 | 0.227 | 0.091 | 0.091 | 0.000 | −0.227 |
| Plastic_Debris | 58 | 0.139 | 0.488 | 0.453 | 0.491 | +0.352 |
| Tire | 45 | 0.045 | 0.210 | 0.164 | 0.177 | +0.132 |
The adapter improves seven of the eight classes. Metal_Debris (15 instances in TEST-200, 102 in
training) is the only class where the base model is better, and the released adapter does not detect it
(0.000, the other adapters reach 0.091). Can (35 instances) is still weak. Per-class figures on so few
instances are very noisy; the 5,000 synthetic images (2,041 Metal_Debris and 2,344 Can instances) did not
rescue these two classes.
Per-source mAP@0.5, TEST-200
Table with columns: Source, n images, Base, exp10g, exp12g, exp11g (this repo), exp11g / base| Source | n images | Base | exp10g | exp12g | exp11g (this repo) | exp11g / base |
|---|
| Global | 200 | 0.138 | 0.295 | 0.282 | 0.294 | 2.13x |
| CleanSea | 28 | 0.163 | 0.260 | 0.202 | 0.177 | 1.09x |
| Neural_Ocean | 64 | 0.089 | 0.321 | 0.278 | 0.357 | 4.01x |
| Ocean_garbage | 108 | 0.121 | 0.299 | 0.291 | 0.346 | 2.85x |
The gain concentrates in Neural_Ocean and Ocean_garbage (Roboflow-exported imagery); on CleanSea
(28 images) the released adapter improves only by +0.014. The per-source and per-class tables can be
recomputed from the cached predictions with scripts/compute_per_source_map.py in the
evaluation dataset repository.
Prompt used for detection
System: You are a marine debris detection system. Output ONLY valid JSON arrays. Never include explanations, markdown, or text outside the JSON.
User (image + text):
Detect ALL marine debris and litter in this image. Output ONLY a JSON array. For each object, provide:- "box_2d": bounding box as [y_min, x_min, y_max, x_max], integers 0-1000- "label": ONE of these 8 labels (snake_case, lowercase): plastic_bottle, metal_can, fishing_net, glove, face_mask, metal_debris, plastic_debris, tire- "material": Plastic, Metal, Glass, Rubber, Fabric, Latex Output format:[{"box_2d": [y_min, x_min, y_max, x_max], "label": "object_type", "material": "material_type"}] If no debris is found, output: []
Deployment
Table with columns: Step, Tooling, Status| Step | Tooling | Status |
|---|
| Train LoRA | Unsloth FastVisionModel | Done |
| Publish adapter | Hugging Face Hub | Done (this repository) |
| Use adapter via Transformers / PEFT / Unsloth | model.load_adapter(...) | Done |
| Merge adapter into the base model (float16) | manual W + (α/r)·B·A merge | Done |
| Convert merged model to GGUF f16 and quantize to Q4_K_M | llama.cpp convert_hf_to_gguf.py, llama-quantize | Done: gemma-4-E2B-it-oceanguard-Q4_K_M.gguf |
| Wire the GGUF to the Android app | LlamaTextEngine + llama.cpp | Done (downloaded from this repository by the app) |
Export merged model to LiteRT-LM (.litertlm) | MediaPipe converter / ai-edge-torch | Pending |
| On-device latency of the adapted model | Android test device | Pending |
The GGUF contains the merged text decoder only (no vision encoder or multimodal projector). To
send images through llama.cpp you need a multimodal projector (mmproj) for Gemma 4 E2B, which is not
part of this repository.
GGUF download
curl -L -o gemma-4-E2B-it-oceanguard-Q4_K_M.gguf \ "https://huggingface.co/asferrer/gemma-4-E2B-it-oceanguard-marine-debris/resolve/main/gemma-4-E2B-it-oceanguard-Q4_K_M.gguf" ./llama-cli -m gemma-4-E2B-it-oceanguard-Q4_K_M.gguf -n 256 --temp 0.0 -p "..."
Limitations
- Small evaluation subsets. TEST-200 has 200 images and VAL-100 has 100; rare classes are
over-represented by design. Intervals are wide (about ±0.06 around 0.29) and per-class and
per-source numbers, especially
Metal_Debris (15 instances), Can (35) and CleanSea (28 images),
are noisy.
- No measurable benefit from synthetic data in global TEST-200 mAP; the choice of this adapter
rests on VAL-100, within run-to-run variability.
Metal_Debris is not detected (mAP 0.000) and Can is weak (0.091). Operators should expect
silent misses on these classes.
- JSON validity is 98 % on TEST-200 (93.5 % to 97.5 % for the other adapters): malformed answers
are dropped by the parser and yield an empty detection set.
- Both towers are adapted. Target modules were selected by name, so the adapter holds low-rank
updates for the language tower and for same-named projections of the vision encoder (112 pairs,
about 4.5 M parameters, non-zero), plus all-zero updates for the audio encoder (36 pairs, no effect).
Loading the adapter with PEFT applies all of them; the GGUF contains only the language-tower part,
so its outputs can differ from the PEFT adapter. The separate contribution of the vision-encoder
updates has not been ablated.
- Geographic and capture bias. Training imagery is predominantly from Japan and the north-western
Pacific; performance elsewhere is not measured. Synthetic composites can inject lighting biases.
- Fixed taxonomy. Eight classes; other debris types are mapped to the closest class or missed.
- Latency figures were measured with other heavy processes on the machine and are indicative.
- Not certified. Not for legal, regulatory or environmental-enforcement reporting. The OceanGuard
app produces draft reports that a human reviews.
- Function-calling untouched. The fine-tune targets the detection output format and is not meant
to change tool-calling behaviour.
Bias, Risks and Safety
- Spurious correlations. Debris classes co-occur with characteristic backgrounds (for example nets
with rocky shorelines); the model may exploit context cues that do not generalise across geographies.
- Sensitive categories. Medical waste is rare and high-stakes; positive detections should trigger
human handling protocols rather than autonomous action.
- Open-vocabulary misuse. The model can be prompted to label arbitrary objects; downstream
applications should constrain inputs to the marine-debris domain and filter implausible outputs.
- Privacy. In the OceanGuard app, photos are analysed on-device and never leave the phone; the
adapter itself processes no user data. Outside the app, operators are responsible for compliance
with applicable privacy regulation.
How to Use
A. PEFT + Unsloth
from unsloth import FastVisionModel model, tokenizer = FastVisionModel.from_pretrained( "unsloth/gemma-4-E2B-it", load_in_4bit=True,)model.load_adapter( "asferrer/gemma-4-E2B-it-oceanguard-marine-debris", adapter_name="oceanguard",)model.set_adapter("oceanguard")FastVisionModel.for_inference(model)
Use the detection prompt shown in Evaluation and greedy decoding
(temperature = 0, max_new_tokens = 256), then parse the answer as a JSON array. An end-to-end
example is in the OceanGuard repository.
B. llama.cpp (GGUF Q4_K_M)
See GGUF download. The OceanGuard Android app downloads and loads this file through
its "Gemma 4 FT (GGUF)" provider using LlamaTextEngine (llama.cpp).
License and Citation
- LoRA adapter: Apache 2.0.
- Base model:
google/gemma-4-E2B-it, subject to the Gemma Terms of Use. The merged GGUF is a
derivative of the base model and is also subject to those terms.
- Training data: source-dataset licenses apply (see the table in Training Data).
If you use this adapter, please cite the adapter, the application and the article:
@misc{sanchezferrer2026oceanguard_adapter, author = {S{\'a}nchez-Ferrer, Alejandro}, title = {{Gemma 4 E2B OceanGuard Marine Debris LoRA Adapter}}, year = {2026}, howpublished = {Hugging Face Model Hub}, note = {LoRA adapter for google/gemma-4-E2B-it. Apache 2.0.}, url = {https://huggingface.co/asferrer/gemma-4-E2B-it-oceanguard-marine-debris}} @misc{sanchezferrer2026oceanguard_app, author = {S{\'a}nchez-Ferrer, Alejandro}, title = {{OceanGuard AI: Fully Offline Marine Debris Intelligence with Gemma 4 and Two-Phase Tool Calling}}, year = {2026}, howpublished = {Kaggle Gemma 4 Good Hackathon (Global Resilience track)}, url = {https://github.com/asferrer/OceanguardAI-App}} @misc{sanchezferrer2026synthetic, author = {S{\'a}nchez-Ferrer, Alejandro and Gallego, Antonio Javier and Calvo-Zaragoza, Jorge}, title = {{When Does Synthetic Data Help Underwater Debris Detection? Gap Metrics, Data Regimes and Detector Paradigms}}, year = {2026}, howpublished = {Neurocomputing}, note = {Manuscript in preparation}}
- Sánchez-Ferrer, A., Valero-Mas, J. J., Gallego, A. J., & Calvo-Zaragoza, J. (2023).
An experimental study on marine debris location and recognition using object detection.
Pattern Recognition Letters, 168, 154-161.
doi.org/10.1016/j.patrec.2022.12.019
- Sánchez-Ferrer, A., Gallego, A. J., Valero-Mas, J. J., & Calvo-Zaragoza, J. (2022).
The CleanSea Set: A Benchmark Corpus for Underwater Debris Detection and Recognition.
IbPRIA 2022, Lecture Notes in Computer Science, Springer.
doi.org/10.1007/978-3-031-04881-4_49
- Sánchez-Ferrer, A. (2024). Modelos de difusión aplicados a la detección de objetos en el
fondo marino. Master's Thesis, Universidad de Alicante.
rua.ua.es
- Sánchez-Ferrer, A. (2021). Deep Learning aplicado a la detección de residuos en el fondo
marino. Bachelor's Thesis, Universidad de Alicante.
rua.ua.es
Acknowledgments
- Google DeepMind for releasing Gemma 4 under terms that enable open research and on-device
deployment.
- The Unsloth team for the
FastVisionModel implementation that makes a Gemma 4 vision-language
fine-tune tractable on a single workstation GPU.
- CleanSea, Ocean_garbage and Neural_Ocean dataset authors for releasing marine-debris
annotations.
- Pattern Recognition and Artificial Intelligence (PRAI) group, Universidad de Alicante, which hosts
the doctoral programme under which this work is carried out and co-authored the cited publications.