Download recipe/portable_model.py from Reza2kn/Bina-0.4-Rizeh-CoreML-INT4: direct link, hf CLI and curl.
- Browser
- Download file 2.13 kB
-
https://huggingface.co/Reza2kn/Bina-0.4-Rizeh-CoreML-INT4/resolve/main/recipe/portable_model.py
- Command line
-
hf download hf://Reza2kn/Bina-0.4-Rizeh-CoreML-INT4/recipe/portable_model.py
-
curl -L -o portable_model.py https://huggingface.co/Reza2kn/Bina-0.4-Rizeh-CoreML-INT4/resolve/main/recipe/portable_model.py
2.13 kB
| """Algebraic pointwise-Conv -> Linear lowering; unchanged masked SE semantics.""" | |
| import copy | |
| import torch | |
| from torch import nn | |
| from torch.nn import functional as F | |
| def linear(conv): | |
| layer = nn.Linear(conv.in_channels, conv.out_channels) | |
| with torch.no_grad(): | |
| layer.weight.copy_(conv.weight[..., 0]) | |
| layer.bias.copy_(conv.bias) | |
| return layer | |
| class PortableBlock(nn.Module): | |
| def __init__(self, block): | |
| super().__init__() | |
| self.dw = copy.deepcopy(block.dw) | |
| for name in ['expand', 'fc1', 'fc2', 'project']: | |
| setattr(self, name, linear(getattr(block, name))) | |
| def forward(self, x, mask): | |
| z = F.hardswish(self.expand(self.dw(x.transpose(1,2)).transpose(1,2))) | |
| pool = (z * mask).sum(1, keepdim=True) / mask.sum(1, keepdim=True).clamp_min(1.) | |
| gate = torch.sigmoid(self.fc2(F.relu(self.fc1(pool)))) | |
| return (x + self.project(z * gate)) * mask | |
| class PortableRecognizer(nn.Module): | |
| """Input widths are true unpadded widths; canvas must be a multiple of eight.""" | |
| def __init__(self, source): | |
| super().__init__() | |
| self.index_dtype = torch.int64 | |
| self.stem = copy.deepcopy(source.stem) | |
| self.bn = copy.deepcopy(source.bn) | |
| self.blocks = nn.ModuleList(PortableBlock(b) for b in source.blocks) | |
| self.head = linear(source.head) | |
| def forward(self, pixels, widths): | |
| z = self.stem(F.pad(pixels, (0,4,0,0))).squeeze(2) | |
| lengths = (widths + 3) // 4 | |
| mask = (torch.arange(z.shape[-1], device=z.device, dtype=self.index_dtype)[None,:] < lengths[:,None])[:,:,None].to(z.dtype) | |
| z = F.hardswish(self.bn(z)).transpose(1,2) * mask | |
| for block in self.blocks: | |
| z = block(z, mask) | |
| return self.head(z), lengths | |
| class Compact(nn.Module): | |
| def __init__(self, source): | |
| super().__init__() | |
| self.model = source | |
| def forward(self, pixels, widths): | |
| logits, lengths = self.model(pixels, widths) | |
| confidence, tokens = logits.softmax(-1).max(-1) | |
| return tokens.to(torch.int32), confidence, lengths.to(torch.int32) | |