Skip to content

Commit

Permalink
更新文档添加 softmax 量化
Browse files Browse the repository at this point in the history
  • Loading branch information
liuxinwei committed Jun 5, 2024
1 parent f0f1f89 commit a749d71
Show file tree
Hide file tree
Showing 67 changed files with 3,474 additions and 1,153 deletions.
1 change: 0 additions & 1 deletion doc/chaos/tutorials/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
:maxdepth: 3
basic/index
transform/index
../quantize/index
relay/index
../vta/index
Expand Down
1 change: 0 additions & 1 deletion doc/chaos/tutorials/relay/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
start/index
merge-composite
build-module
transform/index
annotated-regions
compiler-regions
annotate-target
Expand Down
11 changes: 0 additions & 11 deletions doc/chaos/tutorials/transform/index.md

This file was deleted.

45 changes: 44 additions & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
import sys
from pathlib import Path
from docutils.nodes import literal_block
from pygments.lexers import ClassNotFound, find_lexer_class_by_name
from sphinx.locale import __
from sphinx.transforms.post_transforms import SphinxPostTransform

ROOT = Path(__file__).resolve().parents[1]
print(ROOT)
Expand Down Expand Up @@ -75,9 +79,11 @@
"mystnb.unknown_mime_type", # 禁用 application/vnd.plotly.v1+json and application/vnd.bokehjs_load.v0+json 警告
"myst.xref_missing", # 禁用 myst 警告
"autoapi.python_import_resolution", "autoapi.not_readable" # 禁用 autoapi 警告
"sphinx_automodapi.automodapi",
"autosectionlabel.*", "autosummary", "intersphinx.external",
"autodoc", "autodoc.import_object"
]


# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

Expand Down Expand Up @@ -328,3 +334,40 @@
autoapi_keep_files = False # 要开始自己编写 API 文档,你可以让 AutoAPI 保留其生成的文件作为基础
autoapi_root = "api"
autoapi_member_order = "groupwise"

class LexerValidation(SphinxPostTransform):
"""参考:https://github.com/sphinx-doc/sphinx/issues/11442"""
default_priority = 500
builders = ('dummy',)

def __init__(self, *args, **kwargs):
from sphinx.highlighting import lexers, lexer_classes, logger

super().__init__(*args, **kwargs)
self.lexer_names = lexers.keys() | lexer_classes.keys()
self.logger = logger

def run(self, **kwargs):
for node in self.document.findall(literal_block):
lang = node.get('language', 'default')
self.logger.info(f"lang, node: {lang, node}")
self.validate_lexer(lang, node)

def validate_lexer(self, lang, location):
if lang in {'py', 'py3', 'python3', 'default', 'pycon3'}:
lang = 'python'

if lang in {'C++14', 'C++17', 'C++', 'C++20', 'C++11'}:
lang = 'cpp'

if lang in self.lexer_names:
return

try:
lexer = find_lexer_class_by_name(lang)
except ClassNotFound:
self.logger.warning(__('Pygments lexer name %r is not known'), lang,
location=location)

def setup(app):
app.add_post_transform(LexerValidation)
4 changes: 2 additions & 2 deletions doc/read/ffi/relay-expr.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
"1. `TempExprNode`类:\n",
" - 这个类代表临时表达式的基本类型。临时表达式是在重写过程中有用的特定表达式,例如布局或类型转换。\n",
" - 它有虚析构函数,这意味着它可以被正确地析构,即使通过基类指针删除派生类对象。\n",
" - 它有纯虚函数 `Realize()`,这个函数的目的是将表达式转换为非临时的表达式。具体实现由子类提供。\n",
" - 它有纯虚函数 `Realize()`,这个函数的目的是将表达式转换为普通的(非临时的)表达式。具体实现由子类提供。\n",
" - 它还定义了一些静态常量,包括一个字符串类型的键值 `_type_key`,以及三个布尔类型的值 `_type_has_method_sequal_reduce`、`_type_has_method_shash_reduce` 和 `_type_child_slots`。这些值可能用于在内部跟踪或处理该类型的对象。\n",
" - 最后,`TVM_DECLARE_BASE_OBJECT_INFO` 宏用于声明 `TempExprNode` 的一些基本信息,如名称、父类等。\n",
"\n",
"2. `TempExpr`类:\n",
" - 使用 `TVM_DEFINE_OBJECT_REF_METHODS` 宏来定义一些方法引用。这意味着 `TempExpr` 对象可以像 `RelayExpr` 对象一样使用这些方法。\n",
" - 使用 `TVM_DEFINE_OBJECT_REF_METHODS` 宏来定义一些方法引用。这意味着 `TempExpr` 对象可以像 `RelayExpr` 对象一样使用这些方法。这些方法允许我们在 `RelayExpr` 和 `TempExprNode` 之间进行转换。\n",
"\n",
"总的来说,这段代码定义了 TVM 中的两种表达式类型:`TempExprNode` 和 `TempExpr`。`TempExpr` 是 `TempExprNode` 的具体实现,可以被用来创建临时表达式。"
]
Expand Down
1 change: 1 addition & 0 deletions doc/read/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ name-supply
memory-passes
uma/index
relay/index
qnn/index
testing/index
codegen/index
contrib/index
Expand Down
209 changes: 209 additions & 0 deletions doc/read/qnn/FTVMQnnCanonicalize.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# FTVMQnnCanonicalize\n",
"\n",
"源码:`tvm/include/tvm/relay/qnn/transform.h`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```cpp\n",
"/*!\n",
" * \\brief Legalizes a QNN expr. Contains specifically two types of Legalizations. First,\n",
" * converts/Lowers an expression containing QNN ops to an expression containing only core Relay ops.\n",
" * Each QNN op is lowered to a sequence of exisiting Relay ops. This is a target-independent pass.\n",
" * One can register the lowering/transformation function for this op using FTVMQnnCanonicalize\n",
" * attr_name for FTVMLegalize op attribute. Second, as opposed to Relay Legalize, this one legalizes\n",
" * only QNN ops. One can register a transformation/legalization function for an op by using the\n",
" * FTVMQnnLegalize attr_name for FTVMLegalize op attribute. The isolation of QNN and Relay Legalize\n",
" * gives us separation of concerns, leading to a better software practice. The legalization can be\n",
" * configured to happen per target.\n",
" *\n",
" * \\return The pass.\n",
" */\n",
"TVM_DLL Pass Legalize();\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"这段代码是一个名为 `Legalize` 的函数,它的作用是将 QNN 表达式合法化。具体来说,它包含两种类型的合法化:\n",
"\n",
"1. 将包含 QNN 算子的表达式转换为仅包含核心 Relay 算子的表达式。每个 QNN 算子都会被转换为一系列现有的 Relay 算子。这是一个与目标 target 无关的传递。可以使用 `FTVMQnnCanonicalize` 属性名称为 `FTVMLegalize` 算子属性注册 transformation/legalization 函数。\n",
"\n",
"2. 与 Relay Legalize 不同,这个函数只对 QNN 算子进行合法化。可以通过使用 `FTVMQnnLegalize` 属性名称为 `FTVMLegalize` 算子属性注册一个算子的 transformation/legalization 函数。QNN 和 Relay Legalize 的隔离使我们能够更好地分离关注点,从而得到更好的软件实践。合法化可以针对每个目标(target)进行配置。\n",
"\n",
"函数返回 Pass 对象。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## {func}`~tvm.relay.qnn.transform.CanonicalizeOps`\n",
"\n",
"源码:`tvm/python/tvm/relay/qnn/transform.py`"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import testing"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[0;31mSignature:\u001b[0m \u001b[0mCanonicalizeOps\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mDocstring:\u001b[0m\n",
"Converts/Lowers an expression containing QNN ops to an expression containing only core\n",
"(non-Dialect) Relay ops. Each QNN op is lowered to a sequence of existing Relay ops. This is a\n",
"target-independent pass. One can register the lowering/transformation function for this op using\n",
"FTVMQnnCanonicalize attr_name for FTVMLegalize op attribute. An example of this transformation\n",
"is below\n",
"\n",
"Examples\n",
"________\n",
"\n",
".. code-block:: python\n",
"\n",
" # Original expression\n",
" qnn_expr = relay.qnn.op.requantize(y,\n",
" input_scale=1,\n",
" input_zero_point=0,\n",
" output_scale=1,\n",
" output_zero_point=0,\n",
" out_dtype='int8')\n",
"\n",
" # We want to utilize all the existing Relay infrastructure. So, instead of supporting this\n",
" # QNN requantize op, we convert it into a sequence of existing Relay operators.\n",
" mod = tvm.IRModule.from_expr(qnn_expr)\n",
" mod = relay.qnn.transform.CanonicalizeOps()(mod)\n",
" relay_expr = mod['main']\n",
" print(relay_expr)\n",
"\n",
" def @main(%quantized_data: Tensor[(200), int32]) -> Tensor[(200), int8] {\n",
" %0 = cast(%quantized_data, dtype=\"int64\") /* ty=Tensor[(200), int64] */;\n",
" %1 = multiply(%0, 2 /* ty=int64 */) /* ty=Tensor[(200), int64] */;\n",
" %2 = multiply(%1, 1073741824 /* ty=int64 */) /* ty=Tensor[(200), int64] */;\n",
" %3 = add(%2, 1073741824 /* ty=int64 */) /* ty=Tensor[(200), int64] */;\n",
" %4 = right_shift(%3, 31 /* ty=int64 */) /* ty=Tensor[(200), int64] */;\n",
" %5 = add(0 /* ty=int64 */, %4) /* ty=Tensor[(200), int64] */;\n",
" %6 = clip(%5, a_min=-128f, a_max=127f) /* ty=Tensor[(200), int64] */;\n",
" cast(%6, dtype=\"int8\") /* ty=Tensor[(200), int8] */\n",
" }\n",
"\n",
"Returns\n",
"-------\n",
"ret : tvm.transform.Pass\n",
" The registered pass that canonicalizes QNN ops to Relay ops.\n",
"\u001b[0;31mFile:\u001b[0m /media/pc/data/lxw/ai/tvm/python/tvm/relay/qnn/transform.py\n",
"\u001b[0;31mType:\u001b[0m function"
]
}
],
"source": [
"from tvm.relay.qnn.transform import CanonicalizeOps\n",
"\n",
"CanonicalizeOps?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"这段代码定义了一个名为 `CanonicalizeOps` 的函数,它的作用是将包含 QNN 算子的表达式转换为仅包含核心(非 Dialect)Relay 算子的表达式。每个 QNN 算子都会被转换为一系列现有的 Relay 算子。这是一个与目标无关的传递。\n",
"\n",
"函数返回 {class}`tvm.transform.Pass` 对象,该对象将 QNN 算子规范化为 Relay 算子。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"可以使用 `FTVMQnnCanonicalize` 属性名称为 `FTVMLegalize` 算子属性注册 lowering/transformation 函数。"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[0;31mSignature:\u001b[0m \u001b[0mregister_qnn_canonicalize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mop_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlegal_op\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlevel\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mDocstring:\u001b[0m\n",
"Register canonicalization function for a QNN op.\n",
"\n",
"This transforms QNN ops to mainline Relay components.\n",
"\n",
"Parameters\n",
"----------\n",
"op_name : str\n",
" The name of the operator\n",
"\n",
"legal_op: function (Attrs, List[Expr], List[relay.Type]) -> Expr\n",
" The function for transforming an expr to another expr.\n",
"\n",
"level : int\n",
" The priority level\n",
"\u001b[0;31mFile:\u001b[0m /media/pc/data/lxw/ai/tvm/python/tvm/relay/qnn/op/op.py\n",
"\u001b[0;31mType:\u001b[0m function"
]
}
],
"source": [
"from tvm.relay.qnn.op import register_qnn_canonicalize\n",
"\n",
"register_qnn_canonicalize?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "py312x",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading

0 comments on commit a749d71

Please sign in to comment.