人妻精品在线观看一区二区三区,蜜臀av精品一区二区三区网站,中文一区二区三区亚洲欧美,熟女人妇精品一区二区,人妻av在线观看视频,欧美日韩国产三级精品网站,黄色免费网站直接进入,超碰公开福利正在播放,国产毛片乡下农村妇女毛片

OneFlow源碼解析:靜態(tài)圖與運行時

來源:CSDN博客 | 2023-01-06 19:07:24 |

作者|鄭建華 更新|許嘯宇、張文驍、成誠OneFlow靜態(tài)圖的訓練效率遠高于動態(tài)圖(eager模式)。本文試圖通過一個簡單例子,結合v0.8.0版本的代碼,解讀一下靜態(tài)圖和運行時的實現(xiàn)機制。

在開始之前,建議先讀一下參考資料中《OneFlow框架的系統(tǒng)設計(https://zhuanlan.zhihu.com/p/337851255)》等系列文章。對靜態(tài)圖、運行時的基本概念和設計理念有基本的了解,會更容易理解代碼。


(相關資料圖)

1?

代碼示例

下面的示例代碼來自官方文檔(https://docs.oneflow.org/master/basics/08_nn_graph.html),是一個線性模型的前向計算。后續(xù)主要基于這段代碼進行分析。

import oneflow as flowimport oneflow.nn as nnclass ModuleMyLinear(nn.Module): def __init__(self, in_features, out_features): super().__init__() self.weight = nn.Parameter(flow.randn(in_features, out_features)) self.bias = nn.Parameter(flow.randn(out_features)) def forward(self, input): return flow.matmul(input, self.weight) + self.biaslinear_model = ModuleMyLinear(4, 3)class GraphMyLinear(nn.Graph): def __init__(self): super().__init__() # ModuleBlock self.model = linear_model def build(self, input): # ModuleBlock.__call__ return self.model(input)graph_mylinear = GraphMyLinear()input = flow.randn(1, 4)out = graph_mylinear(input)print(out)

2?

oneflow包的初始化

import oneflow在初始化包(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/__init__.py)時,與靜態(tài)圖相關的主要操作如下:

GetEnv(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/__init__.py#L228

EnvGlobalObjectsScope::Init(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L126

啟動各個節(jié)點的控制面(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L160-L162)網絡連接

初始化VM(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L180

啟動各個節(jié)點的數據面網絡連接(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L184-L188

初始化KernelObserver(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L192-L203

NewDefaultSession(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/__init__.py#L229

RegsiterSession(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/multi_client_session.py#L39)?創(chuàng)建 Session,并注冊為 default session(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/session_util.cpp#L89

創(chuàng)建 Python MultiClientSession 并保存到dict(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/session_context.py#L40),但并不 TryInit

創(chuàng)建 C++ MultiClientSessionContext(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/multi_client_session.py#L41)?但并不 TryInit

EnvGlobalObjectsScope::Init中先創(chuàng)建一個全局的ProcessCtx(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L132)對象。然后根據環(huán)境變量等配置,在各個進程間創(chuàng)建gRPC和CommNet的連接,分別負責控制面和數據面的數據傳輸。其中在Bootstrap過程中會初始化全局的ProcessCtx(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/rpc/lib/grpc.cpp#L42),給每個進程分配一個全局唯一的rank編號(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/rpc/lib/global_process_ctx.cpp#L28)(machine_id(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/rpc/lib/global_process_ctx.cpp#L24))。

本文不涉及網絡層面的操作,只討論同一進程內各線程間的交互。

3?

Module類

雖然可以直接用op和tensor構造模型,但是op的粒度太細了,直接用op構造模型會比較繁瑣。

Module(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/module.py#L54)是由op和tensor構成的、可復用的子模塊。利用Module可以更高效、更快捷的構建復雜模型。oneflow.nn(https://github.com/Oneflow-Inc/oneflow/blob/d825243aa7aff5cba8bd3a901b4cc56c2b1a36af/python/oneflow/nn/__init__.py)模塊導出了很多預定義的Module。

Module定義了自己的屬性設置邏輯(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/module.py#L262),核心邏輯是

如果value是Parameter類型,就保存到Module._parameters中

如果value是Module類型,就保存到Module._modules中

如果value是Tensor類型,就保存到Module._buffers中

否則按常規(guī)屬性處理

Module可以包含子Module,形成樹結構。因為Module通過setattr將子Module和Parameter都保存到字典結構中,可以方便的遍歷所有Module及其參數tensor。

4?

Graph類

4.1 構造函數

Graph的構造函數中GetDefaultSession(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L145)得到的session,就是導入oneflow包時NewDefaultSession(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/__init__.py#L229)構建的session。當時沒有初始化,而是在Graph構造時進行初始化(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L147)。對應的C++函數是MultiClientSessionContext::TryInit(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/multi_client_session_context.cpp#L67),執(zhí)行時會創(chuàng)建各種全局的資源管理器,比如: ?

LazyJobBuildAndInferCtxMgr

BufferMgr

RegstMgr

ActorMsgBus

ThreadMgr

4.2?__setattr__: 將Module和Tensor封裝為Block

Graph.__setattr__ 支持通過設置屬性的方式把一個 Module 添加到 Graph 中,之后改 Module 就可以被 Graph 調用了。添加到 Graph 中的 Module,會被包裝到 Block 里面,Block 起到了代理執(zhí)行的作用,它會給原 Eager 下的 Module 擴展出靜態(tài)執(zhí)行需要的一些特殊功能。

添加到 Graph 中的 Module 和原 Module 共享了狀態(tài)(Parameter、Buffer)和 forward 執(zhí)行邏輯。共享 forward 執(zhí)行邏輯使得靜態(tài)和動態(tài)執(zhí)行計算邏輯相同。共享狀態(tài)則可以使動態(tài)圖下的模型狀態(tài)被靜態(tài)圖復用。基于此,兩個 Graph,一個用于訓練,一個用于預測,他們都復用統(tǒng)一模型 Module,這樣訓練和預測 Graph 也就實現(xiàn)了模型共享。

setattr最重要的動作就是對_add_block的調用(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L1332),_add_block中主要是調用get_block_cls并保存結果(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L1326)。get_block_cls(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L39)的作用是將Module及其所有Tensor屬性都轉為對應的Block對象。為什么要做這個動作呢?主要是靜態(tài)圖編譯需要借助Block類型來實現(xiàn)代理執(zhí)行的功能,這些功能不適合直接寫到 eager 下的 Module 和 Tensor 上。

這個轉換是在ModuleBlock構造時調用set_origin(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L131)完成的。對于子Module,會遞歸調用get_block_cls函數(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L145),這樣所有子Module及其Tensor屬性都會被轉換為對應的Block對象。

所以,上述示例代碼中,GraphMyLinear實際存儲的是ModuleBlock,Graph.build執(zhí)行時獲取的model屬性也是ModuleBlock對象,ModuleBlock.origin才是ModuleMyLinear。

Graph.__setattr__不允許將Tensor對象設置為屬性(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L1340)。Tensor只能存到Module中,因為 Module 是做狀態(tài)共享的基本單位,而 Graph 是不允許復用的。

4.3 針對不同任務,定義不同的計算圖

根據Oneflow Model Zoo的模型示例(https://github.com/Oneflow-Inc/models/blob/1b291f78d8f60e5f04ee0c5962e4611cc4bab40a/Vision/classification/image/alexnet/graph/train.py),train/eval等階段可以創(chuàng)建不同的Graph子類。動態(tài)圖下提供了 Module、Optimizer、Dataloader等模塊,這些模型都可以被添加到 Graph 中。不同的組合可以構建不同類型的任務。

在這些不同階段,Graph構造函數的行為、build函數的輸入輸出都有各自特點。了解這些,看后續(xù)代碼時會更容易理解各個參數的具體含義。

構造函數

train階段,需要添加Module、損失函數、優(yōu)化器和dataloader

eval階段,只需要添加Module和dataloader

build函數

train

導入樣本和label

調用Module得到前向計算結果

計算損失

計算梯度

返回loss

eval

導入樣本和label

調用Module得到預估結果

返回預估結果和label

4.4 小結

上述幾個類型的關系如下:

下面描述了GraphMyLinear的構造流程

* `__init__` * `Graph.__init__` * self.model = linear_model * `Graph.__setattr__` * _add_block * get_block_cls: 遞歸地把Module轉為ModuleBlock * `ModuleBlock.__init__` * ModuleBlock.set_origin * `ModuleBlock._origin = origin` (Module) * 對origin的sub modules, parameters, buffers遞歸調用get_block_cls * `ModuleBlock.__setattr__`

5?

邏輯圖的編譯

計算機語言的編譯,是將高級語言的語句編譯為匯編或機器指令。深度學習框架對計算任務的編譯,是將用戶的特定語句操作轉換為DAG圖。oneflow中用Job(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job.proto#L30)描述邏輯的計算圖。

不同于eager模式的動態(tài)圖,靜態(tài)圖在開始執(zhí)行前可以得到整個計算任務的所有信息,可以對DAG進行多輪優(yōu)化。每輪優(yōu)化都是輸入一個Job、得到一個新Job。

最后,根據分布式環(huán)境配置,將邏輯圖Job轉換為物理執(zhí)行的計算圖Plan(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/plan.proto#L34)。在物理圖中,一個op可能分布在多個節(jié)點/進程。

啟動DAG計算需要調用Graph.__call__,這個函數的執(zhí)行主要分以下幾個步驟:

__call__

_compile(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L221)?if not _is_compiled

build_graph(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L741

__build_graph(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L759

finish_complie_and_init_runtime(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L742

__run(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L226

邏輯圖編譯主要在__build_graph中進行。finish_complie_and_init_runtime會繼續(xù)做一些優(yōu)化pass,然后構建物理圖、初始化運行時Actor系統(tǒng)。__run會啟動一次DAG的運算。

5.1 graph_build_context: 為邏輯圖編譯設置基本環(huán)境

在 Graph 中,build 函數里面的代碼執(zhí)行都在 graph_build_context 的作用域下,這樣實現(xiàn)了動態(tài)轉靜態(tài)的功能。

__build_graph中的graph_build_context(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L851)雖然只有一行代碼,但卻做了幾件非常重要的事情。

首先在context作用域內設置全局的lazy_mode為True(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L46)。在這個context作用域內,所有op都由LazyInterpreter解釋執(zhí)行。

其次,在JobBuildAndInferCtx(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L47)作用域內,JobBuildAndInferCtx_Open(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L57)調用類似如下C++代碼

// oneflow/api/python/job_build/job_build_and_infer.h// oneflow/core/job/job_build_and_infer_ctx_mgr.cpp// 如前所述,LazyJobBuildAndInferCtxMgr 在 MultiClientSessionContext::TryInit 執(zhí)行時初始化。// LazyJobBuildAndInferCtxMgr mgr;mgr.OpenJobBuildAndInferCtx(job_name);

OpenJobBuildAndInferCtx會新建一個Job對象(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job_build_and_infer_ctx_mgr.cpp#L32)、一個LazyJobBuildAndInferCtx對象(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job_build_and_infer_ctx_mgr.cpp#L34)。LazyJobBuildAndInferCtx負責根據用戶定制的op等操作,修改Job,其中最主要的功能是添加新 Op。

5.2 __build_io:為計算圖添加input和output Op

self.__build_io("input",?graph_build_util.build_graph_input_arg,?*args,?**kwargs)

上面這行代碼(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L854-L856)的作用是,對于用戶傳遞給graph_mylinear(input)的input參數,針對其中的每個tensor都在邏輯計算圖中插入一個FeedInputOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/system_ops.h#L48)節(jié)點。也就是說,model的輸入(比如樣本tensor,具體參考4.3節(jié)),在靜態(tài)圖中也視為一個op操作。

__build_io內會用args(即input)和kwargs構造一個ArgsTree。ArgsTree 把 Python 下的輸入、輸出抽象成了一個樹,輸入、輸出可以是嵌套的 Tuple、List、Dict,元素是 Tensor,嵌套的結構剛好可以表示為樹,而 Tensor 是樹中的葉子節(jié)點。示例代碼中kwargs是空的。

遍歷ArgsTree,對args和kwargs的每個tensor都調用傳入的build_func,對于input來說,就是build_graph_input_arg(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L206)。后面會看到,model的output也會調用__build_io,所以這個函數名的意思應該就是對model的輸入、輸出進行靜態(tài)圖的構圖工作。

build_graph_input_arg內部會構造一個FeedInputOpExpr(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L213),提交給解釋器執(zhí)行。因為是在lazy作用域內,由LazyInterpreter解釋執(zhí)行(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L471),LazyInterpreter會將對應的op插入靜態(tài)圖。

附:build input時ArgsTree的內部結構

__build_io(input)?中 ArgsTree 的內部數據組織示意

_named_io_args: NamedArg

_value: tuple

[0]: NamedArg

_value: tuple of NamedArg

[0]: NamedArg

_value: args tensor from?Graph.__call__

[1]: NamedArg

_value: empty kwargs from?Graph.__call__

通過pdb命令可以查看變量:?p args_tree._named_io_args._value[0]._value[0]._value.to_numpy()

5.2.1 將op添加到邏輯圖

LazyInterpreter::ApplyImpl(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L471)在執(zhí)行時,GetCurInferCtx()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L500)返回的就是graph_build_context中OpenJobBuildAndInferCtx(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L57)創(chuàng)建的那個LazyJobBuildAndInferCtx對象,這個對象負責邏輯圖的構建。添加op的主要調用流程如下:

infer_ctx->AddAndInferConsistentOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L503

AddAndInferOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job_build_and_infer_ctx.cpp#L563

ConstructOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job_build_and_infer_ctx.cpp#L580

CheckAndConstructOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/operator/operator.cpp#L1216

NewObj(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/operator/operator.cpp#L51

OperatorConf中,多種op配置共享op_type字段(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/operator/op_conf.proto#L412),protobuf oneof的op_type_case常量作為注冊NewObj的key。

系統(tǒng)預定義的op在oneflow/core/operator(https://github.com/Oneflow-Inc/oneflow/tree/release/v0.8.0/oneflow/core/operator)下,例如UserOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/operator/user_op.h#L24)。

AddAndInferOp將返回的Operator保存到LazyJobBuildAndInferCtx的字典中。后續(xù)的函數調用,主要是進行推導并修改靜態(tài)圖Job,使得各個節(jié)點構成一個DAG。

JobBuildAndInferCtx相關的類關系如下:

5.2.2 lazy tensor 和 eager tensor 的區(qū)別

LazyInterpreter::ApplyImpl的最后,會調用BuildTensor(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L518)構造一個lazy tensor,作為build_graph_input_arg的返回值(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L216)。所以__build_io返回的lazy_args(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L854)是lazy tensor,它將替代eager的args(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L828)(也就是用戶輸入的input)參與后續(xù)的計算圖構建。

那么lazy tensor和eager tensor的區(qū)別是什么呢?eager tensor是要即時計算的,所以需要真實數據;而lazy tensor僅在靜態(tài)圖編譯階段用于推導,只需要描述性質的元信息。靜態(tài)圖編譯是在lazy模式下運行,只是使用lazy tensor 做計算機構圖和校驗。

后面會看到,靜態(tài)圖的運行期已經沒有tensor的概念。運行期看到的只是更廣義的Regst存儲,可能代表tensor/blob,也可能是其它控制信息。靜態(tài)圖運行時的輸入,是直接讀取外部 eager tensor的內存數據到到regst;輸出應該是op寫到regst,通過blob構造eager tensor。

5.3 build: 將UserOp和FeedVariableOp添加到邏輯圖

__build_graph中的self.build()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L861)會調用GraphMyLinear.build(),以及ModuleMyLinear.forward()。因為是在lazy模式下運行,matmul和add都會調用UserOpExpr重載版本的LazyInterpreter::ApplyImpl(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L832),進而調用AddAndInferConsistentOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L940)進行構圖操作。

需要說明的是,在引用Module的Parameter屬性時(如weight/bias),會觸發(fā)FeedVariableOp的構圖操作(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L226)、調用對應版本的LazyInterpreter::ApplyImpl(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L527)。這個是怎么執(zhí)行的呢?

__build_graph中,在進入lazy模式之前,先調用了_create_states_builder(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L843)。其中self._state()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L667)返回所有Module的所有Parameter(包括子Module)。

state_block的類型是TensorBlock(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L631)。所有的state_block的lazy_origin_builder().method(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L647)都被設置為調用build_graph_state(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L683-L688)。

給build_graph_state(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L220)設置個斷點能讓整個調用過程顯形,主要的調用棧如下:

-> out = graph_mylinear(input) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/graph.py(221)__call__()-> self._compile(*args, **kwargs) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/graph.py(741)_compile()-> _, eager_outputs = self.build_graph(*args, **kwargs) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/graph.py(759)build_graph()-> outputs = self.__build_graph(*args, **kwargs) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/graph.py(864)__build_graph()-> outputs = self.build(*lazy_args, **lazy_kwargs) /mnt/project/machine-learning/oneflow/oneflow/test.py(21)build()-> return self.model(input) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(234)__call__()-> result = self.__block_forward(*args, **kwargs) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(266)__block_forward()-> result = self._origin.__class__.forward(self, *args, **kwargs) /mnt/project/machine-learning/oneflow/oneflow/test.py(11)forward()-> return flow.matmul(input, self.weight) + self.bias /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(483)__getattr__()-> p_state = self._get_from_states(name, "_parameters") /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(521)_get_from_states()-> _s_block.try_build() /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(679)try_build()-> self._lazy_origin_builder.try_build(self) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(627)try_build()-> self.result = self.method()> /usr/local/lib64/python3.6/site-packages/oneflow/framework/graph_build_util.py(227)build_graph_state()-> op_name, var_conf_str, ["in_0"], ["out_0"]

這個調用過程比較容易困擾的是,執(zhí)行對象會在Grpah、GraphMyLinear、ModuleMyLinear、ModuleBlock之間切換。

前面在討論Graph的構造時已經提過,執(zhí)行self.model(input)時,Graph.__getattr__返回的屬性model是ModuleBlock對象,所以實際調用的是ModuleBlock.__call__。

在這個函數內調用__block_forward(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L234),其中的_origin(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L266)是ModuleMyLinear,進入到它的forward方法,執(zhí)行到flow.matmul(input, self.weight) + self.bias時,matmul 會被LazyOpInterpreter 所執(zhí)行,在 LazyOpInterpreter 中調用 AddAndInferConsistentOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L503

,在 Job 中添加一個 matmul operator。同理后面的加法會在 job 中添加一個 add operator。

self.weight 和 self.bias 會觸發(fā)調用ModuleBlock.__getattr__,進而調用_get_from_states(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L483),調用TensorBlock.try_build()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L521)。這里執(zhí)行的就是進入lazy模式之前設置的build_graph_state(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L220)。從而增加一個FeedVariableOp到計算圖(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L527)。為什么設置和調用會距離這么遠呢?主要是為了讓參數盡量和消費參數的 Operator 在一個作用域下,所以實現(xiàn)成了惰性求值來達到延遲計算的目的。

再后面的步驟就是調用__build_io(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L869-L875)插入FetchOutputOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L589)。也就是說,獲取model的output也是一個op。

到目前為止,前向計算圖就構建完成了。它的json表示可以參考附錄。net.op是計算圖的節(jié)點,通過input等屬性可以看出節(jié)點之間的連接關系。

示例代碼的前向計算圖如下。從這個圖可以看到,input、output、weights等都是op。

5.4 邏輯圖優(yōu)化

在__build_graph中會調用CurJobBuildAndInferCtx_Complete對靜態(tài)圖進行多輪優(yōu)化(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L923),對應的C++函數是LazyJobBuildAndInferCtx::Complete()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job_build_and_infer_ctx.cpp#L975)。

這之后生成的Job是full_job。本文的示例代碼比較簡單,并不是典型的計算場景,其forwar和ful計算圖的拓撲是一樣的。實際大部的圖優(yōu)化都實現(xiàn)在這個階段,如 Op fusion、AMP、ZeRO、常量折疊等等。

到這里,邏輯圖構建的主體部分就結束了。

隨后會構建一個CNNGraph對象(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L947),對應的C++類型是NNGraph(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.h#L33)。這個對象將負責構建物理計算圖Plan。它也是整個運行時的擁有者和維護者。這個對象析構時,整個運行時也會有序終止并釋放資源。

5.5 物理圖的編譯

接下來就是執(zhí)行finish_complie_and_init_runtime(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L742),其中的核心調用是self._c_nn_graph.complie_and_init_runtime()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L802),對應的C++函數是NNGraph::CompileAndInitRuntime(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L265)。

在這個函數中,JobCompleter().Complete()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L280)會繼續(xù)對邏輯圖做幾輪修改優(yōu)化,補全 Runtime 執(zhí)行所需要的附加信息,Compiler().Compile()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L285)將邏輯圖轉為分設備的物理圖,并繼續(xù)對Plan進行修改優(yōu)化。

Plan的編譯是在master節(jié)點進行的(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L282)。master節(jié)點會將Plan通過gRPC推送給各個worker節(jié)點(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L308),worker節(jié)點從master拉取物理計算圖(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L310)。

之后調用NewRuntimeBuffers創(chuàng)建Buffer對象(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L322),Buffer應該是主要用于進程內的信息同步。

然后就準備初始化運行時了。

示例代碼生成的compiled_job和物理圖Plan的json參見附錄。

最終生成的compiled邏輯圖如下??蚣茏詣硬迦肓撕芏嘞到y(tǒng)控制節(jié)點。

5.6 Plan的結構

示例代碼輸出的Plan json數據見附錄。

Plan在邏輯上和compiled_job是等價的。這里主要關注task/op之間的關系。

Plan.task中的每個元素是一個task,其中的exec_sequence.exec_node對應job中的op,通常只有一個op(數組可以支持sub graph)。

exec_node.kernel_conf.op_attribute描述了op信息。其中op_conf包含op name信息。

kernel_conf.op_attribute.op_conf就是Job中的OperatorConf。

kernel_conf.op_attribute.arg_signature.bn_in_op2lbi體現(xiàn)了task/op之間的連接關系。

bn_in_op就是blob name in op,即op輸入的blob name。

以System-AutoTick-DstSubsetTick_21為例

{ "out": { "op_name": "System-AutoTick-DstSubsetTick_21", "blob_name": "out" }, "in_0": { "op_name": "System-EagerCriticalSection-Interface-End-Tick-19", "blob_name": "out" }, "in_1": { "op_name": "System-AutoTick-SrcSubsetTick_20", "blob_name": "out" }}

exec_node.bn_in_op2regst_desc_id在task層面體現(xiàn)了連接關系。這個map中的key表示輸入輸出,value是register id。

{"out": "29","in_0": "27","in_1": "28"}

task.produced_regst_desc描述了對應task生產的register,consumer_task_id是消費者,

produced_regst_desc.out.regst_desc_type.data_regst_desc.lbi2blob_desc.lbi就是這個register的logic blob id。

task.consumed_regst_desc_id描述了對應task消費的register信息

6?

運行時的初始化

NNGraph::CompileAndInitRuntime中,new Runtime這行代碼會初始化運行時(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L331)。主要做的事情包括:

創(chuàng)建Thread

通知Thread創(chuàng)建Actor,Actor會創(chuàng)建Regst和Kernel

給沒有輸入的source_tasks發(fā)送啟動信號kStart

6.1 Runtime創(chuàng)建Thread

在Runtime的構造函數中,DumpThreadIdsFromPlan(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L65)會將Plan中屬于當前進程的task的thread id存入thread_ids_變量。AddThreads創(chuàng)建這些Thread對象(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L69)。

Thread在構造時會創(chuàng)建一個物理線程(?https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/thread/thread.cpp#L39),線程執(zhí)行的是PollMsgChannel方法(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/thread/thread.cpp#L44),Thread就是在這里持續(xù)等待需要處理的新消息。

Thread只處理兩類命令消息:線程終止消息,創(chuàng)建Actor的消息。其它消息交給Actor::ProcessMsg處理(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/thread/thread.cpp#L83)。

6.2 Runtime通知Thread創(chuàng)建Actor

在Runtime的構造函數中,tasks被分為兩類:source_tasks和other_tasks。在示例代碼中,source_tasks(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L84-L85)是沒有輸入邊的task。

從代碼邏輯看,在Plan proto中,task的consumed_regst_desc_id字段是一個map。如果這個map的所有key都是in_ctrl(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L54),這個task就是source_tasks。

一些source_tasks的示例如下:

System-Src-WaitAndSendIds_16

System-AutoTick-AppendDeviceTick_9

System-EagerCriticalSection-Interface-End-Tick-19

System-EagerCriticalSection-Interface-End-Tick-25

Runtime調用HandoutTasks函數(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L100-L101)會給ActorMsgBus發(fā)送構建Actor的kConstructActor消息(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L49)。

6.3 ActorMsgBus和Thread的消息處理

從接口看,ActorMsgBus?(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor_message_bus.cpp#L24)負責消息的發(fā)送(Actor通過ActorMsgBus發(fā)送消息),Thread::PollMsgChannel(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/thread/thread.cpp#L60) 負責消息的接收和處理。

相關實體的協(xié)作關系如下

Actor是自調度的基本單元,接受消息然后工作,工作完后再繼續(xù)發(fā)送消息。

actor_id就是task_id,是在編譯Plan時就確定的。task是編譯時概念,actor是對等的運行時概念。

task_id有特定的編碼格式(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/graph/task_id.cpp#L21-L29),從中可以解析出machine_id(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/graph/task_id.cpp#L73)和thread_id(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/graph/task_id.cpp#L77)。

在跨網絡的整個物理圖Plan中,actor id相當于地址,通過它可以定位唯一的actor實體。

Actor 通過 ActorMsgBus::SendMsg(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor_message_bus.cpp#L24) 發(fā)送 ActorMsg(https://github.com/Oneflow-Inc/oneflow/blob/4856d691051accd72f13f4139d281e411977b297/oneflow/core/lazy/actor/actor_message.h#L34) 消息。

ActorMsg包含源和目的actor id(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor_message.h#L84-L85)。

如果是進程內通訊(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor_message_bus.cpp#L26),將通過 ActorMsgBus::SendMsgWithoutCommNet?(https://github.com/Oneflow-Inc/oneflow/blob/4856d691051accd72f13f4139d281e411977b297/oneflow/core/lazy/actor/actor_message_bus.cpp#L49)把 ActorMsg 朝目的 actor 所在的 thread 入隊消息(https://github.com/Oneflow-Inc/oneflow/blob/4856d691051accd72f13f4139d281e411977b297/oneflow/core/thread/thread.h#L40)。

Thread::EnqueueActorMsg 會判斷當前 thread 是否是 actor thread,如果是則入本地隊列,否則則入 actor thead 的 channel 隊列。

如果ActorMsg是跨進程消息,ActorMsgBus通過CommNet發(fā)送消息(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor_message_bus.cpp#L42-L44),接收方的CommNet應該會根據actor id獲得線程id,從ThreadMgr查到Thread,將消息交給Thread處理。

Thread::PollMsgChannel(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/thread/thread.cpp#L60) 負責消息的接收和處理。

如果線程本地隊列l(wèi)ocal_msg_queue_為空,則從thread的channel隊列中取出全部ActorMsg放入本地隊列(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/thread/thread.cpp#L63)。

從本地隊列中取出一個ActorMsg,然后開始處理。

處理一些特殊的kCmdMsg消息(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/thread/thread.cpp#L67-L79),然后普通消息交給Actor自行處理(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/thread/thread.cpp#L83)。

Actor收到消息后,會判斷是否滿足了Act的條件,如果滿足,則會執(zhí)行Act,從而調用LaunchKernel執(zhí)行計算,Act執(zhí)行結束后通過ActorMsgBus發(fā)消息通知上下游Actor。

這些對象之間的消息傳遞關系如下圖所示

6.4 激活source Actor

目前的實現(xiàn)中,Actor全部是自調度的,只能接受來自其他Actor的消息。Actor中有一類比較特殊的source actors,它們與source tasks對應。

source actors 沒有上游 actor,它們會朝下游actor發(fā)送消息從而激活所有的Actor運行。

source actors 本身是如何執(zhí)行的呢?它們在接受到 kStart 消息后就會一直 Act 直到進入退出流程。但是其 kernel 會阻塞在 Buffer(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/common/buffer.h#L26) 處,一直等待其他線程往 buffer 中添加數據后,阻塞會被激活,然后 kernel 執(zhí)行讀取,kernel 完成后,actor 的 Act 結束,往下游發(fā)送消息。

source actors 由于會發(fā)生阻塞,所以其必須有單獨的 actor thread。

Runtime 初始化的的最后一步就是朝各 source actors 發(fā)送 kStart 消息用以激活它們,但 source actors 只有接受到 buffer 的數據后才會往下執(zhí)行,然后朝下游 actors 發(fā)送消息,使所有的 actors 都執(zhí)行起來。

7?

Actor

7.1 Actor的創(chuàng)建

Thread在創(chuàng)建Actor時,會先嘗試創(chuàng)建為LightActor(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L104),如果不成功,再嘗試用預先注冊的工廠創(chuàng)建Actor。

有幾種TaskType可以用于LightActor(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/light_actor.cpp#L677-L689):

kNormalForward,比如matmul、add等user op。

kCopyHd

kTick

kCollectiveBoxingGeneric

目前大約有20多種Actor的子類型。其它Actor類型根據TaskType(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/task.proto#L8)預先注冊。例如WaitAndSendIdsActor。

示例代碼的各個節(jié)點對應的actor類型參見附錄。

Actor相關的類關系如下(包含關系只是表示可以訪問到相關信息,并不意味著創(chuàng)建或著擁有該類型對象)

7.2 Actor的初始化

Actor的構造函數一般都是空的,構建之后需要執(zhí)行Init(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L129)函數進行初始化。

LightActor繼承自ActorBase,不是Actor的子類,有自己的Init函數實現(xiàn)。這里只討論Actor的初始化。

在Actor::Init(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L129)中,首先調用ConstructKernel(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L138)創(chuàng)建kernel實例。和Operator類似,kernel也是以OpTypeCase作為注冊的key,例如WaitAndSendIdsKernel(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/kernel/wait_and_send_ids_kernel.cpp#L51)。一個Actor通常只有一個kernel。

之后調用NewRegsts創(chuàng)建Regst(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L152)。Tensor是用戶側的概念。對應的運行時概念是Regst(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/register/register.h#L24),它持有Kernel需要讀寫的內存。Regst的概念比Tensor更寬泛,比如框架自動添加的控制Op也會用到Regst。

Actor將自己創(chuàng)建的Regst保存到produced_regsts_(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L153)。

TakeOverNaiveConsumed(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L182)只記錄需要消費的regst id,但并不push到consumed_regsts_。

TakeOverNaiveProduced(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L183)既記錄生產的regst id,也push到naive_produced_rs_(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L249)。這種區(qū)別是為了首次執(zhí)行計算時,actor能順利執(zhí)行。后面分析Actor的消息處理時會再回過頭來討論一下。

調用InitBnInOp2BlobInfo會初始化BlobInfo(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L184)。

之后就是調用VirtualActorInit(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L185),這里允許各個Actor子類定制自己的初始化邏輯。通常會調用OF_SET_MSG_HANDLER宏(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.h#L76-L80)設置Actor的消息處理函數。

7.3 Actor的消息處理

LightActor 首先會根據消息類型分別處理 kRegstMsg 和 kEordMsg 消息。HandleRegstMsg(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/lazy/actor/light_actor.cpp#L424) 中根據 RegstMsg 的 type (kProduced 或 kComsumed) 來分別處理各種讀寫狀態(tài)計數。

然后判斷讀寫計數是否達到了判斷條件,如果達到了意味著滿足了讀寫 regst 的條件,然后就 執(zhí)行 ActOnce(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/lazy/actor/light_actor.cpp#L451)。

LightActor::ActOnce 會在第一次執(zhí)行時去 InitBnInOp2Blob 和 InitActMsg。InitBnInOp2Blob 初始化 resgt 中的 bn 與 Blob 的映射關系,為 kernel 提供通過 bn 訪問 Blob 的功能。InitActMsg 會初始化好所有需要發(fā)送的消息避免后繼發(fā)消息時重復的構建消息。

然后就是 LaunchKernel,接著會 ResetState 重置 regst 狀態(tài)。

LaunchKernel 后就會把之前構建好的消息發(fā)送出去,同步消息會直接入隊 thread 消息隊列,異步消息通過 callback 發(fā)送到 ActorMsgBus。

普通 Actor::ProcessMsg 會調用 msg handler 來處理消息,最常見的 msg handler 就是 Actor::HandlerNormal(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/lazy/actor/actor.cpp#L329)。

Actor::HandlerNormal 中流程跟 LightActor 中類似,會根據不同的 regst 類型來分別處理,Actor 中對 regst 的狀態(tài)管理方式與 LightActor 不同,LightActor 中的方式更加高效,Actor 中能處理一些特殊情況。

消息處理完畢后,就會調用 ActUntilFail,ActUntilFail 會判斷 IsReadReady 和 IsWriteReady 來決定是否可以進行 Act。

最常見的 NaiveActor::Act() 就是執(zhí)行 AsyncLaunchKernel。

Act 完成后,就開始朝上下游發(fā)送 regst 消息。

還有一些特殊的 Actor,我們以WaitAndSendIdsActor為例,觀察一下這類Actor的消息處理機制。

之所以選擇這個例子,一是這個Actor比較簡單;二是這是一個典型的source task,想看一下計算圖是怎么被觸發(fā)啟動計算的。

Thread收到的消息如果不是kStopThread或kConstructActor,就調用Actor::ProcessMsg(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L83),將消息轉給Actor處理。

ProcessMsg函數只是簡單的將消息轉給handler處理(https://github.com/Oneflow-Inc/oneflow/blob/b6bf3f8843679111eb1edf79deefce814d250f4e/oneflow/core/lazy/actor/actor.h#L38)。

WaitAndSendIdsActor::VirtualActorInit中,handler被設置為HandlerWaitToStart(https://github.com/Oneflow-Inc/oneflow/blob/22f70a1719f371a54512633bb92086580d9c3c89/oneflow/core/lazy/actor/wait_and_send_ids_actor.cpp#L53)。

Runtime的構造函數中,發(fā)送的第一批消息是給source_tasks的kStart消息,這個消息就由HandlerWaitToStart函數處理。

HandlerWaitToStart校驗消息類型后,將handler設置為HandlerNormal(https://github.com/Oneflow-Inc/oneflow/blob/b17a9cd6b930b5817c63623fb682bd708377a93b/oneflow/core/job/runtime.cpp#L109)(這也是大部分Actor的默認handler),然后調用ProcessMsg(https://github.com/Oneflow-Inc/oneflow/blob/22f70a1719f371a54512633bb92086580d9c3c89/oneflow/core/lazy/actor/wait_and_send_ids_actor.cpp#L74),實際就是調用新設置的handler HandlerNormal。

HandlerNormal中,如果是kCmdMsg,只允許是kStart(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L377)。通過消息類型校驗后,會直接調用ActUntilFail(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L378)。

7.4 Act執(zhí)行的條件

LightActor 和 Actor 判斷能否進行 Act 采用了不同的策略,LightActor 的效率更高,Actor 能處理一些特殊情況。

對于 LightActor,當在讀的register計數 total_reading_cnt_ 歸 0,可消費的register計數 ready_consumed_ 增加到 max_ready_consumed_,前者表示所有的消費者已經讀取當前 LightActor 的 Regst,后者表示當前 LightActor 消費的所有 Regst 已經到達(由上游發(fā)送的 Regst 消息)。

對于 Actor,Actor::ActUntilFail中,Act方法(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L424)是各個子類自己實現(xiàn)的,一般主要是啟動kernel計算。

但是在執(zhí)行Act之前,需要先確認:

Act執(zhí)行依賴的數據是否都已經就緒?(IsReadReady)

Act生產出來的數據,消費方是否已經用完、并收到ack消息確認?(IsWriteReady)

Actor有4個與此相關的成員變量

RegstSlot naive_produced_rs_;

RegstSlot inplace_produced_rs_;

RegstSlot naive_consumed_rs_;

RegstSlot inplace_consumed_rs_;

xx_produced_rs_存儲的是當前Actor的下游consumer返回的、已經使用完畢的ack regst信息。(當前Actor生產的Regst存儲在produced_regsts_中。)

運行時在初始化的過程中,所有Actor都沒有運行過,任何Actor都不可能收到ack消息,所以在Actor初始化時,要預先填充xx_produced_rs_,這樣才能保證Actor在首次運行前是WriteReady的,才能順利啟動執(zhí)行。

xx_consumed_rs_存儲的是上游依賴發(fā)來的數據。它不需要預先填充。因為source_tasks沒有輸入依賴,自然就是ReadReady的;而xx_produced_rs_在初始化時的預先填充又保證它是WriteReady的,所以source_tasks可以直接運行。source_tasks的輸出消息發(fā)給下游,下游也會變?yōu)镽eadReady,而下游在初始化后也保證是WriteReady的。整個Actor系統(tǒng)就可以這樣運轉起來了。

7.5 Actor上下游之間的通知機制

Act執(zhí)行完畢后,需要將結果數據發(fā)給下游consumer。以 WaitAndSendIds 的 Naive Produced 為例,ActUntilFail中的調用流程如下:

AsyncSendNaiveProducedRegstMsgToConsumer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L427

VirtualAsyncSendNaiveProducedRegstMsgToConsumer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L441

HandleProducedNaiveDataRegstToConsumer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L446

HandleRegstToConsumer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L577)

EnqueueAsyncMsg(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L523

如果目標線程是當前線程,ActorMsgBus::SendMsg(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L662

否則,將消息加入async_msg_queue_(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L664

增加 total_reading_cnt_(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L526)(這個變量表示已經發(fā)消息給下游、但未收到的ack數量)

naive_produced_rs_.PopFrontRegsts(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L581

AsyncSendProducedCtrlRegstMsgToConsumer

注意naive_produced_rs_.PopFrontRegsts(https://github.com/Oneflow-Inc/oneflow/blob/06a6af1c7f760ba4b12d2dfb8f73d7fda5c7dbab/oneflow/core/lazy/actor/register_slot.cpp#L53)會將Regst指針從隊列中刪掉,相應的可用(https://github.com/Oneflow-Inc/oneflow/blob/06a6af1c7f760ba4b12d2dfb8f73d7fda5c7dbab/oneflow/core/lazy/actor/register_slot.cpp#L49)register計數減1(https://github.com/Oneflow-Inc/oneflow/blob/06a6af1c7f760ba4b12d2dfb8f73d7fda5c7dbab/oneflow/core/lazy/actor/register_slot.cpp#L49)。

而在Actor::HandlerNormal中處理收到的kRegstMsg消息(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L340)時,如果是consumer發(fā)來的ack消息,會調用TryUpdtStateAsProducedRegst(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L355),將Regst再添加到 naive_produced_rs_ 中(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L654),以保證當前Actor在收到所有ack后是WriteReady的;同時遞減在讀的 register 計數total_reading_cnt_。

Actor對依賴的上游消息的處理是類似的。通過以下函數調用給上游發(fā)送ack消息、通知 register 已經用完,可以繼續(xù)更新了:

AsyncSendNaiveConsumedRegstMsgToProducer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L431

AsyncRetInplaceConsumedRegstIfNoConsumer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L432)在Actor::HandlerNormal中收到kRegstMsg消息后,將消息添加到consumed_rs_(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L344),以保證當前Actor在收到所有依賴數據后是ReadReady的。

LightActor有自己的消息處理機制(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/light_actor.cpp#L299),大致原理應該是差不多的。

7.6 Act執(zhí)行的動作

根據上述討論,Actor收到kRegstMsg后也會進入ActUntilFail執(zhí)行。如果讀寫都是Ready,就執(zhí)行Act(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L424)。以WaitAndSendIdsActor為例,主要調用鏈路如下:

AsyncLaunchKernel(https://github.com/Oneflow-Inc/oneflow/blob/22f70a1719f371a54512633bb92086580d9c3c89/oneflow/core/lazy/actor/wait_and_send_ids_actor.cpp#L58

ek.kernel->Launch(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L562),啟動Kernel計算

Forward(https://github.com/Oneflow-Inc/oneflow/blob/eae9ff38f074479d79ce24b0f6e0594f82126171/oneflow/core/kernel/kernel.cpp#L52

ForwardDataContent(https://github.com/Oneflow-Inc/oneflow/blob/eae9ff38f074479d79ce24b0f6e0594f82126171/oneflow/core/kernel/kernel.cpp#L65

buffer->Pull(https://github.com/Oneflow-Inc/oneflow/blob/b17a9cd6b930b5817c63623fb682bd708377a93b/oneflow/core/kernel/wait_and_send_ids_kernel.cpp#L40

給regst的存儲地址mut_dptr賦值(https://github.com/Oneflow-Inc/oneflow/blob/b17a9cd6b930b5817c63623fb682bd708377a93b/oneflow/core/kernel/wait_and_send_ids_kernel.cpp#L47

buffer->Pull會等待條件變量的通知(https://github.com/Oneflow-Inc/oneflow/blob/49f60e682518436dfeb37344a15902a959e0e4f2/oneflow/core/common/buffer.h#L60)?,F(xiàn)在,看上去所有Actor都已準備就緒,只等發(fā)令槍一響就開跑了。

8?

啟動靜態(tài)圖的計算

Graph.__run(https://github.com/Oneflow-Inc/oneflow/blob/81edd938826a7ea903174d682348847658b64653/python/oneflow/nn/graph/graph.py#L226)會扣動發(fā)令槍的板機,啟動計算圖的一輪計算。

主要調用流程如下:

RunLazyNNGraph(https://github.com/Oneflow-Inc/oneflow/blob/81edd938826a7ea903174d682348847658b64653/python/oneflow/nn/graph/graph.py#L1076

builder->LaunchLazyJob(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/nn_graph.cpp#L568

LaunchLazyJobInstructionType(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/instructions_builder.cpp#L179

Buffer::Push(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/instructions_builder.cpp#L179

這里的Buffer::Push就是WaitAndSendIdsKernel在等待的起跑信號。

9?

運行時的退出機制

整個運行時包含很多對象和資源,安全有序的退出是龐雜而又細致的工作。這里僅以WaitAndSendIds為例,從一個側面觀察一下運行時的退出機制。

運行時的退出始于NNGraph對象的析構(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/nn_graph.cpp#L76)。

9.1 Actor的退出

NNGraph在析構時,會關閉所有的Buffer對象(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/nn_graph.cpp#L82)。

Buffer在關閉時,會設置is_closed_ = true并通知所有監(jiān)聽者(https://github.com/Oneflow-Inc/oneflow/blob/49f60e682518436dfeb37344a15902a959e0e4f2/oneflow/core/common/buffer.h#L81)。但是Pull會繼續(xù)處理完已經提交的計算。

所以,Buffer應該是主要用于進程內的通信和異步協(xié)調的一個類。

WaitAndSendIdsKernel這時候正在等待新一輪計算開始(https://github.com/Oneflow-Inc/oneflow/blob/b17a9cd6b930b5817c63623fb682bd708377a93b/oneflow/core/kernel/wait_and_send_ids_kernel.cpp#L40),結果收到Pull返回的kBufferStatusErrorClosed(https://github.com/Oneflow-Inc/oneflow/blob/49f60e682518436dfeb37344a15902a959e0e4f2/oneflow/core/common/buffer.h#L61)。

WaitAndSendIdsActor::IsCustomizedReadReady以后就一直返回false(https://github.com/Oneflow-Inc/oneflow/blob/22f70a1719f371a54512633bb92086580d9c3c89/oneflow/core/lazy/actor/wait_and_send_ids_actor.cpp#L68),IsReadReady也返回false(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L533)。

這之后,ActUntilFail只會執(zhí)行異步消息發(fā)送(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L437)(不再進入while循環(huán))

WaitAndSendIdsActor::HandlerNormal仍然會處理其它Actor發(fā)來的消息(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L340)。但因為IsCustomizedReadReady返回false,會進入AsyncSendEORDMsgForAllProducedRegstDesc(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L394)執(zhí)行。它會給每個下游發(fā)送kEordMsg消息(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L614)。

Actor在收到上游發(fā)來的kEordMsg消息后,遞減remaining_eord_cnt_(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L331)。

remaining_eord_cnt_被初始化為Actor的輸入regst的數量(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L171)。

total_reading_cnt_是當前Actor生產的、已經發(fā)給consumer、但尚未收到ack的消息數量。

Actor目前仍可以正常接收consumer發(fā)來的ack消息。

當上述2個變量都為0時(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L395),意味著所有上游都發(fā)出了kEordMsg消息,也收到了所有下游的ack消息。Actor就給Thread返回1(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L397)。

如果上述兩個變量有不為0的,就修改handler,由HandlerZombie(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L399)處理后續(xù)收到的消息。

Thread收到Actor返回的1后(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L84),將它從自己的存儲中刪除(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L89),并遞減運行Actor的數量。

9.2 Thread的退出

NNGraph重置runtime_導致運行時對象被析構(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/nn_graph.cpp#L83)。

Runtime刪除所有Thread(https://github.com/Oneflow-Inc/oneflow/blob/b17a9cd6b930b5817c63623fb682bd708377a93b/oneflow/core/job/runtime.cpp#L117)。

ThreadMgr給所有Thread發(fā)送kStopThread消息(https://github.com/Oneflow-Inc/oneflow/blob/c8c6d351fa28c5ebce948d69c06670a783f83f74/oneflow/core/thread/thread_manager.cpp#L64)。同時,重置指針導致Thread析構(https://github.com/Oneflow-Inc/oneflow/blob/c8c6d351fa28c5ebce948d69c06670a783f83f74/oneflow/core/thread/thread_manager.cpp#L66)。

Thread的物理線程退出PollMsgChannel循環(huán)(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L68)。

Thread等待物理線程結束,關閉channel(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L52)。

10?

分布式場景的靜態(tài)圖

分布式的compile_job、物理圖Plan和單機場景有明顯變化。

比如,每個進程都有一套WaitAndSendIds等控制節(jié)點。這也容易理解,因為每個節(jié)點都要執(zhí)行__run和Buffer::Push/Pull,都要啟動本進程的Actors執(zhí)行計算。

matmul和broadcast_add等user op也會在兩個節(jié)點進行計算。 ?

10.1 示例代碼

啟動方式參考Global Tensor的官方文檔。

import oneflow as flowimport oneflow.nn as nnP0 = flow.placement("cpu", ranks=[0, 1])a0_sbp = flow.sbp.split(0)class ModuleMyLinear(nn.Module): def __init__(self, in_features, out_features): super().__init__() self.weight = nn.Parameter(flow.randn(in_features, out_features, placement=P0, sbp=flow.sbp.broadcast)) self.bias = nn.Parameter(flow.randn(1, out_features, placement=P0, sbp=flow.sbp.broadcast)) def forward(self, input): return flow.matmul(input, self.weight) + self.biaslinear_model = ModuleMyLinear(4, 3)class GraphMyLinear(nn.Graph): def __init__(self): super().__init__() # ModuleBlock self.model = linear_model def build(self, input): # ModuleBlock.__call__ return self.model(input)graph_mylinear = GraphMyLinear()input = flow.randn(5, 4, placement=P0, sbp=flow.sbp.split(1))out = graph_mylinear(input)print(out)

11?

附錄

11.1 斷點

11.1.1 Python斷點示例

# python3 -m pdb test.pybreak test.py:25break oneflow/nn/graph/graph.py:221break oneflow/nn/graph/graph.py:741break oneflow/nn/graph/graph.py:745break oneflow/nn/graph/graph.py:759break oneflow/nn/graph/graph.py:828break oneflow/nn/graph/graph.py:777break oneflow/nn/graph/graph.py:1066break oneflow/nn/graph/graph.py:1133break oneflow/framework/graph_build_util.py:227

11.1.2 C++斷點示例

啟動命令

source /mnt/oneflow/build/source.shgdb --args python3 /mnt/oneflow/test.py# set breakpoints# run

斷點示例

set breakpoint pending onbreak oneflow::ActorMsg::BuildEordMsgbreak oneflow/core/common/buffer.h:80break oneflow::(anonymous namespace)::CheckAndConstructOpbreak oneflow::WaitAndSendIdsActor::Actbreak oneflow::WaitAndSendIdsActor::HandlerWaitToStartbreak oneflow/core/lazy/actor/light_actor.cpp:452break oneflow/core/lazy/actor/light_actor.cpp:485break oneflow::ForeignInputKernel::ForwardDataContentbreak oneflow::vm::LaunchLazyJobInstructionType::Compute

11.2 靜態(tài)圖的json表示

forward(https://quip.com/OMc4A0HOOr0C)

full(https://quip.com/JLaMAHGBLXmK)

compiled(https://quip.com/tXjuAiS3J0Ab)

plan(https://quip.com/a0DMAAIte6PQ)

11.3 actor type

naive_actor

System-AutoTick-AppendDeviceTick_9System-AutoTick-DstSubsetTick_12System-AutoTick-DstSubsetTick_21System-AutoTick-DstSubsetTick_27System-AutoTick-Prepend-DeviceTick_7System-AutoTick-SrcSubsetTick_20System-AutoTick-SrcSubsetTick_26System-AutoTick-SrcSubsetTick_8System-AutoTick-Tick_11System-AutoTick-Tick_13System-EagerCriticalSection-Callback-23System-EagerCriticalSection-Callback-29System-EagerCriticalSection-Interface-Begin-Tick-18System-EagerCriticalSection-Interface-Begin-Tick-24System-EagerCriticalSection-Interface-End-Tick-19System-EagerCriticalSection-Interface-End-Tick-25System-EagerCriticalSection-Wait-22System-EagerCriticalSection-Wait-28

light_actor

_GraphMyLinear_0_input.0.0_2_GraphMyLinear_0_output.0.0_2model.biasmodel-broadcast_add-1model-matmul-0model.weightSystem-AutoTick-SinkTick_15System-SyncAllRanksSinkTick_14

wait_and_send_ids_actor

???System-Src-WaitAndSendIds_16

call_back_notify_actor

???System-Sink-CallbackNotify_17

12?

參考資料

oneflow v0.8.0(https://github.com/Oneflow-Inc/oneflow/tree/release/v0.8.0)

OneFlow框架的系統(tǒng)設計(上篇)(https://zhuanlan.zhihu.com/p/337851255)

OneFlow框架的系統(tǒng)設計(中篇)(https://zhuanlan.zhihu.com/p/338699487)

OneFlow框架的系統(tǒng)設計(下篇)(https://zhuanlan.zhihu.com/p/339208452)

一個Job在OneFlow中的執(zhí)行過程—上篇(https://zhuanlan.zhihu.com/p/344531540)

一個Job在OneFlow中的執(zhí)行過程—中篇(https://zhuanlan.zhihu.com/p/355654002)

一個Job在OneFlow中的執(zhí)行過程—下篇(https://zhuanlan.zhihu.com/p/363689736)

靜態(tài)圖模塊 nn.Graph(https://docs.oneflow.org/master/basics/08_nn_graph.html)

OneFlow系統(tǒng)設計(https://docs.oneflow.org/v0.4.0/basics_topics/essentials_of_oneflow.html)

torch.nn.Module(https://pytorch.org/docs/1.10/generated/torch.nn.Module.html)

其他人都在看

OneFlow源碼解析:自動微分機制

ChatGPT的一小步,NLP范式轉變的一大步

李白:你的模型權重很不錯,可惜被我沒收了

OpenAI掌門Sam Altman:AI下一個發(fā)展階段

32篇年度最佳AI論文;Python編譯器Codon開源

比快更快,開源Stable Diffusion刷新作圖速度

OneEmbedding:單卡訓練TB級推薦模型不是夢

歡迎Star、試用OneFlow最新版本:GitHub - Oneflow-Inc/oneflow: OneFlow is a deep learning framework designed to be user-friendly, scalable and efficient.OneFlow is a deep learning framework designed to be user-friendly, scalable and efficient. - GitHub - Oneflow-Inc/oneflow: OneFlow is a deep learning framework designed to be user-friendly, scalable and efficient.https://github.com/Oneflow-Inc/oneflow/

關鍵詞:

亚洲美女乱1区2区3区| 青青青草av在线观看| 色婷婷av国产精品欧美| 超碰在线97青青草原| 色婷婷av一区二区三区网| 青青草原国产视频在线观看| 亚洲欧美综合国产精品一| 日本免费一区二区三区中文字幕| 噜噜mm视频在线观看| 午夜dj观看在线观看hd| 成人国产麻豆一区二区| 人人妻人人做人人妻av| 国产91情侣在线视频| 日本午夜免费在线视频| 日韩在线不卡一区在线观看| 人妻中出中文字幕在线| 大乳美女疯狂榨取精子视频| 国产一区二区在线观播放| 黄色av网站手机在线播放| 91av在线观看蜜臀| 九九久久99最新精品| 国产丝袜另类精品综合| 能看国产小视频的网站| 人妻在卧室被老板疯狂进入 | 久久三级视频在线观看| 可以看手机在线黄色视频网| 色一情一乱一乱一区91Av| 在线观看资源青青国产视频| 国产精品成人中文字幕| 欧美激情在线播放一区| 曰本在线精品一区二区三区| 欧美在线视频午夜精品| 久久av成人中文字幕| 久久婷婷色香五月综合激激情| 亚洲综合色在线一区二区| 自拍 偷拍 亚洲 欧美| 青青草原精品免费在线视频| 亚洲欧美自拍偷拍另类| 色婷婷一区二区三区四区在线| 国产欧美日韩精品在线| 日本人妻中文字幕在线| av网站在线观看青青草| 欧美激情视频一区二区三区| 91在线成人在线视频| 国产成人自拍视频在线| 日韩av中文字幕另类 | xxx日韩欧美黄色a| 九九久久99最新精品| 久草视频这里只有精品| 99re这里只有精品在线| 成人在线观看免费视频播放| 97超碰超碰在线观看| 黄色av网站手机在线播放| 成人免费三级在线观看| 人妻中文字幕免费av| 国产亲乱的性视频网站| 韩国性感美女直播热舞| 一级成人欧美一区在线观看| 蜜臀av入口一区二区三区| 青青青青娱乐在线观看| 一区二区三区看国产片在线| 日韩情色一区二区三区四区| 精品日韩欧美人妻系列| 欧美日韩久久综合一区二区| 自拍亚洲一区欧美另类| 成人免费av网址在线观看| 国产精品丝袜久久久久久久久| 天天操天天日天天射天天爽| 少妇人妻av毛片在线看| 91公开在线免费视频| 精品欧美成人观看一级| 熟女人妻专区中文字幕| 一边吃扎一边插逼逼视频| 国产老人一区av二三区| 久久久久久噜噜噜久久久精品 | 人妻熟女一区二区三区98| 精品人妻少妇嫩草一区二区三区| 91av在线观看蜜臀| 黄色av在线免费播放| 黄色一级片久久久免费观看| 成人国产精品av在线| 欧美一区2区三区在线播放| 欧美性色欧美a在线视频| 国产成人不卡在线视频| 国产精品人妻中文字幕| 巨乳人妻中文字幕精品在线| 人妻巨乳中文字幕亚洲在线| 黄色污染网站在线观看| 一边吃扎一边插逼逼视频| 中文字幕乱码在线精品| 你在线上av中文字幕| 国产 剧情 在线 精品| 精品亚洲一区二区三区ftp| 在线观看国产精品av| 色婷婷国产精品免费视频| 91在线精品免费视频| 青青青草原成人在线视频| 国产精品成人自产拍在线| 成人精品国产一级二级| 久久久精品久久久久久69| 美女自拍偷拍亚洲一区| 国产原创av在线免费播放| 凹凸在线视频免费观看| 国产精品丝袜熟女一二三 | 精品日韩欧美人妻系列| 97超频精品在线观看| 国产传媒一区二区三区四区五区| 黄色一级片久久久免费观看| 青青草原国产在线免费观看| av天堂中文字幕精品| 精品人妻少妇嫩草一区二区三区| 最新午夜在线观看视频| 91成人资源在线观看| 欧美情色大片在线观看| 欧美一级内射视频在线播放| 超视在线免费观看视频| 国产av日韩精品久久| 久久亚洲精品色噜噜狠狠| 欧美性色黄大片人与善 | 国产爱爱视频在线播放| 日产日韩亚洲欧美综合在线| 欧美一区二区三区aa大片漫| 97人妻免费公开视频| 欧美一区二区三区aa大片漫| 国产 剧情 在线 精品| 久久av成人中文字幕| 在线 av 中文字幕| 日韩人妻久久中文字幕| 国外成人免费激情在线视频| 91久久精品国产91性色| 国产免费无码午夜福利蜜臀| 久久青青草原在线视频| 国产av成人专区一区| 亚洲av专区在线观看国产| 爆乳美女粉嫩阴蒂被插视频| 91成人精品亚洲国产| 男人女人40分钟视频| 欧美专区一区二区在线| 亚洲国内av不卡在线| av中文字幕一区在线| 久久久久久噜噜噜久久久精品| 国产哟av精品色哟哟| 国产福利精品久久av| 夜精品一区二区无码A片| 欧美精品网站在线视频| 国产精品18久久久久久二百| 亚洲精品国产精品懂色av| 熟女大胸白嫩自慰流白浆| 最新成人精品视频在线| 最新欧美69堂在线视频| 亚洲av无久久精品一区二区| 午夜mm1314视频| 嘴唇上长黄色的小点点| 亚洲综合图片一区二区三区| 啊哈怎么被那么多男生操| 亚洲一区视频在线免费播放| 青青青青在线播放视频| 日韩国产在线不卡av| 国产自拍偷拍在线一区| 深夜视频在线观看免费| 人妻视频资源在线观看| 区一区二区三在线播放| av在线中文字幕资源网| 欧美一区二区三区四区免费| 人妻熟女一区二区91| 国产免费黄色av 网站| 饥渴少妇高潮露脸嗷嗷叫| 熟女一区二区三区播放| 又色又爽又黄又视频毛片| 蜜臀国产在线观看播放免费| 中文字幕亚洲久久爽一区| 老熟女 一区二区三区| 丰满人妻熟妇又伦精品| 夜欲av无码精品一区二区| 成人国产精品视频在线| 亚洲成人av免费在线播放| 中文字幕久久久2029| 午夜秋霞在线免费观看| 综合av一区二区三区| 精品一区二区三区四区在线播放| 桃色视频在线观看97| 在线成人av一区二区| 国产高清亚洲精品视频| 久久av成人中文字幕| 91国产自拍在线视频| 岛国av丝袜在线播放| 成年网站在线视频免费| 精品在线观看视频一区| 91黄页网站在线观看| 成人永久免费激情视频在线| 亚洲观看一区二区三区四区| 亚洲乱码国产一区网址| 亚洲午夜免费在线观看| 国产欧美精选自拍视频| 亚洲av无码一区二区三区免看| 99久久精品婷婷久久久久久| 国产原创AV蜜芽尤物一区| 久久久久久久久久久高| 亚洲免费成人精品视频| 日韩国产精品99久久久久久| 国产三级欧美系列日韩系列| 国产精品亚洲av二区三| 国产网友自拍视频一区| AV午夜福利一片免费看久久| 青青草日韩av在线播放| 熟女人妻中文字幕在线看| 丝袜熟女av一区二区三区| 91丨九色丨韩国人妖| 国产97视频在线观看| 国产精品丝袜熟女一二三| 国产高清亚洲精品视频| 国产有色视频在线网址| 亚洲欧洲自拍拍偷第二页| 国产精彩自拍视频在线观看| 在线91华人精品国产片| 污污污网址免费在线观看| 欧美午夜理论在线观看| 午夜偷拍视频免费观看| 麻豆国产成人av在线 | 天海翼一区二区三区免费| 国产美女扒开粉嫩尿口网站| 亚洲精品自产拍在线观看动漫 | 伊人网站免费在线观看| 91精品视频最新入口| 精品人妻伦一二二区久久| 国产黄色av网站在线| jizz视频在线观看| 国模在线一区二区三区| 欧美日韩午夜精品不卡综合| 黄色美女在线观看日韩| 亚洲国产精品黑丝美女| 亚洲素人中文字幕在线| 国产丝袜另类精品综合| 96av国产在线播放| 青青草草视频在线播放| 婷婷月色一区二区三区| 污污污黄视频免费观看| 久久人妻公开中文字幕网| 久久精品国产高潮av| 亚洲国产精品黑丝美女| 国产传媒一区二区三区四区五区 | 国产成人黄色精品视频| xxx日韩欧美黄色a| 成人美女主播在线播放| carpon视频在线观看| 嘴唇上长黄色的小点点| 国产97色伦在线观看| 亚洲av专区在线观看国产| 中文字幕av在线观看网址| 国产一级黄色性生活片| 久久无语av中文字幕| 日韩人妻熟女中文字幕的视频| 国产视频二区在线观看 | 国产一区二区三区伦理片一级| 国产一级视频在线观看免费| 人妻夜夜爽天天爽欧美色院| av人妻一区二区三区| 久久精品国产v日韩v亚洲 | 精品久久久中文字幕人妻| 国产很黄很色精品久久久| 成人在线播放亚洲一区| 久久久免费一区二区三区| 日本免费精品一二三区| 青娱乐成人免费公开视频| 中文字幕人妻系列在线视频| 国产AV无码专区AV麻豆| 国产精品乱码在线观看| 男人插女人逼有声视频| 好吊色欧美一区二区三区四区| 亚洲精品国产av久久| 朋友的妈妈在线免费观看中字 | 青青草原精品免费在线视频| 免费女女同黄毛片av网站| 欧美一区二区三区av| 九一精品人妻一区二区三区| 轻轻插青青草视频在线播放| 99国产小视频在线播放| 国产97视频免费在线观看| 欧美在线免费在线视频| 国产一区二区不卡视频在线| 人妻精品在线观看视频| 99九九99久久精品| 国产麻豆精品在线视频| 国产精品中文av在线播放| 久久久久人妻精品一区二区三区| 免费一级av高潮喷水片特| 精品人妻伦一二二区久久| 国模午夜写真福利在线| 国产97视频免费在线观看| 欧美日韩三级在线观看| 亚洲 自拍 露出 极品| 成人黄色av免费网站| 九九激综合五月天国产| 中文字慕人妻一区二区在线视频| 国产乱码字幕精品高清人v| 免费播放黄色操逼乱操逼 | 日本一本久a久久精品综合| 精品99在线免费视频| 乱文丝袜乱文丝袜美腿视频| 欧美日韩久久综合一区二区| 亚洲一区二区在线视频播放| 熟女系列丰满熟妇一区二区三区| 青青草日韩av在线播放| 掰开我的大黑逼快来操我| 国产成人精品欧美日韩网站| 成人啪精品视频网站午夜| 污污污黄视频免费观看| 久久久久久狠狠亚洲综合| 中文字幕在线观看地址av| 久久人妻公开中文字幕网| 国产成人麻豆精品视频| 久久久久久久久久久亚洲| 中文字幕精品乱码久久久久| 欧美一区二区三区四区在线观看| 久久久久精品久久久久久| 久久精品人妻系列av| 欧美国产中文一区二区三区| av在线中文字幕播放| 激情伦理一区二区三区| 精品人妻一区二区三区综合部| 国产极品粉嫩交性大片| 精品日韩欧美人妻系列| 5060午夜看片免费| 日韩女优精品在线观看| 日韩精品乱码av在线播放| 国产精品久久久久九九九九| 夜欲av无码精品一区二区| 色94色一区二区三区| 国产精品露脸对白播放| 欧美激情视频一区二区三区| 视频一区二区三区日韩欧美| 中文字幕av在线观看网址| 久久人人妻人人做人人爽| 精品久久99在线观看| 91超碰在线免费视频| 成年人播放视频在线观看| 免费av网址一区二区| av资源在线中文天堂| 国产有色视频在线网址| 欧美三级精品三级在线| 欧美日韩国产三级在线| 人妻少妇激情综合小视频| 夜夜骚av一区二区三区啊| 欧美一区二区三区aa大片漫| 国产精品一二av在线| 国产综合日韩精品欧美| 国产精品人妻中文字幕| 黄视频网站免费观看视频| 在线播放亚洲一级特黄片| 精品日韩欧美人妻系列| 内射中文字幕在线观看| 成年av网站18不禁| 亚洲天堂中文av网站| 97免费视频国产在线观看| 成人黄色免费观看网址| 亚洲国产免费视频网站| 两鸡巴日一个骚逼浪的视频| 欧美日韩午夜精品不卡综合| 鲁片鲁一区二区三区在线观看| 青青操新免费观看视频| 亚洲av无码一区二区三区免看| 两鸡巴日一个骚逼浪的视频| 国产一区二区在线97| 人妻在线免费观看二区| 污污污黄视频免费观看| 乱文丝袜乱文丝袜美腿视频| 成人极品av免费观看| 国产又粗又长又黄又大的视频| 亚洲不伦丝袜人妻在线| 啊哈怎么被那么多男生操| 久久精品国产亚洲av四区| 国产美女在线观看专区| 我的女人呻吟噢噢噢哦哦哦哦| 人妻av在线中文字幕| 国产精品精品免费视频| 国产国拍成人精品视频| 国产视频免费在线播放| 中文字幕亚洲熟女精品人妻| 亚洲精品自产拍在线观看动漫| 伊人丝袜人妻中文字幕| 国产精品久久久久精品日 | 试婚99天视频免费完整版观看| 美女国产高潮福利片在线看| 中文字幕人妻免费网站| 国产亚洲精品高清一区| 在线观看不卡一区二区三区| 免费av在线网站中文字幕| 成人刺激视频免费观看| 欧美一区二区免费在线观看| 国产白嫩在线观看视频| 区一区二区三在线播放| 黄色av在线免费播放| 欧美日韩激情午夜看片| 亚洲欧美丝袜美腿 综合| 久久精品中文字幕乱码视频| 日韩熟女少妇一区二区三区| 国产高清亚洲精品视频| 国产精品美女久久久久久不卡| 亚洲素人中文字幕在线| 成人在线观看免费视频播放| 精品99在线免费视频| 亚洲午夜免费在线观看| 97人妻免费在线视频| 99久久国产综合精品五月天| 综合人妻一区二区三区| 国产原创av在线免费播放| 久久久久久人妻精品一区| 日本一区二区不卡精品| 美女自拍偷拍亚洲一区| 丰满人妻精品一区二区三区| 免费人成在线观看视频高潮| 久久久久久久精品女人毛片| 青青河边草观看完整版高清| 青青免费在线播放av| 久久久久久久98亚洲精品| 国产亚洲精品高清一区| 国产精品短视频在线观看| 丰满熟女一区二区三区91| 青娱乐 青青青操 天天日| av中文字幕一区在线| 欧美一区二区三区再线播放| 激情视频 超黄 在线免费| 狠狠色狠狠色综合日日92| 熟女人妻中文字幕免费观看| 97成人在线视频免费观看| 欧美成人动漫在线观看| 精色av中文字幕在线| 日韩欧美国产一区二区三区在线| 97超碰超碰在线观看| 日本欧美一区二区视频| 日韩人妻久久中文字幕| 人妻丝袜美腿中文字幕 | 精品国产综合av蜜臀18| 亚洲乱码国产一区二区| 国产一区二区在线观播放| 久久久21精品久久久| 国产美女爽到喷出水来视频99| 国产成人高清一区二区三区免费视频| 久久综合中文字幕日韩精品| 日韩欧美一区二区专区在线观看| 自拍偷拍亚洲综合在线| 久久综合熟女中文字幕| 26uuu亚洲综合色欧美| 青青青爽综合在线视频| 青青河边草观看完整版高清| 久久人妻公开中文字幕网| 久青青草视频在线播放| 国产亚洲成人精品视频| 国产成人精品欧美日韩网站| 成人av综合网中文字幕| 日韩熟女少妇一区二区三区| 日韩熟女人妻国产av| 久久久久99精品成人| 国产精品中文字幕av在线| 97com超碰在线免费| 欧美一区二区三区中文字幕| 亚洲一区二区三区成人在线| 国产精品96乱子一级视频| 亚洲黄色分享大全探花| 亚洲第一区二区在线观看| 久久久免费久久久精品| 成人免费看片98欧美| 中文字幕视频观看在线中文| 精品久久99在线观看| 亚洲乱码国产一区二区| 亚洲国产精品视频免费看| 三级国产精品久久久99| 一边吃扎一边插逼逼视频| 午夜日韩私人大片中国黄页网| 巨乳人妻中文字幕精品在线| 24小时在线免费观看高清视频| 国产精品乱码在线观看| 黄视频免费看网站在线观看| 国产视频免费在线播放| 国产欧美精选自拍视频| 99爱在线精品视频免费看| 中文字幕亚洲久久爽一区| 性感美女肉色丝袜诱惑| 青草视频中文字幕在线观看| 蜜臀av国内精品久久久久久 | 97超频精品在线观看| 区一区二区三在线播放| av天堂午夜精品蜜臀| 日本一本久a久久精品综合| carpon视频在线观看| 午夜精彩视频网站免费观看| 又色又爽又黄又视频毛片| 国产原创av在线免费播放| 亚洲中文字幕乱码免费播放| 精品熟妇人妻一区二区三区四区 | 伊人网av中文字幕精品在线| 国产综合日韩精品欧美| seseav在线观看| 制服丝袜 日韩 国产| 欧洲乱码在线观看视频| 97人妻中文字幕精品一区在线| 精品无人区一区二区三区av| 激情av一区av二区| 亚洲熟女区一区二区三| 日韩精品人妻av中文字幕| 中文字幕中文av在线精品| 国产免费在线视频观看| 亚洲男人天堂超碰在线| 国产精品久久久久久96| 日韩 国产 欧美 在线 一区| 草草视频免费在线观看| k到视频在线观看免费网站| 蜜臀成人av在线观看| 白白色发布在线播放国产| 国产91情侣在线视频| 男人插女人逼有声视频| 国产精品久久久久久96| 成人永久免费激情视频在线 | 亚洲欧洲偷拍另类av| 极品少妇av一区二区| 久久久久久久九九九b热| 91在线视频网站总站| 欧美国产精品久久综合| av天堂免费在线播放| 伊人色综合久久天天伊人婷| 精色av中文字幕在线| 欧美日韩一区二区三四| 成年人黄视频免费观看网站| 亚洲观看一区二区三区四区| 青青草久久久久综合精品| 欧美在线免费在线视频| 亚洲美女乱1区2区3区| 欧美性色欧美a在线视频| 饥渴少妇高潮露脸嗷嗷叫| 国产成人自拍视频在线| 国产免费九九久久精品a级| 你懂得在线免费观看99| 国产免费综合视频在线观看| 91成人精品亚洲国产| 久久精品久久一区二区| 国产网友自拍视频一区| 国产有色视频在线网址| 人妻少妇激情综合小视频| 美女在线观看免费在线观看| 成人精品国产一级二级| 国产传媒一区二区三区四区五区| 亚洲 欧美 日韩成人| 久久国产精品亚洲va麻豆| 久久99只有这里有精品| 婷婷丁香精品一区二区三区| 免费人成在线观看视频高潮| 精品人妻av中文字幕乱码男同| 在线播放欧美A在线观看| 在线观看不卡一区二区三区| 91偷拍老熟女露脸合集| 欧洲一区二区三区在线播放| 97成人在线精品视频| 男人和女人上床的真实视频| 性做久久久久久久毛片| 91精品国产色综合久久不卡蜜| 久久久久人妻精品一区二区三区| 亚洲国产成人不卡av| 国产精品亚洲av二区三 | 免费观看国产精品黄色| 国产视频二区在线观看| 久久久精品久久久99| 国产免费黄色av 网站| 久久久久久久久久久亚洲| 亚洲国内av不卡在线| 欧美激情视频免费观看| 国产乱人视频免费观看| 日本午夜免费在线视频| av现场直播亚洲乱码| 97自拍视频国产视频| 91草草视频在线观看| av黄色资源中文字幕| 一级成人欧美一区在线观看 | 国产一区二区在线观播放| 制服丝袜 日韩 国产| 亚洲制服丝袜美腿在线| 91大神精品免费在线播放| 欧美激情精品久久久久久蜜臀| 青青草原精品在线观看视频| 大帝av在线一区二区三区| 国产精品一二av在线| 国内网友自拍视频在线| 免费国产草莓视频在线观看黄| 青青操视频在线观看免费观看| 三上悠亚在线中文字幕| 国产日韩制服丝袜第一页| 国产美女学生在线观看| 亚洲 自拍 欧美 中文| 久久久久人妻精品一区二区三区| 欧美一区二区三区四区免费| av岛国一区二区三区久久| 亚洲成人av中文字幕免费播放| 激情av一区av二区| 国产高清三级在线精品福利| 欧美成人网另类套图超市| 人妻一区二区免费播放| 国产一区二区三区在线h| 老男人xx女人视频试看| 91公开在线免费视频| 夜精品一区二区无码A片| av一区二区三区看片| 青青视频在线观看播放观看| 久久国产精品99精国产| 97超碰人妻在线观看| 青青青草原成人在线视频| 韩国三级一区二区在线观看| 国产精品亚洲av二区三| 综合婷婷一区二区三区| 亚洲一二三区精品在线观看| 一区二区三区 国产日韩欧美| av天堂午夜精品蜜臀| 自拍偷拍色亚洲欧美色| 婷婷月色一区二区三区| 国产亚洲免费在线视频| 欧美一区二区三区色污| 国产午夜精品视频免费福利| av在线观看亚洲中文| 亚洲av无久久精品一区二区| 亚洲国产熟女一区二区三区胖妞 | 91丨九色丨韩国人妖| 正在播放99精品视频在线播放| 亚洲一区二区三区天海翼| 中文字幕在线午夜人妻| 国产精品三级av及在线观看| 亚洲国产精品美女papa| 亚洲一级av对白刺激| 色婷婷国产精品免费视频| 桃色视频在线观看97| 日本丝袜美腿在线观看| 24小时在线播放免费观看| 九九久久久久无限久久| 91黄页网站在线观看| 中文字幕乱码不卡一区二区三区| 抽搐高潮痉挛白浆无码av| 亚洲自拍一区在线观看| 日韩美女美女黄色黄色片| 亚洲一区视频免费在线观看| 自拍 偷拍 亚洲 欧美| 国产午夜高潮熟女精品| 24小时在线播放免费观看| 免费国产草莓视频在线观看黄 | 中文一区二区三区在线播放| 欧美一区二区三区再线播放| 色综合久久综合欧美综合| 日韩一级淫片蜜臀播放口| 丝袜制服诱惑人妻av| 日韩在线一区二区三区中文字幕| 久久精品人妻免费观看| 搬开女人下面使劲插视频| 国产成人av在线精品| 亚洲精品 乱码久久久久久| 老女人乱淫一区二区三区| 翔田千里精品久久一区二| 少妇的玉足让我爽翻天| 免费精品国偷自产在线洗澡| 日韩人妻熟女中文字幕的视频| 激情五月婷亚洲蜜臀av| 欧美性色欧美a在线视频| 试婚99天视频免费完整版观看| 欧美整片一区二区三区| av中文字幕人妻丝袜| 中文字幕人妻丝袜成熟乱三区 | 人妻巨乳中文字幕亚洲在线| 俄罗斯大鸡吧操骚逼水多舒服 | 久久av成人中文字幕| 国产对白av一区二区| 成人午夜精品一区二区三区| 大香视频依人在线中文字幕| 久久久精品久久久久久69| 男人插女人逼有声视频| 久久精品人妻一区二区| 青青操视频在线观看免费观看| 亚洲一级二级三级国产av| 男生把小鸡鸡插到大美女的屁股| 中文乱码在线观看视频| 95国产成人精品视频| 午夜97视频在线观看| 91丨九色丨韩国人妖| 亚洲乱码在线免费观看| 久久综合久久狠狠综合| 夜夜骚av一区二区三区啊| 国产亚洲免费在线视频| 亚洲国产精品黑丝美女| 日韩欧美一区二区专区在线观看| 一区二区三区欧美精选| 成人午夜精品一区二区三区| 美女国产高潮福利片在线看| 91草草视频在线观看| 欧美一级内射视频在线播放| 国产精品久久人妻互换| 一级成人欧美一区在线观看| 人妻熟女一区二区三区98| 日本一本久a久久精品综合| 青青青草av在线观看| 国产欧美一区二区精品性| 美女在线观看免费在线观看| 国产粉精品高潮呻吟久久av| 79久久久久久久久久| 三级久久在线中文字幕| 大象焦伊人久久综合网色视| 精品在线观看视频一区| 黄色污染网站在线观看| 熟女麻豆一区二区三区四区| 中文乱码字幕视频观看网站免费| 欧美日韩制服丝袜第一页| 国产欧美日韩精品一区二区三区 | 国产乱精品一区二区视频了| 日本丝袜美腿自拍亚洲| 熟妇久久久人妻中文字幕| 国产精品成人自拍视频| 熟女大胸白嫩自慰流白浆| 91人人妻人人做人人爱| 亚洲制服丝袜美腿在线| 男人女人40分钟视频| 成人夜间视频免费在线观看| 老熟女老熟妇一区二区| 亚洲三级黄色在线观看| 亚洲一级二级三级国产av| 少妇人妻av毛片在线看| 国外成人免费激情在线视频| 午夜一区视频在线观看 | 国外成人免费激情在线视频| 国产免费av国片精品| 欧美在线免费在线视频| 亚洲熟妇色自偷自拍另类图片| 95国产成人精品视频| 在线播放亚洲一级特黄片| 凹凸在线视频免费观看| 日韩在线一区二区三区中文字幕| 日韩女优精品在线观看| 国产精品中文av在线播放| 亚洲综合国产乱码成人| 爱搞视频在线免费观看的网站| 白乳房天天官网性插视频| av天堂中文字幕精品| 啊啊啊啊插进去你好骚视频| 亚洲国产欧美精品在线| 亚洲 人妻 有码 在线| 亚洲观看一区二区三区四区| 欧美日韩一区三区不卡在线| 精品人妻伦一二二区久久| 蜜桃av精品视频一区二区三区| 久久久久久精品久久久久久| 国产哟av精品色哟哟| 日韩欧美国产精品综合| 在线观看无码免费你懂的| 午夜在线观看视频你懂的| 三级国产精品久久久99| 中文字幕中文av在线精品| av天堂中文字幕精品| 国产av自拍资源网址| 美女制服丝袜高跟诱惑| 亚洲一区二区三区桃乃木香奈| 午夜av中文字幕在线观看| 与女性一起行走男性应走| 伊人网站免费在线观看| 明星性感丝袜图片大全| 欧美精品素人在线观看| 久久久精品久久久99| 岛国av丝袜在线播放| 国产成人av午夜精品免费 | 国产剧情午夜在线观看| 人妻丝袜一区二区三区四区av| 日韩熟女少妇一区二区三区| 超碰97在线公开观看| 日韩精品乱码av在线播放| 国产又粗又黄在线播放| 久久久久亚洲av一区二区三区| 亚洲国内av不卡在线| 黄视频免费看网站在线观看| 色视频在线免费观看视频播放| 巨乳少妇av中文字幕| 亚洲国产99精品国自产| 得得的爱在线视频免费观看 | 亚洲在线视频中文字幕| 国产揄拍视频在线观看| 中文字幕免费av在线| 女人日男人30分钟视频| 色婷婷综合精品久久久| 99综合精品在线观看| 国产老人一区av二三区| 国产成人免费在线观看av| 少妇的玉足让我爽翻天| 黄色av网站 亚洲精品| 中文字幕乱码在线观看| 超碰97在线公开观看| 国产午夜精品视频免费福利| 国产成人av在线精品| 毛片久久久久久久久久久| 亚洲综合国产乱码成人| 男人添女人下边视频免费| 欧洲美女一区二区三区| 欧美 亚洲一区二区在线| 亚洲 人妻 有码 在线| 91在线视频网站总站| 97超频精品在线观看| 天海翼一区二区三区免费| 国产理论视频在线观看| 久久久久久久亚洲综合| av黄色资源中文字幕| 先锋视频资源在线播放| 精品国产专区91精品| 99re这里有精品免费视频| 欧美在线观看亚洲精品| 噜噜mm视频在线观看| 亚洲av日韩精品久久| 精品久久久人妻中文字幕| 亚洲情色一区二区三区四区五区| 国产乱人视频免费观看| 亚洲av无久久精品一区二区| 国产成人黄色在线观看| 国产熟妇一区二区三区四区| 国产精品美女久久久久久不卡| 日韩中文字幕人妻诱惑| 青青草久久久久综合精品| 男人把女人捅到爽歪歪黄| 久久成人在线播放视频| 99久久无码精品区二区毛片| 日韩美女美女黄色黄色片| 日韩少妇一区二区三区四区五区| 中文字幕中文av在线精品| 国产欧美精选自拍视频| 中文字幕在线视频亚洲| 国产欧美精品免费观看久| 久久99精品久久久久蜜臀| 国产精品久久久久精品日| 韩剧熔炉在线完整免费观看| 人妻熟女一区二区91| 国产97自拍视频在线观看| 欧美激情一区二区二区| av黄色资源中文字幕| 国产97视频免费在线观看| 超视在线免费观看视频| 激情五月婷亚洲蜜臀av| 中文字幕国产av中文| 日韩欧美国产精品综合| 亚洲乱熟女一区二区三区com| 乱文丝袜乱文丝袜美腿视频| 国内精品伊人久久久久av| 色综合久久久久久久久8噜啦噜| 国产又粗又黄在线播放| 久久久久久久久久久亚洲| 自拍偷自拍亚洲精品10p | 噜噜mm视频在线观看| 97超碰在线播放视频| 最近中文字幕免费mv在线直播| 丰满熟女一区二区三区在线播放| 成人在线免费播放视频| 国产精品一级二级三级四级| 成人国产av精品蜜桃漫画| av中文在线中文av| 国产精品成人免费av| 丰满美女一区二区三区| 97人人爽人人爽人人人爽| 91超碰国产在线观看| 亚洲欧美丝袜美腿 综合| 麻豆国产成人av在线| 亚洲一区二区在线视频播放 | 日韩国产在线不卡av| 中文字幕乱码在线精品| 国产精品乱码在线观看| 中文字幕人妻丝袜成熟乱三区| 亚州精品一区二区@v| 亚洲午夜精品久久久久久人妖| 99爱在线精品视频免费看| 亚洲一区在线人妻视频| 成人动漫视频在线观看免费| 精品久久久中文字幕人妻 | 午夜日韩私人大片中国黄页网| 亚洲精品国产精品懂色av| 伊人色综合久久天天伊人婷| 美女观看网站免费不卡视频| 久久精品人妻一区二区| 5060午夜看片免费| 人妻夜夜爽天天爽欧美色院| 69久久久久久人妻白浆| av资源在线中文天堂| 成人A级毛片无码免费看| 97人妻中出中文字幕| 午夜在线观看视频你懂的| av激情韩国在线播放| 91在线精品免费视频| 欧美在线视频午夜精品| 精色av中文字幕在线| 精品一区二区三区四区在线播放| 国产aV无码片毛片一级韩国| 亚洲av乱码在线观看| 欧美生活一区二区三区| 精品国产91av在线观看| 91人人妻人人做人人爱| 欧美在线免费激情视频| 麻豆av国语对白麻豆| 国产精品久久久久久av色| 精品人妻av在线观看| 色老久久精品偷偷鲁一区| 欧美少妇一区二区三区| 亚洲综合国产乱码成人| 久久婷婷色香五月综合激激情| 国产精品久久人妻互换| 人妻熟女一区二区91| 综合人妻一区二区三区| 区一区二区三在线播放| 亚洲无码AV在线免费观| 国产av中文字幕乱码| 国产高清av一区二区在线观看| 久久91丨国产人妻熟女| 中文一区二区三区在线播放| 亚洲午夜精品久久久久久人妖| 久久无语av中文字幕| 日本一区二区不卡精品| 极品视频在线免费播放| 国产乱码字幕精品高清人v| av激情韩国在线播放| 成人av在线av在线| 嘴唇上长黄色的小点点| 国产91av精品在线观看| 国内少妇高潮毛片免费看| 韩国床震吃奶摸下的激烈视频| 亚洲国产精品黑丝美女| 97超频精品在线观看| 国产精品久久久久精品日| 韩剧熔炉在线完整免费观看| 欧美一区2区三区在线播放| 中文字幕国产av中文| 欧美一区二区三区啪啪另类| 成人极品av免费观看| 91在线国产视频播放| 亚洲精品乱码久久久久久久久| 美女扒开胸罩露出奶头免费| 日韩av一区二区三区四| 成人av无码区二区三区| 欧美日韩一区三区不卡在线| 丰满熟女一区二区三区在线播放| 日韩 制服 丝袜 中文| 人妻中文字幕永久在线| 国产熟女人妻在线观看| 神马不卡午夜在线观看| 亚洲国产99精品国自产| 亚洲综合色区另类av| 我的放荡丝袜美腿老师| 一道一本av精品久久毛片| 激情av一区av二区| 久久精品久久一区二区| 黄色av网站手机在线播放| 韩国三级一区二区在线观看| 欧美在线1区2区3区| 日韩国产中文字幕精品| 国产原创av在线免费播放| 亚洲成人av免费在线播放| 青青草原网址在线观看| 欧美成人天天综合在线视色 | 美女扒开胸罩露出奶头免费| 欧美成人动漫在线观看| 国内网友自拍视频在线| 神马不卡午夜在线观看| 国产视频午夜在线播放| 久久亚洲国产精品成人| 97国产视频在线观看| 欧美熟妇一级二级三级a| 国产高清在线免费观看不卡av| av黄色资源中文字幕| 精品人妻少妇一区二区三级| 97人人爽人人爽人人人爽| 亚洲高跟丝袜在线观看| 国产亚洲精品成人av丝袜| 亚洲 欧美 日韩成人| 久久激情四射视频一区| 91亚洲精品久久久久蜜桃| 午夜av中文字幕在线观看| 在线成本人视频动漫高清| 我想听大香蕉大家大香蕉| 中文字幕亚洲久久爽一区| 伊人网站免费在线观看| 欧美日韩一区三区不卡在线| 国产精品美女自在线观看免费| 中文字幕亚洲久久爽一区| 日韩中文字幕在线av| 精品人妻一区二区三区成人网 | 欧美精品网站在线视频| 亚洲一级av对白刺激| 女人日男人30分钟视频| 国产乱精品一区二区视频了| 欧美一级色片在线播放| 夜夜欢性恔真人免费视频| 国产高清亚洲精品视频| 上海性战旗袍丝袜女郎| 真人视频在线免费观看| 亚洲欧美人妻最新网址| 中文字幕亚洲久久爽一区| 美女精品一区二区三区免费观看| 国产情侣免费观看视频| 欧美成人网另类套图超市| 午夜mm1314视频| 九一精品人妻一区二区三区| 精品日本一区二区三区四区| 国产偷拍自拍在线免费| 亚洲乱码国产乱码精品精91| 日韩国产精品99久久久久久| 最新中文字幕av大全| 亚洲第一区二区在线观看| 嘴唇上长黄色的小点点| 夜欲av无码精品一区二区| 青青草原精品在线观看视频| 韩剧熔炉在线完整免费观看| 欧美特级特黄a大片免费| 亚洲 自拍 欧美 中文| 精品久久久中文字幕人妻| 草草视频免费在线观看 | 91色乱码一区二区三| 日韩av三级在线网站| 成年av网站18不禁| 丝袜熟女av一区二区三区| 美女视频吃奶视频在线观看| 免费av网址一区二区| 26uuu亚洲综合色欧美| 婷婷月色一区二区三区| 午夜性生大片免费在线观看| 国产欧美在线视频观看| 亚洲综合色区另类av| 97免费视频国产在线观看| 日韩一区二区人妻9999| 国产日韩av大片快播| 青青青色视频在线观看| 性感美女肉色丝袜诱惑| av资源在线中文天堂| 毛片久久久久久久久久久| 自拍 偷拍 亚洲 欧美| 掰开我的大黑逼快来操我| 国产 剧情 在线 精品| 国产成人黄色精品视频| 国产黄色片久久久久久久| 亚洲欧美另类视频一区蜜臀| 99爱精品视频在线视频| 三级国产精品久久久99| 97人妻免费在线视频| 精品人妻一区二区三区综合部| 亚洲乱女色熟一区二区三区| 九九久久99最新精品| 国产有色视频在线网址| 美女扒开胸罩露出奶头免费| 日韩国产在线不卡av| 超污短视频网站在线观看| 日韩不卡毛片午夜在线看片?| 久久精品国产v日韩v亚洲| 午夜日韩私人大片中国黄页网| 亚洲国产99精品国自产 | 亚洲乱码国产一区网址| 久久精品人妻免费观看| 四川熟女a一区二区三区| 精品国产91av在线观看| 国产精品网站调教美女| 久久无语av中文字幕| 国产av 一区二区三区四区| 中文字幕亚洲熟女精品人妻| 91精品国产色综合久久不卡蜜| 国产成人叼嘿视频在线观看| 亚洲国产欧美精品在线| 91自拍免费在线视频| 超视在线免费观看视频| 伊人网站免费在线观看| 亚洲一区二区三区天海翼| 小美女操老头和动物操逼| 青青青草青在线视频免费观看了| 国产视频自拍在线观看| 久久香蕉国产熟女线看| 亚洲日本韩国一级二级三级| 国产成人自拍视频网址| 黑人黄色特级猛男人男人区| 人妻av在线中文字幕| 成人在线一区二区三区av| 日本丝袜美腿在线观看| 少妇直播一区二区三区| 91精品久久久久久五月| 精品国产乱码久久久久夂| 久久99精品久久久久蜜臀| 少妇人妻av毛片在线看| 香蕉免费一区二区三区在线观看| av人妻一区二区三区| 亚洲国产自产一区二区c| 国产原创AV蜜芽尤物一区| 啊啊啊啊插进去你好骚视频| 欧美一区二区三区四区在线观看| 在线观看国产精品av| 中文字幕免费av在线| 久久精品国产亚洲av热黑人| 亚洲人妻av一区二区| 久久久久这里只出精品| 亚洲视频国产精品你懂得| 在线播放一区二区三区三州| 国产成人自拍视频在线| 久久亚洲精品色噜噜狠狠| 国产免费av国片精品| 94精品视频在线播放| 极品视频在线免费播放| 97超碰超碰在线观看| 男人插女人下面出浆视频| 最好看的中文字幕av| 老熟女 一区二区三区| 成人黄色av免费网站| 中文人妻一区二区熟女| 最大的黄色亚洲网站在线观看| 成人黄色在线免费播放| 久久人人妻人人做人人爽| 亚洲男人天堂超碰在线| av在线中文字幕播放| 国产无码精品久久久久久久| 美女国产高潮福利片在线看| 久久激情四射视频一区| 久久国产麻豆免费播放| 亚洲成人av区一区二区三区四| 日韩av大片在线免费观看| 2023国产精品自拍视频| 日本性感丝袜女秘书诱惑| 成人夜间视频免费在线观看| 精品国产黄片一二三区| 婷婷丁香精品一区二区三区| 人妻少妇偷人一区二区三区 | 97 在线免费观看视频| 一区二区三区蜜桃在线观看| 熟女大胸白嫩自慰流白浆| 日韩中文字幕在线av| 中国黄色靠逼大片大黑逼| 国产哟av精品色哟哟| 亚洲综合国产乱码成人| 最新中文字幕av大全| 亚洲人妻一区二区91| 久久久久久噜噜噜久久久精品| 日韩综合在线超乳人妻一区| 久久亚洲国产精品成人| 日本免费一区二区三区中文字幕| 精品成人一区二区三区在线观看| 精品国产污污污的网站| 午夜av中文字幕在线观看| 黄色美女在线观看日韩| 国产免费av国片精品| 成人激情自拍图片视频| 黄色在线观看不卡无广告| 99久久久精品免费看国产| 在线播放一区二区三区三州| 国产av中文字幕乱码| 97超碰超碰在线观看| 熟女麻豆一区二区三区四区| 朋友的妈妈在线免费观看中字| 亚洲综合图片一区二区三区| 欧美日韩一区二区三四| 精品无人区麻豆乱码久久久| 上海性战旗袍丝袜女郎| 亚洲成人av中文字幕免费播放| 国产97色伦在线观看| 黄腔女兵最经典十句话| 亚洲熟女一区2区三区| 国产精品久久久久久永久牛牛| 丰满人妻精品一区二区三区| 在线亚洲视频中文字幕| 日韩在线一区二区三区中文字幕| av黄色资源中文字幕| 黄色av网站手机在线播放| 网友自拍人妻在线视频| 熟女阿av一区二区三| 久久91丨国产人妻熟女| 色av蜜臀av粉嫩av| 国产日韩制服丝袜第一页| 国内网友自拍视频在线| 国产麻豆精品福利在线观看| 午夜精品182视频国产| 亚洲在线视频中文字幕| 久久国产精品9999p| 激情人妻校园春色亚洲欧美| 国产免费无码午夜福利蜜臀| 青青青青草免费视频看看| 黄色传媒在线免费观看| 97在线视频中文字幕| 国产免费在线视频观看| 最新国产网友自拍视频在线| 国产原创AV蜜芽尤物一区| 日韩成人伦理片在线观看| av中文在线中文av| 久久久久久狠狠亚洲综合| 96av国产在线播放| 亚洲中文字幕乱码免费视频| 国产对白av一区二区| 在线人妻av播放观看| 最新免费av在线观看| 大鸡巴操小嫩逼免费全裸| 国产欧美精品日韩精品视频专区 | 国产极品粉嫩交性大片| 国产精品露脸对白播放| 青草视频中文字幕在线观看| 99国产小视频在线播放| 熟女麻豆一区二区三区四区| 精品熟女一区二区三区免费视频| 高颜值美女视频在线观看| 超caopor在线公开视频| 成人精品国产一级二级| 国产精品三级av及在线观看| 久久久久亚洲av一区二区三区| 饥渴少妇高潮露脸嗷嗷叫| 超级碰碰碰视频免费观看| 九九激综合五月天国产| 人妻中文字幕免费av| 欧美国产精品久久综合| 青草青青青青青青操死你| 人妻丝袜美腿中文字幕| 青草视频中文字幕在线观看| 亚洲国内av不卡在线| 凹凸在线视频免费观看| 国产免费综合视频在线观看| 久久一区二区三区av| 在线中文字幕有码视频| 日韩国产偷拍自拍在线| 欧美午夜精品免费视频app| 法国熟女乱淫xxoo| 黄视频免费看网站在线观看| 日韩丝袜诱惑网站大全| 成人 中文字幕 熟女| 亚洲一区在线人妻视频| 国产一级视频在线观看免费 | 日韩中文字幕人妻诱惑| 欧美成人动漫在线观看| 91色乱码一区二区三| 日韩熟女人妻国产av| 国产成人乱色视频网站| 国产免费av国片精品| 97超碰超碰在线观看| 91国产激情视频在线观看| 久久精品国产亚洲av四区| 亚洲精品自产拍在线观看动漫| carpon视频在线观看| 网友自拍人妻在线视频| 成人十八禁av男人的天堂| 高清在线一区二区三区亚洲综合| 亚洲欧美成人自偷自拍一区| 免费一级av高潮喷水片特| 自拍视频在线观看青青网| 伊人精品久久久久中文字幕| 蜜月久久99精品久久久久久| 日本熟日本熟妇中文在线观看| 国产欧美精品日韩精品视频专区 | 你在线上av中文字幕| 久久久久精品久久久久久| 一区二区三区蜜桃在线观看| 小美女操老头和动物操逼| 国内网友自拍视频在线| 久久久久久久98亚洲精品| 国产精品99久久久精品| 青草成人在线观看视频| 国产麻豆精品福利在线观看| 国产自拍偷拍在线一区| 99综合精品在线观看| 一边吃扎一边插逼逼视频| 98久久久久久久久久| 污污污网址免费在线观看| 79久久久久久久久久| 成人在线视频播放 亚洲| 青春草视频免费观看在线| 人妻中出中文字幕在线| 日韩素人mium丝袜| 97人妻超碰在线免费视频| 日韩 欧美 人妻 中文字幕| 久久精品国产高潮av| 中文字幕日韩在线久久| 97视频在线观看免费播放| 久久亚洲国产精品成人| 欧美日韩激情午夜看片| 亚洲综合色区另类av| 欧美性欧美三级全透明时装秀| 黄色mv在线免费观看| 欧美 日韩 一区二区三区| 中文字幕乱码亚洲三区| 丰满熟女一区二区三区91| 免费av在线网站中文字幕| 亚洲乱熟女一区二区三区com| 欧美日韩在线精品激情| 欧美特级特黄a大片免费| 午夜秘密播放器在线观看视频| 一区二区三区欧美精选| 日韩 国产 欧美 在线 一区| 国产91精品入口人妻| 亚洲成人av免费在线播放| 久久久久久久久99密月| 久久香蕉国产熟女线看| 国产精品人妻中文字幕| 熟女大胸白嫩自慰流白浆| 黄视频免费看网站在线观看| 成年人黄色片视频网站| 黄视频网站免费观看视频| 伊人网av中文字幕精品在线| 亚洲欧美人妻最新网址| av在线免费观看网3| 亚洲一a区二a区三a区| 一区二区三区看国产片在线| 成人在线一区二区三区av| 亚洲自拍偷拍 欧美激情| 国产精品一级二级三级四级| 99国产精品久久全免费| 岛国av丝袜在线播放| 久久人人爽人人爽人人片669| 亚洲成人久久精品国产| 91麻豆精品在线播放| 国产精品精品免费视频| 99爱精品视频在线视频| 亚洲丝袜av在线观看| 成人动漫视频在线观看免费| 午夜精品福利一区二区蜜股av| 成人十八禁av男人的天堂| 男人天堂中文字幕av| 超碰人人爱人人爽人人av| 少妇直播一区二区三区| 24小时在线免费观看高清视频 | 免费一级av高潮喷水片特| 国产三级视频在线18播放线观看| 轻轻插青青草视频在线播放| 亚洲国产一区二区久久| 中文字幕在线不卡97| 青春草视频免费观看在线| 1024在线国产视频| 亚洲三级一区二区三区四区| 国产1区2区3区在线播放| 一道一本av精品久久毛片| 超碰在线97青青草原| av资源在线中文天堂| 青青草原在线免费观看网址| 中文字幕乱码激情av| 5060午夜看片免费| 一本92午夜免费不卡福利片 | 精品日本一区二区三区四区| 亚洲乱码在线免费观看| 国产性一交一乱―色―情人| 一区二区三区蜜桃在线观看| 97人在线看视频在线观看| 日韩av在线日韩av日韩av| 91/日韩/精品/乱码| 亚洲精选清纯唯美自拍偷拍| 人妻熟女一区二区91| 欧美情色一区二区三区| 久久国产精品亚洲va麻豆| 97超碰在线公开免费| 午夜一区视频在线观看| 你懂的视频精品在线观看| 精品成人一区二区三区在线观看| 在线播放网站一区二区三区| 成人国产麻豆一区二区| 凹凸在线视频免费观看| 日韩熟女中文字幕一区| 国产成人高清一区二区三区免费视频| 激情视频网站在线观看| 日韩情色一区二区三区四区| 国产 丝袜 欧美中文 另类| av中文字幕一区在线| 国产 中文字幕 乱码 在线| 激情av一区av二区| 青青视频在线观看播放观看| 97 在线免费观看视频| 亚洲一区二区欧美激情| 日韩综合在线超乳人妻一区 | 国产小视频在线观看你懂得| 一级一看免费完整版毛片| 亚洲情色一区二区三区四区五区| 亚洲情色国产自拍偷拍| 免费a站网址在线观看| 伊人av超碰伊人久久久| 青青热久免费精品视频| 国产精品成人中文字幕| 国产小视频在线观看你懂得| 色偷偷av一区二区三区| 欧美在线视频午夜精品| 最好看的中文字幕av| 日韩美女美女黄色黄色片| 黄色美女在线观看日韩| 青草视频在线观看亚洲| 男人操女人逼视频免费观看| 亚洲一级二级三级国产av| 91精品视频最新入口| 欧美精品免费在线播放| 欧美一区二区国产一区| 中文字幕亚洲久久爽一区| 欧美在线视频午夜精品| 亚洲精品国产精品乱码不卡| 精品人妻久久久久一区二| 欧美在线观看亚洲精品| 亚洲国产成人不卡av| 91最新黄色免费网站| 精品国产综合av蜜臀18| 国产自拍视频在线免费| 九九激综合五月天国产| 亚洲av成人噜噜网站| 成人免费视频免费在线观看 | 欧美生活一区二区三区| 人妻丝袜一区二区三区四区av| 超长假大鸡巴从肛门捅到胃视频 | 国产高清av一区二区在线观看| 欧美一区二区三区黄片| 成人亚洲精品在线观看| 久久国产麻豆免费播放| 亚洲 综合 欧美 日韩| 亚洲无av在线中文字幕男男| 久久久国产综合av天堂| 中文字幕国产乱码视频| 在线91华人精品国产片| 青青视频在线观看播放观看 | 日韩 制服 丝袜 中文| 18成人黄色在线观看| 波多野吉衣久久久久久| 欧美日韩一区 二区 三区| 97资源超碰在线中文| 久久综合熟女中文字幕| 很黄很色的视频免费在线观看| 亚洲一区二区av在线| 日日摸夜夜添夜夜添破第一次| 无码国模大尺度自拍视频在线看| 国产福利在线播放视频| 男人和女人逼逼的视频| 久久人人妻人人做人人爽| 日产日韩亚洲欧美综合在线| 欧美一区二区三区色污| 99爱在线精品视频免费看| 亚洲国产99精品国自产| 亚洲欧美日韩av在线观看| 精色av中文字幕在线| 亚洲精品专区一区二区| 中文字幕乱码在线观看| 外国大片在线免费观看| 欧美日韩一区二区三区性| 欧美特级特黄a大片免费| 精品熟妇人妻一区二区三区四区| 26uuu亚洲综合色欧美| 欧美一区二区三区资源| 亚洲欧洲偷拍另类av| 美女观看网站免费不卡视频| 亚洲欧美丝袜美腿 综合| 亚洲 自拍 欧美 中文| 欧美性欧美三级全透明时装秀| 91精品视频最新入口| 久久久久久久久久久亚洲| 国产一区二区三区在线h| 国产免费综合视频在线观看| 人妻一区二区三区精品免费| 人妻av在线中文字幕| 啊啊啊啊插进去你好骚视频| 国产精品入口蜜臀人妻| 波多野吉衣久久久久久| 国产日产欧产精品精乱了派| 青青青草青在线视频免费观看了| 在线观看资源青青国产视频| 9999中文字幕在线视频| 国产精品成人免费av| 蚂蚁三级成人av在线| 国产亚洲欧美日韩三级| 国产午夜高潮熟女精品| 午夜性生大片免费在线观看| 人妻av在线中文字幕| 欧美黄色一级一区二区三区| 成人免费三级在线观看| 久久99亚洲精品久久频| 91国产自拍在线视频| 久久久久久人妻精品一区| 99国产精品久久全免费| 国产成人免费a在线资源| 国产网红主播在线观看视频| 亚洲 自拍 欧美 中文| 欧美一区二区在线观看网站| 欧美成人性做爰77777| 亚洲精品中文字幕一二| 国产香蕉97超级碰碰碰| 蜜臀久久99精品久久宅男| 很黄很色国产精品免费视频| 成年人黄视频免费观看网站| 欧美一区二区三区av| 麻豆国产成人av在线| 97视频在线免费观看网站| 激情人妻校园春色亚洲欧美| 免费av在线网站中文字幕| 国产精品髙潮呻吟久久av| 久久国产精品亚洲va麻豆| 男人添女人下边视频免费| 在线 av 中文字幕| 91人人妻人人做人人爱| 中文字幕女优乱码久久午夜| 免费a站网址在线观看| 日韩少妇一区二区三区四区五区| 在线免费观看青青草av| 两鸡巴日一个骚逼浪的视频| 日韩av在线日韩av日韩av| 好吊色欧美一区二区三区四区| 最新欧美69堂在线视频| 免费一级av高潮喷水片特| 欧美不卡一区二区三区视频| 97超碰人妻在线观看| 在线播放欧美A在线观看| 青青成人免费在线视频| 一区二区在线播放三区| 日韩精品成人av高清在线观看| 少妇人妻一区二区三区3d| 久久综合中文字幕日韩精品| 国产伦精品一区二区三区视频下载| 成年av网站18不禁| 青青河边草观看完整版高清| 桃色视频在线观看97| 成年网站在线视频免费| 亚洲精品 乱码久久久久久| 爱搞一区二区三区av| 欧美一区二区三区四区免费| 亚洲区域一区二区三区| 黑丝美女的骚逼尖叫高潮声| 色婷婷国产精品免费视频| 成年人播放视频在线观看| 久久久精品久久久久久69| 青草青青青青青青操死你| 中文字幕在线乱码观看| 日韩国产精品99久久久久久| 日韩国产精品99久久久久久| av在线观看亚洲中文| 91自拍免费在线视频| 精品在线观看视频一区| 国产香蕉97超级碰碰碰| 国产自拍偷拍在线一区| 成人免费av网址在线观看 | 国产高清亚洲精品视频| 美女黄网站永久观看网站不卡| 亚洲国产蜜臀系列在线观看| 国产97自拍视频在线观看| 国产网红主播在线观看视频| 欧美一区二区在线播放视频| 超碰在线公开内射日韩版| 亚洲熟女久久一区二区| 日韩激情中文字幕在线| 99久久久精品免费看国产| 日本中文字幕乱码免费视频| 亚洲一级av对白刺激| 美女网站免费非常非常黄的| 日韩欧美一区二区专区在线观看| 日韩欧美国产一区二区三区在线 | 欧美性色欧美a在线视频| 在线亚洲视频中文字幕| 欧美在线免费在线视频| 成人24小时免费视频| 国产福利精品久久av| 最新免费av在线观看| 少妇人妻一区二区三区3d| 午夜免费在线观看小视频| 丰满人妻一区二区三区精品av| 欧美日韩久久综合一区二区| 91精品视频最新入口| 最近中文字幕免费mv在线直播| 二区三区免费在线观看| 在线观看日韩三级视频| 美女精品一区二区三区免费观看| 久久久久人妻精品一区二区三区| japanese少妇av| 日韩国产精品99久久久久久| 91最新国产在线播放| 午夜一区视频在线观看| 亚洲一a区二a区三a区| 美女国产高潮福利片在线看| 3p少妇欧美一区二区三区| 熟女系列丰满熟妇一区二区三区| 黄色在线观看不卡无广告| 熟女一区二区三区播放| 久久夜色精品国产亚洲av老牛| 欧美一区二区三区伦理国产| 欧美激情1区2区3区4区| 成人国产麻豆一区二区| 久久人妻一区二区精选| 亚洲综合色在线一区二区| 亚洲精选清纯唯美自拍偷拍| 青青草原国产在线免费观看| 掰开我的大黑逼快来操我| 丰满美女一区二区三区| 久久久亚洲裙底偷窥综合| 超视在线免费观看视频|