Loading weights from external BRAM
Note
This feature is being evaluated for re-implementation. We welcome feedback from users how to make the implementation more flexible.
hls4ml
can optionally store weights in BRAMs external to the design. This is supported in Vivado/Vitis and Catapult backends. It is the responsibility of the user to ensure the weights are properly loaded during the operation of the design.
The feature works as a threshold, exposed through a BramFactor
config parameter. Layers with more weights above the threshold will be exposed as BRAM interface. Consider the following code:
model = tf.keras.models.Sequential()
model.add(Dense(10, activation="relu", input_shape=(12,), name="dense_1"))
model.add(Dense(20, activation="relu", name="dense_2"))
model.add(Dense(5, activation="softmax", name="dense_3"))
model.compile(optimizer='adam', loss='mse')
config = hls4ml.utils.config_from_keras_model(model)
config["Model"]["Strategy"] = "Resource"
config["Model"]["BramFactor"] = 100
hls_model = hls4ml.converters.convert_from_keras_model(
model, hls_config=config, output_dir=output_dir, io_type=io_type, backend=backend
)
Having set BramFactor=100
, only layers with more than 100 weights will be exposed as external BRAM, in this case layers dense_1
and dense_2
. BramFactor
can currently be only set at the model level. The generated code will now have weights as part of the interface.
void myproject(
hls::stream<input_t> &dense_1_input,
hls::stream<result_t> &layer7_out,
model_default_t w2[120],
model_default_t w4[200]
) {
#pragma HLS INTERFACE axis port=dense_1_input,layer7_out
#pragma HLS INTERFACE bram port=w2,w4
...
When integrating the design, users can use the exposed interface to implement weight reloading scheme.