5.4. sail.Tensor
Tensor是模型推理的输入输出类型,包含了数据信息,实现内存管理。
5.4.1. __init__
初始化Tensor,并为Tensor分配内存,如果需要进行系统内存和设备内存的同步,需要执行sync_d2s或sync_s2d
- 接口形式1:
- def __init__(self, handle: Handle, data: np.array, own_sys_data=True) 
参数说明1:
- handle: sail.Handle 
设备标识Handle
- array_data: numpy.array 
利用numpy.array类型初始化Tensor,其数据类型可以是np.float32,np.int8,np.uint8
- own_sys_data: bool 
指示该Tensor是否拥有system memory,如果为False,则直接将数据复制到device memory
- 接口形式2
- def __init__(self, handle: Handle, shape: list[int], dtype: Dtype, own_sys_data: bool, own_dev_data: bool) 
参数说明2:
- handle: sail.Handle 
设备标识Handle
- shape: tuple 
设置Tensor的shape
- dtype: sail.Dtype 
Tensor的数据类型
- own_sys_data: bool 
指示Tensor是否拥有system memory
- own_dev_data: bool 
指示Tensor是否拥有device memory
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = np.array([1, 2, 3]) input_tensor1 = sail.Tensor(handle,input) input_tensor2 = sail.Tensor(handle,[1,2],sail.Dtype.BM_FLOAT32,true,true) 
接口形式3
该初始化方式在一个已存在的源Tensor的基础上创建新Tensor,并复用源Tensor的一部分设备内存,不发生设备内存的数据拷贝。适合LLM推理等复用内存的场景。
在使用该Tensor的过程中,需要保证源Tensor不被释放。
def __init__(self, src: Tensor, shape: list[int], offset: int)
参数说明3:
- src: sail.Tensor 
创建Tensor所使用的源Tensor
- shape: list[int] 
创建Tensor的shape,类型为int的序列。需要保证新shape对应的元素个数不超过src的元素个数
- offset: int 
Tensor的设备内存相对于src的设备内存的偏移量,单位为dtype的字节数
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) height = 1080 width = 1920 data_type = sail.Dtype.BM_INT32 src_shape = [1, 3, height, width] src_tensor = sail.Tensor(handle, src_shape, data_type, False, True) dst_shape = [1, 1, height, width] offset = height * width dst_tensor = sail.Tensor(src_tensor, dst_shape, offset) 
5.4.2. shape
获取Tensor的shape
- 接口形式:
- def shape(self) -> list : 
返回值说明:
- tensor_shape : list 
返回Tensor的shape的列表。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = np.array([1, 2, 3]) input_tensor1 = sail.Tensor(handle,input) print(input_tensor1.shape()) 
5.4.3. dtype
获取Tensor的数据类型
- 接口形式:
- def dtype(self) -> sail.Dtype : 
返回值说明:
- data_type : sail.Dtype 
返回Tensor的数据类型。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = np.array([1, 2, 3]) input_tensor1 = sail.Tensor(handle,input) print(input_tensor1.dtype()) 
5.4.4. asnumpy
获取Tensor中系统内存的数据,返回numpy.array类型。如果需要进行系统内存和设备内存的同步,需要执行sync_d2s。
- 接口形式:
- def asnumpy(self) -> numpy.array def asnumpy(self, shape: tuple) -> numpy.array 
参数说明:
- shape: tuple 
可对Tensor中的数据reshape,返回形状为shape的numpy.array
返回值说明
返回Tensor中系统内存的数据,返回类型为numpy.array。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = np.array([1, 2, 3]) input_tensor1 = sail.Tensor(handle,input) input_ = input_tensor1.asnumpy() input__ = input_tensor1.asnumpy((3,1)) 
5.4.5. update_data
更新Tensor中系统内存的数据,如果没有分配系统内存,则更新设备内存中的数据。
- 接口形式:
- def update_data(self, data: numpy.array) -> None 
参数说明:
- data: numpy.array 
更新的数据,数据类型应和Tensor一致,数据size不能超过Tensor的size,Tensor的shape将保持不变。
注:如果是numpy.float16类型的数据,应使用numpy.view(numpy.uint16)再传递给本接口。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': dev_id = 0 handle = sail.Handle(dev_id) tensor_fp32 = sail.Tensor(handle, [1,3,640,640], sail.BM_FLOAT32, True, True) np_fp32 = np.ones(tensor_fp32.shape(),dtype=np.float32) tensor_fp32.update_data(np_fp32) tensor_fp16 = sail.Tensor(handle, [1,3,640,640], sail.BM_FLOAT16, True, True) np_fp16 = np.ones(tensor_fp16.shape(),dtype=np.float16) tensor_fp16.update_data(np_fp16.view(np.uint16)) 
5.4.6. scale_from
先对data按比例缩放,再将数据更新到Tensor的系统内存。
- 接口形式:
- def scale_from(self, data: numpy.array, scale: float32)->None 
参数说明:
- data: numpy.array 
对data进行scale,再将数据更新到Tensor的系统内存。
- scale: float32 
等比例缩放时的尺度。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = np.array([1, 2, 3]) input_tensor1 = sail.Tensor(handle,input) input_tensor1.scale_from(input,0.1) 
5.4.7. scale_to
先对Tensor进行等比例缩放,再将数据返回到系统内存。
- 接口形式:
- def scale_to(self, scale: float32)->numpy.array def scale_to(self, scale: float32, shape: tuple)->numpy.array 
参数说明:
- scale: float32 
等比例缩放时的尺度。
- shape: tuple 
数据返回前可进行reshape,返回shape形状的数据。
返回值说明:
- data: numpy.array 
将处理后的数据返回至系统内存,返回numpy.array
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = np.array([1, 2, 3]) input_tensor1 = sail.Tensor(handle,input) input_tensor1_ = input_tensor1.scale_to(0.1) input_tensor1__ = input_tensor1.scale_to(0.1,(3,1)) 
5.4.8. reshape
对Tensor进行reshape
- 接口形式:
- def reshape(self, shape: list)->None 
参数说明:
- shape: list 
设置期望得到的新shape。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = np.array([1, 2, 3]) input_tensor1 = sail.Tensor(handle,input) input_tensor1_ = input_tensor1.reshape([3,1]) 
5.4.9. own_sys_data
查询该Tensor是否拥有系统内存的数据指针。
- 接口形式:
- def own_sys_data(self)->bool 
返回值说明:
- judge_ret: bool 
如果拥有系统内存的数据指针则返回True,否则False。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = np.array([1, 2, 3]) input_tensor1 = sail.Tensor(handle,input) print(input_tensor1.own_sys_data()) 
5.4.10. own_dev_data
查询该Tensor是否拥有设备内存的数据
- 接口形式:
- def own_dev_data(self)->bool 
返回值说明:
- judge_ret : bool 
如果拥有设备内存中的数据则返回True,否则False。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = np.array([1, 2, 3]) input_tensor1 = sail.Tensor(handle,input) print(input_tensor1.own_dev_data()) 
5.4.11. sync_s2d
将Tensor中的数据从系统内存拷贝到设备内存。
- 接口形式:
- def sync_s2d(self)->None def sync_s2d(self, size)->None 
参数说明:
- size: int 
将特定size字节的数据从系统内存拷贝到设备内存。
- 接口形式:
- def sync_s2d(self, src: sail.Tensor, offset_src: int, offset_dst: int, len: int)->None 
参数说明:
- src: sail.Tensor 
指定被拷贝的Tensor。
- offset_src: int 
指定被拷贝Tensor上的数据偏移几个元素后开始拷贝。
- offset_dst: int 
指定拷贝目标Tensor上的数据偏移几个元素后开始拷贝。
- len: int 
指定拷贝长度,既拷贝的元素个数。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = np.array([1, 2, 3]) input_tensor1 = sail.Tensor(handle,input) input_tensor2 = sail.Tensor(handle,[1,2], sail.Dtype.BM_FLOAT32, True, True) input_tensor2.sync_s2d() input_tensor2.sync_s2d(1) input_tensor2.sync_s2d(input_tensor1,0,0,2) 
5.4.12. sync_d2s
将Tensor中的数据从设备内存拷贝到系统内存。
- 接口形式:
- def sync_d2s(self)->None def sync_d2s(self, size: int)->None 
参数说明:
- size: int 
将特定size字节的数据从设备内存拷贝到系统内存。
- 接口形式:
- def sync_d2s(self, src: sail.Tensor, offset_src: int, offset_dst: int, len: int)->None 
参数说明:
- src: sail.Tensor 
指定被拷贝的Tensor。
- offset_src: int 
指定被拷贝Tensor上的数据偏移几个元素后开始拷贝。
- offset_dst: int 
指定拷贝目标Tensor上的数据偏移几个元素后开始拷贝。
- len: int 
指定拷贝长度,既拷贝的元素个数。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input_tensor1 = sail.Tensor(handle,[1,3],sail.Dtype.BM_FLOAT32,False,True) input_tensor2 = sail.Tensor(handle,[1,3],sail.Dtype.BM_FLOAT32,True,True) input_tensor1.ones() input_tensor2.sync_d2s() input_tensor2.sync_d2s(2) input_tensor2.sync_d2s(input_tensor1,0,0,2) 
5.4.13. sync_d2d
将另外一个Tensor设备内存上的数据拷贝到本Tensor的设备内存中。
- 接口形式:
- def sync_d2d(self, src: sail.Tensor, offset_src: int, offset_dst: int, len: int)->None 
参数说明:
- src: sail.Tensor 
指定被拷贝的Tensor。
- offset_src: int 
指定被拷贝Tensor上的数据偏移几个元素后开始拷贝。
- offset_dst: int 
指定拷贝目标Tensor上的数据偏移几个元素后开始拷贝。
- len: int 
指定拷贝长度,既拷贝的元素个数。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) handle_ = sail.Handle(1) input_tensor1 = sail.Tensor(handle,[1,3],sail.Dtype.BM_FLOAT32,False,True) input_tensor2 = sail.Tensor(handle_,[1,3],sail.Dtype.BM_FLOAT32,True,True) input_tensor1.ones() input_tensor2.sync_d2d(input_tensor1,0,0,2) 
5.4.14. sync_d2d_stride
以stride的方式将另外一个Tensor设备内存上的数据拷贝到本Tensor的设备内存中。
- 接口形式:
- def sync_d2d_stride(self, src: sail.Tensor, stride_src: int, stride_dst: int, count: int)->None 
参数说明:
- src: sail.Tensor 
指定被拷贝的Tensor。
- stride_src: int 
指定被拷贝Tensor上数据的stride。
- stride_dst: int 
指定拷贝目标Tensor上数据的stride。stride_dst必须是1,除了stride_dst为4且stride_src为1且tensor数据类型大小为1字节的情况。
- count: int 
指定拷贝长度,既拷贝的元素个数。需要保证count * stride_src <= tensor_src_size, count * stride_dst <= tensor_dst_size。
5.4.15. dump_data
将Tensor中的数据写入到指定文件中,如果需要进行系统内存和设备内存的同步,需要执行sync_d2s
- 接口形式:
- def dump_data(file_name: str, bin: bool = False) 
参数说明:
- file_name: str 
写入文件的路径
- bin: bool 
是否采用二进制的形式存储Tensor,默认false.
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': dev_id = 0 handle = sail.Handle(dev_id) data = np.ones([1,20], dtype=int) ts = sail.Tensor(handle, data) ts.scale_from(data, 0.1) ts.dump_data("./temp.txt") ret_data = np.loadtxt("./temp.txt") print(ts.asnumpy(), ret_data) 
5.4.16. memory_set
将本Tensor的数据全部置为c,在接口内部根据本Tensor的dtype对c做相应的类型转换。
- 接口形式:
- def memory_set(self, c: any)->None 
参数说明:
- c: any 
需要填充的值。
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input = 1 input_tensor1 = sail.Tensor(handle,[1],sail.Dtype.BM_FLOAT32,True,True) input_tensor1.memory_set(input) 
5.4.17. zeros
将本Tensor的数据全部置为0。
- 接口形式:
- def zeros(self)->None 
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input_tensor1 = sail.Tensor(handle,(1,3),sail.Dtype.BM_FLOAT32,False,True) input_tensor1.zeros() 
5.4.18. ones
将本Tensor的数据全部置为1。
- 接口形式:
- def ones(self)->None 
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input_tensor1 = sail.Tensor(handle,(1,3),sail.Dtype.BM_FLOAT32,False,True) input_tensor1.ones() 
5.4.19. size
返回Tensor包含的元素数量。
- 接口形式:
- def size(self)->int 
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input_tensor1 = sail.Tensor(handle,(1,3),sail.Dtype.BM_FLOAT32,False,True) print(input_tensor1.size()) 
5.4.20. element_size
返回Tensor中单个元素占用的字节数。
- 接口形式:
- def element_size(self)->int 
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input_tensor1 = sail.Tensor(handle,(1,3),sail.Dtype.BM_FLOAT32,False,True) print(input_tensor1.element_size()) 
5.4.21. nbytes
返回Tensor中所有元素占用的总字节数。
- 接口形式:
- def nbytes(self)->int 
- 示例代码:
- import sophon.sail as sail import numpy as np if __name__ == '__main__': handle = sail.Handle(0) input_tensor1 = sail.Tensor(handle,(1,3),sail.Dtype.BM_FLOAT32,False,True) print(input_tensor1.nbytes())