lt-tensor 0.0.1a8__py3-none-any.whl → 0.0.1a10__py3-none-any.whl

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.
lt_tensor/misc_utils.py CHANGED
@@ -18,8 +18,11 @@ __all__ = [
18
18
  "Packing",
19
19
  "Padding",
20
20
  "Masking",
21
+ "LogTensor",
22
+ "get_losses",
21
23
  ]
22
24
 
25
+ import re
23
26
  import gc
24
27
  import sys
25
28
  import random
@@ -28,9 +31,20 @@ from lt_utils.type_utils import is_str
28
31
  from .torch_commons import *
29
32
  from lt_utils.misc_utils import cache_wrapper
30
33
  from lt_utils.common import *
34
+ from lt_utils.misc_utils import ff_list
31
35
  import torch.nn.functional as F
32
36
 
33
37
 
38
+ def try_torch(fn: str, *args, **kwargs):
39
+ try:
40
+ return getattr(F, fn)(*args, **kwargs)
41
+ except Exception as e:
42
+ try:
43
+ return getattr(torch, fn)(*args, **kwargs)
44
+ except Exception as e:
45
+ return str(e)
46
+
47
+
34
48
  def log_tensor(
35
49
  item: Union[Tensor, np.ndarray],
36
50
  title: Optional[str] = None,
@@ -70,6 +84,210 @@ def log_tensor(
70
84
  sys.stdout.flush()
71
85
 
72
86
 
87
+ def get_losses(base: Tensor, target: Tensor, return_valid_only: bool = False):
88
+ losses = {}
89
+ losses["mse_loss"] = try_torch("mse_loss", base, target)
90
+ losses["l1_loss"] = try_torch("l1_loss", base, target)
91
+ losses["huber_loss"] = try_torch("huber_loss", base, target)
92
+ losses["poisson_nll_loss"] = try_torch("poisson_nll_loss", base, target)
93
+ losses["smooth_l1_loss"] = try_torch("smooth_l1_loss", base, target)
94
+ losses["cross_entropy"] = try_torch("cross_entropy", base, target)
95
+ losses["soft_margin_loss"] = try_torch("soft_margin_loss", base, target)
96
+ losses["nll_loss"] = try_torch("nll_loss", base, target)
97
+ losses["gaussian_nll_loss"] = try_torch("gaussian_nll_loss", base, target, var=1.0)
98
+ losses["gaussian_nll_loss-var_0.25"] = try_torch(
99
+ "gaussian_nll_loss", base, target, var=0.25
100
+ )
101
+ losses["gaussian_nll_loss-var_4.0"] = try_torch(
102
+ "gaussian_nll_loss", base, target, var=4.0
103
+ )
104
+ if not return_valid_only:
105
+ return losses
106
+ valid = {}
107
+ for name, loss in losses.items():
108
+ if isinstance(loss, str):
109
+ continue
110
+ valid[name] = loss
111
+ return valid
112
+
113
+
114
+ class LogTensor:
115
+ negative_slope = 0.1
116
+ do_print: bool = True
117
+ end_with: str = "\n"
118
+ stored_items: List[
119
+ Dict[str, Union[str, Number, Tensor, List[Union[Tensor, Number, str]]]]
120
+ ] = []
121
+ max_stored_items: int = 32
122
+
123
+ def _setup_message(self, title: str, t: Union[Tensor, str, int]):
124
+ try:
125
+ if isinstance(t, Tensor):
126
+ try:
127
+ message = f"{title}: {t}"
128
+ if t.ndim == 0 and t.shape[0] == 1:
129
+ message = f"{title}: {t.item():.5f}"
130
+ elif t.ndim == 1 and t.shape[-1] == 1:
131
+ message = f"{title}: {t[-1].item():.5f}"
132
+ else:
133
+ message = f"{title}: {t.item()}"
134
+ except:
135
+ message = f"{title}: {t}"
136
+ else:
137
+ t = str(t).replace("\n", " ")
138
+ t = (
139
+ re.sub(r"\s+", " ", t)
140
+ .replace("( ", "(")
141
+ .replace("[ ", "[")
142
+ .replace(" ]", "]")
143
+ .replace(" )", ")")
144
+ )
145
+ message = f"{title}: {t}"
146
+ except Exception as e:
147
+ message = f"{title}: {e}"
148
+ return message
149
+
150
+ def _print(self, message: str):
151
+ if self.do_print:
152
+ print(message)
153
+ sys.stdout.flush()
154
+
155
+ def _process(
156
+ self,
157
+ name: str,
158
+ resp: Union[Callable[[Any], Any], Any],
159
+ do_not_print: bool = False,
160
+ ):
161
+ if callable(resp):
162
+ try:
163
+ response = resp()
164
+ except Exception as e:
165
+ response = str(e)
166
+ print(e)
167
+ else:
168
+ response = resp
169
+ if not do_not_print and self.do_print:
170
+ msg = self._setup_message(name, response)
171
+ self._print(msg)
172
+ return dict(item=name, value=response)
173
+
174
+ def __call__(
175
+ self,
176
+ inputs: Union[Tensor, np.ndarray, Sequence[Number]],
177
+ title: Optional[str] = None,
178
+ target: Optional[Union[Tensor, np.ndarray, Sequence[Number]]] = None,
179
+ *,
180
+ log_tensor: bool = False,
181
+ log_device: bool = False,
182
+ log_mean: bool = False,
183
+ log_std: bool = False,
184
+ dim_mean: int = -1,
185
+ dim_std: int = -1,
186
+ print_extended: bool = False,
187
+ external_logs: List[Tuple[str, Union[Dict[str, Any], List[Any], Any]]] = [
188
+ ("softmax", {"dim": 0}),
189
+ ("relu", None),
190
+ ("leaky_relu", [0.1]),
191
+ ("min", 0),
192
+ ("max", dict(dim=-1)),
193
+ ],
194
+ validate_item_type: bool = False,
195
+ **kwargs,
196
+ ):
197
+ invalid_type = not isinstance(inputs, (Tensor, np.ndarray, list, tuple))
198
+ _main_item_tp = type(inputs)
199
+ assert (
200
+ not validate_item_type or not invalid_type
201
+ ), f"Invalid Type: {_main_item_tp}"
202
+ if invalid_type:
203
+ self._print(f"Invalid Type: {_main_item_tp}")
204
+ return
205
+
206
+ inputs = self._setup_tensor(inputs)
207
+ target = self._setup_tensor(target)
208
+ if is_str(title):
209
+ title = re.sub(r"\s+", " ", title.replace("_", " "))
210
+ has_title = is_str(title)
211
+ if has_title:
212
+ self._print("========[ " + title.title() + " ]========")
213
+ else:
214
+ title = "Unnamed"
215
+
216
+ current_register = {"title": title, "values": []}
217
+ current_register["shape"] = self._process("shape", inputs.shape)
218
+ current_register["ndim"] = self._process("ndim", inputs.ndim)
219
+ current_register["dtype"] = self._process("dtype", inputs.dtype)
220
+ if log_device:
221
+ current_register["device"] = self._process("device", inputs.device)
222
+
223
+ if log_mean:
224
+ fn = lambda: inputs.mean(
225
+ dim=dim_mean,
226
+ )
227
+ current_register["mean"] = self._process("mean", fn)
228
+
229
+ if log_std:
230
+ fn = lambda: inputs.std(dim=dim_std)
231
+ current_register["std"] = self._process("std", fn)
232
+
233
+ if external_logs:
234
+ old_print = self.do_print
235
+ self.do_print = print_extended
236
+ self._print("\n---[ External Logs ] ---")
237
+ for log_fn, log_args in external_logs:
238
+ if isinstance(log_args, Sequence) and not isinstance(log_args, str):
239
+ value = try_torch(log_fn, inputs, *log_args)
240
+ elif isinstance(log_args, dict):
241
+ value = try_torch(log_fn, inputs, **log_args)
242
+ elif log_args is None:
243
+ value = try_torch(log_fn, inputs)
244
+ else:
245
+ value = try_torch(log_fn, inputs, log_args)
246
+ results = self._process(log_fn, value)
247
+ current_register[log_fn] = results
248
+ self.do_print = old_print
249
+
250
+ if target is not None:
251
+ losses = get_losses(inputs, target, False)
252
+ started_ls = False
253
+ if self.do_print:
254
+ for loss, res in losses.items():
255
+ if isinstance(res, str):
256
+ continue
257
+ if not started_ls:
258
+ self._print("\n---[ Losses ] ---")
259
+ started_ls = True
260
+ self._print(f"{loss}: {res:.5f}")
261
+ current_register["loss"] = losses
262
+
263
+ if log_tensor:
264
+ current_register["values"].append(
265
+ self._process("Tensor", inputs, not print_extended)
266
+ )
267
+
268
+ self._print(self.end_with)
269
+ self._store_item_and_update(current_register)
270
+ return current_register
271
+
272
+ def _store_item_and_update(self, current_register: Dict[str, Any]):
273
+ self.stored_items.append(current_register.copy())
274
+ self.stored_items = self.stored_items[-self.max_stored_items :]
275
+
276
+ def _setup_tensor(self, itm):
277
+ if isinstance(itm, (list, tuple)):
278
+ try:
279
+ itm = torch.tensor(itm)
280
+ except:
281
+ itm = torch.tensor(ff_list(itm))
282
+ elif isinstance(itm, np.ndarray):
283
+ itm = torch.from_numpy(itm)
284
+ elif isinstance(itm, Tensor):
285
+ itm = itm.detach().cpu()
286
+ else:
287
+ itm = None
288
+ return itm
289
+
290
+
73
291
  def set_seed(seed: int):
74
292
  """Set random seed for reproducibility."""
75
293
  torch.manual_seed(seed)
@@ -17,7 +17,7 @@ class PeriodDiscriminator(Model):
17
17
  self.stride = stride
18
18
  self.kernel_size = kernel_size
19
19
  self.norm_f = weight_norm if use_spectral_norm == False else spectral_norm
20
-
20
+
21
21
  self.channels = [32, 128, 512, 1024, 1024]
22
22
  self.first_pass = nn.Sequential(
23
23
  self.norm_f(
@@ -28,14 +28,18 @@ class PeriodDiscriminator(Model):
28
28
  nn.LeakyReLU(0.1),
29
29
  )
30
30
 
31
-
32
- self.convs = nn.ModuleList([self._get_next(self.channels[i+1], self.channels[i], i == 3) for i in range(4)])
31
+ self.convs = nn.ModuleList(
32
+ [
33
+ self._get_next(self.channels[i + 1], self.channels[i], i == 3)
34
+ for i in range(4)
35
+ ]
36
+ )
33
37
 
34
38
  self.post_conv = nn.Conv2d(1024, 1, (stride, 1), 1, padding=(1, 0))
35
39
 
36
- def _get_next(self, out_dim:int, last_in:int, is_last: bool = False):
40
+ def _get_next(self, out_dim: int, last_in: int, is_last: bool = False):
37
41
  stride = (self.stride, 1) if not is_last else 1
38
-
42
+
39
43
  return nn.Sequential(
40
44
  self.norm_f(
41
45
  nn.Conv2d(
@@ -152,4 +156,37 @@ class GeneralLossDescriminator(Model):
152
156
  pass
153
157
 
154
158
  def forward(self, x: Tensor, y_hat: Tensor):
155
- return
159
+ return
160
+
161
+
162
+ def discriminator_loss(d_outputs_real, d_outputs_fake):
163
+ loss = 0.0
164
+ for real_out, fake_out in zip(d_outputs_real, d_outputs_fake):
165
+ real_score = real_out[0]
166
+ fake_score = fake_out[0]
167
+ loss += torch.mean(F.relu(1.0 - real_score)) + torch.mean(
168
+ F.relu(1.0 + fake_score)
169
+ )
170
+ return loss
171
+
172
+
173
+ def generator_adv_loss(d_outputs_fake):
174
+ loss = 0.0
175
+ for fake_out in d_outputs_fake:
176
+ fake_score = fake_out[0]
177
+ loss += -torch.mean(fake_score)
178
+ return loss
179
+
180
+
181
+ def feature_matching_loss(
182
+ d_outputs_real,
183
+ d_outputs_fake,
184
+ loss_fn: Callable[[Tensor, Tensor], Tensor] = F.mse_loss,
185
+ ):
186
+ loss = 0.0
187
+ for real_out, fake_out in zip(d_outputs_real, d_outputs_fake):
188
+ real_feats = real_out[1]
189
+ fake_feats = fake_out[1]
190
+ for real_f, fake_f in zip(real_feats, fake_feats):
191
+ loss += loss_fn(fake_f, real_f)
192
+ return loss
@@ -22,7 +22,6 @@ class AudioProcessor(Model):
22
22
  hop_length: Optional[int] = None,
23
23
  f_min: float = 0,
24
24
  f_max: float | None = None,
25
- n_iter: int = 32,
26
25
  center: bool = True,
27
26
  mel_scale: Literal["htk", "slaney"] = "htk",
28
27
  std: int = 4,
@@ -30,6 +29,7 @@ class AudioProcessor(Model):
30
29
  inverse_transform_config: Union[
31
30
  Dict[str, Union[Number, Tensor, bool]], InverseTransformConfig
32
31
  ] = dict(n_fft=16, hop_length=4, win_length=16, center=True),
32
+ n_iter: int = 32,
33
33
  *__,
34
34
  **_,
35
35
  ):
@@ -81,16 +81,18 @@ class AudioProcessor(Model):
81
81
  return self._inv_transform(spec, phase, **kwargs)
82
82
 
83
83
  def compute_mel(
84
- self, wave: Tensor, base: float = 1e-6, add_base: bool = False
84
+ self,
85
+ wave: Tensor,
86
+ base: float = 1e-5,
87
+ add_base: bool = True,
85
88
  ) -> Tensor:
86
89
  """Returns: [B, M, ML]"""
87
- wave_device = wave.device
88
90
  mel_tensor = self.mel_spec(wave.to(self.device)) # [M, ML]
89
91
  if not add_base:
90
92
  return (mel_tensor - self.mean) / self.std
91
- return ((torch.log(base + mel_tensor.unsqueeze(0)) - self.mean) / self.std).to(
92
- device=wave_device
93
- )
93
+ return (
94
+ (torch.log(base + mel_tensor.unsqueeze(0)) - self.mean) / self.std
95
+ ).squeeze()
94
96
 
95
97
  def reverse_mel(self, mel: Tensor, n_iter: Optional[int] = None):
96
98
  if isinstance(n_iter, int) and n_iter != self.n_iter:
@@ -167,9 +169,70 @@ class AudioProcessor(Model):
167
169
  break
168
170
  return results
169
171
 
170
- def stft_loss(self, signal: Tensor, ground: Tensor, base: float = 1e-5):
171
- sig_mel = self(signal, base)
172
- gnd_mel = self(ground, base)
172
+ def slice_mismatch_outputs(
173
+ self,
174
+ tensor_1: Tensor,
175
+ tensor_2: Tensor,
176
+ smallest_size: Optional[int] = None,
177
+ left_to_right: bool = True,
178
+ ):
179
+ assert tensor_1.ndim == tensor_2.ndim, (
180
+ "Tensors must have the same dimentions to be sliced! \n"
181
+ f"Received instead a tensor_1 with {tensor_1.ndim}D and tensor_2 with {tensor_1.ndim}D."
182
+ )
183
+ dim = tensor_1.ndim
184
+ assert dim < 5, (
185
+ "Excpected to receive tensors with from 1D up to 4D. "
186
+ f"Received instead a {dim}D tensor."
187
+ )
188
+
189
+ if tensor_1.shape[-1] == tensor_2.shape[-1]:
190
+ return tensor_1, tensor_2
191
+
192
+ if smallest_size is None:
193
+ smallest_size = min(tensor_1.shape[-1], tensor_2.shape[-1])
194
+ if dim == 0:
195
+ tensor_1 = tensor_1.unsqueeze(0)
196
+ tensor_2 = tensor_2.unsqueeze(0)
197
+ dim = 1
198
+
199
+ if dim == 1:
200
+ if left_to_right:
201
+ return tensor_1[:smallest_size], tensor_2[:smallest_size]
202
+ return tensor_1[-smallest_size:], tensor_2[-smallest_size:]
203
+ elif dim == 2:
204
+ if left_to_right:
205
+ return tensor_1[:, :smallest_size], tensor_2[:, :smallest_size]
206
+ return tensor_1[:, -smallest_size:], tensor_2[:, -smallest_size:]
207
+ elif dim == 3:
208
+ if left_to_right:
209
+ return tensor_1[:, :, :smallest_size], tensor_2[:, :, :smallest_size]
210
+ return tensor_1[:, :, -smallest_size:], tensor_2[:, :, -smallest_size:]
211
+
212
+ # else:
213
+ if left_to_right:
214
+ return (
215
+ tensor_1[:, :, :, :smallest_size],
216
+ tensor_2[:, :, :, :smallest_size],
217
+ )
218
+ return (
219
+ tensor_1[:, :, :, -smallest_size:],
220
+ tensor_2[:, :, :, -smallest_size:],
221
+ )
222
+
223
+ def stft_loss(
224
+ self,
225
+ signal: Tensor,
226
+ ground: Tensor,
227
+ slice_mismatch: bool = True,
228
+ base: float = 1e-5,
229
+ ):
230
+ if slice_mismatch:
231
+ smallest = min(signal.shape[-1], ground.shape[-1])
232
+ signal = signal[:, -smallest:]
233
+ ground = ground[:, -smallest:]
234
+ sig_mel = self.compute_mel(signal, base, True).detach().cpu()
235
+ gnd_mel = self.compute_mel(ground, base, True).detach().cpu()
173
236
  return torch.norm(gnd_mel - sig_mel, p=1) / torch.norm(gnd_mel, p=1)
174
237
 
175
238
  # def forward(self, wave: Tensor, base: Optional[float] = None):
lt_tensor/transform.py CHANGED
@@ -415,12 +415,13 @@ class InverseTransform(Model):
415
415
  self.length = length
416
416
  self.win_length = win_length or n_fft // 4
417
417
  self.hop_length = hop_length or n_fft
418
- self.center = center // 4
418
+ self.center = center
419
419
  self.return_complex = return_complex
420
420
  self.onesided = onesided
421
421
  self.normalized = normalized
422
422
  self.window = torch.hann_window(win_length) if window is None else window
423
-
423
+ self.update_settings()
424
+
424
425
  def _apply_device_to(self):
425
426
  """Applies to device while used with module `Model`"""
426
427
  self.window = self.window.to(device=self.device)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lt-tensor
3
- Version: 0.0.1a8
3
+ Version: 0.0.1a10
4
4
  Summary: General utilities for PyTorch and others. Built for general use.
5
5
  Home-page: https://github.com/gr1336/lt-tensor/
6
6
  Author: gr1336
@@ -2,17 +2,17 @@ lt_tensor/__init__.py,sha256=uwJ7uiO18VYj8Z1V4KSOQ3ZrnowSgJWKCIiFBrzLMOI,429
2
2
  lt_tensor/losses.py,sha256=TinZJP2ypZ7Tdg6d9nnFWFkPyormfgQ0Z9P2ER3sqzE,4341
3
3
  lt_tensor/lr_schedulers.py,sha256=LSZzqrOOLzSthD8k-W4cYPJt0vCjmHkiJkLr5e3yRTE,3659
4
4
  lt_tensor/math_ops.py,sha256=ewIYkvxIy_Lab_9ExjFUgLs-oYLOu8IRRDo7f1pn3i8,2248
5
- lt_tensor/misc_utils.py,sha256=sjWUkUaHFhaCdN4rZ6X-cQDbPieimfKchKq9VtjiwEA,17029
5
+ lt_tensor/misc_utils.py,sha256=N9Rf-i6m51Q3YYdmI5tI5Rb3wPz8OAJrTrLlqfCwWrk,24792
6
6
  lt_tensor/model_base.py,sha256=8qN7oklALFanOz-eqVzdnB9RD2kN_3ltynSMAPOl-TI,13413
7
7
  lt_tensor/monotonic_align.py,sha256=LhBd8p1xdBzg6jQrQX1j7b4PNeYGwIqM24zcU-pHOLE,2239
8
8
  lt_tensor/noise_tools.py,sha256=JkWw0-bCMRNNMShwXKKt5KbO3104tvNiBePt-ThPkEo,11366
9
9
  lt_tensor/torch_commons.py,sha256=fntsEU8lhBQo0ebonI1iXBkMbWMN3HpBsG13EWlP5s8,718
10
- lt_tensor/transform.py,sha256=va4bQjpfhH-tnaBDvJZpmYmfg9zwn5_Y6pPOoTswS-U,14471
10
+ lt_tensor/transform.py,sha256=Bxh87vFRKuZay_g1Alf_ZtEo89CzmV3XUQDINwHB7iA,14505
11
11
  lt_tensor/datasets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  lt_tensor/datasets/audio.py,sha256=YREyRsCvy-KS5tE0JNMWEdlIJogE1khLqhiq4wOWXVg,3777
13
13
  lt_tensor/model_zoo/__init__.py,sha256=jipEk50_DTMQbGg8FnDDukxmh7Bcwvl_QVRS3rkb7aY,283
14
14
  lt_tensor/model_zoo/bsc.py,sha256=muxIR7dU-Pvf-HFE-iy3zmRb1sTJlcs1vqdlnbU1Hss,6307
15
- lt_tensor/model_zoo/disc.py,sha256=jZPhoSV1hlrba3ohXGutYAAcSl4pWkqGYFpOlOoN3eo,4740
15
+ lt_tensor/model_zoo/disc.py,sha256=SphFVVPZLP96-mZPEvWD_up2aT63rqSPjnps1-j9D6w,5707
16
16
  lt_tensor/model_zoo/fsn.py,sha256=5ySsg2OHjvTV_coPAdZQ0f7bz4ugJB8mDYsItmd61qA,2102
17
17
  lt_tensor/model_zoo/gns.py,sha256=Tirr_grONp_FFQ_L7K-zV2lvkaC39h8mMl4QDpx9vLQ,6028
18
18
  lt_tensor/model_zoo/istft.py,sha256=0Xms2QNPAgz_ib8XTfaWl1SCHgS53oKC6-EkDkl_qe4,4863
@@ -20,9 +20,9 @@ lt_tensor/model_zoo/pos.py,sha256=N28v-rF8CELouYxQ9r45Jbd4ri5DNydwDgg7nzmQ4Ig,44
20
20
  lt_tensor/model_zoo/rsd.py,sha256=5bba50g1Hm5kMexuJ4SwOIJuyQ1qJd8Acrq-Ax6CqE8,6958
21
21
  lt_tensor/model_zoo/tfrms.py,sha256=kauh-A13pk08SZ5OspEE5a-gPKD4rZr6tqMKWu3KGhk,4237
22
22
  lt_tensor/processors/__init__.py,sha256=4b9MxAJolXiJfSm20ZEspQTDm1tgLazwlPWA_jB1yLM,63
23
- lt_tensor/processors/audio.py,sha256=ljnRCqNzNJrab_uGxTOw_ULat_ilv_AMlN9eCDO9dwA,6674
24
- lt_tensor-0.0.1a8.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
25
- lt_tensor-0.0.1a8.dist-info/METADATA,sha256=dMWV6z5ErsabfuIIPXzgZsmm92xrDvhYrzS80MdK-SY,965
26
- lt_tensor-0.0.1a8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- lt_tensor-0.0.1a8.dist-info/top_level.txt,sha256=35FuhFeXnUyvHWdbVHGPh0hS8euofafnJ_GJAVSF4Kk,10
28
- lt_tensor-0.0.1a8.dist-info/RECORD,,
23
+ lt_tensor/processors/audio.py,sha256=2Sta_KytTqGZh-ZeHpcCbqP6O8VT6QQVkx-7szA3Itc,8830
24
+ lt_tensor-0.0.1a10.dist-info/licenses/LICENSE,sha256=HUnu_iSPpnDfZS_PINhO3AoVizJD1A2vee8WX7D7uXo,11358
25
+ lt_tensor-0.0.1a10.dist-info/METADATA,sha256=-VDQmGfkd5uW4_8B_TbwH-xvRivsGn3jWEtXTyeCT0s,966
26
+ lt_tensor-0.0.1a10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ lt_tensor-0.0.1a10.dist-info/top_level.txt,sha256=35FuhFeXnUyvHWdbVHGPh0hS8euofafnJ_GJAVSF4Kk,10
28
+ lt_tensor-0.0.1a10.dist-info/RECORD,,
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright [yyyy] [name of copyright owner]
189
+ Copyright [2025] [gr1336 (Gabriel Ribeiro)]
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.