bigshanedogg commited on
Commit
99ddb81
Β·
verified Β·
1 Parent(s): 33cffb4

Upload folder using huggingface_hub

Browse files
Files changed (6) hide show
  1. LICENSE +47 -0
  2. README.md +57 -0
  3. config.json +14 -0
  4. model.safetensors +3 -0
  5. modeling_csd.py +138 -0
  6. preprocessor_config.json +14 -0
LICENSE ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ This repository repackages, in HuggingFace format, the CSD style model from
2
+ "Measuring Style Similarity in Diffusion Models" (Somepalli et al., 2024). It is a
3
+ DERIVATIVE of the original CSD work and is NOT an official release by the CSD authors.
4
+
5
+ The licensing is mixed β€” the port code and the model weights carry different licenses:
6
+
7
+ ============================================================================
8
+ 1) PORT CODE (modeling_csd.py, configuration, processing) β€” MIT License
9
+ ============================================================================
10
+ Copyright (c) 2026-present bigshanedogg
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+
30
+ ============================================================================
31
+ 2) MODEL WEIGHTS (model.safetensors) β€” CC-BY-4.0
32
+ ============================================================================
33
+ Copyright (c) Somepalli, Gupta, Gupta, Shrivastava, Goldstein, Feizi /
34
+ University of Maryland.
35
+ Sourced from https://huggingface.co/tomg-group-umd/CSD-ViT-L (CC-BY-4.0).
36
+ You must give appropriate credit under the terms of the Creative Commons
37
+ Attribution 4.0 International License: https://creativecommons.org/licenses/by/4.0/
38
+
39
+ ----------------------------------------------------------------------------
40
+ THIRD-PARTY NOTICES
41
+
42
+ Original CSD code: MIT License, Copyright (c) 2023 the CSD authors
43
+ https://github.com/learn2phoenix/CSD
44
+
45
+ Vendored ViT-L/14 vision tower in modeling_csd.py is adapted (MODIFIED: vision tower
46
+ only, projection removed) from OpenAI CLIP, MIT License, Copyright (c) 2021 OpenAI
47
+ https://github.com/openai/CLIP
README.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: cc-by-4.0
3
+ library_name: transformers
4
+ tags:
5
+ - style-similarity
6
+ - feature-extraction
7
+ - image-feature-extraction
8
+ - csd
9
+ pipeline_tag: image-feature-extraction
10
+ ---
11
+
12
+ # CSD (ViT-L/14) β€” HuggingFace format
13
+
14
+ Unofficial `transformers`-format port of the **CSD** style model from *"Measuring Style
15
+ Similarity in Diffusion Models"* (Somepalli, Gupta, Gupta, Shrivastava, Goldstein, Feizi;
16
+ 2024). Loads via `trust_remote_code` with **no `clip` / `open_clip` runtime dependency** β€”
17
+ the OpenAI CLIP ViT-L/14 vision tower is vendored into `modeling_csd.py` and the released
18
+ CSD weights are stored as `model.safetensors`.
19
+
20
+ > **Not an official release.** Original code: https://github.com/learn2phoenix/CSD (MIT).
21
+ > Official checkpoint mirror: https://huggingface.co/tomg-group-umd/CSD-ViT-L (CC-BY-4.0).
22
+ > This repo repackages that checkpoint for `AutoModel.from_pretrained`.
23
+
24
+ ## What it is
25
+
26
+ A CLIP ViT-L/14 vision backbone (projection removed) whose pre-projection feature (1024-d)
27
+ is mapped by a learned **style** head and a **content** head to 768-d descriptors, each
28
+ L2-normalized. Style similarity between two images is the cosine of their style embeddings.
29
+
30
+ ## Usage
31
+
32
+ ```python
33
+ import torch
34
+ from PIL import Image
35
+ from transformers import AutoModel, AutoImageProcessor
36
+
37
+ model = AutoModel.from_pretrained("bigshanedogg/CSD", trust_remote_code=True).eval()
38
+ proc = AutoImageProcessor.from_pretrained("bigshanedogg/CSD", trust_remote_code=True)
39
+
40
+ px = proc(images=Image.open("a.png"), return_tensors="pt")["pixel_values"]
41
+ out = model(pixel_values=px)
42
+ style = out.embeddings # (1, 768), L2-normalized style descriptor
43
+ content = out.content_embeddings # (1, 768), L2-normalized content descriptor
44
+ ```
45
+
46
+ The image processor resizes the short side to 224 (BICUBIC), center-crops 224, and applies
47
+ the CLIP mean/std β€” matching the upstream CSD preprocessing.
48
+
49
+ ## Licensing
50
+
51
+ - Port (modeling/config/processing): **MIT** β€” Copyright (c) 2026 bigshanedogg.
52
+ - CSD original code: **MIT** β€” Copyright (c) 2023 the CSD authors (https://github.com/learn2phoenix/CSD).
53
+ - Released CSD weights (`model.safetensors`, from `tomg-group-umd/CSD-ViT-L`): **CC-BY-4.0** β€”
54
+ attribute Somepalli et al. / University of Maryland.
55
+ - Vendored ViT tower: **MIT** β€” Copyright (c) 2021 OpenAI (https://github.com/openai/CLIP), MODIFIED.
56
+
57
+ See `LICENSE` for the full notices.
config.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": ["CSDModel"],
3
+ "model_type": "csd",
4
+ "auto_map": {
5
+ "AutoConfig": "modeling_csd.CSDConfig",
6
+ "AutoModel": "modeling_csd.CSDModel"
7
+ },
8
+ "image_resolution": 224,
9
+ "patch_size": 14,
10
+ "width": 1024,
11
+ "layers": 24,
12
+ "heads": 16,
13
+ "embed_dim": 768
14
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7fac618eef38cacebf3644ad805f7ada77f1d2ef9fe24ac8a7254312bf060eb5
3
+ size 1219046216
modeling_csd.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CSD (HuggingFace format) β€” unofficial port. Copyright (c) 2026 bigshanedogg. MIT License.
2
+ #
3
+ # Self-contained transformers port of the CSD style model from
4
+ # "Measuring Style Similarity in Diffusion Models" (Somepalli et al., 2024)
5
+ # https://github.com/learn2phoenix/CSD (code: MIT)
6
+ # so it loads via AutoModel.from_pretrained(trust_remote_code=True) without the `clip`
7
+ # package. The ViT-L/14 vision transformer below is vendored from OpenAI CLIP
8
+ # https://github.com/openai/CLIP (MIT, (c) 2021 OpenAI) β€” MODIFIED: trimmed to the
9
+ # vision tower, projection removed (folded into the CSD style/content heads).
10
+ # The released CSD checkpoint (tomg-group-umd/CSD-ViT-L) is CC-BY-4.0.
11
+
12
+ from collections import OrderedDict
13
+ from typing import Optional
14
+
15
+ import torch
16
+ import torch.nn as nn
17
+ from transformers import PretrainedConfig, PreTrainedModel
18
+ from transformers.modeling_outputs import ModelOutput
19
+
20
+
21
+ class CSDConfig(PretrainedConfig):
22
+ model_type = "csd"
23
+
24
+ def __init__(
25
+ self,
26
+ image_resolution: int = 224,
27
+ patch_size: int = 14,
28
+ width: int = 1024,
29
+ layers: int = 24,
30
+ heads: int = 16,
31
+ embed_dim: int = 768,
32
+ **kwargs,
33
+ ):
34
+ self.image_resolution = image_resolution
35
+ self.patch_size = patch_size
36
+ self.width = width
37
+ self.layers = layers
38
+ self.heads = heads
39
+ self.embed_dim = embed_dim # style/content projection output dim
40
+ super().__init__(**kwargs)
41
+
42
+
43
+ # ── vendored OpenAI CLIP vision tower (MIT, (c) 2021 OpenAI; MODIFIED) ──────────────
44
+ class QuickGELU(nn.Module):
45
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
46
+ return x * torch.sigmoid(1.702 * x)
47
+
48
+
49
+ class ResidualAttentionBlock(nn.Module):
50
+ def __init__(self, d_model: int, n_head: int):
51
+ super().__init__()
52
+ self.attn = nn.MultiheadAttention(d_model, n_head)
53
+ self.ln_1 = nn.LayerNorm(d_model)
54
+ self.mlp = nn.Sequential(
55
+ OrderedDict(
56
+ [
57
+ ("c_fc", nn.Linear(d_model, d_model * 4)),
58
+ ("gelu", QuickGELU()),
59
+ ("c_proj", nn.Linear(d_model * 4, d_model)),
60
+ ]
61
+ )
62
+ )
63
+ self.ln_2 = nn.LayerNorm(d_model)
64
+
65
+ def attention(self, x: torch.Tensor) -> torch.Tensor:
66
+ return self.attn(x, x, x, need_weights=False, attn_mask=None)[0]
67
+
68
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
69
+ x = x + self.attention(self.ln_1(x))
70
+ x = x + self.mlp(self.ln_2(x))
71
+ return x
72
+
73
+
74
+ class Transformer(nn.Module):
75
+ def __init__(self, width: int, layers: int, heads: int):
76
+ super().__init__()
77
+ self.resblocks = nn.Sequential(*[ResidualAttentionBlock(width, heads) for _ in range(layers)])
78
+
79
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
80
+ return self.resblocks(x)
81
+
82
+
83
+ class VisionTransformer(nn.Module):
84
+ def __init__(self, input_resolution: int, patch_size: int, width: int, layers: int, heads: int):
85
+ super().__init__()
86
+ self.conv1 = nn.Conv2d(3, width, kernel_size=patch_size, stride=patch_size, bias=False)
87
+ _scale = width**-0.5
88
+ self.class_embedding = nn.Parameter(_scale * torch.randn(width))
89
+ _num_positions = (input_resolution // patch_size) ** 2 + 1
90
+ self.positional_embedding = nn.Parameter(_scale * torch.randn(_num_positions, width))
91
+ self.ln_pre = nn.LayerNorm(width)
92
+ self.transformer = Transformer(width, layers, heads)
93
+ self.ln_post = nn.LayerNorm(width)
94
+ # NOTE: CSD sets backbone.proj = None and folds projection into last_layer_{style,content}.
95
+
96
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
97
+ x = self.conv1(x) # (B, width, grid, grid)
98
+ x = x.reshape(x.shape[0], x.shape[1], -1).permute(0, 2, 1) # (B, grid**2, width)
99
+ _cls = self.class_embedding.to(x.dtype) + torch.zeros(x.shape[0], 1, x.shape[-1], dtype=x.dtype, device=x.device)
100
+ x = torch.cat([_cls, x], dim=1) # (B, grid**2 + 1, width)
101
+ x = x + self.positional_embedding.to(x.dtype)
102
+ x = self.ln_pre(x)
103
+ x = x.permute(1, 0, 2) # NLD -> LND
104
+ x = self.transformer(x)
105
+ x = x.permute(1, 0, 2) # LND -> NLD
106
+ x = self.ln_post(x[:, 0, :]) # take the [CLS] token
107
+ return x
108
+
109
+
110
+ class CSDOutput(ModelOutput):
111
+ embeddings: Optional[torch.FloatTensor] = None # style embedding (L2-normalized)
112
+ content_embeddings: Optional[torch.FloatTensor] = None
113
+ last_hidden_states: Optional[torch.FloatTensor] = None # pre-projection ViT feature
114
+
115
+
116
+ class CSDModel(PreTrainedModel):
117
+ """CSD style/content encoder. ``embeddings`` is the L2-normalized style descriptor
118
+ (``feature @ last_layer_style``); the perceptual/style scoring lives in the caller."""
119
+
120
+ config_class = CSDConfig
121
+
122
+ def __init__(self, config: CSDConfig):
123
+ super().__init__(config)
124
+ self.backbone = VisionTransformer(
125
+ input_resolution=config.image_resolution,
126
+ patch_size=config.patch_size,
127
+ width=config.width,
128
+ layers=config.layers,
129
+ heads=config.heads,
130
+ )
131
+ self.last_layer_style = nn.Parameter(torch.empty(config.width, config.embed_dim))
132
+ self.last_layer_content = nn.Parameter(torch.empty(config.width, config.embed_dim))
133
+
134
+ def forward(self, pixel_values: torch.Tensor) -> CSDOutput:
135
+ _feature = self.backbone(pixel_values)
136
+ _style = nn.functional.normalize(_feature @ self.last_layer_style, dim=1, p=2)
137
+ _content = nn.functional.normalize(_feature @ self.last_layer_content, dim=1, p=2)
138
+ return CSDOutput(embeddings=_style, content_embeddings=_content, last_hidden_states=_feature)
preprocessor_config.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "image_processor_type": "CLIPImageProcessor",
3
+ "do_resize": true,
4
+ "size": {"shortest_edge": 224},
5
+ "resample": 3,
6
+ "do_center_crop": true,
7
+ "crop_size": {"height": 224, "width": 224},
8
+ "do_rescale": true,
9
+ "rescale_factor": 0.00392156862745098,
10
+ "do_normalize": true,
11
+ "image_mean": [0.48145466, 0.4578275, 0.40821073],
12
+ "image_std": [0.26862954, 0.26130258, 0.27577711],
13
+ "do_convert_rgb": true
14
+ }