pytorch每日一学15(torch.as_strided())根据步长创建一个现有tensor的视图

本文详细介绍了PyTorch中的torch.as_strided函数,该函数用于创建Tensor的视图,不占用额外内存。内容包括视图的概念、参数解释如size和stride的用法,以及storage_offset对行偏移的影响。通过实例展示了如何通过改变步长控制输出Tensor的元素排列。文章强调了视图与原始Tensor之间的关联性,更改视图会影响原始数据,建议谨慎修改视图数据,若需独立副本可使用Tensor.clone()。最后提醒,虽然torch.as_strided提供直接操作,但推荐使用更易读的PyTorch内置方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第15个方法

torch.as_strided(input, size, stride, storage_offset=0)>Tensor
  • 此方法是根据现有tensor以及给定的步长来创建一个视图(类型仍然为tensor)。
视图

  视图是指创建一个方便查看的东西,与原数据共享内存,它并不占用内存,也不存储数据,只是将原有的数据进行整理,显示其中部分内容或者进行重排序后显示出来等等。

接下来介绍此方法,首先看一个示例:
在这里插入图片描述
这样创建出来的b就是a的一个视图,可以发现,b中的元素都是a中的元素,所以其实b中并不存储数据,它只是显示a中的数据如果改变a中的数据的话,b中的数据也会改变,反之亦然。

接下来介绍各个参数:

  • input:此参数指定了在哪个数据上创建视图,input需为tensor。
  • size:指定了生成的视图的大小,需要为一个矩阵(当然此矩阵大小可以大于原矩阵,但是也有限制),可以是tensor或者list等等。
  • stride:输出tensor的步长,根据原矩阵和步长生成了新矩阵,此参数后面会细讲。
  • storage_offset:输出张量的基础存储中的偏移量。

参数的使用
还是用上面的例子,我们使用stride=(0, 0)
在这里插入图片描述

  • 可以看到在没有偏移的情况下,b的数据都是a中的第一个数据,说明了(0,0)不进行偏移,这很好理解。将(0, 0)改为(0,1)后
    在这里插入图片描述
  • 第一行与第二行的元素相等,而每列的元素不同,并且在tensor上从0,1,2开始一次增加一个,这说明第二个元素控制列,而改为(1, 0)得到如下结果
    在这里插入图片描述
  • 这次是每列元素相等,而行不等,说明第一个参数控制行。这就可以理解了,第一个元素控制行,数字代表每次向后走时的跨度,而第二个控制列,如果改成(1, 1)

在这里插入图片描述

  • 发现第二个参数控制的列,每次的开始值不是从原tensor的第0的数开始的,而是从生成视图中每行的第一个数据开始的,然后开始增加, 改为(1, 2)后
    在这里插入图片描述
  • 这说明了,我们stride增加是将整个tensor排成一维数据一直增加的,如果此行数字不够会从下一行继续寻找。


    总结 :stride是指定步长,其中行从原数据第0个数据开始,而列从视图中行的第0个数据开始。将整个数组整合为1维数组后按步长进行寻找。

注意:由于创建出来的是视图,所以更改其中任何一个都会更改另一个,可能会产生意想不到的效果。例如:
在这里插入图片描述

  • 更改a[0, 1]=0,由于b[0, 1]和b[1, 0]都来自a[0, 1]所以这俩也都会改变,反之亦然,有对应关系的都会改变,因为它们来自同一数据区,所以更改数据可能会出现一些意想不到的结果,不建议更改数据,尤其是视图数据。如果你实在需要更改的话,考虑将其克隆,使用Tensor.clone(),这样的话原数据和创建数据就不共享存储区了。

  storage_offset就比较简单了,我们的列是从视图的每行第0个元素开始的,也就是可以控制的,那行应该也可以控制吧,所以storage_offset这个参数就是用来控制行的,默认为0,指定后行从第storage_offset个元素开始。
在这里插入图片描述

  • 许多pytorch函数都可以返回视图,并且在此函数的内部实现,这些方法,例如(torch.Tensor.expand)更容易阅读,所以更推荐使用这些方法。
""" Inference benchmarking tool. Requirements: transformers accelerate bitsandbytes optimum-benchmark Usage: python inference_benchmark.py model_id options: -h, --help show this help message and exit --configs {bf16,fp16,nf4,nf4-dq,int8,int8-decomp} [{bf16,fp16,nf4,nf4-dq,int8,int8-decomp} ...] --bf16 --fp16 --nf4 --nf4-dq --int8 --int8-decomp --batches BATCHES [BATCHES ...] --input-length INPUT_LENGTH --out-dir OUT_DIR """ import argparse from pathlib import Path from optimum_benchmark import Benchmark, BenchmarkConfig, InferenceConfig, ProcessConfig, PyTorchConfig from optimum_benchmark.logging_utils import setup_logging import torch,torch_npu from torch_npu.contrib import transfer_to_npu BFLOAT16_SUPPORT = torch.cuda.get_device_capability()[0] >= 8 WEIGHTS_CONFIGS = { "fp16": {"torch_dtype": "float16", "quantization_scheme": None, "quantization_config": {}}, "bf16": {"torch_dtype": "bfloat16", "quantization_scheme": None, "quantization_config": {}}, "nf4": { "torch_dtype": "bfloat16" if BFLOAT16_SUPPORT else "float16", "quantization_scheme": "bnb", "quantization_config": { "load_in_4bit": True, "bnb_4bit_quant_type": "nf4", "bnb_4bit_use_double_quant": False, "bnb_4bit_compute_dtype": torch.bfloat16 if BFLOAT16_SUPPORT else "float16", }, }, "nf4-dq": { "torch_dtype": "bfloat16" if BFLOAT16_SUPPORT else "float16", "quantization_scheme": "bnb", "quantization_config": { "load_in_4bit": True, "bnb_4bit_quant_type": "nf4", "bnb_4bit_use_double_quant": True, "bnb_4bit_compute_dtype": torch.bfloat16 if BFLOAT16_SUPPORT else "float16", }, }, "int8-decomp": { "torch_dtype": "float16", "quantization_scheme": "bnb", "quantization_config": { "load_in_8bit": True, "llm_int8_threshold": 6.0, }, }, "int8": { "torch_dtype": "float16", "quantization_scheme": "bnb", "quantization_config": { "load_in_8bit": True, "llm_int8_threshold": 0.0, }, }, } if __name__ == "__main__": setup_logging(level="INFO") parser = argparse.ArgumentParser(description="bitsandbytes inference benchmark tool") parser.add_argument("model_id", type=str, help="The model checkpoint to use.") parser.add_argument( "--configs", nargs="+", choices=["bf16", "fp16", "nf4", "nf4-dq", "int8", "int8-decomp"], default=["nf4", "int8", "int8-decomp"], ) parser.add_argument("--bf16", dest="configs", action="append_const", const="bf16") parser.add_argument("--fp16", dest="configs", action="append_const", const="fp16") parser.add_argument("--nf4", dest="configs", action="append_const", const="nf4") parser.add_argument("--nf4-dq", dest="configs", action="append_const", const="nf4-dq") parser.add_argument("--int8", dest="configs", action="append_const", const="int8") parser.add_argument("--int8-decomp", dest="configs", action="append_const", const="int8-decomp") parser.add_argument("--batches", nargs="+", type=int, default=[1, 8, 16, 32]) parser.add_argument("--input-length", type=int, default=64) parser.add_argument("--out-dir", type=str, default="reports") args = parser.parse_args() out_dir = Path(args.out_dir) out_dir.mkdir(parents=True, exist_ok=True) for batch_size in args.batches: print(f"Benchmarking batch size: {batch_size}") for config in args.configs: launcher_config = ProcessConfig(device_isolation=True, start_method="spawn") scenario_config = InferenceConfig( latency=True, memory=True, input_shapes={"batch_size": batch_size, "sequence_length": args.input_length}, ) backend_config = PyTorchConfig( device_map={"":0}, no_weights=False, model=args.model_id, trust_remote_code=True, **WEIGHTS_CONFIGS[config], ) benchmark_config = BenchmarkConfig( name=f"benchmark-{config}-bsz{batch_size}", scenario=scenario_config, launcher=launcher_config, backend=backend_config, ) out_path = out_dir / f"benchmark_{config}_bsz{batch_size}.json" benchmark_report = Benchmark.launch(benchmark_config) benchmark_report.log() benchmark_report.save_json(out_path) ''' python inference_benchmark.py "/models/z50051264/summary/Qwen2.5-7B-nf4" \ --configs bf16 nf4 \ --batches 1 4 8 \ --input-length 128 \ --out-dir ./qwen2.5_nf4_reports ''' 我使用的是npu [root@190f3c453709 benchmarking]# python inference_benchmark.py "/models/z50051264/summary/Qwen2.5-7B-nf4" --configs bf16 nf4 --batches 1 4 8 --input-length 128 --out-dir ./qwen2.5_nf4_reports /usr/local/python3.10.17/lib/python3.10/site-packages/torch_npu/contrib/transfer_to_npu.py:292: ImportWarning: ************************************************************************************************************* The torch.Tensor.cuda and torch.nn.Module.cuda are replaced with torch.Tensor.npu and torch.nn.Module.npu now.. The torch.cuda.DoubleTensor is replaced with torch.npu.FloatTensor cause the double type is not supported now.. The backend in torch.distributed.init_process_group set to hccl now.. The torch.cuda.* and torch.cuda.amp.* are replaced with torch.npu.* and torch.npu.amp.* now.. The device parameters have been replaced with npu in the function below: torch.logspace, torch.randint, torch.hann_window, torch.rand, torch.full_like, torch.ones_like, torch.rand_like, torch.randperm, torch.arange, torch.frombuffer, torch.normal, torch._empty_per_channel_affine_quantized, torch.empty_strided, torch.empty_like, torch.scalar_tensor, torch.tril_indices, torch.bartlett_window, torch.ones, torch.sparse_coo_tensor, torch.randn, torch.kaiser_window, torch.tensor, torch.triu_indices, torch.as_tensor, torch.zeros, torch.randint_like, torch.full, torch.eye, torch._sparse_csr_tensor_unsafe, torch.empty, torch._sparse_coo_tensor_unsafe, torch.blackman_window, torch.zeros_like, torch.range, torch.sparse_csr_tensor, torch.randn_like, torch.from_file, torch._cudnn_init_dropout_state, torch._empty_affine_quantized, torch.linspace, torch.hamming_window, torch.empty_quantized, torch._pin_memory, torch.autocast, torch.load, torch.Generator, torch.set_default_device, torch.Tensor.new_empty, torch.Tensor.new_empty_strided, torch.Tensor.new_full, torch.Tensor.new_ones, torch.Tensor.new_tensor, torch.Tensor.new_zeros, torch.Tensor.to, torch.Tensor.pin_memory, torch.nn.Module.to, torch.nn.Module.to_empty ************************************************************************************************************* warnings.warn(msg, ImportWarning) /usr/local/python3.10.17/lib/python3.10/site-packages/torch_npu/contrib/transfer_to_npu.py:247: RuntimeWarning: torch.jit.script and torch.jit.script_method will be disabled by transfer_to_npu, which currently does not support them, if you need to enable them, please do not use transfer_to_npu. warnings.warn(msg, RuntimeWarning) /usr/local/python3.10.17/lib/python3.10/site-packages/torch_npu/npu/utils.py:118: UserWarning: torch.npu.get_device_capability isn't implemented! warnings.warn("torch.npu.get_device_capability isn't implemented!") Traceback (most recent call last): File "/models/z50051264/bitsandbytes-main/benchmarking/inference_benchmark.py", line 35, in <module> BFLOAT16_SUPPORT = torch.cuda.get_device_capability()[0] >= 8 TypeError: 'NoneType' object is not subscriptable [ERROR] 2025-07-28-02:31:16 (PID:668, Device:-1, RankID:-1) ERR99999 UNKNOWN applicaiton exception /usr/local/python3.10.17/lib/python3.10/tempfile.py:869: ResourceWarning: Implicitly cleaning up <TemporaryDirectory '/tmp/tmpv19_pa_6'> _warnings.warn(warn_message, ResourceWarning)
最新发布
07-29
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值