rxnn 0.1.8__py3-none-any.whl → 0.1.10__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.
rxnn/training/base.py CHANGED
@@ -141,7 +141,8 @@ class BaseTrainer(ABC):
141
141
  callback.on_batch_start(self.model, batch_idx, batch)
142
142
  if self.get_batch_size(batch) == batch_size:
143
143
  loss = self.train_step(batch, batch_idx)
144
- self.accumulated_loss += loss.item()
144
+ orig_loss = loss.item()
145
+ self.accumulated_loss += orig_loss
145
146
  loss = loss / self.gradient_accumulation_steps
146
147
 
147
148
  if self.use_amp:
@@ -192,7 +193,7 @@ class BaseTrainer(ABC):
192
193
  epoch * len(dataloader) + batch_idx)
193
194
 
194
195
  for callback in self.callbacks:
195
- should_stop = callback.on_batch_end(self.model, batch_idx, loss.item() * self.gradient_accumulation_steps, batch)
196
+ should_stop = callback.on_batch_end(self.model, batch_idx, orig_loss, batch)
196
197
  if should_stop:
197
198
  self.is_running = False
198
199
 
@@ -228,7 +229,8 @@ class BaseTrainer(ABC):
228
229
  self.writer.add_scalar('Loss/validation', val_loss, epoch)
229
230
  self.writer.add_scalar('Perplexity/validation', math.exp(val_loss), epoch)
230
231
  if val_metrics['accuracy']:
231
- self.writer.add_scalar('Accuracy/validation', val_metrics['accuracy'], epoch)
232
+ self.writer.add_scalar('Node Accuracy/validation', val_metrics['node_accuracy'], epoch)
233
+ self.writer.add_scalar('Avg. Accuracy/validation', val_metrics['accuracy'], epoch)
232
234
 
233
235
  def valid_step(self, batch: dict[str, torch.Tensor]) -> tuple[torch.Tensor, torch.Tensor]:
234
236
  if self.use_amp:
rxnn/training/bml.py CHANGED
@@ -90,12 +90,15 @@ class MLMTrainer(BaseTrainer):
90
90
  total += valid_indices.sum()
91
91
 
92
92
  avg_loss = (val_loss / len(val_dataloader)).item()
93
+ acc = (correct / total * 100) if total > 0 else torch.tensor(0.0).to(self.device)
94
+ node_acc = acc.item()
93
95
  if self.use_ddp:
94
- dist.all_reduce(correct, op=dist.ReduceOp.SUM)
95
- dist.all_reduce(total, op=dist.ReduceOp.SUM)
96
+ dist.all_reduce(acc, op=dist.ReduceOp.SUM)
97
+ acc = acc / dist.get_world_size()
96
98
 
97
99
  metrics = {
98
- 'accuracy': (correct / total * 100).item() if total > 0 else 0.0
100
+ 'accuracy': acc.item(),
101
+ 'node_accuracy': node_acc,
99
102
  }
100
103
  self.model.train()
101
104
  return avg_loss, metrics
@@ -154,13 +157,15 @@ class AutoregressiveTrainer(BaseTrainer):
154
157
  total += valid_indices.sum()
155
158
 
156
159
  avg_loss = (val_loss / len(val_dataloader)).item()
157
-
160
+ acc = (correct / total * 100) if total > 0 else torch.tensor(0.0).to(self.device)
161
+ node_acc = acc.item()
158
162
  if self.use_ddp:
159
- dist.all_reduce(correct, op=dist.ReduceOp.SUM)
160
- dist.all_reduce(total, op=dist.ReduceOp.SUM)
163
+ dist.all_reduce(acc, op=dist.ReduceOp.SUM)
164
+ acc = acc / dist.get_world_size()
161
165
 
162
166
  metrics = {
163
- 'accuracy': (correct / total * 100).item() if total > 0 else 0.0
167
+ 'accuracy': acc.item(),
168
+ 'node_accuracy': node_acc,
164
169
  }
165
170
  self.model.train()
166
171
  return avg_loss, metrics
@@ -260,8 +265,10 @@ class JointLMTrainer(BaseTrainer):
260
265
  self.writer.add_scalar('Loss/validation', val_loss, epoch)
261
266
  self.writer.add_scalar('Perplexity/validation', math.exp(val_loss), epoch)
262
267
  if val_metrics['accuracy']:
263
- self.writer.add_scalar('Encoder accuracy/validation', val_metrics['accuracy']['encoder'], epoch)
264
- self.writer.add_scalar('Decoder accuracy/validation', val_metrics['accuracy']['decoder'], epoch)
268
+ self.writer.add_scalar('Encoder node accuracy/validation', val_metrics['accuracy']['node_encoder'], epoch)
269
+ self.writer.add_scalar('Decoder node accuracy/validation', val_metrics['accuracy']['node_decoder'], epoch)
270
+ self.writer.add_scalar('Encoder avg. accuracy/validation', val_metrics['accuracy']['encoder'], epoch)
271
+ self.writer.add_scalar('Decoder avg. accuracy/validation', val_metrics['accuracy']['decoder'], epoch)
265
272
  if val_metrics['loss']:
266
273
  self.writer.add_scalar('Encoder loss/validation', val_metrics['loss']['encoder'], epoch)
267
274
  self.writer.add_scalar('Encoder perplexity/validation', math.exp(val_metrics['loss']['encoder']), epoch)
@@ -317,28 +324,30 @@ class JointLMTrainer(BaseTrainer):
317
324
  avg_loss = val_loss / loader_len
318
325
  avg_dec_loss = dec_loss / loader_len
319
326
  avg_enc_loss = enc_loss / loader_len
320
-
327
+ mlm_acc = (correct_mlm / total_mlm * 100) if total_mlm > 0 else torch.tensor(0.0).to(self.device)
328
+ alm_acc = (correct_alm / total_alm * 100) if total_alm > 0 else torch.tensor(0.0).to(self.device)
329
+ node_mlm_acc = mlm_acc.item()
330
+ node_alm_acc = alm_acc.item()
321
331
  if self.use_ddp:
322
332
  dist.all_reduce(avg_dec_loss, op=dist.ReduceOp.SUM)
323
333
  dist.all_reduce(avg_enc_loss, op=dist.ReduceOp.SUM)
324
- dist.all_reduce(correct_mlm, op=dist.ReduceOp.SUM)
325
- dist.all_reduce(total_mlm, op=dist.ReduceOp.SUM)
326
- dist.all_reduce(correct_alm, op=dist.ReduceOp.SUM)
327
- dist.all_reduce(total_alm, op=dist.ReduceOp.SUM)
334
+ dist.all_reduce(mlm_acc, op=dist.ReduceOp.SUM)
335
+ dist.all_reduce(alm_acc, op=dist.ReduceOp.SUM)
328
336
  avg_dec_loss = avg_dec_loss / dist.get_world_size()
329
337
  avg_enc_loss = avg_enc_loss / dist.get_world_size()
330
-
331
- mlm_acc = (correct_mlm / total_mlm * 100).item() if total_mlm > 0 else 0.0
332
- alm_acc = (correct_alm / total_alm * 100).item() if total_alm > 0 else 0.0
338
+ mlm_acc = mlm_acc / dist.get_world_size()
339
+ alm_acc = alm_acc / dist.get_world_size()
333
340
 
334
341
  metrics = {
335
342
  'accuracy': {
336
- 'encoder': mlm_acc,
337
- 'decoder': alm_acc,
343
+ 'encoder': mlm_acc.item(),
344
+ 'decoder': alm_acc.item(),
345
+ 'node_encoder': node_mlm_acc,
346
+ 'node_decoder': node_alm_acc,
338
347
  },
339
348
  'loss': {
340
- 'encoder': avg_enc_loss,
341
- 'decoder': avg_dec_loss,
349
+ 'encoder': avg_enc_loss.item(),
350
+ 'decoder': avg_dec_loss.item(),
342
351
  }
343
352
  }
344
353
  self.model.train()
@@ -83,9 +83,12 @@ class PrintAccuracyCallback(TrainerCallback):
83
83
 
84
84
  def on_validation_end(self, model: nn.Module, epoch: int, val_loss: float, val_metrics: dict) -> None:
85
85
  if self.joint_mode:
86
+ print(f"Epoch {epoch} - encoder node accuracy: {val_metrics['accuracy']['node_encoder']:.4f}")
87
+ print(f"Epoch {epoch} - decoder node accuracy: {val_metrics['accuracy']['node_decoder']:.4f}")
86
88
  print(f"Epoch {epoch} - encoder accuracy: {val_metrics['accuracy']['encoder']:.4f}")
87
89
  print(f"Epoch {epoch} - decoder accuracy: {val_metrics['accuracy']['decoder']:.4f}")
88
90
  else:
91
+ print(f"Epoch {epoch} - node accuracy: {val_metrics['node_accuracy']:.4f}")
89
92
  print(f"Epoch {epoch} - accuracy: {val_metrics['accuracy']:.4f}")
90
93
 
91
94
 
@@ -130,6 +133,7 @@ class ModelSaveCallback(TrainerCallback):
130
133
  save_checkpoint_after_n_batches: int = None,
131
134
  push_batch_checkpoint: bool = False,
132
135
  display_exc_trace: bool = False,
136
+ use_ddp: bool = False,
133
137
  ):
134
138
  self.save_dir = save_dir
135
139
  self.save_best_only = save_best_only
@@ -146,10 +150,11 @@ class ModelSaveCallback(TrainerCallback):
146
150
  self.push_batch_checkpoint = push_batch_checkpoint
147
151
  self.finished_epochs = 0
148
152
  self.display_exc_trace = display_exc_trace
153
+ self.rank = int(os.environ['RANK']) if use_ddp else 0
149
154
 
150
155
  def on_batch_end(self, model: torch.nn.Module, batch_idx: int, loss: int, batch: dict[str, torch.Tensor]) -> Union[
151
156
  bool, None]:
152
- if self.save_checkpoint_after_n_batches is not None and batch_idx != 0 and batch_idx % self.save_checkpoint_after_n_batches == 0:
157
+ if self.rank == 0 and self.save_checkpoint_after_n_batches is not None and batch_idx != 0 and batch_idx % self.save_checkpoint_after_n_batches == 0:
153
158
  if isinstance(model, DistributedDataParallel):
154
159
  model = next(model.children())
155
160
  try:
@@ -195,90 +200,92 @@ class ModelSaveCallback(TrainerCallback):
195
200
  val_loss: float,
196
201
  val_metrics: dict
197
202
  ):
198
- self.finished_epochs += 1
199
- if val_loss < self.best_loss:
200
- self.best_loss = val_loss
203
+ if self.rank == 0:
204
+ self.finished_epochs += 1
205
+ if val_loss < self.best_loss:
206
+ self.best_loss = val_loss
207
+ if isinstance(model, DistributedDataParallel):
208
+ model = next(model.children())
209
+ try:
210
+ if model.save_pretrained is not None:
211
+ ckpt_path = os.path.join(
212
+ self.save_dir,
213
+ f'epoch_{epoch}_val_loss_{val_loss:.4f}'
214
+ )
215
+ path_exists = os.path.exists(ckpt_path)
216
+ if not path_exists:
217
+ os.makedirs(ckpt_path)
218
+ model.save_pretrained(save_directory=ckpt_path)
219
+ else:
220
+ path_exists = os.path.exists(self.save_dir)
221
+ if not path_exists:
222
+ os.makedirs(self.save_dir)
223
+ ckpt_path = os.path.join(
224
+ self.save_dir,
225
+ f'epoch_{epoch}_val_loss_{val_loss:.4f}.pt'
226
+ )
227
+ torch.save(model.state_dict(), ckpt_path)
228
+ self.ckpt_paths.append(ckpt_path)
229
+
230
+ # Keep only N best checkpoints
231
+ if len(self.ckpt_paths) > self.max_keep:
232
+ oldest_path = self.ckpt_paths.pop(0)
233
+ if model.save_pretrained is not None:
234
+ shutil.rmtree(oldest_path)
235
+ else:
236
+ os.remove(oldest_path)
237
+ except Exception as e:
238
+ print(f"Error saving epoch checkpoint: {str(e)}")
239
+ if self.display_exc_trace:
240
+ traceback.print_exc()
241
+
242
+ try:
243
+ if self.push_to_hub and self.push_checkpoint_weights and model.push_to_hub is not None and self.hub_model_id:
244
+ model.push_to_hub(
245
+ repo_id=self.hub_model_id,
246
+ commit_message=f'Epoch {epoch} - Val loss {val_loss:.4f}',
247
+ token=self.hf_token,
248
+ private=self.private_repo,
249
+ )
250
+ except Exception as e:
251
+ print(f"Error pushing epoch checkpoint: {str(e)}")
252
+ if self.display_exc_trace:
253
+ traceback.print_exc()
254
+
255
+ def on_training_end(self, model: Union[torch.nn.Module, PyTorchModelHubMixin]):
256
+ if self.rank == 0:
201
257
  if isinstance(model, DistributedDataParallel):
202
258
  model = next(model.children())
203
259
  try:
260
+ # Save final model
204
261
  if model.save_pretrained is not None:
205
262
  ckpt_path = os.path.join(
206
263
  self.save_dir,
207
- f'epoch_{epoch}_val_loss_{val_loss:.4f}'
264
+ 'final_model'
208
265
  )
209
- path_exists = os.path.exists(ckpt_path)
210
- if not path_exists:
211
- os.makedirs(ckpt_path)
212
266
  model.save_pretrained(save_directory=ckpt_path)
213
267
  else:
214
- path_exists = os.path.exists(self.save_dir)
215
- if not path_exists:
216
- os.makedirs(self.save_dir)
217
- ckpt_path = os.path.join(
218
- self.save_dir,
219
- f'epoch_{epoch}_val_loss_{val_loss:.4f}.pt'
220
- )
268
+ ckpt_path = os.path.join(self.save_dir, 'final_model.pt')
221
269
  torch.save(model.state_dict(), ckpt_path)
222
- self.ckpt_paths.append(ckpt_path)
223
-
224
- # Keep only N best checkpoints
225
- if len(self.ckpt_paths) > self.max_keep:
226
- oldest_path = self.ckpt_paths.pop(0)
227
- if model.save_pretrained is not None:
228
- shutil.rmtree(oldest_path)
229
- else:
230
- os.remove(oldest_path)
270
+ print(f"Final model saved to {ckpt_path}")
231
271
  except Exception as e:
232
- print(f"Error saving epoch checkpoint: {str(e)}")
272
+ print(f"Error saving final model: {str(e)}")
233
273
  if self.display_exc_trace:
234
274
  traceback.print_exc()
235
-
236
275
  try:
237
- if self.push_to_hub and self.push_checkpoint_weights and model.push_to_hub is not None and self.hub_model_id:
276
+ if self.push_to_hub and model.push_to_hub is not None:
238
277
  model.push_to_hub(
239
278
  repo_id=self.hub_model_id,
240
- commit_message=f'Epoch {epoch} - Val loss {val_loss:.4f}',
279
+ commit_message=self.final_commit_message or f'Final pre-trained model, after {self.finished_epochs} epochs',
241
280
  token=self.hf_token,
242
281
  private=self.private_repo,
243
282
  )
283
+ print(f"Model uploaded to repo: {self.hub_model_id}")
244
284
  except Exception as e:
245
- print(f"Error pushing epoch checkpoint: {str(e)}")
285
+ print(f"Error pushing final model: {str(e)}")
246
286
  if self.display_exc_trace:
247
287
  traceback.print_exc()
248
288
 
249
- def on_training_end(self, model: Union[torch.nn.Module, PyTorchModelHubMixin]):
250
- if isinstance(model, DistributedDataParallel):
251
- model = next(model.children())
252
- try:
253
- # Save final model
254
- if model.save_pretrained is not None:
255
- ckpt_path = os.path.join(
256
- self.save_dir,
257
- 'final_model'
258
- )
259
- model.save_pretrained(save_directory=ckpt_path)
260
- else:
261
- ckpt_path = os.path.join(self.save_dir, 'final_model.pt')
262
- torch.save(model.state_dict(), ckpt_path)
263
- print(f"Final model saved to {ckpt_path}")
264
- except Exception as e:
265
- print(f"Error saving final model: {str(e)}")
266
- if self.display_exc_trace:
267
- traceback.print_exc()
268
- try:
269
- if self.push_to_hub and model.push_to_hub is not None:
270
- model.push_to_hub(
271
- repo_id=self.hub_model_id,
272
- commit_message=self.final_commit_message or f'Final pre-trained model, after {self.finished_epochs} epochs',
273
- token=self.hf_token,
274
- private=self.private_repo,
275
- )
276
- print(f"Model uploaded to repo: {self.hub_model_id}")
277
- except Exception as e:
278
- print(f"Error pushing final model: {str(e)}")
279
- if self.display_exc_trace:
280
- traceback.print_exc()
281
-
282
289
 
283
290
  class JointModelSaveCallback(TrainerCallback):
284
291
  def __init__(
@@ -298,6 +305,7 @@ class JointModelSaveCallback(TrainerCallback):
298
305
  push_batch_checkpoint: bool = False,
299
306
  mlm_mode: bool = False,
300
307
  display_exc_trace: bool = False,
308
+ use_ddp: bool = False,
301
309
  ):
302
310
  self.save_dir = save_dir
303
311
  self.save_best_only = save_best_only
@@ -317,6 +325,7 @@ class JointModelSaveCallback(TrainerCallback):
317
325
  self.finished_epochs = 0
318
326
  self.mlm_mode = mlm_mode
319
327
  self.display_exc_trace = display_exc_trace
328
+ self.rank = int(os.environ['RANK']) if use_ddp else 0
320
329
 
321
330
  def _save_batch(self, model: Union[nn.Module, PyTorchModelHubMixin], component: str, hub_id: str = None):
322
331
  try:
@@ -362,7 +371,7 @@ class JointModelSaveCallback(TrainerCallback):
362
371
 
363
372
  def on_batch_end(self, model: torch.nn.Module, batch_idx: int, loss: int, batch: dict[str, torch.Tensor]) -> Union[
364
373
  bool, None]:
365
- if self.save_checkpoint_after_n_batches is not None and batch_idx != 0 and batch_idx % self.save_checkpoint_after_n_batches == 0:
374
+ if self.rank == 0 and self.save_checkpoint_after_n_batches is not None and batch_idx != 0 and batch_idx % self.save_checkpoint_after_n_batches == 0:
366
375
  if isinstance(model, DistributedDataParallel):
367
376
  model = next(model.children())
368
377
  self._save_batch(model.encoder, 'encoder', hub_id=self.hub_model_encoder)
@@ -430,15 +439,16 @@ class JointModelSaveCallback(TrainerCallback):
430
439
  val_loss: float,
431
440
  val_metrics: dict
432
441
  ):
433
- self.finished_epochs += 1
434
- if val_loss < self.best_loss:
435
- self.best_loss = val_loss
436
- if isinstance(model, DistributedDataParallel):
437
- model = next(model.children())
438
- self._save_validation(model.encoder, 'encoder', epoch, val_loss, hub_id=self.hub_model_encoder)
439
- if not self.mlm_mode:
440
- self._save_validation(model.decoder, 'decoder', epoch, val_loss, hub_id=self.hub_model_decoder)
441
- self._save_validation(model.mlm_head, 'head', epoch, val_loss, hub_id=self.hub_model_head)
442
+ if self.rank == 0:
443
+ self.finished_epochs += 1
444
+ if val_loss < self.best_loss:
445
+ self.best_loss = val_loss
446
+ if isinstance(model, DistributedDataParallel):
447
+ model = next(model.children())
448
+ self._save_validation(model.encoder, 'encoder', epoch, val_loss, hub_id=self.hub_model_encoder)
449
+ if not self.mlm_mode:
450
+ self._save_validation(model.decoder, 'decoder', epoch, val_loss, hub_id=self.hub_model_decoder)
451
+ self._save_validation(model.mlm_head, 'head', epoch, val_loss, hub_id=self.hub_model_head)
442
452
 
443
453
  def _save_final(self, model: Union[nn.Module, PyTorchModelHubMixin], component: str, hub_id: str = None):
444
454
  try:
@@ -482,9 +492,10 @@ class JointModelSaveCallback(TrainerCallback):
482
492
  traceback.print_exc()
483
493
 
484
494
  def on_training_end(self, model: Union[torch.nn.Module, PyTorchModelHubMixin]):
485
- if isinstance(model, DistributedDataParallel):
486
- model = next(model.children())
487
- self._save_final(model.encoder, 'encoder', hub_id=self.hub_model_encoder)
488
- if not self.mlm_mode:
489
- self._save_final(model.decoder, 'decoder', hub_id=self.hub_model_decoder)
490
- self._save_final(model.mlm_head, 'head', hub_id=self.hub_model_head)
495
+ if self.rank == 0:
496
+ if isinstance(model, DistributedDataParallel):
497
+ model = next(model.children())
498
+ self._save_final(model.encoder, 'encoder', hub_id=self.hub_model_encoder)
499
+ if not self.mlm_mode:
500
+ self._save_final(model.decoder, 'decoder', hub_id=self.hub_model_decoder)
501
+ self._save_final(model.mlm_head, 'head', hub_id=self.hub_model_head)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rxnn
3
- Version: 0.1.8
3
+ Version: 0.1.10
4
4
  Summary: RxNN: Reactive Neural Networks Platform
5
5
  License: Apache-2.0
6
6
  Keywords: deep-learning,ai,machine-learning
@@ -7,9 +7,9 @@ rxnn/memory/stm.py,sha256=EsD8slSP4_9dLuq6aFPDmuFe8PWilxh90so5Z3nm-ig,2057
7
7
  rxnn/rxt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  rxnn/rxt/models.py,sha256=INTFeNcqzAsjyWhNtbBHL4Tx7tYDsaQHgm72tf6u20M,6918
9
9
  rxnn/training/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- rxnn/training/base.py,sha256=aZ_1cpCIt5aHI2LiW1QB20s5ltB7H6oDEe0psuLwVIA,11066
11
- rxnn/training/bml.py,sha256=pyK6aRLpXlPuLge6CQ9PD64Un57yUgbOpu8lUfTdV9k,14575
12
- rxnn/training/callbacks.py,sha256=IyVJAJ0ggJmfIWBZnpzV9U08URYCeWIStK_wbx7m3pg,21090
10
+ rxnn/training/base.py,sha256=YOtSLlG6-h0r54OJtyU777k5rNkbSCps3YFfB-Fh35g,11176
11
+ rxnn/training/bml.py,sha256=pEH0_pDy8QThsuYgfcT2lSdfMOnqGhlhu63xMFkUSOs,15246
12
+ rxnn/training/callbacks.py,sha256=_YfMKY_eFdc-tubhO9nYH2PXDZDQwlSI74FVOoCXpQg,22108
13
13
  rxnn/training/dataset.py,sha256=vQ5mDF3bA0HXya474n4D4iL8Mn3AEpJukgzFNVkxjGU,5106
14
14
  rxnn/training/scheduler.py,sha256=ow6oALzWjWQmHSpcJEjv6tg4g4CDMvr73TypxfcefMc,712
15
15
  rxnn/training/tokenizer.py,sha256=4Y41f07uo2KPA_7bp3FCcwGKbXoS2hsckOoXUsXfQxY,8052
@@ -23,7 +23,7 @@ rxnn/transformers/moe.py,sha256=JQ5QSX4FS7S-fqB7-s1ZmJbPpOeD_Injn8o4vo7wGQE,4936
23
23
  rxnn/transformers/positional.py,sha256=2l38RS0Dini3f6Z3LUHr3XwWzg1UK7fO2C6wazWDAYU,4292
24
24
  rxnn/transformers/sampler.py,sha256=wSz_1wNloqtuiix5w2Mcsj5NhaO9QlY0j__TVG7wJnM,3938
25
25
  rxnn/utils.py,sha256=d5U8i5ukovgDyqiycc2AoxObTz_eF_bgo2MKvdtJ98s,467
26
- rxnn-0.1.8.dist-info/LICENSE,sha256=C8coDFIUYuOcke4JLPwTqahQUCyXyGq6WOaigOkx8tY,11275
27
- rxnn-0.1.8.dist-info/METADATA,sha256=wgvRRqLr_5KkkWTbVxsaeqtC9DYl4Gjqvt5Q4PQkI8M,14628
28
- rxnn-0.1.8.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
29
- rxnn-0.1.8.dist-info/RECORD,,
26
+ rxnn-0.1.10.dist-info/LICENSE,sha256=C8coDFIUYuOcke4JLPwTqahQUCyXyGq6WOaigOkx8tY,11275
27
+ rxnn-0.1.10.dist-info/METADATA,sha256=dbmUcafrjisLl8YzU7Y9bBeSm0cJ2IaWnts8DdqWzMY,14629
28
+ rxnn-0.1.10.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
29
+ rxnn-0.1.10.dist-info/RECORD,,
File without changes
File without changes