ShuaiAnwo/pore-codec-rsqf42c12a-510
PoreCodec-RSQF42C12A

A lightweight neural codec for nanopore electrical signals based on convolutional feature extraction and Residual Finite Scalar Quantization (Residual FSQ). The model converts continuous nanopore current signals into hierarchical discrete token sequences that can be directly consumed by language models, sequence models, retrieval systems, or downstream bioinformatics applications.
Overview
PoreCodec-RSQF42C12A bridges continuous nanopore electrical signals and discrete sequence modeling. It learns compact discrete representations using a convolutional encoder followed by Residual Finite Scalar Quantization (Residual FSQ), enabling efficient token-based modeling of nanopore signals without the codebook collapse commonly associated with VQ-VAE methods.
The model consists of three major components:
- CNN Encoder
- Extracts latent representations from raw electrical current signals.
- Downsampling factor: 4×
- Output feature dimension: 512
- Residual Finite Scalar Quantizer (Residual FSQ)
- Multi-stage scalar quantization.
- Hierarchical residual coding.
- Produces discrete token representations suitable for transformer-based models.
- CNN Decoder
- Reconstructs normalized nanopore signals from discrete tokens.
Model Architecture
Raw Signal
│
▼
Feature Extractor
│
▼
CNN Encoder
│
▼
Linear Projection
│
▼
Residual FSQ
│
▼
Discrete Tokens
│
▼
Linear Projection
│
▼
CNN Decoder
│
▼
Reconstructed SignalCNN Encoder
The encoder consists of:
- Conv1D
- BatchNorm
- SiLU activation
- Two stride-2 downsampling stages
Residual FSQ
Residual quantization is performed using multiple Finite Scalar Quantizers (FSQ).
Each quantizer encodes the residual error from the previous stage, producing hierarchical discrete representations while maintaining high reconstruction fidelity.
Signal Preprocessing
The accompanying feature extractor performs automatic preprocessing before inference.
Pipeline:
- Physical boundary correction
- Spike removal
- Robust Median-MAD normalization
- Optional median filtering
- Smooth nonlinear clipping
Two preprocessing strategies are available.
apple (default)
- Error repair
- Spike removal
- Median-MAD normalization
- Median filtering
- Smooth clipping
mongo
- Error repair
- Spike removal
- Median-MAD normalization
- Smooth clipping
Quick Start
import numpy as np
from transformers import AutoFeatureExtractor, AutoModel
model_name = "ShuaiAnwo/pore-codec-rsqf42c12a-510"
feature_extractor = AutoFeatureExtractor.from_pretrained(
model_name,
trust_remote_code=True,
)
model = AutoModel.from_pretrained(
model_name,
trust_remote_code=True,
)
model.eval()
raw_signal = np.random.normal(
loc=70.0,
scale=8.0,
size=1855,
).astype(np.float32)
signal = feature_extractor(
raw_signal,
return_tensors="pt",
)["signal"]
token_ids = model.encode_signal(
signal,
layer=2,
)
reconstructed = model.decode_token(
token_ids,
layer=2,
)Usage
Load the Model
from transformers import (
AutoConfig,
AutoFeatureExtractor,
AutoModel,
)
model_name = "ShuaiAnwo/pore-codec-rsqf42c12a-510"
config = AutoConfig.from_pretrained(
model_name,
trust_remote_code=True,
)
feature_extractor = AutoFeatureExtractor.from_pretrained(
model_name,
trust_remote_code=True,
)
model = AutoModel.from_pretrained(
model_name,
trust_remote_code=True,
)
model.eval()
print(model.num_quantizers)Expected output
2Prepare Input
The feature extractor expects a one-dimensional NumPy array containing raw nanopore current measurements.
import numpy as np
raw_signal = np.random.normal(
loc=70.0,
scale=8.0,
size=1855,
).astype(np.float32)
signal = feature_extractor(
raw_signal,
return_tensors="pt",
)["signal"]
print(signal.shape)Expected output
torch.Size([1, 1, 1855])Encode Signals
encode_signal() converts normalized nanopore signals into hierarchical discrete token sequences.
token_ids = model.encode_signal(
signal,
layer=2,
)
print(token_ids.shape)
print(token_ids[0, :20])Expected output
torch.Size([1, 464])
tensor([
1132546210, 766619217, 767357412, 743923015,
744668606, 916327422, 1599713621, 1419557526,
1293561428, 963177038, 1086246378, 1270061142,
1280753282, 949579165, 1132645766, 1098553593,
1097767990, 961814960, 1269315414, 1600419564
])Supported layers
Decode Tokens
Discrete token sequences can be reconstructed back into normalized nanopore signals.
reconstructed = model.decode_token(
token_ids,
layer=2,
)
print(reconstructed.shape)Expected output
torch.Size([1, 1, 1856])Forward API
The forward interface performs end-to-end encoding and decoding in a single call.
reconstruction, level_indices = model(signal)
print(reconstruction.shape)
for i, indices in enumerate(level_indices):
print(f"Quantizer {i}: {indices.shape}")Returns
- reconstruction: reconstructed normalized signal
- level_indices: a list of quantization indices produced by each residual quantizer
Expected output
torch.Size([1, 1, 1856])
Quantizer 0: torch.Size([1, 464])
Quantizer 1: torch.Size([1, 464])Complete Example
import numpy as np
from transformers import (
AutoFeatureExtractor,
AutoModel,
)
model_name = "ShuaiAnwo/pore-codec-rsqf42c12a-510"
feature_extractor = AutoFeatureExtractor.from_pretrained(
model_name,
trust_remote_code=True,
)
model = AutoModel.from_pretrained(
model_name,
trust_remote_code=True,
)
model.eval()
raw_signal = np.random.normal(
loc=70.0,
scale=8.0,
size=1855,
).astype(np.float32)
signal = feature_extractor(
raw_signal,
return_tensors="pt",
)["signal"]
token_ids = model.encode_signal(
signal,
layer=2,
)
reconstructed = model.decode_token(
token_ids,
layer=2,
)
print("Signal shape :", signal.shape)
print("Token shape :", token_ids.shape)
print("Recon shape :", reconstructed.shape)Expected output
Signal shape : torch.Size([1, 1, 1855])
Token shape : torch.Size([1, 464])
Recon shape : torch.Size([1, 1, 1856])Validation Output
The following output was generated using the provided validation script and a real nanopore read.
============================================================
🚀 Starting PoreRSQCodec Closed-Loop Validation Pipeline
🎯 Target Analytical Layer (TARGET_LAYER): 2
============================================================
-> Safetensors structural keys count: 61
[Step 1] Loading local auto-mapped components...
-> AutoConfig loaded successfully!
-> AutoFeatureExtractor loaded successfully!
Loading weights: 100%|████████████████████████████████| 61/61
-> AutoModel (Safetensors weights) loaded successfully!
-> Total residual quantizer layers (num_quantizers): 2
✅ Component decoupling test passed!
[Step 2] Parsing real nanopore raw signals...
Read ID:
250F600084012_1_202_674_11920089_12557
Signal length:
1855
Current range:
[34.10, 99.00] pA
[Step 3] Feature preprocessing
Strategy:
apple
Normalized tensor:
torch.Size([1, 1, 1855])
✅ FeatureExtractor pipeline verification passed!
[Step 4] Encoding
Token shape:
torch.Size([1, 464])
Token value range:
[562424211, 1818974092]
✅ Quantization completed!
[Step 5] Decoding
Layer 1 reconstruction:
torch.Size([1, 1, 1856])
Layer 0 reconstruction:
torch.Size([1, 1, 1856])
Layer 2 reconstruction:
torch.Size([1, 1, 1856])
Ground Truth Mean:
68.2291
Layer 1 Mean:
-0.1262
Layer 0 Mean:
-0.1333
Layer 2 Mean:
-0.1333
✅ Reconstruction completed!Applications
This model can be used for:
- Nanopore signal tokenization
- Neural signal compression
- Discrete representation learning
- Foundation models for nanopore sequencing
- Biological sequence modeling
- Token-based pretraining for genomic language models
- Retrieval and indexing of nanopore signals
Model Configuration
License
Please refer to the repository license for usage terms.
Citation
If you use this model in your research, please cite the repository or the corresponding publication.
@misc{porecodec2026,
title={PoreCodec: Residual Finite Scalar Quantization for Nanopore Signal Tokenization},
author={Shuai Jiao},
year={2026}
}