-
Notifications
You must be signed in to change notification settings - Fork 5.7k
优化LayerList类的insert函数 #71540
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
优化LayerList类的insert函数 #71540
Conversation
modified: paddle/fluid/pybind/pybind.cc modified: paddle/phi/core/memory/stats.cc modified: paddle/phi/core/memory/stats.h modified: python/paddle/device/cuda/__init__.py
modified: paddle/fluid/pybind/pybind.cc modified: python/paddle/device/cuda/__init__.py
modified: paddle/fluid/pybind/pybind.cc modified: paddle/phi/core/memory/stats.cc modified: paddle/phi/core/memory/stats.h modified: test/cpp/fluid/memory/stats_test.cc
new file: test/legacy_test/test_cuda_memory_stats.py new file: test/legacy_test/test_cuda_reset_peak_memory_stats.py
new file: test/legacy_test/test_cuda_reset_max_memory_allocated.py
modified: python/paddle/device/cuda/__init__.py modified: test/legacy_test/test_cuda_memory_stats.py modified: test/legacy_test/test_cuda_reset_max_memory_allocated.py modified: test/legacy_test/test_cuda_reset_peak_memory_stats.py
modified: paddle/fluid/pybind/pybind.cc modified: paddle/phi/core/memory/stats.cc modified: paddle/phi/core/memory/stats.h modified: test/cpp/fluid/memory/stats_test.cc
modified: python/paddle/device/cuda/__init__.py modified: test/legacy_test/test_cuda_reset_max_memory_allocated.py new file: test/legacy_test/test_cuda_reset_max_memory_reserved.py
modified: paddle/fluid/pybind/pybind.cc modified: python/paddle/device/cuda/__init__.py deleted: test/legacy_test/test_cuda_memory_stats.py deleted: test/legacy_test/test_cuda_reset_peak_memory_stats.py
modified: python/paddle/nn/layer/container.py modified: test/sot/test_15_slice.py
test/sot/test_15_slice.py
Outdated
@@ -147,5 +147,26 @@ def test_string_slice(self): | |||
self.assert_results(string_slice, x) | |||
|
|||
|
|||
class TestLayerListEmptyInsert(unittest.TestCase): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这和 SOT 有关么?为什么要加在这里?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
您好,因为我在test文件夹搜了一下,貌似只有SOT中有LayerList类的相关测试。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
那就去 test/legacy_test
自己新增一个单测,从单测名就可以明显看出在这里加是不合适的
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
收到,已修改
new file: test/legacy_test/test_layerlist.py modified: test/sot/test_15_slice.py
python/paddle/nn/layer/container.py
Outdated
) | ||
self.append(sublayer) | ||
return | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
下面的assert可以挪到上面来,做一个整体的assert判断。另外这里能否不加额外分支,和下面代码采用相同实现?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
收到,已修改,_get_abs_idx
函数也没有考虑index=0的情况,也进行了修改。
modified: python/paddle/nn/layer/container.py modified: test/legacy_test/test_layerlist.py
python/paddle/nn/layer/container.py
Outdated
@@ -545,9 +545,11 @@ def __init__(self, sublayers: Iterable[Layer] | None = None) -> None: | |||
|
|||
def _get_abs_idx(self, idx: int) -> int: | |||
if isinstance(idx, int): | |||
if not (-len(self) <= idx < len(self)): | |||
if not (len(self) == 0 and idx == 0) and not ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个是不是因为原来的阈值范围不合理,原来是:[-len, len) 前开后闭,应改成 [-len, len],对于位置为len处的插入就是在最末尾插入。你看下torch是不是这样设计的
也就是新增一个功能:在位置为len处的插入,不仅仅是针对len为0,而是一个通用功能
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pytorch
pytorch中貌似并没有考虑这个问题。
我在pytorch的insert函数中加入了打印:
def insert(self, index: int, module: Module) -> None:
r"""Insert a given module before a given index in the list.
Args:
index (int): index to insert.
module (nn.Module): module to insert
"""
print("inner Pytorch ModuleList insert function: ",self._modules)
for i in range(len(self._modules), index, -1):
self._modules[str(i)] = self._modules[str(i - 1)]
self._modules[str(index)] = module
并对以下代码进行了测试:
import torch
modules = torch.nn.ModuleList()
modules.insert(2, torch.nn.Linear(20, 20))
print("outer modules:", modules)
modules.insert(3, torch.nn.Linear(30, 30))
print("outer modules:", modules)
modules.insert(0, torch.nn.Linear(10, 10))
print("outer modules:", modules)
测试代码出现了报错,应该是因为没有对输入的str(i)
进行限制。
inner Pytorch ModuleList insert function: OrderedDict()
outer modules: ModuleList(
(0): Linear(in_features=20, out_features=20, bias=True)
)
inner Pytorch ModuleList insert function: OrderedDict([('2', Linear(in_features=20, out_features=20, bias=True))])
outer modules: ModuleList(
(0): Linear(in_features=20, out_features=20, bias=True)
(1): Linear(in_features=30, out_features=30, bias=True)
)
inner Pytorch ModuleList insert function: OrderedDict([('2', Linear(in_features=20, out_features=20, bias=True)), ('3', Linear(in_features=30, out_features=30, bias=True))])
Traceback (most recent call last):
File "/home/qinsx/paddle_test/Modulelist/modulelist.py", line 11, in <module>
modules.insert(0, torch.nn.Linear(10, 10))
File "/home/qinsx/pyenv/pdbaddbmm/lib/python3.8/site-packages/torch/nn/modules/container.py", line 377, in insert
self._modules[str(i)] = self._modules[str(i - 1)]
KeyError: '1'
paddle
在paddle中,insert
函数调用了_get_abs_idx
函数来获取id。
def _get_abs_idx(self, idx: int) -> int:
if isinstance(idx, int):
if not (len(self) == 0 and idx == 0) and not (
-len(self) <= idx < len(self)
):
raise IndexError(
f'index {idx} is out of range, should be 0 for empty list or in range [{-len(self)}, {len(self)})'
)
if idx < 0:
idx += len(self)
return idx
_get_abs_idx
函数也会对左闭右开进行检查。我个人认为_get_abs_idx
函数应该保持左闭右开,因为如果其他函数在调用时,如果获取右区间最大值会越界。我加入的特殊情况为length为0时返回idx=0。
我认为现在可以有两种方案:
- 方案一:保持这种修改,即对
_get_abs_idx
和insert
函数加入length为0的特殊情况判断。 - 方案二:不修改
_get_abs_idx
函数。在insert
函数中不调用_get_abs_idx
函数,而仿照_get_abs_idx
函数单独进行判断。
方案二代码
assert isinstance(index, int) and -len(self._sub_layers) <= index <= len(
self._sub_layers
), f"index should be an integer in range [{-len(self)}, {len(self)}]"
if idx < 0:
idx += len(self)
for i in range(len(self._sub_layers), index, -1):
self._sub_layers[str(i)] = self._sub_layers[str(i - 1)]
self._sub_layers[str(index)] = sublayer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Qin-sx 我可能没描述清楚,新增的功能是指:在位置为len(self)处的插入,比如长度为0的,在0位置插入,长度为1的,在1位置插入。
试了下torch,这个功能是支持的。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Qin-sx 按方案二实现吧,如果_get_abs_idx不能修改为前闭后闭,那就不用调这个函数。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
收到,已修改,并对新增的在位置为len(self)处的插入
功能加入了测试。
modified: python/paddle/nn/layer/container.py modified: test/legacy_test/test_layerlist.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
* added reset peak value initialization modified: paddle/fluid/pybind/pybind.cc modified: paddle/phi/core/memory/stats.cc modified: paddle/phi/core/memory/stats.h modified: python/paddle/device/cuda/__init__.py * added comments modified: paddle/fluid/pybind/pybind.cc modified: python/paddle/device/cuda/__init__.py * added cpp tests modified: paddle/fluid/pybind/pybind.cc modified: paddle/phi/core/memory/stats.cc modified: paddle/phi/core/memory/stats.h modified: test/cpp/fluid/memory/stats_test.cc * added python tests new file: test/legacy_test/test_cuda_memory_stats.py new file: test/legacy_test/test_cuda_reset_peak_memory_stats.py * added a python test for reset_max_memory_allocated new file: test/legacy_test/test_cuda_reset_max_memory_allocated.py * formatted by pre-commit modified: python/paddle/device/cuda/__init__.py modified: test/legacy_test/test_cuda_memory_stats.py modified: test/legacy_test/test_cuda_reset_max_memory_allocated.py modified: test/legacy_test/test_cuda_reset_peak_memory_stats.py * formatted by pre-commit (clang-format) modified: paddle/fluid/pybind/pybind.cc modified: paddle/phi/core/memory/stats.cc modified: paddle/phi/core/memory/stats.h modified: test/cpp/fluid/memory/stats_test.cc * added reset max memory reserved function modified: python/paddle/device/cuda/__init__.py modified: test/legacy_test/test_cuda_reset_max_memory_allocated.py new file: test/legacy_test/test_cuda_reset_max_memory_reserved.py * deleted memory stats and reset peak memory stats modified: paddle/fluid/pybind/pybind.cc modified: python/paddle/device/cuda/__init__.py deleted: test/legacy_test/test_cuda_memory_stats.py deleted: test/legacy_test/test_cuda_reset_peak_memory_stats.py * optimized insert function in LayerList class modified: python/paddle/nn/layer/container.py modified: test/sot/test_15_slice.py * removed the test file new file: test/legacy_test/test_layerlist.py modified: test/sot/test_15_slice.py * optimized conditions modified: python/paddle/nn/layer/container.py modified: test/legacy_test/test_layerlist.py * restored _get_abs_idx and modified insert modified: python/paddle/nn/layer/container.py modified: test/legacy_test/test_layerlist.py
PR Category
User Experience
PR Types
Improvements
Description
优化LayerList类的insert函数
对应issue
insert函数在对index判断时没有考虑
_sub_layers
为空的情,即[0,0)。在pytorch中,并没有进行类似的判断,而是直接插入新的layer。
本次优化将
insert
函数的插入范围改为了左闭右闭区间,例如[0,1],[0,0]等。修改后:_sub_layers
为空时,可以index=0插入新的layer。len(self)
处的插入新的layer。加入了相应的测试。