CoolFace
Apppublic

davanstrien/deepseek-ocr

sourceHugging Facemitupdated 11mo agoView on Hugging Face
0likes
build_linear.py175 linesDownload Raw Back to deepencoder
1import torch.nn as nn2import torch3import torch.nn.functional as F4import copy5 6 7class MlpProjector(nn.Module):8 9    def __init__(self, cfg):10 11        super().__init__()12 13        self.cfg = cfg14 15        if cfg.projector_type == "identity":16            modules = nn.Identity()17 18        elif cfg.projector_type == "linear":19            modules = nn.Linear(cfg.input_dim, cfg.n_embed)20 21        elif cfg.projector_type == "mlp_gelu":22            mlp_depth = cfg.get("depth", 1)23            modules = [nn.Linear(cfg.input_dim, cfg.n_embed)]24            for _ in range(1, mlp_depth):25                modules.append(nn.GELU())26                modules.append(nn.Linear(cfg.n_embed, cfg.n_embed))27            modules = nn.Sequential(*modules)28        29        elif cfg.projector_type == "normlayer_downsample_mlp_gelu":30            mlp_depth = cfg.get("depth", 1)31            mlp_ratio = cfg.get("mlp_ratio", 1)32            modules = [33                nn.LayerNorm(cfg.input_dim * cfg.downsample_ratio * cfg.downsample_ratio),34                nn.Linear(cfg.input_dim * cfg.downsample_ratio * cfg.downsample_ratio, cfg.n_embed * mlp_ratio)35            ]36            for _ in range(1, mlp_depth - 1):37                modules.append(nn.GELU())38                modules.append(nn.Linear(cfg.n_embed * mlp_ratio, cfg.n_embed * mlp_ratio))39            modules.append(nn.GELU())40            modules.append(nn.Linear(cfg.n_embed * mlp_ratio, cfg.n_embed))41            modules = nn.Sequential(*modules)42        43        elif cfg.projector_type == "downsample_mlp_gelu":44            mlp_depth = cfg.get("depth", 1)45            mlp_ratio = cfg.get("mlp_ratio", 1)46            modules = [nn.Linear(cfg.input_dim * cfg.downsample_ratio * cfg.downsample_ratio, cfg.n_embed * mlp_ratio)]47            for _ in range(1, mlp_depth - 1):48                modules.append(nn.GELU())49                modules.append(nn.Linear(cfg.n_embed * mlp_ratio, cfg.n_embed * mlp_ratio))50            modules.append(nn.GELU())51            modules.append(nn.Linear(cfg.n_embed * mlp_ratio, cfg.n_embed))52            modules = nn.Sequential(*modules)53 54        elif cfg.projector_type == "low_high_hybrid_split_mlp_gelu":55            mlp_depth = cfg.get("depth", 1)56            self.high_up_proj = nn.Linear(cfg.input_dim, cfg.n_embed // 2)57            self.low_up_proj = nn.Linear(cfg.input_dim, cfg.n_embed // 2)58 59            modules = []60            for _ in range(1, mlp_depth):61                modules.append(nn.GELU())62                modules.append(nn.Linear(cfg.n_embed, cfg.n_embed))63            modules = nn.Sequential(*modules)64 65        elif cfg.projector_type == "hybrid_split_feature_mlp_gelu":66            mlp_depth = cfg.get("depth", 1)67            channel_div = cfg.get("channel_div", 0.5)68            self.high_up_proj = nn.Linear(cfg.input_dim[0], int(cfg.n_embed * channel_div))69            self.low_up_proj = nn.Linear(cfg.input_dim[1], cfg.n_embed - int(cfg.n_embed * channel_div))70 71            modules = []72            for _ in range(1, mlp_depth):73                modules.append(nn.GELU())74                modules.append(nn.Linear(cfg.n_embed, cfg.n_embed))75            modules = nn.Sequential(*modules)76 77        elif cfg.projector_type == "low_high_split_mlp_gelu":78            mlp_depth = cfg.get("depth", 1)79            modules = []80            for _ in range(1, mlp_depth):81                modules.append(nn.GELU())82                modules.append(nn.Linear(cfg.n_embed // 2, cfg.n_embed // 2))83            modules = nn.Sequential(*modules)84            self.high_layers = nn.Sequential(*modules)85            self.low_layers = copy.deepcopy(modules)86 87        else:88            raise ValueError(f"Unknown projector type: {cfg.projector_type}")89 90        if cfg.get("token_pooling", False):91            self.token_pooling_layer = nn.Linear(cfg.input_dim * 4, cfg.input_dim)92 93        if cfg.get("conv_fusion_high_low_features", False):94            self.fusion_layer = nn.Linear(cfg.input_dim, cfg.input_dim)95        self.layers = modules96 97    def forward(self, x):98        if self.cfg.get("token_pooling", False):99            batch_size, wxh, channels = x.shape100            w = h = int(wxh**0.5)101            x = x.view(batch_size, w, h, channels)102            x = x.permute(0, 3, 1, 2)103            # import ipdb; ipdb.set_trace()104            patches = x.unfold(2, 2, 2).unfold(3, 2, 2)105            batch_size, channels, h_patches, w_patches, _, _ = patches.size()106            # 在通道维度上拼接107            patches = patches.contiguous().view(batch_size, channels, h_patches * w_patches, -1)108 109            # 通过线性层110            patches = patches.permute(0, 2, 1, 3).contiguous()111            patches = patches.view(batch_size, h_patches * w_patches, channels * 4)112 113            x = self.token_pooling_layer(patches)114        115        if self.cfg.get("conv_fusion_high_low_features", False):116            x = self.fusion_layer(x[:, 0]) + x[:, 1]117 118        if self.cfg.projector_type == 'low_high_hybrid_split_mlp_gelu':119            high_x, low_x = x[0], x[1]120            high_x = self.high_up_proj(high_x)121            low_x = self.low_up_proj(low_x)122            x = torch.concat([high_x, low_x], dim=-1)123        124        if self.cfg.projector_type == 'hybrid_split_feature_mlp_gelu':125            high_x = x[...,:self.cfg.input_dim[0]]126            low_x = x[...,self.cfg.input_dim[0]:]127            high_x = self.high_up_proj(high_x)128            low_x = self.low_up_proj(low_x)129            x = torch.concat([high_x, low_x], dim=-1)130        131        if self.cfg.projector_type == 'low_high_split_mlp_gelu':132            high_x, low_x = x[0], x[1]133            high_x = self.high_layers(high_x)134            low_x = self.low_layers(low_x)135            x = torch.concat([high_x, low_x], dim=-1)136            return x137        138        if self.cfg.projector_type == 'downsample_mlp_gelu' or self.cfg.projector_type == 'normlayer_downsample_mlp_gelu':139            bs, hw, input_dim = x.shape140            h = w = int((hw) ** 0.5)141 142            """compute padding"""143            if h % self.cfg.downsample_ratio:144                pad = self.cfg.downsample_ratio - h % self.cfg.downsample_ratio145            else:146                pad = 0147            x = x.reshape(bs, h, w, input_dim)148            if pad > 0:149                x = F.pad(x, (0, 0, 0, pad, 0, pad), "constant", 0)150 151            """4 to 1 concat"""152            x = x.permute(0, 3, 1, 2)  # B, C, H, W153            x = F.unfold(x, kernel_size=self.cfg.downsample_ratio, stride=self.cfg.downsample_ratio, padding=0) # B, C*4, HW // 4154            x = x.permute(0, 2, 1)155            156        return self.layers(x)157 158    @staticmethod159    def get_flops_per_sample(cfg):160        if cfg.projector_type == "linear":161            fwd = 2 * cfg.input_dim * cfg.n_embed162 163        elif "mlp_gelu" in cfg.projector_type :164            mlp_depth = cfg.get("depth", 1)165            downsample_ratio = cfg.get("downsample_ratio", 1)166            input_dim = sum(cfg.input_dim) if isinstance(cfg.input_dim, list) else cfg.input_dim167            input_dim = input_dim * downsample_ratio * downsample_ratio168            fwd = 2 * input_dim * cfg.n_embed + (mlp_depth - 1) * 2 * cfg.n_embed * cfg.n_embed169        else:170            fwd = 0171 172        return fwd * 3173 174 175