Skip to content

Commit eac64f7

Browse files
authored
Add DINOv3 models (#131)
- facebook/dinov3-vits16-pretrain-lvd1689m - facebook/dinov3-vits16plus-pretrain-lvd1689m - facebook/dinov3-vitb16-pretrain-lvd1689m - facebook/dinov3-vitl16-pretrain-lvd1689m - facebook/dinov3-vith16plus-pretrain-lvd1689m - facebook/dinov3-vitl16-pretrain-sat493m
1 parent ce628ab commit eac64f7

9 files changed

Lines changed: 96 additions & 15 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ usls = "latest-version"
6666
| [MobileOne](https://github.com/apple/ml-mobileone) | Image Classification | [demo](examples/mobileone) |
6767
| [DeiT](https://github.com/facebookresearch/deit) | Image Classification | [demo](examples/deit) |
6868
| [DINOv2](https://github.com/facebookresearch/dinov2) | Vision Embedding | [demo](examples/dinov2) |
69+
| [DINOv3](https://github.com/facebookresearch/dinov3) | Vision Embedding | [demo](examples/dinov3) |
6970
| [YOLOv5](https://github.com/ultralytics/yolov5) | Image Classification<br />Object Detection<br />Instance Segmentation | [demo](examples/yolo) |
7071
| [YOLOv6](https://github.com/meituan/YOLOv6) | Object Detection | [demo](examples/yolo) |
7172
| [YOLOv7](https://github.com/WongKinYiu/yolov7) | Object Detection | [demo](examples/yolo) |

examples/dinov2/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ fn main() -> Result<()> {
1717
let mut model = DINOv2::new(config)?;
1818

1919
// encode images
20-
let y = model.encode_images(&xs)?;
21-
println!("Feat shape: {:?}", y.shape());
20+
let feats = model.encode_images(&xs)?;
21+
println!("Feat shape: {:?}", feats.shape());
2222

2323
usls::perf(false);
2424

examples/dinov3/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
This demo showcases how to use `DINOv2` to compute image similarity, applicable for image-to-image retrieval tasks.
2+
3+
## Quick Start
4+
5+
```shell
6+
cargo run -r --example dinov2
7+
```

examples/dinov3/main.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use anyhow::Result;
2+
use usls::{models::DINOv3, Config, DataLoader};
3+
4+
/// DINOv3 Example
5+
#[derive(argh::FromArgs)]
6+
struct Args {
7+
/// cpu:0, cuda:0
8+
#[argh(option, default = "String::from(\"cpu:0\")")]
9+
device: String,
10+
11+
/// fp32, fp16, q8, q4, q4f16, bnb4
12+
#[argh(option, default = "String::from(\"fp16\")")]
13+
dtype: String,
14+
}
15+
16+
fn main() -> Result<()> {
17+
tracing_subscriber::fmt()
18+
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
19+
.with_timer(tracing_subscriber::fmt::time::ChronoLocal::rfc_3339())
20+
.init();
21+
let args: Args = argh::from_env();
22+
23+
// images
24+
let xs = DataLoader::try_read_n(&["./assets/bus.jpg", "./assets/bus.jpg"])?;
25+
26+
// model
27+
let config = Config::dinov3_vits16_lvd1689m()
28+
.with_batch_size_all(xs.len())
29+
.with_dtype_all(args.dtype.parse()?)
30+
.with_device_all(args.device.parse()?)
31+
.commit()?;
32+
let mut model = DINOv3::new(config)?;
33+
34+
// encode images
35+
let feats = model.encode_images(&xs)?;
36+
println!("Feat shape: {:?}", feats.shape());
37+
38+
usls::perf(false);
39+
40+
Ok(())
41+
}

src/models/dinov2/impl.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
use aksr::Builder;
22
use anyhow::Result;
33

4-
use crate::{elapsed_module, Config, Engine, Image, Processor, Scale, Xs, X};
4+
use crate::{elapsed_module, Config, Engine, Image, Processor, Xs, X};
55

66
#[derive(Builder, Debug)]
77
pub struct DINOv2 {
88
engine: Engine,
99
height: usize,
1010
width: usize,
1111
batch: usize,
12-
dim: usize,
1312
processor: Processor,
1413
}
1514

@@ -21,14 +20,6 @@ impl DINOv2 {
2120
engine.try_height().unwrap_or(&384.into()).opt(),
2221
engine.try_width().unwrap_or(&384.into()).opt(),
2322
);
24-
let dim = match &config.scale {
25-
Some(Scale::S) => 384,
26-
Some(Scale::B) => 768,
27-
Some(Scale::L) => 1024,
28-
Some(Scale::G) => 1536,
29-
Some(x) => anyhow::bail!("Unsupported scale: {:?}", x),
30-
None => anyhow::bail!("No model scale specified"),
31-
};
3223
let processor = Processor::try_from_config(&config.processor)?
3324
.with_image_width(width as _)
3425
.with_image_height(height as _);
@@ -38,14 +29,12 @@ impl DINOv2 {
3829
height,
3930
width,
4031
batch,
41-
dim,
4232
processor,
4333
})
4434
}
4535

4636
fn preprocess(&mut self, xs: &[Image]) -> Result<Xs> {
4737
let x = self.processor.process_images(xs)?;
48-
4938
Ok(x.into())
5039
}
5140

@@ -57,7 +46,6 @@ impl DINOv2 {
5746
let xs = elapsed_module!("DINOv2", "visual-preprocess", self.preprocess(xs)?);
5847
let xs = elapsed_module!("DINOv2", "visual-inference", self.inference(xs)?);
5948
let x = elapsed_module!("DINOv2", "visual-postprocess", xs[0].to_owned());
60-
6149
Ok(x)
6250
}
6351
}

src/models/dinov3/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# DINOv3
2+
3+
## Official Repository
4+
5+
The official repository can be found on: [GitHub](https://github.com/facebookresearch/dinov3)
6+
7+
## Example
8+
9+
Refer to the [example](../../../examples/dinov3)

src/models/dinov3/config.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/// Model configuration for `DINOv3`
2+
impl crate::Config {
3+
pub fn dinov3() -> Self {
4+
Self::dinov2().with_name("dinov3")
5+
}
6+
7+
pub fn dinov3_vits16_lvd1689m() -> Self {
8+
Self::dinov3().with_model_file("vits16-pretrain-lvd1689m.onnx")
9+
}
10+
11+
pub fn dinov3_vits16plus_lvd1689m() -> Self {
12+
Self::dinov3().with_model_file("vits16plus-pretrain-lvd1689m.onnx")
13+
}
14+
15+
pub fn dinov3_vitb16_lvd1689m() -> Self {
16+
Self::dinov3().with_model_file("vitb16-pretrain-lvd1689m.onnx")
17+
}
18+
19+
pub fn dinov3_vitl16_lvd1689m() -> Self {
20+
Self::dinov3().with_model_file("vitl16-pretrain-lvd1689m.onnx")
21+
}
22+
23+
pub fn dinov3_vith16plus_lvd1689m() -> Self {
24+
Self::dinov3().with_model_file("vith16plus-pretrain-lvd1689m.onnx")
25+
}
26+
27+
pub fn dinov3_vitl16_sat493m() -> Self {
28+
Self::dinov3().with_model_file("vitl16-pretrain-sat493m.onnx")
29+
}
30+
}

src/models/dinov3/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mod config;
2+
3+
pub type DINOv3 = crate::DINOv2;

src/models/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod deit;
1111
mod depth_anything;
1212
mod depth_pro;
1313
mod dinov2;
14+
mod dinov3;
1415
mod dwpose;
1516
mod fast;
1617
mod fastvit;
@@ -47,6 +48,7 @@ pub use db::*;
4748
pub use depth_anything::*;
4849
pub use depth_pro::*;
4950
pub use dinov2::*;
51+
pub use dinov3::*;
5052
pub use florence2::*;
5153
pub use grounding_dino::*;
5254
pub use mediapipe_segmenter::*;

0 commit comments

Comments
 (0)