defunbroadcast(grad, target_shape): # 如果形狀已經完美匹配,直接返回 if grad.shape == target_shape: return grad # 情況一:處理由於廣播而新增的前置維度(例如標量與矩陣運算) ndims_added = grad.ndim - len(target_shape) for _ inrange(ndims_added): grad = grad.sum(axis=0) # 情況二:處理被擴展的維度(原本大小為 1 的維度被擴展成了 N) for i, dim inenumerate(target_shape): if dim == 1: # 沿著被擴展的維度進行求和降維,並保持維度結構 grad = grad.sum(axis=i, keepdims=True) return grad
这个里头比较典型的案例,一个是 Sun 收购了 OpenOffice。Sun 当时收购了很多的这种开源项目,收完了以后说这东西只有我能使,别人不能使了。后来他们就去分叉了,分叉成叫 LibreOffice,但是这两个项目发展的也都不怎么样。还有一个特别典型的案例叫 MySQL,它是被 Oracle 收购了。收购完了以后说:“我们对它进行各种限制,你们以后就少用这玩意,都上我这来买 Oracle 数据库来。”他们后来也是分叉的,一个 m 开头的一个数据库的名字,跟 MySQL 完全兼容的,但是后面我觉得发展的也都不是很好吧。就是你一旦收购回来以后说我要管你了,这就翻车了。
在 fairseq 中,集束搜索返回输出 token 的数量是集束数量的两倍。这是由于集束搜索中的部分集束可能会返回表示句子结束的 EOS token,而我们不想要集束搜索太早就停止。当 EOS token 出现在结果的前半部分时,可以将预测总分与其他已有结果的分数相比较从而完成句子。下图展示了相关代码并附上了一些注释,希望能有助读者理解。
{caption}(a)返回表示集束中具有 EOS token 的掩码;(b)具有 EOS token 集束对应的索引,只有在 EOS 出现在前半部分的情况下(:beam_size)。注意集束搜索返回 2 * beam_size 个结果;(c)对于前 beam_size 个具有 EOS 的集束,组合预测结果并判断是否完成句子。如果是,减少剩余句子的数量,注意我们处理的是一整个 batch 的输入句子;(d)如果剩余句子的数量是 0,完成;(e)如果能够完成一整个 batch 的目标句子,从 batch 中移除元素并调整 batch 索引。{end caption}
torch.version # PyTorch version torch.cuda.is_available() torch.version.cuda # Corresponding CUDA version torch.backends.cudnn.version() # Corresponding cuDNN version torch.cuda.get_device_name(0) # GPU type
// 数据类型, 参见 https://pytorch.org/cppdocs/api/file_torch_csrc_api_include_torch_types.h.html#variables bar = foo.to(torch::kF16); bar = foo.to(torch::kF32); bar = foo.to(torch::kF64); bar = foo.to(torch::kFloat16); bar = foo.to(torch::kFloat32); bar = foo.to(torch::kFloat64); bar = foo.to(torch::kI8); bar = foo.to(torch::kI16); bar = foo.to(torch::kI32); bar = foo.to(torch::kI64); bar = foo.to(torch::kInt8); bar = foo.to(torch::kInt16); bar = foo.to(torch::kInt32); bar = foo.to(torch::kInt64); bar = foo.to(torch::kU8); bar = foo.to(torch::kUInt8);
auto foo = torch::randn({3, 3}); auto bar = foo.to(torch::kMPS);
编译是没有问题的,但运行时会报下面的错:
libc++abi: terminating with uncaught exception of type c10::TypeError: Cannot convert a MPS Tensor to float64 dtype as the MPS framework doesn’t support float64. Please use float32 instead.
// 变形操作 bar = foo.reshape({2, -1}); bar = foo.flatten(); bar = foo.squeeze(); bar = foo.unsqueeze(0); bar = torch::unsqueeze(foo, -1); bar = foo.transpose(0, 1).transpose(2, 3).transpose(3, 1); bar = torch::transpose(foo, 0, 1); bar = torch::cat({foo, foo}, 2);