chore: import upstream snapshot with attribution
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:14:16 +08:00
commit 8a852e4b4e
36502 changed files with 9277225 additions and 0 deletions
+168
View File
@@ -0,0 +1,168 @@
# Composable Tensorflow
## Composable Tensorflow
Composable TensorFlow (TF) is the framework for defining portable TF ops with
composition in the authoring language.
The set of standard TF ops is currently open. New ops are defined for special
purposes but it is hard to make them work end-to-end: The op
needs to be handled separately by several backends (tf2xla bridge, tflite
converter, CPU kernels, etc.). Writing shape functions and gradients for these
ops is extremely difficult. `tf.function` makes some parts of the implementation
simpler, but it introduces runtime overhead and it cannot easily be used to
apply dedicated optimizations to op kernels.
The composable TF framework allows the user to define portable TF ops as
compositions of other TF ops. It translates a Python function used to define the
composition directly into a portable IR at build time, and uses it to expand the
composite op in the TF program during compilation / execution. By using this
expansion mechanism, new op are readily available on different platforms without
extra work. Moreover, since the expansion is optional, the backend can easily
treat it as a monolithic op when needed, for instance to apply optimizations or
associate it with a custom kernel.
### Benefits
Using the Composable TF API to define a new op and its composition can bring the
following benefits:
* *Automatic backend support*: As long as it is composed of ops supported by
the backend, the new op is automatically supported (as a `tf.function`
alternative);
* *Reduced tracing overhead*: Unlike `tf.function`, the composition function
is compiled at build time, hence TF only needs to trace a single op to build
the `graph`;
* *Easy fused op/kernel optimization*: Even if it has complex semantics, the
new op is presented as a single node in the graph, thus optimization passes
and kernels can easily be specialized to this op for better performance.
* *Automatic shape/type inference support*: No shape functions are required
for the new op;
* *Automatic gradient support (WIP)*: The user doesn't need to author gradient
a function of the op for training.
### Use Cases
* (Portability) User wants to add a new op and run this op on different
platforms (CPU, TPU, TFLite, etc.) to be portable.
* *Solution*: The user should define the new op as a composition. The ops
used inside the composition should have support for these platforms.
These ops can also be composite ops.
* (Performance) User defines a custom kernel for a regular structure (i.e.
LSTM), but it is hard to add the logic to fuse the individual ops to target
this kernel in the inference graph.
* *Solution*: The user should define a new TF op, which corresponds to the
fused kernel, with composition, and use this op to build the model for
both training and inference. For the platforms where a fused kernel is
not available, the execution will use the composition instead.
## Gradient
(TODO)
## Authoring Op Composition in Python
The composable TF provides a single API to define a new op with its composition
at the same time. For example, the following code defines a new
`FusedFullyConnected` op, which have `MatMul`, `Add` and some
`activation function` (specified by an op attribute) fused.
```python
import tensorflow as tf
@Composite(
'FusedFullyConnected',
inputs=['input_: T', 'filter_: T', 'bias: T'],
attrs=['act: {"", "RELU", "RELU6", "TANH"} = ""'],
derived_attrs=['T: {float, int8}'],
outputs=['o: T'])
def _composite_fully_connected(input_, filter_, bias, act):
res = tf.raw_ops.MatMul(
a=input_, b=filter_, transpose_a=False, transpose_b=True)
res = tf.raw_ops.Add(x=res, y=bias)
if act == 'RELU':
return tf.raw_ops.Relu(features=res)
elif act == 'RELU6':
return tf.raw_ops.Relu6(features=res)
elif act == 'TANH':
return tf.raw_ops.Tanh(x=res)
else:
return res
```
Besides defining new ops, composition can be specified for an existing op
for portability. The following code defines the semantics of `AddNOp`:
```python
@Composite('AddNOp')
def _my_op_c(ins):
N = len(ins)
if N == 1:
return ins[0]
sum = ins[0]
for i in range(1, N):
sum += ins[i]
return sum
```
Utilities have been built to compile the Python composition functions down to
the backend IR. The project also provides a set of graph optimization passes to
expand the composite ops in the graph by using the input backend IR. These
passes have been added to the TF
[common runtime](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/common_runtime)
for graph execution and
[eager runtime](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/common_runtime/eager)
for eager execution.
## Compiling Op Composition
### Ahead-Of-Time (AOT) mode
Like the op kernels, the op composition can be pre-compiled to the backend IR
so the decomposition can be invoked at runtime. A Python [define_op_template.py](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/compiler/mlir/tfr/define_op_template.py)
file is provided as an example to build composite ops in the users project
directory. All the targets required to build the new ops are created by the
following target:
```BUILD
load("//tensorflow/compiler/mlir/tfr:build_defs.bzl", "gen_op_libraries")
gen_op_libraries(
name = "test_ops",
src = "define_op_template.py",
deps = [
"//third_party/py/tensorflow",
],
)
```
More composite op definitions and usages are here included in the
[examples](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/compiler/mlir/tfr/examples)
directory.
### Just-In-Time (JIT) mode
(TODO)
## Known Limitations
* `while` statement
* condition of `if` statement couldn't be a tensor
## RFC
This project is an alternative implementation of
[RFC:Standardizing composite ops in tensorflow to support efficient inference](https://github.com/tensorflow/community/blob/master/rfcs/20190610-standardizing-composite_ops.md).
This project doesn't rely on the tracing functionality provided by `tf.function`
to avoid all its pitfalls and it helps to build more general transformations in
the backends.
## Team
* Feng Liu
* Dan Moldovan