Skip to content

RADE V2 prototyping#42

Open
drowe67 wants to merge 168 commits intomainfrom
dr-radev2
Open

RADE V2 prototyping#42
drowe67 wants to merge 168 commits intomainfrom
dr-radev2

Conversation

@drowe67
Copy link
Owner

@drowe67 drowe67 commented Jan 17, 2025

Bandwidth/PAPR

Exploring ideas to improve 99% power bandwidth (spectral mask) from RADE V1. Just prototyping with "mixed rate" training and inference, i.e. no pilots or CP, genie phase.

  • Worked out how to put a BPF in training loop (conv1d with training disabled)
  • Take away that phase only (PAPR 0dB) works quite well
  • clip-BPF x 3 produces reasonable 99% power BW, 0dB PAPR, good loss
  • Doc ML EQ training and inference in README.md when we get to final V2 version. Just collect notes here in comments until then

Training:

python3 train.py --cuda-visible-devices 0 --sequence-length 400 --batch-size 512 --epochs 200 --lr 0.003 --lr-decay-factor 0.0001 ~/Downloads/tts_speech_16k_speexdsp.f32 250117_test --bottleneck 3 --h_file h_nc20_train_mpp.f32 --range_EbNo --plot_loss --auxdata --txbpf
Epoch 200 Loss 0.116

Testing:

./inference.sh 250117_test/checkpoints/checkpoint_epoch_200.pth wav/brian_g8sez.wav - --bottleneck 3 --auxdata --write_tx tx_bpf.f32 --write_latent z.f32 --txbpf
          Eb/No   C/No     SNR3k  Rb'    Eq     PAPR
Target..: 100.00  133.01   98.24  2000
Measured: 102.89          101.12       1243.47  0.00
loss: 0.121 BER: 0.000

octave:154> radae_plots; do_plots('z.f32','tx_bpf.f32')
bandwidth (Hz): 1255.813953 power/total_power: 0.990037

Red lines mark 99% power bandwidth:

Screenshot from 2025-01-22 07-13-34

ML EQ

Classical DSP:

python3 ml_eq.py --eq dsp --notrain --EbNodB 4 --phase_offset

MSE loss function:

python3 ml_eq.py --EbNodB 4 --phase_offset --lr 0.001 --epochs 100

Phase loss function:

python3 ml_eq.py --EbNodB 4 --phase_offset --lr 0.001 --epochs 100 --loss_phase

@drowe67
Copy link
Owner Author

drowe67 commented Feb 3, 2025

Frame 2 EQ examples

  1. Ideal (perfect EQ)

    python3 ml_eq.py --frame 2 --notrain --eq bypass --EbNodB 4
    <snip>
    EbNodB:  4.00 n_bits: 240000 n_errors: 3027 BER: 0.013
    
  2. Classical DSP lin:

    python3 ml_eq.py --eq dsp --notrain --EbNodB 4 --phase_offset --frame 2
    <snip>
    EbNodB:  4.00 n_bits: 240000 n_errors: 3921 BER: 0.016
    
  3. ML EQ (using MSE loss function):

    python3 ml_eq.py --frame 2 --lr 0.1 --epochs 100 --EbNodB 4 --phase_offset --n_syms 1000000 --batch_size 128
    <snip>
    EbNodB:  4.00 n_bits: 24000000 n_errors: 437933 BER: 0.018
    

@drowe67
Copy link
Owner Author

drowe67 commented Feb 4, 2025

ML waveform training

  1. Generate 10 hour complex h file:
    Fs=8000; Rs=50; Nc=20; multipath_samples('mpp', Fs, Rs, Nc, 10*60*60, 'h_nc20_train_mpp.c64',"",1);
    
  2. Training:
    python3 train.py --cuda-visible-devices 0 --sequence-length 400 --batch-size 512 --epochs 200 --lr 0.003 --lr-decay-factor 0.0001 ~/Downloads/tts_speech_16k_speexdsp.f32 250204_test --bottleneck 3 --h_file h_nc20_train_mpp.c64 --h_complex --range_EbNo --plot_loss --auxdata
    

@drowe67
Copy link
Owner Author

drowe67 commented Jan 13, 2026

Jan 2026 Timing corner case

While extending ota_test.sh to cover V2, it was discovered the timing estimator sometimes returns values that upset V2 decoder, leading to high loss. To reproduce, we can use the ota_test.sh test framework:

./test/ota_test_cal.sh ~/codec2-dev/build_linux/ -30 0.4 --mpp --freq -25
./ota_test.sh -d -r rx.wav -l wav/brian_g8sez.wav
<snip>
+ python3 loss.py brian_g8sez_features_in.f32 brian_g8sez_features_out_tx1.f32 --features_hat2 features_out_rx1.f32 --compare
loss1: 0.121 loss2: 0.299 delta: 0.178
+ python3 loss.py brian_g8sez_features_in.f32 brian_g8sez_features_out_tx2.f32 --features_hat2 features_out_rx2.f32 --compare
loss1: 0.091 loss2: 3.416 delta: 3.326

Note very high loss2.

The interaction between the timing estimator and the ML decoder hasn't been well understood to date. A timing model has been developed and written up in Section 11 of 2025_rade_hf3. In V1 the pilot phase phase correction took care of timing offsets. In V2 the network must be able to handle them.

Running just the V2 receiver:

python3 ./rx2.py 250725/checkpoints/checkpoint_epoch_200.pth 250725_ml_sync /tmp/tmp.ehSKyo9nPa.f32 features_out_rx2.f32 --latent-dim 56 --w1_dec 128 --agc --quiet
python3 loss.py brian_g8sez_features_in.f32 brian_g8sez_features_out_tx2.f32 --features_hat2 features_out_rx2.f32 --compare

The rx2.sh cmd line was copied from the ./ota_test.sh run, not the tmp filename will vary. The problem can be illustrated by dumping the timing variables:

python3 ./rx2.py 250725/checkpoints/checkpoint_epoch_200.pth 250725_ml_sync /tmp/tmp.ehSKyo9nPa.f32 features_out_rx2.f32 --latent-dim 56 --w1_dec 128 --agc --quiet --write_delta_hat delta_hat.int16 --write_delta_hat_pp delta_hat_pp.int16 --write_sig_det sig_det.int16
octave:1> delta_hat=load_raw('delta_hat.int16'); figure(1); clf; plot(delta_hat); delta_hat_pp = load_raw('delta_hat_pp.int16'); hold on; plot(delta_hat_pp); sig_det=load_raw('sig_det.int16'); plot(sig_det*175); hold off;

The post processor output delta_hat_pp locks onto a timing estimate at the high end of the MPP channel delay range (around 60), this value causes a high loss in the decoded signal. When we fix the timing est at 50 using --fix_delta_hat 50, we get acceptable loss.

Script that supports testing timing offsets and verifying models in the paper:

./test/v2_timing.sh --correct_time_offset -22

Testing proposed solution:

octave:> multipath_samples("mpp_low", 8000, 50, 14, 10, "", "g_mpp_low.f32")
octave:> multipath_samples("mpp_high", 8000, 50, 14, 10, "", "g_mpp_high.f32")

./test/v2_timing.sh --g_file g_mpp_low.f32 --correct_time_offset -8 --fix_delta_hat 32
./test/v2_timing.sh --g_file g_mpp_low.f32 --correct_time_offset -8 --fix_delta_hat 48
./test/v2_timing.sh --g_file g_mpp_high.f32 --correct_time_offset -8 --fix_delta_hat 32
./test/v2_timing.sh --g_file g_mpp_low.f32 --correct_time_offset -8 --fix_delta_hat 48

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant