Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LayerNorm support for Vivado #1110

Open
wants to merge 57 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
c4c818b
paser_mht
Ethan0Jiang Jul 13, 2022
3ee64d1
change parser and modify keras_to_hls
Ethan0Jiang Jul 13, 2022
5626a1a
IR_mutihead_attention
Ethan0Jiang Jul 14, 2022
d51f8a9
IR done
Ethan0Jiang Jul 15, 2022
89025a2
create mha file in template
Ethan0Jiang Jul 19, 2022
d76cf60
mha .h file dummy algo
Ethan0Jiang Jul 19, 2022
56811de
config of mha
Ethan0Jiang Jul 21, 2022
45cd493
update mha config
Ethan0Jiang Jul 21, 2022
1402f48
dummy mha
Ethan0Jiang Jul 21, 2022
430b9ea
add transpose into mha
Ethan0Jiang Jul 23, 2022
97f3e8d
projection_of_qkv_in_mha
Ethan0Jiang Jul 27, 2022
52cc7e8
mha_first_draft
Ethan0Jiang Aug 4, 2022
3961f97
able to predict model correct
Ethan0Jiang Aug 11, 2022
3533999
delete some unnassary comments
Ethan0Jiang Aug 11, 2022
d2f0df6
delete comments
Ethan0Jiang Aug 11, 2022
6aaa5ed
resource strategy of transformer
Ethan0Jiang Sep 16, 2022
3b7a288
change sm lagacy
Ethan0Jiang Oct 1, 2022
130092d
update MHA, optimized
Ethan0Jiang Oct 12, 2022
09b0ba0
support resource
Ethan0Jiang Oct 23, 2022
b49fffd
update
Ethan0Jiang Nov 27, 2022
5324a11
dense_muti_dim_support
Ethan0Jiang Dec 30, 2022
bf8c788
parallel execute dense
Ethan0Jiang Jan 1, 2023
b6be2c4
updates
Ethan0Jiang Jan 27, 2023
2472b7d
add_layerNorm_support
Ethan0Jiang Feb 15, 2023
97e71e9
MHA updated
Ethan0Jiang Feb 27, 2023
5ed4a76
LayerNorm_bug_fix
Ethan0Jiang Apr 4, 2023
5d28f58
update bit precision
Ethan0Jiang Apr 15, 2023
2fc68d0
config update
Ethan0Jiang Apr 17, 2023
b5c95cf
add some comment
Ethan0Jiang Apr 21, 2023
3b8aa8d
run pre-commit
JanFSchulte Sep 13, 2024
d28b24c
Added support on QMultiHeadAttention, QLayerNormalization, and quanti…
LostEcho365 Aug 7, 2023
de79bb9
updated on hls4ml transformer
LostEcho365 Nov 12, 2023
6c23326
trying to clean the diff
JanFSchulte Sep 13, 2024
20a0199
trying to clean the diff
JanFSchulte Sep 13, 2024
ddccde2
trying to clean the diff
Sep 17, 2024
afbe00b
trying to clean the diff
Sep 17, 2024
dedf96c
trying to clean the diff
Sep 17, 2024
a9de9cb
undo vhdl -> verilog change
Sep 18, 2024
49313d3
halfway working layernorm + test
Sep 18, 2024
1156ba5
layernorm is now pretty functional
Sep 18, 2024
17e0048
layernorm on pytorch also
Sep 19, 2024
63891fd
minor cleanup
Sep 19, 2024
8dccac6
more cleanup, pre-commit
Sep 19, 2024
595cc71
test for mha which kinda works maybe if you squint
Sep 19, 2024
5f3ec00
multihead attention working on keras and pytorch
Sep 20, 2024
5697334
fiddly precision / accuracy changes for layernorm
Sep 25, 2024
d2e27b8
Merge remote-tracking branch 'upstream/main' into transformer
rianbrooksflynn Oct 11, 2024
a149f2e
fix lookup table and label loops
rianbrooksflynn Oct 22, 2024
552fa83
remove dense_seq
rianbrooksflynn Oct 23, 2024
69f26bc
Merge remote-tracking branch 'upstream/main' into transformer
rianbrooksflynn Oct 23, 2024
be5f5a4
undo qkeras changes
rianbrooksflynn Oct 23, 2024
adf7356
fix merge conflict residue
rianbrooksflynn Oct 24, 2024
8437581
Merge remote-tracking branch 'upstream/main' into transformer
rianbrooksflynn Nov 4, 2024
39ab36c
remove non-layernorm changes
rianbrooksflynn Nov 4, 2024
b5b82e2
change to uniform LUT and fix precision
rianbrooksflynn Dec 9, 2024
f3ff077
Merge remote-tracking branch 'upstream/main' into layernorm
rianbrooksflynn Dec 9, 2024
0f08e7a
[pre-commit.ci] auto fixes from pre-commit hooks
pre-commit-ci[bot] Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 63 additions & 1 deletion hls4ml/backends/vivado/passes/core_templates.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
from hls4ml.backends.backend import get_backend
from hls4ml.backends.template import FunctionCallTemplate, LayerConfigTemplate
from hls4ml.model.layers import Activation, BatchNormalization, Dense, HardActivation, ParametrizedActivation, PReLU, Softmax
from hls4ml.model.layers import (
Activation,
BatchNormalization,
Dense,
HardActivation,
LayerNormalization,
ParametrizedActivation,
PReLU,
Softmax,
)
from hls4ml.model.optimizer.passes.hgq_proxy_model import UnaryLUT

# Dense templates
Expand Down Expand Up @@ -119,6 +128,59 @@ def format(self, node):
return self.template.format(**params)


# LayerNormalization templates

layernorm_config_template = """struct config{index} : nnet::layernorm_config {{
static const unsigned n_in = {n_in};
static const unsigned seq_len = {seq_len};
static const unsigned table_size = {table_size};
static constexpr double table_range = {table_range};
static const unsigned io_type = nnet::{iotype};
static const unsigned reuse_factor = {reuse};
static const bool store_weights_in_bram = false;
static constexpr double epsilon = {epsilon};
typedef {bias_t.name} bias_t;
typedef {scale_t.name} scale_t;
typedef {mean_t.name} mean_t;
typedef {table_t.name} table_t;
template<class x_T, class y_T>
using product = nnet::product::{product_type}<x_T, y_T>;
}};\n"""

layernorm_function_template = 'nnet::layernormalize<{input_t}, {output_t}, {config}>({input}, {output}, {scale}, {bias});'

layernorm_include_list = ['nnet_utils/nnet_layernorm.h']


class LayerNormalizationConfigTemplate(LayerConfigTemplate):
def __init__(self):
super().__init__(LayerNormalization)
self.template = layernorm_config_template

def format(self, node):
params = self._default_config_params(node)
params['n_in'] = node.get_input_variable().size_cpp()
params['seq_len'] = node.get_attr('seq_len')
params['product_type'] = get_backend('vivado').product_type(
node.get_input_variable().type.precision, node.get_weights('scale').type.precision
)

return self.template.format(**params)


class LayerNormalizationFunctionTemplate(FunctionCallTemplate):
def __init__(self):
super().__init__(LayerNormalization, include_header=layernorm_include_list)
self.template = layernorm_function_template

def format(self, node):
params = self._default_function_params(node)
params['scale'] = node.get_weights('scale').name
params['bias'] = node.get_weights('bias').name

return self.template.format(**params)


# Activation templates

activ_config_template = """struct {type}_config{index} : nnet::activ_config {{
Expand Down
16 changes: 16 additions & 0 deletions hls4ml/backends/vivado/vivado_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
GarNet,
GarNetStack,
Layer,
LayerNormalization,
Pooling1D,
Pooling2D,
SeparableConv1D,
Expand Down Expand Up @@ -558,6 +559,21 @@ def init_softmax(self, layer):
len(layer.get_input_variable().shape) == 1
), 'Softmax with io_parallel strategy cannot be used on multidimensional tensors.'

@layer_optimizer(LayerNormalization)
def init_layernormalization(self, layer):
if 'table_t' not in layer.attributes:
layer.set_attr(
'table_t', NamedType(name=layer.name + '_table_t', precision=FixedPrecisionType(width=16, integer=6))
)
if 'table_size' not in layer.attributes:
layer.set_attr('table_size', 4096) # table size
if 'table_range' not in layer.attributes:
layer.set_attr('table_range', 1.0) # table range
if 'mean_t' not in layer.attributes:
layer.set_attr(
'mean_t', NamedType(name=layer.name + '_mean_t', precision=FixedPrecisionType(width=19, integer=6))
)

@layer_optimizer(Embedding)
def init_embed(self, layer):
if layer.attributes['n_in'] is None:
Expand Down
Loading