已合并
Update readme and add defualt_loader patch #117
wang-guangbin创建于 2024年8月7日
Update readme and add defualt_loader patch #117
已合并
wang-guangbin创建于 2024年8月7日
从refs/pull/117/head合入到master
共 4 个文件变更+53-77
MOWNERS+2-0
@@ -12,3 +12,5 @@ reviewers:
12- dilililiwhy12- dilililiwhy
13- shaoyf13- shaoyf
14- wang-guangbin14- wang-guangbin
15+- liu-jiaweikf
16+- zqwzju
MREADME.md+26-77
@@ -17,9 +17,9 @@
17**前提条件**17**前提条件**
18- 需完成CANN开发或运行环境的安装,具体操作请参考《[CANN 软件安装指南](https://www.hiascend.com/document/detail/zh/canncommercial/601/envdeployment/instg/instg_000002.html)》。18- 需完成CANN开发或运行环境的安装,具体操作请参考《[CANN 软件安装指南](https://www.hiascend.com/document/detail/zh/canncommercial/601/envdeployment/instg/instg_000002.html)》。
19- 需完成PyTorch Adapter插件安装,具体请参考 https://gitee.com/ascend/pytorch 。19- 需完成PyTorch Adapter插件安装,具体请参考 https://gitee.com/ascend/pytorch 。
20+- 昇腾软件栈需要安装的版本请参考[版本配套表](#版本配套表)
20- Python支持版本为3.8.X,3.9.X,3.10.X,PyTorch支持版本为2.1.0, Torchvision支持版本为0.16.0。21- Python支持版本为3.8.X,3.9.X,3.10.X,PyTorch支持版本为2.1.0, Torchvision支持版本为0.16.0。
21 22 
22- 
23**安装步骤**23**安装步骤**
24 24 
251. 编译安装Torchvision。251. 编译安装Torchvision。
@@ -42,6 +42,7 @@
42 ```42 ```
43 43 
442. 编译安装Torchvision Adapter插件。442. 编译安装Torchvision Adapter插件。
45+ 使用最新版本,可拉取对应分支最新代码编译安装,稳定版本可以切换到对应分支的tag, 参考[版本配套表](#版本配套表)。
W
Wwang-guangbin2024年9月13日

已更改,配套表已更新tag对应的分支

likedislike
45 46 
46 按照以下命令进行编译安装。47 按照以下命令进行编译安装。
47 48 
@@ -49,9 +50,11 @@
49 # 下载Torchvision Adapter代码,进入插件根目录50 # 下载Torchvision Adapter代码,进入插件根目录
50 git clone https://gitee.com/ascend/vision.git vision_npu51 git clone https://gitee.com/ascend/vision.git vision_npu
51 cd vision_npu52 cd vision_npu
52- git checkout master53+ git checkout v0.16.0-6.0.rc2
53 # 安装依赖库54 # 安装依赖库
54 pip3 install -r requirement.txt55 pip3 install -r requirement.txt
56+ # 初始化CANN环境变量
57+ source /usr/local/Ascend/ascend-toolkit/set_env.sh # Default path, change it if needed.
55 # 编包58 # 编包
56 python setup.py bdist_wheel59 python setup.py bdist_wheel
57 # 安装60 # 安装
@@ -69,6 +72,7 @@
69 # Default path, change it if needed.72 # Default path, change it if needed.
70 source /usr/local/Ascend/ascend-toolkit/set_env.sh73 source /usr/local/Ascend/ascend-toolkit/set_env.sh
71 ```74 ```
75+ 注:docker中运行使用dvpp功能,需要映射`/dev/dvpp_cmdlist`设备文件
72 76 
73## NPU 适配。77## NPU 适配。
74 78 
@@ -188,72 +192,18 @@
188 192 
1891. 脚本适配。1931. 脚本适配。
190 194 
191- 通过以下方式使能DVPP加速,在导入torchvision相关包后导入torchvision_npu包,在构造dataset前设置图像处理后端为npu:195+ 通过以下方式使能DVPP加速,在导入torchvision相关包后导入torchvision_npu包。
192- ```python196+```python
193 # 使能DVPP图像处理后端197 # 使能DVPP图像处理后端
194 ...198 ...
199+ import torch
200+ import torch_npu
195 import torchvision201 import torchvision
196 import torchvision_npu # 导入torchvision_npu包202 import torchvision_npu # 导入torchvision_npu包
197- import torchvision.datasets as datasets203+ 
198- ...
199 torchvision.set_image_backend('npu') # 设置图像处理后端为npu,即使能DVPP加速204 torchvision.set_image_backend('npu') # 设置图像处理后端为npu,即使能DVPP加速
200- ...205+ npu_input = torch.randint(0, 256, (4, 3, 480, 960), dtype=torch.uint8).npu()
201- train_dataset = torchvision.datasets.ImageFolder(...)206+ output = torchvision.transforms.functional.center_crop(npu_input, (100, 200))
202- ...
203- ```
204- 
205- 数据预处理多进程场景下,worker进程默认运行在主进程设置的device上(如无设置默认0)。
206- 可通过set_accelerate_npu接口设置worker进程的device,例如:
207- ``` python
208- # 设置worker进程的device_id
209- ...
210- train_dataset = torchvision.datasets.ImageFolder(...)
211- train_dataset.set_accelerate_npu(npu=1) # npu参数表示要设置的device_id
212- ...
213- ```
214- 
215- 部分网络脚本的ImageFolder中不包括ToTensor,DataLoader中collate_fn使用自定义的fast_collate,进行数据从PIL.Image.Imgae对象到torch.Tensor的转换。此时,使用DVPP加速需要关闭fast_collate使用默认的defualt_collate。
216- ```python
217- ''' 用户脚本中自定义的collate函数 '''
218- def fast_collate(batch):
219- imgs = [img[0] for img in batch]
220- targets = torch.tensor([target[1] for target in batch], dtype=torch.int64)
221- w = imgs[0].size[0]
222- h = imgs[0].size[1]
223- tensor = torch.zeros((len(imgs), 3, h, w), dtype=torch.uint8)
224- for i, img in enumerate(imgs):
225- nump_array = np.asarray(img, dtype=np.uint8)
226- if nump_array.ndim < 3:
227- nump_array = np.expand_dims(nump_array, axis=-1)
228- # 如果此处没有进行nump_array从(H, W, C)到(C, H, W)的转换,那么转换会放在训练中
229- nump_array = np.rollaxis(nump_array, 2)
230- tensor[i] += torch.from_numpy(nump_array)
231-
232- return tensor, targets
233- ...
234- train_loader = torch.utils.data.DataLoader(
235- train_dataset, batch_size=args.batch_size, shuffle=(train_sampler is None),
236- num_workers=args.workers, pin_memory=True, sampler=train_sampler,
237- # collate_fn=fast_collate, drop_last=True)
238- drop_last=True) # 使用collate_fn的默认defualt_collate
239- ...
240- if 'npu' in args.device:
241- # images = images.npu(non_blocking=True).permute(0, 3, 1, 2).to(torch.float).sub(mean).div(std)
242- # 如果轴转换放在训练中,使用DVPP加速时需要去掉
243- images = images.npu(non_blocking=True).to(torch.float).sub(mean).div(std)
244- target = target.npu(non_blocking=True)
245- ...
246- ```
247- 
248- 如果脚本中有多个dataset,希望一些dataset使用DVPP加速,一些使用原生处理,只需要在对应dataset构造前设置相应的处理后端,如:
249- ```python
250- ...
251- torchvision.set_image_backend('npu') # 设置dataset1的图像处理后端为npu
252- dataset1 = torchvision.datasets.ImageFolder(...)
253- ...
254- torchvision.set_image_backend('PIL') # 设置dataset2的图像处理后端为PIL
255- dataset2 = torchvision.datasets.ImageFolder(...)
256- ...
257 ```207 ```
258 208 
2592. 执行单元测试脚本。2092. 执行单元测试脚本。
@@ -270,17 +220,16 @@
270 220 
271 **表 2** DVPP支持功能列表221 **表 2** DVPP支持功能列表
272 222 
273- | datasets/transforms/io | functional | 处理结果是否和pillow完全一致 | 限制 |223+ | datasets/transforms/io | functional | 处理结果是否和社区接口一致 | 限制 |
274 |----------------------|------------------|--------------------|------------------------------ |224 |----------------------|------------------|--------------------|------------------------------ |
275- | default_loader | | √ | JPEG图像分辨率: 6x4~32768x32768 |225+ | default_loader | | 输出为NPU tensor,一般与to_tensor搭配使用 | JPEG图像分辨率: 6x4~32768x32768 |
276- | ToTensor | to_tensor | √ | 分辨率: 6x4~4096x8192 |226+ | ToTensor | to_tensor | 支持四维tensor输入,一般与default_loader搭配使用 | 分辨率: 6x4~4096x8192 |
277 | Normalize | normalize | √ | 分辨率: 6x4~4096x8192 |227 | Normalize | normalize | √ | 分辨率: 6x4~4096x8192 |
278- | Resize | resize | 底层实现有差异,误差±1左右 | 分辨率: 6x4~32768x32768<br>输出宽超过4096时输入宽高不能小于128x16 |
279 | CenterCrop<br>FiveCrop<br>TenCrop | crop | √ | 分辨率: 6x4~32768x32768 |228 | CenterCrop<br>FiveCrop<br>TenCrop | crop | √ | 分辨率: 6x4~32768x32768 |
280 | Pad | pad | √ | 分辨率: 6x4~32768x32768<br>填充宽度支持范围[0,2048] |229 | Pad | pad | √ | 分辨率: 6x4~32768x32768<br>填充宽度支持范围[0,2048] |
281 | RandomHorizontalFlip | hflip | √ | 分辨率: 6x4~4096x8192 |230 | RandomHorizontalFlip | hflip | √ | 分辨率: 6x4~4096x8192 |
282 | RandomVerticalFlip | vflip | √ | 分辨率: 6x4~4096x8192 |231 | RandomVerticalFlip | vflip | √ | 分辨率: 6x4~4096x8192 |
283- | RandomResizedCrop<br>RandomSizedCrop | resized_crop | 底层实现有差异,误差±1左右 | 分辨率: 6x4~32768x32768<br>输出宽超过4096时输入宽高不能小于128x16 |232+ | RandomResizedCrop<br>RandomSizedCrop | resized_crop | BILINEAR和BICUBIC: 误差+1左右。其他插值模式无法对标 | 分辨率: 6x4~32768x32768<br>输出宽超过4096时输入宽高不能小于128x16 |
284 | ColorJitter | adjust_hue | 底层实现有差异,误差±1左右 | 分辨率: 6x4~4096x8192 |233 | ColorJitter | adjust_hue | 底层实现有差异,误差±1左右 | 分辨率: 6x4~4096x8192 |
285 | ColorJitter | adjust_contrast | 底层实现有差异,factor在[0,1]时误差±1 | 分辨率: 6x4~4096x8192 |234 | ColorJitter | adjust_contrast | 底层实现有差异,factor在[0,1]时误差±1 | 分辨率: 6x4~4096x8192 |
286 | ColorJitter | adjust_brightness| 底层实现有差异,误差±1左右 | 分辨率: 6x4~4096x8192 |235 | ColorJitter | adjust_brightness| 底层实现有差异,误差±1左右 | 分辨率: 6x4~4096x8192 |
@@ -289,19 +238,12 @@
289 | RandomAffine | affine | 底层实现有差异 | 分辨率: 6x4~32768x32768 |238 | RandomAffine | affine | 底层实现有差异 | 分辨率: 6x4~32768x32768 |
290 | RandomPerspective | perspective | 底层实现有差异 | 分辨率: 6x4~4096x8192 |239 | RandomPerspective | perspective | 底层实现有差异 | 分辨率: 6x4~4096x8192 |
291 | RandomRotation | rotate | 底层实现有差异 | 分辨率: 6x4~32768x32768 |240 | RandomRotation | rotate | 底层实现有差异 | 分辨率: 6x4~32768x32768 |
292- | Grayscale<br>RandomGrayscale | rgb_to_grayscale | √ | 分辨率: 6x4~4096x8192 |241+ | Grayscale<br>RandomGrayscale | rgb_to_grayscale | float误差±1/255, uint8误差±1 | 分辨率: 6x4~4096x8192 |
293 | RandomPosterize | posterize | √ | 分辨率: 6x4~4096x8192 |242 | RandomPosterize | posterize | √ | 分辨率: 6x4~4096x8192 |
294- | RandomSolarize | solarize | √ | 分辨率: 6x4~4096x8192 |243+ | RandomSolarize | solarize | float误差在±0.1,uint对标 | 分辨率: 6x4~4096x8192 |
295 | RandomInvert | invert | √ | 分辨率: 6x4~4096x8192 |244 | RandomInvert | invert | √ | 分辨率: 6x4~4096x8192 |
296 | encode_jpeg | | | 分辨率: 32x32~8192x8192<br>输出宽高需要2对齐 |245 | encode_jpeg | | | 分辨率: 32x32~8192x8192<br>输出宽高需要2对齐 |
297 246 
298-4. 说明。
299- 
300- 只有通过torchvision.datasets.ImageFolder/DatasetFolder构造的dataset才可以使能DVPP加速。
301- 
302- torchvision.transforms方法对外接口不变,只支持NCHW(N=1)格式的npu tensor作为入参,其他限制见表2。
303- 
304- 物理机场景下,一个device上最多支持64个用户进程,即单p数据预处理进程数最多设置63。
305 247 
306## 使用DVPP视频处理后端248## 使用DVPP视频处理后端
307 249 
@@ -357,6 +299,13 @@
357 | roi_align | √ |299 | roi_align | √ |
358 | roi_pool | √ |300 | roi_pool | √ |
359 301 
302+# 版本配套表
303+ 
304+|Torchvision Adapter分支 |Torchvision Adapter Tag | PyTorch版本 | PyTorch Extension版本 |Torchvision版本 | 驱动版本 | CANN版本|
305+| -----------------------|----------------------- | ------------- | ------------------------ | ------------- | -----| ---------|
306+| master | v0.16.0-6.0.rc2 | 2.1.0 | 2.1.0.post6 | 0.16.0 | Ascend HDK 24.1.RC2 | CANN 8.0.RC2|
307+| v0.12.0-dev | v0.12.0-6.0.rc2 | 1.11.0 | 1.11.0.post14 | 0.12.0 | Ascend HDK 24.1.RC2 | CANN 8.0.RC2|
308+ 
360**Torchvision Adapter适配NPU的方案见[适配指导](docs/适配指导.md)。**309**Torchvision Adapter适配NPU的方案见[适配指导](docs/适配指导.md)。**
361 310 
362# 安全声明311# 安全声明
@@ -0,0 +1,24 @@
1+import torch
2+import torch_npu
3+from torch_npu.testing.testcase import TestCase, run_tests
4+import torchvision
5+import torchvision_npu
6+ 
7+ 
8+class TestDefaultLoader(TestCase):
9+ 
10+ def test_default_loader(self):
11+ path = "../Data/dog/dog.0001.jpg"
12+ torchvision.set_image_backend('PIL')
13+ img_output = torchvision.datasets.folder.default_loader(path)
14+ cpu_output = torchvision.transforms.functional.to_tensor(img_output)
15+ 
16+ torchvision.set_image_backend('npu')
17+ npu_output = torchvision.datasets.folder.default_loader(path)
18+ npu_output = torchvision.transforms.functional.to_tensor(npu_output).squeeze(0)
19+ 
20+ self.assertEqual(cpu_output, npu_output)
21+ 
22+ 
23+if __name__ == '__main__':
24+ run_tests()
@@ -40,6 +40,7 @@ def add_datasets_folder():
40 torchvision.__name__ = 'torchvision_npu'40 torchvision.__name__ = 'torchvision_npu'
41 torchvision.datasets.DatasetFolder = DatasetFolder41 torchvision.datasets.DatasetFolder = DatasetFolder
42 torchvision.datasets.ImageFolder = ImageFolder42 torchvision.datasets.ImageFolder = ImageFolder
43+ torchvision.datasets.folder.default_loader = default_loader
43 44 
44 45 
45def _assert_image_3d(img: torch.Tensor):46def _assert_image_3d(img: torch.Tensor):