vector-quantize-pytorch 1.22.18__tar.gz → 1.23.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/PKG-INFO +1 -1
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/pyproject.toml +1 -1
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/tests/test_readme.py +27 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/finite_scalar_quantization.py +4 -1
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/vector_quantize_pytorch.py +64 -19
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/.github/workflows/build.yml +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/.github/workflows/python-publish.yml +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/.github/workflows/test.yml +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/.gitignore +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/LICENSE +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/README.md +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/examples/autoencoder.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/examples/autoencoder_fsq.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/examples/autoencoder_lfq.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/examples/autoencoder_sim_vq.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/images/fsq.png +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/images/lfq.png +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/images/simvq.png +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/images/vq.png +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/ruff.toml +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/tests/test_latent_quantization.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/tests/test_lfq.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/__init__.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/latent_quantization.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/lookup_free_quantization.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/random_projection_quantizer.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/residual_fsq.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/residual_lfq.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/residual_sim_vq.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/residual_vq.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/sim_vq.py +0 -0
- {vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vector-quantize-pytorch
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.23.4
|
|
4
4
|
Summary: Vector Quantization - Pytorch
|
|
5
5
|
Project-URL: Homepage, https://pypi.org/project/vector-quantize-pytorch/
|
|
6
6
|
Project-URL: Repository, https://github.com/lucidrains/vector-quantizer-pytorch
|
|
@@ -434,3 +434,30 @@ def test_vq_custom_ema_update_weighting(
|
|
|
434
434
|
|
|
435
435
|
assert torch.allclose(codebook_before[did_not_update], codebook_after[did_not_update], atol = 1e-6)
|
|
436
436
|
assert (codebook_before[did_update] != codebook_after[did_update]).all()
|
|
437
|
+
|
|
438
|
+
def test_accum_ema_update():
|
|
439
|
+
from vector_quantize_pytorch import VectorQuantize
|
|
440
|
+
|
|
441
|
+
vq = VectorQuantize(
|
|
442
|
+
dim = 256,
|
|
443
|
+
use_cosine_sim = True,
|
|
444
|
+
codebook_dim = 128,
|
|
445
|
+
codebook_size = 8, # codebook size
|
|
446
|
+
decay = 0.8, # the exponential moving average decay, lower means the dictionary will change faster
|
|
447
|
+
commitment_weight = 1., # the weight on the commitment loss
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
x = torch.randn(16, 1024, 256)
|
|
451
|
+
|
|
452
|
+
codebook_before = vq.codebook.clone()
|
|
453
|
+
|
|
454
|
+
vq.train()
|
|
455
|
+
|
|
456
|
+
_ = vq(x, accum_ema_update = True)
|
|
457
|
+
_ = vq(x, accum_ema_update = True)
|
|
458
|
+
|
|
459
|
+
assert torch.allclose(codebook_before, vq.codebook, atol = 1e-6)
|
|
460
|
+
|
|
461
|
+
_ = vq(x)
|
|
462
|
+
|
|
463
|
+
assert not torch.allclose(codebook_before, vq.codebook, atol = 1e-6)
|
|
@@ -61,7 +61,7 @@ def floor_ste(z):
|
|
|
61
61
|
class FSQ(Module):
|
|
62
62
|
def __init__(
|
|
63
63
|
self,
|
|
64
|
-
levels: list[int],
|
|
64
|
+
levels: list[int] | tuple[int, ...],
|
|
65
65
|
dim: int | None = None,
|
|
66
66
|
num_codebooks = 1,
|
|
67
67
|
keep_num_codebooks_dim: bool | None = None,
|
|
@@ -76,6 +76,9 @@ class FSQ(Module):
|
|
|
76
76
|
):
|
|
77
77
|
super().__init__()
|
|
78
78
|
|
|
79
|
+
if isinstance(levels, tuple):
|
|
80
|
+
levels = list(levels)
|
|
81
|
+
|
|
79
82
|
_levels = tensor(levels, dtype = int32)
|
|
80
83
|
self.register_buffer('_levels', _levels, persistent = False)
|
|
81
84
|
|
|
@@ -61,7 +61,22 @@ def log(t, eps = 1e-20):
|
|
|
61
61
|
def entropy(prob, eps = 1e-5):
|
|
62
62
|
return (-prob * log(prob, eps = eps)).sum(dim = -1)
|
|
63
63
|
|
|
64
|
+
def accum_grad_(t, grad):
|
|
65
|
+
if exists(t.grad):
|
|
66
|
+
t.grad.add_(grad)
|
|
67
|
+
else:
|
|
68
|
+
t.grad = grad.clone().detach()
|
|
69
|
+
|
|
64
70
|
def ema_inplace(old, new, decay, weight = None):
|
|
71
|
+
|
|
72
|
+
# if old.grad is populated, add it to new and set it to None
|
|
73
|
+
|
|
74
|
+
if exists(old.grad):
|
|
75
|
+
new.add_(old.grad)
|
|
76
|
+
old.grad = None
|
|
77
|
+
|
|
78
|
+
# take care of custom weighting
|
|
79
|
+
|
|
65
80
|
weight = default(weight, 1.)
|
|
66
81
|
|
|
67
82
|
if is_tensor(weight):
|
|
@@ -71,7 +86,7 @@ def ema_inplace(old, new, decay, weight = None):
|
|
|
71
86
|
assert weight.ndim == 2 and weight.shape == old.shape[:2]
|
|
72
87
|
weight = append_dims_to(weight, old.ndim)
|
|
73
88
|
|
|
74
|
-
old.lerp_(new, (1. - decay) * weight)
|
|
89
|
+
old.data.lerp_(new, (1. - decay) * weight)
|
|
75
90
|
|
|
76
91
|
def pack_one(t, pattern):
|
|
77
92
|
packed, ps = pack([t], pattern)
|
|
@@ -258,12 +273,14 @@ def efficient_rotation_trick_transform(u, q, e):
|
|
|
258
273
|
e = rearrange(e, 'b d -> b 1 d')
|
|
259
274
|
w = l2norm(u + q, dim = 1).detach()
|
|
260
275
|
|
|
261
|
-
|
|
276
|
+
out = (
|
|
262
277
|
e -
|
|
263
278
|
2 * (e @ rearrange(w, 'b d -> b d 1') @ rearrange(w, 'b d -> b 1 d')) +
|
|
264
279
|
2 * (e @ rearrange(u, 'b d -> b d 1').detach() @ rearrange(q, 'b d -> b 1 d').detach())
|
|
265
280
|
)
|
|
266
281
|
|
|
282
|
+
return rearrange(out, '... 1 -> ...')
|
|
283
|
+
|
|
267
284
|
def rotate_to(src, tgt):
|
|
268
285
|
# rotation trick STE (https://arxiv.org/abs/2410.06424) to get gradients through VQ layer.
|
|
269
286
|
src, inverse = pack_one(src, '* d')
|
|
@@ -276,7 +293,7 @@ def rotate_to(src, tgt):
|
|
|
276
293
|
safe_div(src, norm_src),
|
|
277
294
|
safe_div(tgt, norm_tgt),
|
|
278
295
|
src
|
|
279
|
-
)
|
|
296
|
+
)
|
|
280
297
|
|
|
281
298
|
rotated = rotated_tgt * safe_div(norm_tgt, norm_src).detach()
|
|
282
299
|
|
|
@@ -511,7 +528,8 @@ class EuclideanCodebook(Module):
|
|
|
511
528
|
mask = None,
|
|
512
529
|
freeze_codebook = False,
|
|
513
530
|
codebook_transform_fn: Callable | None = None,
|
|
514
|
-
ema_update_weight: Tensor | Callable | None = None
|
|
531
|
+
ema_update_weight: Tensor | Callable | None = None,
|
|
532
|
+
accum_ema_update = False
|
|
515
533
|
):
|
|
516
534
|
needs_codebook_dim = x.ndim < 4
|
|
517
535
|
sample_codebook_temp = default(sample_codebook_temp, self.sample_codebook_temp)
|
|
@@ -603,12 +621,16 @@ class EuclideanCodebook(Module):
|
|
|
603
621
|
if callable(ema_update_weight):
|
|
604
622
|
ema_update_weight = ema_update_weight(embed_sum, cluster_size)
|
|
605
623
|
|
|
606
|
-
|
|
607
|
-
|
|
624
|
+
if accum_ema_update:
|
|
625
|
+
accum_grad_(self.cluster_size, cluster_size)
|
|
626
|
+
accum_grad_(self.embed_avg, embed_sum)
|
|
627
|
+
else:
|
|
628
|
+
ema_inplace(self.cluster_size, cluster_size, self.decay, ema_update_weight)
|
|
629
|
+
ema_inplace(self.embed_avg, embed_sum, self.decay, ema_update_weight)
|
|
608
630
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
631
|
+
if not self.manual_ema_update:
|
|
632
|
+
self.update_ema()
|
|
633
|
+
self.expire_codes_(x)
|
|
612
634
|
|
|
613
635
|
if needs_codebook_dim:
|
|
614
636
|
quantize, embed_ind = map(lambda t: rearrange(t, '1 ... -> ...'), (quantize, embed_ind))
|
|
@@ -743,7 +765,8 @@ class CosineSimCodebook(Module):
|
|
|
743
765
|
mask = None,
|
|
744
766
|
freeze_codebook = False,
|
|
745
767
|
codebook_transform_fn: Callable | None = None,
|
|
746
|
-
ema_update_weight: Tensor | None = None
|
|
768
|
+
ema_update_weight: Tensor | None = None,
|
|
769
|
+
accum_ema_update = False
|
|
747
770
|
):
|
|
748
771
|
needs_codebook_dim = x.ndim < 4
|
|
749
772
|
sample_codebook_temp = default(sample_codebook_temp, self.sample_codebook_temp)
|
|
@@ -819,12 +842,17 @@ class CosineSimCodebook(Module):
|
|
|
819
842
|
if callable(ema_update_weight):
|
|
820
843
|
ema_update_weight = ema_update_weight(embed_sum, bins)
|
|
821
844
|
|
|
822
|
-
|
|
823
|
-
|
|
845
|
+
if accum_ema_update:
|
|
846
|
+
accum_grad_(self.cluster_size, bins)
|
|
847
|
+
accum_grad_(self.embed_avg, embed_sum)
|
|
848
|
+
else:
|
|
849
|
+
|
|
850
|
+
ema_inplace(self.cluster_size, bins, self.decay, ema_update_weight)
|
|
851
|
+
ema_inplace(self.embed_avg, embed_sum, self.decay, ema_update_weight)
|
|
824
852
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
853
|
+
if not self.manual_ema_update:
|
|
854
|
+
self.update_ema()
|
|
855
|
+
self.expire_codes_(x)
|
|
828
856
|
|
|
829
857
|
if needs_codebook_dim:
|
|
830
858
|
quantize, embed_ind = map(lambda t: rearrange(t, '1 ... -> ...'), (quantize, embed_ind))
|
|
@@ -870,7 +898,7 @@ class VectorQuantize(Module):
|
|
|
870
898
|
stochastic_sample_codes = False,
|
|
871
899
|
sample_codebook_temp = 1.,
|
|
872
900
|
straight_through = False,
|
|
873
|
-
rotation_trick =
|
|
901
|
+
rotation_trick = None, # Propagate grads through VQ layer w/ rotation trick: https://arxiv.org/abs/2410.06424 by @cfifty
|
|
874
902
|
sync_codebook = None,
|
|
875
903
|
sync_affine_param = False,
|
|
876
904
|
ema_update = True,
|
|
@@ -885,6 +913,8 @@ class VectorQuantize(Module):
|
|
|
885
913
|
return_zeros_for_masked_padding = True
|
|
886
914
|
):
|
|
887
915
|
super().__init__()
|
|
916
|
+
rotation_trick = default(rotation_trick, dim > 1) # only use rotation trick if feature dimension greater than 1
|
|
917
|
+
|
|
888
918
|
self.dim = dim
|
|
889
919
|
self.heads = heads
|
|
890
920
|
self.separate_codebook_per_head = separate_codebook_per_head
|
|
@@ -1037,6 +1067,19 @@ class VectorQuantize(Module):
|
|
|
1037
1067
|
if not exists(self.in_place_codebook_optimizer):
|
|
1038
1068
|
return
|
|
1039
1069
|
|
|
1070
|
+
# handle ddp, thanks to @gdoras
|
|
1071
|
+
|
|
1072
|
+
if self._codebook.use_ddp:
|
|
1073
|
+
|
|
1074
|
+
for param in self._codebook.parameters():
|
|
1075
|
+
if not exists(param.grad):
|
|
1076
|
+
continue
|
|
1077
|
+
|
|
1078
|
+
distributed.all_reduce(param.grad)
|
|
1079
|
+
param.grad /= distributed.get_world_size()
|
|
1080
|
+
|
|
1081
|
+
# optimizer step
|
|
1082
|
+
|
|
1040
1083
|
self.in_place_codebook_optimizer.step()
|
|
1041
1084
|
self.in_place_codebook_optimizer.zero_grad()
|
|
1042
1085
|
|
|
@@ -1062,7 +1105,8 @@ class VectorQuantize(Module):
|
|
|
1062
1105
|
freeze_codebook = None,
|
|
1063
1106
|
return_loss_breakdown = False,
|
|
1064
1107
|
codebook_transform_fn: Callable | None = None,
|
|
1065
|
-
ema_update_weight: Tensor | None = None
|
|
1108
|
+
ema_update_weight: Tensor | None = None,
|
|
1109
|
+
accum_ema_update = False
|
|
1066
1110
|
):
|
|
1067
1111
|
orig_input, input_requires_grad = x, x.requires_grad
|
|
1068
1112
|
|
|
@@ -1119,7 +1163,8 @@ class VectorQuantize(Module):
|
|
|
1119
1163
|
mask = mask,
|
|
1120
1164
|
freeze_codebook = freeze_codebook,
|
|
1121
1165
|
codebook_transform_fn = codebook_transform_fn,
|
|
1122
|
-
ema_update_weight = ema_update_weight
|
|
1166
|
+
ema_update_weight = ema_update_weight,
|
|
1167
|
+
accum_ema_update = accum_ema_update
|
|
1123
1168
|
)
|
|
1124
1169
|
|
|
1125
1170
|
# quantize
|
|
@@ -1222,7 +1267,7 @@ class VectorQuantize(Module):
|
|
|
1222
1267
|
# calculate codebook diversity loss (negative of entropy) if needed
|
|
1223
1268
|
|
|
1224
1269
|
if self.has_codebook_diversity_loss:
|
|
1225
|
-
prob = (
|
|
1270
|
+
prob = (distances * self.codebook_diversity_temperature).softmax(dim = -1)
|
|
1226
1271
|
avg_prob = reduce(prob, '... n l -> n l', 'mean')
|
|
1227
1272
|
codebook_diversity_loss = -entropy(avg_prob).mean()
|
|
1228
1273
|
|
{vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/.github/workflows/build.yml
RENAMED
|
File without changes
|
|
File without changes
|
{vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/.github/workflows/test.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/examples/autoencoder_fsq.py
RENAMED
|
File without changes
|
{vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/examples/autoencoder_lfq.py
RENAMED
|
File without changes
|
{vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/examples/autoencoder_sim_vq.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/tests/test_latent_quantization.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/sim_vq.py
RENAMED
|
File without changes
|
{vector_quantize_pytorch-1.22.18 → vector_quantize_pytorch-1.23.4}/vector_quantize_pytorch/utils.py
RENAMED
|
File without changes
|