fastmachinelearning / hls4ml

Machine learning on FPGAs using HLS
https://fastmachinelearning.org/hls4ml
Apache License 2.0
1.24k stars 402 forks source link

QKeras support for RNN layers #856

Closed laurilaatu closed 7 months ago

laurilaatu commented 1 year ago

Description

:memo: This pull request adds QKeras support for RNN layers

The quantizers for kernel, recurrent kernel and bias are retrieved from the QKeras model. State quantizer corresponds to the output precision of the hidden state which is set by altering the default precision (discussed in issue #825). Currently the quantized activations for the RNN layers are not supported.

Type of change

Tests

:memo: Please describe the tests that you ran to verify your changes.

  • Tested with several different network configurations
  • Pytests implemented
  • All layers produce expected output except for the Vivado implementation of the SimpleRNN (excluded from pytests)

Test Configuration: Quartus 21.1.0.169.pro

Example usage:

qmodel = Sequential()
qmodel.add(QSimpleRNN(4, input_shape=(5,1), name='rnn',
                      kernel_quantizer=quantized_bits(bits=9, integer=0, symmetric=False, alpha=1.0),
                      recurrent_quantizer=quantized_bits(bits=9, integer=0, symmetric=False, alpha=1.0),
                      bias_quantizer=quantized_bits(bits=9, integer=0, symmetric=False, alpha=1.0),
                      state_quantizer=quantized_bits(bits=9, integer=0, symmetric=False, alpha=1.0),
                      activation='relu'))
qmodel.summary()
qmodel.compile(loss='mse', optimizer='adam')

config = hls4ml.utils.config_from_keras_model(qmodel,
                                           default_precision="ap_fixed<9,1>",
                                           granularity='name')

hls_model = hls4ml.converters.convert_from_keras_model(qmodel,
                                           hls_config=config,
                                           output_dir='model_qrnn/hls4ml_prj',
                                           part='AGFB014R24A2E2VR0',
                                           backend='Quartus')
hls_model.compile()

Checklist

jmitrevs commented 11 months ago

@laurilaatu , is it possible for you to fix the conflicts so we can merge this PR?

laurilaatu commented 11 months ago

@jmitrevs , the conflict is now resolved.

vloncar commented 11 months ago

The newly added test fails with:

FAILED test_qkeras.py::test_qsimplernn[Quartus] - AssertionError: 
Not equal to tolerance rtol=1e-07, atol=0.1
Mismatched elements: 1 / 4 (25%)
Max absolute difference: 0.953125
Max relative difference: 1.
 x: array([[0.      , 1.004456, 0.024292, 0.352661]], dtype=float32)
 y: array([[0.953125, 0.921875, 0.015625, 0.351562]])

@laurilaatu can you investigate?

laurilaatu commented 10 months ago

@vloncar it seems that the test fails occasionally due to the random initialization. The latest commit fixes the issue by setting the seed. The issue does not affect QLSTM or QGRU.

Please let me know if any other changes are required.