From 0690dc9d99e0f5a264be77f01cbf9cf367d7cfd4 Mon Sep 17 00:00:00 2001 From: Arash Ashari Date: Tue, 4 Aug 2020 10:20:46 -0700 Subject: [PATCH 01/16] Sparse Transformer: adding codes related to ST (#58) * Sparse Transformer: adding codes related to ST * updating dependency version of Triton * applying comments * updating triton dependecny to new version * applied comments * small change --- csrc/sparse_transformer/utils.cpp | 165 ++++ deepspeed/pt/sparse_transformer/__init__.py | 5 + .../bert_sparse_self_attention.py | 79 ++ deepspeed/pt/sparse_transformer/matmul.py | 725 ++++++++++++++++++ deepspeed/pt/sparse_transformer/softmax.py | 290 +++++++ .../sparse_self_attention.py | 330 ++++++++ deepspeed/pt/sparse_transformer/utils.py | 136 ++++ deepspeed/trsrc/__init__.py | 33 + deepspeed/trsrc/sparse_transformer/matmul.tr | 201 +++++ .../trsrc/sparse_transformer/softmax_bwd.tr | 54 ++ .../trsrc/sparse_transformer/softmax_fwd.tr | 135 ++++ requirements.txt | 1 + setup.py | 7 +- 13 files changed, 2160 insertions(+), 1 deletion(-) create mode 100644 csrc/sparse_transformer/utils.cpp create mode 100644 deepspeed/pt/sparse_transformer/__init__.py create mode 100755 deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py create mode 100644 deepspeed/pt/sparse_transformer/matmul.py create mode 100644 deepspeed/pt/sparse_transformer/softmax.py create mode 100644 deepspeed/pt/sparse_transformer/sparse_self_attention.py create mode 100644 deepspeed/pt/sparse_transformer/utils.py create mode 100644 deepspeed/trsrc/__init__.py create mode 100644 deepspeed/trsrc/sparse_transformer/matmul.tr create mode 100644 deepspeed/trsrc/sparse_transformer/softmax_bwd.tr create mode 100644 deepspeed/trsrc/sparse_transformer/softmax_fwd.tr diff --git a/csrc/sparse_transformer/utils.cpp b/csrc/sparse_transformer/utils.cpp new file mode 100644 index 000000000000..7e717596aa20 --- /dev/null +++ b/csrc/sparse_transformer/utils.cpp @@ -0,0 +1,165 @@ +// DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +// https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py +// https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/attention.py + +#include +#include +#include +#include +#ifdef _OPENMP +#include +#endif + +typedef std::vector> ret_t; + +void segment_blocks(torch::Tensor layout, + torch::Tensor idx, + torch::Tensor scratch, + int max_width, + ret_t& ret) +{ + size_t H = layout.size(0); + size_t M = layout.size(1); + size_t N = layout.size(2); + torch::Tensor tmp = torch::zeros_like(layout); + + auto _tmp = tmp.accessor(); + auto _layout = layout.accessor(); + auto _idx = idx.accessor(); + auto _scratch = scratch.accessor(); + std::vector current(H, 0); + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (size_t h = 0; h < H; h++) { + // surrounding indices + std::vector ii_left(max_width, -1); + std::vector> ii_top(max_width, std::vector(N, -1)); + + for (size_t m = 0; m < M; m++) { + for (size_t n = 0; n < N; n++) { + int v = _layout[h][m][n]; + if (v == 0) continue; + int n_left = ii_left[max_width - 1]; + int m_top = ii_top[max_width - 1][n]; + int top = (m_top >= 0) ? _tmp[h][m_top][n] : 0; + int left = (n_left >= 0) ? _tmp[h][m][n_left] : 0; + int topleft = (m_top >= 0 && n_left >= 0) ? _tmp[h][m_top][n_left] : 0; + int width = std::min(left, std::min(top, topleft)) + 1; + + // reset width if blocks cannot be + // packed together (i.e., there's a 1 "in the middle") + for (int nn = n_left + 1; nn < n; nn++) + if (ii_top[max_width - 1][nn] > ii_top[max_width - 1][n]) width = 1; + _tmp[h][m][n] = width; + + // update n_left ring buffer + for (int k = 0; k < max_width - 1; k++) ii_left[k] = ii_left[k + 1]; + ii_left[max_width - 1] = n; + + // update ii_top ring buffer + for (int k = 0; k < max_width - 1; k++) ii_top[k][n] = ii_top[k + 1][n]; + ii_top[max_width - 1][n] = m; + + // block is too small -- skip + if (width != max_width) continue; + + // retained blocks are set to zeros + for (size_t km = 0; km < max_width; km++) + for (size_t kn = 0; kn < max_width; kn++) { + int mm = ii_top[km][n]; + int nn = ii_left[kn]; + if (mm < 0 || nn < 0) continue; + _layout[h][mm][nn] = 0; + _tmp[h][mm][nn] = 0; + _scratch[h][current[h]][0] = (int)h; + _scratch[h][current[h]][1] = (int)mm; + _scratch[h][current[h]][2] = (int)nn; + _scratch[h][current[h]][3] = _idx[h][mm][nn]; + current[h]++; + } + } + } + } + std::vector to_cat; + for (size_t h = 0; h < H; h++) + if (current[h] > 0) to_cat.push_back(scratch[h].slice(0, 0, current[h])); + if (!to_cat.empty()) ret.push_back({max_width, torch::cat(to_cat)}); +} + +ret_t sdd_segment(torch::Tensor layout, int start_width) +{ + ret_t ret; + + // block index + torch::Tensor idx = torch::zeros_like(layout); + int current = 0; + size_t H = layout.size(0); + size_t M = layout.size(1); + size_t N = layout.size(2); + auto _layout = layout.accessor(); + auto _idx = idx.accessor(); + for (size_t h = 0; h < H; h++) + for (size_t m = 0; m < M; m++) + for (size_t n = 0; n < N; n++) { + if (_layout[h][m][n] == 0) continue; + _idx[h][m][n] = current++; + } + + // scratch memory + torch::Tensor scratch = torch::empty({H, layout.sum().item(), 4}, layout.dtype()); + + for (int max_width = start_width; max_width > 0; max_width /= 2) + segment_blocks(layout, idx, scratch, max_width, ret); + return ret; +} + +torch::Tensor make_layout(int num_heads, + const std::string& mode, + int num_blocks, + int block_stride, + const std::string& attention, + int numverts, + int vertsize) +{ + /* + Currently this function is able to create 'dense' or 'fixed' layout as described here: + https://openai.com/blog/sparse-transformer/ You can extend this function to add any block-base + sparsity following the 'fixed' part below. + */ + std::vector shape = {{num_heads, num_blocks, num_blocks}}; + + // attention type is currently supposed to be either unidirectional or bidirectional + // adding any other type, you need to update this function accordingly + bool unidirectional = (attention == "unidirectional") ? true : false; + + if (mode == "dense") + return torch::ones(shape, torch::kLong); + else if (mode == "fixed") { + torch::Tensor ret = torch::zeros(shape, torch::kLong); + auto _ret = ret.accessor(); + for (int h = 0; h < num_heads; h++) { + // set first part of layout + for (int i = 0; i < num_blocks; i += block_stride) + for (int j = i; j < i + block_stride; j++) + for (int k = i; k < (unidirectional ? j + 1 : i + block_stride); k++) + _ret[h][j][k] = 1; + // set second part of layout + int start = block_stride - (1 + h % numverts) * vertsize; + for (int i = 0; i < num_blocks; i++) { + int end = unidirectional ? i : num_blocks; + for (int j = start; j < end; j += block_stride) + for (int k = j; k < j + vertsize; k += num_blocks) _ret[h][i][k] = 1; + } + } + return ret; + } + return torch::zeros(shape, torch::kLong); +} + +PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) +{ + m.def("make_layout", &make_layout, "make sparsity layout"); + m.def("sdd_segment", &sdd_segment, "SDD segmentation handler"); +} diff --git a/deepspeed/pt/sparse_transformer/__init__.py b/deepspeed/pt/sparse_transformer/__init__.py new file mode 100644 index 000000000000..688c7e59eccf --- /dev/null +++ b/deepspeed/pt/sparse_transformer/__init__.py @@ -0,0 +1,5 @@ +from .softmax import Softmax +from .matmul import MatMul +from .sparse_self_attention import SparseSelfAttention, SparsityConfig +from .bert_sparse_self_attention import BertSparseSelfAttention +from .utils import extend_position_embedding, update_tokenizer_model_max_length, replace_model_self_attention_with_sparse_self_attention, replace_self_attention_layer_with_sparse_self_attention_layer diff --git a/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py b/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py new file mode 100755 index 000000000000..320e542002fa --- /dev/null +++ b/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py @@ -0,0 +1,79 @@ +""" +Copyright 2020 The Microsoft DeepSpeed Team +""" + +from torch import nn +from deepspeed.pt.sparse_transformer import SparseSelfAttention, SparsityConfig + + +class BertSparseSelfAttention(nn.Module): + """Implements Sparse Self Attention layer of Bert model based on https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/nvidia/modelingpreln.py#L373 + + For more information please see, TODO DeepSpeed Sparse Transformer. + + For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial. + """ + def __init__(self, + config, + sparsity_config=SparsityConfig('fixed', + 16, + 64, + 'bidirectional', + 4, + 1)): + """Initialize the bert sparse self attention layer. + Arguments: + config: required: Bert model config + sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on SparsityConfig class. + """ + + super(BertSparseSelfAttention, self).__init__() + if config.hidden_size % config.num_attention_heads != 0: + raise ValueError( + "The hidden size (%d) is not a multiple of the number of attention " + "heads (%d)" % (config.hidden_size, + config.num_attention_heads)) + self.num_attention_heads = config.num_attention_heads + self.attention_head_size = int(config.hidden_size / config.num_attention_heads) + self.all_head_size = self.num_attention_heads * self.attention_head_size + + self.query = nn.Linear(config.hidden_size, self.all_head_size) + self.key = nn.Linear(config.hidden_size, self.all_head_size) + self.value = nn.Linear(config.hidden_size, self.all_head_size) + + self.sparsity_config = sparsity_config + self.sparse_self_attention = SparseSelfAttention(sparsity_config) + + def transpose_for_scores(self, x): + new_x_shape = x.size()[:-1] + (self.num_attention_heads, + self.attention_head_size) + x = x.view(*new_x_shape) + return x.permute(0, 2, 1, 3) + + def forward(self, hidden_states, attention_mask): + """Applies forward phase of bert sparse self attention + + Arguments: + hidden_states: required: hidde_states tensor of the bert model + attn_mask: required: a mask tensor of size (SequenceLength X SequenceLength); currently only 2D is supported + + Return: + context_layer: a dense tensor containing attnetion context + """ + mixed_query_layer = self.query(hidden_states) + mixed_key_layer = self.key(hidden_states) + mixed_value_layer = self.value(hidden_states) + + query_layer = self.transpose_for_scores(mixed_query_layer) + key_layer = self.transpose_for_scores(mixed_key_layer) + value_layer = self.transpose_for_scores(mixed_value_layer) + + context_layer = self.sparse_self_attention(query_layer, + key_layer, + value_layer, + key_padding_mask=attention_mask) + + context_layer = context_layer.permute(0, 2, 1, 3).contiguous() + new_context_layer_shape = context_layer.size()[:-2] + (self.all_head_size, ) + context_layer = context_layer.view(*new_context_layer_shape) + return context_layer diff --git a/deepspeed/pt/sparse_transformer/matmul.py b/deepspeed/pt/sparse_transformer/matmul.py new file mode 100644 index 000000000000..1b4c57928f3f --- /dev/null +++ b/deepspeed/pt/sparse_transformer/matmul.py @@ -0,0 +1,725 @@ +# DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +# https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py + +import triton +import torch +import math +import deepspeed_sparse_transformer_util +from deepspeed.trsrc import matmul + + +############## +# MAIN API # +############## +class _sparse_matmul(torch.autograd.Function): + + sdd_cache = dict() + dsd_cache = dict() + dds_cache = dict() + locks = dict() + + # Given an array sizes representing reduction size for each + # column of a block-mode matrix multiplication, + # performs load-balancing to achieve more smaller reductions + # between `seg_size` elements + @staticmethod + def load_balance(sizes, block): + # segment size + # heuristics taken from OpenAI blocksparse code + # https://github.com/openai/blocksparse/blob/master/blocksparse/matmul.py#L95 + max_size = sizes.max() + min_size = sizes[sizes != 0].min() + #if max_size > min_size * 2.0: + # seg_max = max(triton.cdiv(max_size, 4), min_size*2) + #else: + # seg_max = max_size + seg_max = max_size + seg_min = max(triton.cdiv(seg_max, 4), 4) + # split reduction into segments + div = sizes // seg_max + rem = sizes % seg_max + packs = div + (sizes < seg_min).long() + (rem >= seg_min).long() + width = packs.sum() + segments = torch.empty(width, dtype=sizes.dtype) + column = torch.empty_like(segments) + lockid = torch.zeros_like(segments) + maxid = torch.zeros_like(segments) + nlocks = 0 + current = 0 + col_idx = 0 + for i in range(len(sizes)): + d, r = div[i], rem[i] + isempty = sizes[i] < seg_min + last = current + d + (r >= seg_min) + isempty + # column id + column[current:last] = col_idx + # lock id + if d > 1 or (d == 1 and r >= seg_min): + nlocks += 1 + lockid[current:last] = nlocks + maxid[current:last] = last - current + # segment size + segments[current:current + d] = seg_max + if r < seg_min and not isempty: + segments[current + d - 1] += r + if r >= seg_min or isempty: + segments[current + d] = r + current = last + col_idx += 1 + offsets = torch.zeros_like(segments) + offsets[1:] = torch.cumsum(segments[:-1], dim=0) + return segments, column, lockid, maxid, offsets + + @staticmethod + def get_locks(size, dev): + if dev not in _sparse_matmul.locks or \ + size > _sparse_matmul.locks[dev].size(0): + _sparse_matmul.locks[dev] = torch.zeros(size, dtype=torch.int32, device=dev) + return _sparse_matmul.locks[dev] + + ########################## + # SPARSE = DENSE x DENSE # + ########################## + sdd_segment = deepspeed_sparse_transformer_util.sdd_segment + + @staticmethod + def make_sdd_lut(layout, block, dtype, device): + start_width = 64 // block + segmented = _sparse_matmul.sdd_segment(layout.type(torch.int32), start_width) + luts, widths, packs = [], [], [] + for size, nnz in segmented: + width = nnz.shape[0] // (size * size) + h = nnz[:, 0] + i = nnz[:, 1] + j = nnz[:, 2] + b = nnz[:, 3] + lut = torch.stack((h, i, j, b), dim=1).view(-1).contiguous() + luts.append(lut.type(torch.int32).to(device)) + widths.append(width) + packs.append(size) + # create locks + return luts, None, widths, packs + + @staticmethod + def _sdd_matmul(a, + b, + trans_a, + trans_b, + trans_c, + spdims, + block, + luts, + num_locks, + widths, + packs, + bench, + time): + if trans_c: + a, b = b, a + trans_a, trans_b = not trans_b, not trans_a + AS0 = a.size(0) + AS1 = a.size(1) + AS2 = a.size(3 if trans_a else 2) + AS3 = a.size(2 if trans_a else 3) + BS0 = b.size(0) + BS1 = b.size(1) + BS2 = b.size(3 if trans_b else 2) + BS3 = b.size(2 if trans_b else 3) + dtype = a.dtype + is_16_multiple = AS3 % 16 == 0 + is_32_multiple = AS3 % 32 == 0 + is_64_multiple = AS3 % 64 == 0 + if not is_16_multiple: + raise ValueError('Reduction size for SDD must be a multiple of 16') + # create kernel + total_width = sum([width * pack * pack for width, pack in zip(widths, packs)]) + c = torch.empty((AS0, total_width, block, block), dtype=dtype, device=a.device) + for lut, width, pack in zip(luts, widths, packs): + num_lock = 1 + key = (block, + a.dtype, + b.dtype, + trans_a, + trans_b, + trans_c, + pack, + is_32_multiple, + is_64_multiple) + if key not in _sparse_matmul.sdd_cache: + F32TK = [8, 16] + F16TK = [16] + F16TK += [32] if is_32_multiple else [] + F16TK += [64] if is_64_multiple else [] + TK = {torch.float32: F32TK, torch.float16: F16TK}[dtype] + defines = { + 'TM': block * pack, + 'TN': block * pack, + 'TMN': block * block * pack * pack, + 'BLOCK': block, + 'TK': TK, + 'TYPE': dtype, + 'STRIDE_AM': '1' if trans_a else 'lda', + 'STRIDE_AK': 'lda' if trans_a else '1', + 'STRIDE_BN': 'ldb' if trans_b else '1', + 'STRIDE_BK': '1' if trans_b else 'ldb', + 'STRIDE_CM': 'ldc', + 'STRIDE_CN': '1', + 'SDD': True, + 'TZ': 1, + 'NAME': 'sdd_kernel' + } + _sparse_matmul.sdd_cache[key] = triton.kernel(matmul, + defines=defines, + num_warps=[1, + 2, + 4]) + #_sparse_matmul.sdd_cache[key] = triton.kernel(src, defines=defines, num_warps=[1, 2, 4]) + + kernel = _sparse_matmul.sdd_cache[key] + # create output + locks = _sparse_matmul.get_locks(2 * width * AS0 * num_lock, a.device) + # maximum grid size is 65535 + # so operation might be decomposed into multiple + # kernel calls + max_width = 49152 + total = 0 if bench else None + for off_width in range(0, width, max_width): + current = kernel(a, + b, + c, + a.stride(2), + b.stride(2), + block, + a.stride(0), + b.stride(0), + c.stride(0), + a.stride(1), + b.stride(1), + c.stride(0), + AS2, + AS2, + AS3, + off_width, + lut, + locks, + num_lock, + grid=lambda opt: + [opt.d('TZ'), + min(max_width, + width - off_width), + AS0], + bench=bench) + total = total + current if bench else None + time[0] = total + # save for backward pass + return c + + ########################## + # DENSE = DENSE x SPARSE # + ########################## + + # Given a binary layout of 0s and 1s, + # Construct look-up table for efficient execution on GPUs + @staticmethod + def make_dxx_lut(layout, block, step, trans, device, transform=lambda idx: idx): + # load-balancing + _empty = torch.tensor([], dtype=torch.int64, device=layout.device) + segments = _empty.clone() + column = _empty.clone() + depth = _empty.clone() + lockid = _empty.clone() + maxid = _empty.clone() + offsets = _empty.clone() + current_offset = 0 + current_maxid = 0 + for z in range(layout.size(0)): + if trans: + sizes = torch.sum(layout[z, :, :], 1) + else: + sizes = torch.sum(layout[z, :, :], 0) + z_segments, z_column, z_lockid, z_maxid, z_offsets = _sparse_matmul.load_balance(sizes, block) + z_depth = z * torch.ones_like(z_segments) + z_lockid[z_lockid > 0] += current_maxid + current_maxid = z_lockid.max() + # concatenate depth + segments = torch.cat((segments, z_segments)) + column = torch.cat((column, z_column)) + depth = torch.cat((depth, z_depth)) + maxid = torch.cat((maxid, z_maxid)) + offsets = torch.cat((offsets, current_offset + z_offsets)) + lockid = torch.cat((lockid, z_lockid)) + current_offset += layout[z, :, :].sum() + segments *= step + # pointer increments + if trans: + nnz = layout.nonzero() + else: + nnz = layout.transpose(1, 2).nonzero() + num_blocks = nnz.size(0) + offsets = torch.min(offsets, (num_blocks - 1) * torch.ones_like(offsets)) + idx = transform(nnz[:, 2] * block) + xincs = idx.clone() + xincs[1:] -= idx[:-1] + # divide block into multiple steps + div = block // step + xincs = xincs.view(-1, 1).repeat(1, div) + xincs[:, 1:] = step + xincs[:, 0] -= (div - 1) * step + # first increment for each reduction is actually the offset + xincs[offsets[segments > 0], 0] = idx[offsets[segments > 0]] + xincs = xincs.view(-1) + # block-mode input increments + if trans: + widx = torch.arange(num_blocks) + else: + widx = _empty.clone() + current_offset = 0 + for z in range(layout.size(0)): + layoutw = layout[z, :, :].clone() + msum = layoutw.sum() + layoutw[layoutw > 0] = 1 + torch.arange(msum) + widx = torch.cat((widx, current_offset + layoutw.T[layoutw.T > 0] - 1)) + current_offset += msum + widx = widx + wincs = widx * block * block + wincs[1:] -= widx[:-1] * block * block + wincs = wincs.view(-1, 1).repeat(1, div) + if trans: + wincs[:, 1:] = step + wincs[:, 0] -= (div - 1) * step + else: + wincs[:, 1:] = step * block + wincs[:, 0] -= (div - 1) * step * block + wincs[offsets[segments > 0], 0] = widx[offsets[segments > 0]] + wincs = wincs.view(-1) + # adjust offset and segment size + offsets *= 2 * div + segments *= div + # create header + width = column.size(0) + offsets += 6 * width + header = torch.stack((offsets, + segments, + column, + depth, + lockid, + maxid), + dim=1).view(-1).contiguous() + incs = torch.stack((xincs, wincs), dim=1).view(-1).contiguous() + incs = torch.cat((incs, torch.zeros(2, device=incs.device, dtype=incs.dtype))) + # create lut + lut = torch.cat((header, incs)) + lut = lut.type(torch.int32).to(device) + # create locks + num_locks = max(1, lockid.max()) + return lut, num_locks, width, None + + @staticmethod + def _dds_matmul(a, + b, + trans_a, + trans_b, + trans_c, + spdims, + block, + lut, + num_locks, + width, + packs, + bench, + time): + # shapes / dtypes + AS0 = a.size(0) + AS1 = a.size(1) + AS2 = a.size(3 if trans_a else 2) + AS3 = a.size(2 if trans_a else 3) + BS0 = spdims[0] + BS1 = block * spdims[2 if trans_b else 1] + BS2 = block * spdims[1 if trans_b else 2] + dtype = a.dtype + # kernel + key = (block, a.dtype, b.dtype, trans_a, trans_b, trans_c) + if key not in _sparse_matmul.dds_cache: + TM = [64, 128] if dtype == torch.float32 else [64, 128, 256] + TK = [8] if dtype == torch.float32 else [16] + defines = { + 'TM': TM, + 'TN': block, + 'TK': TK, + 'BLOCK': block, + 'TYPE': dtype, + 'STRIDE_AM': 1 if trans_a else 'lda', + 'STRIDE_AK': 'lda' if trans_a else 1, + 'STRIDE_BN': block if trans_b else 1, + 'STRIDE_BK': 1 if trans_b else block, + 'STRIDE_CM': '1' if trans_c else 'ldc', + 'STRIDE_CN': 'ldc' if trans_c else '1', + 'NAME': 'dds_kernel', + 'DDS': True + } + _sparse_matmul.dds_cache[key] = triton.kernel(matmul, + defines=defines, + num_warps=[4]) + #_sparse_matmul.dds_cache[key] = triton.kernel(src, defines=defines, num_warps=[4]) + kernel = _sparse_matmul.dds_cache[key] + # output + CS0 = AS0 + CS1 = AS1 + CS2 = BS2 if trans_c else AS2 + CS3 = AS2 if trans_c else BS2 + locks = _sparse_matmul.get_locks(2 * AS0 * AS2 // 32 * num_locks, a.device) + c = torch.empty((CS0, CS1, CS2, CS3), dtype=dtype, device=a.device) + time[0] = kernel(a, + b, + c, + a.stride(2), + block, + c.stride(2), + a.stride(0), + b.stride(0), + c.stride(0), + a.stride(1), + b.stride(1), + c.stride(1), + AS2, + BS2, + 0, + 0, + lut, + locks, + num_locks, + grid=lambda opt: [width, + triton.cdiv(AS2, + opt.d('TM')), + AS0], + bench=bench) + return c + + @staticmethod + def _dsd_matmul(a, + b, + trans_a, + trans_b, + trans_c, + spdims, + block, + lut, + num_locks, + width, + packs, + bench, + time): + # shapes / dtypes + AS0 = spdims[0] + AS1 = block * spdims[2 if trans_a else 1] + AS2 = block * spdims[1 if trans_a else 2] + BS0 = b.size(0) + BS1 = b.size(1) + BS2 = b.size(3 if trans_b else 2) + BS3 = b.size(2 if trans_b else 3) + dtype = a.dtype + # kernel + key = (block, a.dtype, b.dtype, trans_a, trans_b, trans_c) + if key not in _sparse_matmul.dsd_cache: + TN = [64, 128] if dtype == torch.float32 else [64, 128, 256] + TK = [8] if dtype == torch.float32 else [16] + defines = { + 'TM': block, + 'TN': TN, + 'TK': TK, + 'BLOCK': block, + 'TYPE': dtype, + 'STRIDE_AM': 1 if trans_a else block, + 'STRIDE_AK': block if trans_a else 1, + 'STRIDE_BN': 'ldb' if trans_b else '1', + 'STRIDE_BK': '1' if trans_b else 'ldb', + 'STRIDE_CM': '1' if trans_c else 'ldc', + 'STRIDE_CN': 'ldc' if trans_c else '1', + 'NAME': 'dsd_kernel', + 'DSD': True + } + _sparse_matmul.dsd_cache[key] = triton.kernel(matmul, + defines=defines, + num_warps=[4]) + #_sparse_matmul.dsd_cache[key] = triton.kernel(src, defines=defines, num_warps=[4]) + kernel = _sparse_matmul.dsd_cache[key] + # output + CS0 = BS0 + CS1 = BS1 + CS2 = BS3 if trans_c else AS1 + CS3 = AS1 if trans_c else BS3 + locks = _sparse_matmul.get_locks(2 * BS0 * BS3 // 32 * num_locks, a.device) + c = torch.empty((CS0, CS1, CS2, CS3), dtype=dtype, device=a.device) + time[0] = kernel(a, + b, + c, + block, + b.stride(2), + c.stride(2), + a.stride(0), + b.stride(0), + c.stride(0), + a.stride(1), + b.stride(1), + c.stride(1), + BS3, + AS1, + 0, + 0, + lut, + locks, + num_locks, + grid=lambda opt: [width, + triton.cdiv(BS3, + opt.d('TN')), + BS0], + bench=bench) + return c + + fn = { + 'sdd': _sdd_matmul.__get__(object), + 'dsd': _dsd_matmul.__get__(object), + 'dds': _dds_matmul.__get__(object) + } + + @staticmethod + def forward(ctx, + a, + b, + trans_a, + trans_b, + trans_c, + mode, + spdims, + block, + c_lut, + c_num_locks, + c_width, + c_packs, + c_bench, + c_time, + da_lut, + da_num_locks, + da_width, + da_packs, + da_bench, + da_time, + db_lut, + db_num_locks, + db_width, + db_packs, + db_bench, + db_time): + c = _sparse_matmul.fn[mode](a, + b, + trans_a, + trans_b, + trans_c, + spdims, + block, + c_lut, + c_num_locks, + c_width, + c_packs, + c_bench, + c_time) + # save for backward + ctx.save_for_backward(a, b) + ctx.da_num_locks = da_num_locks + ctx.da_lut = da_lut + ctx.da_width = da_width + ctx.da_packs = da_packs + ctx.da_bench = da_bench + ctx.da_time = da_time + ctx.db_lut = db_lut + ctx.db_num_locks = db_num_locks + ctx.db_width = db_width + ctx.db_bench = db_bench + ctx.db_packs = db_packs + ctx.db_time = db_time + ctx.mode = mode + ctx.spdims = spdims + ctx.block = block + ctx.trans_a = trans_a + ctx.trans_b = trans_b + return c + + @staticmethod + def backward(ctx, dc): + # saved for backward + a, b = ctx.saved_tensors + mode = ctx.mode + # gradients w.r.t. a + if ctx.needs_input_grad[0]: + mode_da = mode[1] + mode[0] + mode[2] + da = _sparse_matmul.fn[mode_da](dc, + b, + False, + not ctx.trans_b, + ctx.trans_a, + ctx.spdims, + ctx.block, + ctx.da_lut, + ctx.da_num_locks, + ctx.da_width, + ctx.da_packs, + ctx.da_bench, + ctx.da_time) + # gradients w.r.t. b + if ctx.needs_input_grad[1]: + mode_db = mode[2] + mode[1] + mode[0] + db = _sparse_matmul.fn[mode_db](a, + dc, + not ctx.trans_a, + False, + ctx.trans_b, + ctx.spdims, + ctx.block, + ctx.db_lut, + ctx.db_num_locks, + ctx.db_width, + ctx.db_packs, + ctx.db_bench, + ctx.db_time) + return da, db, None, None, None,\ + None, None, None, None,\ + None, None, None, None, None, None,\ + None, None, None, None, None, None,\ + None, None, None, None, None, None + + +class MatMul: + """Block-Sparse MatMul class; this class handles three types of matrix-multiplication: + - sparse = dense X dense + - dense = sparse X dense + - dense = dense X sparse + + For more details about sparsity config, please see `Generative Modeling with Sparse Transformers`: https://arxiv.org/abs/1904.10509 + """ + def make_lut(self, dtype, device): + """Generates the sparsity layout/s used in block-sparse matmul + """ + key = (dtype, device) + if key in self.lut_cache: + return self.lut_cache[key] + # C look-up table + layout, block = self.layout, self.block + step = 8 if dtype == torch.float32 else 16 + if self.mode == 'sdd': + c_lut, c_num_locks, c_width, c_packs = _sparse_matmul.make_sdd_lut(layout, block, dtype, device) + elif self.mode == 'dsd': + c_lut, c_num_locks, c_width, c_packs = _sparse_matmul.make_dxx_lut(layout, block, step, not self.trans_a, device) + elif self.mode == 'dds': + c_lut, c_num_locks, c_width, c_packs = _sparse_matmul.make_dxx_lut(layout, block, step, self.trans_b, device) + # DA look-up table + if self.mode == 'sdd': + da_lut, da_num_locks, da_width, da_packs = _sparse_matmul.make_dxx_lut(layout, block, step, True, device) + elif self.mode == 'dsd': + da_lut, da_num_locks, da_width, da_packs = _sparse_matmul.make_sdd_lut(layout, block, dtype, device) + elif self.mode == 'dds': + da_lut, da_num_locks, da_width, da_packs = _sparse_matmul.make_dxx_lut(layout, block, step, not self.trans_b, device) + # DB look-up table + if self.mode == 'sdd': + db_lut, db_num_locks, db_width, db_packs = _sparse_matmul.make_dxx_lut(layout, block, step, False, device) + elif self.mode == 'dsd': + db_lut, db_num_locks, db_width, db_packs = _sparse_matmul.make_dxx_lut(layout, block, step, self.trans_a, device) + elif self.mode == 'dds': + db_lut, db_num_locks, db_width, db_packs = _sparse_matmul.make_sdd_lut(layout, block, dtype, device) + self.lut_cache[key] = (c_lut, c_num_locks, c_width, c_packs,\ + da_lut, da_num_locks, da_width, da_packs,\ + db_lut, db_num_locks, db_width, db_packs) + return self.lut_cache[key] + + def __init__(self, layout, block, mode, trans_a=False, trans_b=False, bench=False): + """Initialize the Block-Sparse MatMul class. + + Arguments: + layout: required: sparsity layout tensor + block: required: an integer determining the block size. + mode: required: a string determining type of matmul; ('sdd') sparse = dense X dense, ('dsd') dense = sparse X dense, ('dds') dense = dense X sparse + trans_a: optional: a boolean determining if multiplication needs to be applied on transpose of input a; default is false + trans_b: optional: a boolean determining if multiplication needs to be applied on transpose of input b; default is false + bench: optional: set if you want to do benchmarking + """ + + if mode not in ['sdd', 'dsd', 'dds']: + raise NotImplementedError('Supported modes are: sdd, dsd, dds') + # look-up table cache + self.lut_cache = dict() + # attributes + self.trans_a = trans_a + self.trans_b = trans_b + self.mode = mode + self.spdims = layout.shape + self.block = block + self.layout = layout + # timings + self.bench = bench + self.time_c = None + self.time_da = None + self.time_db = None + + # pad shapes of a tensor to make it + # compatible with kernel calls + @staticmethod + def _pad_shape(x, is_sparse): + max_dim = 3 if is_sparse else 4 + for i in range(max_dim - x.dim()): + x = x.unsqueeze(0) + return x + + def __call__(self, a, b): + """Applies Block-Sparse MatMul. + + For more details about sparsity config, please see `Generative Modeling with Sparse Transformers`: https://arxiv.org/abs/1904.10509 + + Arguments: + a: required: a dense/block-sparse tensor; first input of mat-mul + b: required: a dense/block-sparse tensor; second input of mat-mul + + Return: + c: a dense/block-sparse tensor result of a X b + """ + + + c_lut, c_num_locks, c_width, c_packs,\ + da_lut, da_num_locks, da_width, da_packs,\ + db_lut, db_num_locks, db_width, db_packs = self.make_lut(a.dtype, a.device) + # timings + time_c = [None] + time_da = [None] + time_db = [None] + # pad shapes with ones + a = MatMul._pad_shape(a, self.mode == 'dsd') + b = MatMul._pad_shape(b, self.mode == 'dds') + # execute + c = _sparse_matmul.apply(a, + b, + self.trans_a, + self.trans_b, + False, + self.mode, + self.spdims, + self.block, + c_lut, + c_num_locks, + c_width, + c_packs, + self.bench, + time_c, + da_lut, + da_num_locks, + da_width, + da_packs, + self.bench, + time_da, + db_lut, + db_num_locks, + db_width, + db_packs, + self.bench, + time_db) + self.time_c = time_c[0] + self.time_da = time_da[0] + self.time_db = time_db[0] + return c diff --git a/deepspeed/pt/sparse_transformer/softmax.py b/deepspeed/pt/sparse_transformer/softmax.py new file mode 100644 index 000000000000..1ae733a25c3b --- /dev/null +++ b/deepspeed/pt/sparse_transformer/softmax.py @@ -0,0 +1,290 @@ +# DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +# https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py + +import triton +import torch +import math +from deepspeed.trsrc import softmax_fwd, softmax_bwd + +fwd_kernels = dict() +bwd_kernels = dict() + + +class _sparse_softmax(torch.autograd.Function): + + bwd_kernels = dict() + + @staticmethod + def make_lut(layout, block, device): + _empty = torch.tensor([], dtype=torch.int64, device=layout.device) + sizes = _empty.clone() + # sizes along rows + for h in range(layout.shape[0]): + sizes = torch.cat((sizes, layout[h, :, :].sum(-1))) + # offsets in block format + offsets = torch.zeros_like(sizes) + offsets[1:] = torch.cumsum(sizes[:-1], dim=0) + # block indices + idx = torch.arange(layout.sum()) + rows = layout.nonzero()[:, 1] + columns = layout.nonzero()[:, 2] + core = torch.stack((idx, columns, rows), dim=1).view(-1) + # construct look-up table + offsets = offsets * 3 + 2 * sizes.numel() + header = torch.stack((sizes, offsets), dim=1).view(-1) + lut = torch.cat((header, core)).type(torch.int32).to(device) + return lut, int(sizes.max()) + + @staticmethod + def make_kernel(cache, + src, + max_k, + dtype, + block, + apply_scale, + apply_rpe, + apply_kp_mask, + apply_attn_mask, + kp_mask_mode, + attn_mask_mode): + if max_k >= 32768: + raise NotImplementedError('Reductions larger than 32768 elements '\ + 'are not yet implemented') + num_warps = 4 if max_k < 512 else (8 if max_k < 2048 else 16) + pad = num_warps * 32 * 2 + TN = (int(max_k) + pad - 1) // pad * pad + # just-in-time compile kernel + key = (block, + dtype, + num_warps, + TN, + apply_scale, + apply_rpe, + apply_kp_mask, + apply_attn_mask, + kp_mask_mode, + attn_mask_mode) + if key not in cache: + defines = { + 'TM': [1], + 'TN': [TN], + 'TYPE': dtype, + 'BLOCK': block, + 'INFINITY': { + torch.float32: 'F32_INFINITY', + torch.float16: 'F16_INFINITY' + }[dtype] + } + if apply_scale: + defines['APPLY_SCALE'] = True + if apply_rpe: + defines['APPLY_RPE'] = True + if apply_kp_mask: + defines['APPLY_KP_MASK'] = True + if kp_mask_mode == 'mul': + defines['KP_MASK_MUL'] = True + if apply_attn_mask: + defines['APPLY_ATTN_MASK'] = True + if attn_mask_mode == 'mul': + defines['ATTN_MASK_MUL'] = True + kernel = triton.kernel(src, defines=defines, num_warps=[num_warps]) + cache[key] = kernel + return cache[key] + + @staticmethod + def forward(ctx, + x, + scale, + rpe, + key_padding_mask, + attn_mask, + kp_mask_mode, + attn_mask_mode, + spdims, + block, + lut, + num_blocks, + num_blocks_per_head, + maxlut, + bench, + time): + apply_scale = False if scale == 1.0 else True + + # handle None rpe + if rpe is None: + apply_rpe = False + stride_zrpe, stride_hrpe, stride_srpe = 0, 0, 0 + rpe = torch.empty(0, dtype=x.dtype, device=x.device) + else: + apply_rpe = True + stride_zrpe, stride_hrpe, stride_srpe = rpe.stride(0), rpe.stride(1), rpe.stride(2) + + # handle None key_padding_mask + if key_padding_mask is None: + apply_kp_mask = False + stride_zkpm = 0 + key_padding_mask = torch.empty(0, dtype=x.dtype, device=x.device) + else: + apply_kp_mask = True + stride_zkpm = key_padding_mask.stride(0) + + # handle None attention_mask + if attn_mask is None: + apply_attn_mask = False + stride_zattnm = 0 + attn_mask = torch.empty(0, dtype=x.dtype, device=x.device) + else: + apply_attn_mask = True + stride_zattnm = attn_mask.stride(0) + + # run kernel + kernel = _sparse_softmax.make_kernel(fwd_kernels, + softmax_fwd, + maxlut * block, + x.dtype, + block, + apply_scale, + apply_rpe, + apply_kp_mask, + apply_attn_mask, + kp_mask_mode, + attn_mask_mode) + M = x.shape[0] + grid = lambda opt: [triton.cdiv(spdims[0] * spdims[1] * block, opt.d('TM')), M] + + # run kernel + time[0] = kernel(x, scale, lut, rpe, key_padding_mask, attn_mask,\ + num_blocks, num_blocks_per_head, maxlut,\ + x.stride(0),\ + stride_zrpe, stride_hrpe, stride_srpe,\ + stride_zkpm, stride_zattnm,\ + grid=grid, bench=bench) + # save to context + ctx.mark_dirty(x) + ctx.save_for_backward(x, lut) + ctx.spdims = spdims + ctx.block = block + ctx.maxlut = maxlut + ctx.scale = scale + ctx.apply_scale = apply_scale + ctx.apply_rpe = apply_rpe + ctx.apply_kp_mask = apply_kp_mask + ctx.apply_attn_mask = apply_attn_mask + ctx.kp_mask_mode = kp_mask_mode + ctx.attn_mask_mode = attn_mask_mode + return x + + @staticmethod + def backward(ctx, dx): + # retrieve from context + x, lut = ctx.saved_tensors + # run kernel + kernel = _sparse_softmax.make_kernel(bwd_kernels, + softmax_bwd, + ctx.maxlut * ctx.block, + x.dtype, + ctx.block, + ctx.apply_scale, + ctx.apply_rpe, + ctx.apply_kp_mask, + ctx.apply_attn_mask, + ctx.kp_mask_mode, + ctx.attn_mask_mode) + M = x.shape[0] + grid = lambda opt: [ + triton.cdiv(ctx.spdims[0] * ctx.spdims[1] * ctx.block, + opt.d('TM')), + M + ] + kernel(x, ctx.scale, dx, lut, ctx.maxlut, x.stride(0), dx.stride(0), grid=grid) + return dx, None, None, None, None, None, None, None, None, None, None, None, None, None, None + + +class Softmax: + """Block-Sparse Softmax class; this class computes softmax on a block sparse matrix. It is also able to apply either/all of the following masks: + - relative position embedding + - key padding mask + - attention mask + + For more details about sparsity config, please see `Generative Modeling with Sparse Transformers`: https://arxiv.org/abs/1904.10509 + """ + + sparse_softmax = _sparse_softmax.apply + + def make_lut(self, device): + """Generates the sparsity layout used in block-sparse softmax + """ + key = (device, ) + if key not in self.lut_cache: + self.lut_cache[key] = _sparse_softmax.make_lut(self.layout, + self.block, + device) + return self.lut_cache[key] + + def __init__(self, layout, block, bench=False): + """Initialize the Block-Sparse Softmax class. + + Arguments: + layout: required: sparsity layout tensor + block: required: an integer determining the block size. + bench: optional: set if you want to do benchmarking + """ + + self.num_blocks = layout.sum() + self.num_blocks_per_head = self.num_blocks / layout.shape[0] + self.spdims = layout.shape + self.layout = layout + self.block = block + self.bench = bench + self.lut_cache = dict() + + def __call__(self, + x, + scale=1., + rpe=None, + key_padding_mask=None, + attn_mask=None, + key_padding_mask_mode='add', + attn_mask_mode='add'): + """Applies softmax on a Block-Sparse input tensor. + + For more details about sparsity config, please see `Generative Modeling with Sparse Transformers`: https://arxiv.org/abs/1904.10509 + + Arguments: + x: required: a block-sparse tensor that softmax is applied on it; computation will be in place and result will be returned in the same tensor + scale: optional: a float value; x values will be multiplied by this value before normalization. Default value is 1.0. + rpe: optional: a tensor same dimension as x that is used as relative position embedding + key_padding_mask: optional: a mask tensor of size (BatchSize X SequenceLength) + attn_mask: optional: a mask tensor of size (SequenceLength X SequenceLength); currently only 2D is supported + key_padding_mask_mode: optional: a boolean determining if key_padding_mask needs to be added or multiplied + attn_mask_mode: optional: a boolean determining if attn_mask needs to be added or multiplied + + Return: + x: a block-sparse tensor contains normalized input x using softmax; and masks applied if given + """ + + time_y = [None] + if rpe is not None and rpe.dtype != x.dtype: + raise ValueError('relative position embedding must be %s' % x.dtype) + if attn_mask is not None and attn_mask.dtype != x.dtype: + raise ValueError('Attention mask must be %s' % x.dtype) + if key_padding_mask is not None and key_padding_mask.dtype != x.dtype: + raise ValueError('Key padding mask must be %s' % x.dtype) + lut, maxlut = self.make_lut(x.device) + x = Softmax.sparse_softmax(x, + scale, + rpe, + key_padding_mask, + attn_mask, + key_padding_mask_mode, + attn_mask_mode, + self.spdims, + self.block, + lut, + self.num_blocks, + self.num_blocks_per_head, + maxlut, + self.bench, + time_y) + self.time_y = time_y[0] + return x diff --git a/deepspeed/pt/sparse_transformer/sparse_self_attention.py b/deepspeed/pt/sparse_transformer/sparse_self_attention.py new file mode 100644 index 000000000000..b143bdadbfae --- /dev/null +++ b/deepspeed/pt/sparse_transformer/sparse_self_attention.py @@ -0,0 +1,330 @@ +""" +Copyright 2020 The Microsoft DeepSpeed Team +""" + +import torch.nn as nn +from torch.nn.functional import * +import torch +from collections import namedtuple +import deepspeed_sparse_transformer_util +from deepspeed.pt.sparse_transformer import MatMul, Softmax +import sys + +make_layout = deepspeed_sparse_transformer_util.make_layout + + +class SparsityConfig: + """Configuration class to store sparsity configuration of a self attention layer`. + """ + def __init__(self, + mode='fixed', + block=16, + stride=64, + attention='bidirectional', + numverts=1, + vertsize=1): + """Initialize the Sparsity Pattern Config. + + For more details about sparsity config, please see `Generative Modeling with Sparse Transformers`: https://arxiv.org/abs/1904.10509 + + For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial + + Arguments: + mode: optional: a string determining the sparsity mode. In addition to `dense`, currently we support `fixed` mode that combines local and global attention suitable for document modeling. + block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. + stride: optional: an integer determining the local attention window size. + attention: optional: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. + numverts: optional: an integer determining number of different global attentions. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks local window and global attention size of 1, we can have 4 different versions in which first, Second, third, or forth block of each local window be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on block and stride size. As an example, considering one block as global representative, in the above figure, there are maximum of four versions of global attention. + vertsize: optional: an integer determining how many consecutive blocks a local window is used for global attention. + """ + if mode != 'dense' and mode != 'fixed': + raise NotImplementedError( + 'only \"dense\" and \"fixed\" modes are supported for now') + self.mode = mode + self.block = block + self.stride = stride + if attention != 'unidirectional' and attention != 'bidirectional': + raise NotImplementedError( + 'only \"uni/bi-directional\" attentions are supported for now') + self.attention = attention + self.numverts = numverts + self.vertsize = vertsize + + +class SparseSelfAttention(nn.Module): + """Implements an efficient Sparse Self Attention of Transformer layer based on `Generative Modeling with Sparse Transformers`: https://arxiv.org/abs/1904.10509 + + For more information please see, TODO DeepSpeed Sparse Transformer. + + For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial. + """ + def __init__(self, + sparsity_config=SparsityConfig(), + key_padding_mask_mode='add', + attn_mask_mode='mul'): + """Initialize the sparse self attention layer. + Arguments: + sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on SparsityConfig class. + key_padding_mask_mode: optional: a string determining if key padding mask needs to be added, `add`, or be multiplied, `mul`. + attn_mask_mode: optional: a string determining if attention mask needs to be added, `add`, or be multiplied, `mul`. + """ + super().__init__() + + # sparsity information + self.sparsity_config = sparsity_config + + # mask modes + self.key_padding_mask_mode = key_padding_mask_mode + self.attn_mask_mode = attn_mask_mode + + @staticmethod + def _set_local_layout(layout, h, num_blocks, block_stride, attention): + """Sets local attantion layout used by the given head in the sparse attention. + + Arguments: + layout: required: sparsity layout tensor + h: required: an integer determining head index + num_blocks: required: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. + block_stride: required: an integer determining the local attention window size. + attention: required: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. + Return: + layout: the layout tensor in which the local attention for head #h has been set + """ + + for i in range(0, num_blocks, block_stride): + for j in range(i, i + block_stride): + for k in range( + i, + (j + 1 if attention == 'unidirectional' else i + block_stride)): + layout[h, j, k] = 1 + return layout + + @staticmethod + def _set_global_layout(layout, + h, + num_blocks, + block_stride, + attention, + numverts, + vertsize): + """Sets global attantion layout used by the given head in the sparse attention. + + Arguments: + layout: required: sparsity layout tensor + h: required: an integer determining head index + num_blocks: required: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. + block_stride: required: an integer determining the local attention window size. + attention: required: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. + numverts: required: an integer determining number of different global attentions. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks local window and global attention size of 1, we can have 4 different versions in which first, Second, third, or forth block of each local window be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on block and stride size. As an example, considering one block as global representative, in the above figure, there are maximum of four versions of global attention. + vertsize: required: an integer determining how many consecutive blocks a local window is used for global attention. + Return: + layout: the layout tensor in which the global attention for head #h has been set + """ + + start = block_stride - (1 + h % numverts) * vertsize + for i in range(0, num_blocks): + end = i if attention == 'unidirectional' else num_blocks + for j in range(start, end, block_stride): + for k in range(j, min(j + vertsize, num_blocks)): + layout[h, i, k] = 1 + return layout + + @staticmethod + def _make_layout_python(num_heads, + mode, + num_blocks, + block_stride, + attention, + numverts, + vertsize): + """Generates sparsity layout used by each head in the sparse attention. + Currently this function is able to create 'dense' or 'fixed' layout as described here: https://arxiv.org/abs/1904.10509 + + This function can be extend to add any block-base sparsity following the 'fixed' part below. + + Arguments: + num_heads: required: an integer determining number of heads of the model + mode: required: a string determining the sparsity mode. In addition to `dense`, currently we support `fixed` mode that combines local and global attention suitable for document modeling. + num_blocks: required: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. + block_stride: required: an integer determining the local attention window size. + attention: required: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. + numverts: required: an integer determining number of different global attentions. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks local window and global attention size of 1, we can have 4 different versions in which first, Second, third, or forth block of each local window be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on block and stride size. As an example, considering one block as global representative, in the above figure, there are maximum of four versions of global attention. + vertsize: required: an integer determining how many consecutive blocks a local window is used for global attention. + Return: + layout: a tensor determining the sparsity layout of each head + """ + + if (block_stride % vertsize) != 0: + raise ValueError( + f'Number of blocks in a stride window {block_stride} must be dividable by vertical block size {vertsize}' + ) + + if numverts > (block_stride / vertsize): + raise ValueError( + f'Number of layout versions {num_verts} cannot be larger than blocks in a stride window divided by vertical block size {block_stride} / {vertsize} = {block_stride/vertsize}' + ) + + layout = torch.zeros((num_heads, num_blocks, num_blocks), dtype=torch.int64) + if mode == "dense": + layout[:, :, :] = 1 + elif mode == "fixed": + for i in range(0, num_heads): + layout = SparseSelfAttention._set_local_layout( + layout, + i, + num_blocks, + block_stride, + attention) + layout = SparseSelfAttention._set_global_layout( + layout, + i, + num_blocks, + block_stride, + attention, + numverts, + vertsize) + else: + raise NotImplementedError( + 'Only \"dense\" and \"fixed\" modes are supported for now!') + + return layout + + @staticmethod + def _make_layout(num_heads, + mode, + num_blocks, + block_stride, + attention, + numverts, + vertsize): + return make_layout(num_heads, + mode, + num_blocks, + block_stride, + attention, + numverts, + vertsize) + + ops = dict() + + # add to cache + def get_ops(self, H, L): + import sys + if L not in SparseSelfAttention.ops: + spConfig = self.sparsity_config + + if L % spConfig.block != 0: + raise ValueError( + f'Sequence length {L} must be dividable by block size {spConfig.block}' + ) + num_blocks = L // spConfig.block + + if spConfig.stride % spConfig.block != 0: + raise ValueError( + f'Stride {spConfig.stride} must be dividable by block size {spConfig.block}' + ) + block_stride = spConfig.stride // spConfig.block + + layout = SparseSelfAttention._make_layout(H, + num_blocks, + spConfig.mode, + block_stride, + spConfig.attention, + spConfig.numverts, + spConfig.vertsize) + + sparse_dot_sdd_nt = MatMul(layout, + spConfig.block, + 'sdd', + trans_a=False, + trans_b=True) + + sparse_dot_dsd_nn = MatMul(layout, + spConfig.block, + 'dsd', + trans_a=False, + trans_b=False) + + sparse_softmax = Softmax(layout, spConfig.block) + + SparseSelfAttention.ops[L] = (sparse_dot_sdd_nt, + sparse_dot_dsd_nn, + sparse_softmax) + return SparseSelfAttention.ops[L] + + def transpose_key_for_scores(self, x, L): + bsz, num_heads, seq_len, head_dim = x.size() + if seq_len != L: + return x.permute(0, 1, 3, 2) + return x + + def transpose_mask_for_sparse(self, qtype, x, is_key_padding_mask=False): + x = x.type(qtype) + if is_key_padding_mask: + xdim = x.dim() + for d in range(xdim - 1, 0, -1): + x = x.squeeze(dim=d) + return x + return x.squeeze() + + # forward pass + def forward(self, + query, + key, + value, + rpe=None, + key_padding_mask=None, + attn_mask=None): + """Applies forward phase of sparse self attention + + Arguments: + query: required: query tensor + key: required: key tensor + value: required: value tensor + rpe: optional: a tensor same dimension as x that is used as relative position embedding + key_padding_mask: optional: a mask tensor of size (BatchSize X SequenceLength) + attn_mask: optional: a mask tensor of size (SequenceLength X SequenceLength); currently only 2D is supported + key_padding_mask_mode: optional: a boolean determining if key_padding_mask needs to be added or multiplied + attn_mask_mode: optional: a boolean determining if attn_mask needs to be added or multiplied + + Return: + attn_output: a dense tensor containing attnetion context + """ + bsz, num_heads, tgt_len, head_dim = query.size() + + # transpose back key if it is already transposed + key = self.transpose_key_for_scores(key, tgt_len) + + # check that operation is supported + if query.shape != key.shape or key.shape != value.shape: + raise NotImplementedError('only self-attention is supported for now') + + # squeeze key_padding_mask if it is given + if key_padding_mask is not None: + key_padding_mask = self.transpose_mask_for_sparse(query.dtype, + key_padding_mask, + is_key_padding_mask=True) + + # squeeze attn_mask if it is given + if attn_mask is not None: + attn_mask = self.transpose_mask_for_sparse(query.dtype, attn_mask) + + # cache look-up table computations etc + sparse_dot_sdd_nt, sparse_dot_dsd_nn, sparse_softmax = self.get_ops(num_heads, tgt_len) + + scaling = float(head_dim)**-0.5 + + # attention scores + attn_output_weights = sparse_dot_sdd_nt(query, key) + attn_output_weights = sparse_softmax( + attn_output_weights, + scale=scaling, + rpe=rpe, + key_padding_mask=key_padding_mask, + attn_mask=attn_mask, + key_padding_mask_mode=self.key_padding_mask_mode, + attn_mask_mode=self.attn_mask_mode) + + # outputs + attn_output = sparse_dot_dsd_nn(attn_output_weights, value) + return attn_output diff --git a/deepspeed/pt/sparse_transformer/utils.py b/deepspeed/pt/sparse_transformer/utils.py new file mode 100644 index 000000000000..516a466f2e70 --- /dev/null +++ b/deepspeed/pt/sparse_transformer/utils.py @@ -0,0 +1,136 @@ +""" +Copyright 2020 The Microsoft DeepSpeed Team +""" + +from torch import nn +from deepspeed.pt.sparse_transformer import DeepSpeedBertSparseSelfAttention, SparsityConfig +''' +This file contains few utility functions to handle adapting pretrained model with sparse self-attention module. +''' + + +def extend_position_embedding(model, max_position): + """This function extends the position embedding weights of a model loaded from a checkpoint. + It assumes the new max position is bigger than the original max length. + + Arguments: + model: required: a transformer model + max_position: required: an integer determining new position embedding size + Return: + model: updated model; in which position embedding weights have been extended based on new size + """ + + if hasattr(model, 'bert'): + original_max_position = model.bert.embeddings.position_embeddings.weight.size(0) + assert max_position > original_max_position + extend_multiples = max(1, max_position // original_max_position) + model.bert.embeddings.position_embeddings.weight.data = model.bert_model.embeddings.position_embeddings.weight.repeat( + extend_multiples, + 1) + elif hasattr(model, 'roberta'): + # RoBERTa has positions 0 & 1 reserved, so embedding size is max position + 2 + original_max_position, embed_size = model.roberta.embeddings.position_embeddings.weight.shape + original_max_position -= 2 + extend_multiples = max(1, max_position // original_max_position) + assert max_position > original_max_position + max_position += 2 + extended_position_embedding = model.roberta.embeddings.position_embeddings.weight.new_empty( + max_position, + embed_size) + k = 2 + for i in range(extend_multiples): + extended_position_embedding[k:( + k + original_max_position + )] = model.roberta.embeddings.position_embeddings.weight[2:] + k += original_max_position + model.roberta.embeddings.position_embeddings.weight.data = extended_position_embedding + else: + raise ValueError( + 'Please extend \"extend_position_embedding\" function to support your model type. It currently only supports \"bert\" & \"roberta\"!' + ) + + model.config.max_position_embeddings = max_position + print(f'Extended position embeddings to {original_max_position * extend_multiples}') + + return model + + +def update_tokenizer_model_max_length(tokenizer, max_position): + """This function updates the position embedding length of a tokenizer to a new max position. + + Arguments: + tokenizer: required: a transformer tokenizer + max_position: required: an integer determining new position embedding size + Return: + tokenizer: updated tokenizer; in which model maximum length has been extended based on new size + """ + + tokenizer.model_max_length = max_position + tokenizer.init_kwargs['model_max_length'] = max_position + print(f'updated tokenizer model max imum length to {max_position}') + + return tokenizer + + +def replace_model_self_attention_with_sparse_self_attention(model, + max_position, + sparsity_config=None): + """This function replaces the self attention layers in model encoder with sparse self attention. + It currently supports bert and roberta model and can be easily extended to any other models following similar steps here. + For sparsityConfig, refer to the config class. + + Arguments: + model: required: a transformer model + max_position: required: an integer determining new position embedding size + sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on SparsityConfig class + + Return: + model: updated model; in which self attention layer has been repleaced with DeepSpeed Sparse Self Attention layer. + """ + + if hasattr(model, 'bert'): + model.config.max_position_embeddings = max_position + replace_self_attention_layer_with_sparse_self_attention_layer( + model.config, + model.bert.encoder.layer, + sparsity_config) + elif hasattr(model, 'roberta'): + model.config.max_position_embeddings = max_position + 2 + replace_self_attention_layer_with_sparse_self_attention_layer( + model.config, + model.roberta.encoder.layer, + sparsity_config) + else: + raise ValueError( + 'Please extend \"update_model_self_attention_to_sparse_self_attention\" function to support \ + your model type. It currently only supports \"bert\" & \"roberta\"!') + return model + + +def replace_self_attention_layer_with_sparse_self_attention_layer( + config, + layers, + sparsity_config=None): + """This function replaces the self attention layers in attention layer with sparse self attention. + For sparsityConfig, refer to the config class. + + Arguments: + config: required: transformer model config + layers: required: transformer model attention layers + sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on SparsityConfig class + + Return: + layers: updated attention layers; in which self attention layers have been repleaced with DeepSpeed Sparse Self Attention layer. + """ + + for layer in layers: + deepspeed_sparse_self_attn = DeepSpeedBertSparseSelfAttention( + config, + sparsity_config) + deepspeed_sparse_self_attn.query = layer.attention.self.query + deepspeed_sparse_self_attn.key = layer.attention.self.key + deepspeed_sparse_self_attn.value = layer.attention.self.value + + layer.attention.self = deepspeed_sparse_self_attn + + return layers diff --git a/deepspeed/trsrc/__init__.py b/deepspeed/trsrc/__init__.py new file mode 100644 index 000000000000..bc80704f6b57 --- /dev/null +++ b/deepspeed/trsrc/__init__.py @@ -0,0 +1,33 @@ +import sys +import os + + +def _build_file_index(directory, suffix='.tr'): + """Build an index of source files and their basenames in a given directory. + + Args: + directory (string): the directory to index + suffix (string): index files with this suffix + + Returns: + list: A list of tuples of the form [(basename, absolute path), ...] + """ + + index = [] + + for fname in os.listdir(directory): + if fname.endswith(suffix): + basename = fname[:fname.rfind(suffix)] # strip the suffix + path = os.path.join(directory, fname) + index.append((basename, path)) + + return index + + +# Go over all local source files and parse them as strings +_module = sys.modules[_build_file_index.__module__] +_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'sparse_transformer') +for name, fname in _build_file_index(_directory): + with open(fname, 'r') as fin: + setattr(_module, name, fin.read()) diff --git a/deepspeed/trsrc/sparse_transformer/matmul.tr b/deepspeed/trsrc/sparse_transformer/matmul.tr new file mode 100644 index 000000000000..61cd2a4299eb --- /dev/null +++ b/deepspeed/trsrc/sparse_transformer/matmul.tr @@ -0,0 +1,201 @@ +// DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +// https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py + +__global__ void NAME (TYPE* A __readonly __noalias __aligned(16), + TYPE* B __readonly __noalias __aligned(16), + TYPE* C __noalias __aligned(16), + int lda __multipleof(8), + int ldb __multipleof(8), + int ldc __multipleof(8), + long stride_za __multipleof(8), + long stride_zb __multipleof(8), + long stride_zc __multipleof(8), + long stride_ha __multipleof(8), + long stride_hb __multipleof(8), + long stride_hc __multipleof(8), + int DS0, int DS1, + int SDD_K __multipleof(16), + int SDD_off_width, + int* lut, int* locks, int nlocks) { + /* ---------------- */ + /* Prologue */ + /* ---------------- */ + // program ids + int pid0 = get_program_id(0); + int pid1 = get_program_id(1); + int pidz = get_program_id(2); +#ifdef SDD + // load LUT header + pid1 = pid1 + SDD_off_width; + int blockidm[TM] = (0 ... TM) / BLOCK; + int blockidn[TN] = (0 ... TN) / BLOCK; + int offlutm[TM] = blockidm*(TN/BLOCK)*4; + int offlutn[TN] = blockidn*4; + int *header = lut + pid1 * (TM/BLOCK) * (TN/BLOCK) * 4; + int z = *(header + 0); + int i[TM] = *(header + 1 + offlutm); + int j[TN] = *(header + 2 + offlutn); + int AS1 = SDD_K / TZ; + int lockid = select(TZ > 1, 1, 0); + int offka = pid0 * AS1; + int offkb = pid0 * AS1; + int offmc = 0; + int offnc = 0; + int offpa = 0; + int offpb = 0; + int maxid = TZ; + int offhc = 0; + int offha = z; + int offhb = z; + int ram[TM] = i*BLOCK + ((0 ... TM) % BLOCK); + int rbn[TN] = j*BLOCK + ((0 ... TN) % BLOCK); +#else + // load LUT header + int *header = lut + pid0 * 6; + int offset = *(header + 0); + int AS1 = *(header + 1); + int column = *(header + 2); + int depth = *(header + 3); + int lockid = *(header + 4); + int maxid = *(header + 5); + int *pinc = lut + offset; + int offhc = depth; +#ifdef DSD + // output offset + int offnc = pid1 * TN; + int offmc = column * TM; + int offpc = 0; + // dense input offset + int offnb = pid1 * TN; + int offkb __multipleof(8) = *pinc; + int offpb = 0; + // sparse input offset + int offma = 0; + int offka = 0; + long offpa __multipleof(8) = *(pinc + 1); + offpa = offpa * BLOCK * BLOCK; + int offha = 0; + int offhb = depth; +#endif +#ifdef DDS + // output offset + int offmc = pid1 * TM; + int offnc = column * TN; + int offpc = 0; + // dense input offset + int offma = pid1 * TM; + int offka __multipleof(8) = *pinc; + int offpa = 0; + // sparse input offset + int offnb = 0; + int offkb = 0; + long offpb __multipleof(8) = *(pinc + 1); + offpb = offpb * BLOCK * BLOCK; + int offha = depth; + int offhb = 0; +#endif + int ram[TM] = offma + 0 ... TM; + int rbn[TN] = offnb + 0 ... TN; +#endif + // initialize a, b pointers + int rka[TK] = offka + 0 ... TK; + int rkb[TK] = offkb + 0 ... TK; + TYPE* pa[TM, TK] = A + pidz * stride_za + offha * stride_ha + offpa + ram[:, newaxis] * STRIDE_AM + rka[newaxis, :] * STRIDE_AK; + TYPE* pb[TK, TN] = B + pidz * stride_zb + offhb * stride_hb + offpb + rbn[newaxis, :] * STRIDE_BN + rkb[:, newaxis] * STRIDE_BK; + // pre-fetch +#ifdef DDS + bool checkam[TM, TK] = ram[:, newaxis] < DS0; +#else + bool checkam[TM, TK] = AS1 > 0; +#endif +#ifdef DSD + bool checkbn[TK, TN] = rbn[newaxis, :] < DS0; +#else + bool checkbn[TK, TN] = AS1 > 0; +#endif + TYPE a[TM, TK] = checkam ? *pa : 0; + TYPE b[TK, TN] = checkbn ? *pb : 0; + + /* ---------------- */ + /* Inner Loop */ + /* ---------------- */ + // create result tile + float acc[TM, TN] = 0; + int step = TK; + for(int k = AS1; k > 0; k -= step) { + acc += a @ b; + // update pointers +#ifdef SDD + int inc_a = TK * STRIDE_AK; + int inc_b = TK * STRIDE_BK; +#else + pinc += 2; +#ifdef DSD + int inc_b __multipleof(8) = *pinc; + int inc_a __multipleof(8) = *(pinc + 1); + inc_b = inc_b * STRIDE_BK; +#endif +#ifdef DDS + int inc_a __multipleof(8) = *pinc; + int inc_b __multipleof(8) = *(pinc + 1); + inc_a = inc_a * STRIDE_AK; +#endif +#endif + pa += inc_a; + pb += inc_b; + // pre-fetch + bool checkak[TM, TK] = k > TK; + bool checkbk[TK, TN] = k > TK; + bool checka[TM, TK] = checkam && checkak; + bool checkb[TK, TN] = checkbk && checkbn; + a = *?(checka)pa; + b = *?(checkb)pb; + } + TYPE c[TM, TN] = acc; + + /* ---------------- */ + /* Epilogue */ + /* ---------------- */ + // initialize c pointers +#ifdef SDD + bool checkc[TM, TN] = 1; + // rematerialize + int rr_blockidm[TM] = (0 ... TM) / BLOCK; + int rr_blockidn[TN] = (0 ... TN) / BLOCK; + int rr_offlutm[TM] = rr_blockidm*(TN/BLOCK)*4; + int rr_offlutn[TN] = rr_blockidn*4; + int off_bkid[TM, TN] = 3 + rr_offlutm[:, newaxis] + rr_offlutn[newaxis, :]; + int bkid[TM, TN] = *(header + off_bkid); + long offpc[TM, TN] = bkid * BLOCK * BLOCK; + // range within blocks + int rcm[TM] = (0 ... TM) % BLOCK; + int rcn[TN] = (0 ... TN) % BLOCK; +#else + int rcm[TM] = offmc + 0 ... TM; + int rcn[TN] = offnc + 0 ... TN; +#ifdef DSD + bool checkc[TM, TN] = rcn[newaxis, :] < DS0; +#endif +#ifdef DDS + bool checkc[TM, TN] = rcm[:, newaxis] < DS0; +#endif +#endif + TYPE* pc[TM, TN] = C + offpc + offhc*stride_hc + pidz*stride_zc + rcm[:, newaxis]*STRIDE_CM + rcn[newaxis, :]*STRIDE_CN; + // write-back directly + if(lockid == 0) { + *?(checkc) pc = c; + } + // accumulate partial result using spin-locks + else { + int *plock = locks + get_program_id(2)*nlocks*get_num_programs(1) + get_program_id(1)*nlocks + lockid - 1; + int *pcount = plock + get_num_programs(2)*get_num_programs(1)*nlocks; + for(int repeat = 1; repeat == 1; repeat = atomic_cas(plock, 0, 1)); + int count = *pcount; + if(count == 0) + *?(checkc) pc = c; + else + *?(checkc) pc = c + *?(checkc)pc; + atomic_xchg(pcount, (count + 1) % maxid); + atomic_xchg(plock, 0); + } + } diff --git a/deepspeed/trsrc/sparse_transformer/softmax_bwd.tr b/deepspeed/trsrc/sparse_transformer/softmax_bwd.tr new file mode 100644 index 000000000000..358d6e5ea57e --- /dev/null +++ b/deepspeed/trsrc/sparse_transformer/softmax_bwd.tr @@ -0,0 +1,54 @@ +// DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +// https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/softmax.py + +__global__ void softmax_bwd(TYPE * X __readonly __noalias __aligned(16), + float scale, + TYPE* DX __readonly __noalias __aligned(16), + int* LUT, + int sizemax, + long stride_zx __multipleof(BLOCK), + long stride_zdx __multipleof(BLOCK)) { + int pidhm = get_program_id(0); + int pidz = get_program_id(1); + + // create index ranges + int rxm = pidhm % BLOCK; + int rbm = pidhm / BLOCK; + int rxn[TN] = (0 ... TN) % BLOCK; + int rbn[TN] = (0 ... TN) / BLOCK; + + // extract information from look-up table + int* header = LUT + rbm * 2; + int size = *(header + 0); + int offset = *(header + 1); + + // bounds checking on lut + bool check[TN] = rbn < size; + int rbmn[TN] = check ? rbn : size - 1; + + // initialize pointers to block-sparse input + long blockid[TN] = *(LUT + offset + rbmn*3); + + TYPE* px[TN] = X + pidz * stride_zx + + blockid * BLOCK * BLOCK + + rxm * BLOCK + + rxn; + + TYPE* pdx[TN] = DX + pidz * stride_zdx + + blockid * BLOCK * BLOCK + + rxm * BLOCK + + rxn; + + // compute fused softmax backward + TYPE x[TN] = check ? *px : 0; + TYPE dx[TN] = check ? *pdx : 0; + float Fdx[TN] = dx; + float Fx[TN] = x; + float Fxdx[TN] = Fdx*Fx; + float Fxdxsum = Fxdx[+]; + float Fy[TN] = Fx * (Fdx - Fxdxsum) * scale; + TYPE y[TN] = Fy; + + // write-back + *? (check)pdx = y; +} diff --git a/deepspeed/trsrc/sparse_transformer/softmax_fwd.tr b/deepspeed/trsrc/sparse_transformer/softmax_fwd.tr new file mode 100644 index 000000000000..5d5f162073e8 --- /dev/null +++ b/deepspeed/trsrc/sparse_transformer/softmax_fwd.tr @@ -0,0 +1,135 @@ +// DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +// https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/softmax.py + +__global__ void softmax_fwd(TYPE *X __readonly __noalias __aligned(16), + float scale, + int *LUT __readonly __noalias __aligned(16), + TYPE *RPE __readonly __noalias __aligned(16), + TYPE *KP_M __readonly __noalias __aligned(16), + TYPE *ATTN_M __readonly __noalias __aligned(16), + int num_blocks, int num_blocks_per_head, + int sizemax, + long stride_zx __multipleof(BLOCK), + long stride_zrpe __multipleof(BLOCK), + int stride_hrpe __multipleof(BLOCK), + int stride_srpe __multipleof(BLOCK), + int stride_zkpm __multipleof(BLOCK), + int stride_zattnm __multipleof(BLOCK)){ + int pidhm = get_program_id(0); + int pidz = get_program_id(1); + + // create index ranges + int rxm = pidhm % BLOCK; + int rbm = pidhm / BLOCK; + int rxn[TN] = (0 ... TN) % BLOCK; + int rbn[TN] = (0 ... TN) / BLOCK; + + // extract information from look-up table + int* header = LUT + rbm * 2; + int size = *(header + 0); + int offset = *(header + 1); + + bool check[TN] = rbn < size; + int rbmn[TN] = check ? rbn : size - 1; + + // block id and column id + long blockid [TN] = *(LUT + offset + rbmn*3 + 0); + long columnid[TN] = *(LUT + offset + rbmn*3 + 1); + long rowid [TN] = *(LUT + offset + rbmn*3 + 2); + + // pointers to X + TYPE* px[TN] = X + pidz * stride_zx + + blockid * BLOCK * BLOCK + + rxm * BLOCK + + rxn; +#ifdef APPLY_RPE + // pointers to relative position embedding + TYPE* prpe[TN] = RPE + pidz * stride_zrpe + + blockid / num_blocks_per_head * stride_hrpe + + columnid * BLOCK + + rowid * BLOCK * stride_srpe + + rxm * stride_srpe + + rxn; +#endif + +#ifdef APPLY_KP_MASK + // pointers to key padding mask + TYPE* pkp_m[TN] = KP_M + pidz * stride_zkpm + + columnid * BLOCK + + rxn; +#endif + +#ifdef APPLY_ATTN_MASK + // pointers to attention mask + TYPE* pattn_m[TN] = ATTN_M + columnid * BLOCK + + rowid * BLOCK * stride_zattnm + + rxm * stride_zattnm + + rxn; +#endif + + // load input + TYPE x[TN] = check ? *px : -INFINITY; + +#ifdef APPLY_RPE + // load relative position embedding + TYPE rpe[TN] = check ? *prpe : 0; +#endif + +#ifdef APPLY_KP_MASK + // load key-padding mask + TYPE kp_m[TN] = check ? *pkp_m : -INFINITY; +#endif + +#ifdef APPLY_ATTN_MASK + // load attention mask + TYPE attn_m[TN] = check ? *pattn_m : -INFINITY; +#endif + + // compute softmax in float +#ifdef APPLY_RPE + float Frpe[TN] = rpe; +#endif + +#ifdef APPLY_KP_MASK + float Fkp_m[TN] = kp_m; +#endif + +#ifdef APPLY_ATTN_MASK + float Fattn_m[TN] = attn_m; +#endif + +#ifdef KP_MASK_MUL + Fkp_m = (Fkp_m == 0) ? (float[TN])-INFINITY : 0; +#endif + +#ifdef ATTN_MASK_MUL + Fattn_m = (Fattn_m == 0) ? (float[TN])-INFINITY : 0; +#endif + + float Fx[TN] = x; + +#ifdef APPLY_SCALE + Fx = Fx * scale; // apply scale +#endif + +#ifdef APPLY_RPE + Fx = Fx + Frpe; // apply relative position embedding +#endif + +#ifdef APPLY_KP_MASK + Fx = Fx + Fkp_m; // apply key padding mask +#endif + +#ifdef APPLY_ATTN_MASK + Fx = Fx + Fattn_m; // apply attention mask +#endif + + float Fxmax = Fx[max]; + float Fy[TN] = exp(Fx - Fxmax); + float Fysum = (check ? Fy : 0)[+]; + + // write-back in half/float + TYPE y[TN] = Fy; + TYPE ysum = Fysum; + *?(check)px = y / ysum; +} diff --git a/requirements.txt b/requirements.txt index 9ccac27407f4..9ca0fd6e511b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ pytest pytest-forked pre-commit clang-format +triton>=0.2.1 diff --git a/setup.py b/setup.py index 24623a004b6e..d17b3ff4c57e 100755 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ import os import torch from setuptools import setup, find_packages -from torch.utils.cpp_extension import CUDAExtension, BuildExtension +from torch.utils.cpp_extension import CUDAExtension, BuildExtension, CppExtension cmdclass = {} cmdclass['build_ext'] = BuildExtension.with_options(use_ninja=False) @@ -114,6 +114,10 @@ '-D__STOCHASTIC_MODE__' ] }), + CppExtension(name='deepspeed_sparse_transformer_util', + sources=['csrc/sparse_transformer/utils.cpp'], + extra_compile_args={'cxx': ['-O2', + '-fopenmp']}) ] setup(name='deepspeed', @@ -125,6 +129,7 @@ packages=find_packages(exclude=["docker", "third_party", "csrc"]), + package_data={'': ['trsrc/sparse_transformer/*.tr']}, scripts=['bin/deepspeed', 'bin/deepspeed.pt', 'bin/ds', From 0d8bed947076695c54326c9c1123e7aeed203d77 Mon Sep 17 00:00:00 2001 From: Jeff Rasley Date: Wed, 5 Aug 2020 09:45:39 -0700 Subject: [PATCH 02/16] docker update (#66) --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 04d8530d4496..a29462485410 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,8 @@ RUN apt-get update && \ software-properties-common \ openssh-client openssh-server \ pdsh curl sudo net-tools \ - vim iputils-ping wget + vim iputils-ping wget \ + llvm-9-dev cmake ############################################################################## # Installation Latest Git @@ -85,7 +86,7 @@ RUN mkdir -p ${STAGE_DIR} && \ dpkg -i ${STAGE_DIR}/nvidia-peer-memory_${NV_PEER_MEM_TAG}_all.deb ############################################################################## -## Ucomment and set SSH Daemon port +## SSH daemon port inside container cannot conflict with host OS port ############################################################################### ENV SSH_PORT=2222 RUN cat /etc/ssh/sshd_config > ${STAGE_DIR}/sshd_config && \ From f1b34728cfde4b7f0bcdc3a0569d8625be14ff06 Mon Sep 17 00:00:00 2001 From: Arash Ashari Date: Tue, 11 Aug 2020 15:55:19 -0700 Subject: [PATCH 03/16] Adding/updating sparsity config (#68) * adding/updating sparsity config patterns * adding random to Variable sparsity * fixing a typo * applying comment adding missing argument docstring --- csrc/sparse_transformer/utils.cpp | 44 -- deepspeed/pt/sparse_transformer/__init__.py | 3 +- .../bert_sparse_self_attention.py | 22 +- deepspeed/pt/sparse_transformer/softmax.py | 12 +- .../sparse_self_attention.py | 215 +------ .../pt/sparse_transformer/sparsity_config.py | 575 ++++++++++++++++++ deepspeed/pt/sparse_transformer/utils.py | 19 +- .../trsrc/sparse_transformer/softmax_bwd.tr | 4 +- .../trsrc/sparse_transformer/softmax_fwd.tr | 13 +- 9 files changed, 627 insertions(+), 280 deletions(-) create mode 100644 deepspeed/pt/sparse_transformer/sparsity_config.py diff --git a/csrc/sparse_transformer/utils.cpp b/csrc/sparse_transformer/utils.cpp index 7e717596aa20..425b0e6b698b 100644 --- a/csrc/sparse_transformer/utils.cpp +++ b/csrc/sparse_transformer/utils.cpp @@ -115,51 +115,7 @@ ret_t sdd_segment(torch::Tensor layout, int start_width) return ret; } -torch::Tensor make_layout(int num_heads, - const std::string& mode, - int num_blocks, - int block_stride, - const std::string& attention, - int numverts, - int vertsize) -{ - /* - Currently this function is able to create 'dense' or 'fixed' layout as described here: - https://openai.com/blog/sparse-transformer/ You can extend this function to add any block-base - sparsity following the 'fixed' part below. - */ - std::vector shape = {{num_heads, num_blocks, num_blocks}}; - - // attention type is currently supposed to be either unidirectional or bidirectional - // adding any other type, you need to update this function accordingly - bool unidirectional = (attention == "unidirectional") ? true : false; - - if (mode == "dense") - return torch::ones(shape, torch::kLong); - else if (mode == "fixed") { - torch::Tensor ret = torch::zeros(shape, torch::kLong); - auto _ret = ret.accessor(); - for (int h = 0; h < num_heads; h++) { - // set first part of layout - for (int i = 0; i < num_blocks; i += block_stride) - for (int j = i; j < i + block_stride; j++) - for (int k = i; k < (unidirectional ? j + 1 : i + block_stride); k++) - _ret[h][j][k] = 1; - // set second part of layout - int start = block_stride - (1 + h % numverts) * vertsize; - for (int i = 0; i < num_blocks; i++) { - int end = unidirectional ? i : num_blocks; - for (int j = start; j < end; j += block_stride) - for (int k = j; k < j + vertsize; k += num_blocks) _ret[h][i][k] = 1; - } - } - return ret; - } - return torch::zeros(shape, torch::kLong); -} - PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { - m.def("make_layout", &make_layout, "make sparsity layout"); m.def("sdd_segment", &sdd_segment, "SDD segmentation handler"); } diff --git a/deepspeed/pt/sparse_transformer/__init__.py b/deepspeed/pt/sparse_transformer/__init__.py index 688c7e59eccf..73d025890fa6 100644 --- a/deepspeed/pt/sparse_transformer/__init__.py +++ b/deepspeed/pt/sparse_transformer/__init__.py @@ -1,5 +1,6 @@ +from .sparsity_config import SparsityConfig, DenseSparsityConfig, FixedSparsityConfig, VariableSparsityConfig, BigBirdSparsityConfig, BSLongformerSparsityConfig from .softmax import Softmax from .matmul import MatMul -from .sparse_self_attention import SparseSelfAttention, SparsityConfig +from .sparse_self_attention import SparseSelfAttention from .bert_sparse_self_attention import BertSparseSelfAttention from .utils import extend_position_embedding, update_tokenizer_model_max_length, replace_model_self_attention_with_sparse_self_attention, replace_self_attention_layer_with_sparse_self_attention_layer diff --git a/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py b/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py index 320e542002fa..2f87c8474609 100755 --- a/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py +++ b/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py @@ -3,7 +3,7 @@ """ from torch import nn -from deepspeed.pt.sparse_transformer import SparseSelfAttention, SparsityConfig +from deepspeed.pt.sparse_transformer import SparseSelfAttention, FixedSparsityConfig class BertSparseSelfAttention(nn.Module): @@ -13,18 +13,19 @@ class BertSparseSelfAttention(nn.Module): For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial. """ - def __init__(self, - config, - sparsity_config=SparsityConfig('fixed', - 16, - 64, - 'bidirectional', - 4, - 1)): + def __init__( + self, + config, + # SparsityConfig parameters needs to be set accordingly + sparsity_config=FixedSparsityConfig(num_heads=4, + seq_len=1024)): """Initialize the bert sparse self attention layer. + + Note) you can use any of the provided sparsity configs or simply add yours! + Arguments: config: required: Bert model config - sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on SparsityConfig class. + sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on FixedSparsityConfig class. """ super(BertSparseSelfAttention, self).__init__() @@ -41,7 +42,6 @@ def __init__(self, self.key = nn.Linear(config.hidden_size, self.all_head_size) self.value = nn.Linear(config.hidden_size, self.all_head_size) - self.sparsity_config = sparsity_config self.sparse_self_attention = SparseSelfAttention(sparsity_config) def transpose_for_scores(self, x): diff --git a/deepspeed/pt/sparse_transformer/softmax.py b/deepspeed/pt/sparse_transformer/softmax.py index 1ae733a25c3b..0c00a9b216d7 100644 --- a/deepspeed/pt/sparse_transformer/softmax.py +++ b/deepspeed/pt/sparse_transformer/softmax.py @@ -1,4 +1,4 @@ -# DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +# DeepSpeed note, code taken & adapted from commit beddcc3eda6d3df1b34f74c2e10139e4317d0e7f # https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py import triton @@ -26,11 +26,12 @@ def make_lut(layout, block, device): offsets[1:] = torch.cumsum(sizes[:-1], dim=0) # block indices idx = torch.arange(layout.sum()) + head = layout.nonzero()[:, 0] rows = layout.nonzero()[:, 1] columns = layout.nonzero()[:, 2] - core = torch.stack((idx, columns, rows), dim=1).view(-1) + core = torch.stack((idx, columns, rows, head), dim=1).view(-1) # construct look-up table - offsets = offsets * 3 + 2 * sizes.numel() + offsets = offsets * 4 + 2 * sizes.numel() header = torch.stack((sizes, offsets), dim=1).view(-1) lut = torch.cat((header, core)).type(torch.int32).to(device) return lut, int(sizes.max()) @@ -104,7 +105,6 @@ def forward(ctx, block, lut, num_blocks, - num_blocks_per_head, maxlut, bench, time): @@ -154,7 +154,7 @@ def forward(ctx, # run kernel time[0] = kernel(x, scale, lut, rpe, key_padding_mask, attn_mask,\ - num_blocks, num_blocks_per_head, maxlut,\ + num_blocks, maxlut,\ x.stride(0),\ stride_zrpe, stride_hrpe, stride_srpe,\ stride_zkpm, stride_zattnm,\ @@ -231,7 +231,6 @@ def __init__(self, layout, block, bench=False): """ self.num_blocks = layout.sum() - self.num_blocks_per_head = self.num_blocks / layout.shape[0] self.spdims = layout.shape self.layout = layout self.block = block @@ -282,7 +281,6 @@ def __call__(self, self.block, lut, self.num_blocks, - self.num_blocks_per_head, maxlut, self.bench, time_y) diff --git a/deepspeed/pt/sparse_transformer/sparse_self_attention.py b/deepspeed/pt/sparse_transformer/sparse_self_attention.py index b143bdadbfae..44740b596138 100644 --- a/deepspeed/pt/sparse_transformer/sparse_self_attention.py +++ b/deepspeed/pt/sparse_transformer/sparse_self_attention.py @@ -6,50 +6,9 @@ from torch.nn.functional import * import torch from collections import namedtuple -import deepspeed_sparse_transformer_util -from deepspeed.pt.sparse_transformer import MatMul, Softmax +from deepspeed.pt.sparse_transformer import MatMul, Softmax, SparsityConfig import sys -make_layout = deepspeed_sparse_transformer_util.make_layout - - -class SparsityConfig: - """Configuration class to store sparsity configuration of a self attention layer`. - """ - def __init__(self, - mode='fixed', - block=16, - stride=64, - attention='bidirectional', - numverts=1, - vertsize=1): - """Initialize the Sparsity Pattern Config. - - For more details about sparsity config, please see `Generative Modeling with Sparse Transformers`: https://arxiv.org/abs/1904.10509 - - For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial - - Arguments: - mode: optional: a string determining the sparsity mode. In addition to `dense`, currently we support `fixed` mode that combines local and global attention suitable for document modeling. - block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. - stride: optional: an integer determining the local attention window size. - attention: optional: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. - numverts: optional: an integer determining number of different global attentions. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks local window and global attention size of 1, we can have 4 different versions in which first, Second, third, or forth block of each local window be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on block and stride size. As an example, considering one block as global representative, in the above figure, there are maximum of four versions of global attention. - vertsize: optional: an integer determining how many consecutive blocks a local window is used for global attention. - """ - if mode != 'dense' and mode != 'fixed': - raise NotImplementedError( - 'only \"dense\" and \"fixed\" modes are supported for now') - self.mode = mode - self.block = block - self.stride = stride - if attention != 'unidirectional' and attention != 'bidirectional': - raise NotImplementedError( - 'only \"uni/bi-directional\" attentions are supported for now') - self.attention = attention - self.numverts = numverts - self.vertsize = vertsize - class SparseSelfAttention(nn.Module): """Implements an efficient Sparse Self Attention of Transformer layer based on `Generative Modeling with Sparse Transformers`: https://arxiv.org/abs/1904.10509 @@ -58,10 +17,13 @@ class SparseSelfAttention(nn.Module): For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial. """ - def __init__(self, - sparsity_config=SparsityConfig(), - key_padding_mask_mode='add', - attn_mask_mode='mul'): + def __init__( + self, + # SparsityConfig parameters needs to be set accordingly + sparsity_config=SparsityConfig(num_heads=4, + seq_len=1024), + key_padding_mask_mode='add', + attn_mask_mode='mul'): """Initialize the sparse self attention layer. Arguments: sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on SparsityConfig class. @@ -77,175 +39,26 @@ def __init__(self, self.key_padding_mask_mode = key_padding_mask_mode self.attn_mask_mode = attn_mask_mode - @staticmethod - def _set_local_layout(layout, h, num_blocks, block_stride, attention): - """Sets local attantion layout used by the given head in the sparse attention. - - Arguments: - layout: required: sparsity layout tensor - h: required: an integer determining head index - num_blocks: required: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. - block_stride: required: an integer determining the local attention window size. - attention: required: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. - Return: - layout: the layout tensor in which the local attention for head #h has been set - """ - - for i in range(0, num_blocks, block_stride): - for j in range(i, i + block_stride): - for k in range( - i, - (j + 1 if attention == 'unidirectional' else i + block_stride)): - layout[h, j, k] = 1 - return layout - - @staticmethod - def _set_global_layout(layout, - h, - num_blocks, - block_stride, - attention, - numverts, - vertsize): - """Sets global attantion layout used by the given head in the sparse attention. - - Arguments: - layout: required: sparsity layout tensor - h: required: an integer determining head index - num_blocks: required: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. - block_stride: required: an integer determining the local attention window size. - attention: required: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. - numverts: required: an integer determining number of different global attentions. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks local window and global attention size of 1, we can have 4 different versions in which first, Second, third, or forth block of each local window be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on block and stride size. As an example, considering one block as global representative, in the above figure, there are maximum of four versions of global attention. - vertsize: required: an integer determining how many consecutive blocks a local window is used for global attention. - Return: - layout: the layout tensor in which the global attention for head #h has been set - """ - - start = block_stride - (1 + h % numverts) * vertsize - for i in range(0, num_blocks): - end = i if attention == 'unidirectional' else num_blocks - for j in range(start, end, block_stride): - for k in range(j, min(j + vertsize, num_blocks)): - layout[h, i, k] = 1 - return layout - - @staticmethod - def _make_layout_python(num_heads, - mode, - num_blocks, - block_stride, - attention, - numverts, - vertsize): - """Generates sparsity layout used by each head in the sparse attention. - Currently this function is able to create 'dense' or 'fixed' layout as described here: https://arxiv.org/abs/1904.10509 - - This function can be extend to add any block-base sparsity following the 'fixed' part below. - - Arguments: - num_heads: required: an integer determining number of heads of the model - mode: required: a string determining the sparsity mode. In addition to `dense`, currently we support `fixed` mode that combines local and global attention suitable for document modeling. - num_blocks: required: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. - block_stride: required: an integer determining the local attention window size. - attention: required: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. - numverts: required: an integer determining number of different global attentions. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks local window and global attention size of 1, we can have 4 different versions in which first, Second, third, or forth block of each local window be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on block and stride size. As an example, considering one block as global representative, in the above figure, there are maximum of four versions of global attention. - vertsize: required: an integer determining how many consecutive blocks a local window is used for global attention. - Return: - layout: a tensor determining the sparsity layout of each head - """ - - if (block_stride % vertsize) != 0: - raise ValueError( - f'Number of blocks in a stride window {block_stride} must be dividable by vertical block size {vertsize}' - ) - - if numverts > (block_stride / vertsize): - raise ValueError( - f'Number of layout versions {num_verts} cannot be larger than blocks in a stride window divided by vertical block size {block_stride} / {vertsize} = {block_stride/vertsize}' - ) - - layout = torch.zeros((num_heads, num_blocks, num_blocks), dtype=torch.int64) - if mode == "dense": - layout[:, :, :] = 1 - elif mode == "fixed": - for i in range(0, num_heads): - layout = SparseSelfAttention._set_local_layout( - layout, - i, - num_blocks, - block_stride, - attention) - layout = SparseSelfAttention._set_global_layout( - layout, - i, - num_blocks, - block_stride, - attention, - numverts, - vertsize) - else: - raise NotImplementedError( - 'Only \"dense\" and \"fixed\" modes are supported for now!') - - return layout - - @staticmethod - def _make_layout(num_heads, - mode, - num_blocks, - block_stride, - attention, - numverts, - vertsize): - return make_layout(num_heads, - mode, - num_blocks, - block_stride, - attention, - numverts, - vertsize) - ops = dict() # add to cache def get_ops(self, H, L): import sys if L not in SparseSelfAttention.ops: - spConfig = self.sparsity_config - - if L % spConfig.block != 0: - raise ValueError( - f'Sequence length {L} must be dividable by block size {spConfig.block}' - ) - num_blocks = L // spConfig.block - - if spConfig.stride % spConfig.block != 0: - raise ValueError( - f'Stride {spConfig.stride} must be dividable by block size {spConfig.block}' - ) - block_stride = spConfig.stride // spConfig.block - - layout = SparseSelfAttention._make_layout(H, - num_blocks, - spConfig.mode, - block_stride, - spConfig.attention, - spConfig.numverts, - spConfig.vertsize) - - sparse_dot_sdd_nt = MatMul(layout, - spConfig.block, + sparse_dot_sdd_nt = MatMul(self.sparsity_config.layout, + self.sparsity_config.block, 'sdd', trans_a=False, trans_b=True) - sparse_dot_dsd_nn = MatMul(layout, - spConfig.block, + sparse_dot_dsd_nn = MatMul(self.sparsity_config.layout, + self.sparsity_config.block, 'dsd', trans_a=False, trans_b=False) - sparse_softmax = Softmax(layout, spConfig.block) + sparse_softmax = Softmax(self.sparsity_config.layout, + self.sparsity_config.block) SparseSelfAttention.ops[L] = (sparse_dot_sdd_nt, sparse_dot_dsd_nn, diff --git a/deepspeed/pt/sparse_transformer/sparsity_config.py b/deepspeed/pt/sparse_transformer/sparsity_config.py new file mode 100644 index 000000000000..d282da9c9f97 --- /dev/null +++ b/deepspeed/pt/sparse_transformer/sparsity_config.py @@ -0,0 +1,575 @@ +""" +Copyright 2020 The Microsoft DeepSpeed Team +""" + +import torch +import random + + +class SparsityConfig: + """Abstract Configuration class to store `sparsity configuration of a self attention layer`. + It contains shared property of different block-sparse sparsity patterns. However, each class needs to extend it based on required property and functionality. + """ + def __init__(self, num_heads, seq_len, block=16, different_layout_per_head=False): + """Initialize the Sparsity Pattern Config. + + For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial + + Arguments: + num_heads: required: an integer determining number of attention heads of the layer. + seq_len: required: an integer determining number of attention heads of the layer. + block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. + different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. + """ + + self.num_heads = num_heads + if (seq_len % block != 0): + raise ValueError( + f'Sequence Length, {seq_len}, needs to be dividable by Block size {block}!' + ) + self.seq_len = seq_len + self.block = block + self.num_blocks = seq_len // block + self.different_layout_per_head = different_layout_per_head + # TODO (ARASH) Currently we allocate layout per head; needs to be updated if heads share a single layout. + self.layout = torch.zeros((self.num_heads, + self.num_blocks, + self.num_blocks), + dtype=torch.int64) + self.num_layout_heads = num_heads if different_layout_per_head else 1 + + def check_and_propagate_first_head_layout(self): + if not self.different_layout_per_head: + self.layout[1:self.num_heads, :, :] = self.layout[0, :, :] + + +class DenseSparsityConfig(SparsityConfig): + def __init__(self, + num_heads=8, + seq_len=1024, + block=16, + different_layout_per_head=False): + """Initialize the Dense Sparsity Pattern Config. + In reality, this is not sparse and all blocks are used. We keep it for the sake of comparison and comprehension. + + Arguments: + num_heads: required: an integer determining number of attention heads of the layer. + seq_len: required: an integer determining number of attention heads of the layer. + block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. + different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. This argument can be completely ignored and we kept it here for consistency with the parent class. + """ + super().__init__(num_heads, seq_len, block, different_layout_per_head) + self.make_layout() + + def make_layout(self): + """Set 1 to all blocks of the layout meanins the pattern is dense; not sparse. + """ + self.layout[:, :, :] = 1 + return self.layout + + +class FixedSparsityConfig(SparsityConfig): + """Configuration class to store `Fixed` sparsity configuration. + For more details about this sparsity config, please see `Generative Modeling with Sparse Transformers`: https://arxiv.org/abs/1904.10509; this has been customized. + This class extends parent class of `SparsityConfig` and customizes it for `Fixed` sparsity. + """ + def __init__(self, + num_heads, + seq_len, + block=16, + different_layout_per_head=False, + num_local_blocks=4, + num_global_blocks=1, + attention='bidirectional', + horizontal_global_attention=False, + num_differnt_global_patterns=1): + """Initialize `Fixed` Sparsity Pattern Config. + + For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial + + Arguments: + num_heads: required: an integer determining number of attention heads of the layer. + seq_len: required: an integer determining number of attention heads of the layer. + block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. + different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. + num_local_blocks: optional: an integer determining the number of blocks in local attention window. + num_global_blocks: optional: an integer determining how many consecutive blocks in a local window is used as the representetive of the window for global attention. + attention: optional: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. + horizontal_global_attention: optional: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but aso horizontal blocks. + num_differnt_global_patterns: optional: an integer determining number of different global attentions layouts. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks local window and global attention size of 1 block, we can have 4 different versions in which the first, Second, third, or forth block of each local window can be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on num_local_blocks and num_global_blocks. + """ + super().__init__(num_heads, seq_len, block, different_layout_per_head) + + if (seq_len % (block * num_local_blocks) != 0): + raise ValueError( + f'Sequence Length, {seq_len}, must be dividable by local window, {block*num_local_blocks}!' + ) + self.num_local_blocks = num_local_blocks + + if (num_local_blocks % num_global_blocks != 0): + raise ValueError( + f'Number of blocks in a local window, {num_local_blocks}, must be dividable by number of global blocks, {num_global_blocks}!' + ) + self.num_global_blocks = num_global_blocks + + if (attention != 'unidirectional' and attention != 'bidirectional'): + raise NotImplementedError( + 'only \"uni/bi-directional\" attentions are supported for now!') + self.attention = attention + + if (attention != 'bidirectional' and horizontal_global_attention): + raise ValueError( + 'only \"bi-directional\" attentions can support horizontal global attention!' + ) + self.horizontal_global_attention = horizontal_global_attention + + if (num_differnt_global_patterns > 1 and not different_layout_per_head): + raise ValueError( + f'Number of different layouts cannot be more than one when you have set a single layout for all heads! Set different_layout_per_head to True.' + ) + if (num_differnt_global_patterns > (num_local_blocks // num_global_blocks)): + raise ValueError( + f'Number of layout versions (num_differnt_global_patterns), {num_differnt_global_patterns}, cannot be larger than number of local window blocks divided by number of global blocks, {num_local_blocks} / {num_global_blocks} = {num_local_blocks//num_global_blocks}!' + ) + self.num_differnt_global_patterns = num_differnt_global_patterns + self.make_layout() + + def set_local_layout(self, h): + """Sets local attantion layout used by the given head in the sparse attention. + + Arguments: + h: required: an integer determining head index + """ + for i in range(0, self.num_blocks, self.num_local_blocks): + for row in range(i, i + self.num_local_blocks): + for col in range(i, + (row + 1 if self.attention == 'unidirectional' else i + + self.num_local_blocks)): + self.layout[h, row, col] = 1 + + def set_global_layout(self, h): + """Sets global attantion layout used by the given head in the sparse attention. + + Currently we set global blocks starting from the last block of a local window to the first one. That means if a local window consists of 4 blocks and global attention size is one block, we use block #4 in each local window as global. If we have different layout per head, then other heads will get #3, #2, and #1. And if we have more heads (and different layout has set) than num of global attentions, multiple head may have same global attentions. + Note) if horizontal_global_attention is set, global blocks will be set both horizontally and vertically. + + Arguments: + h: required: an integer determining head index + """ + first_global_block_idx = self.num_local_blocks - ( + 1 + h % self.num_differnt_global_patterns) * self.num_global_blocks + for i in range(first_global_block_idx, self.num_blocks, self.num_local_blocks): + + # vertical global attention + first_row = 0 if self.attention == 'bidirectional' else (( + (i // self.num_local_blocks) + 1) * self.num_local_blocks) + self.layout[h, first_row:, i:i + self.num_global_blocks] = 1 + ''' + for row in range(first_row, self.num_blocks): + for col in range(i, i + self.num_global_blocks): + self.layout[h, row, col] = 1 + ''' + + # horizontal global attention + if (self.horizontal_global_attention): + self.layout[h, i:i + self.num_global_blocks, :] = 1 + ''' + for row in range(i, i + self.num_global_blocks): + for col in range(0, self.num_blocks): + self.layout[h, row, col] = 1 + ''' + + def make_layout(self): + """Generates `Fixed` sparsity layout used by each head in the sparse attention. + + Return: + layout: a tensor determining the sparsity layout of each head + """ + + for h in range(0, self.num_layout_heads): + self.set_local_layout(h) + self.set_global_layout(h) + + self.check_and_propagate_first_head_layout() + return self.layout + + +class VariableSparsityConfig(SparsityConfig): + """Configuration class to store `Variable` sparsity configuration. + This layout is an extension of FixedSparsityConfig in which: + - user can set random layout; default value is zero means no random block + - user can provide a list of local block sizes + - user can provide a list of global block indices. + + For more details about `Fixed` sparsity config, please see `Generative Modeling with Sparse Transformers`: https://arxiv.org/abs/1904.10509; this has been customized. + This class extends parent class of `SparsityConfig` and customizes it for `Fixed` sparsity. + """ + def __init__(self, + num_heads, + seq_len, + block=16, + different_layout_per_head=False, + num_random_blocks=0, + local_window_blocks=[4], + global_block_indices=[0], + global_block_end_indices=None, + attention='bidirectional', + horizontal_global_attention=False): + """Initialize `Variable` Sparsity Pattern Config. + + For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial + + Arguments: + num_heads: required: an integer determining number of attention heads of the layer. + seq_len: required: an integer determining number of attention heads of the layer. + block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. + different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. Currently this sparsity config can only assign single layout to all heads; needs to be extended for different layout per head. + num_random_blocks: optional: an integer determining the number of random blocks in each block row. + local_window_blocks: optional: a list of integers determining the number of blocks in each local attention window. It assumes first number determines # of blocks in the first local window, second the second window, ..., and the last number determines the number of blocks in the remaining local windows. + global_block_indices: optional: a list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Default value is only index 0. Notice that if global_block_end_indices parameter is set, this parameter is used as starting index of each global window. + global_block_end_indices: optional: a list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size of global_block_indices parameter, and combining this two parameters, for each index i, blocks from global_block_indices[i] to global_block_end_indices[i] (exclusive) are considered as global attention. + num_global_blocks: optional: an integer determining how many consecutive blocks in a local window is used as the representetive of the window for global attention. + attention: optional: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. + horizontal_global_attention: optional: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but aso horizontal blocks. + """ + super().__init__(num_heads, seq_len, block, different_layout_per_head) + + all_local_blocks = 0 + for local_blocks in local_window_blocks: + all_local_blocks += local_blocks + if (self.num_blocks < all_local_blocks): + raise ValueError( + f'Number of all local window blocks, {all_local_blocks}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' + ) + self.local_window_blocks = local_window_blocks + if (self.num_blocks < len(global_block_indices)): + raise ValueError( + f'Number of global blocks indices, {global_block_indices}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' + ) + for idx in global_block_indices: + if idx >= self.num_blocks: + raise ValueError( + f'Global block index, {global_block_indices[idx]}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' + ) + self.global_block_indices = global_block_indices + + if (global_block_end_indices is not None): + if (len(global_block_indices) != len(global_block_end_indices)): + raise ValueError( + f'Global block start indices length, {len(global_block_indices)}, must be same as global block end indices length, {len(global_block_end_indices)}!' + ) + for _, (start_idx, end_idx) in enumerate(zip(global_block_indices, global_block_end_indices)): + if end_idx > self.num_blocks: + raise ValueError( + f'Global block end index, {global_block_end_indices[idx]}, must be smaller (equal) than overal number of blocks in a row, {self.num_blocks}!' + ) + if start_idx >= end_idx: + raise ValueError( + f'Global block start index, {start_idx}, must be smaller than global block end index, {end_idx}!' + ) + self.global_block_end_indices = global_block_end_indices + + if (attention != 'unidirectional' and attention != 'bidirectional'): + raise NotImplementedError( + 'only \"uni/bi-directional\" attentions are supported for now!') + self.attention = attention + + if (attention != 'bidirectional' and horizontal_global_attention): + raise ValueError( + 'only \"bi-directional\" attentions can support horizontal global attention!' + ) + self.horizontal_global_attention = horizontal_global_attention + self.make_layout() + + def set_random_layout(self, h): + """Sets random attantion layout used by the given head in the sparse attention. + Note) By default, it assumes there will be a unique random block layout for all heads; unless `different_layout_per_head` parameter is set in which each head can have a different random layout. + + Arguments: + h: required: an integer determining head index + """ + + for row in range(0, self.num_blocks): + rnd_cols = random.sample(range(0, self.num_blocks), self.num_random_blocks) + self.layout[h, row, rnd_cols] = 1 + + def set_local_layout(self, h): + """Sets local attantion layout used by the given head in the sparse attention. + + Arguments: + h: required: an integer determining head index + """ + start_block_idx = 0 + end_block_idx = 0 + for block_size in self.local_window_blocks: + end_block_idx += block_size + end_block_idx = min(end_block_idx, self.num_blocks) + for row in range(start_block_idx, end_block_idx): + for col in range( + start_block_idx, + (row + 1 if self.attention == 'unidirectional' else end_block_idx)): + self.layout[h, row, col] = 1 + start_block_idx += block_size + + # if there is any remaining not attended part, use the lats local window block size as local window for the remaining applicable local windows + for i in range(start_block_idx, self.num_blocks, block_size): + end_block_idx = min(i + block_size, self.num_blocks) + for row in range(i, end_block_idx): + for col in range( + i, + (row + 1 if self.attention == 'unidirectional' else end_block_idx)): + self.layout[h, row, col] = 1 + + def set_global_layout(self, h): + """Sets global attantion layout used by the given head in the sparse attention. + + Arguments: + h: required: an integer determining head index + """ + if (self.global_block_end_indices is None): + for idx in self.global_block_indices: + #global rows + if (self.horizontal_global_attention): + self.layout[h, idx, :] = 1 + + #global columns + self.layout[h, :, idx] = 1 + else: + for _, (start_idx, end_idx) in enumerate(zip(self.global_block_indices, self.global_block_end_indices)): + #global rows + if (self.horizontal_global_attention): + self.layout[h, start_idx:end_idx, :] = 1 + + #global columns + self.layout[h, :, start_idx:end_idx] = 1 + + def make_layout(self): + """Generates `Fixed` sparsity layout used by each head in the sparse attention. + + Return: + layout: a tensor determining the sparsity layout of each head + """ + + for h in range(0, self.num_layout_heads): + self.set_random_layout(h) + self.set_local_layout(h) + self.set_global_layout(h) + + self.check_and_propagate_first_head_layout() + return self.layout + + +class BigBirdSparsityConfig(SparsityConfig): + """Configuration class to store `BigBird` sparsity configuration. + For more details about this sparsity config, please see `Big Bird: Transformers for Longer Sequences`: https://arxiv.org/pdf/2007.14062.pdf + This class extends parent class of `SparsityConfig` and customizes it for `BigBird` sparsity. + """ + def __init__(self, + num_heads=8, + seq_len=1024, + block=16, + different_layout_per_head=False, + num_random_blocks=1, + num_sliding_window_blocks=3, + num_global_blocks=1): + """Initialize the BigBird Sparsity Pattern Config. + + For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial + + Arguments: + num_heads: required: an integer determining number of attention heads of the layer. + seq_len: required: an integer determining number of attention heads of the layer. + block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. + different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. + num_random_blocks: optional: an integer determining the number of random blocks in each block row. + num_sliding_window_blocks: optional: an integer determining the number of blocks in sliding local attention window. + num_global_blocks: optional: an integer determining how many consecutive blocks, starting from index 0, are considered as global attention. Global block tokens will be attended by all other block tokens and will attend to all other block tokens as well. + """ + super().__init__(num_heads, seq_len, block, different_layout_per_head) + + if (self.num_blocks < num_random_blocks): + raise ValueError( + f'Number of random blocks, {num_random_blocks}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' + ) + self.num_random_blocks = num_random_blocks + + if (self.num_blocks < num_sliding_window_blocks): + raise ValueError( + f'Number of sliding window blocks, {num_sliding_window_blocks}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' + ) + self.num_sliding_window_blocks = num_sliding_window_blocks + + if (self.num_blocks < num_global_blocks): + raise ValueError( + f'Number of global blocks, {num_global_blocks}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' + ) + self.num_global_blocks = num_global_blocks + self.make_layout() + + def set_random_layout(self, h): + """Sets random attantion layout used by the given head in the sparse attention. + Note) By default, it assumes there will be a unique random block layout for all heads; unless `different_layout_per_head` parameter is set in which each head can have a different random layout. + + Arguments: + h: required: an integer determining head index + """ + + for row in range(0, self.num_blocks): + rnd_cols = random.sample(range(0, self.num_blocks), self.num_random_blocks) + self.layout[h, row, rnd_cols] = 1 + + def set_sliding_window_layout(self, h): + """Sets sliding local attantion layout used by the given head in the sparse attention. + + Arguments: + h: required: an integer determining head index + """ + + w = self.num_sliding_window_blocks // 2 + for row in range(0, self.num_blocks): + start = max(0, row - w) + end = min(row + w + 1, self.num_blocks) + self.layout[h, row, start:end] = 1 + + def set_global_layout_itc(self, h): + """Sets global attantion layout used by the given head in the sparse attention. + + Arguments: + h: required: an integer determining head index + """ + + #global rows + self.layout[h, 0:self.num_global_blocks, :] = 1 + + #global columns + self.layout[h, :, 0:self.num_global_blocks] = 1 + + def make_layout(self): + """Generates `BigBird` sparsity layout used by each head in the sparse attention. + + Return: + layout: a tensor determining the sparsity layout of each head + """ + + for h in range(0, self.num_layout_heads): + self.set_random_layout(h) + self.set_sliding_window_layout(h) + self.set_global_layout_itc(h) + + self.check_and_propagate_first_head_layout() + return self.layout + + +class BSLongformerSparsityConfig(SparsityConfig): + """Configuration class to store edited `Longformer` sparsity configuration. + + Note) this is a block-sparse version of the Longformer which is slightly different than original Longformer; which is element-wise sparsity. + + For more details about this sparsity config, please see `Longformer: The Long-Document Transformer`: https://arxiv.org/pdf/2004.05150.pdf + This class extends parent class of `SparsityConfig` and customizes it for `Longformer` sparsity. + """ + def __init__(self, + num_heads=8, + seq_len=1024, + block=16, + different_layout_per_head=False, + num_sliding_window_blocks=3, + global_block_indices=[0], + global_block_end_indices=None): + """Initialize the edited `Longformer` Sparsity Pattern Config. + + For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial + + Arguments: + num_heads: required: an integer determining number of attention heads of the layer. + seq_len: required: an integer determining number of attention heads of the layer. + block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. + different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. + + num_sliding_window_blocks: optional: an integer determining the number of blocks in sliding local attention window. + global_block_indices: optional: a list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Default value is only index 0. Notice that if global_block_end_indices parameter is set, this parameter is used as starting index of each global window. + global_block_end_indices: optional: a list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size of global_block_indices parameter, and combining this two parameters, for each index i, blocks from global_block_indices[i] to global_block_end_indices[i] (exclusive) are considered as global attention. + """ + super().__init__(num_heads, seq_len, block, different_layout_per_head) + + if (self.num_blocks < num_sliding_window_blocks): + raise ValueError( + f'Number of sliding window blocks, {num_sliding_window_blocks}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' + ) + self.num_sliding_window_blocks = num_sliding_window_blocks + + if (self.num_blocks < len(global_block_indices)): + raise ValueError( + f'Number of global blocks indices, {global_block_indices}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' + ) + for idx in global_block_indices: + if idx >= self.num_blocks: + raise ValueError( + f'Global block index, {global_block_indices[idx]}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' + ) + self.global_block_indices = global_block_indices + + if (global_block_end_indices is not None): + if (len(global_block_indices) != len(global_block_end_indices)): + raise ValueError( + f'Global block start indices length, {len(global_block_indices)}, must be same as global block end indices length, {len(global_block_end_indices)}!' + ) + for _, (start_idx, end_idx) in enumerate(zip(global_block_indices, global_block_end_indices)): + if end_idx > self.num_blocks: + raise ValueError( + f'Global block end index, {global_block_end_indices[idx]}, must be smaller (equal) than overal number of blocks in a row, {self.num_blocks}!' + ) + if start_idx >= end_idx: + raise ValueError( + f'Global block start index, {start_idx}, must be smaller than global block end index, {end_idx}!' + ) + self.global_block_end_indices = global_block_end_indices + self.make_layout() + + def set_sliding_window_layout(self, h): + """Sets sliding local attantion layout used by the given head in the sparse attention. + + Arguments: + h: required: an integer determining head index + """ + + w = self.num_sliding_window_blocks // 2 + for row in range(0, self.num_blocks): + start = max(0, row - w) + end = min(row + w + 1, self.num_blocks) + self.layout[h, row, start:end] = 1 + + def set_global_layout(self, h): + """Sets global attantion layout used by the given head in the sparse attention. + + Arguments: + h: required: an integer determining head index + """ + if (self.global_block_end_indices is None): + for idx in self.global_block_indices: + #global rows + self.layout[h, idx, :] = 1 + + #global columns + self.layout[h, :, idx] = 1 + else: + for _, (start_idx, end_idx) in enumerate(zip(self.global_block_indices, self.global_block_end_indices)): + #global rows + self.layout[h, start_idx:end_idx, :] = 1 + + #global columns + self.layout[h, :, start_idx:end_idx] = 1 + + def make_layout(self): + """Generates edited `Longformer` sparsity layout used by each head in the sparse attention. + + Return: + layout: a tensor determining the sparsity layout of each head + """ + + for h in range(0, self.num_layout_heads): + self.set_sliding_window_layout(h) + self.set_global_layout(h) + + self.check_and_propagate_first_head_layout() + return self.layout diff --git a/deepspeed/pt/sparse_transformer/utils.py b/deepspeed/pt/sparse_transformer/utils.py index 516a466f2e70..e9814be79ed5 100644 --- a/deepspeed/pt/sparse_transformer/utils.py +++ b/deepspeed/pt/sparse_transformer/utils.py @@ -3,7 +3,7 @@ """ from torch import nn -from deepspeed.pt.sparse_transformer import DeepSpeedBertSparseSelfAttention, SparsityConfig +from deepspeed.pt.sparse_transformer import BertSparseSelfAttention, SparsityConfig ''' This file contains few utility functions to handle adapting pretrained model with sparse self-attention module. ''' @@ -72,9 +72,12 @@ def update_tokenizer_model_max_length(tokenizer, max_position): return tokenizer -def replace_model_self_attention_with_sparse_self_attention(model, - max_position, - sparsity_config=None): +def replace_model_self_attention_with_sparse_self_attention( + model, + max_position, + # SparsityConfig parameters needs to be set accordingly + sparsity_config=SparsityConfig(num_heads=4, + seq_len=1024)): """This function replaces the self attention layers in model encoder with sparse self attention. It currently supports bert and roberta model and can be easily extended to any other models following similar steps here. For sparsityConfig, refer to the config class. @@ -110,7 +113,9 @@ def replace_model_self_attention_with_sparse_self_attention(model, def replace_self_attention_layer_with_sparse_self_attention_layer( config, layers, - sparsity_config=None): + # SparsityConfig parameters needs to be set accordingly + sparsity_config=SparsityConfig(num_heads=4, + seq_len=1024)): """This function replaces the self attention layers in attention layer with sparse self attention. For sparsityConfig, refer to the config class. @@ -124,9 +129,7 @@ def replace_self_attention_layer_with_sparse_self_attention_layer( """ for layer in layers: - deepspeed_sparse_self_attn = DeepSpeedBertSparseSelfAttention( - config, - sparsity_config) + deepspeed_sparse_self_attn = BertSparseSelfAttention(config, sparsity_config) deepspeed_sparse_self_attn.query = layer.attention.self.query deepspeed_sparse_self_attn.key = layer.attention.self.key deepspeed_sparse_self_attn.value = layer.attention.self.value diff --git a/deepspeed/trsrc/sparse_transformer/softmax_bwd.tr b/deepspeed/trsrc/sparse_transformer/softmax_bwd.tr index 358d6e5ea57e..c87973973422 100644 --- a/deepspeed/trsrc/sparse_transformer/softmax_bwd.tr +++ b/deepspeed/trsrc/sparse_transformer/softmax_bwd.tr @@ -1,4 +1,4 @@ -// DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +// DeepSpeed note, code taken & adapted from commit beddcc3eda6d3df1b34f74c2e10139e4317d0e7f // https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/softmax.py __global__ void softmax_bwd(TYPE * X __readonly __noalias __aligned(16), @@ -27,7 +27,7 @@ __global__ void softmax_bwd(TYPE * X __readonly __noalias __aligned(16), int rbmn[TN] = check ? rbn : size - 1; // initialize pointers to block-sparse input - long blockid[TN] = *(LUT + offset + rbmn*3); + long blockid[TN] = *(LUT + offset + rbmn*4); TYPE* px[TN] = X + pidz * stride_zx + blockid * BLOCK * BLOCK diff --git a/deepspeed/trsrc/sparse_transformer/softmax_fwd.tr b/deepspeed/trsrc/sparse_transformer/softmax_fwd.tr index 5d5f162073e8..7a3415a9ed62 100644 --- a/deepspeed/trsrc/sparse_transformer/softmax_fwd.tr +++ b/deepspeed/trsrc/sparse_transformer/softmax_fwd.tr @@ -1,4 +1,4 @@ -// DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +// DeepSpeed note, code taken & adapted from commit beddcc3eda6d3df1b34f74c2e10139e4317d0e7f // https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/softmax.py __global__ void softmax_fwd(TYPE *X __readonly __noalias __aligned(16), @@ -7,7 +7,7 @@ __global__ void softmax_fwd(TYPE *X __readonly __noalias __aligned(16), TYPE *RPE __readonly __noalias __aligned(16), TYPE *KP_M __readonly __noalias __aligned(16), TYPE *ATTN_M __readonly __noalias __aligned(16), - int num_blocks, int num_blocks_per_head, + int num_blocks, int sizemax, long stride_zx __multipleof(BLOCK), long stride_zrpe __multipleof(BLOCK), @@ -33,9 +33,10 @@ __global__ void softmax_fwd(TYPE *X __readonly __noalias __aligned(16), int rbmn[TN] = check ? rbn : size - 1; // block id and column id - long blockid [TN] = *(LUT + offset + rbmn*3 + 0); - long columnid[TN] = *(LUT + offset + rbmn*3 + 1); - long rowid [TN] = *(LUT + offset + rbmn*3 + 2); + long blockid [TN] = *(LUT + offset + rbmn*4 + 0); + long columnid[TN] = *(LUT + offset + rbmn*4 + 1); + long rowid [TN] = *(LUT + offset + rbmn*4 + 2); + long headid [TN] = *(LUT + offset + rbmn*4 + 3); // pointers to X TYPE* px[TN] = X + pidz * stride_zx @@ -45,7 +46,7 @@ __global__ void softmax_fwd(TYPE *X __readonly __noalias __aligned(16), #ifdef APPLY_RPE // pointers to relative position embedding TYPE* prpe[TN] = RPE + pidz * stride_zrpe - + blockid / num_blocks_per_head * stride_hrpe + + headid * stride_hrpe + columnid * BLOCK + rowid * BLOCK * stride_srpe + rxm * stride_srpe From b6435ba504f345f8a83c8ff28716971d34ea951a Mon Sep 17 00:00:00 2001 From: Arash Ashari Date: Wed, 12 Aug 2020 11:43:26 -0700 Subject: [PATCH 04/16] adding unit test/s for sparse transformer (#60) * adding unit test/s for sparse transformer * file-name change update * updated tests based on new list of sparsity configs * Adding/updating sparsity config (#68) * adding/updating sparsity config patterns * adding random to Variable sparsity * fixing a typo * applying comment adding missing argument docstring * adding unit test/s for sparse transformer * file-name change update * updated tests based on new list of sparsity configs * skipping a test if it is run on gpu with compute capability < 7; minimum V100 --- tests/unit/test_sparse_transformer.py | 359 ++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100755 tests/unit/test_sparse_transformer.py diff --git a/tests/unit/test_sparse_transformer.py b/tests/unit/test_sparse_transformer.py new file mode 100755 index 000000000000..b86405e99a0e --- /dev/null +++ b/tests/unit/test_sparse_transformer.py @@ -0,0 +1,359 @@ +# DeepSpeed note, some parts of code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +# https://github.com/ptillet/torch-blocksparse/blob/master/tests/test_softmax.py +# https://github.com/ptillet/torch-blocksparse/blob/master/tests/test_matmul.py +# https://github.com/ptillet/torch-blocksparse/blob/master/tests/utils + +import pytest +import torch + + +def test_sparse_transformer_module_availability(): + try: + from deepspeed.pt import sparse_transformer + except ImportError: + print("Sparse Transformer Module is not installed!") + return False + return True + + +def test_matmul_module_availability(): + try: + from deepspeed.pt.sparse_transformer import MatMul + except ImportError: + print("Sparse Transformer MatMul Module is not installed!") + return False + return True + + +def test_softmax_module_availability(): + try: + from deepspeed.pt.sparse_transformer import Softmax + except ImportError: + print("Sparse Transformer Softmax Module is not installed!") + return False + return True + + +def test_sparsityconfig_module_availability(): + try: + from deepspeed.pt.sparse_transformer import SparsityConfig + except ImportError: + print("SparsityConfig Module is not installed!") + return False + return True + + +def test_densesparsityconfig_module_availability(): + try: + from deepspeed.pt.sparse_transformer import DenseSparsityConfig + except ImportError: + print("DenseSparsityConfig Module is not installed!") + return False + return True + + +def test_fixedsparsityconfig_module_availability(): + try: + from deepspeed.pt.sparse_transformer import FixedSparsityConfig + except ImportError: + print("FixedSparsityConfig Module is not installed!") + return False + return True + + +def test_variablesparsityconfig_module_availability(): + try: + from deepspeed.pt.sparse_transformer import VariableSparsityConfig + except ImportError: + print("VariableSparsityConfig Module is not installed!") + return False + return True + + +def test_bigbirdsparsityconfig_module_availability(): + try: + from deepspeed.pt.sparse_transformer import BigBirdSparsityConfig + except ImportError: + print("BigBirdSparsityConfig Module is not installed!") + return False + return True + + +def test_bslongformersparsityconfig_module_availability(): + try: + from deepspeed.pt.sparse_transformer import BSLongformerSparsityConfig + except ImportError: + print("BSLongformerSparsityConfig Module is not installed!") + return False + return True + + +def test_sparseselfattention_module_availability(): + try: + from deepspeed.pt.sparse_transformer import SparseSelfAttention + except ImportError: + print("SparseSelfAttention Module is not installed!") + return False + return True + + +def test_bertsparseselfattention_module_availability(): + try: + from deepspeed.pt.sparse_transformer import BertSparseSelfAttention + except ImportError: + print("BertSparseSelfAttention Module is not installed!") + return False + return True + + +def test_extend_position_embedding_module_availability(): + try: + from deepspeed.pt.sparse_transformer import extend_position_embedding + except ImportError: + print("Sparse Transformer extend_position_embedding Module is not installed!") + return False + return True + + +def test_update_tokenizer_model_max_length_module_availability(): + try: + from deepspeed.pt.sparse_transformer import update_tokenizer_model_max_length + except ImportError: + print( + "Sparse Transformer update_tokenizer_model_max_length Module is not installed!" + ) + return False + return True + + +def test_replace_model_self_attention_with_sparse_self_attention_module_availability(): + try: + from deepspeed.pt.sparse_transformer import replace_model_self_attention_with_sparse_self_attention + except ImportError: + print( + "Sparse Transformer replace_model_self_attention_with_sparse_self_attention Module is not installed!" + ) + return False + return True + + +def test_replace_self_attention_layer_with_sparse_self_attention_layer_modules_availability( +): + try: + from deepspeed.pt.sparse_transformer import replace_self_attention_layer_with_sparse_self_attention_layer + except ImportError: + print( + "Sparse Transformer replace_self_attention_layer_with_sparse_self_attention_layer Module is not installed!" + ) + return False + return True + + +def dense_to_sparse(w, mask, block): + """Converts dense matrix with explicit zeros to sparse matrix + """ + Z = w.size(0) + ret = torch.empty((Z, mask.sum(), block, block), dtype=w.dtype, device=w.device) + nnz = mask.nonzero() + h, i, j = nnz[:, 0], nnz[:, 1], nnz[:, 2] + for zz in range(Z): + for idx, (hh, ii, jj) in enumerate(zip(h, i, j)): + ret[zz, idx, :, :] = w[zz, hh, ii*block: (ii+1)*block, jj*block: (jj+1)*block] + return ret + + +def sparse_to_dense(w, mask, block, zero=0): + """Converts sparse matrix to dense matrix with explicit zeros + """ + maskedw = w.clone() + for bz, wz in enumerate(range(0, w.size(0))): + for bh, wh in enumerate(range(0, w.size(1))): + for bi, wi in enumerate(range(0, w.size(2), block)): + for bj, wj in enumerate(range(0, w.size(3), block)): + if mask[bh, bi, bj] == 0: + maskedw[wz, wh, wi:wi + block, wj:wj + block] = zero + #maskedw[wz, wh, wi : wi+block, wj : wj+block] *= mask[bh, bi, bj] + return maskedw + + +def allclose(x, y): + assert x.dtype == y.dtype + rtol, atol = {torch.float32: (1e-4, 1e-5), torch.float16: (1e-2, 1e-3)}[x.dtype] + return torch.allclose(x, y, rtol=rtol, atol=atol) + + +def make_layout(rho, shape): + probs = torch.Tensor([rho, 1 - rho]) + generator = torch.distributions.categorical.Categorical(probs) + layout = generator.sample(shape) + return layout + + +def run_softmax_reference(x, scale, dx, kp_mask, attn_mask, layout, block): + x = sparse_to_dense(x, layout, block, zero=float('-inf')) + x.retain_grad() + if kp_mask is not None: + bcattn_mask = attn_mask[None, None, :, :] + torch.zeros_like(x) + x[bcattn_mask == 0] = float('-inf') + y = torch.softmax(x * scale + kp_mask[:, None, None, :], -1) + else: + y = torch.softmax(x * scale, -1) + y.backward(dx) + dx = x.grad.clone() + dx = dense_to_sparse(dx, layout, block) + y = dense_to_sparse(y, layout, block) + return y, dx + + +def run_softmax_st(x, scale, dx, kp_mask, attn_mask, layout, block): + from deepspeed.pt.sparse_transformer import Softmax + sparse_softmax = Softmax(layout, block, bench=False) + dx = dense_to_sparse(dx, layout, block) + x = dense_to_sparse(x, layout, block) + x.retain_grad() + y = sparse_softmax(x, + scale=scale, + key_padding_mask=kp_mask, + key_padding_mask_mode='add', + attn_mask=attn_mask, + attn_mask_mode='mul') + y.backward(dx) + dx = x.grad.clone() + x.grad.zero_() + return x, dx + + +def init_softmax_inputs(Z, H, M, N, scale, rho, block, dtype, dense_x=True, layout=None): + if layout is None: + layout = make_layout(rho, (H, M // block, N // block)) + if dense_x: + x = torch.rand((Z, H, M, N), dtype=dtype, requires_grad=True, device='cuda') + else: + x = torch.rand((Z, + layout.sum(), + block, + block), + dtype=dtype, + requires_grad=True, + device='cuda') + dx = torch.rand_like(x) + bool_attn_mask = torch.randint(low=0, + high=2, + size=(N, + N), + dtype=torch.bool, + requires_grad=False, + device='cuda') + fp_attn_mask = bool_attn_mask.type(dtype) + kp_mask = torch.randint(low=0, + high=2, + size=(Z, + N), + dtype=dtype, + requires_grad=False, + device='cuda') + kp_mask[kp_mask == 1.] = float('-inf') + return layout, x, dx, bool_attn_mask, fp_attn_mask, kp_mask + + +@pytest.mark.skipif(torch.cuda.get_device_capability()[0] < 7, + reason="needs minimum compute capability 7; v100") +@pytest.mark.parametrize("block", [16, 32]) +@pytest.mark.parametrize("width", [256, 576]) +@pytest.mark.parametrize("dtype", [torch.float16, torch.float32]) +def test_softmax(block, width, dtype): + Z = 2 + H = 4 + scale = 0.4 + rho = 0.4 + M = N = width + layout, x, dx, bool_attn_mask, fp_attn_mask, kp_mask = init_softmax_inputs(Z, H, M, N, scale, rho, block, dtype, layout=None) + ref_y, ref_dx = run_softmax_reference(x, scale, dx, kp_mask, bool_attn_mask, layout, block) + st_y, st_dx = run_softmax_st(x, scale, dx, kp_mask, fp_attn_mask, layout, block) + assert allclose(ref_y, st_y) + assert allclose(ref_dx, st_dx) + + +def run_matmul_reference(x, w, mode, trans_a, trans_b, layout, block, dy): + x = sparse_to_dense(x, layout, block) if mode == 'dsd' else x + w = sparse_to_dense(w, layout, block) if mode == 'dds' else w + x.retain_grad() + w.retain_grad() + xx = x.transpose(2, 3) if trans_a else x + ww = w.transpose(2, 3) if trans_b else w + y = torch.matmul(xx, ww) + y = sparse_to_dense(y, layout, block) if mode == 'sdd' else y + y.backward(dy) + dx = x.grad.clone() + dw = w.grad.clone() + x.grad.zero_() + w.grad.zero_() + y = dense_to_sparse(y, layout, block) if mode == 'sdd' else y + dx = dense_to_sparse(dx, layout, block) if mode == 'dsd' else dx + dw = dense_to_sparse(dw, layout, block) if mode == 'dds' else dw + return y, dx, dw + + +def run_matmul_st(x, w, mode, trans_a, trans_b, layout, block, dy): + from deepspeed.pt.sparse_transformer import MatMul + x = dense_to_sparse(x, layout, block) if mode == 'dsd' else x + w = dense_to_sparse(w, layout, block) if mode == 'dds' else w + dy = dense_to_sparse(dy, layout, block) if mode == 'sdd' else dy + op = MatMul(layout, block, mode, trans_a=trans_a, trans_b=trans_b) + x.retain_grad() + w.retain_grad() + y = op(x, w) + y.backward(dy) + dx = x.grad.clone() + dw = w.grad.clone() + x.grad.zero_() + return y, dx, dw + + +def init_matmul_inputs(Z, H, M, N, K, rho, mode, trans_a, trans_b, block, dtype, layout): + torch.manual_seed(1) + AS0 = K if trans_a else M + AS1 = M if trans_a else K + BS0 = N if trans_b else K + BS1 = K if trans_b else N + shape = {'sdd': (M, N), 'dsd': (AS0, AS1), 'dds': (BS0, BS1)}[mode] + x = torch.rand((Z, H, AS0, AS1), dtype=dtype, requires_grad=True, device='cuda') + w = torch.rand((Z, H, BS0, BS1), dtype=dtype, requires_grad=True, device='cuda') + dy = torch.rand((Z, H, M, N), dtype=dtype, device='cuda') + if layout is None: + layout = make_layout(rho, (H, shape[0] // block, shape[1] // block)) + else: + assert list(layout.shape) == [H, shape[0] // block, shape[1] // block] + x.retain_grad() + w.retain_grad() + return x, w, dy, shape, layout + +testdata = [ + (16, dtype, mode, trans_a, trans_b)\ + for dtype in [torch.float16, torch.float32]\ + for mode in ['sdd', 'dsd', 'dds']\ + for trans_a in [False, True]\ + for trans_b in [False, True]\ + ] + [ + (block, torch.float16, mode, False, False)\ + for block in [16, 32, 64]\ + for mode in ['sdd', 'dsd', 'dds']\ + ] + + +@pytest.mark.skipif(torch.cuda.get_device_capability()[0] < 7, + reason="needs minimum compute capability 7; v100") +@pytest.mark.parametrize("block, dtype, mode, trans_a, trans_b", testdata) +def test_matmul(block, dtype, mode, trans_a, trans_b): + Z = 3 + H = 2 + M = 128 + N = 256 + K = 192 + rho = 0.5 + x, w, dy, shape, layout = init_matmul_inputs(Z, H, M, N, K, rho, mode, trans_a, trans_b, block, dtype, layout=None) + ref_y, ref_dx, ref_dw = run_matmul_reference(x.clone(), w.clone(), mode, trans_a, trans_b, layout, block, dy) + st_y, st_dx, st_dw = run_matmul_st(x.clone(), w.clone(), mode, trans_a, trans_b, layout, block, dy) + assert allclose(ref_y, st_y) + assert allclose(ref_dx, st_dx) + assert allclose(ref_dw, st_dw) From 631fba47476da03bf530102f4b1a812f4bce79f1 Mon Sep 17 00:00:00 2001 From: Arash Ashari Date: Wed, 12 Aug 2020 15:08:21 -0700 Subject: [PATCH 05/16] fix a naming issue in utils file: bert_mode -> bert (#69) --- deepspeed/pt/sparse_transformer/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deepspeed/pt/sparse_transformer/utils.py b/deepspeed/pt/sparse_transformer/utils.py index e9814be79ed5..b5d8b6bd23eb 100644 --- a/deepspeed/pt/sparse_transformer/utils.py +++ b/deepspeed/pt/sparse_transformer/utils.py @@ -24,7 +24,7 @@ def extend_position_embedding(model, max_position): original_max_position = model.bert.embeddings.position_embeddings.weight.size(0) assert max_position > original_max_position extend_multiples = max(1, max_position // original_max_position) - model.bert.embeddings.position_embeddings.weight.data = model.bert_model.embeddings.position_embeddings.weight.repeat( + model.bert.embeddings.position_embeddings.weight.data = model.bert.embeddings.position_embeddings.weight.repeat( extend_multiples, 1) elif hasattr(model, 'roberta'): From dce7755824f75a3d131cbf2444ada656c717061e Mon Sep 17 00:00:00 2001 From: Arash Ashari Date: Fri, 21 Aug 2020 17:32:44 -0700 Subject: [PATCH 06/16] updating deepspeed config for Sparse Transformer (#62) * updating deepspeed config for Sparse Transformer * Adding/updating sparsity config (#68) * adding/updating sparsity config patterns * adding random to Variable sparsity * fixing a typo * applying comment adding missing argument docstring * updating deepspeed config for Sparse Transformer * updating sparsity config for DeepSpeed parameter list * adding unit test/s for sparse transformer (#60) * adding unit test/s for sparse transformer * file-name change update * updated tests based on new list of sparsity configs * Adding/updating sparsity config (#68) * adding/updating sparsity config patterns * adding random to Variable sparsity * fixing a typo * applying comment adding missing argument docstring * adding unit test/s for sparse transformer * file-name change update * updated tests based on new list of sparsity configs * skipping a test if it is run on gpu with compute capability < 7; minimum V100 * fix a naming issue in utils file: bert_mode -> bert (#69) * updating deepspeed config for Sparse Transformer * updating sparsity config for DeepSpeed parameter list --- deepspeed/pt/deepspeed_config.py | 173 ++++++++++++++++++++++++++++ deepspeed/pt/deepspeed_constants.py | 36 ++++++ 2 files changed, 209 insertions(+) diff --git a/deepspeed/pt/deepspeed_config.py b/deepspeed/pt/deepspeed_config.py index f618124d74c7..748adc66bb26 100755 --- a/deepspeed/pt/deepspeed_config.py +++ b/deepspeed/pt/deepspeed_config.py @@ -158,6 +158,177 @@ def get_gradient_clipping(param_dict): return get_scalar_param(param_dict, GRADIENT_CLIPPING, GRADIENT_CLIPPING_DEFAULT) +def get_sparse_self_attention(param_dict): + if SPARSE_SELF_ATTENTION in param_dict.keys(): + sparsity = param_dict[SPARSE_SELF_ATTENTION] + mode = get_sparse_self_attention_mode(sparsity) + + if (mode == SPARSE_DENSE_MODE): + return get_sparse_dense_config(sparsity) + elif (mode == SPARSE_FIXED_MODE): + return get_sparse_fixed_config(sparsity) + elif (mode == SPARSE_VARIABLE_MODE): + return get_sparse_variable_config(sparsity) + elif (mode == SPARSE_BIGBIRD_MODE): + return get_sparse_bigbird_config(sparsity) + elif (mode == SPARSE_BSLONGFORMER_MODE): + return get_sparse_bslongformer_config(sparsity) + else: + raise NotImplementedError( + f'Given sparsity mode, {mode}, has not been implemented yet!') + + else: + return None + + +def get_sparse_dense_config(sparsity): + block = get_scalar_param(sparsity, SPARSE_BLOCK, SPARSE_BLOCK_DEFAULT) + return {SPARSE_MODE: SPARSE_DENSE_MODE, SPARSE_BLOCK: block} + + +def get_sparse_fixed_config(sparsity): + block = get_scalar_param(sparsity, SPARSE_BLOCK, SPARSE_BLOCK_DEFAULT) + different_layout_per_head = get_scalar_param( + sparsity, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD_DEFAULT) + num_local_blocks = get_scalar_param(sparsity, + SPARSE_NUM_LOCAL_BLOCKS, + SPARSE_NUM_LOCAL_BLOCKS_DEFAULT) + num_global_blocks = get_scalar_param(sparsity, + SPARSE_NUM_GLOBAL_BLOCKS, + SPARSE_NUM_GLOBAL_BLOCKS_DEFAULT) + attention = get_scalar_param(sparsity, + SPARSE_ATTENTION_TYPE, + SPARSE_ATTENTION_TYPE_DEFAULT) + horizontal_global_attention = get_scalar_param( + sparsity, + SPARSE_HORIZONTAL_GLOBAL_ATTENTION, + SPARSE_HORIZONTAL_GLOBAL_ATTENTION_DEFAULT) + num_differnt_global_patterns = get_scalar_param( + sparsity, + SPARSE_NUM_DIFFERENT_GLOBAL_PATTERNS, + SPARSE_NUM_DIFFERENT_GLOBAL_PATTERNS_DEFAULT) + + return { + SPARSE_MODE: SPARSE_FIXED_MODE, + SPARSE_BLOCK: block, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD: different_layout_per_head, + SPARSE_NUM_LOCAL_BLOCKS: num_local_blocks, + SPARSE_NUM_GLOBAL_BLOCKS: num_global_blocks, + SPARSE_ATTENTION_TYPE: attention, + SPARSE_HORIZONTAL_GLOBAL_ATTENTION: horizontal_global_attention, + SPARSE_NUM_DIFFERENT_GLOBAL_PATTERNS: num_differnt_global_patterns + } + + +def get_sparse_variable_config(sparsity): + block = get_scalar_param(sparsity, SPARSE_BLOCK, SPARSE_BLOCK_DEFAULT) + different_layout_per_head = get_scalar_param( + sparsity, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD_DEFAULT) + num_random_blocks = get_scalar_param(sparsity, + SPARSE_NUM_RANDOM_BLOCKS, + SPARSE_NUM_RANDOM_BLOCKS_DEFAULT) + local_window_blocks = get_scalar_param(sparsity, + SPARSE_LOCAL_WINDOW_BLOCKS, + SPARSE_LOCAL_WINDOW_BLOCKS_DEFAULT) + global_block_indices = get_scalar_param(sparsity, + SPARSE_GLOBAL_BLOCK_INDICES, + SPARSE_GLOBAL_BLOCK_INDICES_DEFAULT) + global_block_end_indices = get_scalar_param(sparsity, + SPARSE_GLOBAL_BLOCK_END_INDICES, + SPARSE_GLOBAL_BLOCK_END_INDICES_DEFAULT) + attention = get_scalar_param(sparsity, + SPARSE_ATTENTION_TYPE, + SPARSE_ATTENTION_TYPE_DEFAULT) + horizontal_global_attention = get_scalar_param( + sparsity, + SPARSE_HORIZONTAL_GLOBAL_ATTENTION, + SPARSE_HORIZONTAL_GLOBAL_ATTENTION_DEFAULT) + + return { + SPARSE_MODE: SPARSE_VARIABLE_MODE, + SPARSE_BLOCK: block, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD: different_layout_per_head, + SPARSE_NUM_RANDOM_BLOCKS: num_random_blocks, + SPARSE_LOCAL_WINDOW_BLOCKS: local_window_blocks, + SPARSE_GLOBAL_BLOCK_INDICES: global_block_indices, + SPARSE_GLOBAL_BLOCK_END_INDICES: global_block_end_indices, + SPARSE_ATTENTION_TYPE: attention, + SPARSE_HORIZONTAL_GLOBAL_ATTENTION: horizontal_global_attention + } + + +def get_sparse_bigbird_config(sparsity): + block = get_scalar_param(sparsity, SPARSE_BLOCK, SPARSE_BLOCK_DEFAULT) + different_layout_per_head = get_scalar_param( + sparsity, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD_DEFAULT) + num_random_blocks = get_scalar_param(sparsity, + SPARSE_NUM_RANDOM_BLOCKS, + SPARSE_NUM_RANDOM_BLOCKS_DEFAULT) + num_sliding_window_blocks = get_scalar_param( + sparsity, + SPARSE_NUM_SLIDING_WINDOW_BLOCKS, + SPARSE_NUM_SLIDING_WINDOW_BLOCKS_DEFAULT) + num_global_blocks = get_scalar_param(sparsity, + SPARSE_NUM_GLOBAL_BLOCKS, + SPARSE_NUM_GLOBAL_BLOCKS_DEFAULT) + + return { + SPARSE_MODE: SPARSE_BIGBIRD_MODE, + SPARSE_BLOCK: block, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD: different_layout_per_head, + SPARSE_NUM_RANDOM_BLOCKS: num_random_blocks, + SPARSE_NUM_SLIDING_WINDOW_BLOCKS: num_sliding_window_blocks, + SPARSE_NUM_GLOBAL_BLOCKS: num_global_blocks + } + + +def get_sparse_bslongformer_config(sparsity): + block = get_scalar_param(sparsity, SPARSE_BLOCK, SPARSE_BLOCK_DEFAULT) + different_layout_per_head = get_scalar_param( + sparsity, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD_DEFAULT) + num_sliding_window_blocks = get_scalar_param( + sparsity, + SPARSE_NUM_SLIDING_WINDOW_BLOCKS, + SPARSE_NUM_SLIDING_WINDOW_BLOCKS_DEFAULT) + global_block_indices = get_scalar_param(sparsity, + SPARSE_GLOBAL_BLOCK_INDICES, + SPARSE_GLOBAL_BLOCK_INDICES_DEFAULT) + global_block_end_indices = get_scalar_param(sparsity, + SPARSE_GLOBAL_BLOCK_END_INDICES, + SPARSE_GLOBAL_BLOCK_END_INDICES_DEFAULT) + + return { + SPARSE_MODE: SPARSE_BSLONGFORMER_MODE, + SPARSE_BLOCK: block, + SPARSE_DIFFERENT_LAYOUT_PER_HEAD: different_layout_per_head, + SPARSE_NUM_SLIDING_WINDOW_BLOCKS: num_sliding_window_blocks, + SPARSE_GLOBAL_BLOCK_INDICES: global_block_indices, + SPARSE_GLOBAL_BLOCK_END_INDICES: global_block_end_indices + } + + +def get_sparse_self_attention_mode(param_dict): + if SPARSE_MODE in param_dict.keys(): + return param_dict[SPARSE_MODE] + else: + return SPARSE_MODE_DEFAULT + + +def get_sparse_self_attention_type(param_dict): + if SPARSE_ATTENTION_TYPE in param_dict.keys(): + return param_dict[SPARSE_ATTENTION_TYPE] + else: + return SPARSE_ATTENTION_TYPE_DEFAULT + + def get_optimizer_name(param_dict): if OPTIMIZER in param_dict.keys() and \ TYPE in param_dict[OPTIMIZER].keys(): @@ -358,6 +529,8 @@ def _initialize_params(self, param_dict): self.tensorboard_output_path = get_tensorboard_output_path(param_dict) self.tensorboard_job_name = get_tensorboard_job_name(param_dict) + self.sparse_self_attention = get_sparse_self_attention(param_dict) + def _batch_assertion(self): train_batch = self.train_batch_size diff --git a/deepspeed/pt/deepspeed_constants.py b/deepspeed/pt/deepspeed_constants.py index 1ba3dd482e25..a68151ca09ca 100755 --- a/deepspeed/pt/deepspeed_constants.py +++ b/deepspeed/pt/deepspeed_constants.py @@ -17,6 +17,42 @@ TRAIN_BATCH_SIZE = "train_batch_size" TRAIN_BATCH_SIZE_DEFAULT = None +############################################# +# Sparse self attention +############################################# +SPARSE_SELF_ATTENTION = "sparse_self_attention" +SPARSE_DENSE_MODE = "dense" +SPARSE_FIXED_MODE = "fixed" +SPARSE_VARIABLE_MODE = "variable" +SPARSE_BIGBIRD_MODE = "bigbird" +SPARSE_BSLONGFORMER_MODE = "bslongformer" +SPARSE_MODE = "mode" +SPARSE_MODE_DEFAULT = SPARSE_FIXED_MODE +SPARSE_BLOCK = "block" +SPARSE_BLOCK_DEFAULT = 16 +SPARSE_DIFFERENT_LAYOUT_PER_HEAD = "different_layout_per_head" +SPARSE_DIFFERENT_LAYOUT_PER_HEAD_DEFAULT = False +SPARSE_NUM_LOCAL_BLOCKS = "num_local_blocks" +SPARSE_NUM_LOCAL_BLOCKS_DEFAULT = 4 +SPARSE_NUM_GLOBAL_BLOCKS = "num_global_blocks" +SPARSE_NUM_GLOBAL_BLOCKS_DEFAULT = 1 +SPARSE_ATTENTION_TYPE = "attention" +SPARSE_ATTENTION_TYPE_DEFAULT = "bidirectional" +SPARSE_HORIZONTAL_GLOBAL_ATTENTION = "horizontal_global_attention" +SPARSE_HORIZONTAL_GLOBAL_ATTENTION_DEFAULT = False +SPARSE_NUM_DIFFERENT_GLOBAL_PATTERNS = "num_differnt_global_patterns" +SPARSE_NUM_DIFFERENT_GLOBAL_PATTERNS_DEFAULT = 1 +SPARSE_NUM_RANDOM_BLOCKS = "num_random_blocks" +SPARSE_NUM_RANDOM_BLOCKS_DEFAULT = 0 +SPARSE_LOCAL_WINDOW_BLOCKS = "local_window_blocks" +SPARSE_LOCAL_WINDOW_BLOCKS_DEFAULT = [4] +SPARSE_GLOBAL_BLOCK_INDICES = "global_block_indices" +SPARSE_GLOBAL_BLOCK_INDICES_DEFAULT = [0] +SPARSE_GLOBAL_BLOCK_END_INDICES = "global_block_end_indices" +SPARSE_GLOBAL_BLOCK_END_INDICES_DEFAULT = None +SPARSE_NUM_SLIDING_WINDOW_BLOCKS = "num_sliding_window_blocks" +SPARSE_NUM_SLIDING_WINDOW_BLOCKS_DEFAULT = 3 + ############################################# # Optimizer and lr scheduler ############################################# From e2f1eb4b2c021538b9f6fb39c0bd3a5c55f2f19f Mon Sep 17 00:00:00 2001 From: Arash Ashari Date: Fri, 21 Aug 2020 22:59:24 -0700 Subject: [PATCH 07/16] updating sparsityconfig and layout creation to enable variable sequence length per batch (#71) * updating sparsityconfig and layout creation to enable variable sequence length per batch * added utility functions to help with un/padding of input ids/embedding for ST * added utility function to module list and updated unit tests accordingly; add module availability unit tests --- deepspeed/pt/sparse_transformer/__init__.py | 2 +- .../bert_sparse_self_attention.py | 3 +- .../sparse_self_attention.py | 11 +- .../pt/sparse_transformer/sparsity_config.py | 488 +++++++++++------- deepspeed/pt/sparse_transformer/utils.py | 84 ++- tests/unit/test_sparse_transformer.py | 20 +- 6 files changed, 394 insertions(+), 214 deletions(-) diff --git a/deepspeed/pt/sparse_transformer/__init__.py b/deepspeed/pt/sparse_transformer/__init__.py index 73d025890fa6..9872f73ced5d 100644 --- a/deepspeed/pt/sparse_transformer/__init__.py +++ b/deepspeed/pt/sparse_transformer/__init__.py @@ -3,4 +3,4 @@ from .matmul import MatMul from .sparse_self_attention import SparseSelfAttention from .bert_sparse_self_attention import BertSparseSelfAttention -from .utils import extend_position_embedding, update_tokenizer_model_max_length, replace_model_self_attention_with_sparse_self_attention, replace_self_attention_layer_with_sparse_self_attention_layer +from .utils import extend_position_embedding, update_tokenizer_model_max_length, replace_model_self_attention_with_sparse_self_attention, replace_self_attention_layer_with_sparse_self_attention_layer, pad_to_block_size, unpad_sequence_output diff --git a/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py b/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py index 2f87c8474609..0370798eeaf5 100755 --- a/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py +++ b/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py @@ -17,8 +17,7 @@ def __init__( self, config, # SparsityConfig parameters needs to be set accordingly - sparsity_config=FixedSparsityConfig(num_heads=4, - seq_len=1024)): + sparsity_config=FixedSparsityConfig(num_heads=4)): """Initialize the bert sparse self attention layer. Note) you can use any of the provided sparsity configs or simply add yours! diff --git a/deepspeed/pt/sparse_transformer/sparse_self_attention.py b/deepspeed/pt/sparse_transformer/sparse_self_attention.py index 44740b596138..b14069caadbb 100644 --- a/deepspeed/pt/sparse_transformer/sparse_self_attention.py +++ b/deepspeed/pt/sparse_transformer/sparse_self_attention.py @@ -20,8 +20,7 @@ class SparseSelfAttention(nn.Module): def __init__( self, # SparsityConfig parameters needs to be set accordingly - sparsity_config=SparsityConfig(num_heads=4, - seq_len=1024), + sparsity_config=SparsityConfig(num_heads=4), key_padding_mask_mode='add', attn_mask_mode='mul'): """Initialize the sparse self attention layer. @@ -45,20 +44,20 @@ def __init__( def get_ops(self, H, L): import sys if L not in SparseSelfAttention.ops: - sparse_dot_sdd_nt = MatMul(self.sparsity_config.layout, + sparsity_layout = self.sparsity_config.make_layout(L) + sparse_dot_sdd_nt = MatMul(sparsity_layout, self.sparsity_config.block, 'sdd', trans_a=False, trans_b=True) - sparse_dot_dsd_nn = MatMul(self.sparsity_config.layout, + sparse_dot_dsd_nn = MatMul(sparsity_layout, self.sparsity_config.block, 'dsd', trans_a=False, trans_b=False) - sparse_softmax = Softmax(self.sparsity_config.layout, - self.sparsity_config.block) + sparse_softmax = Softmax(sparsity_layout, self.sparsity_config.block) SparseSelfAttention.ops[L] = (sparse_dot_sdd_nt, sparse_dot_dsd_nn, diff --git a/deepspeed/pt/sparse_transformer/sparsity_config.py b/deepspeed/pt/sparse_transformer/sparsity_config.py index d282da9c9f97..d4fa5240baf3 100644 --- a/deepspeed/pt/sparse_transformer/sparsity_config.py +++ b/deepspeed/pt/sparse_transformer/sparsity_config.py @@ -10,62 +10,85 @@ class SparsityConfig: """Abstract Configuration class to store `sparsity configuration of a self attention layer`. It contains shared property of different block-sparse sparsity patterns. However, each class needs to extend it based on required property and functionality. """ - def __init__(self, num_heads, seq_len, block=16, different_layout_per_head=False): + def __init__(self, num_heads, block=16, different_layout_per_head=False): """Initialize the Sparsity Pattern Config. For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial Arguments: num_heads: required: an integer determining number of attention heads of the layer. - seq_len: required: an integer determining number of attention heads of the layer. block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. """ self.num_heads = num_heads - if (seq_len % block != 0): - raise ValueError( - f'Sequence Length, {seq_len}, needs to be dividable by Block size {block}!' - ) - self.seq_len = seq_len self.block = block - self.num_blocks = seq_len // block self.different_layout_per_head = different_layout_per_head - # TODO (ARASH) Currently we allocate layout per head; needs to be updated if heads share a single layout. - self.layout = torch.zeros((self.num_heads, - self.num_blocks, - self.num_blocks), - dtype=torch.int64) self.num_layout_heads = num_heads if different_layout_per_head else 1 - def check_and_propagate_first_head_layout(self): + def setup_layout(self, seq_len): + """Create layout tensor for the given sequence length + + Arguments: + seq_len: required: an integer determining number of attention heads of the layer. + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) for sparsity layout of all head; initialized with zero + """ + + if (seq_len % self.block != 0): + raise ValueError( + f'Sequence Length, {seq_len}, needs to be dividable by Block size {self.block}!' + ) + num_blocks = seq_len // self.block + # TODO Currently we allocate layout per head; needs to be updated if heads share a single layout. + layout = torch.zeros((self.num_heads, num_blocks, num_blocks), dtype=torch.int64) + return layout + + def check_and_propagate_first_head_layout(self, layout): + """If all heads require same sparsity layout, it propagate first head layout to all heads + + Arguments: + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head + """ + if not self.different_layout_per_head: - self.layout[1:self.num_heads, :, :] = self.layout[0, :, :] + layout[1:self.num_heads, :, :] = layout[0, :, :] + return layout class DenseSparsityConfig(SparsityConfig): - def __init__(self, - num_heads=8, - seq_len=1024, - block=16, - different_layout_per_head=False): + """Configuration class to store `Dense` configuration. + In reality, this is not sparse and all blocks are used. We keep it for the sake of comparison and comprehension. + """ + def __init__(self, num_heads, block=16, different_layout_per_head=False): """Initialize the Dense Sparsity Pattern Config. In reality, this is not sparse and all blocks are used. We keep it for the sake of comparison and comprehension. Arguments: num_heads: required: an integer determining number of attention heads of the layer. seq_len: required: an integer determining number of attention heads of the layer. - block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. - different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. This argument can be completely ignored and we kept it here for consistency with the parent class. + different_layout_per_head: optional: this is just for the sake of consistency with other sparsity formats; can ignore it for DenseSparsityConfig """ - super().__init__(num_heads, seq_len, block, different_layout_per_head) - self.make_layout() - def make_layout(self): + super().__init__(num_heads, block, different_layout_per_head) + + def make_layout(self, seq_len): """Set 1 to all blocks of the layout meanins the pattern is dense; not sparse. + + Arguments: + seq_len: required: an integer determining the underling sequence length; must be <= max sequence length + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; for dense everything is 1 """ - self.layout[:, :, :] = 1 - return self.layout + + layout = self.setup_layout(seq_len) + layout[:, :, :] = 1 + return layout class FixedSparsityConfig(SparsityConfig): @@ -75,7 +98,6 @@ class FixedSparsityConfig(SparsityConfig): """ def __init__(self, num_heads, - seq_len, block=16, different_layout_per_head=False, num_local_blocks=4, @@ -89,7 +111,6 @@ def __init__(self, Arguments: num_heads: required: an integer determining number of attention heads of the layer. - seq_len: required: an integer determining number of attention heads of the layer. block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. num_local_blocks: optional: an integer determining the number of blocks in local attention window. @@ -98,12 +119,9 @@ def __init__(self, horizontal_global_attention: optional: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but aso horizontal blocks. num_differnt_global_patterns: optional: an integer determining number of different global attentions layouts. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks local window and global attention size of 1 block, we can have 4 different versions in which the first, Second, third, or forth block of each local window can be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on num_local_blocks and num_global_blocks. """ - super().__init__(num_heads, seq_len, block, different_layout_per_head) - if (seq_len % (block * num_local_blocks) != 0): - raise ValueError( - f'Sequence Length, {seq_len}, must be dividable by local window, {block*num_local_blocks}!' - ) + super().__init__(num_heads, block, different_layout_per_head) + self.num_local_blocks = num_local_blocks if (num_local_blocks % num_global_blocks != 0): @@ -132,22 +150,29 @@ def __init__(self, f'Number of layout versions (num_differnt_global_patterns), {num_differnt_global_patterns}, cannot be larger than number of local window blocks divided by number of global blocks, {num_local_blocks} / {num_global_blocks} = {num_local_blocks//num_global_blocks}!' ) self.num_differnt_global_patterns = num_differnt_global_patterns - self.make_layout() - def set_local_layout(self, h): + def set_local_layout(self, h, layout): """Sets local attantion layout used by the given head in the sparse attention. Arguments: h: required: an integer determining head index + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head in which local layout is set """ - for i in range(0, self.num_blocks, self.num_local_blocks): - for row in range(i, i + self.num_local_blocks): - for col in range(i, - (row + 1 if self.attention == 'unidirectional' else i + - self.num_local_blocks)): - self.layout[h, row, col] = 1 - - def set_global_layout(self, h): + + num_blocks = layout.shape[1] + for i in range(0, num_blocks, self.num_local_blocks): + end = min(i + self.num_local_blocks, num_blocks) + for row in range(i, end): + for col in range( + i, + (row + 1 if self.attention == 'unidirectional' else end)): + layout[h, row, col] = 1 + return layout + + def set_global_layout(self, h, layout): """Sets global attantion layout used by the given head in the sparse attention. Currently we set global blocks starting from the last block of a local window to the first one. That means if a local window consists of 4 blocks and global attention size is one block, we use block #4 in each local window as global. If we have different layout per head, then other heads will get #3, #2, and #1. And if we have more heads (and different layout has set) than num of global attentions, multiple head may have same global attentions. @@ -155,43 +180,64 @@ def set_global_layout(self, h): Arguments: h: required: an integer determining head index + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head in which global layout is set """ + + num_blocks = layout.shape[1] first_global_block_idx = self.num_local_blocks - ( 1 + h % self.num_differnt_global_patterns) * self.num_global_blocks - for i in range(first_global_block_idx, self.num_blocks, self.num_local_blocks): + + # set all global blocks except the last one if (in last local window) + end = num_blocks - (num_blocks % self.num_local_blocks) + for i in range(first_global_block_idx, end, self.num_local_blocks): + + # vertical global attention + first_row = 0 if self.attention == 'bidirectional' else i + #(((i // self.num_local_blocks) + 1) * self.num_local_blocks) + #if (first_row < num_blocks): + layout[h, first_row:, i:i + self.num_global_blocks] = 1 + + # horizontal global attention; only in bidirectional attention + if (self.horizontal_global_attention): + layout[h, i:i + self.num_global_blocks, :] = 1 + + # set last global blocks; handle possible short last local window + if (end < num_blocks): + start = min(end + first_global_block_idx, + num_blocks - self.num_global_blocks) + end = start + self.num_global_blocks # vertical global attention - first_row = 0 if self.attention == 'bidirectional' else (( - (i // self.num_local_blocks) + 1) * self.num_local_blocks) - self.layout[h, first_row:, i:i + self.num_global_blocks] = 1 - ''' - for row in range(first_row, self.num_blocks): - for col in range(i, i + self.num_global_blocks): - self.layout[h, row, col] = 1 - ''' + first_row = 0 if self.attention == 'bidirectional' else start + #(((start // self.num_local_blocks) + 1) * self.num_local_blocks) + #if (first_row < num_blocks): + layout[h, first_row:, start:end] = 1 # horizontal global attention if (self.horizontal_global_attention): - self.layout[h, i:i + self.num_global_blocks, :] = 1 - ''' - for row in range(i, i + self.num_global_blocks): - for col in range(0, self.num_blocks): - self.layout[h, row, col] = 1 - ''' - - def make_layout(self): + layout[h, start:end, :] = 1 + return layout + + def make_layout(self, seq_len): """Generates `Fixed` sparsity layout used by each head in the sparse attention. + Arguments: + seq_len: required: an integer determining number of attention heads of the layer. + Return: - layout: a tensor determining the sparsity layout of each head + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing `Fixed` sparsity layout of all head """ + layout = self.setup_layout(seq_len) for h in range(0, self.num_layout_heads): - self.set_local_layout(h) - self.set_global_layout(h) + layout = self.set_local_layout(h, layout) + layout = self.set_global_layout(h, layout) - self.check_and_propagate_first_head_layout() - return self.layout + layout = self.check_and_propagate_first_head_layout(layout) + return layout class VariableSparsityConfig(SparsityConfig): @@ -206,7 +252,6 @@ class VariableSparsityConfig(SparsityConfig): """ def __init__(self, num_heads, - seq_len, block=16, different_layout_per_head=False, num_random_blocks=0, @@ -221,7 +266,6 @@ def __init__(self, Arguments: num_heads: required: an integer determining number of attention heads of the layer. - seq_len: required: an integer determining number of attention heads of the layer. block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. Currently this sparsity config can only assign single layout to all heads; needs to be extended for different layout per head. num_random_blocks: optional: an integer determining the number of random blocks in each block row. @@ -232,25 +276,11 @@ def __init__(self, attention: optional: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. horizontal_global_attention: optional: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but aso horizontal blocks. """ - super().__init__(num_heads, seq_len, block, different_layout_per_head) - all_local_blocks = 0 - for local_blocks in local_window_blocks: - all_local_blocks += local_blocks - if (self.num_blocks < all_local_blocks): - raise ValueError( - f'Number of all local window blocks, {all_local_blocks}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' - ) + super().__init__(num_heads, block, different_layout_per_head) + + self.num_random_blocks = num_random_blocks self.local_window_blocks = local_window_blocks - if (self.num_blocks < len(global_block_indices)): - raise ValueError( - f'Number of global blocks indices, {global_block_indices}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' - ) - for idx in global_block_indices: - if idx >= self.num_blocks: - raise ValueError( - f'Global block index, {global_block_indices[idx]}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' - ) self.global_block_indices = global_block_indices if (global_block_end_indices is not None): @@ -259,10 +289,6 @@ def __init__(self, f'Global block start indices length, {len(global_block_indices)}, must be same as global block end indices length, {len(global_block_end_indices)}!' ) for _, (start_idx, end_idx) in enumerate(zip(global_block_indices, global_block_end_indices)): - if end_idx > self.num_blocks: - raise ValueError( - f'Global block end index, {global_block_end_indices[idx]}, must be smaller (equal) than overal number of blocks in a row, {self.num_blocks}!' - ) if start_idx >= end_idx: raise ValueError( f'Global block start index, {start_idx}, must be smaller than global block end index, {end_idx}!' @@ -279,84 +305,117 @@ def __init__(self, 'only \"bi-directional\" attentions can support horizontal global attention!' ) self.horizontal_global_attention = horizontal_global_attention - self.make_layout() - def set_random_layout(self, h): + def set_random_layout(self, h, layout): """Sets random attantion layout used by the given head in the sparse attention. Note) By default, it assumes there will be a unique random block layout for all heads; unless `different_layout_per_head` parameter is set in which each head can have a different random layout. Arguments: h: required: an integer determining head index + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head in which random layout is set """ - for row in range(0, self.num_blocks): - rnd_cols = random.sample(range(0, self.num_blocks), self.num_random_blocks) - self.layout[h, row, rnd_cols] = 1 + num_blocks = layout.shape[1] + if (num_blocks < self.num_random_blocks): + raise ValueError( + f'Number of random blocks, {self.num_random_blocks}, must be smaller than overal number of blocks in a row, {num_blocks}!' + ) + for row in range(0, num_blocks): + rnd_cols = random.sample(range(0, num_blocks), self.num_random_blocks) + layout[h, row, rnd_cols] = 1 + return layout - def set_local_layout(self, h): + def set_local_layout(self, h, layout): """Sets local attantion layout used by the given head in the sparse attention. - Arguments: h: required: an integer determining head index + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head in which local layout is set """ + + num_blocks = layout.shape[1] start_block_idx = 0 end_block_idx = 0 for block_size in self.local_window_blocks: end_block_idx += block_size - end_block_idx = min(end_block_idx, self.num_blocks) + end_block_idx = min(end_block_idx, num_blocks) for row in range(start_block_idx, end_block_idx): for col in range( start_block_idx, (row + 1 if self.attention == 'unidirectional' else end_block_idx)): - self.layout[h, row, col] = 1 + layout[h, row, col] = 1 start_block_idx += block_size # if there is any remaining not attended part, use the lats local window block size as local window for the remaining applicable local windows - for i in range(start_block_idx, self.num_blocks, block_size): - end_block_idx = min(i + block_size, self.num_blocks) + for i in range(start_block_idx, num_blocks, block_size): + end_block_idx = min(i + block_size, num_blocks) for row in range(i, end_block_idx): for col in range( i, (row + 1 if self.attention == 'unidirectional' else end_block_idx)): - self.layout[h, row, col] = 1 + layout[h, row, col] = 1 + return layout - def set_global_layout(self, h): + def set_global_layout(self, h, layout): """Sets global attantion layout used by the given head in the sparse attention. Arguments: h: required: an integer determining head index + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head in which global layout is set """ + + num_blocks = layout.shape[1] if (self.global_block_end_indices is None): for idx in self.global_block_indices: - #global rows - if (self.horizontal_global_attention): - self.layout[h, idx, :] = 1 - - #global columns - self.layout[h, :, idx] = 1 + # if global block idx is in the range of the sequnce blocks + if (idx < num_blocks): + #global rows + if (self.horizontal_global_attention): + layout[h, idx, :] = 1 + + #global columns + first_row = 0 if self.attention == 'bidirectional' else idx + layout[h, first_row:, idx] = 1 else: for _, (start_idx, end_idx) in enumerate(zip(self.global_block_indices, self.global_block_end_indices)): - #global rows - if (self.horizontal_global_attention): - self.layout[h, start_idx:end_idx, :] = 1 + # if global block idx is in the range of the sequnce blocks + if (start_idx < num_blocks): + end_idx = min(end_idx, num_blocks) + #global rows + if (self.horizontal_global_attention): + layout[h, start_idx:end_idx, :] = 1 - #global columns - self.layout[h, :, start_idx:end_idx] = 1 + #global columns + first_row = 0 if self.attention == 'bidirectional' else start_idx + layout[h, first_row:, start_idx:end_idx] = 1 + return layout - def make_layout(self): - """Generates `Fixed` sparsity layout used by each head in the sparse attention. + def make_layout(self, seq_len): + """Generates `Variable` sparsity layout used by each head in the sparse attention. + + Arguments: + seq_len: required: an integer determining number of attention heads of the layer. Return: - layout: a tensor determining the sparsity layout of each head + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing `Variable` sparsity layout of all head """ + layout = self.setup_layout(seq_len) for h in range(0, self.num_layout_heads): - self.set_random_layout(h) - self.set_local_layout(h) - self.set_global_layout(h) + layout = self.set_random_layout(h, layout) + layout = self.set_local_layout(h, layout) + layout = self.set_global_layout(h, layout) - self.check_and_propagate_first_head_layout() - return self.layout + layout = self.check_and_propagate_first_head_layout(layout) + return layout class BigBirdSparsityConfig(SparsityConfig): @@ -365,8 +424,7 @@ class BigBirdSparsityConfig(SparsityConfig): This class extends parent class of `SparsityConfig` and customizes it for `BigBird` sparsity. """ def __init__(self, - num_heads=8, - seq_len=1024, + num_heads, block=16, different_layout_per_head=False, num_random_blocks=1, @@ -378,86 +436,109 @@ def __init__(self, Arguments: num_heads: required: an integer determining number of attention heads of the layer. - seq_len: required: an integer determining number of attention heads of the layer. block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. num_random_blocks: optional: an integer determining the number of random blocks in each block row. num_sliding_window_blocks: optional: an integer determining the number of blocks in sliding local attention window. num_global_blocks: optional: an integer determining how many consecutive blocks, starting from index 0, are considered as global attention. Global block tokens will be attended by all other block tokens and will attend to all other block tokens as well. """ - super().__init__(num_heads, seq_len, block, different_layout_per_head) - if (self.num_blocks < num_random_blocks): - raise ValueError( - f'Number of random blocks, {num_random_blocks}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' - ) - self.num_random_blocks = num_random_blocks + super().__init__(num_heads, block, different_layout_per_head) - if (self.num_blocks < num_sliding_window_blocks): - raise ValueError( - f'Number of sliding window blocks, {num_sliding_window_blocks}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' - ) + self.num_random_blocks = num_random_blocks self.num_sliding_window_blocks = num_sliding_window_blocks - - if (self.num_blocks < num_global_blocks): - raise ValueError( - f'Number of global blocks, {num_global_blocks}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' - ) self.num_global_blocks = num_global_blocks - self.make_layout() - def set_random_layout(self, h): + def set_random_layout(self, h, layout): """Sets random attantion layout used by the given head in the sparse attention. Note) By default, it assumes there will be a unique random block layout for all heads; unless `different_layout_per_head` parameter is set in which each head can have a different random layout. Arguments: h: required: an integer determining head index + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head in which random layout is set """ - for row in range(0, self.num_blocks): - rnd_cols = random.sample(range(0, self.num_blocks), self.num_random_blocks) - self.layout[h, row, rnd_cols] = 1 + num_blocks = layout.shape[1] + if (num_blocks < self.num_random_blocks): + raise ValueError( + f'Number of random blocks, {self.num_random_blocks}, must be smaller than overal number of blocks in a row, {num_blocks}!' + ) + + for row in range(0, num_blocks): + rnd_cols = random.sample(range(0, num_blocks), self.num_random_blocks) + layout[h, row, rnd_cols] = 1 + return layout - def set_sliding_window_layout(self, h): + def set_sliding_window_layout(self, h, layout): """Sets sliding local attantion layout used by the given head in the sparse attention. Arguments: h: required: an integer determining head index + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head in which local sliding window layout is set """ + num_blocks = layout.shape[1] + if (num_blocks < self.num_sliding_window_blocks): + raise ValueError( + f'Number of sliding window blocks, {self.num_sliding_window_blocks}, must be smaller than overal number of blocks in a row, {num_blocks}!' + ) + w = self.num_sliding_window_blocks // 2 - for row in range(0, self.num_blocks): + for row in range(0, num_blocks): start = max(0, row - w) - end = min(row + w + 1, self.num_blocks) - self.layout[h, row, start:end] = 1 + end = min(row + w + 1, num_blocks) + layout[h, row, start:end] = 1 + return layout - def set_global_layout_itc(self, h): + def set_global_layout_itc(self, h, layout): """Sets global attantion layout used by the given head in the sparse attention. Arguments: h: required: an integer determining head index + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head in which global layout is set """ + num_blocks = layout.shape[1] + if (num_blocks < self.num_global_blocks): + raise ValueError( + f'Number of global blocks, {self.num_global_blocks}, must be smaller than overal number of blocks in a row, {num_blocks}!' + ) + #global rows - self.layout[h, 0:self.num_global_blocks, :] = 1 + layout[h, 0:self.num_global_blocks, :] = 1 #global columns - self.layout[h, :, 0:self.num_global_blocks] = 1 + layout[h, :, 0:self.num_global_blocks] = 1 + + return layout - def make_layout(self): + def make_layout(self, seq_len): """Generates `BigBird` sparsity layout used by each head in the sparse attention. + Arguments: + seq_len: required: an integer determining number of attention heads of the layer. + Return: - layout: a tensor determining the sparsity layout of each head + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing `BigBird` sparsity layout of all head """ + layout = self.setup_layout(seq_len) for h in range(0, self.num_layout_heads): - self.set_random_layout(h) - self.set_sliding_window_layout(h) - self.set_global_layout_itc(h) + layout = self.set_random_layout(h, layout) + layout = self.set_sliding_window_layout(h, layout) + layout = self.set_global_layout_itc(h, layout) - self.check_and_propagate_first_head_layout() - return self.layout + layout = self.check_and_propagate_first_head_layout(layout) + return layout class BSLongformerSparsityConfig(SparsityConfig): @@ -469,8 +550,7 @@ class BSLongformerSparsityConfig(SparsityConfig): This class extends parent class of `SparsityConfig` and customizes it for `Longformer` sparsity. """ def __init__(self, - num_heads=8, - seq_len=1024, + num_heads, block=16, different_layout_per_head=False, num_sliding_window_blocks=3, @@ -482,7 +562,6 @@ def __init__(self, Arguments: num_heads: required: an integer determining number of attention heads of the layer. - seq_len: required: an integer determining number of attention heads of the layer. block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. @@ -490,23 +569,10 @@ def __init__(self, global_block_indices: optional: a list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Default value is only index 0. Notice that if global_block_end_indices parameter is set, this parameter is used as starting index of each global window. global_block_end_indices: optional: a list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size of global_block_indices parameter, and combining this two parameters, for each index i, blocks from global_block_indices[i] to global_block_end_indices[i] (exclusive) are considered as global attention. """ - super().__init__(num_heads, seq_len, block, different_layout_per_head) - if (self.num_blocks < num_sliding_window_blocks): - raise ValueError( - f'Number of sliding window blocks, {num_sliding_window_blocks}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' - ) - self.num_sliding_window_blocks = num_sliding_window_blocks + super().__init__(num_heads, block, different_layout_per_head) - if (self.num_blocks < len(global_block_indices)): - raise ValueError( - f'Number of global blocks indices, {global_block_indices}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' - ) - for idx in global_block_indices: - if idx >= self.num_blocks: - raise ValueError( - f'Global block index, {global_block_indices[idx]}, must be smaller than overal number of blocks in a row, {self.num_blocks}!' - ) + self.num_sliding_window_blocks = num_sliding_window_blocks self.global_block_indices = global_block_indices if (global_block_end_indices is not None): @@ -515,61 +581,83 @@ def __init__(self, f'Global block start indices length, {len(global_block_indices)}, must be same as global block end indices length, {len(global_block_end_indices)}!' ) for _, (start_idx, end_idx) in enumerate(zip(global_block_indices, global_block_end_indices)): - if end_idx > self.num_blocks: - raise ValueError( - f'Global block end index, {global_block_end_indices[idx]}, must be smaller (equal) than overal number of blocks in a row, {self.num_blocks}!' - ) if start_idx >= end_idx: raise ValueError( f'Global block start index, {start_idx}, must be smaller than global block end index, {end_idx}!' ) self.global_block_end_indices = global_block_end_indices - self.make_layout() - def set_sliding_window_layout(self, h): + def set_sliding_window_layout(self, h, layout): """Sets sliding local attantion layout used by the given head in the sparse attention. Arguments: h: required: an integer determining head index + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head in which local sliding window layout is set """ + num_blocks = layout.shape[1] + if (num_blocks < self.num_sliding_window_blocks): + raise ValueError( + f'Number of sliding window blocks, {self.num_sliding_window_blocks}, must be smaller than overal number of blocks in a row, {num_blocks}!' + ) + w = self.num_sliding_window_blocks // 2 - for row in range(0, self.num_blocks): + for row in range(0, num_blocks): start = max(0, row - w) - end = min(row + w + 1, self.num_blocks) - self.layout[h, row, start:end] = 1 + end = min(row + w + 1, num_blocks) + layout[h, row, start:end] = 1 + return layout - def set_global_layout(self, h): + def set_global_layout(self, h, layout): """Sets global attantion layout used by the given head in the sparse attention. Arguments: h: required: an integer determining head index + layout: required: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head; may not be completly set at this step + + Return: + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing sparsity layout of all head in which global layout is set """ + + num_blocks = layout.shape[1] if (self.global_block_end_indices is None): for idx in self.global_block_indices: - #global rows - self.layout[h, idx, :] = 1 + # if global block idx is in the range of the sequnce blocks + if (idx < num_blocks): + #global rows + layout[h, idx, :] = 1 - #global columns - self.layout[h, :, idx] = 1 + #global columns + layout[h, :, idx] = 1 else: for _, (start_idx, end_idx) in enumerate(zip(self.global_block_indices, self.global_block_end_indices)): - #global rows - self.layout[h, start_idx:end_idx, :] = 1 + # if global block idx is in the range of the sequnce blocks + if (start_idx < num_blocks): + end_idx = min(end_idx, num_blocks) + #global rows + layout[h, start_idx:end_idx, :] = 1 - #global columns - self.layout[h, :, start_idx:end_idx] = 1 + #global columns + layout[h, :, start_idx:end_idx] = 1 + return layout - def make_layout(self): + def make_layout(self, seq_len): """Generates edited `Longformer` sparsity layout used by each head in the sparse attention. + Arguments: + seq_len: required: an integer determining number of attention heads of the layer. + Return: - layout: a tensor determining the sparsity layout of each head + layout: a tensor of dimension (num_heads, num_blocks, num_blocks) containing `BSLongformer` sparsity layout of all head """ + layout = self.setup_layout(seq_len) for h in range(0, self.num_layout_heads): - self.set_sliding_window_layout(h) - self.set_global_layout(h) + layout = self.set_sliding_window_layout(h, layout) + layout = self.set_global_layout(h, layout) - self.check_and_propagate_first_head_layout() - return self.layout + layout = self.check_and_propagate_first_head_layout(layout) + return layout diff --git a/deepspeed/pt/sparse_transformer/utils.py b/deepspeed/pt/sparse_transformer/utils.py index b5d8b6bd23eb..50bee1ea0407 100644 --- a/deepspeed/pt/sparse_transformer/utils.py +++ b/deepspeed/pt/sparse_transformer/utils.py @@ -3,6 +3,7 @@ """ from torch import nn +from torch.nn import functional as F from deepspeed.pt.sparse_transformer import BertSparseSelfAttention, SparsityConfig ''' This file contains few utility functions to handle adapting pretrained model with sparse self-attention module. @@ -76,8 +77,7 @@ def replace_model_self_attention_with_sparse_self_attention( model, max_position, # SparsityConfig parameters needs to be set accordingly - sparsity_config=SparsityConfig(num_heads=4, - seq_len=1024)): + sparsity_config=SparsityConfig(num_heads=4)): """This function replaces the self attention layers in model encoder with sparse self attention. It currently supports bert and roberta model and can be easily extended to any other models following similar steps here. For sparsityConfig, refer to the config class. @@ -114,8 +114,7 @@ def replace_self_attention_layer_with_sparse_self_attention_layer( config, layers, # SparsityConfig parameters needs to be set accordingly - sparsity_config=SparsityConfig(num_heads=4, - seq_len=1024)): + sparsity_config=SparsityConfig(num_heads=4)): """This function replaces the self attention layers in attention layer with sparse self attention. For sparsityConfig, refer to the config class. @@ -137,3 +136,80 @@ def replace_self_attention_layer_with_sparse_self_attention_layer( layer.attention.self = deepspeed_sparse_self_attn return layers + + +def pad_to_block_size(block_size, + input_ids, + attention_mask, + token_type_ids, + position_ids, + inputs_embeds, + pad_token_id, + model_mbeddings): + """This function pads input tokens and attention mask on sequence length dimension to be multiple of block size. + This is a requirement for Sparse Transformer in which the self attention layer works on sequences of length multiple of block size. + It needs to be called in your model, such as BertModel, right before you calculate the embedding outputs. + Note) + 1- instead of passing your embedding layer to this function, you can simply add this function to your model. It can be more simplified if given attention_mask and/or token_type_ids are none. + 2- you need to call unpdad function before returning your model output to unpad the encoder sequence output. + + Arguments: + block_size: required: an integer determining the block size of sparsity config. + pad_token_id: required: an integer determining the pad token from the model config; such as bert.config.pad_token_id. + input_ids: a torch.LongTensor of shape [batch_size, sequence_length] with the word token indices in the vocabulary + attention_mask: a torch.LongTensor of shape [batch_size, sequence_length] with indices selected in [0, 1]. It's a mask to be used if the input sequence length is smaller than the max input sequence length in the current batch. It's the mask that we typically use for attention when a batch has varying length sentences. + token_type_ids: a torch.LongTensor of shape [batch_size, sequence_length] with the token types indices selected in [0, 1]. Type 0 corresponds to a `sentence A` and type 1 corresponds to a `sentence B` token (see BERT paper for more details). + position_ids: a torch.LongTensor of shape [batch_size, sequence_length] with the indices of positions of each input sequence tokens in the position embeddings. + inputs_embeds: an optional torch.FloatTensor of shape [batch_size, sequence_length, hidden_size] that contains embedded representation and can be passed instead of input_ids directly. + model_embeddings: an optional object. If inputs_embeds are not none, this will be your model embeddings such as BertEmbeddings from your model such as BertModel. You can move this function inside your model and use self.embeddings instead of passing this parameter. + + Return: + pad_len: an integer determining how much inputs have been padded to transfer sequence length dimension to multiple of block size. + input_ids: if input_ids are not none padded input_ids otherwise none. + attention_mask: if attention_mask is not none padded attention_mask otherwise none. + token_type_ids: if token_type_ids are not none padded token_type_ids otherwise none. + position_ids: if position_ids are not none padded position_ids otherwise none. + inputs_embeds: if inputs_embeds are not none padded inputs_embeds otherwise none. + """ + + batch_size, seq_len = input_ids.shape if input_ids is not None else inputs_embeds.shape[:-1] + + pad_len = (block_size - seq_len % block_size) % block_size + if pad_len > 0: + if inputs_embeds is not None: + pad_input_ids = inputs_embeds.new_full((batch_size, + pad_len), + pad_token_id, + dtype=torch.long) + pad_inputs_embeds = model_embeddings(pad_input_ids) + inputs_embeds = torch.cat([inputs_embeds, pad_inputs_embeds], dim=-2) + # may not be needed as input_ids are not used if inputs_embeds are given + if input_ids is not None: + input_ids = F.pad(input_ids, (0, pad_len), value=pad_token_id) + if position_ids is not None: + # pad position_id with pad_token_id + position_ids = F.pad(position_ids, (0, pad_len), value=pad_token_id) + # pad attention mask without attention on the padding tokens + attention_mask = F.pad(attention_mask, (0, pad_len), value=False) + # pad token_type_ids with token_type_id = 0 + token_type_ids = F.pad(token_type_ids, (0, pad_len), value=0) + + return pad_len, input_ids, attention_mask, token_type_ids, position_ids, inputs_embeds + + +def unpad_sequence_output(pad_len, sequence_output): + """This function unpads sequence output if inputs of the model were padded. + This is a requirement for Sparse Transformer in which the self attention layer works on sequences of length multiple of block size. + It needs to be called in your model, such as BertModel, right before you return the model outputs. + + Arguments: + pad_len: required: an integer determining how much model inputs have been padded to transfer sequence length dimension to multiple of block size. + sequence_output: required: sequence output of the encoder layer. + + Return: + sequence_output: unpaded sequence output of the encoder layer. + """ + + if (pad_len > 0): + sequence_output = sequence_output[:, :-pad_len] + return sequence_output diff --git a/tests/unit/test_sparse_transformer.py b/tests/unit/test_sparse_transformer.py index b86405e99a0e..e3aeca438ab9 100755 --- a/tests/unit/test_sparse_transformer.py +++ b/tests/unit/test_sparse_transformer.py @@ -137,7 +137,7 @@ def test_replace_model_self_attention_with_sparse_self_attention_module_availabi return True -def test_replace_self_attention_layer_with_sparse_self_attention_layer_modules_availability( +def test_replace_self_attention_layer_with_sparse_self_attention_layer_module_availability( ): try: from deepspeed.pt.sparse_transformer import replace_self_attention_layer_with_sparse_self_attention_layer @@ -149,6 +149,24 @@ def test_replace_self_attention_layer_with_sparse_self_attention_layer_modules_a return True +def test_pad_to_block_size_module_availability(): + try: + from deepspeed.pt.sparse_transformer import pad_to_block_size + except ImportError: + print("Sparse Transformer pad_to_block_size Module is not installed!") + return False + return True + + +def test_unpad_sequence_output_module_availability(): + try: + from deepspeed.pt.sparse_transformer import unpad_sequence_output + except ImportError: + print("Sparse Transformer unpad_sequence_output Module is not installed!") + return False + return True + + def dense_to_sparse(w, mask, block): """Converts dense matrix with explicit zeros to sparse matrix """ From fb5bec262e404218382008d331c15dae3437ffaf Mon Sep 17 00:00:00 2001 From: Arash Ashari Date: Tue, 25 Aug 2020 13:15:25 -0700 Subject: [PATCH 08/16] Adding Sparse Transformer Tutorial Documentation (#70) * Adding Sparse Transformer Tutorial Documentation --- docs/_tutorials/sparse_transformer.md | 81 ++++++++++++++++++ docs/assets/images/fixed_sparsity_pattern.png | Bin 0 -> 51803 bytes .../images/variable_sparsity_pattern.png | Bin 0 -> 42663 bytes 3 files changed, 81 insertions(+) create mode 100644 docs/_tutorials/sparse_transformer.md create mode 100644 docs/assets/images/fixed_sparsity_pattern.png create mode 100644 docs/assets/images/variable_sparsity_pattern.png diff --git a/docs/_tutorials/sparse_transformer.md b/docs/_tutorials/sparse_transformer.md new file mode 100644 index 000000000000..82bc93a88ef6 --- /dev/null +++ b/docs/_tutorials/sparse_transformer.md @@ -0,0 +1,81 @@ +--- +title: "DeepSpeed Sparse Transformer (Sparse Self Attention)" +--- + +In this tutorial we describe how to use DeepSpeed Sparse Self Attention and its building-block kernels through DeepSpeed launcher or integrating individual kernels into your code. + +## How to use +DeepSpeed Sparse transformer can be used as a feature through DeepSpeed, or simply integrated with any Transformer model as a self-attention module alone. Further, the building block kernels, matrix multiplication and softmax can be used separately. To use sparse transformer alone, you can simply install DeepSpeed and import any of the following modules from it; example: +```python +from deepspeed.pt.sparse_transformer import SparseSelfAttention +``` +Following we describe Sparse Transformer modules: +* **MatMul**: this module handles block-sparse matrix-matrix multiplication. Currently it supports SDD, DSD, and DDS as described in [DeepSpeed Sparse Transformer](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_posts/2020-08-00-sparse-transformer.md) section. +* **Softmax**: this module applies block sparse softmax. It handles both forward and backward pass. +* **SparseSelfAttention**: this module uses MatMul and Softmax kernels and generates Context Layer output given Query, Keys and Values. It is a simplified version of common operations in any self-attention layer. It can also apply: + * `Relative position embedding` + * `Attention mask` + * `Key padding mask` +on the intermediate attention scores. For more details about SelfAttantion, please check [MultiHeadAttention](https://pytorch.org/docs/master/generated/torch.nn.MultiheadAttention.html#multiheadattention). +* **BertSparseSelfAttention**: This module contains a simplified BertSelfAttention layer that can be used instead of original dense Bert Self-Attention layer. Our implementation is based on [DeepSpeedExample](https://github.com/microsoft/DeepSpeedExamples/blob/9e2c34e31cec99f7d5785c6a1a3b0854c322f883/bing_bert/nvidia/modelingpreln.py#L373-#L434). +* **Utils**: we also provide few utility modulse/functions to handle adapting pre-trained model with sparse self-attention: + * `replace_model_self_attention_with_sparse_self_attention`: If you have currently loaded a model and want to replace self-attention module with sparse self-attention, you can simply use this function to handle it for you. It currently handles BERT and RoBERTa based pre-trained models, but you can extend it base on your model type if it is different from these two. You also need to extend the position embedding to handle new sequence length; this can be done using `extend_position_embedding` function. + * `update_tokenizer_model_max_length`: This function simply updates maximum position embedding in your tokenizer with the new value. + * `extend_position_embedding`: This function extends the position embedding based on the current values. For example, if you have a 128 max sequence length model and extending it to a 1k sequence length, it replicates current embeddings 8 times to initialize new embedding. Experimentally we have seen such initialization works much better than initializing from scratch; leads to faster convergence. +* **SparsityConfig**: this is an abstract class for sparsity structure. Any sparsity structure extends this class and writes its own `make_layout` function. DeepSpeed currently provides the following structures that will be described in next section: + * `FixedSparsityConfig` + * `BSLongformerSparsityConfig` + * `BigBirdSparsityConfig` + * `VariableSparsityConfig` + +#### BertSparseSelfAttention Example +We have currently integrated Sparse Transformer with our [bing-bert](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/nvidia/modelingpreln.py) code that can be used as an example for integration. In this example, we replace, BertSelfAttention module with BertSparseSelfAttention. Using DeepSpeed launcher, you can enable sparse transformer using `deepspeed_sparse_attention` argument ([example](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/deepspeed_bsz64k_lamb_config_seq128.json)) and add your desired sparsity config into the [DeepSpeed config file](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/deepspeed_bsz64k_lamb_config_seq128.json). In this example, we have used `fixed` sparsity mode. + + +#### Sparsity structures +Following we describe supported sparsity structures, their parameter set and the flexibility of adding arbitrary sparsity pattern on the self-attention layer. +First, `SpasityConfig` module, which is the parent class, takes the following parameters: + * `num_heads`: an integer determining number of attention heads of the layer. + * `seq_len`: an integer determining number of attention heads of the layer. + * `block`: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such square blocks; `Block X Block`. + * `different_layout_per_head`: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. + +* **Fixed**: +This pattern is based on [Generative Modeling with Sparse Transformers](https://arxiv.org/abs/1904.10509), in which local and global attention is fixed by the given parameters: + * `num_local_blocks`: an integer determining the number of blocks in local attention window. As it is illustrated in the below figure (adapted from original paper), tokens in a local window, attend to all tokens local to them. In the case of autoregressive model, as in the figure, tokens attend to tokens appearing before them in the local window. And in the case of Masked model such as BERT, attention is bidirectional. + * `num_global_blocks`: an integer determining how many consecutive blocks in a local window is used as the representative of the window for global attention; illustrated in the figure below as well. + * `attention`: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. + * `horizontal_global_attention`: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but also horizontal blocks. + * `num_different_global_patterns`: an integer determining number of different global attentions layouts. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks constructing local window and global attention size of a single block, we can have 4 different versions in which the first, second, third, or forth block of each local window can be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on `num_local_blocks` and `num_global_blocks`. Further, if you set this to more than one, you need to set `different_layout_per_head` to `True`. + +![fixed_sparsity_pattern](/assets/images/fixed_sparsity_pattern.png) + +* **BSLongformer**: +This pattern is an edited version of [Longformer: The Long-Document Transformer](https://arxiv.org/pdf/2004.05150.pdf), in which instead of single token-wise sparsity, we offer block of tokens sparsity. Parameters that define this patters are: + * `num_sliding_window_blocks`: an integer determining the number of blocks in sliding local attention window. + * `global_block_indices`: a list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Notice that if `global_block_end_indices` parameter is set, this parameter is used as starting index of each global window. + * `global_block_end_indices`: a list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size as `global_block_indices` parameter, and combining this two parameters, for each index `i`, blocks from `global_block_indices[i]` to `global_block_end_indices[i]` (exclusive) are considered as global attention block. + +* **BigBird**: +This pattern is based on [Big Bird: Transformers for Longer Sequences](https://arxiv.org/pdf/2007.14062.pdf). It somehow combines the idea of `fixed` and `longformer` patterns along with random attention. Following parameters define this structure: + * `num_random_blocks`: an integer determining how many blocks in each row block are attended randomly. + * `num_sliding_window_blocks`: an integer determining the number of blocks in sliding local attention window. + * `num_global_blocks`: an integer determining how many consecutive blocks, starting from index 0, are considered as global attention. Global block tokens will be attended by all other block tokens and will attend to all other block tokens as well. + +* **Variable**: +This pattern also combines the idea of local, global and random attention. Further, it has the flexibility of defining variable size local windows. Following is the list of parameters that define this structure: + * `num_random_blocks`: an integer determining how many blocks in each row block are attended randomly. + * `local_window_blocks`: a list of integers determining the number of blocks in each local attention window. It assumes first number determines # of blocks in the first local window, second number the second window, ..., and the last number determines the number of blocks in the remaining local windows. + * `global_block_indices`: a list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Notice that if `global_block_end_indices` parameter is set, this parameter is used as starting index of each global window. + * `global_block_end_indices`: a list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size as `global_block_indices` parameter, and combining this two parameters, for each index `i`, blocks from `global_block_indices[i]` to `global_block_end_indices[i]` (exclusive) are considered as global attention block. + * `attention`: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. + * `horizontal_global_attention`: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but also horizontal blocks +Figure bellow illustrates an example of `variable` sparsity, in which blue, orange and green blocks illustrate local, global, and random attention blocks respectively. + +![variable_sparsity_pattern](/assets/images/variable_sparsity_pattern.png) + +Further, we provide a `dense` pattern (`DenseSparsityConfig`), that can be used for the sake of testing while it represents the full attention. + + +#### How to expand block-base sparsity patterns +Our building block kernels, block-based `MatMul` & `Softmax`, can accept any block-based sparsity. This provides the flexibility to apply any block-based sparsity pattern to attention score. To define and apply a new sparsity pattern, you can simply follow any of the above sparsity structures. You need to add a new class that expands `SparsityConfig` and define `make_layout` function based on how your sparsity is structured. You can add any extra parameters you may need or just use default parameters of the parent class. diff --git a/docs/assets/images/fixed_sparsity_pattern.png b/docs/assets/images/fixed_sparsity_pattern.png new file mode 100644 index 0000000000000000000000000000000000000000..eb463e246282e6468e68c0ee880892e7ab519fd9 GIT binary patch literal 51803 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

UK`ZW${Z~%bHYT_b; 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 literal 0 HcmV?d00001 diff --git a/docs/assets/images/variable_sparsity_pattern.png b/docs/assets/images/variable_sparsity_pattern.png new file mode 100644 index 0000000000000000000000000000000000000000..09fb18be7ee041596950a35d1b41765f349ad4cf GIT binary patch literal 42663 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 a>N(jG30PVp`-}etK9m&H Date: Tue, 25 Aug 2020 13:17:49 -0700 Subject: [PATCH 09/16] adding documentation for Sparse Transformer and current result (#64) * adding documentation for Sparse Transformer and current result --- docs/_posts/2020-08-00-sparse-transformer.md | 35 +++++++++ docs/_tutorials/sparse_transformer_results.md | 68 ++++++++++++++++++ .../sparse_self_attention_backward_pass.png | Bin 0 -> 18207 bytes .../sparse_self_attention_forward_pass.png | Bin 0 -> 13237 bytes docs/assets/images/st_bert_base_result.png | Bin 0 -> 41819 bytes docs/assets/images/st_bert_large_result.png | Bin 0 -> 29423 bytes docs/assets/images/st_deepthink_result.png | Bin 0 -> 25294 bytes .../assets/images/st_megatron_gpt2_result.png | Bin 0 -> 36251 bytes 8 files changed, 103 insertions(+) create mode 100644 docs/_posts/2020-08-00-sparse-transformer.md create mode 100644 docs/_tutorials/sparse_transformer_results.md create mode 100644 docs/assets/images/sparse_self_attention_backward_pass.png create mode 100644 docs/assets/images/sparse_self_attention_forward_pass.png create mode 100644 docs/assets/images/st_bert_base_result.png create mode 100644 docs/assets/images/st_bert_large_result.png create mode 100644 docs/assets/images/st_deepthink_result.png create mode 100644 docs/assets/images/st_megatron_gpt2_result.png diff --git a/docs/_posts/2020-08-00-sparse-transformer.md b/docs/_posts/2020-08-00-sparse-transformer.md new file mode 100644 index 000000000000..ca442231fe7c --- /dev/null +++ b/docs/_posts/2020-08-00-sparse-transformer.md @@ -0,0 +1,35 @@ +--- +layout: single +title: "DeepSpeed Sparse Transformer (Sparse Self Attention)" +excerpt: "" +categories: news +new_post: true +date: 2020-08-00 00:00:00 +--- + +We introduce DeepSpeed Sparse Transformer, an instrumental technology to support long sequence of model inputs, whether for text, image or sound. Comparing with the classic dense transformers, it powers input sequence with an order-of-magnitude longer and obtains up to 6x faster execution with comparable accuracy; it also outperforms state-of-arts sparse implementations with 1.5 - 3x faster execution. Furthermore, our sparse kernels support efficient execution of flexible sparse format and empower users to innovate on their customized sparse structures. +This library is PyTorch based and develops required kernels through [Triton](https://github.com/ptillet/triton) platform; kernels are not written in CUDA, which leaves the door open for CPU/OpenCL/Vulkan support in the future. The library is an extension to DeepSpeed and can be used through DeepSpeed as well as stand alone. +DeepSpeed Sparse Attention kernels, handles the following block-sparse computations: +(`S` stands for a `sparse matrix` and `D` a `dense matrix`. Sparse matrix is `blocked sparse matrix`.) + +* Forward: + +![sparse_self_attention_forward_pass](/assets/images/sparse_self_attention_forward_pass.png){: .align-center} + + * `S = D X D => w = q X trans(k)` + * `S = softmax(S) => w = softmax(w)` + * `D = S X D => a = w X v` + + +* Backward: + +![sparse_self_attention_backward_pass](/assets/images/sparse_self_attention_backward_pass.png){: .align-center} + + * `D = S X D => v = trans(w) X da` + * `S = D X D => w = da X trans(v)` + * `S = bwd_softmax(S) => dw = w X (dw - sum(dw X w))` + * `D = D X S => k = q X trans(dw)` + * `D = S X D => q = dw X k` + +For Sparsity Config, and also how to use this library, please check our [tutorial](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_tutorials/sparse_transformer.md) that provides detailed information about it. +In [result](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_tutorials/sparse_transformer_results.md) section, we provide a summary of our experiments using this library. This section also contains experiments comparing our library with [Longformer](https://arxiv.org/abs/2004.05150); state-of-arts sparse implementation of sparsity pattern. diff --git a/docs/_tutorials/sparse_transformer_results.md b/docs/_tutorials/sparse_transformer_results.md new file mode 100644 index 000000000000..d71d836aff6c --- /dev/null +++ b/docs/_tutorials/sparse_transformer_results.md @@ -0,0 +1,68 @@ +--- +layout: single +title: "DeepSpeed Sparse Transformer - experimental results)" +excerpt: "" +categories: news +new_post: true +date: 2020-08-00 00:00:00 +--- + +* **Power 10x longer sequences** +We have run a pre-training experiment using BERT model, both base and large, with batch size of 1 on a single Nvidia V100 GPU-32GB memory. Following table shows maximum possible sequence length for: + * original dense model + * + adding checkpointing + * and replacing self-attention with sparse self-attention + +|Max SeqLen |Dense |Dense\_chpt|Sparse\_chpt| +|---------------|-------|-----------|------------| +|BERT Base |4k |14k |39k | +|BERT Large |2k |12k |32k | + +* **up to 6.3x faster computation** +Further, we ran a pre-training experiment for different batch sizes and sequence lengths, using [BERT base/large](https://github.com/microsoft/DeepSpeedExamples/tree/fd869ae1c9de686f8cb92413efeba83fc989027c/bing_bert) model and [Megatron GPT2](https://github.com/microsoft/DeepSpeedExamples/tree/master/Megatron-LM). In this experiment we let the experiment to continue for 100 iteration and recorded the average time per last 30 iterations. Following charts shows these results in which we can see up to `6.3X`, `5.3X`, and `6.1X` speed up for BERT Base, BERT large and GPT2 models respectively. + +![st_bert_base_result](/assets/images/st_bert_base_result.png){: .align-center} +![st_bert_large_result](/assets/images/st_bert_result_result.png){: .align-center} +![st_megatron_gpt2_result](/assets/images/st_megatron_gpt2_result.png){: .align-center} + +* **higher accuracy** +In addition to lower memory overhead and faster computation, interestingly we have seen higher accuracy and faster convergence. As mentioned in the original paper, this may point to a useful inductive bias introduced by sparsity or an underlying optimization issue in full attention. In the following chart we show accuracy of fine-tuning three models for long document comprehension. In this application we use sequence length of 2k. What we have observed, pre-training from scratch, sparse transformer is much faster and converges with the higher accuracy. Further, fine-tuning from a pre-trained checkpoint, we gain better performance in the point of time and accuracy. In how to use section we will describe how to extend a pre-trained model with smaller sequence lengths, to be used fine-tuning with sparse transformer. + +![st_deepthink_result](/assets/images/st_deepthink_result.png){: .align-center} + +* **flexibility to handle any block-sparse structure** +DeepSpeed sparse kernels support efficient execution of flexible sparse format and empower users to innovate on their customized sparse structures. Currently DeepSpeed has added the following sparsity structures: + * `Fixed` + * `BigBird` + * `BSLongformer` (Block-Sparse Longformer) + * `Variable` (Can be used to simply customize any block-sparse random/local/global attention pattern.) +In addition to this list, user can add any other sparsity structure as described in [tutorial](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_tutorials/sparse_transformer.md) section. + + +# Comparison with Longformer +[Longformer](https://arxiv.org/abs/2004.05150) is another sparse transformer work that leverages the idea of local and global notion sparsifying the attention matrix. Local attention is satisfied through local sliding window attention, and global attention through global task specific attention. Longformer has been applied to multiple downstream tasks where it shows superior result compared to SOTA. Considering that these kind of works sparsify the attention matrix similarly, we expect comparable accuracy result. This is what we have observed through few experiments that we will show in the following. However, we have noticed higher speed in DeepSpeed Sparse Self-Attention compared to Longformer. +In the first experiment, we have followed the [notebook](https://github.com/allenai/longformer/blob/master/scripts/convert_model_to_long.ipynb) offered by Longformer. In this experiment, we pre-train an MLM model using RoBERTa-base checkpoint. This is done on 8 GPU V100-SXM2 node. Following table shows the result in which using DeepSpeed Sparse Self-Attention, we see up to **1.47X** speed-up. + +|Model |Window - Stride |BPC |Train Step |Time Per Iteration |Time Improvement |Accuracy improvement | +|-------------------|----------------|--------|------------|--------------------|------------------|----------------------| +|RoBERTa Checkpoint | |2.5326 | | +|Longformer |512 |2.6535 |0 | |1.47 |1.01 | +|Sparse Transformer | |2.6321 | | | | | +|Longformer | |1.6708 |3k |1.6280 | |1.01 | +|Sparse Transformer | |1.6613 | |1.1059 | | | +|Longformer |64 |5.7840 |0 | |1.31 |1.46 | +|Sparse Transformer | |3.9737 | | | | | +|Longformer | |2.0466 |3k |1.4855 | |1.09 | +|Sparse Transformer | |1.8693 | |1.1372 | | | + + +Through our DeepThink application we described above, we also checked the inference time for different window sizes testing BERT model on a `2k` Sequence Length and batch size `1`. In this experiment, we noticed up to `3.13X` speed up replacing Bert Self-Attention with DeepSpeed Sparse Self-Attention instead of Longformer Self-Attention. Following table shows the complete result. + +|Window Size / Stride |Time Improvement| +|----------------------|----------------| +|512 |3.13 | +|256 |2.29 | +|128 |2.16 | +|64 |1.5 | +|32 |1.24 | +|16 |1.23 | diff --git a/docs/assets/images/sparse_self_attention_backward_pass.png b/docs/assets/images/sparse_self_attention_backward_pass.png new file mode 100644 index 0000000000000000000000000000000000000000..1b0a2a0f188ab0af04b48a6818dc0c36dcde0351 GIT binary patch literal 18207 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 WzkAa75csMKnw*rfWTE(zH~$wqK47f? literal 0 HcmV?d00001 diff --git a/docs/assets/images/sparse_self_attention_forward_pass.png b/docs/assets/images/sparse_self_attention_forward_pass.png new file mode 100644 index 0000000000000000000000000000000000000000..d6affbd4f1e925d02326686388a97db48db51711 GIT binary patch literal 13237 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 literal 0 HcmV?d00001 diff --git a/docs/assets/images/st_bert_base_result.png b/docs/assets/images/st_bert_base_result.png new file mode 100644 index 0000000000000000000000000000000000000000..0638950f71f6bc57d3f446db6dea0e0edbb8a70c GIT binary patch literal 41819 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 literal 0 HcmV?d00001 diff --git a/docs/assets/images/st_deepthink_result.png b/docs/assets/images/st_deepthink_result.png new file mode 100644 index 0000000000000000000000000000000000000000..36b7f9f2b3362e5fba50bffb2f233002844aa426 GIT binary patch literal 25294 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 literal 0 HcmV?d00001 From f75791cd13358bd2eb4847cc0bd4f4137c6722cb Mon Sep 17 00:00:00 2001 From: Jeff Rasley Date: Thu, 27 Aug 2020 15:47:24 -0700 Subject: [PATCH 10/16] DeepSpeed ops refactor (#73) * major refactor to separate main ds components --- .gitignore | 2 +- basic_install_test.py | 5 +- deepspeed/__init__.py | 37 +++++++------ deepspeed/{pt => launcher}/__init__.py | 0 .../launch.py} | 2 +- .../deepspeed_run.py => launcher/runner.py} | 8 +-- deepspeed/ops/__init__.py | 0 deepspeed/ops/lamb/__init__.py | 1 + .../lamb/fused_lamb.py} | 42 +++++++-------- .../sparse_transformer/__init__.py | 0 .../bert_sparse_self_attention.py | 2 +- .../{pt => ops}/sparse_transformer/matmul.py | 8 +-- .../{pt => ops}/sparse_transformer/softmax.py | 2 +- .../sparse_self_attention.py | 2 +- .../sparse_transformer/sparsity_config.py | 0 .../sparse_transformer}/trsrc/__init__.py | 3 +- .../sparse_transformer/trsrc}/matmul.tr | 0 .../sparse_transformer/trsrc}/softmax_bwd.tr | 0 .../sparse_transformer/trsrc}/softmax_fwd.tr | 0 .../{pt => ops}/sparse_transformer/utils.py | 2 +- deepspeed/ops/transformer/__init__.py | 1 + .../transformer/transformer.py} | 36 ++++++++++--- deepspeed/runtime/__init__.py | 0 .../activation_checkpointing/__init__.py | 0 .../checkpointing.py} | 13 ++--- .../activation_checkpointing/config.py} | 2 +- .../deepspeed_config.py => runtime/config.py} | 12 ++--- .../config_utils.py} | 0 .../constants.py} | 0 .../csr_tensor.py} | 0 .../dataloader.py} | 0 .../deepspeed_light.py => runtime/engine.py} | 39 +++++++------- deepspeed/runtime/fp16/__init__.py | 0 .../fp16/fused_optimizer.py} | 6 +-- deepspeed/{pt => runtime/fp16}/loss_scaler.py | 0 .../fp16/unfused_optimizer.py} | 6 +-- .../lr_schedules.py} | 4 +- .../deepspeed_utils.py => runtime/utils.py} | 2 +- deepspeed/runtime/zero/__init__.py | 0 .../zero/config.py} | 5 +- .../zero/stage1.py} | 10 ++-- .../zero/stage2.py} | 9 ++-- .../zero_utils.py => runtime/zero/utils.py} | 2 +- deepspeed/utils/__init__.py | 1 + .../{pt/log_utils.py => utils/logging.py} | 0 .../{pt/deepspeed_timer.py => utils/timer.py} | 2 +- install.sh | 3 +- setup.py | 33 +++++++----- tests/unit/test_checkpointing.py | 8 +-- tests/unit/test_config.py | 2 +- tests/unit/test_csr.py | 2 +- tests/unit/test_ds_config.py | 2 +- tests/unit/test_run.py | 2 +- tests/unit/test_sparse_transformer.py | 54 +++++++++++-------- 54 files changed, 203 insertions(+), 169 deletions(-) rename deepspeed/{pt => launcher}/__init__.py (100%) rename deepspeed/{pt/deepspeed_launch.py => launcher/launch.py} (99%) rename deepspeed/{pt/deepspeed_run.py => launcher/runner.py} (98%) create mode 100644 deepspeed/ops/__init__.py create mode 100644 deepspeed/ops/lamb/__init__.py rename deepspeed/{pt/deepspeed_fused_lamb.py => ops/lamb/fused_lamb.py} (89%) rename deepspeed/{pt => ops}/sparse_transformer/__init__.py (100%) rename deepspeed/{pt => ops}/sparse_transformer/bert_sparse_self_attention.py (95%) rename deepspeed/{pt => ops}/sparse_transformer/matmul.py (99%) rename deepspeed/{pt => ops}/sparse_transformer/softmax.py (99%) rename deepspeed/{pt => ops}/sparse_transformer/sparse_self_attention.py (98%) rename deepspeed/{pt => ops}/sparse_transformer/sparsity_config.py (100%) rename deepspeed/{ => ops/sparse_transformer}/trsrc/__init__.py (88%) rename deepspeed/{trsrc/sparse_transformer => ops/sparse_transformer/trsrc}/matmul.tr (100%) rename deepspeed/{trsrc/sparse_transformer => ops/sparse_transformer/trsrc}/softmax_bwd.tr (100%) rename deepspeed/{trsrc/sparse_transformer => ops/sparse_transformer/trsrc}/softmax_fwd.tr (100%) rename deepspeed/{pt => ops}/sparse_transformer/utils.py (99%) create mode 100644 deepspeed/ops/transformer/__init__.py rename deepspeed/{pt/deepspeed_cuda.py => ops/transformer/transformer.py} (94%) mode change 100755 => 100644 create mode 100644 deepspeed/runtime/__init__.py create mode 100644 deepspeed/runtime/activation_checkpointing/__init__.py rename deepspeed/{pt/deepspeed_checkpointing.py => runtime/activation_checkpointing/checkpointing.py} (96%) rename deepspeed/{pt/deepspeed_checkpointing_config.py => runtime/activation_checkpointing/config.py} (95%) rename deepspeed/{pt/deepspeed_config.py => runtime/config.py} (95%) rename deepspeed/{pt/deepspeed_config_utils.py => runtime/config_utils.py} (100%) rename deepspeed/{pt/deepspeed_constants.py => runtime/constants.py} (100%) rename deepspeed/{pt/deepspeed_csr_tensor.py => runtime/csr_tensor.py} (100%) rename deepspeed/{pt/deepspeed_dataloader.py => runtime/dataloader.py} (100%) rename deepspeed/{pt/deepspeed_light.py => runtime/engine.py} (98%) create mode 100644 deepspeed/runtime/fp16/__init__.py rename deepspeed/{pt/fp16_optimizer.py => runtime/fp16/fused_optimizer.py} (98%) rename deepspeed/{pt => runtime/fp16}/loss_scaler.py (100%) rename deepspeed/{pt/fp16_unfused_optimizer.py => runtime/fp16/unfused_optimizer.py} (98%) rename deepspeed/{pt/deepspeed_lr_schedules.py => runtime/lr_schedules.py} (99%) rename deepspeed/{pt/deepspeed_utils.py => runtime/utils.py} (99%) create mode 100644 deepspeed/runtime/zero/__init__.py rename deepspeed/{pt/deepspeed_zero_config.py => runtime/zero/config.py} (94%) rename deepspeed/{pt/zero_optimizer_stage1.py => runtime/zero/stage1.py} (99%) rename deepspeed/{pt/deepspeed_zero_optimizer.py => runtime/zero/stage2.py} (97%) rename deepspeed/{pt/zero_utils.py => runtime/zero/utils.py} (95%) create mode 100644 deepspeed/utils/__init__.py rename deepspeed/{pt/log_utils.py => utils/logging.py} (100%) rename deepspeed/{pt/deepspeed_timer.py => utils/timer.py} (99%) diff --git a/.gitignore b/.gitignore index e83ac2d32f53..2d2878e2b6f7 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ deepspeed/git_version_info.py # Build + installation data build/ dist/ -fused_lamb_*.so +*.so deepspeed.egg-info/ # Website diff --git a/basic_install_test.py b/basic_install_test.py index 966b124f5813..7207fe0319c6 100644 --- a/basic_install_test.py +++ b/basic_install_test.py @@ -18,7 +18,7 @@ raise err try: - fused_lamb = importlib.import_module('deepspeed_lamb_cuda') + fused_lamb = importlib.import_module('deepspeed.ops.lamb.fused_lamb_cuda') print('deepspeed fused lamb kernels successfully installed') except Exception as err: raise err @@ -30,7 +30,8 @@ print("using new-style apex") try: - ds_transformer = importlib.import_module('deepspeed_transformer_cuda') + ds_transformer = importlib.import_module( + 'deepspeed.ops.transformer.transformer_cuda') print('deepspeed transformer kernels successfully installed') except Exception as err: raise err diff --git a/deepspeed/__init__.py b/deepspeed/__init__.py index b1970ac4ebbe..5f55b49fece8 100755 --- a/deepspeed/__init__.py +++ b/deepspeed/__init__.py @@ -2,14 +2,13 @@ Copyright 2020 The Microsoft DeepSpeed Team ''' -from deepspeed.pt.deepspeed_light import DeepSpeedLight -from deepspeed.pt.deepspeed_light import ADAM_OPTIMIZER, LAMB_OPTIMIZER -from deepspeed.pt.deepspeed_lr_schedules import add_tuning_arguments -from deepspeed.pt.log_utils import logger -from deepspeed.pt.deepspeed_cuda import DeepSpeedTransformerLayer, DeepSpeedTransformerConfig -from deepspeed.pt.deepspeed_config import DeepSpeedConfig - -import deepspeed.pt.deepspeed_checkpointing as checkpointing +from deepspeed.runtime.engine import DeepSpeedEngine +from deepspeed.runtime.engine import ADAM_OPTIMIZER, LAMB_OPTIMIZER +from deepspeed.runtime.lr_schedules import add_tuning_arguments +from deepspeed.runtime.config import DeepSpeedConfig +from deepspeed.runtime.activation_checkpointing import checkpointing +from deepspeed.ops.transformer import DeepSpeedTransformerLayer, DeepSpeedTransformerConfig +from deepspeed.utils import logger try: from deepspeed.git_version_info import git_hash, git_branch @@ -19,7 +18,7 @@ # Export version information __version_major__ = 0 -__version_minor__ = 2 +__version_minor__ = 3 __version_patch__ = 0 __version__ = '.'.join( map(str, @@ -90,16 +89,16 @@ def initialize(args, __git_branch__), ) - engine = DeepSpeedLight(args=args, - model=model, - optimizer=optimizer, - model_parameters=model_parameters, - training_data=training_data, - lr_scheduler=lr_scheduler, - mpu=mpu, - dist_init_required=dist_init_required, - collate_fn=collate_fn, - config_params=config_params) + engine = DeepSpeedEngine(args=args, + model=model, + optimizer=optimizer, + model_parameters=model_parameters, + training_data=training_data, + lr_scheduler=lr_scheduler, + mpu=mpu, + dist_init_required=dist_init_required, + collate_fn=collate_fn, + config_params=config_params) return_items = [ engine, diff --git a/deepspeed/pt/__init__.py b/deepspeed/launcher/__init__.py similarity index 100% rename from deepspeed/pt/__init__.py rename to deepspeed/launcher/__init__.py diff --git a/deepspeed/pt/deepspeed_launch.py b/deepspeed/launcher/launch.py similarity index 99% rename from deepspeed/pt/deepspeed_launch.py rename to deepspeed/launcher/launch.py index 55399194d23d..b59a13d33bb6 100755 --- a/deepspeed/pt/deepspeed_launch.py +++ b/deepspeed/launcher/launch.py @@ -10,7 +10,7 @@ from collections import defaultdict from argparse import ArgumentParser, REMAINDER -from deepspeed.pt.log_utils import logger +from deepspeed.utils import logger def parse_args(): diff --git a/deepspeed/pt/deepspeed_run.py b/deepspeed/launcher/runner.py similarity index 98% rename from deepspeed/pt/deepspeed_run.py rename to deepspeed/launcher/runner.py index 894657faa02c..920af79b460f 100755 --- a/deepspeed/pt/deepspeed_run.py +++ b/deepspeed/launcher/runner.py @@ -14,8 +14,8 @@ import torch.cuda -from deepspeed.pt.deepspeed_constants import TORCH_DISTRIBUTED_DEFAULT_PORT -from deepspeed.pt.log_utils import logger +from deepspeed.runtime.constants import TORCH_DISTRIBUTED_DEFAULT_PORT +from deepspeed.utils import logger DLTS_HOSTFILE = "/job/hostfile" EXPORT_ENVS = ["NCCL", "PYTHON"] @@ -285,7 +285,7 @@ def main(args=None): sys.executable, "-u", "-m", - "deepspeed.pt.deepspeed_launch", + "deepspeed.runtime.launch", "--world_info={}".format(world_info_base64), "--master_addr={}".format(args.master_addr), "--master_port={}".format(args.master_port) @@ -328,7 +328,7 @@ def main(args=None): sys.executable, "-u", "-m", - "deepspeed.pt.deepspeed_launch", + "deepspeed.runtime.launch", '--world_info={}'.format(world_info_base64), "--node_rank=%n", "--master_addr={}".format(args.master_addr), diff --git a/deepspeed/ops/__init__.py b/deepspeed/ops/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/deepspeed/ops/lamb/__init__.py b/deepspeed/ops/lamb/__init__.py new file mode 100644 index 000000000000..128f0d66195c --- /dev/null +++ b/deepspeed/ops/lamb/__init__.py @@ -0,0 +1 @@ +from deepspeed.ops.lamb.fused_lamb import FusedLamb diff --git a/deepspeed/pt/deepspeed_fused_lamb.py b/deepspeed/ops/lamb/fused_lamb.py similarity index 89% rename from deepspeed/pt/deepspeed_fused_lamb.py rename to deepspeed/ops/lamb/fused_lamb.py index 387421ffe9b8..8117cdc7b0d0 100644 --- a/deepspeed/pt/deepspeed_fused_lamb.py +++ b/deepspeed/ops/lamb/fused_lamb.py @@ -3,46 +3,37 @@ Copyright NVIDIA/apex This file is adapted from NVIDIA/apex/optimizer/fused_adam and implements the LAMB optimizer - ''' import types -import torch import importlib +import torch class FusedLamb(torch.optim.Optimizer): - """Implements LAMB algorithm. Currently GPU-only. Requires DeepSpeed adapted Apex to be installed via - ``python setup.py install --cuda_ext --cpp_ext``. + """Implements the LAMB algorithm. Currently GPU-only. - For usage example please see, TODO DeepSpeed Tutorial - - It has been proposed in `Large Batch Optimization for Deep Learning: Training BERT in 76 minutes. + LAMB was proposed in `Large Batch Optimization for Deep Learning: Training BERT in 76 minutes. https://arxiv.org/abs/1904.00962 - Arguments: params (iterable): iterable of parameters to optimize or dicts defining parameter groups. lr (float, optional): learning rate. (default: 1e-3) + bias_correction (bool, optional): bias correction (default: True) betas (Tuple[float, float], optional): coefficients used for computing running averages of gradient and its square. (default: (0.9, 0.999)) eps (float, optional): term added to the denominator to improve numerical stability. (default: 1e-8) - weight_decay (float, optional): weight decay (L2 penalty) (default: 0) - max_coeff(float, optional): maximum value of the lamb coefficient (default: 10.0) - min_coeff(float, optional): minimum value of the lamb coefficient (default: 0.01) - amsgrad (boolean, optional): whether to use the AMSGrad variant of this - algorithm from the paper `On the Convergence of Adam and Beyond`_ - (default: False) NOT SUPPORTED in FusedAdam! eps_inside_sqrt (boolean, optional): in the 'update parameters' step, adds eps to the bias-corrected second moment estimate before evaluating square root instead of adding it to the square root of second moment estimate as in the original paper. (default: False) - - .. _Adam\: A Method for Stochastic Optimization: - https://arxiv.org/abs/1412.6980 - .. _On the Convergence of Adam and Beyond: - https://openreview.net/forum?id=ryQu7f-RZ + weight_decay (float, optional): weight decay (L2 penalty) (default: 0) + max_grad_norm (float, optional): value used to clip global grad norm + (default: 0.0) + max_coeff(float, optional): maximum value of the lamb coefficient (default: 10.0) + min_coeff(float, optional): minimum value of the lamb coefficient (default: 0.01) + amsgrad (boolean, optional): NOT SUPPORTED in FusedLamb! """ def __init__(self, params, @@ -58,7 +49,14 @@ def __init__(self, min_coeff=0.01, amsgrad=False): global fused_lamb_cuda - fused_lamb_cuda = importlib.import_module("deepspeed_lamb_cuda") + try: + fused_lamb_cuda = importlib.import_module( + "deepspeed.ops.lamb.fused_lamb_cuda") + except ImportError as err: + print( + "Unable to import Lamb cuda extension, please build DeepSpeed with cuda/cpp extensions." + ) + raise err if amsgrad: raise RuntimeError('FusedLamb does not support the AMSGrad variant.') @@ -153,9 +151,7 @@ def step(self, if grad is None: grad = p.grad.data if grad.is_sparse: - raise RuntimeError( - 'FusedAdam does not support sparse gradients, please consider SparseAdam instead' - ) + raise RuntimeError('FusedLamb does not support sparse gradients') state = self.state[p] diff --git a/deepspeed/pt/sparse_transformer/__init__.py b/deepspeed/ops/sparse_transformer/__init__.py similarity index 100% rename from deepspeed/pt/sparse_transformer/__init__.py rename to deepspeed/ops/sparse_transformer/__init__.py diff --git a/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py b/deepspeed/ops/sparse_transformer/bert_sparse_self_attention.py similarity index 95% rename from deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py rename to deepspeed/ops/sparse_transformer/bert_sparse_self_attention.py index 0370798eeaf5..3c9e07a14b1b 100755 --- a/deepspeed/pt/sparse_transformer/bert_sparse_self_attention.py +++ b/deepspeed/ops/sparse_transformer/bert_sparse_self_attention.py @@ -3,7 +3,7 @@ """ from torch import nn -from deepspeed.pt.sparse_transformer import SparseSelfAttention, FixedSparsityConfig +from deepspeed.ops.sparse_transformer import SparseSelfAttention, FixedSparsityConfig class BertSparseSelfAttention(nn.Module): diff --git a/deepspeed/pt/sparse_transformer/matmul.py b/deepspeed/ops/sparse_transformer/matmul.py similarity index 99% rename from deepspeed/pt/sparse_transformer/matmul.py rename to deepspeed/ops/sparse_transformer/matmul.py index 1b4c57928f3f..76ad0eca3bcf 100644 --- a/deepspeed/pt/sparse_transformer/matmul.py +++ b/deepspeed/ops/sparse_transformer/matmul.py @@ -1,11 +1,10 @@ # DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 # https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py - +import importlib import triton import torch import math -import deepspeed_sparse_transformer_util -from deepspeed.trsrc import matmul +from deepspeed.ops.sparse_transformer.trsrc import matmul ############## @@ -80,7 +79,8 @@ def get_locks(size, dev): ########################## # SPARSE = DENSE x DENSE # ########################## - sdd_segment = deepspeed_sparse_transformer_util.sdd_segment + cpp_util = importlib.import_module('deepspeed.ops.sparse_transformer.cpp_util') + sdd_segment = cpp_util.sdd_segment @staticmethod def make_sdd_lut(layout, block, dtype, device): diff --git a/deepspeed/pt/sparse_transformer/softmax.py b/deepspeed/ops/sparse_transformer/softmax.py similarity index 99% rename from deepspeed/pt/sparse_transformer/softmax.py rename to deepspeed/ops/sparse_transformer/softmax.py index 0c00a9b216d7..e722ae699180 100644 --- a/deepspeed/pt/sparse_transformer/softmax.py +++ b/deepspeed/ops/sparse_transformer/softmax.py @@ -4,7 +4,7 @@ import triton import torch import math -from deepspeed.trsrc import softmax_fwd, softmax_bwd +from deepspeed.ops.sparse_transformer.trsrc import softmax_fwd, softmax_bwd fwd_kernels = dict() bwd_kernels = dict() diff --git a/deepspeed/pt/sparse_transformer/sparse_self_attention.py b/deepspeed/ops/sparse_transformer/sparse_self_attention.py similarity index 98% rename from deepspeed/pt/sparse_transformer/sparse_self_attention.py rename to deepspeed/ops/sparse_transformer/sparse_self_attention.py index b14069caadbb..2fa29e3df2d3 100644 --- a/deepspeed/pt/sparse_transformer/sparse_self_attention.py +++ b/deepspeed/ops/sparse_transformer/sparse_self_attention.py @@ -6,7 +6,7 @@ from torch.nn.functional import * import torch from collections import namedtuple -from deepspeed.pt.sparse_transformer import MatMul, Softmax, SparsityConfig +from deepspeed.ops.sparse_transformer import MatMul, Softmax, SparsityConfig import sys diff --git a/deepspeed/pt/sparse_transformer/sparsity_config.py b/deepspeed/ops/sparse_transformer/sparsity_config.py similarity index 100% rename from deepspeed/pt/sparse_transformer/sparsity_config.py rename to deepspeed/ops/sparse_transformer/sparsity_config.py diff --git a/deepspeed/trsrc/__init__.py b/deepspeed/ops/sparse_transformer/trsrc/__init__.py similarity index 88% rename from deepspeed/trsrc/__init__.py rename to deepspeed/ops/sparse_transformer/trsrc/__init__.py index bc80704f6b57..765d34f574a2 100644 --- a/deepspeed/trsrc/__init__.py +++ b/deepspeed/ops/sparse_transformer/trsrc/__init__.py @@ -26,8 +26,7 @@ def _build_file_index(directory, suffix='.tr'): # Go over all local source files and parse them as strings _module = sys.modules[_build_file_index.__module__] -_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), - 'sparse_transformer') +_directory = os.path.dirname(os.path.realpath(__file__)) for name, fname in _build_file_index(_directory): with open(fname, 'r') as fin: setattr(_module, name, fin.read()) diff --git a/deepspeed/trsrc/sparse_transformer/matmul.tr b/deepspeed/ops/sparse_transformer/trsrc/matmul.tr similarity index 100% rename from deepspeed/trsrc/sparse_transformer/matmul.tr rename to deepspeed/ops/sparse_transformer/trsrc/matmul.tr diff --git a/deepspeed/trsrc/sparse_transformer/softmax_bwd.tr b/deepspeed/ops/sparse_transformer/trsrc/softmax_bwd.tr similarity index 100% rename from deepspeed/trsrc/sparse_transformer/softmax_bwd.tr rename to deepspeed/ops/sparse_transformer/trsrc/softmax_bwd.tr diff --git a/deepspeed/trsrc/sparse_transformer/softmax_fwd.tr b/deepspeed/ops/sparse_transformer/trsrc/softmax_fwd.tr similarity index 100% rename from deepspeed/trsrc/sparse_transformer/softmax_fwd.tr rename to deepspeed/ops/sparse_transformer/trsrc/softmax_fwd.tr diff --git a/deepspeed/pt/sparse_transformer/utils.py b/deepspeed/ops/sparse_transformer/utils.py similarity index 99% rename from deepspeed/pt/sparse_transformer/utils.py rename to deepspeed/ops/sparse_transformer/utils.py index 50bee1ea0407..4d704354ac70 100644 --- a/deepspeed/pt/sparse_transformer/utils.py +++ b/deepspeed/ops/sparse_transformer/utils.py @@ -4,7 +4,7 @@ from torch import nn from torch.nn import functional as F -from deepspeed.pt.sparse_transformer import BertSparseSelfAttention, SparsityConfig +from deepspeed.ops.sparse_transformer import BertSparseSelfAttention, SparsityConfig ''' This file contains few utility functions to handle adapting pretrained model with sparse self-attention module. ''' diff --git a/deepspeed/ops/transformer/__init__.py b/deepspeed/ops/transformer/__init__.py new file mode 100644 index 000000000000..4a056762beac --- /dev/null +++ b/deepspeed/ops/transformer/__init__.py @@ -0,0 +1 @@ +from deepspeed.ops.transformer.transformer import DeepSpeedTransformerLayer, DeepSpeedTransformerConfig diff --git a/deepspeed/pt/deepspeed_cuda.py b/deepspeed/ops/transformer/transformer.py old mode 100755 new mode 100644 similarity index 94% rename from deepspeed/pt/deepspeed_cuda.py rename to deepspeed/ops/transformer/transformer.py index 3b86f06cc383..54ed407c6ddb --- a/deepspeed/pt/deepspeed_cuda.py +++ b/deepspeed/ops/transformer/transformer.py @@ -1,10 +1,16 @@ -from torch import nn -from torch.autograd import Function -import torch +''' +Copyright 2020 The Microsoft DeepSpeed Team +''' import json import math -import deepspeed_transformer_cuda as ds_transformer_cuda -import deepspeed_stochastic_transformer_cuda as ds_stochastic_transformer_cuda +import importlib +import torch +from torch import nn +from torch.autograd import Function + +# Cuda modules will be imported if needed +transformer_cuda_module = None +stochastic_transformer_cuda_module = None class TransformerConfig(): @@ -159,7 +165,7 @@ def forward(ctx, if bsz > config.batch_size: raise ValueError('Input batch size exceeds the limit.') - cuda_module = ds_stochastic_transformer_cuda if config.stochastic_mode else ds_transformer_cuda + cuda_module = stochastic_transformer_cuda_module if config.stochastic_mode else transformer_cuda_module forward_func = cuda_module.forward_fp16 if config.fp16 else cuda_module.forward_fp32 (output, @@ -321,7 +327,7 @@ def backward(ctx, grad_output): norm_w, norm_b) = ctx.saved_tensors - cuda_module = ds_stochastic_transformer_cuda if ctx.config.stochastic_mode else ds_transformer_cuda + cuda_module = stochastic_transformer_cuda_module if ctx.config.stochastic_mode else transformer_cuda_module backward_func = cuda_module.backward_fp16 if ctx.config.fp16 else cuda_module.backward_fp32 (grad_input, @@ -457,8 +463,22 @@ def __init__(self, layer_id, config, initial_weights=None, initial_biases=None): self.norm_w = initial_weights[7] self.norm_b = initial_biases[7] + # Import cuda modules if needed + global transformer_cuda_module, stochastic_transformer_cuda_module + if transformer_cuda_module is None or stochastic_transformer_cuda_module is None: + try: + transformer_cuda_module = importlib.import_module( + "deepspeed.ops.transformer.transformer_cuda") + stochastic_transformer_cuda_module = importlib.import_module( + "deepspeed.ops.transformer.stochastic_transformer_cuda") + except ImportError as err: + print( + "Unable to import transformer cuda extension, please build DeepSpeed with cuda/cpp extensions." + ) + raise err + # create the layer in cuda kernels. - cuda_module = ds_stochastic_transformer_cuda if self.config.stochastic_mode else ds_transformer_cuda + cuda_module = stochastic_transformer_cuda_module if self.config.stochastic_mode else transformer_cuda_module create_layer_func = cuda_module.create_transformer_layer_fp16 if self.config.fp16 else cuda_module.create_transformer_layer_fp32 create_layer_func(self.config.layer_id, diff --git a/deepspeed/runtime/__init__.py b/deepspeed/runtime/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/deepspeed/runtime/activation_checkpointing/__init__.py b/deepspeed/runtime/activation_checkpointing/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/deepspeed/pt/deepspeed_checkpointing.py b/deepspeed/runtime/activation_checkpointing/checkpointing.py similarity index 96% rename from deepspeed/pt/deepspeed_checkpointing.py rename to deepspeed/runtime/activation_checkpointing/checkpointing.py index 2a5bb2ab688b..7c63f4a62767 100755 --- a/deepspeed/pt/deepspeed_checkpointing.py +++ b/deepspeed/runtime/activation_checkpointing/checkpointing.py @@ -13,16 +13,17 @@ # Parts of the code here are adapted from PyTorch # repo: https://github.com/pytorch/pytorch -import contextlib import copy -import torch.distributed as dist import torch +import contextlib +import torch.distributed as dist + from torch import _C from torch.cuda import _lazy_call, device as device_ctx_manager -from deepspeed.pt.deepspeed_timer import SynchronizedWallClockTimer as Timers -import torch.distributed as dist -from deepspeed.pt.deepspeed_config import DeepSpeedConfig -from deepspeed.pt.log_utils import logger + +from deepspeed.runtime.config import DeepSpeedConfig +from deepspeed.utils import logger +from deepspeed.utils.timer import SynchronizedWallClockTimer as Timers #DeepSpeed Checkpointing Enabled or Disabled deepspeed_checkpointing_enabled = False diff --git a/deepspeed/pt/deepspeed_checkpointing_config.py b/deepspeed/runtime/activation_checkpointing/config.py similarity index 95% rename from deepspeed/pt/deepspeed_checkpointing_config.py rename to deepspeed/runtime/activation_checkpointing/config.py index 63e2b29f702a..30ac5157f843 100755 --- a/deepspeed/pt/deepspeed_checkpointing_config.py +++ b/deepspeed/runtime/activation_checkpointing/config.py @@ -3,7 +3,7 @@ Licensed under the MIT license. """ -from deepspeed.pt.deepspeed_config_utils import get_scalar_param +from deepspeed.runtime.config_utils import get_scalar_param ######################################### # DeepSpeed Activation Checkpointing diff --git a/deepspeed/pt/deepspeed_config.py b/deepspeed/runtime/config.py similarity index 95% rename from deepspeed/pt/deepspeed_config.py rename to deepspeed/runtime/config.py index 748adc66bb26..eeb5fffd7ef9 100755 --- a/deepspeed/pt/deepspeed_config.py +++ b/deepspeed/runtime/config.py @@ -6,12 +6,12 @@ import torch import json import copy -from deepspeed.pt.deepspeed_constants import * -from deepspeed.pt.loss_scaler import INITIAL_LOSS_SCALE, SCALE_WINDOW, DELAYED_SHIFT, MIN_LOSS_SCALE -from deepspeed.pt.deepspeed_config_utils import get_scalar_param, dict_raise_error_on_duplicate_keys -from deepspeed.pt.deepspeed_zero_config import DeepSpeedZeroConfig -from deepspeed.pt.deepspeed_checkpointing_config import DeepSpeedActivationCheckpointingConfig -from deepspeed.pt.log_utils import logger +from deepspeed.runtime.constants import * +from deepspeed.runtime.fp16.loss_scaler import INITIAL_LOSS_SCALE, SCALE_WINDOW, DELAYED_SHIFT, MIN_LOSS_SCALE +from deepspeed.runtime.config_utils import get_scalar_param, dict_raise_error_on_duplicate_keys +from deepspeed.runtime.zero.config import DeepSpeedZeroConfig +from deepspeed.runtime.activation_checkpointing.config import DeepSpeedActivationCheckpointingConfig +from deepspeed.utils import logger TENSOR_CORE_ALIGN_SIZE = 8 ADAM_OPTIMIZER = 'adam' diff --git a/deepspeed/pt/deepspeed_config_utils.py b/deepspeed/runtime/config_utils.py similarity index 100% rename from deepspeed/pt/deepspeed_config_utils.py rename to deepspeed/runtime/config_utils.py diff --git a/deepspeed/pt/deepspeed_constants.py b/deepspeed/runtime/constants.py similarity index 100% rename from deepspeed/pt/deepspeed_constants.py rename to deepspeed/runtime/constants.py diff --git a/deepspeed/pt/deepspeed_csr_tensor.py b/deepspeed/runtime/csr_tensor.py similarity index 100% rename from deepspeed/pt/deepspeed_csr_tensor.py rename to deepspeed/runtime/csr_tensor.py diff --git a/deepspeed/pt/deepspeed_dataloader.py b/deepspeed/runtime/dataloader.py similarity index 100% rename from deepspeed/pt/deepspeed_dataloader.py rename to deepspeed/runtime/dataloader.py diff --git a/deepspeed/pt/deepspeed_light.py b/deepspeed/runtime/engine.py similarity index 98% rename from deepspeed/pt/deepspeed_light.py rename to deepspeed/runtime/engine.py index c6e7623b1792..a0c9b8dda62f 100755 --- a/deepspeed/pt/deepspeed_light.py +++ b/deepspeed/runtime/engine.py @@ -2,36 +2,35 @@ Copyright 2019 The Microsoft DeepSpeed Team ''' -import torch import os +import torch import warnings import torch.distributed as dist + +from apex import amp from torch.nn.modules import Module from torch.distributed.distributed_c10d import _get_global_rank -from apex import amp - from tensorboardX import SummaryWriter -from deepspeed.pt.deepspeed_timer import ThroughputTimer, SynchronizedWallClockTimer -from deepspeed.pt.deepspeed_zero_optimizer import FP16_DeepSpeedZeroOptimizer -from deepspeed.pt.zero_optimizer_stage1 import FP16_DeepSpeedZeroOptimizer_Stage1 -from deepspeed.pt.log_utils import logger -import deepspeed.pt.deepspeed_checkpointing as deepspeed_activation_checkpointing - -from deepspeed.pt.fp16_optimizer import FP16_Optimizer -from deepspeed.pt.fp16_unfused_optimizer import FP16_UnfusedOptimizer -from deepspeed.pt.deepspeed_fused_lamb import FusedLamb -from deepspeed.pt.deepspeed_config import DeepSpeedConfig, \ +from deepspeed.runtime.zero.stage2 import FP16_DeepSpeedZeroOptimizer +from deepspeed.runtime.zero.stage1 import FP16_DeepSpeedZeroOptimizer_Stage1 +from deepspeed.runtime.activation_checkpointing import checkpointing as activation_checkpointing +from deepspeed.runtime.fp16.fused_optimizer import FP16_Optimizer +from deepspeed.runtime.fp16.unfused_optimizer import FP16_UnfusedOptimizer +from deepspeed.runtime.config import DeepSpeedConfig, \ ADAM_OPTIMIZER, LAMB_OPTIMIZER, DEEPSPEED_OPTIMIZERS - -from deepspeed.pt.deepspeed_dataloader import DeepSpeedDataLoader -from deepspeed.pt.deepspeed_constants import \ +from deepspeed.runtime.dataloader import DeepSpeedDataLoader +from deepspeed.runtime.constants import \ ROUTE_TRAIN, ROUTE_PREDICT, ROUTE_EVAL, \ TORCH_DISTRIBUTED_DEFAULT_PORT, \ ZERO_OPTIMIZATION_OPTIMIZER_STATES, ZERO_OPTIMIZATION_GRADIENTS +from deepspeed.runtime.csr_tensor import CSRTensor +import deepspeed.runtime.lr_schedules as lr_schedules + +from deepspeed.ops.lamb import FusedLamb -import deepspeed.pt.deepspeed_lr_schedules as lr_schedules -from deepspeed.pt.deepspeed_csr_tensor import CSRTensor +from deepspeed.utils import logger +from deepspeed.utils.timer import ThroughputTimer, SynchronizedWallClockTimer MEMORY_OPT_ALLREDUCE_SIZE = 500000000 SUMMARY_WRITER_DIR_NAME = "JobId" @@ -92,7 +91,7 @@ def print_configuration(args, name): logger.info(' {} {} {}'.format(arg, dots, getattr(args, arg))) -class DeepSpeedLight(Module): +class DeepSpeedEngine(Module): r"""DeepSpeed engine for training. """ def __init__(self, @@ -106,7 +105,7 @@ def __init__(self, dist_init_required=None, collate_fn=None, config_params=None): - super(DeepSpeedLight, self).__init__() + super(DeepSpeedEngine, self).__init__() self.client_optimizer = optimizer self.client_model_parameters = model_parameters diff --git a/deepspeed/runtime/fp16/__init__.py b/deepspeed/runtime/fp16/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/deepspeed/pt/fp16_optimizer.py b/deepspeed/runtime/fp16/fused_optimizer.py similarity index 98% rename from deepspeed/pt/fp16_optimizer.py rename to deepspeed/runtime/fp16/fused_optimizer.py index a03c3738a4db..3c5f66b21fb5 100755 --- a/deepspeed/pt/fp16_optimizer.py +++ b/deepspeed/runtime/fp16/fused_optimizer.py @@ -9,9 +9,9 @@ import math from torch._utils import _flatten_dense_tensors, _unflatten_dense_tensors -from deepspeed.pt.deepspeed_utils import get_grad_norm, CheckOverflow, get_weight_norm -from deepspeed.pt.loss_scaler import INITIAL_LOSS_SCALE, SCALE_WINDOW, MIN_LOSS_SCALE -from deepspeed.pt.log_utils import logger +from deepspeed.runtime.utils import get_grad_norm, CheckOverflow, get_weight_norm +from deepspeed.runtime.fp16.loss_scaler import INITIAL_LOSS_SCALE, SCALE_WINDOW, MIN_LOSS_SCALE +from deepspeed.utils import logger class FP16_Optimizer(object): diff --git a/deepspeed/pt/loss_scaler.py b/deepspeed/runtime/fp16/loss_scaler.py similarity index 100% rename from deepspeed/pt/loss_scaler.py rename to deepspeed/runtime/fp16/loss_scaler.py diff --git a/deepspeed/pt/fp16_unfused_optimizer.py b/deepspeed/runtime/fp16/unfused_optimizer.py similarity index 98% rename from deepspeed/pt/fp16_unfused_optimizer.py rename to deepspeed/runtime/fp16/unfused_optimizer.py index c21e92a6c5db..7775924625ad 100755 --- a/deepspeed/pt/fp16_unfused_optimizer.py +++ b/deepspeed/runtime/fp16/unfused_optimizer.py @@ -9,9 +9,9 @@ from torch._utils import _flatten_dense_tensors, _unflatten_dense_tensors import math -from deepspeed.pt.deepspeed_utils import get_grad_norm, CheckOverflow, get_weight_norm -from deepspeed.pt.loss_scaler import INITIAL_LOSS_SCALE, SCALE_WINDOW, MIN_LOSS_SCALE -from deepspeed.pt.log_utils import logger +from deepspeed.runtime.utils import get_grad_norm, CheckOverflow, get_weight_norm +from deepspeed.runtime.fp16.loss_scaler import INITIAL_LOSS_SCALE, SCALE_WINDOW, MIN_LOSS_SCALE +from deepspeed.utils import logger class FP16_UnfusedOptimizer(object): diff --git a/deepspeed/pt/deepspeed_lr_schedules.py b/deepspeed/runtime/lr_schedules.py similarity index 99% rename from deepspeed/pt/deepspeed_lr_schedules.py rename to deepspeed/runtime/lr_schedules.py index 996d41ae9088..76c4582fcc1f 100755 --- a/deepspeed/pt/deepspeed_lr_schedules.py +++ b/deepspeed/runtime/lr_schedules.py @@ -12,8 +12,8 @@ from torch.optim import Optimizer from typing import Union, List import math -from deepspeed.pt.deepspeed_constants import * -from deepspeed.pt.log_utils import logger +from deepspeed.runtime.constants import * +from deepspeed.utils import logger LR_SCHEDULE = 'lr_schedule' LR_RANGE_TEST = 'LRRangeTest' diff --git a/deepspeed/pt/deepspeed_utils.py b/deepspeed/runtime/utils.py similarity index 99% rename from deepspeed/pt/deepspeed_utils.py rename to deepspeed/runtime/utils.py index cb90a92c3c91..d9d0781aa4fe 100755 --- a/deepspeed/pt/deepspeed_utils.py +++ b/deepspeed/runtime/utils.py @@ -9,7 +9,7 @@ import torch from torch._six import inf -from deepspeed.pt.log_utils import logger +from deepspeed.utils import logger class CheckOverflow(object): diff --git a/deepspeed/runtime/zero/__init__.py b/deepspeed/runtime/zero/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/deepspeed/pt/deepspeed_zero_config.py b/deepspeed/runtime/zero/config.py similarity index 94% rename from deepspeed/pt/deepspeed_zero_config.py rename to deepspeed/runtime/zero/config.py index 4f654d3b8c30..3ad10a811fe1 100755 --- a/deepspeed/pt/deepspeed_zero_config.py +++ b/deepspeed/runtime/zero/config.py @@ -3,9 +3,8 @@ Licensed under the MIT license. """ -#from deepspeed.pt.deepspeed_constants import * -from deepspeed.pt.deepspeed_config_utils import get_scalar_param -from deepspeed.pt.log_utils import logger +from deepspeed.runtime.config_utils import get_scalar_param +from deepspeed.utils import logger ######################################### # ZeRO optimization diff --git a/deepspeed/pt/zero_optimizer_stage1.py b/deepspeed/runtime/zero/stage1.py similarity index 99% rename from deepspeed/pt/zero_optimizer_stage1.py rename to deepspeed/runtime/zero/stage1.py index 82812bccdb3a..1acef4898e36 100755 --- a/deepspeed/pt/zero_optimizer_stage1.py +++ b/deepspeed/runtime/zero/stage1.py @@ -4,11 +4,11 @@ from torch._utils import _flatten_dense_tensors, _unflatten_dense_tensors from collections import defaultdict -from deepspeed.pt.zero_utils import _initialize_parameter_parallel_groups -from deepspeed.pt.log_utils import log_dist, logger -from deepspeed.pt.loss_scaler import LossScaler, DynamicLossScaler -from deepspeed.pt.deepspeed_utils import get_grad_norm, CheckOverflow -from deepspeed.pt.deepspeed_zero_config import ZERO_OPTIMIZATION_OPTIMIZER_STATES +from deepspeed.runtime.zero.utils import _initialize_parameter_parallel_groups +from deepspeed.runtime.fp16.loss_scaler import LossScaler, DynamicLossScaler +from deepspeed.runtime.utils import get_grad_norm, CheckOverflow +from deepspeed.runtime.zero.config import ZERO_OPTIMIZATION_OPTIMIZER_STATES +from deepspeed.utils import logger, log_dist def get_alignment_padding(flattened_lean_size, sub_partition_id, sub_partition_size): diff --git a/deepspeed/pt/deepspeed_zero_optimizer.py b/deepspeed/runtime/zero/stage2.py similarity index 97% rename from deepspeed/pt/deepspeed_zero_optimizer.py rename to deepspeed/runtime/zero/stage2.py index cbfb249b501d..c131cb692ce8 100755 --- a/deepspeed/pt/deepspeed_zero_optimizer.py +++ b/deepspeed/runtime/zero/stage2.py @@ -10,16 +10,15 @@ from torch._six import inf from torch.autograd import Variable -from deepspeed.pt.loss_scaler import LossScaler, DynamicLossScaler -from deepspeed.pt.deepspeed_utils import see_memory_usage, is_model_parallel_parameter -from deepspeed.pt.deepspeed_zero_config import ZERO_OPTIMIZATION_GRADIENTS +from deepspeed.runtime.fp16.loss_scaler import LossScaler, DynamicLossScaler +from deepspeed.runtime.utils import see_memory_usage, is_model_parallel_parameter +from deepspeed.runtime.zero.config import ZERO_OPTIMIZATION_GRADIENTS +from deepspeed.utils import logger #Toggle this to true to enable correctness test #with gradient partitioning and without pg_correctness_test = False -from deepspeed.pt.log_utils import logger - try: from apex_C import flatten from apex_C import unflatten diff --git a/deepspeed/pt/zero_utils.py b/deepspeed/runtime/zero/utils.py similarity index 95% rename from deepspeed/pt/zero_utils.py rename to deepspeed/runtime/zero/utils.py index e125f82d9b39..86d1930a9223 100644 --- a/deepspeed/pt/zero_utils.py +++ b/deepspeed/runtime/zero/utils.py @@ -1,7 +1,7 @@ import torch import torch.distributed as dist -from deepspeed.pt.log_utils import logger +from deepspeed.utils import logger def _initialize_parameter_parallel_groups(parameter_parallel_size=None): diff --git a/deepspeed/utils/__init__.py b/deepspeed/utils/__init__.py new file mode 100644 index 000000000000..ed95832b8fd1 --- /dev/null +++ b/deepspeed/utils/__init__.py @@ -0,0 +1 @@ +from deepspeed.utils.logging import logger, log_dist diff --git a/deepspeed/pt/log_utils.py b/deepspeed/utils/logging.py similarity index 100% rename from deepspeed/pt/log_utils.py rename to deepspeed/utils/logging.py diff --git a/deepspeed/pt/deepspeed_timer.py b/deepspeed/utils/timer.py similarity index 99% rename from deepspeed/pt/deepspeed_timer.py rename to deepspeed/utils/timer.py index f78330d60179..cd572a04eb5b 100755 --- a/deepspeed/pt/deepspeed_timer.py +++ b/deepspeed/utils/timer.py @@ -6,7 +6,7 @@ import psutil import torch -from deepspeed.pt.log_utils import logger +from deepspeed.utils import logger def print_rank_0(message): diff --git a/install.sh b/install.sh index 433bcd8b0b07..6acedda5e5f7 100755 --- a/install.sh +++ b/install.sh @@ -205,7 +205,8 @@ if [ "$local_only" == "1" ]; then echo "Installing deepspeed" $PIP_SUDO pip uninstall -y deepspeed $PIP_SUDO $PIP_INSTALL dist/deepspeed*.whl - python basic_install_test.py + # -I to exclude local directory files + python -I basic_install_test.py if [ $? == 0 ]; then echo "Installation is successful" else diff --git a/setup.py b/setup.py index d17b3ff4c57e..8b7da5a2ba8a 100755 --- a/setup.py +++ b/setup.py @@ -40,9 +40,12 @@ version_ge_1_5 = ['-DVERSION_GE_1_5'] version_dependent_macros = version_ge_1_1 + version_ge_1_3 + version_ge_1_5 -ext_modules = [ +ext_modules = [] + +## Lamb ## +ext_modules.append( CUDAExtension( - name='deepspeed_lamb_cuda', + name='deepspeed.ops.lamb.fused_lamb_cuda', sources=['csrc/lamb/fused_lamb_cuda.cpp', 'csrc/lamb/fused_lamb_cuda_kernel.cu'], include_dirs=['csrc/includes'], @@ -52,8 +55,11 @@ ] + version_dependent_macros, 'nvcc': ['-O3', '--use_fast_math'] + version_dependent_macros - }), - CUDAExtension(name='deepspeed_transformer_cuda', + })) + +## Transformer ## +ext_modules.append( + CUDAExtension(name='deepspeed.ops.transformer.transformer_cuda', sources=[ 'csrc/transformer/ds_transformer_cuda.cpp', 'csrc/transformer/cublas_wrappers.cu', @@ -82,8 +88,9 @@ '-U__CUDA_NO_HALF_CONVERSIONS__', '-U__CUDA_NO_HALF2_OPERATORS__' ] - }), - CUDAExtension(name='deepspeed_stochastic_transformer_cuda', + })) +ext_modules.append( + CUDAExtension(name='deepspeed.ops.transformer.stochastic_transformer_cuda', sources=[ 'csrc/transformer/ds_transformer_cuda.cpp', 'csrc/transformer/cublas_wrappers.cu', @@ -113,15 +120,17 @@ '-U__CUDA_NO_HALF2_OPERATORS__', '-D__STOCHASTIC_MODE__' ] - }), - CppExtension(name='deepspeed_sparse_transformer_util', + })) + +## Sparse transformer ## +ext_modules.append( + CppExtension(name='deepspeed.ops.sparse_transformer.cpp_util', sources=['csrc/sparse_transformer/utils.cpp'], extra_compile_args={'cxx': ['-O2', - '-fopenmp']}) -] + '-fopenmp']})) setup(name='deepspeed', - version='0.2.0', + version='0.3.0', description='DeepSpeed library', author='DeepSpeed Team', author_email='deepspeed@microsoft.com', @@ -129,7 +138,7 @@ packages=find_packages(exclude=["docker", "third_party", "csrc"]), - package_data={'': ['trsrc/sparse_transformer/*.tr']}, + package_data={'deepspeed.ops.sparse_transformer.trsrc': ['*.tr']}, scripts=['bin/deepspeed', 'bin/deepspeed.pt', 'bin/ds', diff --git a/tests/unit/test_checkpointing.py b/tests/unit/test_checkpointing.py index d80bd897ee1a..ac2aee4ead69 100755 --- a/tests/unit/test_checkpointing.py +++ b/tests/unit/test_checkpointing.py @@ -1,10 +1,10 @@ import torch import deepspeed -from deepspeed.pt.deepspeed_zero_optimizer import FP16_DeepSpeedZeroOptimizer -from deepspeed.pt.zero_optimizer_stage1 import FP16_DeepSpeedZeroOptimizer_Stage1 +from deepspeed.runtime.zero.stage2 import FP16_DeepSpeedZeroOptimizer +from deepspeed.runtime.zero.stage1 import FP16_DeepSpeedZeroOptimizer_Stage1 -from deepspeed.pt.fp16_optimizer import FP16_Optimizer -from deepspeed.pt.fp16_unfused_optimizer import FP16_UnfusedOptimizer +from deepspeed.runtime.fp16.fused_optimizer import FP16_Optimizer +from deepspeed.runtime.fp16.unfused_optimizer import FP16_UnfusedOptimizer import argparse import pytest diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 297658f71e6e..e5fe75b281e0 100755 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -9,7 +9,7 @@ # A test on its own import deepspeed -from deepspeed.pt.deepspeed_config import DeepSpeedConfig +from deepspeed.runtime.config import DeepSpeedConfig def test_cuda(): diff --git a/tests/unit/test_csr.py b/tests/unit/test_csr.py index 06b43cdeacb9..766be7fb7470 100644 --- a/tests/unit/test_csr.py +++ b/tests/unit/test_csr.py @@ -1,6 +1,6 @@ import torch import random -from deepspeed.pt.deepspeed_csr_tensor import CSRTensor +from deepspeed.runtime.csr_tensor import CSRTensor def test_csr_addition_self(): diff --git a/tests/unit/test_ds_config.py b/tests/unit/test_ds_config.py index 9f19fd226326..728a46bbbb1b 100755 --- a/tests/unit/test_ds_config.py +++ b/tests/unit/test_ds_config.py @@ -1,7 +1,7 @@ import pytest import os import json -from deepspeed.pt import deepspeed_config as ds_config +from deepspeed.runtime import config as ds_config def test_only_required_fields(tmpdir): diff --git a/tests/unit/test_run.py b/tests/unit/test_run.py index 4329e7a885bd..ed069c335fe6 100644 --- a/tests/unit/test_run.py +++ b/tests/unit/test_run.py @@ -1,6 +1,6 @@ import pytest -from deepspeed.pt import deepspeed_run as dsrun +from deepspeed.launcher import runner as dsrun def test_parser_mutual_exclusive(): diff --git a/tests/unit/test_sparse_transformer.py b/tests/unit/test_sparse_transformer.py index e3aeca438ab9..e847d54d7796 100755 --- a/tests/unit/test_sparse_transformer.py +++ b/tests/unit/test_sparse_transformer.py @@ -9,7 +9,7 @@ def test_sparse_transformer_module_availability(): try: - from deepspeed.pt import sparse_transformer + from deepspeed.ops import sparse_transformer except ImportError: print("Sparse Transformer Module is not installed!") return False @@ -18,7 +18,7 @@ def test_sparse_transformer_module_availability(): def test_matmul_module_availability(): try: - from deepspeed.pt.sparse_transformer import MatMul + from deepspeed.ops.sparse_transformer import MatMul except ImportError: print("Sparse Transformer MatMul Module is not installed!") return False @@ -27,7 +27,7 @@ def test_matmul_module_availability(): def test_softmax_module_availability(): try: - from deepspeed.pt.sparse_transformer import Softmax + from deepspeed.ops.sparse_transformer import Softmax except ImportError: print("Sparse Transformer Softmax Module is not installed!") return False @@ -36,7 +36,7 @@ def test_softmax_module_availability(): def test_sparsityconfig_module_availability(): try: - from deepspeed.pt.sparse_transformer import SparsityConfig + from deepspeed.ops.sparse_transformer import SparsityConfig except ImportError: print("SparsityConfig Module is not installed!") return False @@ -45,7 +45,7 @@ def test_sparsityconfig_module_availability(): def test_densesparsityconfig_module_availability(): try: - from deepspeed.pt.sparse_transformer import DenseSparsityConfig + from deepspeed.ops.sparse_transformer import DenseSparsityConfig except ImportError: print("DenseSparsityConfig Module is not installed!") return False @@ -54,7 +54,7 @@ def test_densesparsityconfig_module_availability(): def test_fixedsparsityconfig_module_availability(): try: - from deepspeed.pt.sparse_transformer import FixedSparsityConfig + from deepspeed.ops.sparse_transformer import FixedSparsityConfig except ImportError: print("FixedSparsityConfig Module is not installed!") return False @@ -63,7 +63,7 @@ def test_fixedsparsityconfig_module_availability(): def test_variablesparsityconfig_module_availability(): try: - from deepspeed.pt.sparse_transformer import VariableSparsityConfig + from deepspeed.ops.sparse_transformer import VariableSparsityConfig except ImportError: print("VariableSparsityConfig Module is not installed!") return False @@ -72,7 +72,7 @@ def test_variablesparsityconfig_module_availability(): def test_bigbirdsparsityconfig_module_availability(): try: - from deepspeed.pt.sparse_transformer import BigBirdSparsityConfig + from deepspeed.ops.sparse_transformer import BigBirdSparsityConfig except ImportError: print("BigBirdSparsityConfig Module is not installed!") return False @@ -81,7 +81,7 @@ def test_bigbirdsparsityconfig_module_availability(): def test_bslongformersparsityconfig_module_availability(): try: - from deepspeed.pt.sparse_transformer import BSLongformerSparsityConfig + from deepspeed.ops.sparse_transformer import BSLongformerSparsityConfig except ImportError: print("BSLongformerSparsityConfig Module is not installed!") return False @@ -90,7 +90,7 @@ def test_bslongformersparsityconfig_module_availability(): def test_sparseselfattention_module_availability(): try: - from deepspeed.pt.sparse_transformer import SparseSelfAttention + from deepspeed.ops.sparse_transformer import SparseSelfAttention except ImportError: print("SparseSelfAttention Module is not installed!") return False @@ -99,7 +99,7 @@ def test_sparseselfattention_module_availability(): def test_bertsparseselfattention_module_availability(): try: - from deepspeed.pt.sparse_transformer import BertSparseSelfAttention + from deepspeed.ops.sparse_transformer import BertSparseSelfAttention except ImportError: print("BertSparseSelfAttention Module is not installed!") return False @@ -108,7 +108,7 @@ def test_bertsparseselfattention_module_availability(): def test_extend_position_embedding_module_availability(): try: - from deepspeed.pt.sparse_transformer import extend_position_embedding + from deepspeed.ops.sparse_transformer import extend_position_embedding except ImportError: print("Sparse Transformer extend_position_embedding Module is not installed!") return False @@ -117,7 +117,7 @@ def test_extend_position_embedding_module_availability(): def test_update_tokenizer_model_max_length_module_availability(): try: - from deepspeed.pt.sparse_transformer import update_tokenizer_model_max_length + from deepspeed.ops.sparse_transformer import update_tokenizer_model_max_length except ImportError: print( "Sparse Transformer update_tokenizer_model_max_length Module is not installed!" @@ -128,7 +128,7 @@ def test_update_tokenizer_model_max_length_module_availability(): def test_replace_model_self_attention_with_sparse_self_attention_module_availability(): try: - from deepspeed.pt.sparse_transformer import replace_model_self_attention_with_sparse_self_attention + from deepspeed.ops.sparse_transformer import replace_model_self_attention_with_sparse_self_attention except ImportError: print( "Sparse Transformer replace_model_self_attention_with_sparse_self_attention Module is not installed!" @@ -140,7 +140,7 @@ def test_replace_model_self_attention_with_sparse_self_attention_module_availabi def test_replace_self_attention_layer_with_sparse_self_attention_layer_module_availability( ): try: - from deepspeed.pt.sparse_transformer import replace_self_attention_layer_with_sparse_self_attention_layer + from deepspeed.ops.sparse_transformer import replace_self_attention_layer_with_sparse_self_attention_layer except ImportError: print( "Sparse Transformer replace_self_attention_layer_with_sparse_self_attention_layer Module is not installed!" @@ -151,7 +151,7 @@ def test_replace_self_attention_layer_with_sparse_self_attention_layer_module_av def test_pad_to_block_size_module_availability(): try: - from deepspeed.pt.sparse_transformer import pad_to_block_size + from deepspeed.ops.sparse_transformer import pad_to_block_size except ImportError: print("Sparse Transformer pad_to_block_size Module is not installed!") return False @@ -160,7 +160,7 @@ def test_pad_to_block_size_module_availability(): def test_unpad_sequence_output_module_availability(): try: - from deepspeed.pt.sparse_transformer import unpad_sequence_output + from deepspeed.ops.sparse_transformer import unpad_sequence_output except ImportError: print("Sparse Transformer unpad_sequence_output Module is not installed!") return False @@ -224,7 +224,7 @@ def run_softmax_reference(x, scale, dx, kp_mask, attn_mask, layout, block): def run_softmax_st(x, scale, dx, kp_mask, attn_mask, layout, block): - from deepspeed.pt.sparse_transformer import Softmax + from deepspeed.ops.sparse_transformer import Softmax sparse_softmax = Softmax(layout, block, bench=False) dx = dense_to_sparse(dx, layout, block) x = dense_to_sparse(x, layout, block) @@ -274,12 +274,21 @@ def init_softmax_inputs(Z, H, M, N, scale, rho, block, dtype, dense_x=True, layo return layout, x, dx, bool_attn_mask, fp_attn_mask, kp_mask -@pytest.mark.skipif(torch.cuda.get_device_capability()[0] < 7, - reason="needs minimum compute capability 7; v100") +def _skip_on_cuda_compatability(): + if torch.cuda.get_device_capability()[0] != 7: + pytest.skip("needs compute capability 7; v100") + cuda_major = int(torch.version.cuda.split('.')[0]) * 10 + cuda_minor = int(torch.version.cuda.split('.')[1]) + cuda_version = cuda_major + cuda_minor + if cuda_version != 101 and cuda_version != 102: + pytest.skip("requires cuda 10.1 or 10.2") + + @pytest.mark.parametrize("block", [16, 32]) @pytest.mark.parametrize("width", [256, 576]) @pytest.mark.parametrize("dtype", [torch.float16, torch.float32]) def test_softmax(block, width, dtype): + _skip_on_cuda_compatability() Z = 2 H = 4 scale = 0.4 @@ -313,7 +322,7 @@ def run_matmul_reference(x, w, mode, trans_a, trans_b, layout, block, dy): def run_matmul_st(x, w, mode, trans_a, trans_b, layout, block, dy): - from deepspeed.pt.sparse_transformer import MatMul + from deepspeed.ops.sparse_transformer import MatMul x = dense_to_sparse(x, layout, block) if mode == 'dsd' else x w = dense_to_sparse(w, layout, block) if mode == 'dds' else w dy = dense_to_sparse(dy, layout, block) if mode == 'sdd' else dy @@ -359,10 +368,9 @@ def init_matmul_inputs(Z, H, M, N, K, rho, mode, trans_a, trans_b, block, dtype, ] -@pytest.mark.skipif(torch.cuda.get_device_capability()[0] < 7, - reason="needs minimum compute capability 7; v100") @pytest.mark.parametrize("block, dtype, mode, trans_a, trans_b", testdata) def test_matmul(block, dtype, mode, trans_a, trans_b): + _skip_on_cuda_compatability() Z = 3 H = 2 M = 128 From 57f51aa4382c22484652e80dab24290ea09b3872 Mon Sep 17 00:00:00 2001 From: Jeff Rasley Date: Fri, 28 Aug 2020 09:49:18 -0700 Subject: [PATCH 11/16] Update ds --- bin/ds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/ds b/bin/ds index 47efea32da34..6bb47da8ce7c 100755 --- a/bin/ds +++ b/bin/ds @@ -1,6 +1,6 @@ #!/usr/bin/env python -from deepspeed.pt.deepspeed_run import main +from deepspeed.launcher.runner import main if __name__ == '__main__': main() From c45d99a14963d91b3da1b7c8d994dbea50e8eaa1 Mon Sep 17 00:00:00 2001 From: Jeff Rasley Date: Fri, 28 Aug 2020 10:23:48 -0700 Subject: [PATCH 12/16] Update runner.py --- deepspeed/launcher/runner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deepspeed/launcher/runner.py b/deepspeed/launcher/runner.py index 920af79b460f..565083aa7feb 100755 --- a/deepspeed/launcher/runner.py +++ b/deepspeed/launcher/runner.py @@ -285,7 +285,7 @@ def main(args=None): sys.executable, "-u", "-m", - "deepspeed.runtime.launch", + "deepspeed.launcher.launch", "--world_info={}".format(world_info_base64), "--master_addr={}".format(args.master_addr), "--master_port={}".format(args.master_port) @@ -328,7 +328,7 @@ def main(args=None): sys.executable, "-u", "-m", - "deepspeed.runtime.launch", + "deepspeed.launcher.launch", '--world_info={}'.format(world_info_base64), "--node_rank=%n", "--master_addr={}".format(args.master_addr), From e3b01cc3fe89476091ffe990f7b477cf050a50bb Mon Sep 17 00:00:00 2001 From: Arash Ashari Date: Fri, 28 Aug 2020 13:36:02 -0700 Subject: [PATCH 13/16] Updated code based on name change from "sparse transformer" to "sparse attention" (#76) * sparse attention name change * updated config, setup, and tests --- .../utils.cpp | 5 +- .../__init__.py | 2 +- .../bert_sparse_self_attention.py | 2 +- .../matmul.py | 8 +- .../softmax.py | 4 +- .../sparse_attention_utils.py | 225 ++++++++++++++++++ .../sparse_self_attention.py | 2 +- .../sparsity_config.py | 0 .../trsrc/__init__.py | 0 .../trsrc/matmul.tr | 2 +- .../trsrc/softmax_bwd.tr | 2 +- .../trsrc/softmax_fwd.tr | 2 +- deepspeed/ops/sparse_transformer/utils.py | 215 ----------------- deepspeed/runtime/config.py | 14 +- deepspeed/runtime/constants.py | 4 +- setup.py | 6 +- ...ransformer.py => test_sparse_attention.py} | 97 +++----- 17 files changed, 278 insertions(+), 312 deletions(-) rename csrc/{sparse_transformer => sparse_attention}/utils.cpp (93%) rename deepspeed/ops/{sparse_transformer => sparse_attention}/__init__.py (58%) rename deepspeed/ops/{sparse_transformer => sparse_attention}/bert_sparse_self_attention.py (95%) rename deepspeed/ops/{sparse_transformer => sparse_attention}/matmul.py (99%) rename deepspeed/ops/{sparse_transformer => sparse_attention}/softmax.py (98%) create mode 100644 deepspeed/ops/sparse_attention/sparse_attention_utils.py rename deepspeed/ops/{sparse_transformer => sparse_attention}/sparse_self_attention.py (98%) rename deepspeed/ops/{sparse_transformer => sparse_attention}/sparsity_config.py (100%) rename deepspeed/ops/{sparse_transformer => sparse_attention}/trsrc/__init__.py (100%) rename deepspeed/ops/{sparse_transformer => sparse_attention}/trsrc/matmul.tr (98%) rename deepspeed/ops/{sparse_transformer => sparse_attention}/trsrc/softmax_bwd.tr (94%) rename deepspeed/ops/{sparse_transformer => sparse_attention}/trsrc/softmax_fwd.tr (97%) delete mode 100644 deepspeed/ops/sparse_transformer/utils.py rename tests/unit/{test_sparse_transformer.py => test_sparse_attention.py} (75%) diff --git a/csrc/sparse_transformer/utils.cpp b/csrc/sparse_attention/utils.cpp similarity index 93% rename from csrc/sparse_transformer/utils.cpp rename to csrc/sparse_attention/utils.cpp index 425b0e6b698b..a802025e92ed 100644 --- a/csrc/sparse_transformer/utils.cpp +++ b/csrc/sparse_attention/utils.cpp @@ -1,6 +1,5 @@ -// DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 -// https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py -// https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/attention.py +// DeepSpeed note, code taken & adapted from commit 9aa94789f13ada713af36cfd8cca2fc9a7f6b79a +// https://github.com/ptillet/torch-blocksparse/blob/master/csrc/utils.cpp #include #include diff --git a/deepspeed/ops/sparse_transformer/__init__.py b/deepspeed/ops/sparse_attention/__init__.py similarity index 58% rename from deepspeed/ops/sparse_transformer/__init__.py rename to deepspeed/ops/sparse_attention/__init__.py index 9872f73ced5d..604ab29a8d6b 100644 --- a/deepspeed/ops/sparse_transformer/__init__.py +++ b/deepspeed/ops/sparse_attention/__init__.py @@ -3,4 +3,4 @@ from .matmul import MatMul from .sparse_self_attention import SparseSelfAttention from .bert_sparse_self_attention import BertSparseSelfAttention -from .utils import extend_position_embedding, update_tokenizer_model_max_length, replace_model_self_attention_with_sparse_self_attention, replace_self_attention_layer_with_sparse_self_attention_layer, pad_to_block_size, unpad_sequence_output +from .sparse_attention_utils import SparseAttentionUtils diff --git a/deepspeed/ops/sparse_transformer/bert_sparse_self_attention.py b/deepspeed/ops/sparse_attention/bert_sparse_self_attention.py similarity index 95% rename from deepspeed/ops/sparse_transformer/bert_sparse_self_attention.py rename to deepspeed/ops/sparse_attention/bert_sparse_self_attention.py index 3c9e07a14b1b..40dc697e11b1 100755 --- a/deepspeed/ops/sparse_transformer/bert_sparse_self_attention.py +++ b/deepspeed/ops/sparse_attention/bert_sparse_self_attention.py @@ -3,7 +3,7 @@ """ from torch import nn -from deepspeed.ops.sparse_transformer import SparseSelfAttention, FixedSparsityConfig +from deepspeed.ops.sparse_attention import SparseSelfAttention, FixedSparsityConfig class BertSparseSelfAttention(nn.Module): diff --git a/deepspeed/ops/sparse_transformer/matmul.py b/deepspeed/ops/sparse_attention/matmul.py similarity index 99% rename from deepspeed/ops/sparse_transformer/matmul.py rename to deepspeed/ops/sparse_attention/matmul.py index 76ad0eca3bcf..db4ce1399594 100644 --- a/deepspeed/ops/sparse_transformer/matmul.py +++ b/deepspeed/ops/sparse_attention/matmul.py @@ -1,10 +1,10 @@ -# DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +# DeepSpeed note, code taken & adapted from commit 9aa94789f13ada713af36cfd8cca2fc9a7f6b79a # https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py import importlib import triton import torch import math -from deepspeed.ops.sparse_transformer.trsrc import matmul +from deepspeed.ops.sparse_attention.trsrc import matmul ############## @@ -79,8 +79,8 @@ def get_locks(size, dev): ########################## # SPARSE = DENSE x DENSE # ########################## - cpp_util = importlib.import_module('deepspeed.ops.sparse_transformer.cpp_util') - sdd_segment = cpp_util.sdd_segment + cpp_utils = importlib.import_module('deepspeed.ops.sparse_attention.cpp_utils') + sdd_segment = cpp_utils.sdd_segment @staticmethod def make_sdd_lut(layout, block, dtype, device): diff --git a/deepspeed/ops/sparse_transformer/softmax.py b/deepspeed/ops/sparse_attention/softmax.py similarity index 98% rename from deepspeed/ops/sparse_transformer/softmax.py rename to deepspeed/ops/sparse_attention/softmax.py index e722ae699180..b722fb32a2d8 100644 --- a/deepspeed/ops/sparse_transformer/softmax.py +++ b/deepspeed/ops/sparse_attention/softmax.py @@ -1,10 +1,10 @@ -# DeepSpeed note, code taken & adapted from commit beddcc3eda6d3df1b34f74c2e10139e4317d0e7f +# DeepSpeed note, code taken & adapted from commit 9aa94789f13ada713af36cfd8cca2fc9a7f6b79a # https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py import triton import torch import math -from deepspeed.ops.sparse_transformer.trsrc import softmax_fwd, softmax_bwd +from deepspeed.ops.sparse_attention.trsrc import softmax_fwd, softmax_bwd fwd_kernels = dict() bwd_kernels = dict() diff --git a/deepspeed/ops/sparse_attention/sparse_attention_utils.py b/deepspeed/ops/sparse_attention/sparse_attention_utils.py new file mode 100644 index 000000000000..32999f62323f --- /dev/null +++ b/deepspeed/ops/sparse_attention/sparse_attention_utils.py @@ -0,0 +1,225 @@ +""" +Copyright 2020 The Microsoft DeepSpeed Team +""" + +from torch import nn +from torch.nn import functional as F +from deepspeed.ops.sparse_attention import BertSparseSelfAttention, SparsityConfig +''' +This file contains few utility functions to handle adapting pretrained model with sparse self-attention module. +''' + + +class SparseAttentionUtils: + """This class provides some utility functions that are use integrating sparse attention into transformer models. + Such utilities include extending position embeddings, replacing current self-attention layer with sparse attention, padding sequences to multiple of block size, etc. + + """ + @staticmethod + def extend_position_embedding(model, max_position): + """This function extends the position embedding weights of a model loaded from a checkpoint. + It assumes the new max position is bigger than the original max length. + + Arguments: + model: required: a transformer model + max_position: required: an integer determining new position embedding size + Return: + model: updated model; in which position embedding weights have been extended based on new size + """ + + if hasattr(model, 'bert'): + original_max_position = model.bert.embeddings.position_embeddings.weight.size( + 0) + assert max_position > original_max_position + extend_multiples = max(1, max_position // original_max_position) + model.bert.embeddings.position_embeddings.weight.data = model.bert.embeddings.position_embeddings.weight.repeat( + extend_multiples, + 1) + elif hasattr(model, 'roberta'): + # RoBERTa has positions 0 & 1 reserved, so embedding size is max position + 2 + original_max_position, embed_size = model.roberta.embeddings.position_embeddings.weight.shape + original_max_position -= 2 + extend_multiples = max(1, max_position // original_max_position) + assert max_position > original_max_position + max_position += 2 + extended_position_embedding = model.roberta.embeddings.position_embeddings.weight.new_empty( + max_position, + embed_size) + k = 2 + for i in range(extend_multiples): + extended_position_embedding[k:( + k + original_max_position + )] = model.roberta.embeddings.position_embeddings.weight[2:] + k += original_max_position + model.roberta.embeddings.position_embeddings.weight.data = extended_position_embedding + else: + raise ValueError( + 'Please extend \"extend_position_embedding\" function to support your model type. It currently only supports \"bert\" & \"roberta\"!' + ) + + model.config.max_position_embeddings = max_position + print( + f'Extended position embeddings to {original_max_position * extend_multiples}' + ) + + return model + + @staticmethod + def update_tokenizer_model_max_length(tokenizer, max_position): + """This function updates the position embedding length of a tokenizer to a new max position. + + Arguments: + tokenizer: required: a transformer tokenizer + max_position: required: an integer determining new position embedding size + Return: + tokenizer: updated tokenizer; in which model maximum length has been extended based on new size + """ + + tokenizer.model_max_length = max_position + tokenizer.init_kwargs['model_max_length'] = max_position + print(f'updated tokenizer model max imum length to {max_position}') + + return tokenizer + + @staticmethod + def replace_model_self_attention_with_sparse_self_attention( + model, + max_position, + # SparsityConfig parameters needs to be set accordingly + sparsity_config=SparsityConfig(num_heads=4)): + """This function replaces the self attention layers in model encoder with sparse self attention. + It currently supports bert and roberta model and can be easily extended to any other models following similar steps here. + For sparsityConfig, refer to the config class. + + Arguments: + model: required: a transformer model + max_position: required: an integer determining new position embedding size + sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on SparsityConfig class + + Return: + model: updated model; in which self attention layer has been repleaced with DeepSpeed Sparse Self Attention layer. + """ + + if hasattr(model, 'bert'): + model.config.max_position_embeddings = max_position + replace_self_attention_layer_with_sparse_self_attention_layer( + model.config, + model.bert.encoder.layer, + sparsity_config) + elif hasattr(model, 'roberta'): + model.config.max_position_embeddings = max_position + 2 + replace_self_attention_layer_with_sparse_self_attention_layer( + model.config, + model.roberta.encoder.layer, + sparsity_config) + else: + raise ValueError( + 'Please extend \"update_model_self_attention_to_sparse_self_attention\" function to support \ + your model type. It currently only supports \"bert\" & \"roberta\"!' + ) + return model + + @staticmethod + def replace_self_attention_layer_with_sparse_self_attention_layer( + config, + layers, + # SparsityConfig parameters needs to be set accordingly + sparsity_config=SparsityConfig(num_heads=4)): + """This function replaces the self attention layers in attention layer with sparse self attention. + For sparsityConfig, refer to the config class. + + Arguments: + config: required: transformer model config + layers: required: transformer model attention layers + sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on SparsityConfig class + + Return: + layers: updated attention layers; in which self attention layers have been repleaced with DeepSpeed Sparse Self Attention layer. + """ + + for layer in layers: + deepspeed_sparse_self_attn = BertSparseSelfAttention(config, sparsity_config) + deepspeed_sparse_self_attn.query = layer.attention.self.query + deepspeed_sparse_self_attn.key = layer.attention.self.key + deepspeed_sparse_self_attn.value = layer.attention.self.value + + layer.attention.self = deepspeed_sparse_self_attn + + return layers + + @staticmethod + def pad_to_block_size(block_size, + input_ids, + attention_mask, + token_type_ids, + position_ids, + inputs_embeds, + pad_token_id, + model_mbeddings): + """This function pads input tokens and attention mask on sequence length dimension to be multiple of block size. + This is a requirement for Sparse Transformer in which the self attention layer works on sequences of length multiple of block size. + It needs to be called in your model, such as BertModel, right before you calculate the embedding outputs. + Note) + 1- instead of passing your embedding layer to this function, you can simply add this function to your model. It can be more simplified if given attention_mask and/or token_type_ids are none. + 2- you need to call unpdad function before returning your model output to unpad the encoder sequence output. + + Arguments: + block_size: required: an integer determining the block size of sparsity config. + pad_token_id: required: an integer determining the pad token from the model config; such as bert.config.pad_token_id. + input_ids: a torch.LongTensor of shape [batch_size, sequence_length] with the word token indices in the vocabulary + attention_mask: a torch.LongTensor of shape [batch_size, sequence_length] with indices selected in [0, 1]. It's a mask to be used if the input sequence length is smaller than the max input sequence length in the current batch. It's the mask that we typically use for attention when a batch has varying length sentences. + token_type_ids: a torch.LongTensor of shape [batch_size, sequence_length] with the token types indices selected in [0, 1]. Type 0 corresponds to a `sentence A` and type 1 corresponds to a `sentence B` token (see BERT paper for more details). + position_ids: a torch.LongTensor of shape [batch_size, sequence_length] with the indices of positions of each input sequence tokens in the position embeddings. + inputs_embeds: an optional torch.FloatTensor of shape [batch_size, sequence_length, hidden_size] that contains embedded representation and can be passed instead of input_ids directly. + model_embeddings: an optional object. If inputs_embeds are not none, this will be your model embeddings such as BertEmbeddings from your model such as BertModel. You can move this function inside your model and use self.embeddings instead of passing this parameter. + + Return: + pad_len: an integer determining how much inputs have been padded to transfer sequence length dimension to multiple of block size. + input_ids: if input_ids are not none padded input_ids otherwise none. + attention_mask: if attention_mask is not none padded attention_mask otherwise none. + token_type_ids: if token_type_ids are not none padded token_type_ids otherwise none. + position_ids: if position_ids are not none padded position_ids otherwise none. + inputs_embeds: if inputs_embeds are not none padded inputs_embeds otherwise none. + """ + + batch_size, seq_len = input_ids.shape if input_ids is not None else inputs_embeds.shape[:-1] + + pad_len = (block_size - seq_len % block_size) % block_size + if pad_len > 0: + if inputs_embeds is not None: + pad_input_ids = inputs_embeds.new_full((batch_size, + pad_len), + pad_token_id, + dtype=torch.long) + pad_inputs_embeds = model_embeddings(pad_input_ids) + inputs_embeds = torch.cat([inputs_embeds, pad_inputs_embeds], dim=-2) + # may not be needed as input_ids are not used if inputs_embeds are given + if input_ids is not None: + input_ids = F.pad(input_ids, (0, pad_len), value=pad_token_id) + if position_ids is not None: + # pad position_id with pad_token_id + position_ids = F.pad(position_ids, (0, pad_len), value=pad_token_id) + # pad attention mask without attention on the padding tokens + attention_mask = F.pad(attention_mask, (0, pad_len), value=False) + # pad token_type_ids with token_type_id = 0 + token_type_ids = F.pad(token_type_ids, (0, pad_len), value=0) + + return pad_len, input_ids, attention_mask, token_type_ids, position_ids, inputs_embeds + + @staticmethod + def unpad_sequence_output(pad_len, sequence_output): + """This function unpads sequence output if inputs of the model were padded. + This is a requirement for Sparse Transformer in which the self attention layer works on sequences of length multiple of block size. + It needs to be called in your model, such as BertModel, right before you return the model outputs. + + Arguments: + pad_len: required: an integer determining how much model inputs have been padded to transfer sequence length dimension to multiple of block size. + sequence_output: required: sequence output of the encoder layer. + + Return: + sequence_output: unpaded sequence output of the encoder layer. + """ + + if (pad_len > 0): + sequence_output = sequence_output[:, :-pad_len] + return sequence_output diff --git a/deepspeed/ops/sparse_transformer/sparse_self_attention.py b/deepspeed/ops/sparse_attention/sparse_self_attention.py similarity index 98% rename from deepspeed/ops/sparse_transformer/sparse_self_attention.py rename to deepspeed/ops/sparse_attention/sparse_self_attention.py index 2fa29e3df2d3..2e3156049e94 100644 --- a/deepspeed/ops/sparse_transformer/sparse_self_attention.py +++ b/deepspeed/ops/sparse_attention/sparse_self_attention.py @@ -6,7 +6,7 @@ from torch.nn.functional import * import torch from collections import namedtuple -from deepspeed.ops.sparse_transformer import MatMul, Softmax, SparsityConfig +from deepspeed.ops.sparse_attention import MatMul, Softmax, SparsityConfig import sys diff --git a/deepspeed/ops/sparse_transformer/sparsity_config.py b/deepspeed/ops/sparse_attention/sparsity_config.py similarity index 100% rename from deepspeed/ops/sparse_transformer/sparsity_config.py rename to deepspeed/ops/sparse_attention/sparsity_config.py diff --git a/deepspeed/ops/sparse_transformer/trsrc/__init__.py b/deepspeed/ops/sparse_attention/trsrc/__init__.py similarity index 100% rename from deepspeed/ops/sparse_transformer/trsrc/__init__.py rename to deepspeed/ops/sparse_attention/trsrc/__init__.py diff --git a/deepspeed/ops/sparse_transformer/trsrc/matmul.tr b/deepspeed/ops/sparse_attention/trsrc/matmul.tr similarity index 98% rename from deepspeed/ops/sparse_transformer/trsrc/matmul.tr rename to deepspeed/ops/sparse_attention/trsrc/matmul.tr index 61cd2a4299eb..bf87e993feda 100644 --- a/deepspeed/ops/sparse_transformer/trsrc/matmul.tr +++ b/deepspeed/ops/sparse_attention/trsrc/matmul.tr @@ -1,4 +1,4 @@ -// DeepSpeed note, code taken & adapted from commit c368a9fd1b2c9dee4cc94de9a6bb0be3d447be41 +// DeepSpeed note, code taken & adapted from commit 9aa94789f13ada713af36cfd8cca2fc9a7f6b79a // https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py __global__ void NAME (TYPE* A __readonly __noalias __aligned(16), diff --git a/deepspeed/ops/sparse_transformer/trsrc/softmax_bwd.tr b/deepspeed/ops/sparse_attention/trsrc/softmax_bwd.tr similarity index 94% rename from deepspeed/ops/sparse_transformer/trsrc/softmax_bwd.tr rename to deepspeed/ops/sparse_attention/trsrc/softmax_bwd.tr index c87973973422..25d15a99e468 100644 --- a/deepspeed/ops/sparse_transformer/trsrc/softmax_bwd.tr +++ b/deepspeed/ops/sparse_attention/trsrc/softmax_bwd.tr @@ -1,4 +1,4 @@ -// DeepSpeed note, code taken & adapted from commit beddcc3eda6d3df1b34f74c2e10139e4317d0e7f +// DeepSpeed note, code taken & adapted from commit 9aa94789f13ada713af36cfd8cca2fc9a7f6b79a // https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/softmax.py __global__ void softmax_bwd(TYPE * X __readonly __noalias __aligned(16), diff --git a/deepspeed/ops/sparse_transformer/trsrc/softmax_fwd.tr b/deepspeed/ops/sparse_attention/trsrc/softmax_fwd.tr similarity index 97% rename from deepspeed/ops/sparse_transformer/trsrc/softmax_fwd.tr rename to deepspeed/ops/sparse_attention/trsrc/softmax_fwd.tr index 7a3415a9ed62..7d5cc50b282d 100644 --- a/deepspeed/ops/sparse_transformer/trsrc/softmax_fwd.tr +++ b/deepspeed/ops/sparse_attention/trsrc/softmax_fwd.tr @@ -1,4 +1,4 @@ -// DeepSpeed note, code taken & adapted from commit beddcc3eda6d3df1b34f74c2e10139e4317d0e7f +// DeepSpeed note, code taken & adapted from commit 9aa94789f13ada713af36cfd8cca2fc9a7f6b79a // https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/softmax.py __global__ void softmax_fwd(TYPE *X __readonly __noalias __aligned(16), diff --git a/deepspeed/ops/sparse_transformer/utils.py b/deepspeed/ops/sparse_transformer/utils.py deleted file mode 100644 index 4d704354ac70..000000000000 --- a/deepspeed/ops/sparse_transformer/utils.py +++ /dev/null @@ -1,215 +0,0 @@ -""" -Copyright 2020 The Microsoft DeepSpeed Team -""" - -from torch import nn -from torch.nn import functional as F -from deepspeed.ops.sparse_transformer import BertSparseSelfAttention, SparsityConfig -''' -This file contains few utility functions to handle adapting pretrained model with sparse self-attention module. -''' - - -def extend_position_embedding(model, max_position): - """This function extends the position embedding weights of a model loaded from a checkpoint. - It assumes the new max position is bigger than the original max length. - - Arguments: - model: required: a transformer model - max_position: required: an integer determining new position embedding size - Return: - model: updated model; in which position embedding weights have been extended based on new size - """ - - if hasattr(model, 'bert'): - original_max_position = model.bert.embeddings.position_embeddings.weight.size(0) - assert max_position > original_max_position - extend_multiples = max(1, max_position // original_max_position) - model.bert.embeddings.position_embeddings.weight.data = model.bert.embeddings.position_embeddings.weight.repeat( - extend_multiples, - 1) - elif hasattr(model, 'roberta'): - # RoBERTa has positions 0 & 1 reserved, so embedding size is max position + 2 - original_max_position, embed_size = model.roberta.embeddings.position_embeddings.weight.shape - original_max_position -= 2 - extend_multiples = max(1, max_position // original_max_position) - assert max_position > original_max_position - max_position += 2 - extended_position_embedding = model.roberta.embeddings.position_embeddings.weight.new_empty( - max_position, - embed_size) - k = 2 - for i in range(extend_multiples): - extended_position_embedding[k:( - k + original_max_position - )] = model.roberta.embeddings.position_embeddings.weight[2:] - k += original_max_position - model.roberta.embeddings.position_embeddings.weight.data = extended_position_embedding - else: - raise ValueError( - 'Please extend \"extend_position_embedding\" function to support your model type. It currently only supports \"bert\" & \"roberta\"!' - ) - - model.config.max_position_embeddings = max_position - print(f'Extended position embeddings to {original_max_position * extend_multiples}') - - return model - - -def update_tokenizer_model_max_length(tokenizer, max_position): - """This function updates the position embedding length of a tokenizer to a new max position. - - Arguments: - tokenizer: required: a transformer tokenizer - max_position: required: an integer determining new position embedding size - Return: - tokenizer: updated tokenizer; in which model maximum length has been extended based on new size - """ - - tokenizer.model_max_length = max_position - tokenizer.init_kwargs['model_max_length'] = max_position - print(f'updated tokenizer model max imum length to {max_position}') - - return tokenizer - - -def replace_model_self_attention_with_sparse_self_attention( - model, - max_position, - # SparsityConfig parameters needs to be set accordingly - sparsity_config=SparsityConfig(num_heads=4)): - """This function replaces the self attention layers in model encoder with sparse self attention. - It currently supports bert and roberta model and can be easily extended to any other models following similar steps here. - For sparsityConfig, refer to the config class. - - Arguments: - model: required: a transformer model - max_position: required: an integer determining new position embedding size - sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on SparsityConfig class - - Return: - model: updated model; in which self attention layer has been repleaced with DeepSpeed Sparse Self Attention layer. - """ - - if hasattr(model, 'bert'): - model.config.max_position_embeddings = max_position - replace_self_attention_layer_with_sparse_self_attention_layer( - model.config, - model.bert.encoder.layer, - sparsity_config) - elif hasattr(model, 'roberta'): - model.config.max_position_embeddings = max_position + 2 - replace_self_attention_layer_with_sparse_self_attention_layer( - model.config, - model.roberta.encoder.layer, - sparsity_config) - else: - raise ValueError( - 'Please extend \"update_model_self_attention_to_sparse_self_attention\" function to support \ - your model type. It currently only supports \"bert\" & \"roberta\"!') - return model - - -def replace_self_attention_layer_with_sparse_self_attention_layer( - config, - layers, - # SparsityConfig parameters needs to be set accordingly - sparsity_config=SparsityConfig(num_heads=4)): - """This function replaces the self attention layers in attention layer with sparse self attention. - For sparsityConfig, refer to the config class. - - Arguments: - config: required: transformer model config - layers: required: transformer model attention layers - sparsity_config: optional: this parameter determins sparsity pattern configuration; it is based on SparsityConfig class - - Return: - layers: updated attention layers; in which self attention layers have been repleaced with DeepSpeed Sparse Self Attention layer. - """ - - for layer in layers: - deepspeed_sparse_self_attn = BertSparseSelfAttention(config, sparsity_config) - deepspeed_sparse_self_attn.query = layer.attention.self.query - deepspeed_sparse_self_attn.key = layer.attention.self.key - deepspeed_sparse_self_attn.value = layer.attention.self.value - - layer.attention.self = deepspeed_sparse_self_attn - - return layers - - -def pad_to_block_size(block_size, - input_ids, - attention_mask, - token_type_ids, - position_ids, - inputs_embeds, - pad_token_id, - model_mbeddings): - """This function pads input tokens and attention mask on sequence length dimension to be multiple of block size. - This is a requirement for Sparse Transformer in which the self attention layer works on sequences of length multiple of block size. - It needs to be called in your model, such as BertModel, right before you calculate the embedding outputs. - Note) - 1- instead of passing your embedding layer to this function, you can simply add this function to your model. It can be more simplified if given attention_mask and/or token_type_ids are none. - 2- you need to call unpdad function before returning your model output to unpad the encoder sequence output. - - Arguments: - block_size: required: an integer determining the block size of sparsity config. - pad_token_id: required: an integer determining the pad token from the model config; such as bert.config.pad_token_id. - input_ids: a torch.LongTensor of shape [batch_size, sequence_length] with the word token indices in the vocabulary - attention_mask: a torch.LongTensor of shape [batch_size, sequence_length] with indices selected in [0, 1]. It's a mask to be used if the input sequence length is smaller than the max input sequence length in the current batch. It's the mask that we typically use for attention when a batch has varying length sentences. - token_type_ids: a torch.LongTensor of shape [batch_size, sequence_length] with the token types indices selected in [0, 1]. Type 0 corresponds to a `sentence A` and type 1 corresponds to a `sentence B` token (see BERT paper for more details). - position_ids: a torch.LongTensor of shape [batch_size, sequence_length] with the indices of positions of each input sequence tokens in the position embeddings. - inputs_embeds: an optional torch.FloatTensor of shape [batch_size, sequence_length, hidden_size] that contains embedded representation and can be passed instead of input_ids directly. - model_embeddings: an optional object. If inputs_embeds are not none, this will be your model embeddings such as BertEmbeddings from your model such as BertModel. You can move this function inside your model and use self.embeddings instead of passing this parameter. - - Return: - pad_len: an integer determining how much inputs have been padded to transfer sequence length dimension to multiple of block size. - input_ids: if input_ids are not none padded input_ids otherwise none. - attention_mask: if attention_mask is not none padded attention_mask otherwise none. - token_type_ids: if token_type_ids are not none padded token_type_ids otherwise none. - position_ids: if position_ids are not none padded position_ids otherwise none. - inputs_embeds: if inputs_embeds are not none padded inputs_embeds otherwise none. - """ - - batch_size, seq_len = input_ids.shape if input_ids is not None else inputs_embeds.shape[:-1] - - pad_len = (block_size - seq_len % block_size) % block_size - if pad_len > 0: - if inputs_embeds is not None: - pad_input_ids = inputs_embeds.new_full((batch_size, - pad_len), - pad_token_id, - dtype=torch.long) - pad_inputs_embeds = model_embeddings(pad_input_ids) - inputs_embeds = torch.cat([inputs_embeds, pad_inputs_embeds], dim=-2) - # may not be needed as input_ids are not used if inputs_embeds are given - if input_ids is not None: - input_ids = F.pad(input_ids, (0, pad_len), value=pad_token_id) - if position_ids is not None: - # pad position_id with pad_token_id - position_ids = F.pad(position_ids, (0, pad_len), value=pad_token_id) - # pad attention mask without attention on the padding tokens - attention_mask = F.pad(attention_mask, (0, pad_len), value=False) - # pad token_type_ids with token_type_id = 0 - token_type_ids = F.pad(token_type_ids, (0, pad_len), value=0) - - return pad_len, input_ids, attention_mask, token_type_ids, position_ids, inputs_embeds - - -def unpad_sequence_output(pad_len, sequence_output): - """This function unpads sequence output if inputs of the model were padded. - This is a requirement for Sparse Transformer in which the self attention layer works on sequences of length multiple of block size. - It needs to be called in your model, such as BertModel, right before you return the model outputs. - - Arguments: - pad_len: required: an integer determining how much model inputs have been padded to transfer sequence length dimension to multiple of block size. - sequence_output: required: sequence output of the encoder layer. - - Return: - sequence_output: unpaded sequence output of the encoder layer. - """ - - if (pad_len > 0): - sequence_output = sequence_output[:, :-pad_len] - return sequence_output diff --git a/deepspeed/runtime/config.py b/deepspeed/runtime/config.py index eeb5fffd7ef9..78e9eaaf1b3f 100755 --- a/deepspeed/runtime/config.py +++ b/deepspeed/runtime/config.py @@ -158,10 +158,10 @@ def get_gradient_clipping(param_dict): return get_scalar_param(param_dict, GRADIENT_CLIPPING, GRADIENT_CLIPPING_DEFAULT) -def get_sparse_self_attention(param_dict): - if SPARSE_SELF_ATTENTION in param_dict.keys(): - sparsity = param_dict[SPARSE_SELF_ATTENTION] - mode = get_sparse_self_attention_mode(sparsity) +def get_sparse_attention(param_dict): + if SPARSE_ATTENTION in param_dict.keys(): + sparsity = param_dict[SPARSE_ATTENTION] + mode = get_sparse_attention_mode(sparsity) if (mode == SPARSE_DENSE_MODE): return get_sparse_dense_config(sparsity) @@ -315,14 +315,14 @@ def get_sparse_bslongformer_config(sparsity): } -def get_sparse_self_attention_mode(param_dict): +def get_sparse_attention_mode(param_dict): if SPARSE_MODE in param_dict.keys(): return param_dict[SPARSE_MODE] else: return SPARSE_MODE_DEFAULT -def get_sparse_self_attention_type(param_dict): +def get_sparse_attention_type(param_dict): if SPARSE_ATTENTION_TYPE in param_dict.keys(): return param_dict[SPARSE_ATTENTION_TYPE] else: @@ -529,7 +529,7 @@ def _initialize_params(self, param_dict): self.tensorboard_output_path = get_tensorboard_output_path(param_dict) self.tensorboard_job_name = get_tensorboard_job_name(param_dict) - self.sparse_self_attention = get_sparse_self_attention(param_dict) + self.sparse_attention = get_sparse_attention(param_dict) def _batch_assertion(self): diff --git a/deepspeed/runtime/constants.py b/deepspeed/runtime/constants.py index a68151ca09ca..57bd5ecf81fc 100755 --- a/deepspeed/runtime/constants.py +++ b/deepspeed/runtime/constants.py @@ -18,9 +18,9 @@ TRAIN_BATCH_SIZE_DEFAULT = None ############################################# -# Sparse self attention +# Sparse attention ############################################# -SPARSE_SELF_ATTENTION = "sparse_self_attention" +SPARSE_ATTENTION = "sparse_attention" SPARSE_DENSE_MODE = "dense" SPARSE_FIXED_MODE = "fixed" SPARSE_VARIABLE_MODE = "variable" diff --git a/setup.py b/setup.py index 8b7da5a2ba8a..d2f90e678c83 100755 --- a/setup.py +++ b/setup.py @@ -124,8 +124,8 @@ ## Sparse transformer ## ext_modules.append( - CppExtension(name='deepspeed.ops.sparse_transformer.cpp_util', - sources=['csrc/sparse_transformer/utils.cpp'], + CppExtension(name='deepspeed.ops.sparse_attention.cpp_utils', + sources=['csrc/sparse_attention/utils.cpp'], extra_compile_args={'cxx': ['-O2', '-fopenmp']})) @@ -138,7 +138,7 @@ packages=find_packages(exclude=["docker", "third_party", "csrc"]), - package_data={'deepspeed.ops.sparse_transformer.trsrc': ['*.tr']}, + package_data={'deepspeed.ops.sparse_attention.trsrc': ['*.tr']}, scripts=['bin/deepspeed', 'bin/deepspeed.pt', 'bin/ds', diff --git a/tests/unit/test_sparse_transformer.py b/tests/unit/test_sparse_attention.py similarity index 75% rename from tests/unit/test_sparse_transformer.py rename to tests/unit/test_sparse_attention.py index e847d54d7796..3f2078946297 100755 --- a/tests/unit/test_sparse_transformer.py +++ b/tests/unit/test_sparse_attention.py @@ -7,36 +7,36 @@ import torch -def test_sparse_transformer_module_availability(): +def test_sparse_attention_module_availability(): try: - from deepspeed.ops import sparse_transformer + from deepspeed.ops import sparse_attention except ImportError: - print("Sparse Transformer Module is not installed!") + print("Sparse Attention Module is not installed!") return False return True def test_matmul_module_availability(): try: - from deepspeed.ops.sparse_transformer import MatMul + from deepspeed.ops.sparse_attention import MatMul except ImportError: - print("Sparse Transformer MatMul Module is not installed!") + print("Sparse MatMul Module is not installed!") return False return True def test_softmax_module_availability(): try: - from deepspeed.ops.sparse_transformer import Softmax + from deepspeed.ops.sparse_attention import Softmax except ImportError: - print("Sparse Transformer Softmax Module is not installed!") + print("Sparse Softmax Module is not installed!") return False return True def test_sparsityconfig_module_availability(): try: - from deepspeed.ops.sparse_transformer import SparsityConfig + from deepspeed.ops.sparse_attention import SparsityConfig except ImportError: print("SparsityConfig Module is not installed!") return False @@ -45,7 +45,7 @@ def test_sparsityconfig_module_availability(): def test_densesparsityconfig_module_availability(): try: - from deepspeed.ops.sparse_transformer import DenseSparsityConfig + from deepspeed.ops.sparse_attention import DenseSparsityConfig except ImportError: print("DenseSparsityConfig Module is not installed!") return False @@ -54,7 +54,7 @@ def test_densesparsityconfig_module_availability(): def test_fixedsparsityconfig_module_availability(): try: - from deepspeed.ops.sparse_transformer import FixedSparsityConfig + from deepspeed.ops.sparse_attention import FixedSparsityConfig except ImportError: print("FixedSparsityConfig Module is not installed!") return False @@ -63,7 +63,7 @@ def test_fixedsparsityconfig_module_availability(): def test_variablesparsityconfig_module_availability(): try: - from deepspeed.ops.sparse_transformer import VariableSparsityConfig + from deepspeed.ops.sparse_attention import VariableSparsityConfig except ImportError: print("VariableSparsityConfig Module is not installed!") return False @@ -72,7 +72,7 @@ def test_variablesparsityconfig_module_availability(): def test_bigbirdsparsityconfig_module_availability(): try: - from deepspeed.ops.sparse_transformer import BigBirdSparsityConfig + from deepspeed.ops.sparse_attention import BigBirdSparsityConfig except ImportError: print("BigBirdSparsityConfig Module is not installed!") return False @@ -81,7 +81,7 @@ def test_bigbirdsparsityconfig_module_availability(): def test_bslongformersparsityconfig_module_availability(): try: - from deepspeed.ops.sparse_transformer import BSLongformerSparsityConfig + from deepspeed.ops.sparse_attention import BSLongformerSparsityConfig except ImportError: print("BSLongformerSparsityConfig Module is not installed!") return False @@ -90,7 +90,7 @@ def test_bslongformersparsityconfig_module_availability(): def test_sparseselfattention_module_availability(): try: - from deepspeed.ops.sparse_transformer import SparseSelfAttention + from deepspeed.ops.sparse_attention import SparseSelfAttention except ImportError: print("SparseSelfAttention Module is not installed!") return False @@ -99,70 +99,27 @@ def test_sparseselfattention_module_availability(): def test_bertsparseselfattention_module_availability(): try: - from deepspeed.ops.sparse_transformer import BertSparseSelfAttention + from deepspeed.ops.sparse_attention import BertSparseSelfAttention except ImportError: print("BertSparseSelfAttention Module is not installed!") return False return True -def test_extend_position_embedding_module_availability(): +def test_sparseattentionutils_availability(): try: - from deepspeed.ops.sparse_transformer import extend_position_embedding + from deepspeed.ops.sparse_attention import SparseAttentionUtils except ImportError: - print("Sparse Transformer extend_position_embedding Module is not installed!") + print("SparseAttentionUtils Module is not installed!") return False return True -def test_update_tokenizer_model_max_length_module_availability(): +def test_cpp_utils_availability(): try: - from deepspeed.ops.sparse_transformer import update_tokenizer_model_max_length + from deepspeed.ops.sparse_attention import cpp_utils except ImportError: - print( - "Sparse Transformer update_tokenizer_model_max_length Module is not installed!" - ) - return False - return True - - -def test_replace_model_self_attention_with_sparse_self_attention_module_availability(): - try: - from deepspeed.ops.sparse_transformer import replace_model_self_attention_with_sparse_self_attention - except ImportError: - print( - "Sparse Transformer replace_model_self_attention_with_sparse_self_attention Module is not installed!" - ) - return False - return True - - -def test_replace_self_attention_layer_with_sparse_self_attention_layer_module_availability( -): - try: - from deepspeed.ops.sparse_transformer import replace_self_attention_layer_with_sparse_self_attention_layer - except ImportError: - print( - "Sparse Transformer replace_self_attention_layer_with_sparse_self_attention_layer Module is not installed!" - ) - return False - return True - - -def test_pad_to_block_size_module_availability(): - try: - from deepspeed.ops.sparse_transformer import pad_to_block_size - except ImportError: - print("Sparse Transformer pad_to_block_size Module is not installed!") - return False - return True - - -def test_unpad_sequence_output_module_availability(): - try: - from deepspeed.ops.sparse_transformer import unpad_sequence_output - except ImportError: - print("Sparse Transformer unpad_sequence_output Module is not installed!") + print("Sparse Attention cpp_utils Module is not installed!") return False return True @@ -223,8 +180,8 @@ def run_softmax_reference(x, scale, dx, kp_mask, attn_mask, layout, block): return y, dx -def run_softmax_st(x, scale, dx, kp_mask, attn_mask, layout, block): - from deepspeed.ops.sparse_transformer import Softmax +def run_softmax_sparse(x, scale, dx, kp_mask, attn_mask, layout, block): + from deepspeed.ops.sparse_attention import Softmax sparse_softmax = Softmax(layout, block, bench=False) dx = dense_to_sparse(dx, layout, block) x = dense_to_sparse(x, layout, block) @@ -296,7 +253,7 @@ def test_softmax(block, width, dtype): M = N = width layout, x, dx, bool_attn_mask, fp_attn_mask, kp_mask = init_softmax_inputs(Z, H, M, N, scale, rho, block, dtype, layout=None) ref_y, ref_dx = run_softmax_reference(x, scale, dx, kp_mask, bool_attn_mask, layout, block) - st_y, st_dx = run_softmax_st(x, scale, dx, kp_mask, fp_attn_mask, layout, block) + st_y, st_dx = run_softmax_sparse(x, scale, dx, kp_mask, fp_attn_mask, layout, block) assert allclose(ref_y, st_y) assert allclose(ref_dx, st_dx) @@ -321,8 +278,8 @@ def run_matmul_reference(x, w, mode, trans_a, trans_b, layout, block, dy): return y, dx, dw -def run_matmul_st(x, w, mode, trans_a, trans_b, layout, block, dy): - from deepspeed.ops.sparse_transformer import MatMul +def run_matmul_sparse(x, w, mode, trans_a, trans_b, layout, block, dy): + from deepspeed.ops.sparse_attention import MatMul x = dense_to_sparse(x, layout, block) if mode == 'dsd' else x w = dense_to_sparse(w, layout, block) if mode == 'dds' else w dy = dense_to_sparse(dy, layout, block) if mode == 'sdd' else dy @@ -379,7 +336,7 @@ def test_matmul(block, dtype, mode, trans_a, trans_b): rho = 0.5 x, w, dy, shape, layout = init_matmul_inputs(Z, H, M, N, K, rho, mode, trans_a, trans_b, block, dtype, layout=None) ref_y, ref_dx, ref_dw = run_matmul_reference(x.clone(), w.clone(), mode, trans_a, trans_b, layout, block, dy) - st_y, st_dx, st_dw = run_matmul_st(x.clone(), w.clone(), mode, trans_a, trans_b, layout, block, dy) + st_y, st_dx, st_dw = run_matmul_sparse(x.clone(), w.clone(), mode, trans_a, trans_b, layout, block, dy) assert allclose(ref_y, st_y) assert allclose(ref_dx, st_dx) assert allclose(ref_dw, st_dw) From e23fec11cae0794d9f6d1a537fd90a9d1d3c5eb3 Mon Sep 17 00:00:00 2001 From: Arash Ashari Date: Tue, 1 Sep 2020 15:50:52 -0700 Subject: [PATCH 14/16] Updated/added Sparse Attention Documentation (#78) * update sparse attention post doc * added json config doc for sparse attention and fixed few typos * updated tutorial * updated the post based on the blog post text and image sizings * ran formatter * renamed a figure in the post; sa_backward_pass * updated the triton version with the latest; this version will resolve some synchronization issue was happenening in compile * few figure size and caption updates * fixed a bullet ordering issue * fixed another bullet ordering issue * added warning notes regarding incompatability of Transformer Kernels and SA * adding a note for V100 and Cuda requirement --- .../ops/sparse_attention/sparsity_config.py | 22 ++--- docs/_pages/config-json.md | 40 ++++++++ docs/_posts/2020-08-00-sparse-transformer.md | 35 ------- docs/_posts/2020-09-09-sparse-attention.md | 83 +++++++++++++++++ docs/_tutorials/sparse_attention.md | 88 ++++++++++++++++++ docs/_tutorials/sparse_transformer.md | 81 ---------------- docs/_tutorials/sparse_transformer_results.md | 68 -------------- docs/_tutorials/transformer_kernel.md | 3 + docs/assets/images/fixed_sparsity_pattern.png | Bin 51803 -> 0 bytes docs/assets/images/sa_backward_pass.png | Bin 0 -> 43362 bytes .../images/sa_bert_base_time_result.png | Bin 0 -> 65509 bytes .../images/sa_bert_large_time_result.png | Bin 0 -> 60952 bytes .../images/sa_fixed_sparsity_structure.png | Bin 0 -> 70347 bytes docs/assets/images/sa_forward_pass.png | Bin 0 -> 34972 bytes docs/assets/images/sa_gpt2_time_result.png | Bin 0 -> 62039 bytes .../sa_long_document_comprehension_result.png | Bin 0 -> 58951 bytes .../sa_maximum_sequence_runnable_on_bert.png | Bin 0 -> 34017 bytes .../images/sa_variable_sparsity_structure.png | Bin 0 -> 101093 bytes .../sparse_self_attention_backward_pass.png | Bin 18207 -> 0 bytes .../sparse_self_attention_forward_pass.png | Bin 13237 -> 0 bytes docs/assets/images/st_bert_base_result.png | Bin 41819 -> 0 bytes docs/assets/images/st_bert_large_result.png | Bin 29423 -> 0 bytes docs/assets/images/st_deepthink_result.png | Bin 25294 -> 0 bytes .../assets/images/st_megatron_gpt2_result.png | Bin 36251 -> 0 bytes requirements.txt | 2 +- 25 files changed, 226 insertions(+), 196 deletions(-) delete mode 100644 docs/_posts/2020-08-00-sparse-transformer.md create mode 100644 docs/_posts/2020-09-09-sparse-attention.md create mode 100644 docs/_tutorials/sparse_attention.md delete mode 100644 docs/_tutorials/sparse_transformer.md delete mode 100644 docs/_tutorials/sparse_transformer_results.md delete mode 100644 docs/assets/images/fixed_sparsity_pattern.png create mode 100644 docs/assets/images/sa_backward_pass.png create mode 100644 docs/assets/images/sa_bert_base_time_result.png create mode 100644 docs/assets/images/sa_bert_large_time_result.png create mode 100644 docs/assets/images/sa_fixed_sparsity_structure.png create mode 100644 docs/assets/images/sa_forward_pass.png create mode 100644 docs/assets/images/sa_gpt2_time_result.png create mode 100644 docs/assets/images/sa_long_document_comprehension_result.png create mode 100644 docs/assets/images/sa_maximum_sequence_runnable_on_bert.png create mode 100644 docs/assets/images/sa_variable_sparsity_structure.png delete mode 100644 docs/assets/images/sparse_self_attention_backward_pass.png delete mode 100644 docs/assets/images/sparse_self_attention_forward_pass.png delete mode 100644 docs/assets/images/st_bert_base_result.png delete mode 100644 docs/assets/images/st_bert_large_result.png delete mode 100644 docs/assets/images/st_deepthink_result.png delete mode 100644 docs/assets/images/st_megatron_gpt2_result.png diff --git a/deepspeed/ops/sparse_attention/sparsity_config.py b/deepspeed/ops/sparse_attention/sparsity_config.py index d4fa5240baf3..5d8e2fa5fa46 100644 --- a/deepspeed/ops/sparse_attention/sparsity_config.py +++ b/deepspeed/ops/sparse_attention/sparsity_config.py @@ -104,7 +104,7 @@ def __init__(self, num_global_blocks=1, attention='bidirectional', horizontal_global_attention=False, - num_differnt_global_patterns=1): + num_different_global_patterns=1): """Initialize `Fixed` Sparsity Pattern Config. For usage example please see, TODO DeepSpeed Sparse Transformer Tutorial @@ -114,10 +114,10 @@ def __init__(self, block: optional: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. different_layout_per_head: optional: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. num_local_blocks: optional: an integer determining the number of blocks in local attention window. - num_global_blocks: optional: an integer determining how many consecutive blocks in a local window is used as the representetive of the window for global attention. + num_global_blocks: optional: an integer determining how many consecutive blocks in a local window is used as the representative of the window for global attention. attention: optional: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. - horizontal_global_attention: optional: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but aso horizontal blocks. - num_differnt_global_patterns: optional: an integer determining number of different global attentions layouts. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks local window and global attention size of 1 block, we can have 4 different versions in which the first, Second, third, or forth block of each local window can be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on num_local_blocks and num_global_blocks. + horizontal_global_attention: optional: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but also horizontal blocks. + num_different_global_patterns: optional: an integer determining number of different global attentions layouts. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks local window and global attention size of 1 block, we can have 4 different versions in which the first, Second, third, or forth block of each local window can be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on num_local_blocks and num_global_blocks. """ super().__init__(num_heads, block, different_layout_per_head) @@ -141,15 +141,15 @@ def __init__(self, ) self.horizontal_global_attention = horizontal_global_attention - if (num_differnt_global_patterns > 1 and not different_layout_per_head): + if (num_different_global_patterns > 1 and not different_layout_per_head): raise ValueError( f'Number of different layouts cannot be more than one when you have set a single layout for all heads! Set different_layout_per_head to True.' ) - if (num_differnt_global_patterns > (num_local_blocks // num_global_blocks)): + if (num_different_global_patterns > (num_local_blocks // num_global_blocks)): raise ValueError( - f'Number of layout versions (num_differnt_global_patterns), {num_differnt_global_patterns}, cannot be larger than number of local window blocks divided by number of global blocks, {num_local_blocks} / {num_global_blocks} = {num_local_blocks//num_global_blocks}!' + f'Number of layout versions (num_different_global_patterns), {num_different_global_patterns}, cannot be larger than number of local window blocks divided by number of global blocks, {num_local_blocks} / {num_global_blocks} = {num_local_blocks//num_global_blocks}!' ) - self.num_differnt_global_patterns = num_differnt_global_patterns + self.num_different_global_patterns = num_different_global_patterns def set_local_layout(self, h, layout): """Sets local attantion layout used by the given head in the sparse attention. @@ -188,7 +188,7 @@ def set_global_layout(self, h, layout): num_blocks = layout.shape[1] first_global_block_idx = self.num_local_blocks - ( - 1 + h % self.num_differnt_global_patterns) * self.num_global_blocks + 1 + h % self.num_different_global_patterns) * self.num_global_blocks # set all global blocks except the last one if (in last local window) end = num_blocks - (num_blocks % self.num_local_blocks) @@ -272,9 +272,9 @@ def __init__(self, local_window_blocks: optional: a list of integers determining the number of blocks in each local attention window. It assumes first number determines # of blocks in the first local window, second the second window, ..., and the last number determines the number of blocks in the remaining local windows. global_block_indices: optional: a list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Default value is only index 0. Notice that if global_block_end_indices parameter is set, this parameter is used as starting index of each global window. global_block_end_indices: optional: a list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size of global_block_indices parameter, and combining this two parameters, for each index i, blocks from global_block_indices[i] to global_block_end_indices[i] (exclusive) are considered as global attention. - num_global_blocks: optional: an integer determining how many consecutive blocks in a local window is used as the representetive of the window for global attention. + num_global_blocks: optional: an integer determining how many consecutive blocks in a local window is used as the representative of the window for global attention. attention: optional: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. - horizontal_global_attention: optional: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but aso horizontal blocks. + horizontal_global_attention: optional: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but also horizontal blocks. """ super().__init__(num_heads, block, different_layout_per_head) diff --git a/docs/_pages/config-json.md b/docs/_pages/config-json.md index ea5fcb256818..ff929a67cf8c 100755 --- a/docs/_pages/config-json.md +++ b/docs/_pages/config-json.md @@ -335,3 +335,43 @@ Enabling and configure ZeRO memory optimizations | Description | Default | | ------------------------------------------------------------ | ------- | | Logs the forward and backward time for each checkpoint function | `false` | + +### Sparse Attention + +***sparse\_attention***: [dictionary] + +| Fields | Value | Example | +| ------ | ------------------------------------------------------------ | ------------------------------ | +| mode | A string determining sparsity structure type. Deepspeed currently supports `"dense"`, `"fixed"`, `"bigbird"`, `"bslongformer"`, and `"variable"`. | `"fixed"` | +| block | An integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such blocks, `Block X Block`. | 16 | +| different\_layout\_per\_head | A boolean determining if each head should be assigned a different sparsity layout; this will be satisfied based on availability. | false | +| num\_local\_blocks | An integer determining the number of random blocks in each block row; only used in `"fixed"` mode. | 4 | +| num\_global\_blocks | An integer determining how many consecutive blocks in a local window is used as the representative of the window for global attention; used in `"fixed"` and `"bigbird"` modes. | 1 | +| attention | A string determining attention type. Attention can be `"unidirectional"`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty. Or it can be `"bidirectional"`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular; used in `"fixed"` and `"variable"` modes. | `"bidirectional"` | +| horizontal\_global\_attention | A boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `"bidirectional"`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but also horizontal blocks; used in `"fixed"` and `"variable"` modes. | false | +| num\_different\_global\_patterns | An integer determining number of different global attentions layouts. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative; used only in `"fixed"` mode. | 4 | +| num\_random\_blocks | An integer determining the number of random blocks in each block row; used in `"variable"` and `"bigbird"` modes. | 0 | +| local\_window\_blocks | A list of integers determining the number of blocks in each local attention window. It assumes first number determines # of blocks in the first local window, second the second window, ..., and the last number determines the number of blocks in the remaining local windows; only used in `"variable"` mode. | [4] | +| global\_block\_indices | A list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Notice that if global\_block\_end\_indices parameter is set, this parameter is used as starting index of each global window; used in `"variable"` and `"bslongformer"` modes. | [0] | +| global\_block\_end\_indices | A list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size of global\_block\_indices parameter, and combining this two parameters, for each index i, blocks from global\_block\_indices[i] to global\_block\_end\_indices[i], exclusive, are considered as global attention; used in `"variable"` and `"bslongformer"` modes. | None | +| num\_sliding\_window\_blocks | An integer determining the number of blocks in sliding local attention window; used in `"bigbird"` and `"bslongformer"` modes. | 3 | + + Example of ***sparse\_attention*** + +```json + "sparse_attention": { + "mode": "fixed", + "block": 16, + "different_layout_per_head": true, + "num_local_blocks": 4, + "num_global_blocks": 1, + "attention": "bidirectional", + "horizontal_global_attention": false, + "num_different_global_patterns": 4, + "num_random_blocks": 0, + "local_window_blocks": [4], + "global_block_indices": [0], + "global_block_end_indices": None, + "num_sliding_window_blocks": 3 + } +``` diff --git a/docs/_posts/2020-08-00-sparse-transformer.md b/docs/_posts/2020-08-00-sparse-transformer.md deleted file mode 100644 index ca442231fe7c..000000000000 --- a/docs/_posts/2020-08-00-sparse-transformer.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -layout: single -title: "DeepSpeed Sparse Transformer (Sparse Self Attention)" -excerpt: "" -categories: news -new_post: true -date: 2020-08-00 00:00:00 ---- - -We introduce DeepSpeed Sparse Transformer, an instrumental technology to support long sequence of model inputs, whether for text, image or sound. Comparing with the classic dense transformers, it powers input sequence with an order-of-magnitude longer and obtains up to 6x faster execution with comparable accuracy; it also outperforms state-of-arts sparse implementations with 1.5 - 3x faster execution. Furthermore, our sparse kernels support efficient execution of flexible sparse format and empower users to innovate on their customized sparse structures. -This library is PyTorch based and develops required kernels through [Triton](https://github.com/ptillet/triton) platform; kernels are not written in CUDA, which leaves the door open for CPU/OpenCL/Vulkan support in the future. The library is an extension to DeepSpeed and can be used through DeepSpeed as well as stand alone. -DeepSpeed Sparse Attention kernels, handles the following block-sparse computations: -(`S` stands for a `sparse matrix` and `D` a `dense matrix`. Sparse matrix is `blocked sparse matrix`.) - -* Forward: - -![sparse_self_attention_forward_pass](/assets/images/sparse_self_attention_forward_pass.png){: .align-center} - - * `S = D X D => w = q X trans(k)` - * `S = softmax(S) => w = softmax(w)` - * `D = S X D => a = w X v` - - -* Backward: - -![sparse_self_attention_backward_pass](/assets/images/sparse_self_attention_backward_pass.png){: .align-center} - - * `D = S X D => v = trans(w) X da` - * `S = D X D => w = da X trans(v)` - * `S = bwd_softmax(S) => dw = w X (dw - sum(dw X w))` - * `D = D X S => k = q X trans(dw)` - * `D = S X D => q = dw X k` - -For Sparsity Config, and also how to use this library, please check our [tutorial](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_tutorials/sparse_transformer.md) that provides detailed information about it. -In [result](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_tutorials/sparse_transformer_results.md) section, we provide a summary of our experiments using this library. This section also contains experiments comparing our library with [Longformer](https://arxiv.org/abs/2004.05150); state-of-arts sparse implementation of sparsity pattern. diff --git a/docs/_posts/2020-09-09-sparse-attention.md b/docs/_posts/2020-09-09-sparse-attention.md new file mode 100644 index 000000000000..b6221c85d5c4 --- /dev/null +++ b/docs/_posts/2020-09-09-sparse-attention.md @@ -0,0 +1,83 @@ +--- +layout: single +title: "DeepSpeed Sparse Attention" +excerpt: "" +categories: news +new_post: true +date: 2020-09-09 01:00:00 +--- + +Attention-based deep learning models such as the transformers are highly effective in capturing relationship between tokens in an input sequence, even across long distances. As a result, they are used with text, image, and sound-based inputs, where the sequence length can be in thousands of tokens. However, despite the effectiveness of attention modules to capture long term dependencies, in practice, their application to long sequence input is limited by compute and memory requirements of the attention computation that grow quadratically, `O(n^2)`, with the sequence length n. + +To address this limitation, DeepSpeed offers a suite of sparse attention kernels --an instrumental technology that can reduce the compute and memory requirement of attention computation by orders-of-magnitude via block-sparse computation. The suite not only alleviates the memory bottleneck of attention calculation, but also performs sparse computation efficiently. Its APIs allow convenient integration with any transformer-based models. Along with providing a wide spectrum of sparsity structures, it has the flexibility of handling any user-defined block-sparse structures. More specifically, sparse attention (SA) can be designed to compute local attention between nearby tokens, or global attention via summary tokens computed with local attention. Moreover, SA can also allow random attention, or any combination of local, global, and random attention as shown in the following figure with blue, orange, and green blocks, respectively. As a result, SA decreases the memory footprint to `O(wn)`, in which `1 < w < n` is a parameter, whose value depends on the attention structure. + +![Variable sparsity structure](/assets/images/sa_variable_sparsity_structure.png){: .align-center} + +This library is PyTorch based and develops required kernels through [Triton](https://github.com/ptillet/triton) platform; kernels are not written in CUDA, which leaves the door open for CPU/OpenCL/Vulkan support in the future. The library is an extension to DeepSpeed and can be used through DeepSpeed as well as stand alone. +Block-sparse computations handled by DeepSpeed Sparse Attention kernels are illustrated in following figures for forward and backward passes respectively. In the figures, `S` stands for a `block-sparse matrix` and `D` a `dense matrix`. + +![Sparse attention forward pass](/assets/images/sa_forward_pass.png){: .align-center} + +![Sparse attention backward pass](/assets/images/sa_backward_pass.png){: .align-center} + +To learn more about Sparsity Config, and also how to use this library, please check our [tutorial](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_tutorials/sparse_attention.md) that provides detailed information about it. + +## Performance Results + +* **Power over 10x longer sequences** +In a pre-training experiment, we ran BERT model under three settings: dense, dense with activation checkpoint, and sparse (SA) with activation checkpoint. SA empowers 10x and 16x longer sequences comparing with dense for BERT base and large, respectively. Following figure shows the longest sequence length runnable in BERT base and large model; experiment is performed with batch size 1 on a single Nvidia V100 GPU-32GB memory. + +![Maximum sequence runnable on BERT](/assets/images/sa_maximum_sequence_runnable_on_bert.png){: .align-center} + +* **up to 6.3x faster computation** +We continued the pre-training experiment for different batch sizes and sequence lengths, using [BERT base/large](https://github.com/microsoft/DeepSpeedExamples/tree/master/bing_bert) and [Megatron GPT2](https://github.com/microsoft/DeepSpeedExamples/tree/master/Megatron-LM). In this experiment we let the training to continue for 100 iteration and recorded the average time per last 30 iterations. SA reduces total computation comparing with dense and improves training speed: the boost is higher with increased sequence length and it is up to 6.3x faster for BERT base, 5.3x for BERT large, and 6.1x for GPT2. Following charts show these results. + +![Training time for BERT base with varying sequence length](/assets/images/sa_bert_base_time_result.png){: .align-center} + +![Training time for BERT large with varying sequence length](/assets/images/sa_bert_large_time_result.png){: .align-center} + +![Training time for GPT2 with varying sequence length](/assets/images/sa_gpt2_time_result.png){: .align-center} + +* **higher accuracy** +Related works along the line of sparse attention ([Sparse Transformer](https://arxiv.org/pdf/1904.10509.pdf), [Longformer](https://arxiv.org/pdf/2004.05150.pdf), [BigBird](https://arxiv.org/pdf/2007.14062.pdf)) have shown comparable or higher accuracy than full attention. Our experience is well aligned. In addition to lower memory overhead and faster computation, we also observe cases in production where SA reaches higher accuracy and faster convergence. The following chart illustrates accuracy of training a production model based on BERT for long document comprehension (2,048 sequence length). The experiment is performed in three settings: dense starting from scratch, SA starting from scratch, and SA continued training from a checkpoint of using dense with sequence length of 512. We have observed that, for pre-training from scratch, SA converges faster with higher accuracy comparing with dense. Furthermore, SA continuing training from a pre-trained checkpoint performs even better, with respect to both time and accuracy. + + +![Accuracy of long document comprehension application](/assets/images/sa_long_document_comprehension_result.png){: .align-center} + +* **flexibility to handle any block-sparse structure** +DeepSpeed Sparse Attention suite does not target at any specific sparse structure but enables model scientists to explore any block sparse structure with efficient system support. Currently, we have added popular sparse structure like: + * [Fixed](https://arxiv.org/pdf/1904.10509.pdf) (from OpenAI Sparse Transformer) + * [BigBird](https://arxiv.org/pdf/2007.14062.pdf) (from Google) + * BSLongformer (Block-Sparse implementation of [Longformer](https://arxiv.org/pdf/2004.05150.pdf) from AI2) +We also define a template to have `variable` structure (top figure), which can be used to simply customize any block-sparse random/local/global attention pattern. In addition to this list, user can add any other sparsity structure as described in [tutorial](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_tutorials/sparse_transformer.md) section. + + +* **comparison with state of the art, Longformer** +We compared SA with Longformer, a state-of-the-art sparse structure and implementation. In our experiment, SA uses `Fixed` sparsity, and two implementations have comparable accuracy. On system performance, SA outperforms Longformer both in training and inference: + * 1.47x faster execution pre-training MLM on Wikitext103 +We ran an experiment following the [notebook](https://github.com/allenai/longformer/blob/master/scripts/convert_model_to_long.ipynb) offered by Longformer. In this experiment, we pre-train an MLM model using RoBERTa-base checkpoint. This is done on 8 V100-SXM2 GPU. Following table shows the details of the result in which using DeepSpeed Sparse Attention shows 1.47x speed up. + +|Model |Local Window Size |BPC |Train Step |Time Per Iteration |Time Improvement |Accuracy improvement | +|-------------------|------------------|--------|------------|--------------------|------------------|----------------------| +|RoBERTa Checkpoint | |2.5326 | | +|Longformer |512 |2.6535 |0 | |1.47 |1.01 | +|Sparse Attention | |2.6321 | | | | | +|Longformer | |1.6708 |3k |1.6280 | |1.01 | +|Sparse Attention | |1.6613 | |1.1059 | | | +|Longformer |64 |5.7840 |0 | |1.31 |1.46 | +|Sparse Attention | |3.9737 | | | | | +|Longformer | |2.0466 |3k |1.4855 | |1.09 | +|Sparse Attention | |1.8693 | |1.1372 | | | + + + * 3.13x faster execution inference on BERT-Base +Through our Long Document Comprehension application we described above, we also checked the inference time for different window sizes testing BERT model on a `2,048` Sequence Length and batch size `1`. In this experiment, we noticed up to `3.13X` speed up replacing Bert Attention with DeepSpeed Sparse Attention instead of Longformer Attention. Following table shows the complete result. + +|Local Window Size |Time Improvement| +|--------------------|----------------| +|512 |3.13 | +|256 |2.29 | +|128 |2.16 | +|64 |1.5 | +|32 |1.24 | +|16 |1.23 | diff --git a/docs/_tutorials/sparse_attention.md b/docs/_tutorials/sparse_attention.md new file mode 100644 index 000000000000..7b8233543378 --- /dev/null +++ b/docs/_tutorials/sparse_attention.md @@ -0,0 +1,88 @@ +--- +title: "DeepSpeed Sparse Attention" +--- + +In this tutorial we describe how to use DeepSpeed Sparse Attention and its building-block kernels through DeepSpeed launcher or integrating individual kernels into your code. + +**Note:** Currently DeepSpeed Sparse Attention can be used only on Nvidia V100 GPU using Cuda 10.1 or 10.2. +{: .notice--warning} + +## How to use +DeepSpeed Sparse Attention can be used as a feature through DeepSpeed, or simply integrated with any Transformer model as a self-attention module alone. Further, the building block kernels, matrix multiplication and softmax can be used separately. To use sparse attention alone, you can simply install DeepSpeed and import any of the following modules from it; example: +```python +from deepspeed.ops.sparse_attention import SparseSelfAttention +``` +Following we describe Sparse Attention modules: +* **MatMul**: This module handles block-sparse matrix-matrix multiplication. Currently it supports SDD, DSD, and DDS as described in [DeepSpeed Sparse Attention](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_posts/2020-09-09-sparse-attention.md) section. +* **Softmax**: This module applies block sparse softmax. It handles both forward and backward pass. +* **SparseSelfAttention**: This module uses MatMul and Softmax kernels and generates Context Layer output given Query, Keys and Values. It is a simplified version of common operations in any self-attention layer. It can also apply: + * `Relative position embedding` + * `Attention mask` + * `Key padding mask` +on the intermediate attention scores. For more details about SelfAttantion, please check [MultiHeadAttention](https://pytorch.org/docs/master/generated/torch.nn.MultiheadAttention.html#multiheadattention). +* **BertSparseSelfAttention**: This module contains a simplified BertSelfAttention layer that can be used instead of original dense Bert Self-Attention layer. Our implementation is based on [DeepSpeedExample](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/nvidia/modelingpreln.py#L373-#L434). +* **SparseAttentionUtils**: This module provides few utility functions to handle adapting pre-trained model with sparse attention: + * `replace_model_self_attention_with_sparse_self_attention`: If you have currently loaded a model and want to replace self-attention module with sparse self-attention, you can simply use this function to handle it for you. It currently handles BERT and RoBERTa based pre-trained models, but you can extend it base on your model type if it is different from these two. You also need to extend the position embedding to handle new sequence length; this can be done using `extend_position_embedding` function. + * `update_tokenizer_model_max_length`: This function simply updates maximum position embedding in your tokenizer with the new value. + * `extend_position_embedding`: This function extends the position embedding based on the current values. For example, if you have a 128 max sequence length model and extending it to a 1k sequence length, it replicates current embeddings 8 times to initialize new embedding. Experimentally we have seen such initialization works much better than initializing from scratch; leads to faster convergence. + * `pad_to_block_size`: This function pads input tokens and attention mask on sequence length dimension to be multiple of block size; this is a requirement for SA. + * `unpad_sequence_output`: This function unpads sequence output if inputs of the model were padded. +* **SparsityConfig**: this is an abstract class for sparsity structure. Any sparsity structure extends this class and writes its own `make_layout` function. DeepSpeed currently provides the following structures that will be described in next section: + * `FixedSparsityConfig` + * `BSLongformerSparsityConfig` + * `BigBirdSparsityConfig` + * `VariableSparsityConfig` + +### BertSparseSelfAttention Example +We have currently integrated Sparse Attention with our [bing_bert](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/nvidia/modelingpreln.py) code that can be used as an example for integration. In this example, we replace, BertSelfAttention module with BertSparseSelfAttention. Using DeepSpeed launcher, you can enable sparse attention using `deepspeed_sparse_attention` argument ([example](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/ds_sa_train_bert_bsz64k_seq128.sh)) and add your desired sparsity config into the [DeepSpeed config file](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/deepspeed_bsz64k_lamb_config_seq128.json). In this example, we have used `fixed` sparsity mode. Further, you need to pad sequence dimension of `input_ids` and `attention_mask` to be multiple of sparse block size. As mentioned above, DeepSpeed provides utility functions for padding and unpadding and you can check our [example](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/nvidia/modelingpreln.py) to see where and how pad and unpad the inputs or outputs of the model. + +**Note:** Currently DeepSpeed Transformer Kernels do not support Sparse Attention. To use Sparse Attention, you need to disable Transformer Kernels! +{: .notice--warning} + +### Sparsity structures +Following we describe supported sparsity structures, their parameter set and the flexibility of adding arbitrary sparsity pattern on the self-attention layer. +* **SpasityConfig**: +This module, is the parent class for all sparsity structures and contains the shared features of all sparsity structures. It takes the following parameters: + * `num_heads`: an integer determining number of attention heads of the layer. + * `block`: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such square blocks; `Block X Block`. + * `different_layout_per_head`: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. + +* **Fixed** (FixedSparistyConfig): +This structure is based on [Generative Modeling with Sparse Transformers](https://arxiv.org/abs/1904.10509) from OpenAI, in which local and global attention is fixed by the given parameters: + * `num_local_blocks`: an integer determining the number of blocks in local attention window. As it is illustrated in the below figure (adapted from original paper), tokens in a local window, attend to all tokens local to them. In the case of autoregressive model, as in the figure, tokens attend to tokens appearing before them in the local window. And in the case of Masked model such as BERT, attention is bidirectional. + * `num_global_blocks`: an integer determining how many consecutive blocks in a local window is used as the representative of the window for global attention; illustrated in the figure below as well. + * `attention`: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. + * `horizontal_global_attention`: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but also horizontal blocks. + * `num_different_global_patterns`: an integer determining number of different global attentions layouts. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks constructing local window and global attention size of a single block, we can have 4 different versions in which the first, second, third, or forth block of each local window can be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on `num_local_blocks` and `num_global_blocks`. Further, if you set this to more than one, you need to set `different_layout_per_head` to `True`. + +![Fixed sparsity structure](/assets/images/sa_fixed_sparsity_structure.png) + +* **BSLongformer** (BSLongformerSparistyConfig): +This structure is an edited version of [Longformer: The Long-Document Transformer](https://arxiv.org/pdf/2004.05150.pdf), in which instead of single token-wise sparsity, we offer block of tokens sparsity. Parameters that define this patters are: + * `num_sliding_window_blocks`: an integer determining the number of blocks in sliding local attention window. + * `global_block_indices`: a list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Notice that if `global_block_end_indices` parameter is set, this parameter is used as starting index of each global window. + * `global_block_end_indices`: a list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size as `global_block_indices` parameter, and combining this two parameters, for each index `i`, blocks from `global_block_indices[i]` to `global_block_end_indices[i]` (exclusive) are considered as global attention block. + +* **BigBird** (BigBirdSparsityConfig): +This structure is based on [Big Bird: Transformers for Longer Sequences](https://arxiv.org/pdf/2007.14062.pdf). It somehow combines the idea of `fixed` and `longformer` patterns along with random attention. Following parameters define this structure: + * `num_random_blocks`: an integer determining how many blocks in each row block are attended randomly. + * `num_sliding_window_blocks`: an integer determining the number of blocks in sliding local attention window. + * `num_global_blocks`: an integer determining how many consecutive blocks, starting from index 0, are considered as global attention. Global block tokens will be attended by all other block tokens and will attend to all other block tokens as well. + +* **Variable** (VariableSparsityConfig): +This structure also combines the idea of local, global and random attention. Further, it has the flexibility of defining variable size local windows. Following is the list of parameters that define this structure: + * `num_random_blocks`: an integer determining how many blocks in each row block are attended randomly. + * `local_window_blocks`: a list of integers determining the number of blocks in each local attention window. It assumes first number determines # of blocks in the first local window, second number the second window, ..., and the last number determines the number of blocks in the remaining local windows. + * `global_block_indices`: a list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Notice that if `global_block_end_indices` parameter is set, this parameter is used as starting index of each global window. + * `global_block_end_indices`: a list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size as `global_block_indices` parameter, and combining this two parameters, for each index `i`, blocks from `global_block_indices[i]` to `global_block_end_indices[i]` (exclusive) are considered as global attention block. + * `attention`: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. + * `horizontal_global_attention`: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but also horizontal blocks +Figure bellow illustrates an example of `variable` sparsity, in which blue, orange and green blocks illustrate local, global, and random attention blocks respectively. + +![Variable sparsity structure](/assets/images/sa_variable_sparsity_structure.png) + +Further, we provide a `dense` pattern (`DenseSparsityConfig`), that can be used for the sake of testing while it represents the full attention. + + +### How to expand block-base sparsity patterns +Our building block kernels, block-based `MatMul` & `Softmax`, can accept any block-based sparsity. This provides the flexibility to apply any block-based sparsity pattern to attention score. To define and apply a new sparsity pattern, you can simply follow any of the above sparsity structures. You need to add a new class that expands `SparsityConfig` and define `make_layout` function based on how your sparsity is structured. You can add any extra parameters you may need or just use default parameters of the parent class. diff --git a/docs/_tutorials/sparse_transformer.md b/docs/_tutorials/sparse_transformer.md deleted file mode 100644 index 82bc93a88ef6..000000000000 --- a/docs/_tutorials/sparse_transformer.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: "DeepSpeed Sparse Transformer (Sparse Self Attention)" ---- - -In this tutorial we describe how to use DeepSpeed Sparse Self Attention and its building-block kernels through DeepSpeed launcher or integrating individual kernels into your code. - -## How to use -DeepSpeed Sparse transformer can be used as a feature through DeepSpeed, or simply integrated with any Transformer model as a self-attention module alone. Further, the building block kernels, matrix multiplication and softmax can be used separately. To use sparse transformer alone, you can simply install DeepSpeed and import any of the following modules from it; example: -```python -from deepspeed.pt.sparse_transformer import SparseSelfAttention -``` -Following we describe Sparse Transformer modules: -* **MatMul**: this module handles block-sparse matrix-matrix multiplication. Currently it supports SDD, DSD, and DDS as described in [DeepSpeed Sparse Transformer](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_posts/2020-08-00-sparse-transformer.md) section. -* **Softmax**: this module applies block sparse softmax. It handles both forward and backward pass. -* **SparseSelfAttention**: this module uses MatMul and Softmax kernels and generates Context Layer output given Query, Keys and Values. It is a simplified version of common operations in any self-attention layer. It can also apply: - * `Relative position embedding` - * `Attention mask` - * `Key padding mask` -on the intermediate attention scores. For more details about SelfAttantion, please check [MultiHeadAttention](https://pytorch.org/docs/master/generated/torch.nn.MultiheadAttention.html#multiheadattention). -* **BertSparseSelfAttention**: This module contains a simplified BertSelfAttention layer that can be used instead of original dense Bert Self-Attention layer. Our implementation is based on [DeepSpeedExample](https://github.com/microsoft/DeepSpeedExamples/blob/9e2c34e31cec99f7d5785c6a1a3b0854c322f883/bing_bert/nvidia/modelingpreln.py#L373-#L434). -* **Utils**: we also provide few utility modulse/functions to handle adapting pre-trained model with sparse self-attention: - * `replace_model_self_attention_with_sparse_self_attention`: If you have currently loaded a model and want to replace self-attention module with sparse self-attention, you can simply use this function to handle it for you. It currently handles BERT and RoBERTa based pre-trained models, but you can extend it base on your model type if it is different from these two. You also need to extend the position embedding to handle new sequence length; this can be done using `extend_position_embedding` function. - * `update_tokenizer_model_max_length`: This function simply updates maximum position embedding in your tokenizer with the new value. - * `extend_position_embedding`: This function extends the position embedding based on the current values. For example, if you have a 128 max sequence length model and extending it to a 1k sequence length, it replicates current embeddings 8 times to initialize new embedding. Experimentally we have seen such initialization works much better than initializing from scratch; leads to faster convergence. -* **SparsityConfig**: this is an abstract class for sparsity structure. Any sparsity structure extends this class and writes its own `make_layout` function. DeepSpeed currently provides the following structures that will be described in next section: - * `FixedSparsityConfig` - * `BSLongformerSparsityConfig` - * `BigBirdSparsityConfig` - * `VariableSparsityConfig` - -#### BertSparseSelfAttention Example -We have currently integrated Sparse Transformer with our [bing-bert](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/nvidia/modelingpreln.py) code that can be used as an example for integration. In this example, we replace, BertSelfAttention module with BertSparseSelfAttention. Using DeepSpeed launcher, you can enable sparse transformer using `deepspeed_sparse_attention` argument ([example](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/deepspeed_bsz64k_lamb_config_seq128.json)) and add your desired sparsity config into the [DeepSpeed config file](https://github.com/microsoft/DeepSpeedExamples/blob/master/bing_bert/deepspeed_bsz64k_lamb_config_seq128.json). In this example, we have used `fixed` sparsity mode. - - -#### Sparsity structures -Following we describe supported sparsity structures, their parameter set and the flexibility of adding arbitrary sparsity pattern on the self-attention layer. -First, `SpasityConfig` module, which is the parent class, takes the following parameters: - * `num_heads`: an integer determining number of attention heads of the layer. - * `seq_len`: an integer determining number of attention heads of the layer. - * `block`: an integer determining the block size. Current implementation of sparse self-attention is based on blocked sparse matrices. In which this parameter defines size of such square blocks; `Block X Block`. - * `different_layout_per_head`: a boolean determining if each head should be assigned a different sparsity layout; default is false and this will be satisfied based on availability. - -* **Fixed**: -This pattern is based on [Generative Modeling with Sparse Transformers](https://arxiv.org/abs/1904.10509), in which local and global attention is fixed by the given parameters: - * `num_local_blocks`: an integer determining the number of blocks in local attention window. As it is illustrated in the below figure (adapted from original paper), tokens in a local window, attend to all tokens local to them. In the case of autoregressive model, as in the figure, tokens attend to tokens appearing before them in the local window. And in the case of Masked model such as BERT, attention is bidirectional. - * `num_global_blocks`: an integer determining how many consecutive blocks in a local window is used as the representative of the window for global attention; illustrated in the figure below as well. - * `attention`: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. - * `horizontal_global_attention`: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but also horizontal blocks. - * `num_different_global_patterns`: an integer determining number of different global attentions layouts. While global attention can be fixed by which block/s are representative of any local window, since there are multi-heads, each head can use a different global representative. For example, with 4 blocks constructing local window and global attention size of a single block, we can have 4 different versions in which the first, second, third, or forth block of each local window can be global representative of that window. This parameter determines how many of such patterns we want. Of course, there is a limitation based on `num_local_blocks` and `num_global_blocks`. Further, if you set this to more than one, you need to set `different_layout_per_head` to `True`. - -![fixed_sparsity_pattern](/assets/images/fixed_sparsity_pattern.png) - -* **BSLongformer**: -This pattern is an edited version of [Longformer: The Long-Document Transformer](https://arxiv.org/pdf/2004.05150.pdf), in which instead of single token-wise sparsity, we offer block of tokens sparsity. Parameters that define this patters are: - * `num_sliding_window_blocks`: an integer determining the number of blocks in sliding local attention window. - * `global_block_indices`: a list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Notice that if `global_block_end_indices` parameter is set, this parameter is used as starting index of each global window. - * `global_block_end_indices`: a list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size as `global_block_indices` parameter, and combining this two parameters, for each index `i`, blocks from `global_block_indices[i]` to `global_block_end_indices[i]` (exclusive) are considered as global attention block. - -* **BigBird**: -This pattern is based on [Big Bird: Transformers for Longer Sequences](https://arxiv.org/pdf/2007.14062.pdf). It somehow combines the idea of `fixed` and `longformer` patterns along with random attention. Following parameters define this structure: - * `num_random_blocks`: an integer determining how many blocks in each row block are attended randomly. - * `num_sliding_window_blocks`: an integer determining the number of blocks in sliding local attention window. - * `num_global_blocks`: an integer determining how many consecutive blocks, starting from index 0, are considered as global attention. Global block tokens will be attended by all other block tokens and will attend to all other block tokens as well. - -* **Variable**: -This pattern also combines the idea of local, global and random attention. Further, it has the flexibility of defining variable size local windows. Following is the list of parameters that define this structure: - * `num_random_blocks`: an integer determining how many blocks in each row block are attended randomly. - * `local_window_blocks`: a list of integers determining the number of blocks in each local attention window. It assumes first number determines # of blocks in the first local window, second number the second window, ..., and the last number determines the number of blocks in the remaining local windows. - * `global_block_indices`: a list of integers determining which blocks are considered as global attention. Given indices, determine the blocks that all other token blocks attend to and they attend to all other token blocks. Notice that if `global_block_end_indices` parameter is set, this parameter is used as starting index of each global window. - * `global_block_end_indices`: a list of integers determining end indices of global window blocks. By default this is not used. But if it is set, it must have the same size as `global_block_indices` parameter, and combining this two parameters, for each index `i`, blocks from `global_block_indices[i]` to `global_block_end_indices[i]` (exclusive) are considered as global attention block. - * `attention`: a string determining attention type. Attention can be `unidirectional`, such as autoregressive models, in which tokens attend only to tokens appear before them in the context. Considering that, the upper triangular of attention matrix is empty as above figure. Or it can be `bidirectional`, such as BERT, in which tokens can attend to any other tokens before or after them. Then, the upper triangular part of the attention matrix is mirror of the lower triangular in the above figure. - * `horizontal_global_attention`: a boolean determining if blocks that are global representative of a local window, also attend to all other blocks. This is valid only if attention type is `bidirectional`. Looking at the attention matrix, that means global attention not only includes the vertical blocks, but also horizontal blocks -Figure bellow illustrates an example of `variable` sparsity, in which blue, orange and green blocks illustrate local, global, and random attention blocks respectively. - -![variable_sparsity_pattern](/assets/images/variable_sparsity_pattern.png) - -Further, we provide a `dense` pattern (`DenseSparsityConfig`), that can be used for the sake of testing while it represents the full attention. - - -#### How to expand block-base sparsity patterns -Our building block kernels, block-based `MatMul` & `Softmax`, can accept any block-based sparsity. This provides the flexibility to apply any block-based sparsity pattern to attention score. To define and apply a new sparsity pattern, you can simply follow any of the above sparsity structures. You need to add a new class that expands `SparsityConfig` and define `make_layout` function based on how your sparsity is structured. You can add any extra parameters you may need or just use default parameters of the parent class. diff --git a/docs/_tutorials/sparse_transformer_results.md b/docs/_tutorials/sparse_transformer_results.md deleted file mode 100644 index d71d836aff6c..000000000000 --- a/docs/_tutorials/sparse_transformer_results.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -layout: single -title: "DeepSpeed Sparse Transformer - experimental results)" -excerpt: "" -categories: news -new_post: true -date: 2020-08-00 00:00:00 ---- - -* **Power 10x longer sequences** -We have run a pre-training experiment using BERT model, both base and large, with batch size of 1 on a single Nvidia V100 GPU-32GB memory. Following table shows maximum possible sequence length for: - * original dense model - * + adding checkpointing - * and replacing self-attention with sparse self-attention - -|Max SeqLen |Dense |Dense\_chpt|Sparse\_chpt| -|---------------|-------|-----------|------------| -|BERT Base |4k |14k |39k | -|BERT Large |2k |12k |32k | - -* **up to 6.3x faster computation** -Further, we ran a pre-training experiment for different batch sizes and sequence lengths, using [BERT base/large](https://github.com/microsoft/DeepSpeedExamples/tree/fd869ae1c9de686f8cb92413efeba83fc989027c/bing_bert) model and [Megatron GPT2](https://github.com/microsoft/DeepSpeedExamples/tree/master/Megatron-LM). In this experiment we let the experiment to continue for 100 iteration and recorded the average time per last 30 iterations. Following charts shows these results in which we can see up to `6.3X`, `5.3X`, and `6.1X` speed up for BERT Base, BERT large and GPT2 models respectively. - -![st_bert_base_result](/assets/images/st_bert_base_result.png){: .align-center} -![st_bert_large_result](/assets/images/st_bert_result_result.png){: .align-center} -![st_megatron_gpt2_result](/assets/images/st_megatron_gpt2_result.png){: .align-center} - -* **higher accuracy** -In addition to lower memory overhead and faster computation, interestingly we have seen higher accuracy and faster convergence. As mentioned in the original paper, this may point to a useful inductive bias introduced by sparsity or an underlying optimization issue in full attention. In the following chart we show accuracy of fine-tuning three models for long document comprehension. In this application we use sequence length of 2k. What we have observed, pre-training from scratch, sparse transformer is much faster and converges with the higher accuracy. Further, fine-tuning from a pre-trained checkpoint, we gain better performance in the point of time and accuracy. In how to use section we will describe how to extend a pre-trained model with smaller sequence lengths, to be used fine-tuning with sparse transformer. - -![st_deepthink_result](/assets/images/st_deepthink_result.png){: .align-center} - -* **flexibility to handle any block-sparse structure** -DeepSpeed sparse kernels support efficient execution of flexible sparse format and empower users to innovate on their customized sparse structures. Currently DeepSpeed has added the following sparsity structures: - * `Fixed` - * `BigBird` - * `BSLongformer` (Block-Sparse Longformer) - * `Variable` (Can be used to simply customize any block-sparse random/local/global attention pattern.) -In addition to this list, user can add any other sparsity structure as described in [tutorial](https://github.com/microsoft/DeepSpeed-internal/tree/master/docs/_tutorials/sparse_transformer.md) section. - - -# Comparison with Longformer -[Longformer](https://arxiv.org/abs/2004.05150) is another sparse transformer work that leverages the idea of local and global notion sparsifying the attention matrix. Local attention is satisfied through local sliding window attention, and global attention through global task specific attention. Longformer has been applied to multiple downstream tasks where it shows superior result compared to SOTA. Considering that these kind of works sparsify the attention matrix similarly, we expect comparable accuracy result. This is what we have observed through few experiments that we will show in the following. However, we have noticed higher speed in DeepSpeed Sparse Self-Attention compared to Longformer. -In the first experiment, we have followed the [notebook](https://github.com/allenai/longformer/blob/master/scripts/convert_model_to_long.ipynb) offered by Longformer. In this experiment, we pre-train an MLM model using RoBERTa-base checkpoint. This is done on 8 GPU V100-SXM2 node. Following table shows the result in which using DeepSpeed Sparse Self-Attention, we see up to **1.47X** speed-up. - -|Model |Window - Stride |BPC |Train Step |Time Per Iteration |Time Improvement |Accuracy improvement | -|-------------------|----------------|--------|------------|--------------------|------------------|----------------------| -|RoBERTa Checkpoint | |2.5326 | | -|Longformer |512 |2.6535 |0 | |1.47 |1.01 | -|Sparse Transformer | |2.6321 | | | | | -|Longformer | |1.6708 |3k |1.6280 | |1.01 | -|Sparse Transformer | |1.6613 | |1.1059 | | | -|Longformer |64 |5.7840 |0 | |1.31 |1.46 | -|Sparse Transformer | |3.9737 | | | | | -|Longformer | |2.0466 |3k |1.4855 | |1.09 | -|Sparse Transformer | |1.8693 | |1.1372 | | | - - -Through our DeepThink application we described above, we also checked the inference time for different window sizes testing BERT model on a `2k` Sequence Length and batch size `1`. In this experiment, we noticed up to `3.13X` speed up replacing Bert Self-Attention with DeepSpeed Sparse Self-Attention instead of Longformer Self-Attention. Following table shows the complete result. - -|Window Size / Stride |Time Improvement| -|----------------------|----------------| -|512 |3.13 | -|256 |2.29 | -|128 |2.16 | -|64 |1.5 | -|32 |1.24 | -|16 |1.23 | diff --git a/docs/_tutorials/transformer_kernel.md b/docs/_tutorials/transformer_kernel.md index ce5955e0fe6f..7c0d622ec8e5 100755 --- a/docs/_tutorials/transformer_kernel.md +++ b/docs/_tutorials/transformer_kernel.md @@ -19,6 +19,9 @@ training](https://www.deepspeed.ai/news/2020/05/27/fastest-bert-training.html). To use transformer kernel for training a model, you should Integrate DeepSpeed into your training script using the [Getting Started](/getting-started/) guide. +**Note:** Currently DeepSpeed Transformer Kernels do not support Sparse Attention. To use Sparse Attention, you need to disable Transformer Kernels! +{: .notice--warning} + ### **Integrate Transformer Kernel** First of all, you need to integrate transformer kernel into the top-level model. Here, we show an example of instantiating the transformer kernel using the Pre-LN BERT-Large configuration settings. This configuration has 24 layers with 1024 hidden-dimension and uses the sequence length of 128 and batch size of 64. To add all these layers, we copy the same layer specification `num_hidden_layer` times with different IDs inside a ModuleList. diff --git a/docs/assets/images/fixed_sparsity_pattern.png b/docs/assets/images/fixed_sparsity_pattern.png deleted file mode 100644 index eb463e246282e6468e68c0ee880892e7ab519fd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51803 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

UK`ZW${Z~%bHYT_b; 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 diff --git a/docs/assets/images/sa_backward_pass.png b/docs/assets/images/sa_backward_pass.png new file mode 100644 index 0000000000000000000000000000000000000000..acdf9a26e0a5b7427fd9b9868cd8bcb52be77511 GIT binary patch literal 43362 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 z zV-KX{;-1+Qer# zB9-YZBnPiHE>9D^Q1+$jz9PxzCFWbg9<+)R3keL9BPU%8x;01r7I(8HWGO$s_RLhn zaBukHwcJr<2(Lc|B4RLww*~qAGf20J1+?pY+~WE=6ujb#HY8$9t-xUH<9T^Dm-^?7 zsy345BwKH~23uEh zCFDROYkRf9w2&VWQ`MD7N3X5j8teDM@&%>0!6ULQ|Ak!TJE)n3L@JW;IdiyjnDez2 zQ^`Vk3JQiqU&$gCUMC5~Q7@vp0AeIu6h~RMW-&xv^kScm*;m=RU>r{+ts_+RrN1&$ zIl&ya^1T&h0Wzt_+)Ae4A4JpyYnt4oJ>+ECFUW6Sw6tyMWO$CL`gKl*9E-z{IrxAY;m5)x+(?@5SKWt_;b-M?t$o?}P9O!OE?eC3W@l8gV=vNP*6)6>V{ z?We=Z97oP*qfmwtuZRGo{ufE680Or3S$xixB_GeC*QZfsVpcKVd@*7Qk@yigztc?=JtuI(2PW%Q+*Y$D;>AE|!Eq+=ksqs4%{alA#h<#vRONhF?%*ry65cJFV1{PAu*@JRM0 zU+u9f8Z-8Jw;WKR>$kS9C&#XOVk=x>#*;zC(A6{cT*Mvr@l}4^whPe|uNjzeJ=fY4 zGS_+Vxx0YMv>ezcuyeVMf!ZCZ2y0ua(%3mK?C?!z8q_9 zQvI3f;J}lf4<;jvmJdRqhGR|WGN`3h7BZA_;8|i z2N&x_u$|{FiA){`{*yfP$j%c!wmz1>H?Lx1`ihwlEktU$y>+fQ&=|j=-uzY%eRh`M z1`skJ$2>>4L{akaZQ$wb{UBB75l%jc+`S8hsgXDHo0~%T|1yVwmVqz=J=b@u58kg# zl?CzQPiv%!&0I;70eD@MxHjs?hjiqm6{h0uZ-V%c5oz7#o0V=}Mk7z`RaEMk@&9GA z6*NjLhRz~@p)YeXCms~8iC)n-8B>VhdB2KsTfS8VeZ~wKSERM_{&tMT9?t`FL!_VO zI|u?3y1t;-Y#ez!eLKdJ4frp2-5AUWB2^NJe_cttqsWBJ1PDhH5=9p26=;ggezu%N zl31sAP|;K=RSN90#UlLQF{ljaZFL`gNgMfKJ}4{sMP+2c?M+CthFRM^Hs55lzfT~K zyj~8g;>aqVXvz2g`3sBGVRNG2l)m!+WnP`J z%&b8|Kh7odeLtUiPh$)2_)5D2Y2S$44tA}qiT+pVr{o+Nnm=PT*fxR%4^6U{!cB@L zn)4mYBDzW8XrovnQG)z;-Xdst=v8U2<3PqfqQ~S(Ie;&*eVKFKwYhOE2sY+1d+b`X zf(DyQVRmuf8Z;*jJxmA$grbjl3@q!r?*_J&dISDmd7x7OF2&yLWkChJaPDCLJP9UdevN;d}&xKxw;6gzk`U1RS?;YZ5t z9%%ztXw4g^VSNJBn&J$dNSnXGd2CCMPvF3CQOh@s^@H~HM( zZwmC3RX8L&A-IMa^~yB%8+%v3nZbUSSd|b+=Tn)kM-!eRqK1?sEiCLPbs1P^TUwdb=)snFX)e<3yvWHR`Dh{olQ5CF}ki?mX9;O?pF53kANEIIMfS z^eOf8>XuKxN^wyE$h!!ELCO9DY`F+o40{|Juxjh(;{IPum+9sl$MxYoyX8dWUkl=Y z2-yFR^w$3uO{aec^b;JjWi*MhxAY<|t7u}NzwO?0i{){uSwDUl0wkmoVW3rgm2kB9 z!*D6vRnHHd*6Q6m&9wl_UgvMV5w(`1zs0`$&+8h^XEBa++*o>$3f&F6chu z?k+&+v4b%&i5pXeJqiNp=~yv@87g#q9sB7ZX0ye-rkxJ2R8<2l9yZjF>k*G?8RE(K z+tr>UKRg_8HDk3%=j6b}5KSjF3?bBj&d!$X&MD{FZf+|Orid4g7>4gqy=fkK6P_J5 z$oq@BQ-s~j65%jgPkC|K)b4Tn;1`FZ?^+5Jx{Q!IG&30=ylyR zjby$)pdoB)H$Q6X4cnG(nt-5tp@11~C93~M!w6=ucMj^o5iT;)+79WP&7o*<+CdfU zj|qH;%24%9(ME@^IE#xm^$i`T&p0M0W#<{=bvNbAwf!OgSUS|~PTH@mNF?dm0%Tdt zhk0G?_1~pExKt*QZ7!Fc?k`9n5G?8*h83Sup`oB8zn2IDUt!Ks-x~IMr;{UIK5+aA9(`O*zWr3}RqA zscH#AeBeIo_My(Um?@)a&j%hkd$~QOV$qvWKIdBwxm`!N)cO~RO1v$;<*2O4H5+ym}Q=GY8R+7MIV-Ws%On{8S|@`V(UKlh^mwAOJp@ zjkw9WLkOlhv0#XA&T4yEsvixr57WF4v7h0wUJsjg#PsZ;UeGO;;S%NR^B{Z7qs1O- z2bID-iAPsfsMVO0xY0kWgLlfgi2fp!cA2<_hE7$UJdi%xomu*hTkYz)B&~Ri^~>&! zGDYG;Z`k(3eAg7duZXM7i3@I z{XRwU?Mw-D+O|%vLtWS*O+(nMtI+CVpyOIdfEHGVkU@R82n5Vav_W7 z-SC=DaVg>BKOO$QcqXV+$7el(t;PTO8@r3!*%g=ZaTy#oJXpXmv9i0T0TrBKrg2<9 zW~XR|zlI;rwjt_&th^U~eejXOO0ZwdsdeX^v)vfC*)8W|tl1vZgM2)E<_Qc%y{~Vn zFA~A?mlbv<7Zyaw3@@Bwd)G`{9lz8sA~Z~gP2*l27;fJY)k5NaDGZK>{cbi}3R4=TS6ad_XV2IJ@wp`L*;_N#8A>uQoJy4Guw$@Lc}^vj3QVSC!ar z=w~VXL~;n9Ta%!GVr3x1XwJ$8J6Z@&E~W9bdJndh6f9@Z-mvmsK#^yzO#23SB&XyS zaKVW<`$`k(_1iLH-Ax+{tD8f-WJw`vlQJJ>P6vm9F`P?<-Sxe%4%SOj84Okfz5|KP zj0k(|v=O4N6}Jvyym^KY_PrzR%Q!}sVjE75lnj@sqyBBiAWMtyUS`GG?N}F^7N1+2F<*e)C;9cKEg;S1S=0 zQIzZX>e}-AOqX*gC#?Bx$pKBdGJi9_5lOv5hi&ZWM9o%mwyVWVQ|CCv>BZ0zl=90@ zE9!m4GuEwY0+L_Zjq;d+{M2ENb^~6r)*gK`Dn>>zdW$pEexGohw^mq7MFSOwCGy%0 z_=1m-gXWsu8hL;r>{=m9Jeif0;>!x=VeY;KpIr8F>6*V~(gA?| z4SM_o2*T4LV27D~MuUh&^i!&Hj9tucME}a83O{7~JIxV32_B=sRBTrN>NZq#k>$kP z600uM#)3v70@dP5BdACx9T!BB5oU=kd!bxB4#U*X4|A!v^^?9{P06n;tr4SsF>@AuTeo<(K5_w76rRslRBzxP)2pWaX8G3d zX{1Y^QSt2|TsjS~Gw65GkDb+sxsqhtva>wgO*^+7tAyxTUY#FaTPJ_wrr~KV zr<2Z2!mpN$2_kVFmk{pW5BH<9ml-(e^KTZ>YuyYc)UwC8Qv4|?r}&t!pH&TA(joXHYc zxz0CnM|P{m@xIw-zDh-FLK|a_`=`dwp%NQ&DX$B1G9mRw5Vd5_*G9$9fmKcS)jSOX1mR#%P{iImaV-SE! z+AmlGa@gG{W|7`3&mUn#&d5lMMEH(goTl&O!(K(o@siXr{#=mN)BY^N(mT8U z?apI*%?PL04$aIg9&?oHG>Lg_=HcuLWF@`5@jRA*4pYW&mboYv@INB6U5NN`OVB9x3G z&e#JnKK|u&8%J`+XcbB%4}=i@)jPs3b`B!aC3;u=eoE1qEw;h2RU~iLcZKOHG_PTJ zi3pi1Gomn1_=8!jgDq-gO#lwCVmT>{*`#P~!XGwJw}q4hQQeOH=Ey=UHcK#>Yxxks z1%J-bt;o_QPIxG=LI1+;nDi`R(XG{IY6Bs3bzKH*34j(chyHkn)a3wPNb+h8R5U3+ z3lUJT+I8>aX3*^@pdArA4mo5V!K3&lJUqlOxo&zvO0lU}BwmQFh4JBNI#|_qblpBg z@usQC*Xdz2^F@}Cvli1w+R6(3*5*@8YBEaYzMV@BURcu&#^&}$)PzMm>V46G;HxyQm zo-Qjq>7+DwL)0cmI2AspT`iPi5BfxU|4s=9wbhj3MH+XvUF~UKbvRpur7R5-EX=dh z>Z(x3XGdy9Y`)m?4rhI9^C}^Ub;y+*;|Sr5=C6HKmU)1Zoybt6JZ-ZsY*+LxZbvSf zB(V|eB%UtV19rw&`LsUUuyTk$abFzZ6oC(njF+v{O{eOy9mY)+G6ADB z@kL6aXE4VJKE}+<&4J68cnd8?3brAjL{H_<*lzoYfTuXm|BRuSS0G;FQ)kELM>KzY z;Nck)d>nhzf2uGLA46`fwUdHNZszx-M4c4O&gRLsYFQN}zP zMl#2T57o6sd@+KchDjhs>|bBBa5d`iEr|ks zFmZ+n0&c7Ih`FsK#MT!6HfFnLYk_#3yV+F~lDzdQFdOs9wIL@ae7_oW%k-eve~)Wn zpW4?aKf3ghojCFxlbCBAgHhL4mRG!qniu<9NB>W8=N%MP)3$lxL2?EOA~|P4a#V7X zsFE3!K|pdIU_QYmyZD8a0J|4laO7T zVHI7$FW8x>$nz>oNON4ee$OyP4sVWcVGd?zS@2Y^P>EHX{%LhS9c_C>Q~rly^HAs^hglo;YHb>N;Or?hNzFIA{^ z4MnElLXFLhOm{WVWEtbiom6FfwBWL_dAMM!`k)4wz@s}2JfnF=id2@I#$3Q7K_( z`v5@}in@IPQc*mS4!E1M-n1#I_wkY!e z)L9V=$vyF|i(qxMZO6D|ja+#kJ-=YdkmqH-ru@+GUGlqHAHqUr%qROI%J2fo%)Bzx z%_#}q?%YO@4Joeq zj$Ah7{odWS&_$U<6WaAPAGCW!Hx14yifh)=S4g@k%u)qKEwAnhJXi^MqU1d~B?fTw zuA0X78>%W>zUz1DPrFVN3t6aC8BBpHhK2 z)vgUdwllKh>ok`oz4Xg zWCd-e=F9<`$-V-`ba6cYnSzt)(`141Y`IwIc)Xuz<+xH5>y>%25?{N&jF-}1!9@4s z4=|6i+DjW-sI)AVZ0xB%rAiJk{hxFON#QSSj!L%jM%8Vze8Lnd(aT z)IV2R8SZ!*<>OJ;%r4zz)BPkJf=KM6psO#6MT=A8$P z)lJm@QJAy~5E#Du2Lt->>b1k`?n9Ch?+M3S@4!wx({M`OxQQ6to2F!ct0YSL1c zT2T3dCzU1(XzGqtAh=2Z;5nB&d?7To9GzkmEaU6G-5*I7J>JGXeKdZ>=;idDXse45 zBmkNTI`S6vLj|0v3Qxrs3b$7MQaE*D9}KPHYNBw%*q5#Z<0RNNDk}A97epe`aC56tlQhuAAK8 z5nV@=6WZ0c+{p&@4!0HYG!ylly6RddvuyB(CUXCpXn8C|JlyJ~) ze>6ZrU@V@wj10!pwiPGw)P}hB9gLO@EPL>jLgA{T!L7>wkoJE}tnLaEHCM>VJe+-_ z_iisaKcMIOzT$bWqz#!YHk|mB$z?=bM*GuIo0rOy?I`S4mS0WPCp#It%9d!Rs)Yk5 zD0{N-I8N3MLF7dB8+m3n{4-*fl|d2q>0jeyG@&%#T>YXzAMj|d)Eg6tJBx6E>@P=c zX16&%H2cq0an+`GfzPM$zhpYyHj} zBc+$_z>b0uaeWgc^1AxYzzpl@t(mh)w&6qO5XsKe=O=4?*#e7$bqLOwYp>-%+|nNo-G~F(Livj40tcga9+POhb-z&YFGope|LZ>A|dlU9#8M9@;)0h!%p*YI2oFX(;<>&rWdAs?0fvUs+H?e(PGu9yz>>(M8dgtgx+6fi)VNT z{I60h_W%ppKy^wa5ap0PyO59>ZIf8=09nZPzkB1!6zh_e3%``9j-fZw9 z0Y+5*`vbZd2ppp)YG!wvYa3$T;~bEunwAJtp*-PHL=O2J1+{E>%cpR#My2)v={NMl zKZ%^fH;k^%93LWlP}R`o`nH1kaHi(f$LZBUHFf{k6v8ZiNHXu7%>fcisiX? zeEJ=bYAn)E5o~HgJM1~HR?NR-lJy68pYqX(cvG=B!4oF|L>YJLASrZE0KM zz0{Y@UK>l&-2aYHl%RSP5KPH30bf#ns=^)>yOdS4<^UNREDqmkVex_HSZ!3ts$ z!8eS?TL4xgcraEkl+4I3I@z?wV;k{M`_ilGis?AT1ydFxjf&5H;2Rw`9AH~6NFT@qH+3maOE z1f^~1J*v=e64uf^?A|oUEM_1Ak>kP>|G4Q7+)#|siawVOQ z!-nHXbi0;slS^s_INZdm*)gafc0{ab_?ZrXFVPCPbLB>kV$ul#&*TbLcc#zF6=ak* z#^-nZ0VBTOI8Q2SDykC$jl<|#-KUcS5$r~X1+hJ!)eJBOMqDh5;cDz*9(5)4qcjA5 z91XpGg*@+LCFLpz=VxP;-Yy~PZ>s}-=%!m-Gw-_gtN;$x1~oXuNv>66&f@A**~6?n zm?uEtdK@?!<(Y`@DPW-m}1j;u<~)S z4xB>2OXirox1z_@ab&s+3->2jC;LdC=>ze1rVk-!o^!NyZe$-%9L|H94vM*)Gnie8 z+Tr*iRprT5O`-OP?L1c!z*j|~7hZGPEq;x@WY9m}`B^K^=;O+=c5YVRtwx^D)%o#fIar zMvw=S$mq*=2N$2^^+%#omDNyu9i`rLyf{$6fG454=%i@dA9Sx#QpRALS*?qgnCkgySVvqJ=w70v5QrYUe|>x+QtRTmb;nwR<7Ns2^wNUx0Oib)Ro* z0L#!(F;6jOo`%f{F=ijdJ{;iPe;I@CYk!#~AhSN8U!*cebLy|u27&Agi*;FS%K1{3 z!e#T|cJFfx>z0Ra%q&GQRJeNT?Z_{?nyV@K{<{nsoWKTsBMy3$UbJI_CAYwdgY@YXTVHKD1=5T_Pa5uTreN>9jw{r$<@V`L1yzj z0H*CxGjcjPuRIn_3)Xgw*-@R|mzK?;au1aNTv$+kuEFO66%CUc!9(VK*l{&#vd>0V zq_M%n4P5KBqqs?&Rm?Tq&WBXQh0^D0{HKMhTjTg)(|EfqSa1$F_GtVoA{P&<9kXK# zlF#3_)bH$h2zZP5UfaX0;DCCy8WO6YTqrxUy8y7(d_UHm*McAl55IcA!ixhrAO~`!F5p~=Cl#tSxc z>}w#gjW(|8^J9P6eII|;uQxAgk4N)EFdE-TP1!zE&#(W8Qxk4iR>p56Ox8^st^R7v z*5d8?J}p_9Dmvh3$4fv=tWfR@LG59OZ)<~KxXXyj)ogQ{RVI>MfEkeW?jON>s5))C zLl~L`#Yi)kbdukCmWPI1`OBc`5fkO+rLcX1#V9;>kzMZ|=5zV5hu>9H8? z?3OKPd*U%TLSuX1or15-(VEE(?k}+wUzAXBpi3`Y_OW6rpEgNsjv?}UP^*JJT1qh; zw=d5~C_an6v{uo^>m*j)eMvL;8S0iucW;o3asTdWtbIC*5pq22ejhe2q>(3R2eSV5 zbefJktV((L5HherFfv8QoFkKmH`Y^~U3uQ=(*jzDbG(0dHS%_(sP(IyNp>2I&Ko)H zx9qy_fFWr8O%AV^>6vzlf)d~{{tz8ogc*Qj`m2#l7Uxx}HMmi#0jBSuXIU0)! zp|j$6xw&S5Sh`NmE)RfBs932a+&qkMTsb}xdDwXoY+P@}uGPh}`!?L0`FeYd^v!7{ zM}nZNTt7Vxt>dXwn8N+%vfeuOsXry6)G4c;4^V`=LP=x&zHYKRw#xs5znBJuF$EAW z-Mm7)2M)5ZZXg=JW>Y+xHYttlv(_0Qg*5;2e#wp0ztKzTw$q-FMDXHKoLqN<(=3v5 zU7I6+ac|5OaAL}llh~q6Z#`%K@x&xP4<=T1$^N=^<)c#1W{6c{P_gpusPl3UTl%}l zn>DhDDSt;u>MYW73{~owCF}V)6Z&!ePb+&ua~^Y45p3w&S)5TF@f2pJ=7k4FrauXh zFB^+O%T3SX-4%O2%#y*_jAbiUC>YxWKJtyAI`PpPM|(pMQ^;+G1ZGLkE2bx=l0lPx5 z1ynCml+neHI3DjVZi+sG55Wanj7dmo^m2a`Gn~<@JUkbc7SoMoMxbM!$oqdIQI2U< zS)zxHvzx6;h;dnR1Iq^AjMAMv0GkG1_z=lkq#H{>B%f z<#`heY6|sRhzlwFH2EJ)?}ctq@O2y6=p;H>_tpEg8D#@BN8L516GZw%`gRTn8V<@rUCfCx_B}-v_Y3tY~s!=y3{qd=@|p7h`#qoO~!ZR0Yy?Uwt~Li@GIar8Aq@ z(F&NE9a^*JiT%1otdOu1k;NLeNAYu&vUtYFqft#mqM@pG?WU341fvaF$MW0HsQN5= z{#EPYCs|~h%pM}r#(%|4{N)M+nj;4+8+*gh#)(=r`X=d5KLA}p{rN}KL&~eJaY8?b z$9#}Gyp7Fb0;HOW?svRM+IUW-k=P!l?%)WV=;8-ULy4At;J1`zx<%nEx2XATJm_^_ zg$+C|n`8HWq90!xk*V_ToxAhE{e~QO$6;H6DOVh?I%{ikQ9&;?>@A(=cbC^(KSCb0 z_$6$mF$_r{-~C)A#%Wbh^<%Bn2Q{c+EHUBbdMnIhZVmys`gRcsX$MZnw$2mw1k0m3 zhtG&aMH`;l&y>Ge$xUF%)cw}h@1fdXKI8>rml_Sqh4 z;58rU)mwAj&7m?#C3N2CY(4e|&u2{qfbpxadCf$o*5<--@2lqu-5+ao!E@ z|C_0X5ynIs^)YHdkw?U8MMa=?>ow{a(EoCcfy@>o{E&h#8b--#`IaeQ3ZF$)gR zGQfCE$9?$C+@r4bjuv&%gj-y6$p8pKHBRfR{eX$hWkV}xE1-x!oI>j2qQL?r-uX%s ztwg^!()G!H%TePOk4vJA)sDqx@bz9-+J^mII*g?_01w=K=^6Qgqxqd#t63(iBE&5j zDj{qcgra`3aqL$wxtpXbIt1~wsKoXr7@ zBJFS9BWc6s>dmS@-s-G}%57OmN;7`A*+3Sng%qahQVXQ&W`j8hr2*U^5FzNwz>v@u z^`95SAQU^u2{0f?R7D(S^|f*! z4WjLzZj9fz3FfhIzi&tG)#4QVau0Sa;Qhlw+O8~#QRY}@}H$P z<6S88o^HBu&KG{;E4DZcrzUOIh?sA-Dv^jG0{x)aEhJ#Y4g@A00kB~M-pi6y>XtKp z^#xk((dKClo}UFW>-m0T&(?*1&v$U4v3 z%^oORt1cNDBTfcn;N$;!6rFG`I?1tezHgO}aEQy=X?NTUT0OcnAq1VhN^tKUdf*RJ z8amaxE=Yo1rioF5wQL?2Cn4!RFgx-eKfV~L#5@N|80_hrf1a^fS0#mA zD)FVZR!rOT^u>*h9`laUkeJ>2P%g# zdufhFQ|P*;D0#zLpQuM4&$T+gK0K^#`T-QBLHwtvApjaHchYO9&^Rxx`M8#MBmc!0 z)L9UT-tjd9FLY1VP-5G?Sg{sV&wqP8(>U|TCf4+3+A97DB_`yNe?neK^@(cjN`_MC zaw(8EV>drZZ=KtA`CMb~JZM6|VJbw3-dh{;5ygzgJJVMCaa+b`|K3^suY-U?x+~EB z=odq&(AQGf+mmoijTrwldjku$T4wzKHG3gb{N)gc^E(i@wnG~t4!hT}ld<9_F@n1a z3-3_wPF;t230p(i zU$cfHD*>9kNm+K7o=gV!cNgI{8|k@{72ulC4J%JL)w>YleO+}xEC4fe8=ZADy-}S=6+#m1>jg2`0_%w3!cc%^vG>9;m zTsq)YO8fi9fw6(m{R|xFC?m6Gp!;jg$Omv0!y~%GpwYgXT)XdCe_&S+v&RgTFuSF& wdq3AQy(Iu5hAHCWe=Q3G>&5)&9@ckF#v%6=b@-fw^ak*!sj90|u4EnjU)}S0U;qFB literal 0 HcmV?d00001 diff --git a/docs/assets/images/sa_bert_base_time_result.png b/docs/assets/images/sa_bert_base_time_result.png new file mode 100644 index 0000000000000000000000000000000000000000..958ed8d28b76414e861e3e0f7db6ba72edcebb1a GIT binary patch literal 65509 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

tK??#0 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 X7XNsn&LR>l%t!UPmLgi-3h}=HULt1N literal 0 HcmV?d00001 diff --git a/docs/assets/images/sa_bert_large_time_result.png b/docs/assets/images/sa_bert_large_time_result.png new file mode 100644 index 0000000000000000000000000000000000000000..400a591be1e24be6a4506d09cd11dfbfb511b584 GIT binary patch literal 60952 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 literal 0 HcmV?d00001 diff --git a/docs/assets/images/sa_fixed_sparsity_structure.png b/docs/assets/images/sa_fixed_sparsity_structure.png new file mode 100644 index 0000000000000000000000000000000000000000..5352f0d6067b182a1522aac68bdbe208359e487d GIT binary patch literal 70347 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 z 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

3JQ5VqegKKmh_6Nta5O5p! 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 qd#Q$Sg%6I0sB9b;B$ol literal 0 HcmV?d00001 diff --git a/docs/assets/images/sa_long_document_comprehension_result.png b/docs/assets/images/sa_long_document_comprehension_result.png new file mode 100644 index 0000000000000000000000000000000000000000..c6a23bdccd1cb6b55a50b5ab94bda1a7bb418cc6 GIT binary patch literal 58951 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

0-NR4e;U+BPTiBh5wR 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≦qc_r0Fu8i*xC@8~rHrfdb;+A9h_+X|ezH`S7MOBd$Mv^Q&quzDN zRbYz@+^Idiv7>!Sc7&aOcYXY(Coy75fOQ~5rW%JLED(nZgVE(p-VmugkA7hq95>vpdQ=R|ss&~T zZI1)nxhBaZIg7h5E!$4(<3OPDDOX(EJ?tZtG@-@zdbt*^NgWK)M!#9x6(n5UVJA;jJe8&33+s%b6Gu znJCr7yxmX@p{s=Uv{JjGE1g%{$84^z=u49;xD-6=?1fW5R#DizJs1z!M{!TQ`?A}I zSTHEo8tu%?f&R#7$sR2-Ryh`QMBr;H>adz*;)=tFTN=vW#QQJRB`ur&(=&Z>$9#5N zl?f!OXAw*Ud`4ifCUh51b3}Ec!i*EX##|hZAg%>obT{Nisc^e~1Rip%!e9~TkpJo$pNQXf7!lu{E+xgG%b}^G;$qB!Fb4D`y=bD`$e#X=gI&F zXcU2yE{0^7^BYs?h1bHW7T~1JZiMJG{(sE?vs6&*)0QK42dN=uB7Jn zUT!;PE)hvQZ-K1iK=cS^`ox5;S&*htXKn};-1*K|;oz}~!ztb4yyxM_Rb^Js&X>*X>o=I#xTKx*wQAbso1k zo5$tgsT;A8%xM1d#%}-DUo@z~&*WpeY(%$o>!jtenC~7UPa#qQrMqZT zLDTx)HMd{OX{1$;`tRq6$=rK7IKd}0;e;NudAw0Oko7n{iTNAxXgv{SD6wC~`t}Yp z4i=+>3|ex*tV>(0wL0&>jc%jE=garZ(Z;6s++^e?*;j&G&%=pK7^Fv}qZ1$ZjY;)I zwhVd&3l`G|X))4Mxg9v*BtsMFQ~77569Q0ke{%8bjeR(N#HOy!MJqRN_+&J&+=Nf@ zPZ)$8^)yHL$2}gYzC@3~IXz&##KIz?u685Hp208Aoc^KjvWP!Kyy`7C#{XSh{7q(! zpkE{T9e=xGRYN89JK@HVA}9r+rGnV2;jyMfQc6_pt$zJ)jkoTaKqM z;g*My{W?>38lSJ?a2%`rk0JEzJ+$C>?@!dPo(s)M*t+O(w&`L0K1dEvWS4bu54d<; zR+i8@#qcBp{!&y=D#$M0$aJ>^r^69fvUpOIu;(a>JSx8F6X*kgK8NnZoj*Q{C2?1H zy4PNcMqwIigHfn*hWqJ$bz%&wG8kOuJS(mZNoB@Kt+V5wEHhMtjxKLO!r^=5$4t7Y zve_eDEuN`-Wd^YP5p+30X#_2yL_T$U`~WnPpy}K(#Rq$nt;i;dXCtLH(Uw-UDv74^ zn=172!wfIc@8MA@6xp8_Gv5^n!b_zyjVXCJcN*O737yjxTN&`|p4sV;h=$>46Y?TZ z3t*$%aJp9cTv_LBq3(~pXnKHwPA;V-zC|<%-Yn;PH@7AdxHGcWC1V71o_|1FDn6QU z)Fz{LP6G@3x)COut@*6{{kk6>mn4noxEQYwnTm;Sh8kjFw|=j14TK|rEVv!?*fki5 zys<=du70-$$tGr;6iW(%TF)RiLAPC0XXR(-Nvd;l#_(z0m@c`N${ zq&(5SeXw03)=xo3yCbe5@=WWXfn3eS<<@r}$U&Cv)L1g>>C=f>>@-5&+Zru-H=hFk za=AJyG_59=i4;V^mGfX4<)RJ%ya6gja_u}>B`(>Y+?BmICvebtWMky3F}wBSD8|)w z;Mz?);1v*dqCK$YO`c9#E=J^*M`w<^Kx99=JiCGyU2Q3)sTys##jg3N7;)6I?WB9U zYT6gRP+w}}jB9D@{xFd`dGUKioLnn7)d6qg`{#4hIlPn8wms1F*8zZ6k=35~r%&Ug z_W}>F$hgbnxe7(Hn{CL~cmuNhovoP58y1Z`g&+4fVfrG>yT9F;YZR4uw(>A^8mG;D zA$tTa+^Dp)gBt@`j~@R!z@UIBM&{>1wb+7zsBBjPCmTsC1)7dPZQf>ooLuo~&+p?G z{xyh2?kpE@?f+ZXHmORm-4R(+zo_!?dJx`&$s7Q=?D##VhcS^Bz^emxx*F9g2f ziSTUWWSY_&QV+jpb5lBlCmQoL)J;|j5|WaNch#}F<|*UnPwP-7A8$^gm^XD{C2Q?>{G{LR8`;qxjRHzJfe4?DQ{suU!Hx*Ae+9WmibsR`O9ht zqB#2^8%(p?HD+gL=hue0S3vk%^JU{Jz)t>wvnnPu^C`XgAhvJ!yHQ= zfm;Hj3|S~bxRSR&9Wq%Mji-{ced2Q|`t``9Bb@ zS5UzEVryIKc&IhSzA3Mu9MKR8sOFaec610=DeKwMnB3TW9B{BY^i z*1>;vl28>E_6MKDBMMsHIb7A!JcM1_gk_s^)ot^s9Sc+ct0T#gLFr&HiK{=J-4s`G zv|JQ4RYH2jBBHB)FJDm0NNUF5(jD+sSfzmqi67&k#(j<#=9IO%>V`4m&ui~FoHRci z2*HS(S4@W}U<$sYH8=P-CM$n`$@T2~#RVFoULZRI!>~h6D6i}ZrDKKg>MH>`8?`<_ zM*#yEu6D21%+dKz8YVedji_0EH zGMNIS^Q0)4p249u{}4Pm`+dT==6f@3b>#+ApTRURUuvP_~4@b1RkpDbMzEE0i<%&e(eI=Ue zXsHCQUf!>oJojc)0DzcM^gT%ja`}J&I4}`otO2ecTwoPfI0SO477Se3Pp7A+<*AhC z;;8vbh4S6B-vFTTXDC%r$O*q{GiUAFb4Kv%MAt6l@x)I?j(_Dm$!b1VD)^VzVSM5r z7?|&6LDfvF?cvdcbP^U8rUr&#e9|c#au`n1(qSOeyR&0DQJci5>vM5<_;i=j@Zo9Z zU{ZLQySnxMxJRQj-7jp?CN~#8%naYCkBLf2;0fx}*XX3SKaU?!G2-QEY4Omjrx zKBYsI5}v0_wHb_G?ilUWk|3nn(yGN4$GVe-L7{ricli))y@#O`9^`byH5-F5BpgzE z00AAZaBh#|(WeHkUnOxkT?LgT)4!1YPRjhCjlIZtuDhAg&>Cf{r}xu>OEW*OE7L~5 zRJ~7)j-r4r8BUSva&>u9@hFvJv9qE%0hGz5p>J+4c7pLAkAor*K2F6YdC3qmT5>eq zTnS2{otB@QkH#X{9sWjb4?u0L*dB|DjQsAR2l!W$vFsnB5hVCbdVa^YLaQl4egOeL zl&9$N`Ru&vq%;%QAx5Hbuk2RE+>TmB5fD=uCnVMG*Sm6c6~llnK3$3>D%Ktt@nH#wqux8yV*d20WHW)C z^aKRg*}+$>M%VmYnT1<>os4B{wPufd#?QZBQczKuopXB|zxO=pr3wlUSNi*|2p~pB z_bP6>>2vrtemGr94uV64*~fcVjKO>L7fX7hLHvmjoXqMRI9olz6|OJnE{?lTAH6=r zd1?}-F`A50xLqzd_Gvks^q-VA+V9UQhTTBJ(VjPVr^AZht7Eh$^@W6<^8(Mb{ZJ`r zudA@%-=MX4rD-y~{w+FN{3C3;ef6-RHWdD0?tJA}&l|hl8Q9dDDqrmZd?^GXOTXZi zb|xo12Dh7;ZqxT2;b`R^Ztm_QMVef5fZ8!%YHHkBpO&`mi>1E0E0@J!vx)s0q2_AZ zQp08RQTyy*@x_YnO4aD=05sC@G#=Nt=_PAGm<9Mn5vyQnhkaJtO)0nI?e68uZ-{KO zGz@t`>-&cHw`;+MeRr-;H{TbN2cjxvv_Y7EE>yWBVK`XOwv56e;xFcKITZADv5gsr zd?^tXQKC5XQ)MZ2?#BhkqglA^^6Y$C-Im>G>`zcCm*cDE?;jzdshFf83+f@Cv?`n{ z^elLlvS0sDuU_oYuEppNk%(;0n?`^&tD;$ju-dUsnlD0$&WU6PFa&N&5dEmgp{UsynP=4@)6(kMM&|zAcP{<(uDg9bezozR{}Jc(0ZCTqc~> z9xSp0LpN25xhv9_Ka1yF(x2_mDTj$%(=RO9FTWq+R(9L^{lipT5DZ+$N!cxl<>loo zJTIS5!cP6{3WxY+*=FnA1_*#s8C`p!(lD;h=BmPR3L~1H~NZdWzee)V2OtM8U*n%atsn|FP}D?DmR~(Nz4yciw!gJXjZco;uzHF zl|1H>#K6%^DLO@aQb;4*>m64+LlOp)7_p0BY;TgP^`_%)x^`8fV!X-g z+52*C|5@y0!_D(}B6vLf_*^sPw~O}j@!QHKIYQJyXDorZ)15@|8e&8TtA{tnwCnm$ zASZeU^M_^^o#Z{vaN4Z);arm~-sB&n<;jV$meXXHWR>GzsKwuk^#AnH7GS@ssD~Sn z#-V^?+p7{YFjyzOXQPNdJYMSt^{GFRfc)lQXVx=yZ{vUq#r;i^A;{ZSD0Jd9^N>wx z>8F=AR|Yq5QRQ^32MFmCK}*5aa*HTM;r!ApMr2t+2DYW~{|2mEPK2QVO7s3)D%i@9B}X^fnT z%4gRXi8rR`@#%-q*hvUd_r#Z}L0M?(BooFyA)Ji0rJt~57WN*i?nQ9@_s6-K7rD-O zXAw3;@>;WQU@5_HZhpy@Dcs{=Dd>_@lhMYZ;zZlDurh5#Bl0QvYTFnjp-hb`lRpW^s0%Jna|#bAwahF%t*I4Ak{> z;PtUyEweqMs=!rNh>COlzu9ntbEyS12FSDiRcPA|~N; z*?QYp3+fmwvoE7IYoj(yP8rZjI0kjlm(!f4=L5g)kNxFNmkqRyITs>K27=GK7Gh(w zPBBsvecZ(Fzf7O^YT%=6Qc|tlEryL|nEwXUdI-_^w2B&9ful78s}RWH z3CrLT7R?xK;ZQQs#;ek2r zD;#ML)a~vwCkC5`h=wQ=t&A7FP>Fg^st4ZfM~%)HZ$IUh%~=wo*Yo{er&j9v`))2$j%M7^?{WhLhE z5C9!OnH1iz##=NUqdW5sD$2Z(RKWP4Lf(IE^$q+L-rhTAT*1ki!t01i^HoXrY`T;~ z*@!`UGYaojCd1%o`g~{wLYseRpiQft=(WZ*wF|P670C*&?Bt$uuU22RQ7oBR-|W4& zAmk*Dk;5EbOkL+904Y;uOIzBhsI~4=Mtdd!fp+t$!5P~Pd^Wx3lYLujv0)(W`GwMG zx@3jJZ4Y3ySc%=+<*Q6wY$&c%n=4lr_5ks-4&`mo=h3^P)O+~(3G{~VEa|9Q&j?sL zm2yYJ`zl@3g2E&Lr~3=+Rl`)`;Fh?Ji(S-_Sh{9?&>&69>j}df;}%s;iTl3r|BWfT!Hqzx=8=YAfy9@QeSNq{a8UOtx zX-4<8?)Y@C2tLmuDTMQ~!^-oL8mO;EcEG$X9sO>#@p7bmSV!F?oPg8|OgGl1nmtH) z$pi7{5`qv?{75u8zw6fzGwDu0@sr@$HUB9XIh`vS=qR;U(% zy$%)rB_awx>7PEmU5@7IOXgnZ&0er&p8JfeQ1I44nU~vKht%)(_Vd_pflHX$Z5K76E<*&!>z~;`Dw1v=n@9zieHW{B9!y%)xonS5f z4k4Wz^}f!r158{3O6859V+UM4yc@DLPp>NqceQ+D{w)I&+clA&$sO^BnI5lv_GYL* z&Thds|3tg2#6j!L!3sPVUE*yVF9h+nLh8>;$NJU>zu8!|IKyv{MZ>JiPf#vm3q)!R z4n(fW#*=wn9}o^$wK`HvqEsq5#1{f*tyR4l-fFQ0hReU7}VE(=E82(+m` z;ErdI<`-%El)_U3nJP}31ch}-_ea|e3ZyIrnRc(1gMf5f3)JA**%!I2!Df@MTA<-WAZ9b(LrR zf)8 z%sOTCbfI|5Kms+;mY!4bGSOh55&k{B!cpT&Zkbr6+-fg=={HW3 z;8X|{;kVaPErZCS<3mRD%tR~vFZ$4|y0N#V8!Q{1%rm=P+!!8FX1(qmgJv6KYgF8G z0VpsWzA${*9PDVdFqTz8Ne#mN=*S$!JszX2jGy*2^W6za}5}QFLXoZ~34@RP6pG`lG{qEl!6i_um9DiYu4P?dXv!x`6(Fa(QA%Eweb4rQ9 z{^dE-e+@fPuAL*AgS&cQnk`hV6qL?l!H`*QPSYetf}Gi2VkC}4qRC};fTfp^5N%mC zU9BRvdajvE1k_QFxeQ!>8^~Ct?$T)$8M~Vf(RT|R3SaS?k82F6n*BQVSh%Lh=ncNu zN`c&#&(`U~8o9a>b@TYn*2}ufUHX@!jvA*T(qqOZ5jj((qMVJjr)zTU$X+!b1!EKZ z9DyE*uOaz4XYdN?=&ro+LpzkgbnlU|upjZK!ZMHZ9=LyITE5L>F$Q*>Qpv(trk>#` zX!E8T;Y#$HKz{X;xkmigZcHbe1#_a?e{n|zzkIXZ*f(RhVG27r2sOio%cY&+64h+C91KTx^v>|R6cS(hC`}=8?(%Fa z{`u>J^;6ji-3{30jgFE4LfFAnF@T}fwBG_aEYBu4ARB54#ynZuSZzSQ&2nQq_q;h0 z+-5vFxs2IEknn<1E@QDn=u_XBvrb(cmW&YL6gPQk*?5&2)Us}c%r9nHn}1#kj84De zE!8msVBcRyFsBV`5%GLBRAu8`hoY5|`nk?Qoh;cUW@%?aQ zbhf^NC85?*WE~Tf5SvxF&9cRgz&u7oMFk|wi82-W62kVc`DnQqI@0(=_XY!dTdHU# z=?u^iNGBli8hznE$d&Ytlk<1rp`@sHYR1l5{b0J`!jZAq?n%^Zrk^_vqVuSTf)%R>^Zd$!s^;sh$` z;sIJ!AP)Q2?!_>tuCoB`>Hmi@^*`-jRD6HG9jb$cx?cak30w_b|1xL)NBnF3uRZKO z{{N50tjXNU+kWl;#YEe^r2bDF48I}M%c=uLx}}eXs{x|m>*v(gGFSi21SJhvFIFE(M4j%{0Fa7U~iUD&4}x0KnT@a3S_H zpv;-4`<)|E4NsB1d5K@GNu_JjZwR})IrG9?D=HW#*Y@`oC!%D&nLo#-q{8qG^NdwXguDFC+JS*~nVBhxmzWAa_5jq_t@%}YeBfnx9=gA$3r zH3qqO{F?saKArdO1EIa%r=v?M-EE*HHmLwP>6BdxT79ls*|uoA z6dVi>EMty&j)9YKPwjtU}79uC5664gaM zk2NcaBy0rgr(>nA@6rd)zG@23OsggOx0FJYxCpKkP>0b)QGfdvCXdKWE>9(t3#+%E zoJTfCd=~N(z>@+)v+hDj#{2mPf{{&Zb7p~qzCw_t2!0S0(cQRN01q9NQcFBe$HR~$ z+tCtpL#8iCuQi{o<5_gKg~n}7l(SFLOLsNB>n|}gjCT}^q+2Kx5E1tdiX~av3B8`C zdJZ&iI@M=4juM;&3ehV?l?BPP-c7t}KE^X&*eEncL*r02w>RVD*$IF|(V?ghb5vIF zP-aQb;zB@Q`_+X+T@v#w!F+y5EQ>OD=)=E`fWk&8i8{hE^_h2^JTzPFz_iZj@__*m zZJi`>mS*W@u*VbkM95L}jh?gYf}B5Y*=Q4*lV(gVcQi7Cmm;F=LR6Kb(NfcJXr~-< zk;7A{B1i(r)u(iZ^EC8hi)cE$EK|pEJYCJl2M^x8SE;olxv{@SRZqytcY(Uy*DLM% zCG1xuE6``N=k3I&2D-SE#UK2*eLI?1+V4swAGDJL;9Rpvl(UD0r#s}tf)HC_$Osfj zHwhMK#-bTZM5zkYDCDV}7rO z;iaWv1aEJct%ZC%-up8JkSB+ZA2>L~vfc|Jw0WNCTm`2}w+N1kq8<2NdR|v=z0;ux z2)k&FjKT_IG;QFUb)O?3^?Z1DgF+a*qVHDeQn=!)n?bn};s808zO`avD3Mi zP2|9UaM}sw$fTlUV;4-E`iaN59WS~zcO^2dg}MhLpdhs^lL;QpEj{4!w_c29KIEi( z1b|_Nep&ipnM`6(1mDB+XLXK#=@sOu!`tYL9u#n5kq?{s3=~U(oz+h(O`O`i_$hdkJDBwCWitZ((Hp4Z{MRNyg#bDIS_n*)m^hlg=0LB6C|jnOX`x+QA)4pNY6Sdh$*>m?~hH zH!lu5Ig*-Z_1@KC1)#UkrnT05lU^qhF}KriKw=y{-BNs?#8Kv&;pXx?1y7Tt&}lY^ z>kpc)gt=5QJqw@P731bGXx znveP4flaNu&$h=j)Az(BB#>m%xVLW%=o=zETko(n=oe<)7#oUEp|B1~AF7q0oFy*3 zW~pcEJ=mhOM5onET%w!}=e?8?foMazfW!T=yy#O9vXr z2<`)O54}c>7uatcASy9ngU@AftpCtNITG9r-C2^s&=~|!ijbkk7If|08P<55DxLP5 z_kd~0r@tT%u&k7tP0_D!Y}7WDQjPs=w~3Sdk_|wf$)Gx#ZVcR`aO7)hzCOwVKMwPm z8WL$X-&U|KbyQT8H`wwRDhq-NeCWSLj7s~j@?Ws&YI2o9bVv0K;9H7-D2fP--vOXR z!OV?f=*pI4C4gc5OwxUZ-%sYE^8qWaM(t6kUbX*gh$0$xlF?>SXG$yzF|VS(*;Kk2 zSb1oiie;5^*uMVqrOX2B2;@iQK7M?;uDK3QTkH+-i^Uo;@5yXnR3f9K>;kePMyFCs z?M9c4n=UCQct^K8+LSj@Ws4Qnh`Ugil3K$DO-?K2Y1N>Jh-%rEHbElx;`X4RgK3po z1R9ywx}7F01+>Y&-fQ)1CvlQR2}zO`7IXrFf)?QBcj6;ZFrX3ypAbH?1t z$W(xssF6`8%Y(hf2L_}jbgRkt&dO}TX@CRQ&}wiA3tE2iiTL`q0(ll_|NmDG`hSxJ zd4Ohr71cj6>wg>m&~`o)NP*gc{?E;Pq99=U2j7JUCIpRtLk%>b+LeXI8va+j8pws9 zcnWk*0KU&$@*ipi8rY_Tjt~B^4Y7f+b{P2Ue~$&0mB2rw{R6!Gl@FapEZKoJV3DDE_!xX6t~xSvG9MS0YxCBHCo>~a{^va-o5Nnd6;;Bcdt?f65XNVr{ zi=!z8oo+z7v?*Bn`1s7)Vd5gz6z0&C0&U1e{|y2nV!4e(Pb_?=+3s)9V$a}AnXe@2 zAI1BzcLxjQg{VkgQ&3D(=|l~75-~BC!LundbmiIFhRNBH5%^M`nX|wIiYL38oK|p4 zv?3j66@21ehlMb!{GJ_0BHKx*rkRlD>3ltBK4s?a&J)j|9lk$TUEjon=Rh)pVU7%w z4nEuP7)Q|E$f1~*FMLpJUGAEN80J5AwfS)`p54<@a}z?-9SXQPYzND-@^T9-MrU8D z{f+hY8t^fl8iff%LTtlH6Z;HElTyk3Tz7<%Q~Sp4OK77)20w5o#`U!w)ml}$^MpYbaX5$uujn( ztXq%nI*~ORG`wG*{?VPP<8Fu+>23IY`dL`|ebL_1S9HXa>cjccxP$(L;>_|AtmATH z8ueWehZ^K#rNGZ|D2S(V zVV1|Do}ZV0EY+g|QWg>XJRYllgwE5_F`yXPAH`UIU!2XmLccqZ#A0o5io~7U{Hw5C z30>RWIsa*3Rgq9v8#b6Wi2S8Zh@(Dm>32zi%|se=WYhHb1K!~i&cfz13<@8VI_a;c ze)E6OuV3AJA56e@(l0ZyL8Cl=-4#KSbc@+q*V{WN$nSz=8B5wWHhT(g^GBIG#3VgE zuPq#i+017{Mdgb@^P%PH%eiUR^DD#Y24@y6L}vi;d=J~MUm2Y#ijoP00NxgWGol8c zVl7CsrBc~m05@BSBKz4&*X|Ssa7me(1cOZ;pe*kZ4FNGALj^>31T>0%efsM&N$#lH zmW*F6ItoZ-6J1m(H!5_Q3{Ra_b-z0!5O{WPU1Ue31?^<9oOG=~5S*qE5|fC=n@Q#U z(QOr0qgbrsF`UXjx_v^gt9(RCvNfJ|ap;W3274GlU`APbRO+5zGwb!mr3JIE)2Ro9 zzTU=vug4*fsr!vr6np(oE=K<^GT(7JYFHE7O6M^$t5$Q0&VZi^-G`CX*M__xr(D9# zj<=%w1OIn3pHktQanKs=YkO+9JubH}Q#%mgeu_(}(==|}ZPg?)9!v2qm0KNQf+l*D zk&g~7qf17lnV%ekg$Gfb8FO++Et1g@adV)*6_^v?$-NY2P_4s}j5=~J-5>I!?;@@<5KU7IHi zrAF0RdjlpLC57^Qwo#pZZr?~z_s5l>Rfmx1j6@7?DTM_SrzCd@5m7dDy}*erG5_Kc z5;D>rpksNW0ab5;j*9QoXRjY3J}7m`>yu`OO>a`(O3V?w8;wsrc|N16x;6iUXH!h| z6pzxhKkHesMhYL@)Aj%q6Z=1{V4Wc3;(YHa$%t^-o|20pmV#;Nw@xsEfGJq@c&Fd1 z@&+>ph^7(~7;zfw9a<7$8W|PD+=gNqDWF09bEBSS5bqAL@x9d<3KaviJd~W+W=Fk$ zy&$e1sBh_(!e*r=74pe!p`q2pNaM{W0(j3v(mJPcRPfcg-Qvg_34`T;pWq+^jxz;%&a0i`(J`( znFNeBvD4MheB4CHoU^&}#RZY6X{>s8<_}noR~W%>T}wcUu?uxCY%!JV6`h<<-?)l? z=1@vNF&_r$1%#Xz?E5Dkz4Qh|^v~;;Uh(Ta-&F-sf?Xq>VtV|^dM+a&Sp6YZK_W?_ zWV-W_;^dBO@5V@-cB*KK-(AmdbUs#x~=5fdIyzohh8k_ zEw0WJqCghVp$Kj z?d`0ukM25hIaJHCuggvDgBW;RroCWCBWY^AH^Ox5-VSzic)FoY2DvjFGuw*!C(VlY zsev6RBrbcgh`?hgTZDL4C8z?MK7*TGHpa;o-bNr(d6@L?rVA_QknxFla{3n0Z4Rr*GDL7CKHA3<9px|?DNx6V-SShwM*cFm}Dhn<&__bdWDP}7?71SNIRuuD5EnVFV&VyQVD@XP>*{?x~r zD~$(-=C~r9c|=XQOYGbvny4h!7sU(puPKkptW~a_`+|?e(nZ`QG-vY=|1lIhUaF zQukC~W=ekQDwhkjj=z0(x7;4#*o}RgI$w`k<32DK*wHCnO_&dL;Mc6GK_M|6Csu^w zT5OzB@v~g=zU%1m%D3?<+h@Af%Dgd)Go!aSLS9+zL8CEPoO+)p<-I<|)E(VFtgm*8 zi0QdK-)2eS#2`yx?%dsly72okco{FL%?@6IH%OkIM&bk@`l$-2;(!E*-56Id)QO>A zD>UuBTeD6cIG#6cU(OLnW64R3#j?Lk0qOP^2xDJlfC6$iSI;aSLb;2U1Nk!7WfX z?j)Q{S9oo;VPzi=g`hO|SXm?m>t+6X&DI9byYazm#+XS+ZEQqENJhn^TRh^~x@7W0 z?~gn6N6Q|)k+;n%e;vt@`y0J2Rs$_^nNWI|iP9@L>lhgGJ5C{Jvzv9TUR>%8R!K73 zMew0_0Nq;Ib6$*68<}}1v_)}0|6ct+n7wB}2C9p`8&8>B4yZ2saQ4U-!?m~ zhHl0B$noOy#5RG+ft#ay3o`;(wOC2{{}NTk6;2EA+}~?Y>;MyT2GwuBv;XbBHFCL0ki+`?*6yC{{NocBKGL~FB8}8FM6*Ms^eJ8m1+M6y7HIU2XvbvuwMm;6)1R5 zmuWbV;{O33@60>UM+d6B{BMK{Lf`sdULf>;(1bVo2nANeSkKGyMA@0gNPW~+T^Z!w(@Kh5dyW&c;Rt9uLLWhR4uW=E zL_{$cJ=>(7KtK?TH@U#Oz#mDh%F{<fhhX+H|#iKA2Uia%Ut{jLVmwEOt8 zS-m;(hD1FeWb`MkvAb%5M46rr3oqclKh6%s<-*JKvooEP`iCmY%!keOclo&Z+mHT5 z6!Cw;Wawn-6xCUCt_c8IWuuD7)R0=yzWg2U*SN@b6+4H7UOy1D`lndXn|L`^Y86p& zn{%MF&>HPqmj1v9z7XzDwhPo>eR8r1?7kFtlg|HPjW+GE0sB5^`nWEI+jRby?)!1K zdT%WuD$!F)z~r4c18)~sN(5t&m&bdy2+QXx|M*0QeXr*jm6F0HEk;s(TAfK+Cs>V zxtBd#n~5IY-Ao5M0wHxL5;EUOOBA?k)m+~c=C(TckAi(v>`plfz9Iih%s!l-EH(l{ zQ40&M+vL~bRH4l7gG+1vQXtB6mq2=O4A7S)`t_0n^N-QXJiSQ*`y>_fCe)^Fs1WTS& z1cso?X=ORy$W0jI2i-i-U~mKs5K>j&Ko?0Ab|D+S$Zdm%sl;-b@o~?5Ga&R~u~6Yr zvAot^LfF$w3Pc7_mQvvE&-qb41)-)2&5{1;(1#{eAmS%Da#7@!*``CHvCq;gX4#AY zw&b@9F9d^ro*DN?pmx67o=(b<6>9pdU73W(@y7j`2}sR3dbRWGtw3t5^plvI`N;a1 zzc{po)S$;KM)}xR!V>c*PLI8^R)W8LbAQd_>rhVitYX^qZCytg)L~_vsx{f5kAQS9 z#|v?;@oyxv!N-Spsq!e~f=|?p+Z`4IQV!(q_jFP+SB~B#9sBbZbzCV*_MBw*dV|R+ zHcYh?VVK815-s(;B!5jI!PW9BqGWW9uQ`9(IbBKx_o?vy0Dkbd&owy|b!>-SqR&k> z+AceqxL1%}(N})G+Sv@oF0iYQ{<3{uev89rO02NAknSR>#e+d9lf*PzuYpv9r}OsK z9i;ubVp$9w%(J3@|cXKpc%!Y0cDx?2i4hcj1X17Lu2e%F zxP2|x5>POXy3D9Nzv}AL%SfA%-!bl-7ab+s$>ZKDirm4#-=0;)FD~^o5sy`uPHoGD zkqf}!h{aZVWx~%+4L^7uT_1`_Mqz;MSkNKD*}(*=p7(M7m93BJ5FQO2<0_Dx{C~9} z(b6;*rQj|96tp|D%}>&MBP<(s#A#!%JTfTYd?lsxZJG5;?7rBff~FX#(}##F9#7uo zPb#2Pjt4ea ze)=A*b+^;$U?Kb-8B>4p;a*p)(Q3AuRzQFhosfmgE8>~33wGgTvGiMYHbO?lF6!-C zcBsFX+C+=BaRzv^^KSL_v)s3i3|=b8wbAM6kqbLP=eGhQDLdF?W7S;Zt(iwQ<^4vi zEPhGt*q<%I_Ua;I2JK%Qa<)dd1x5)uvzSUE85oHPU|Q?>-E+*GgcLLVsx~G72rB*7 zH5AKd(}6$bZ_9dNEULfJIDcUG@H525zTbeUg zqY`6+9Xm{~b)HXEtYYJCm_4NvlG3^JIvS=fUUU)HefYc{=;YxdYM1_gW|js40coZC zS0?bQ@qIoc4!|S}XeD5JPX^_r&vRQ$7=l6FlgEqR9{0%A9EG-`EhS5>#wW;cCd_AL znPkXj8?7*YGDLO(qdjm#q+Q$#ut9ctEt`SuYkeA@T;#K4VJ^H?Lv{@UP+QwO<&$jF zE8c@2c|PT3rOK3wR0ZLGE^w=Vu2Au!qQB?=+v5*TtQZm`@tEe$gx( zW^{X@GrH9|>F~yM=@Ubg6M5$nv_e*r*TM6NI07U!IvE?A04z4w$nbnYy0hW?RHG4D zs_5pu;Km4@aBxF|&|Yk(f!fXvnQ~MuLSXi3x-|%_fsR%hFk2@J`%LA@IEt0)@Y97u z0V&W>UuQ?v6YQhg@tcP2;rEd@z3&nUaeM8MXizOV)qq<3L##ol-BhJJ)&soFKRu%kKh_5i1Vii*nTxDyAIDFASRvBSl(NfDfCAd)syWFofF zTg3US8BD;hVP50acFtozU2cYTa(a5aH_Zvq9vz)EMsI9F983sN0+idU4isUhF zfL|t0b>HZ}X88$WAD`8y5zoeuBH~@O3s6cAt=k=%d5~nAm2VdXS zr$<^!tIGuKz)Z!@bMz{{dGi^ZVf3=Wr<4vCqC6imn4Mls8i6USNt+p);iPIpT2U(z z(!o7so2P%W4G^89n(Dkr$m~_v?G;E1N+3#tnT~=v#Y+q&?>5Q4)^PqZ|M-PQ`Jj6O zZ0orOb(?~hGd*n^iUwV}cw54a0Ozi)y~p4M1kCp&@;Z^y7_I;zIQGUP8^GTu(VPee z_39(j%bs)Wut2A;HCniKtRc#@=l=O5e0nVHhVOtF9DH@wr?b;Qf6IWJNqF`WDQdmCkLr43?VMI--Es(=Ax8*Sra_B5J^gV!i1c^`3Tzbl2 zX(^rgSAIqYY;?4^xz$sBTyt&hWZ={I&Ta9H^yyUmf8Zm=ST|vB(7Vwu_Z_an4|F@3lvoRZG{Xntj>+}zKnWg{++rVaw@qbjs{{$%i4R`*_ zE8qVgXh@C!KPm4oY5c$JLygVUONT%j4D=BW`R9bc_&*zpfCBlCeOV2*b5Moy|6(XA znuPAnpoSwT6a_#{{s&kBl{jaCJ07YtLN!fvaA$D%4~7ng-Jsgy-yG=#h&`MtNIw=W z@?}mLM*;cZUgl&u2-iy={OA}+03De6d+RBgI)~YdDy#W0M#X(@7F=5=CmyE*e50wj zf*+b|S*)!s#f4dT!~X^gY8(kFyPT=T;bh;%HZHwhR<;N12&i)Xf`**vf+*CJ-e(&? z2vaQb>Rs@EWx&>WZkFuIZ~U$_CPPbL5jXnI^>*PQL#_=CRlC$$%}`EPz;sCGh4HZ_ z4ioAhG8Zj8**IRdY?ERoUXJKIX#QgONpC$d`vg%gtFH8UI1vaZ{$$fA-jf=exJH%H zEe|xR(@r5NdD&MF1%~I}B@0F?f9~AaYnONiMFnk7Ron-G?8G6o96KEWh9oEQwv{tW z?V6`ngE`6k_DI3O!NBv*D84`S3m%<_#Q`LA(9qEQl{EQ;gtQ%D_TDUq#H+_P5(^3G z%~$38TTb50E?WuG&sNPc=*O6giGBGUuT$%K%3x?{I3w9?Hk8@{XbakDd#HlOT@kX3 z9XWH}N3Sq2cU-fd+R%?okD_(XGKNo;8}OfSj3{fV9YTRXi%k^#{QTft;ByC(cni(; z(S{^KF)^e%f*S{T-L`vk;9XbGybi0W<%u~-H=V2`SGVEw1Z#&-c>A!7hHln(z6E`v z&P5tE%fguVxeyx<)%XJKvNZHv#j@!9pYYqO8bNxd0YM z?u7;5x}AgesfyG9)DyB-%b|7MXupYh@{LH}pw%IHrj~ND57T0_?5FODntK&~?db{* zr65_?;CT9(3nC_Y{R%;#qME^N6K7CLYM6$-ik(!q%j2IuAUG#>mW*(mk@1N~Z)d!l z1Z4#|zfLhqT;`^cnMH+wrp&^WK_Wi(m+OzUC-WxcLUxsvsYrnes)mbyq=@Wyhq}TbO(WzW`32&-@f`RzrA&^^N5?vLG zPv(2K-lwdmR|>5AFUib^`Q((;)uDM*qhCw}J#V<~?(URSRZYpUP-lW^4*=e3)=|RK z$(F}zCTk%RjQ(ENJ8a{6&{I+_{(jRT4INTiVYW$p(VHCUT5h&Hb&LmWu<2Bv+3fdc zxQ){Ez4+nVzK}&4W_yFatUf9Ch;pKk*GtSd8aCbO(A`Z*+VhT{81ADKw*NTb6Tfed z{erLap2YO5tB|&lfWo_hSqH)UUhk39&G}|xq8tnrb(VS^^Iom3Mh=&oDFS;j5zy_9 z(RR+a{=gqX9z~$WZy>du?M@N_T21TiVPhbx=r#7eo5RS4d?0ivt;;EGne}mn^}UxP zV3c~@-zC?$=IBkM$n*Sl1ujf!38F7wL7? z2YKN4x@}?HDgRhEX2JUS(4qH$A@Xp>1Y%)RF;nW#Tcl6=-61#JO%{u~*WXGog~9Mv zQwtb0v!4~2t9P~;Us#B(f@UbYh?iqM(hE3j=`%qrcY#N|Q%@$z=tclEM}JUx9Knis zJPJD;KDCp-Q`s#gJ=>XqJ$zg-yE+?Hw94KcJhbt?)iPnKcUmd;K3DVhFVU$d?UL}V zE1HBn>_Vzi7*_ubd0lW;Kv5?@=Ifo+j>~`t%4#~n?(#I!D|GR0M-6ad%8MOPXTBXT zMqqJboOE_kc^9QtTI4Rkb&g=_d7Cm(a+o^D^UY;y@j5y=$$jKT)X{Om9*YnZo+(Bx$A+J*o3Q6hSEH9bg#4D!Xr+lk(|czGw(Y3gAQR zZN#-vj5kxmiA|Rtb2tYlq9>XqLKF z#GJ7s%J!=`C1b*!>zao(PWR6h^eiPu?kuxd2D-unZEW+Uz*t&*9YdT>Z8(@#H2JFT z-`klBt_}s(4b2leUCW&OZVN6A8qj`0A-8g)mC zmgRT93}(gN>+!lrT$tCK;*!026aC|xf4P~$Dxjpy2%I5A{C2q#kv4OhA#YLsb}Nnp ztX{)`wIJh{Vm2L&1D4!=9&0tbegrT4Qk<*x!)JVx?3Ic2RTsC@kOebna^l_6#s^~t z`L2l-+{(FZXj%rXv`ItuClE38j|b_=KeEz+$IZ=M)hkD})SWas`LY`P?Vcr%FOfoN z3V>v6dsD3}6(5b8^eJ**QziF$p#i z+FD!k@QTN_burH?z^)gEd!SA#>-G1k6;l9788wu8YF;SpEnXo$`)H+7TB%Ji7~;)y zmbst^s6;*NB(TJVOQlE9_FT=LNo7g9xK>vywkM4#i7u2mS@f0|?rm%UtEv zGl7{V4+8JHfkMbU*nWNTSqTyt#gIgGL&qCI=&_Yz`zT$*Ys`SOQaz)B5@@?8`zrvn?Qq_*Z+Im4C+GvTWbC#FOpT7?^LQ!85Ws^qWP5kJp9uF9&v(`Gc_Muw-%+`zymjUiZa z`V6ih__%C}tpfU|bVa-)KHlB3>Y(ztPxWzhJw*tiSprZyf)%VwS#>bF^vW*n>j#@t zx|b1@JR3)JMO?r|p7O~Km#`;1Qv~Q2Z~XvfoR~9zpV8pjzj~XlsC#N!bdRoRg$iUm zal-EI4C4{!x#E7C4RjPxRg!78w6O+%S64WHlWzz@aA6?How%I25Hv@oJ`i%?6*x6BViEXln6hY3Dwl_6J#Y zu|pdDixVjoU3Xo!N}l2|oofZ(=d0+cGTvy&MvCWKNLBtBMx zPBXoSwf37)9Nw@wuMsk9p2CC4y2%`a4)zV3S2aw+}9S#bJ72Ri?R>_eWY%NF1G^3*fvzWJBisqXem@^_mifnQ%| znvcJ6#7F`4$Cpif#UEU<^KXrJ@Wuq)&hls$u}O~O5)z;>K(6ErA`RB_0^>-aZC*Bi z^mZNe1`D362#WMOaT;yB><_{0Sm3T5p`7^SIe~U_g!57GPi&VQSz;uZO}1Dp^%I1E zcE`J4!TU1c#qX0cB;o&@RcAWRMTt9R0{p~+6HfC=Y1Q)4aeFyEVjZ^mWU2RqS9#zw zBGVvT?~FczoAZ=~20y9V@`KYTU;~~>q`F&mF(&HiqV|blo1tw{0eLt9ky9@S& zoQC4QdM;}cQbpfH13j^*X1L*;e(zAjBsq^(XKK9Xii zg->h@;7vXCK0Zw=OezRCAKjD>T)ubDP`p&Q>R7zPxWOV$_pD}Q8*tL|_8aoLguQXv zeRe)4mlQx4V_mN((q8IyDo9;Py)|tXg#)PDz9qsp%lB9!oq<%|0S|ss=I0e#g2eM~ z7hP%h*LoQimm()6EkNo?WU*1YDTLhcyP>0kAg}&6`ba8#m9i$0YxbIT z=bSPq?fy=<;(kh? z{YBv~4{J?ddKA2-t6cF0pf%;|*1t7sn&$<7)76#4lf7xgwwueb+d_ho!N4Fa@4KYS zqw~qdnKud7>&1c%#evm$?7;4%xFoOKz#jfM6KnzA8V@H4kP02%vB&tj_`KNtIubVh zr(P_Mqt*8AP>}JMk6rbBLfT5~qGz5p$?x5^3g%S^7{~PLA!|4f9-1j8TiF!7B|D4y z%~7?}n+=-piiYN;l=H`c@JqDH14UAc#d_M7mppN?gLj!RN1E%nwnvV}CdtYnaOr7M z9SUK@IN5t={P?(cZ>IgBr-~=y;h^jG*z4N6?oxPD*eq>c@a%v>V0ymFYLI`ETr37w z8NnWjfB=y|_UF?LAGnZbrpij~GJ`G2r}kaXzVQf?^nI{DzdaDi=sdicsdPbgjFYm!}zpcraz*=MiO`i9&9VNEbVyuQ3}6#nhhWgssJM+tEayvcn<@u8ea z$ORF9Qb=s=TS}1JjQ`{syy!}NjjAol`uX9~vM@a22gjO6@eNrQnf27VxY7$FD&-7Z zX}H_Y$~yDwPkY(%Hv6%cFT^12l`9MOA)pt4)9@6(Ye=_EV&HS_TdysrJ4==o+!*C8 zDPQ-&2|P+lYj>=~aJ7~@x-N>Wvnim~5q zoa^ibEiu}giHi7+aW6pD=js{+DlFz0?)VbRi>E6Ath>Nso?VyVOOMaDb5A>K|wE=Ls=#IMY^K}2}Jn_-@E&H!1|kkhIg!V5v&))yt#E`^DDN}mxIh#Hgif`_^9a3`GJ3&U9Bi{jUU7fsE2yda^B zMYmAN{THsHxWPDj7I~vjPZR8p$+KYEFP^JJ9j5%ctt&$ficEIJO9_=FMEncBA|7w{ zHRObtYQj!#E~jpp7JN6PKOHoD?a1Hp>PslwYqD*tVrIvYO=>$n+CV(_3c)W|wS5A~ zXli3MI9^qD)@==mjC9_mf0=4obBjwT%5cwZBX;`jtIq8au4>P9<|mK1opMx{J@5Au zM}!V*ZgFw(f=%*^SL~2_@BlnPf~*FOZl@QU)#(=Jof1fsa;{a^BqP$d+@caM>Ro<{ z`Pj?)l*Yhp#?i(I0AVVX1a^Xxwz*^g#g-P_j#SFW zq=Z1q=e!@K4E)LombRH{0Hq8^Ki3rDYLpGmawrU@o`<&C%@kn@{LXjk4IA7ZF1VAm z5ix9)*}pqlaKb^Kzdis*|GR}hjy^bnBJeAnW|SjoPB=@1seBUH2d*%f*?&)5mU>@J zuq416!@ia#;Ok1)3}GShYYZ`l-9VC2RCK<3y%-|b_nsqQlqZ(m7MW#8Bp-oqyY~&< zX0d9ZojJ7)J)z`n9donTmq)W0_NiZ3J;Vi;3`Q<;ev>VH3Y}$toHzpJ^uC7~oL%Wf zhkZeqN-=)&1;Rrju~RDB`O5FR{OXqUTsSb6 zm^qN?JnA;(2;d!at}4?0+BSx~hsH*g)6zpcN0KB$XJjkwb4^#MN85a0DsdAP_N7ZY zUnI$=>p`lAxOWa)U&JT)^%w=Lb#hosgdI=T^vho(4$~ZQCfk$h+1vV=y!f9sXFQG9V*i?Tqjpy$n)h3H{ zbIjr$;irjYYy{`dhk{_C#LUg1wtL4{;Hu&Tkz{E@(=}1Dr3{H||NS9p>^SNr&&#(Z zN}9K%YSxp6A6%Z$RPQNu$^9;SqYXYTcdhQkoGsEO?+wLbU2uDM7M`A8(YxFZs64zO zN8Ka4<#S&^qobozP1CrdFCqBUp>;vb2}iW@YDQz-uf5#2FV72xTn6HU5&fseZoUb| zp5rSBzMCS{C!`@Ha7N@~V;i=DH9g*lt=XHo$fB4cD2I(iXDJkW7pB4VEMQS-F<7^f zSUL|2ymYhGHeJ6mD^z}eJm*s0po2d^VPkBtz3f)-qG|04o2dkHZho#kK}GB8-^J0T z!Bf@0-xD=xmOS`38mXTZsUm`gUV8-m6c`c?nRc1+Ps(389$-|6Y^)#v^-W8We#RqF= znt&3IQGdK({DnJ;v$dK&WtxtFaW{5+hs33T6i9;HU{?3ZfWI}^$@&w7qVw#Af!d>o z{N>SQ$E2u7#Bn*YzTxoGw~4|^SYq(QM(SE;JM(y8)hG0{M-p+bHVV8zIZHAww3=W| z34Q(L-Jg6Ni&&LK;NaULzl!fKVMX=}Hv08oUE!fP& z@(4Frb;G~6$PL#&Dm@|RK$8>a2@=9VS2I*S;_#Skpf~N;4RZ}u?Gu94E(xp__4+hV zd1`glr;dyJB_hS$u-zOBffc1i`$S?zgWcxO3xokIvDph9wif#r8_`&}imgA_mlN4s zNs*qAiWg>2zsSkvaX|7)?nAyT)wL=eD%PndOifJ%7;jO~#HBk)rsm*Kp-3OnFyFhX zH)un8sab&nx?s}k>WSTUND<4*nO*w*!>}mdS0m5y6aHQy8vAp%ANleX*YpR#CJV7TMR6}J|$G)!5;-F(on5~pcV5yo7xE6Lh zYp(b>Y8l_dj)RLEg1J9yuS}-RA3{GG!LORa=k`S!I;y zXw>=@^+hmzS75t+0MN^S8qHQE%3byv6*}nQwk9Bq67K}!NCYlruRkA@hV^K|U1@YFnjwXWLcwcnYxWtrW6&Jp&L{YiL{1ziVwi}$Pc^tEuO zH7oqx_jh*{rAD@!dKE6HQWz9r+Y76|KJI`1!;88rL1eI9^n42hC{Gk;G|$(NkkRsf zG?07G1$PGz7}ehN%`rBE%@kR3n+l1Whv710=VY~?aR`T!f~_fLY2)CA6ol<;-CS?= z=Z;#`dCZV#)R=Ml%;8RKD8^$ix2Wkr*2zl;VM1oDLjP>)UD!k0S!m?>_pqs|PdwO+!->J-5}Ua-U*mUJ58vHFkZ5gn1ZvA@QTd=nqU7>Q1r$FZ#feL%pQKK`^%jl-4Xah0Y z3MZ2dH_UE3XtzF!=;kri&O{aaa*}N?$qSckni@HxM!t!3+>2X`r(-HF2-OX0i7 z0Qyvf!M6@4cieB2*oiLndZFt+gpkX7`%V08^-hamCF4s_X!T3QUsBSV>!L)Y)`i@z z{ayS$#C6uU^2sH;=rfiEt;SWI!t}nb@HsFB)IyH+wUi~2=T^l1kPG@vtt)zhKu}){gAvsK`^6ht!2Lh1#nM2*<_U^GpTA%3KK{R`5uxXCz7Hve z@$L>dOZ8PkPR7`t$)`<}gS(?9i)pujbJ}wypi%dk?+;ij0ayM2X0nN8d~`NMxLcYV zb6Dr481w`5qhLHnuXyM~&|Ncp@%vg%{R^f(7Gv8CcEeKUwIPY>k=QPHTtAqEi6(mG zl_z4!INPJoO1%7&$++M6@RQ-Dy>KjyD~IX1>s;a>{Y~wFW)~IY)V+Uw#W*K&B zKG%6|&|=S6LItkDA7LsQLpDT%i7$YkET$e#Tg{Wmf`}CR2)hMOa4;VZF zwmex9E)T5>d*2Wf%MHi{r7&zp-}Lt4kkwM=VjU_K+OCJLWfHt+HJK(s$@+d*Zgzph zT2)l^vPiSC_qZpO+gL)N2nh#VVlG3J?M9<9wo?VCqg0}6J_;9nBpA>rZRaR@`na&b zEZI8|U@1f34F1q&C@WzyX-J_|rG{#SmNK#tmNLnRG8?>7)WxZ%p$ELi5_KAx2=Xhk z&kAV`dK#YCKwiBcgAnoKPF1`82pmW~><)O}G99HGqRr&;+pfNWnrx)y?DScoH`7Vc z632B<^Ov*GpebU%B;LHCX|BNld|X^ZEuU){sX>vA5}3ysOBo^9G7F69D4L_1qu-h@ zgV-$)JC4X!I*T;J#wr|U;k5PKu`GD~4W-s($X{Yg8(O2pl+<(%-hEJy6@h4|s?*A;O?GyXBC9K|RxD+XlW3I>q3-fG}cx^Z5uc|SNk2|QmBgGo) zLdeaC+0%KO?r(|A$4?lakaM8`Qp-CM7VR&t@W_~wfUz;0BTu%!OPq|DX*Q&Lb&yp0 zCu2O4cma~ImGm{kvo2FDm*?tk$h$NBi(mVpGt$K`zzexL>0=!iTf*%k;oEN4d${AT ztFm}4(%mFWJW-A8=Dh!E@&VTK=Aw;lxjyAfpXGQRx7XDL)7kcju4lsg0F;%gy9ctn zeX7NuW@#;33xyCuw+qUzgY!2_eWj2#-hm&PLp}yHik&bH+Y3aG7xhEK`C6=JTf$09 z-Jn~Cty#JKb?D*9?EDd&z)ehKn)k7@$6^CP-8uOyZzJ%D+WO-TQ}@UF@$6df_}wn% z&H{bv*M<9lbd%kPtBoYnog>ePkNFrWU+~E8?hn1yWC^mooskAbI`8*)OCePhZF{R} z`HQv_6oL<*A=~ry)pZjk5b`!rE}ICdBu_us`H$MWvpNxKuzt5^&CWoOF4nA6y<~=# z0o96!P52PKRjS2D#FX1AsoPZ1?Tksqt6y!rS9s@>UiW#B8RE&rzWtjHBE2bVvJHD7 zTSA6<6HH<@pUyVX4Ck&Y=ssQrF0y{#>jrkw^A^MHe8);KKx=fWeHD_DsPC=8t660k zeAslW&;hLs0U>3T)%%9lZMboU1k1JmU^W~6=4>Z>aM0Qkq7LgGMg=9Cjo{uATc^lP ziYpJIlD~=YKb%^waTOq_9%(4&2I2zEKE6UACAEka&%t+E}f ztE-izMn_MCPK^mwUnU1;7McXkD{#aEr*g~$c>Ng0P0+o?4%KKtJK_qEzmml8`W_GmM43~IM6 zhska6nrHQvCb=Heb;sJCw92>B?X?~Kq3o`6(OQ$?dsCCB2B)a!U8G%)NV2wjTz*Y6 z8Pacm&G*BRWL5aC?7213ZeulQ#lD*mAnOp@&1b2X8p^n3Z=7-NeVFv5k3X5W5a6dQ;EOng{v1q@acH^@{ z_x=X065Y0jspILpt!Iy1)(#INh21ZvLg+6JN3!LPvW}1X7py*c;O~y2k=lfornF21 z#iQu_#%5GZQ9WmfUw)!pE%dNCJ&bXYV3b<^^tjS#cl#m*?rka`;r4A+MwDvHN+asC z8kZ-GSahwk_CF;)dROH{rrRXL9}vEx_nK_UR9SmReVXgOsxuxQ(1ndV6!Jr>d3Pq@ z>s{cyH^RVo<~_}i8i*@AC0*ZXdoaGIO+j0!2ZRL!4$f3!_FZ?};K58OV0R9{dQdYI zna-LgJ?uR1hL94FHL$Ck;;m}M9b}>|_R!d<_O(rm*YJ90Ag|_9LHOHx*KkR5q^~O# zuchZpn#@@8>FCr@Xa`{TH5QxGPu9;i<9S`vxQcL$%Zh^0@M+J#dO1vTUd*#neU+Qo5vni4-p#U%ck#xMb9~7?X-q8zHtFt+9Tbj!d8Sg})m& zl(g!Ry<`B%bRnVA!{ETC#j3jpOCsK@#ravKl_w(}znw2=83k>O=_LLA_Wz6G>VGxhZvM69UfPrW zYxMo?vw?b13iRi=!(jTfnf^8Ypgll1DId`vIQq2B3Il)3MriNP$?9Lr4jz2@_fz!^ z9#96ln^SuAqleJ#kJbk1nHyfz2kd3K<7^4TVp;1pznizPF+R78<=HNk((2Z@XDQ zpZ4Vq!}9B%4|6?(uYA%H-n5wKrY!tQR6meO>C#V zKBX@6H{b-{4hB^i=`pDK7k6dvSvGi`N?A&f44J13`}w02&4d_i2z#9n-(DPcz38G- zS>bQf3d!9by&ty=F4cn&^5fP(PBb9zauwPDn!~DtjVgtNf-LX~qfkjcwwnk)L8V`_ zh5at*W-x%>zRc{W%{rjoSgBGxYDg)H?6Fr6TZzwxghlYXXoGEW#?=)*8!!%Tv+&S ztL^Ruh1UA#C*?t)VU z^(0!F_l2Oxb;qXp!8`VR)y*n3u2oSyNIvmdS)QVnxk}_M_ z0=eIXq+eI-#bEum!4;^o{_<@gX?gMS5|Tb1xo9!Tn#p;6wZ7QYtoL|EqIrMBEbzx! z)+FfZL4x-+r`KbkXr{?7=G89~E#|wi0t&CIUjz?FxsWBrv`38M8An`Kj;$F&tE0#J z$9wc9n+06vt$JhKcNOO2x+eNJ3Eua-6=ln;nU1pxSC@;P0jv)f^j>$tk2z}Ae%@9` zkjHz`qsY=9e;TW8TI~Wi?`VH`UvdjnTFhtNCx0+>e%FBh!KMr`75Ok!UNMNN1R&?lz zKH@!GY>JN5NF6KQtA(kd;Uk_gFG;4 zR^RrN}uMik-js3hf8siZS!5X8UO$HG$ z8ZEMj3kw|^W%M%hRU|`9Ctr{~nD6Hax*@rhh(Q{S#9dCEaEeUEx_EO8-b_kAlKgAR zO!#7(h+H&gm!Ny0%TVRllY3UVhMWu|fbC~$!C#Hl6BfeTh2Yw87&XW2aS zUkMD9^Sq8Q=_^Z>wNHELUmP^%emD{?3J&VZnWCt9#Qj77dL+-XIj)ZPYGl1C>WV(} zV9=$0?Y(XOQ^a)iormnhm?&KY!o@!9HF3jJgjwh8!mjRYM;pl!g5<~QvK@9)Bxb4J zUzYDd*L4VurThUk>a!3sj)8^k>dOuUM*L--*qM=#!0ejOmZIVtSF6`LA@uXa3=4uU zR<|O|i}ZfMxY(;f-gaiHAlxWOia8-&E791~VJFyYBD+O)&GzoDA$NUmF8B4MrNZMa z?MTh5bWw2&UxCCu4B(dHf=;~9ONqH3CNlD2t%5h+@##`8y3lqQKU{A{*NEV6k1f_x zeVoKQAG&GaOcdxXE^HIuB1Ryrh!oWM zKh?t;JDQ;1?2g|VMWeLQ8((S9Fs3Wg`trHXYyyW{L~dPOY|bI1O?@PS=rZr^JaNvA zr>Yl5;0g_Py@=#?q|>Yt$zh?5(yU9m50_7u>hS`dQZ0dN?y{)=Os65_p3=4(jy!1A zC%59Q87xsPVMA$?f3CwlL)}I9#j}EBnrKE?t}T3BzMKnZzJb(zVf{KD{Sz0V!kP^4 zQiKI>fp6rY!?m1bz4&~C&3>lohjiL~Li(j|E0H}g#k?r<`ZLo1%)!62lE91iLrp4+ z7mykMu=5mOhGr739QjUh2411wr;2|5zuQ4-?HS~+pW4x}Rp0eKzj6=jC|_Z^IecaNBsLNihbdYz zwp-enWqJ`_w-yC?mG(G-;ns$~1hItR#kIgWcj{6uL)SC032U;G(v=ZZgqyc?%p;cx zEk;gGJ1qU#JyrY1{#SCQ@*Ugv!8f-x2$X?TgnAusOOKxoh?ICUS7RK)jv~;zjT^?< z`nr=Qye@&6AdhGp;0l1G*NlZ5lniwt@=ukUQ2d;HSxL}F{@9S+rB#gBuz0_?LI0Ar znFTbeHh4j8LE8+0=>n1>Gw3f}0}ZkU2NWtopiuc+t@O=x0+|tE3XQgzV-oxm4jNk< z4{&olpoD6LDv{6|&guEgcA}JV&^Al?B>6%QfuP9)X9>i{@3-i-v&68fpa4R#eFr^s zLWSO}m<{fwy*I2i8EtcK7z`P#H5&8~oYWLb84x^84p^J5j1bhnL(fmX1sqP%LvL0E zp0ocRvBoM4h6$=&);xzE)_;ZGOcmN7gTPdW)n{`>SViI%F^;fnT% z;EE!CHn@tRk`kpO7Ifd8O8;tJL_V~zE(pPQRaNp?l^5nI-pG8$%T4~erz`!K-K6Bz zgK%-JpLyN4*Wn%FYuqhXC)IHD{ERr#7`6^ZOU=^Twh#*V`g~4)^4P( z`dOYwn9p>mT~IqD#v{r_)%Lq%BpKCf*RKq}KVVofRAv)kkxMHhohrxSL+aSyHe9|( zqIyj-D6QO7GRYd7!4Qq7Y|AboPb>*mh;NI0ks4GHKi6of=|LBdESxns354WsfTbx$ z`nXhsMV@C-Nx0)gIgYEv`?A??FC9#1;D9H?oSg&-S3|0fYd@WYl^=^Tdk)A&LR78` zr}aoK(d@X}?C{q^KYd?)(!QDbto-`f8<831ok`rFSzG*dy7!}WvbUOGF#?Y(XzmLk zUvJo=rBDX5ENKMo@`@o+Z>LlmmX4Kp1M)@E;@6j-GGC2>{|(iQm4rz{W{)0Qr93RF z>6MGhHdu@r-w%T_@L4af&7xs{_wp1GUPS-AUH248p?}f+EOxmQzZB+Hwm|MhC0(+a zc_+_+5!XP|ojH9y$#?uRnn_;}8)^5oB<+A5iRqcG0{Iln37zr&V#Izl)AAud((bo` z%nwJHC-hRFMy+*c!j+8zD7=8N6uVw5P!G1Jx)lB3#Y?3PTp~|+ZkxRP_6=^p`Mwxz zb-U_p^3#?@l5$EA{ngGw8l+%8!8+NsP1~bRx)wP-R_pXSaCNQ8iUWEEE4G%3aNqiq zeUB+eqbe?mSDeYkJVp!>mQLe%JN5%|hn`$rBO5uR71QCq1D7kU{II+$&#k#)-r!3G z%h~S?Cv>*8edd)5^^4ea2mCKSCmT5TK7T^N4_m(R@aDzL>xIAP`4#zw*<34hJh zO4d6s_PBxjTxKCH`1M+8WGPPN5khQP`JjURuzJF7rZ^m#hvUM`a97B5x%01LPIW6++{K z7+3jMO{wzpvUrm{iE=WsQ$ex#kKk|qHo{;>@FCS`Jl1!0tsZ|DS7GEThP?6{!xKDg z@%#I;Wn-|0-fj-c7kXB{oIAwhWH4ZEH1-E8giCwN^E%HQ`% zXMqrTcE#>?x$_0J4Y}ED&ekQ8A_ozIO3U8ht>|&NuD8tX_ROPmM^7;P1!N#{F~jWg zAn~nVa9Sy=ho^_OuWM>5rTJtDv)kqW!Q5L1Mg9KozfvNNw4{_sgCL-kh!WC`G^})k zbc#xch=inoNSAasi!?~*($Y&V&AAuf@9+2XJ#%Kx@64Is%UI3%1aY@SP@Y~$U*(NurIc{vi<*EX$u@*xa z7(bMf9)KV3)JX2h>Sl2cct5Ew3Fq@wT(4 zUbAJgc8Rl9d7W!oj5ngyH~7FL=d;la4aMaXm*0VfA`@g@5?&oK?Y%isO_J}7zdj*a zS~u`nH!w9&J2_Qo8BA}3Z&%Hmu#HxD)b3I3(N<7#qh;V-hzPG$L3USJfCrW^!ZME6o($1i!U9R{+ zwqRF4u7rO0k??BCF3pZ+uu;J}JpF9ZGsc^EVN=p&S}o$*z#wMSJlg!-Fy4mqY^_VC z_4H&B3%9+!_xY$ekCieV)zSjbW3wo#VFI)>M4Or%?Wv(iKx${yHymdw+Vy=RT}*Ck z$IE>zj+Aw2xeJD)V6ElXEnj8f6e`wni!VBP>pd@jv|uSLC4ZW(w1wuXWz+Z#RfTR) zGIhRK(CZX~U0&WcWTGo{R}DF{&gQjOEa@h&9PdvN4g#LKkl18dO^d|CMX1|Fj?}(F z>w%SeoL)=DB#Qffufd{KWjO>|!eYm_fz5@+ZME{Kz+FAEN-5vri&(}{S)^0vhhp|G>CKoTzskIsp@ z_Lg{~j~n@^IRON6a{EnkkJjtV?p;;AdFO~JX!AmE&zawW`HQbsE`1blCY`cE#G1A!72??blCxoXx zq8bkMkazBA7~|kU8mX%c($SGX-vD<}vT5hO&5(QBvkj z9RoH5kWiBVzb>_zRMmTxDz~ln1JFeH`H7rpFRHmCO5vx zE?#uh*D~BgP>z;?%~x=h(;%x|zDi!o@rWIWJfV=+TCoIx?sOhlC3!L|KR0@eXv1+b z-h`BzNm4u6k9{jqE!Oi*k3t-f7i&i`O5;yQE`)|+KW?t$69Cr@=YBssIyyeLR#e1a z?Mqrac{4!9kr>sXn|*)X>fvW6Ei3vb_K%5v#zWvITsie`yRYQ5>y`-19MN9&SPq%} zj--APz^Pja>%j5C!AU)IdUXBgj|K80a5U|9=P)fa;NUuCE>Drs(>$3!N9wX{1ayA)zN=l z<$r|40{j0Pr*{Jff)@v3Ao4W#sqJ;!x9_{6fzGmOW&xZ)7LI2sjEvLYZuvHQPc#K!)x)! zoqv|tjEw|B_EW74_!9S-=4<`;-zOd>i~IVE ziQaH=q2{C2ZkHUZ11Xuez3PthqcVE?zn^6p#d^oUf8LJeXVoDhc}7g_C0$vXMc32Z zc=B-MVDEeJ#xgiiRNqw%SUH6Au`;tv)7Do@(g-;;Z)ZOAfajgFfI-?e@vqJ-LQ$Yk z95|h=np4QXsdbcuS?w!^mozR7Yyapi;;Vp$@Yz@+&|BJ3yTAPcKVX$p`lxL!hdKJQ zyCzQ*pRVnEY+zRU0?b&cO1@KngUdk8Y(cM|=I`NAFT4Uj#CvABZ4C|&!JTxf%qnBG zEjtnoF^Nm!uhuW|@UYy{8e8&QhJ;+$dX81TQ2S9gef>IOXiEu2r(-!C5DRr$|Jk8k zA$;pRY|PkCqM8h!%)YrO$(qN+$xWn20fG+jhhCj@lasqYRo#r&#X8$B z#KTvsbi%HwldA>1_&&R>B>SK zOId33JNWoN9yMv*v)L-|vuTorQ;HLb`yx2Ky|X9w<9n!i9PWF%?%djSWc*Vn((x$K z{{rWm=f->?W39_>9X8o2}NdcB+p!>5nL&-m6fcEcyH(1MY^=tm$HK2{o-EnUE}t`{qkwx3lYX5n%jhjzQg|j> z?ZRl1D~fr%^RBuOtMX#y(OPd(kYy?{VU^iEd=+6iQ|;2U%djZ*C(nH@FGj31&wR01 zSy^RXy;4p2fZ1?(_!i7>b#A+wi+yFfS6qM;r!)Tuu6I{VNlXMg$vdBA0sVS+-s9bQ zd-lMXm>6ECWtoCh@t6%a0EH<$EA>n;aox^%CQrdf=1dku|I}EVp_1vYYjwMs4qks^ z8E&#?bPUOh&MmO)+c4R^P$#O-MmOOJd6=y}!WmQg#E#&p%lgNcJ!83~xyYG;)HrD< z-I<_Zx+{eAGdQcMy2ekwlN|j?EMq7P3C`Y~VsIwuw%t{`rk8Gt|_qc1)~ zAM8j24-SfMC~VYx3-qS+Y2xz5#{}Tsd(`gQWGn_Xmg&MiqYX7|G{mFMu&!x3-krwO z)#OrL%A_dMRK}&7yc^L`_M_SUCuRo3M7=?_@d;WLPSo|xn#(!$_+7*kGOtwFgl$s8 z`EjOSn!yA~Ek%%p4e74Jt#LUUiipch>4m;&L$SLTfNx`+OU+~u?K|!$-4d@>j zfL@#)(4=im=4s@sPfz)%{{oI}U?9w@(;%mSRn5;|<9$Hjsc4!a>L{sl!E?x`LW>J%!MPqUR~lRPHK-i7CRD7n zym6b)te>pWhMUVx!dAR>Y(~x#0oe}y(++VxVRKgOBERULa{~0BKT*iA7D7Y~k zfj;<8T!03QFUV;Gj2q-YyW21L@AN?g7-@jRiu@k`GHd^7Zr&sp03HWI3dq;|2aQ9% z4K5%iF2DX8dq7&BRR4@g;QJtXIxqww#~MF=q+pl=yi%lXiX_>PX^6`z5}2h}jEYu* zq(NN1V$sL=$JM^4=yB*L0@TK`q)1Y!SJwSQ&SSY~4-Wm5m$p#tTc^E-{h`L=YU$9stV|u_m3FZ=mn)kqvhVGGjbz&A>mzB}) z-Kz)Cf`j+4AT4fdtLBo_m_)5(-`R?`j~Bss{|^(e*HDYQ;Sm_1uDH!-E~Z+Kh~CCG zH+T+9&dRC3rq&?H5x*nC4*EAMwr89-A~d4A z&`Ey(zqXs~Wk`D*x=pyEl*B2c%bV=>ij2>JA8MiYgte|Xpu5QUJXj_5*1k%f2y2-& zC=b$v%GLrc_yLuwj7%_*LtUq|N`K}aeC{!kJtbX7LPY@Nyz1C_0wU5Fk1ZiC1QRFR9lpF ze_;T-`DxSjtlu~AuY2P$*1A|kxE3b-Zfob?y^Bb4ljwSBcH0^`kt=DpKRn8+l;HlbLqo{t&;HH7Q32+>{gie z#GL>}s`$!qQ3&n4%eLEgv%leLFUn8-YkPHJdo9Ueipg>IZe!<~`cBn+)w4SM*}+;{ z7S3|Zag2HXbCjm@sDZ&+8owQm{lpADB)Qdeb;*8l73HUSFYrxjxWIPZqT%(?JbV_x z`FATys0eZ+lD#i{G|y=nby8f#nF4Z3D{p}&x=NwXC@-H3AqU*op$P8S>RGpMVy z9>@2~p159}E*`4TC4aj!tb&tr$9AgnhtLJVG;i-rn(rAF2v2_1T?z|rqw_1*e*oo) z3bOUPP>hIDt$zh`M4T62M>hHGVN6xpn&<1?jye~)a!!lC(npPNSvnT{F6ehYJ#RBk zjIgJb)BWAxS~X+{Fss3zPdtzRL}C(H+@9?6Ek!*}7D5?UqJFMF_gdZXN#RE?L2iak zBZePd;ZiUAu|_rwlDsIRkp=N1w)efwNAb69lT++X72rr6?HgzEE_(5_GSYJleC ztG>Rr`98*rSlR0+9B_MQn`@5D>=@;pJ8!L`ayP*8$bsJyXTx5PaI*|6XMTpeI((@PQsRDvYBL>^ zPFtK>qaF-k2)#uUgRif0nsZP4SK?qI62Mgz;exoh<6fYV-*1A86`CD&ztQW?Zx0@# zop6Dna~W^~ev@l8mXUdhAuux0KZe|HQ72g@%P`5MlZf{aVUvk7+hl*BH;)QdnCz*xfkRdM;X+ z;2gE{e&CH#(D0Rw!mq$ik+K3MJoI__7cA_q{Zzu zZPUV8=g@rhejtInTaTOU2oi|jUMGseE_&ZT8^r_sY;s5@!}awbEqoRg{8-(i&J?!o z%P@PR;(hZ)jgafaS(qryv*AqRa#e-ZiSO7*;m<4Tr>U8=RdXB*mpv?8Em4l*TPX9a zen0N-6;!M3$#3TiY@rmpZlP?({sN%$Yzd|}o6>eMh+FlFCh5+UVCp$2O&cCZ&>05V z1~a$QBQ!a&ANQ;@IL?*1x)D_WPXaxmj7YYosPw-9bV~R(%kr9ZSF-Fcnk7-AIfgRp zrU|qkdnzDsB@~$UW$7gKTF0x|ey&0K+cp2pg4gJFF?tdC0g)ynAGh)PR}Uutg# zOwUdkPAxD(lwZ5vMm6teLaD4WG4JW_ZUvJmb=uZzWf;dy*Hih1^UAHH4_+^Gsy%3( z(SBrH?f5_i*QXao)S2uIqO6D&O6_DgM?}MGuHv zdtIJYJO#1U$TDk=<{f;4nIAKit_0hD7bjSn1=^7_nO^?qiAO!9XXU6`dO3M6IF41Jl`3~N3c4|v_^T&q;o<$#|z-hr^QF`){Wedq#DPOBM$xFSS6_!sF zp@9ypW|kjEbb-z0KueBi4#HMMEj2z=SN*% zx2%LzH?Go-*&2j=rGnniVj>bQDw1+awccthC0me2<8}GLy;DoytW|8FAw63Q>51cP z11&=|X@}bjnbKB{%8smRH_`?GrRuT4JxGL2Pl#4X`EO5`gKe*U7=6Cz)N*>Qg^ZqJpBT8Dv%lZS5Amj7xnf?6ia%JaDhDaLu zfNLf(oU`vbj(={Skn^`OY#~ zkC;Y=^TN#yM7j=YG5`gqt$g8KA6;QjmA9`L)+n1(>qtvprpjZx&*VZ@uJ2c6HyznE z$XqSYzMGdsexrD>_lwUvkiB&mdi6>U$+ue0oZ#w-;Uu;oIQNp@4Xmw}ee+;$o@aJs zQrFVTcYd3#l(wTe4d3$vZ7UjSE}ID+$qi}FEcL!%`R07G|3I5&UUmpQkw{; zL5FQ@l13z7xIW`KrGi)$UHhA~Tgd|r?{TzVf&6N(u-DgtfXI)2FmFBX0xfp65O#Xu zCRAXZwC=oT`IMr?<;3)6EtZ~n2{kYxF}MJys%y<8+8kpXdX({$L#Od}nC1t@gDsbB zr<(AsdK2`1TOpjprB_yxSR##jeGP#f>}##o9nWkUs&S+59hB@_hc9sa2|y(h>=T1t?N|4G{p3DuQu%2 z61Vd?Ea;=;UK^^9cazbbtEbuASGFeXxRgSKXpeb8HOJfSF}!*2BZ6|rmnx+S=qE%7jqiW`OV;p~TVQlAz(jw0%>DKMGnq_?)E7vsZ41l?}NVale2T~p+b9>x9gJz1PxEWxj@q%23{Kp z2Y&6j_eJdb!Wqn;OLxu5tbmrd{ivqNDQ$DED7JxO=QmAZl3$p;rT6++L*2%E@Ih#v z>=DY3PH{}QT;T;RI%HNhKXsKZ&k35-uHcw&ZO5m^+=V_3mO*q6*Jss4c`a<3X3&n4 zKfKamYs&3{_6&<~ep?kNN|uo*NyAJf)oigV?L8pe^o?MZM?Is|#POi#zdUr4Fg)zPNo4 zz+r)K`=OYU_c`&vO_mzVrhf4bHn!?DH`sP;J3>i?K%Gvl*6h<&Xd+@)y!kV8nByKC zzrJuR-!M{RPN(`yBaShBx{w1u74zd_4c837jq3%_G44K12+2ipcFbH(pJI=7*PJn- zjV)z$C12&x&UISdi2DVTt^;9!PreM&e-}>mW18@kKXUAsI{U8&z?|cwM@kzpx(RW7 z(nRFeof@pi4yqv3SGe>l@mX1eY&v*!Wi7E5mlmT_J=J|Q2e@3GY3jdzKl!d~G;~Z6 zmrqbw_l0vW{q?|UUDdbR&9q7uB3JK-I1cnc5NR%hVH z-mAR|Ac(E$GpCrg)N7tx6OM@5{_@MT-u;xa?1w^2Uzzk?(OI0gJ*qoh^+_wQ{Lzp* zR+!qWJu%uQ`7AWDl8fKD34$&^iR{SUgqUMk;lK+x2vW$RI?t9IWoqtzoY?XRZYu9$ zCgS35ox3=i@MgHT9UtZFUToiyWf~lE2f8jP3u7AIWw#F&(`n&;9BUvVWkLZPlhX!e zn+~921o65kOR#@056(l%A>SH*V_8Zs^ zJY1-bdwZ3L0U?_E;s#D@%p8jSmkW23^}!_Q#`g;z<^m>!-B?6jJhx$B^5JZ=egn`H zR>-xBsOQ66^0k&6R!P-WfA5D$a!?j2s~%vVMQV>RvYeSda_5dWZ0#0G$@cyvM3m5DNeop;47kWRpSt>Kzs1<(Um@VcUNl#v#vLH5 z$BxaGnk(D)`O}^6Sy@wdTE5BMzZN~xhKu$XjZ*LILyYS>W4a6vh{jG2*1!}HVc3eD ze9wP>YYF5rAV?`JJGN`4jMOoSL3y>4mgoA68QkDnC<+60n)%k-Q@YsiC$D}hJ4Ekj zR5cM*8+2RVJxJT&v=|J(mi&E@RD_3Ad<~TP8yqganDl%e#)WU$eb&`1xaBy2Af8DzOB?nNO{tLPg31*S~ zi;)l-i-tE}+PuJPB7+1-*$XMN0lUugcwWoDI633tH;L4jvS?c}zM7##uy|&sX8v1p zBJ9d8I8ky=vA2TE+Zk5O_!qf2+sAt3#3SV7N)S_?dbuJYOM?BzlP!HE9=Cnp-?G1t zB37c0XJ+416e6aBlBh>=8Hk$fc5!RYITO247AC23(z|`12)3bf9;D_?0@EXc)e3{W zXFcQfoO1Ie8EUWXzAl!7lvHOiu~8z2?9n7TNxr-CbJY4IboW>yBgMDP*@C5is!_uR zF;N;{qV}3Fg5>#J#3E*J=yXI)m}dGJeRHRIk2L0k~ z?(FQpP{(oT)E8C#vrpxv^!H)|aV7XAhgvtE>J5m7n3nzEf79!c=doR8 zRo|rbflCg0|M*Z*uTT;CYZ3hoDa+H2UyIv98i^lzVxgZtd+9KnCNv463R>mrQT^+0 zvPfhSs08i1YXp;V7s zHFi|Kl`87De)7OaPCV|N&z?#ScX#?9MwIw&0g-n4x!n>bJc7KfnZ*(6 z4tH8(Dgf6&Ll#;;BH4q!#K#*H&+0ngw@f`Yu6AMjI2HN;??xdH{U64srvk4}+Sw`E zc=b7njBxb(N$2>?vmxh-S6_hdS-gLxYcm}iX!;+<=iFc8Ggej>1TF05Qk>k+ZhtF3 zuBdFPm0F88rYY)BktyCt@yPjJ`Hf+L>qtV8k+V!wvt}?DV0zF*}W1ZQ4JzOq6`qOsCRf6f=n>tCTKm z8^$ObEVhlWDN7vcr|!IwSO6nMXsZ)1+T-rDaN%W7u*CEi{k$AARQUCIXW;v(Ae0xA@d51d)_{X zo!L^~OV81MFzyvsdtfwUR!rMc9Y;@pi7G8uYwDdXwS*acxTY)(u(ZbSP#<(Bgp>DC#9Ki2KF-8oJZf}pb>zj$feAkh-8#n$;l5zjOKprJK3ZLF+QsQi-d6b)lDO zZ{lMdT3T8w(t_#T1n9-Ra+5S6$Bb>yDJhrVb<%<#xKiKS)-KW0zuPd~-uIy3b3!+0 zvJ~<l%TFBr|_HL<=L+Eh@d%#7h`?0#W zU?FB>!YmahS;X_64u}}mYPrEvvX~`uNM~g1iJ#I5<#iMyih^h>7r%WRW#G_Eb?In# z6fHF~&}il2*^oFEd%zFK>awH7XkJ#LrIQH;$Xn=f2|mR^&mQ_L)L#N_nJ%~ejjhHK znQ<2D6H~(Ae%nmx=*4s#Cn2>6G_EOMv#>RR7s8vPq=bIzasN#}ZfW=f*l~6x&Es$J z-3(>GV%j@rcA(+ZE_r6kdQZ%|y4D_iNM;@+Hw3agy+CdR_BakizyzO~&KLWoe96r@;Sfqr)zSb8oe{%QFPz9Bg68t4B*)&1S`W+c+02!p6 zf&fHnL@&%a1N>mm!5(;^U44#69eGSs$LQ`G+~pkjRYGoX>pTre2-s$y0I2i4d8>oX zWwC1hGB}rS_0xdo)uVte>3)*YOvJMj1p>`^=Dh-#7v6n8VVCWfK1Si&6sy@h92UUV zR|9yREGz-${B642GV{S(SCfR|6R5QtO+lLKr{TVue5)@3E37C1h(*Ffyu(`EV=mfJ|#}VX9&vY zH>EI|g9#MN!dPv$3GDW}F5eM7bas}zakZp=iNhH4m;~+7^&CezYM3@3 zJD7uYnr^?26om>py`AUgRs<(9kLJeb z?gI7sp{56c(Apon4=Oc5kGL}HuWTjFGKZzPTDSf`g39v|!_$<6&j-+v8*!PsEvnnWMvKFQVLbDDIGybD!6|&9ZNu^&!b8|6 za=y;uf+!BDD%X1=1=;CROn}JT@}18ONBHZTO716JI14b%35~S|*~t8^&nXEc_j{3w z!N%Cxqw}Ir+doEn7=AWt9YkKVJ$vp}t@b+n1WCb39p@`!}SSsiY`x6Wb3EuhK z^|nFHJ2V6h7|Xw6niiQ0UU#{@ktFhofwPykbd-vggUri};K?$(&ls^V|8 z@g;FT7R?Nm4-S#k?8E}NTi*q)>;Py$ISkiA*4(89p5FVM`V}i`!8Vae`y5%-wwfzsr%3N2QG)iGiz0p(dUL!D6tXNc+=u< zyD9k#+Rt6=mERM-DN$r@20w+T@yAJ6aQkSy5T({Ubr$2vp1{KerUJhox15tMG*K_C zf6|-M$!f+h=ZYmYN8_=sW!^Fj1V1frqA^)!WHHHNOvzQgsieu>en&pgg7RS{^47s* z%g!Bm@vp#k7UN4wlq(0KI2uqs!n_uhcQX)CnoFv(7~d2ViX|ie!gV(2xL|P^(HO+A zww}csp5XLpt9W=%&9o5eJ>q%Eb|@_kpp^scPBk> z@wR3!o_Y&p{Lv#N*x<4D%nH8bHb>k|e`lY5@(fMXEXdr`)*Ccua>qH2XQB!Y? z!8*RaIS~?b3+L0@V}0Qo5yhw9KA3%UFKTWO-A{+`=K&5J z9@`6K?4&GGcL7>OZ2SS&*NL0$~E8e}4W*P4lANT=UJb&LtQUqYE`H}SH z5VzgA4$vn&^2^ONLdkiFuj5pBYYKQ8tr5 zpAam&lws)C759s(B)s*b&G9^a_s_eLoT~V?%#($OZ zmKQ+$_u4R9t!M7Y(+cb1h!IN}%Uq{g97i>^TK6iuV^N#K52%C2#C?NOMLnC_oFCQu zcrUDMFA>d&i6sbG5=~XuN6q=1Ss6m%dq-_uLy*BD1?$7jp?i%noxzPr%nmgZ^SEW) z&@V!kmi8vC-RP?}SY_yUF#$M#`4qtUx7c^9Ypj+uio!${j}-zCC(#t5HuoDZH|QwD zjX$5v_QN*Uf@m8&)77RmDfr6i>T^@F9=%YmnVqhBejZ7~JJ}-#6sVacob!*xND%&r@H2Q4tX8F=1kZBmNB1V8Pe*j;#^ zrc))|Ge*Pn=EQy5Njh@HNfa&_Huh(l-&T?)@ePDE>u_fMTfj;m*|E?di&v z9A1cRY!7(tD9US55z!6+>Rl=B!(RY@X|%!>O5S*tRNUC^P^-0zb#@th^tSiY6~#nT zny1tBgczu;6cRIAcG!wA2wJK$apZU+g~NhizVF%hDE$6iMWxUT>!lZ|AASe9nSe$@ zZIRyuK~=V$d$YRhyL!jj(WUIPL2m6vl=^idU36d1t3pJuSP-_*N<4O6pJD9+{io#F z_z!YtDn9#Z!W(RL>0Y6kX;G)|b}J*;;vp{|6yDM5Pr-_ce(!iZh!3>t>|an&W5eiq zWTI;uQ)ABlIkSzo-jHBxraaJlFn=B*Y~skqd`}KFn{m*K!BwiTEu;bK(BA1uM06=1 zne@5=d0#TBU!sxeR%T^-Q^<<;ry3R%%tgk#fB5bmT=+O7dK(!sfvDQf!iT;;0Q)>{ zw;POP?v$;q;>?d%7Cm}FcFqohPq-cM@6nR#nkAVeF}1vo$tEYt!(`!9Q*_bnWI2_e zL33+Pc)|OSiFzlLdJCS{wNAvYTYb;;7A0Eg<0mTlNO9tdTKrow37eL9Dv6jo}YYmbu(L@!0N>ZD+lvAR+-{ln73~93O2zkVak- zUiu`3cv|k}X2X0bRH{|hMD*xa)3QQ7uj5w2110pNEtK))6cx;?rj-UgJO`=FdNpYt zw>%aD5Q7u7Z^r?(!F}s%8o{{w{vgv0|NfACw?+@zd6eC3D#A4Y{qYGy=%?r_=3_vM zo)B&a;6Mp0obD>Bpuu}?ZOk*#ak^{yP%*!?ZC>7USCvR}F%)8i`*H}rc^FdSxhDq` zLfcgv*iRXO6UEtG61n>|id-kZV$qIu{=9*xJh@b8J||ORbMOy%Y&?st?j%3MNdktV z&1H>knysja<~WV8y&rRqDe93J^~FxtngW$7Uw`S2p(wFa9;=`ikzVYN|8Aw0&x-Zz zi#W(@1f6$t^NpSt_XBcMh2DK^zuR(jSWZNLV5T}Pwe;9$ECS088Z=@U*Pj|7XXypM zk`%2$)$iGhi76$wmeitOamQ!dX>2Q0oy%S!4;G79+#mp4oiaB+sXAP&q}LXAb(YQJ zL(Yll26Mp_bdW2iMV53#PCL8kZ?4GK8!I1{ij+mpyUv?H{aJUR&e8LD5N}jGC1yh~ z$9<5x&n$*&Z-pZ^*1+y?@nz)=J(tZrg<%L~CwU*m>eXwH^$&^uV{?sfxC8U;8H8QP zR}~L_iZ>Ga{VK>6Y7kese#wRkgA@K;Mirb7ooOrka z3+B|rWxCPuL1T^3h<5O8Gpe@&7W_^9YQu9Yl8|xqw`w5Jb|2&P_aZz0t@*ebGB}=S z)@BWgDsfd#xI92x&5u|!uxFm5_VV4|xxW>LEbZV-w|?!PrZK0E@^Fu-r1}jL^zj`Y zWTFuzs)z6oq0#mkbIC0&Z$j9N8gR14(Psomk}<)dRtYCmUrW(I<#6JJJ@b)Vp$-mH zPT8b!;n=wk1g2vI3ZBSxtCkT94!rEucIARo8kxQds-D+Dz*PfLHJ{_`Z6$gXGe3;T zJ4M;%8h12Msq>%a*_}IZh;lVa@tx*YCpT)H-rq~~@A-yufQ7Ywqv zh9IRU=qF#hFOae%ZP*kUb8|ioYJt{+_hmef?>MCHgZ3h$oylYq=H~G)w>D3E8hr?1 zkMHi`ql~e~vpl#M6TpEl6h^yiN!w;pwULOEj*Kskb4XA1YcumtE#Y+7tgOVm^55Lm zt0ZsZH#2+%G|%6%{(e@aG;D0M0mJ zl&r#u)eK%Ve7pJ~jPL9t#@g$02mUBa{3gfB(Wj<_jzf)#+@%`6Y+}R3FU@7jLq(sl z!?Md!HQDV$tWmU1)M~HVuoI||oiF&RUF=3g_P*`8W?_kC_w7I-IQGfCLjQ{0*yaeh zwPrIOs&})&R}u%(aZ2>+&t@xI??FMJ9o5EtOv|{MSj|igElX81gt<&9)d=>p02|Yoxc}mvvp=S15jXK4}z08RD1vQsO?X4f3hp+9*x1kZ7~Cr894Nc9^JLk-y;=Jq>mv z-+;VXLo7Y+YY#t6kYfia@}7&ENP9IPUVB8a{t^D|&;bNH@NdffQ5E>jf70d^t)Pqh zzoX^jFwaM*1sFHTtdLm*vQ`@=g$%P7!a4J>K%~xB5Tf^`GndXM1{OY>d6E zuQLoECy{vydv~^R3ejHPeUGT9f}f?XR=h=X_adiii(~LPHxpU7<)_T%%<1mjgic^t zvZ|&YxgFj{MVSNI;Sfq}DqoU5x^LXiK1I)nujnQZnMPN)Bh{yRVR90Tz8y z+%EvXg4npSIWxBoSzr+NQO_IoSu~Lb^ZT0@cT}Iy9TlDPL~rlNm3%=)QC{p~i&k)I>^}7E&MjsxBzQSB zSC~h)-pPX)sI4#C(4M!_>758QrYtL_756_y@x_BAHap&4<<1nUcXucEQ3?Sh53hIp zhma_T!t{?+QBg$2SVDoIpW`H*$ws$|I?KZxd5AEJuu7jrQnY_|6-n=icTLMYTV@RR zP$jLS|8lsN>N;Ig)Q~CLKf{_@ElUYE0Iu7d=tBwK+01JaLnMVqhjDUsdH!dvkp1s% zCUyC3*DgFDtNeCz;x=fg;lo{RI@+e+X9}kt!34Q@cAdxeff5aMxoz+#OHu4R_JsP^ zvs!+V(`56;C;kQuO0B^t4MX|PULfl{Ka}o*6HYOqd#HeFIGc~LeGA@oc8(S&Rz$gr+Jm@zbi6bFCR(aZ-i-rJ!*B{ zJESqv8f-9xRilXcMI^SGet9$<*h4W`hLh-b&g`49If>*b(7aqa(tNLX*?MAAyl5oE zTsH?pH`WmpmTiWeIW3nt3fBRZBbAal^SGNV2cRqYwyOT+QkXc1=BBB0gt)N!L#nN( z<4(?ciU)uAXdTk<$eX?#me}=`90bWA@2mKxp|zGjqiznwk>M?%Yw>=g{T1=m8KQW| zZ}85$C2GB$UGa0`DVINi28W>g3Ds~s*V_I9YVP*}VQ~2}k`G)Ki8}9n{{HzmfHT6b z6%pUw&-q|3&>8xMjfwNO5n3hD`*>OyQ*SA#?^>e!lS*Ms+y`Mz>!Bj`{oO}8}EJ23J!_LY$6p{ z5Rz1J#EMMoY901){#4D2+wp|u=8lUQv6#r-l+pwtW7MKmeKlVhQyG|3)dQQh-q&Ty zDz90clG6+7QDYt`wx@rHsP;Jv2KaA)vvjn}!+SB%h}Ie$az|)jQiW;h)P|vf|T-;c|1^Pn*VRsVgVl&Z`8LWTmS-4>t<}`{FV?zszzsc^ohq zqZvIcC4y$6aoh>-zqCm!>!=0<1PD(}H2KlRZbn&qcs%4_GDMFg?XC0KBs0m#<6M&XYUjj_uhnv9rzThXctWnLw*gG}s(O*=p1Hlr`5f*ECRb}{NuQ8Q4Pg+U z^UEUA_3UEf^Br7VN&))z2U^qlMj3rTK9Cl3jd>$M*`B`>^jrSFu7cjO)I z$q2hBEX&BS*uCmx#-(^lh9w*|T;ahmfL#=&7LR@RC)e!*GA>E73ht;VRq<$tb48TO z7f_>L!=_zowdvDqp$}K>jgD$#|Lp$8r+O4{x7O|Hb3{#NH`;ppES1l~eXOU|7YFZ)-Rwpq~G3AEfsC6G;W_ z=;@k&kg3x>%@I=Ac7w@xn^~ERFGj-j*D)+g>KWVM_DkWb4Eto&n2+F&?|wjm*12v| z{u5QMR`4J!O{%`+owc^;!q$6IN$#%9Hl9sNoj;KGDXE4|S5W%?b*BQfYJGY%UkkM5 z2doWjcks;50}F(ZmUibPOcVzfm&y41NrmMK)AurqMJvI$38ENRBPE;f-IbkDmK{$k z0!$LBYE0VV?z0&;O+nVa6V}shW5*)=0WVnUv`uC+?eT*7guB3-3k2Mtn`=(5VC%&G z))+?{W$iJ_s^^rL!~HGxI-jOKe-i3fzD7^DTTLiTko?TD(D&;_&Xw!Bq`Uk15-t{- zAF}ns$DsjqiUcaCl;-5+Ih4mW(ujJJI669367M&8?os~ois7+T5&y1f(^^!|vsJrF z=~YzRQJGAd0GlMhh*tt3$J^^tr?F}YJ8MhuMf3A*!&V($0#?l9g|B@r{un}RY}l5T zmLP+!t0K!|&Dh?ufSS{f2wum1{$vq9wR4>! zf};4sUzQVuH5jBT{54gU)IqwHHZ7oYVJ1FH}f#g>HA}q*M*UgmebfFDmU;jpC~+8B$O#_VPjylDpO_7xdj3Ul{%5Sc5*gJ8 znRfuuAlpFyq1*o>yl)GVaN;1~cGJoEZ#4eqZJpb*HmfzTWbU{MxWI{Gjb(6{GET{( zAVau@l;3lm_ps=}ut#K9-xSrCPqw7($!5^#xdMMapnVI}0y{3YBdwIef(&dd6)Hyo z&={5YA;c%zyL{33o>ftDd-Au*N=)ubaI1jH(Z(nMJHmT7gyI#CbU8r&O!f&I4i{vB z!%xKfq8%hE;}U&Igdq$nZSTi_zpBAy-yvVxZgcu>H!c5u-gO$ampC8P;6AK|h;-FC z6KVSTiji?>!$A8%wL*>UHf7p}3Mg2x|tB;9eePl8}h7^kg!YnprN9YUgQG({MpUK@WM=lvnLaqJAQKnJ9I%Xik+~@ z?p{U}-SeaOZV!w7G8KO~eVmeR&bn|az>i{q`cW zVlg=pEKgUz*l?8HdC2g@P?ylB;N$|v>bDFpakTn>K-MZ1 z;FOQiwIX++Sp{tj#aNHj95{p8ZEDE{q-~mO4%S9{FF?sKS4%yB6d`+y9ad!Dy=WK( z1loZPg6&j1~Z5pIp4OM=7n_TKsHY5m?A&0YZc{?Rs{tGZC4s! zfza;gn?c2|Gi2W0D~Fb9rR-LCT$^LuM@j7b3ksnIL0JdyOT7jRR+`iU`QXceK9y8$ z-hMOlC)zS@Chiv}dlOamX`FrVfqE|d}XcuiyY#C<}W zs10)XM0#0Prl(ipq|=r{%n7wn>HrMEJbu0I+y&TC5>p|1(Twz@2^xZp2DadAI z+u`fg*DXhmpEpcjPDu6YmV7v~PP8&dR+gvv?w<@08_rUg&3(j~)UFXgzpS5P5b+Us z?y4Z!WjB6jmX9XvbHk9mve%YeWJfGt;$`e7xh3O`|BJMlUO1uZQpzXuVy4elcY|~swgHnIPFu<6D){9UKKExWkDIct3K^CIdM~SN zTD||wwx9`0qQBc`P8h{m&xG)v9gL%=^SivqM&G`rt?&^R7KXAM+%NVD0p4wRd21`A zy!C-dS68>@AOSuo=r)AhTj{T4c<%F@W1BCG%(&x#5!vnBNj@H9RX?iY!VPIu$|5#f z4(RgCm+*4?Y#N1Q2-sl(6{Sm+n0-*NrM1QDHV0ttK?={U4oA2F-n$1MsHIwv{pLbz z$6P9s;C%cE^)Ry3ELDu#7UDLtw zkn71B-Rz6_J7S?lVxN1+6sH-1;lPsg;=`ZWW|7(2L#cg%zV~u$H=}?KF9NAJJH%4W z%q7@atP=3HJSC;Ois~R3$^J?Z92XzFTwLDLc4hF?Dl#N@B6*+Bo(&=Hy->BK&ciC^ z84x4cajiWmvRBN$JCSA?-^}bh_L^gJT7B{56S-vGL3NVCvaZ3)L_~S9H`*orx+;L> z3mhg%pyqk!A>EYuH95HedfICe=}qx_&!QFRb&Sb)%mq!^5Zy>nsk1djY?2KYv7+fI=+zDJSb(XY*|kY+-c&dbG)PY?yA(dxiNPF^kI$D4OYZJ zR`zDN(yO4wS%JAT9QmYtZ^ta5n8R|2sM?1fh()X)wQ8*?{ogO9a$CKFnohFo>NL zFUWr(Sjfo0fXO%9W>xPk2FG2d?XQ)Ok-M`)Sg*jcOz@KSpue7@!gB~OL3_o~8Aicq z$u2BHeZZFDoY{XXMBnO@AmB!ePIk`$jG+Tx_q5A8szl^*TV)9oZ;}@C2~AqPcHp1D zdjiSTM2FlDVE%Nf8Ax5b*QI$w7Dl~dseq}F));M&OJ|_i&#-S%FKln~p4wA|DzQ`} zXdvl_RX3a=ag_Ysw~|oDPK8Xvh0v&|&V~wGLGLRZCoY$2C6HXfrRK82GlLD%JKoA? z82iww>hMMFjV~OXpV_|HAGtt*$>{KCYg&S6iUF$vdWI^+;~hKm*(Hp*4a_BHc`4Hq z`t_xs_L$M%$$BD^E-rlC%45m5jg5`@K|5fCn-IE0;>S_gsQSwMZ!!pIFA^MJMLDaS zO&%l3uj?BTN#ve#(XXrjm6MYtWPhe3I5km#+=sLdiWM44j*V3s4j_!%2A4o^LGv-s z@-D0#gT5{aEo?4nrOGhv1N;eNbo>eYg%>yb0&q8q;xH_{kL6A9 zR)5nLnZeC~$_4P`p{VwMhz3_r0dfg|PeEcM^e8k(ao{gJ_1F-o!9m6PSFZh!UGd*& z^#2+EWcBZCsQwhlE`JP6T zw|Q8rw(}qfE+1jE1xWb_1|~h1ukW z%CRvJKqe#b%lpepexCRwT{J?s?0uRA2h!&a27;@58;$jRueIlaOm7x%87jZ|4r}RB zVKkSR9Qti&#ntuHpXeFrR$q6sou?0FqhMlIp#-V1iXcPskDqr>l-n^jJ{eFK|NI1q zyq$BevfHeX@hX6OP1-k~ddnTn%Nvk5=U;k+3x$An#;SF|pWPgPI1eCh1MR5Hn+Mf( zu-mEjM}QHwI|#n0)+X0x1%CREVsCM(Z3=U%&!RAXFT*Dbz&5!Y>ej+tO{CU}pj24< z&{kM~F|l}dB`5|#3-!a!%kkkHYW?s|vdM9cv^=yCoSdL^KFQ75ctxaHu9XLpu3fkwU zoOH$DZw><^hcLB%+~lg+@2|DYiqY1ot+EOD^bKe`~U?Ad}xJhtouad)PD{b zj09W`MQ5XVo4z5@EXKZ)b~68)^>Yxa9TvDCdAz(KFfNkE_W}*K?C1}dshUR6IWe~M z^BDh;%VIC+)C^md zbqM$LPjgJ}nL2LcHSd+ys4(U~W8LHyt>kW^l3SVfx!q z2OE4}q5+*fju&>NG2t8k`_XC(e6^Nzd$*o$M1O}j2*PhvR(ZuxOKBRFQzDENM88Dc zM15!^VZwvYHc5(prd2hZ*sA@#d5(7Qj0P;)3>J_)LRv3s?bnlcIOgV_Eqz*BB@DJ+uDMU5Vr(9ph^!)Y> zWa!xX5c4}0Xt57Ua|?fBi|55s_0eh3*0GpUf9cTCC7mp23^&P=9x-H*6bAKtbYfa0 z8V+W)5O6ILQyRo+)Vz9wl5N3bc+q4;z~;(H=X&*VDA*Lt4rwf@VYgmN?$+p3*lsgI z>$+vhMPU`=TpdW6Mze0K9KtEk2*WEL5^7Y=N~Cn@{P>6lkQk9E4vC{C_wLBKujmyr z!sBv#s5m*h-uoCG#g~D(*Jo?XU(pd5YZ2w;wegvMg)oxife>&oacnDQEqZDv>^lY3~ zzG%ZI6>zTDU=1M7#JJtslNWRakhIX~Xi6NtHbJf?%;0F*q_U zRD7U=-RIbxg;^I9{ZSKTG=E7cl1PAXK$>8SRd*tg-e6^{8pzIJKK$HyP1OR6l2nT8 zh6Q3N1Ek~g<6T{-{339mX8|BQFP4)++4g|qT!%I5utaJsLkeL|!MC8C;eFvNNyVe~ zWy;QR?nvk-*B+hhQB!IEqFy?luCTIC0rj+c1?Mq+t~M_ymK*?i?-Ob@lZG;aF*}2~ z`#c^&)XX9owpz_2B&goicIyXTMuJY~^;z??vkYHAC|Nczi0-xUpG!LWQTC)5B&%ek z3n-~*6<>6@V*J7dsHbnQ^p8*<+WekEXQOQ%kh@ixt{tUs`;pzJJ6iqtqmn3OcpIzk zn=o>zuf&ZeD^y;J9IV|}(aI(kXvRXpB!jCWR*WynX2KxwU(aO$HamnEpTjioFi%&o zYK`@<^k}V-#X`((SDQcMi!L-xh4R{^{15VHo-zp<_?IR_aV>hVwIU+c>qy93QyY*` zu#n(gLs#s*YV+}KVgd$>ximfxq5%5y*Mrya)Aqsd6TV9IqqI{jDe&5wl9P#e=IB5? z%hNvTk9NQV)d@^YLFu;}OW5!U6E&VVCw&2`sS?$cW>*0T#!f2<4Z6$}mnz#glX+6LojeL{hmo!2|Zl!~y`8<)|(>ZtCjNIM_T7IlgC z;3m(Z!g#<66~-_;cNRkZBZ=tEsN`q17P? zW!waSvUm2~Y4-Vweh?k&{s1rAB2XOS1zvTD^){-21uWa;J6(nzxie+AKp+yhd6DHl z^TUa}V^U&ybBMU+qkp?yFZLVnB~aI|C4)(MNW*z?7zILr z89h_jpFvm`J@0Z#Ez8gL`+BB6mz<4vru4{^RKs<(s z#qcT4k0=Fw3=TDgc?d@Iqe%reL2z-x7c~m!HTN{WwE2qs9%w+QvR>$kEa9^>zIX(o z+gp=-h4gnR4)c{+ZJKp)PJug@(NLH~cR`l)=)7-XoyTDd^eS&_PK3o%E_q&E)fVs$ zO#RFcmxmUpNWx>@-c6R)T>93>A1$KiUjlvva+=RH$m(>PD*O1w#%Hgknn<8L$c#GA zl3D`(?5)J6GGJ2>n}{K!Y5Flqf~W?qe{|CrqD{@dHUiS&?S`00 zqy!K}u)xCoIrzSN`~cz9AGiGE&hcu2LMA23IzccH|>pa9?ez=6@yD2H#$x!By?LS)|s<9J7ktE!xALB*K?n8&`hz3 zh>dZ0=YT}_L4ZFS0AuNY!q=f$?98VCiN*|x0WjBpQD31m>;K>f{jZ17plPuF^v_(n zb@NW|_ez%M&N+E2w_nw2nXT(THK8u!8AdNRyjoIXB`)@{}rsj~{pXRz` zya^IGMZH^Jr-Tc?VP#UgFW9FEr)_)Lx_R4tzKHIsR+6on?|iO+Cf_O1c%8^90*RCupwI^l858VohlW$P)uBn zd`l8?(8HE_xF21giWU~Lw+`CYb)CkzuQ;+gm)!8`&D!|@1=*V25|4u!UfMWj``9fo zKFZckFIV5usg5HHul6ivK6(N1x7zpYuOY9dfM7nq)xMF;`(b>lcvsDt5|qu{O1T>llWa|w1o(M`>guP`%XBX8Vq z?-OEFHjbALR4~c(KtfeqZ0s`FENbD9gm$Fjn^{imm7@}2Fdb-j3>Ieg26qLBwhA}1 zTaB5*$se}?2JDAqjs+BKN%VHbp%#g(k+(Og57nozcfaziWT9LQ7*2srReM3-2G~k zHJG0xX5tN{8m@+l*38nm&I0tjN6l3W;rCztzoJ{UH?!Kseih3~UPY6OFKy5!j^dC# z`{qtGor~>$wih;2WfJihJDW=b2rE%wnmJoWuWR6Sx!|%huP<=P?{c6mm&^;}bA7|% zNWKKS0D1TpC7fY(>{jIiiOm-K(|9)U>5*69Js_&HTTA)C$xoCnNi!Nl(Dq}Q~mWQ}+`K?<>2J#e+T%_jmRh_W>9UJcsqblOMPll8tLRvkC zwFBo-KaReAfb|KG Sv_Rlu7|z_j_r?QEAl(fHQIO5o`)94&qEryVyYGl=jhif^ z`H!~eLRgai_;x~cijX8dpAZ1m|MCd5ol~;q-eRNmvMyIQH`C!r2oOprc{I-_=_q@| zj*hKm(i#=<-QDAr7>67g2Z;j!j~Yt8X6ue$3XCHVG<_XUpARHM6T4H4T4Hyz8`Jnz zWF9qv7AyL95eYl`{8o$(Me}#1Ph=A`|yQtrETv{ZQ0FVF#L#zx8(nej& zGULtB?OVRq^G$?{@jZrSzZ^+s$%2HG0gHAoV#ZgVX)~8qUe)!&sCFK}KngiE?ylYf z0N)m5U(x@kv-0zc*@C5eySV8$`+QmIE?qs4xsxRIY*B~JkKtRcZ$ntRVQyX)M$+j& zexzngr85);mRq|RK>OpZL=f@b{NlolPJRNr>pv2^$t(hv)jQCY3IOI7%E_c{(6ex% zA!3k>Nw|OD?};Rh2pX^PxY(=2?F0yH0=|!M?}t#bYQkf8RodFElpTkd0Zdnk0c{4_ zV=bTdN-EWB>p9D6zRqro;A%^JoZ2PG&xi)wgbEE-nv_j{9JOybU;fsI; ziEc{1ahk5PhZ&3cRv@G=yqB(bW()6K(syf;7D-7>E#{TziZvZBI{+1ED3D4cWT-Rf zy(KR#V13h_x0X!GD=Wlaq4kp9@Tvll8EPJkXP@U!n60>Gy{3C|DWl~4SDqn$4?tb_ z@_e7ezZIMpsP+-`cfI#kv(p3Ns+;41 z8TfH;mOr6}d5l#uFyi6jZWNV%<90+)K<+@obrmX`ONxO-pZB=d?{@ z+o~E#ibS#SVo1p7GrK1n6u5D(=#Fv&dg2}SWPzURkb0~7_*wRUkvMd~xV6-TxveRO zOGNC|e_t~}srLWv0{?$lGyMzO@xQ5={-0t1XiqR8BB|$%c(_ePYHOT$$6=N%GK6Bo zM2z4CgzYrru9^W+*(kAJ?VpcWy{AE8Q>V%tG@SYm$=~r$F2v79Vav{b?4iPqy*}AX zX>O0$2VT;haT=FM#g2wJr)1!l_>&4Z&-7+v=rnnN-e4h5*Z4Pj{&z|{72cxL;U|}} zApTn^K--HFy<42(rSM|Sld2cT?3tc>SvqSfwO7n$wV&BzpEPDpNt>4PH`O3e#;SNL{_m25>nnv0;UEWRUhSZuUOg zKv_ykIC2)EwEE&NOF0P8EtglYeVgW-WCnqxIA=$FI@2AmMa87}6Cz;$n3IW;ilsC? z@`nG@>Mt^T`+`LtZ@O2Aa4TSTLzP69OI|p{Jdms(KRQM~-1OM>=4;O2>QABxUwl>^ z{b8{~Q$qM#IX1m;Ne`)nc!Q5#2beBFY-+7k;bD??_d<>~i(t;oYRVeo^K}j+j6>}X zodpY!r}_oqoJ-cf(r4tQs+#&5*tyktT$ahQm6w#r85yk@b~~0E3c4P>E+qog`Ka+` zt>fhP&d@PA?$3_a^aOtpi8`94WKgV~;guCJlnT)1v^C9TAm1!arp)wDz|yN9a} z&9@(1ua+r`7>iZEe|E*PX|d_!FsYJzOtZoe?e>Uj9{* z)dB0gJ3l^I!rS5+erVs`Bv5A8xJRjwHqZ$$L6$QO*tFG(w&yj2)vLzGLL?#%Xlp|G zs~r4EJaX{-^IeOW zg;>6N1%V~FrH;VJ628vtL!jT&TWX3nT@XKSKAIX`Ify_TvVD6<{Lfe~u8Q(}h4+jg_a;C!Q@)K|ZhsUE zMja0p)s3E=9DOZ=A5P;0i+L!+SjZhC@bD)EC_sOE1oty`%>?zxpHQ=>14+2+7~{{S zEX=FTxy_%*lK{Yeci3VRws;?0Bqt88eh&2R3Y{V?=D{nu^bC(csa%$n;T4kQkYqjH zvIrg8gsC(*?-$i@?OoJ^4|-z)n%QQFrs;zhs62&m+PQC-VrHO0S8Us9=Y8A2bnDq< zD1ipa_+v}5gd1YmSNVar-X^twTfqJ`>$k&c|H$-XAn0-KT0M)?N#-}hNo3KCq?UZA zmLahy>j1xLM~9N3d}^r;8W9o3^{2BYSJ(OrpZR#5OcAfKsBcZ%kA<}2>L_tQ{L?#+ z=gtE<&F)-+f`Y2(hTsio;wR?*^z36t;>wl6eNEqdyzhFlEh_mqhR4N0^#<$KoOXjJ zpTDX94~u~hX<2{eJQp$jIx_yVW?dN1!pTBX;&Q9m1k9N|-=lRskIB&ZsUOzx_p5#h zgMdy_@B`43?cS_QEx$!>N^d9hziI&ri;9?xjEo{HH-Rn%RB{>V_AVss3ieOJubg(1 zZsaF{3*bY&uko62Xms|-I#k$WIr~#uo_DW{?eyy5YLp8l2NZK}Y0}{*Q5>ybsUUh%GlZg?$a6}me%c7NqBvF*(&LW@r* zx>&wO(r`E@0hBaq;F-NLtU1g_I(=QT@Ei!ln&`4_mfcf?Sm9K@552ZOL7y0YN6h~e z+Kt?)D)R)p$t}}=PfLiVcW~}WlIs|aTqEE%eS$^xeg&>O1V;etl}ooFQ*;K(d=Z?ghrJpTJ|np3vU)>$nAuzq2TYH8<{s~Z)^J>P2ZEQSX6Q&> zXvEyRXjA8LVrj9mc6XpX@cw+P=tS}8Ddu#!@CA9)(IB!Kx`L~yVAHO%Z3jUESA{Cm zJ8EEbDAnrC_kL+XY;n7D8ncm*$7ar_a2x1}`%PRvCU?h^FV!11_1l45cCfeKpRPv% zzPt7+8Sm{XnKBh7Xl`t|#G5PRt^?l42FT%fgbePbc0l~t)?z{1S2V4-CRW^-CBUdR z0x`EG4=3l0S90l50vqQAZp^1Nsv=L`#cb(+Xww$V$yQzE?KE6P9Q$PO80S#n{lWp{ zqkg-fY|0;e+vr&@E-pczvR08g3`R{S~GLXYOlt9{8QJFWO{o+Oh*VF+|V1C zR(kPc%AV-JeB6RMJ2H;%o>Y_~si4+GMj~o88?ZsJ@a0K9t$H`E^@~;ZFf^+ znO{^%Bf0GtJgzA2ogdNw*i7v?R9*v9WS#Se#}kGB@Cv4Bi)R;ZiRNg42G`Bx`TAi9 zAe-f!9kcwIXFmU!p&E>PINiFV#fyUN@)06oO)Mo9s*mm~Vh|-G(t*x+prBK!m zcQS{8u(kF*f(I)~0{+8$PO_Z38!iPC{Eyu`!L?bMbv8I6ICb*vHkg?WuEg<8-@y_) z%H2R3AkTHc`kgVdaBi ztzYG!0lQ`~U3ieuUwARXEh2Vf3P2w2n+GGYKqhgn>{}lHM32(X2-De5=bEN1e;!{S z4+lEzH1-ZYGXtYfaH$0VkoBv|jyv@KuVfdhx=q|Y!~fT4^q=gA`QCrTyI>IdA6R?V zfVKB91NGQBoBv;M2vj@)jkEeE)oNK0NOiUITmM}H40?m*eJz4QhrG2ecD z%2=fZs*TxVP5Pt#wzKsK2Pcos18I%x>+9A9X$^V|Wi7LelFrJTi?TJEk{7iK9S!Hi z>4DuQ#|;2v!^4NPn*xs0Tq<-R&pij+4YL}Bj@6R4o>+-InSpBW%Z0T-R0FtoBPXm$ zu~hIB`ZWC<67?VBsxAN>#qAkuYjAvpW4Ri=K{Jdq>EP?1(BG;244(f&J{2?gTG5ou za46gEmjG4HpEU5es?p>e$P9h#yh$yHChuI#R$xo}YpgUw!a5OFwPjunf7{mc*mh(z zzES9EsJ5`B+T|P`rEtEub4$|KmDofYOc%h|<$3#S>8#8U%5iQ+#4ym+f5IKa(k}j? zIg{^)%2_$m*yXDJJVGRy5HdtD4Y01`yslqyThF5EwKCMDd58n4QC^z1n(@hZwlu{# zmRq`IL3y@|!^rNdII*}yyR?>p=vF?BW^NK$f8%APRlKy3X;vt?ZK?3gOQVY7nGjud z&zO!%g??i#9v=Ozf$_LTWCr(hN~ZUPw~3zdw!v*FeiD%+VK^W1(pz1X*QM*EnBI7+ z@_FC6&RKPODmYfUo#LelMsq;|uPBILenj!lp9LPY;~mdwuUvyx*D z_GW$q+I6lB?+4R^BAc})0<}t@C;X~V0he%k;}MMR_Osv9sh{(L#3VN|ddfi5L-Rf~%HQ6^$*Uye(Ze zS2bGx=tuHzhe;Lw{Uq$4C~jO1BU5y-D>!YxYDlQW`lu>)-k!g0j26-Fj~qQp<$r_n z`+JOk$P@)&OcROSURLQSo*G}TK@MBG_qJ6m7j|ETlat3BoBm#vWY%Mo1hV7a)$2d= z*(^P%&^O_vLDy^90$hhD@W;pK7yPlKfZ6MHiaifHK>nc|PF!#HB-l+UP zt*n@WQy`ZR_R(es$-l<6MAl~#vO7E~%|ZpOJGE%FhHW_HcW0e0$%=-7U>F^p3FGBq zpj2+XLyEi4zbP!?l@Ey8jD{HWpORNaBvI1TlQ`g;~miMm+Vb<4TM5;U63=IExY=!~K3abg%4UqCi zX0GQ$M_AgdPZ457W2_f2m$&k6vOq#bqLQ2~$;H7UE{gxzEeT|7KIMUcKa2I|Y|q%k zQ}gwG9&S|LZ^521*McRzBqhP26QUT(00iiAU)h&Wva`!B*X~3gt1Mlndm=uh+IDT8 zeQ%*gGjDr9!0x$Q!&C-u@og%_=@V<6;jZ9V z_-AM*kg%uHy&^8E%(+NEqA4yNiMW|lBR2dV>b#F>tTTjxnQ}~Lb+~@5F3tN%@z!8h zk$9Dz0KLjJR834)Evay09ZB{Jh5j9Ha38)O{Yp=Y>R!~s6M%fNy=9&#Z?g*);Ge8fRReP2mLE-`+KX?=4lIzO!z!YK27pRyS31(?m%d z;jvTXM>>APtcM%+dxpn$y$(zeG$z$7mlC4eJA1}VxmG*BZQ?h)FNJoeYy9tr2F8l^H#W;#K)YSHBK;NFE72*v+P2f7=VE z_Tjo^qRez$BZz9%ji=)bwW6-tgYn?ryA)!CKfvDw*->S`ecSwdZ2F5#7NIyRan;qQ zmb#5NlJPam;zL%;cJTLFVHSdnkl!BNp;}d_DUOCs7%V3=g5{!`i-a^KT4iLn$KGF0 zKt>fZV=ea~r~kd+k@h}u(&!S)(jjWhfZgV6s`sqO2#fRae8T|j)&9Fl$?+wiZ4oLm zDQmjIqnPH{XD-1`l1AVcH#{`vF@>FyBd1BWB#0o)4;hY%#Yj8pMZmkxQhjectp~9}} zK`{;K4PkW;)vrJ^-oNaaO#BAF@OJWLyr>;p>WzH+MtnaasB7zRIq8NjQl5>E5oGU{ zo2Md5ed`kW-&VRUH^ zm5B#)&Gf-)|4X~7Q>JAu+UK=0I}^~$;$;DbiFU_0p~KN~-h)$QNLMCq6M+XtrUb56 z3>3?eQxw9ecM?>bH#=qTCFlviC+G;Pyt1q0m42ye6}iG%q}Jbi#WisJc}i1}#MRF)xD$6jGzg*sRYW-?Bmo;@oxhau(s~Z=ecaK+K zPW+XPga&iI!5Y4(EUo4o?~ItyM5OdrP05Ey7joSx{JQrQt%AzSuUsTbbFW@ZSrfm! zv=c@Du0Rmfu)B2*;2=*0rdX!pZ`}OaFjqoXez|ePwNN9J54_;!nhPI&nz#HJ$ujy0$=YVKgh*OkTg2g41_zZn~qA5b9N+ew!A z_Dg(Vt2y}91;fQX8+^wyGUVS1(IBEOizWZs3TyjQz9Tq6DyRKo#p;8GX-^mHlK-OB z4@y4Kwc4zOzThtvy9C@N$l`9!!9+=UHL-0d%{WA<+#xT!P{L)wXyd|1+m^7gwnXgg zYhKOA^IgraE8e$J z`~?kWR8EgT`e!*N%+%JW4-{>jxsxsGuoyIHX?%_cgTb%h!3ajb>WSU}$cIs(gO~2E zc979v)b#E9H^2?pgfb3YS>B;1BbLX&4w6O)g#JaQ*fJ3#F}ICNU+s%7K$$i;{BTzY zNEHB~;c6e}a;G2gq^cEG5^n1EZyDM)$#}z~VBy^w49Jn;&K)_t#-&S;HeGk;hT$y{ zT=G)ZWyYl=2*=*ubIrv~S)_!>sUX$<5KO-4O7A=(kZI3xWfq(D2o2l%>- z$R`%b4J1bq(n8D(1<+ zE&iffrl6=6XlUWUyq@m>C&&fVRs>d45Gc6Gg8*s$+eH2&#McI)$iOAKeESNP8AS&4 zor(2P25?s<9I%#fbqsY@pgl#HipSJv0YAA0KhdzpV0!RCVS~RF;UdNgdx0^jXm+I9 z!D`2{+<$c>u-rK(a2u8qq%Qi z>y6mN+C$k!4y(5Oq5Wa8wGXtJixh1&K8T+6qP{-yOE8kfOMN@gcQs@QMo(s8fkFlr z++Hp`L>6*E6%Icg1rGBzRf&SPRl^bh%{=wcKtnoB(dM|+VD#$h!TbKu*P#!iS>xsx z_YU|pcVO6Hq7i;<@$8S+dmXxjyiB9Y3bg`BrK8KHA))Cyz*#F*O${5UtGk;Vmw9J7Mh` z`Kg#1sn6Pejs;bNbw+QfF1bH;SpS&WKGyb5eNrm`6EJ}PRBcmCJ6H2c;ls>Alc&G% zZ~Hg383oZcpP$*+kJJx4-W!q0hbkP(zV0$7YTEmWwk9tmKh~@yh5hD2bX|(VTD%W; zFlAL5I||Fohtw*b1mCao7}Hf0TdHX+5~(POr+g=l05kk5-K_5Mj?}zxz}}fkeOV>1 zY@zUt>$>xvaIyk5Nz^R{=*wIRWy+TY5Zq3#rU$m^ z9Y*&6D971F4LfA9ZVaWBrKX#L1u0k^4U-34HAIC$V*kZqR|=w;t#fwqr0GE;4}B8D9-2oe{cc^xa_RXh zR#;aA?QuHqPZ3xzItsG^A|Mb?Vf5b5nMvmKe6l(6HD`Dn1cb-dnW1$g!R4BSaEH#l zzLX(V1@$%h3E#90Rq*+4w9x1-SR3s{>qh9N&ryDPKjJ)V4B4!nuCT|vakh%-&2tzJ zdp&l^12eH-Hf=k2M22xV+WDOD$8!PG$roVdw!Xw&luxL;wjyfP=;e^C9qjups(9Q` z?NC{4na7UC8B(g=BBhOFha;vl_YfF$MhXROzd8A?_6#W_TKMttqUDyUn8xDrvA%Wj zaJcz&$n*E_nuSuUTB~8rK0c{oK9jy@$OXPg)c&FVS;@5Fm~mMIO6>Vt2Rd0%A@?^K zr^6q9TTJqMl$toTUZttr?#-$xP9Ui{cy}F8-9Nm#upY_fPY+>Jl-zm#*=Y-I%U07G z>-|t_K-aIKf}94dH3oeb&6ijm_sdPrgrBMJ3emrx>eM+uzbp^eKZ+LiJ4zzj59>4r&YT;zob1nLQ~m_ z1J|Y0&uaeU-Wd_0SC*f~s`EEKkGzj<$b)suYh2kOMsKXPP>Ll87a9*y$5kTFddj86 zfw|g#Kk!cVowq9f_i#a$x^#6Vba>wKkbz*_X}vi56Pkio17vjEdJ_|;&c+~Dy0`EHS3&l=;2SpZ8T-DF6 zc_^EmR%_;;dV)YisT2x^lEv5q+ghfST3(MI_<3g@%{3RW`VE0>8g(4?q+@>$!W0cmZN-pc28Wokg7yCtSO2O`Tz|WtKfq}sW z*WtJoF1D{Fj1zm~W50e4{#C&?n8t@47dPry#u-QN7ju4c@}1;C)2f!y>FSd zD)Cw$YM!)b+dV^%z;*i&7zpWPrGSk{Ea{kci+E0&M0Y|17t%vT@dC@|_SVJL=~B$} zt$%NP+k>0ywPAO^nz_ho;l%`tDF#0Me3L8I$c@19`h}Vf0eMSs)!p4-r?gN2@o$g4 zQYKfS$(WKWTaxKk3=9d$k=OHm9*-Nh!JFc#H8$8OhdFipy zZkdiwR#-NGumHi(rO~!|exvmk%@RSXXteR_Jpc76QfI3PR{4D+o;|uIN`-P2qKU5Jk%#D9vz6!s=K;3<6NC0 zvV`=RH?i%`73*OQ5>xE?D;0Zhx4B)ktGj!3Z$-zoh^OUCF{^~l>e;CI7t6jkx7QKt zk0{{NV`wVkf^N5d+S?my?IWT$x6&!83c1~kIwrX|J?(^|P|$WRFRvZU%Y}rdSeEFg zi0B2*GysKoyLWgfsigGWdadE#cr$^)(b+@AsD4 z+I)8~Y-%QzAE(3Eqcgdb&|BRdQ6Lvzs95;W(DEB?*A^Wd7hOwGrVgXBeT{!9bM79r zc(tqmj zQRzQ4E+1S+Y5lU)wSGykFI=o!w^GY_?yL7~+qzitOF8i(hI~`?i{tNpfvJa4_}?Yg zrsKqZUr7HnPP5I+%QLmKOuLKl-X*UKv4XER6?#{CFj~c$6GL=_!v7Rsfr6JU7Aqn1 zBLRoP(V637P-k5b0%CUUMuEEla3#TtV3Y1xNxt<3p#tu&-01F|&oqRbajn{)9X=d? z(_(GXl9dvG=^YvOBT7i4>^V*)azKYm*b!ngsx%mg|?I z>>)!%f`t<*`nAsP@kO@-5pReddhWG8?GFz7U-m0CvsOEs%P8kmU%8H=W%3fLrKE;B z_gB;dr>GPo9&T+$y-wMYuPR@^4|6vjVvUy8W~oE<_8Xj8ARpSgVPm@y1v7k(6Fe(? zo3`HrCa=tWrqyBZ@;!sUkc3eqT1=phhE_gF`h{BD(&7zXwteSE9m}C1iQR0S9uYBf zo7Y*btwan&)!)Cm{Av^CIt2R?~ z40Lqx;&*&+3F}TZsjPX%wxm*%LP6B z?~esNT-t`S%nA-OwBh~h?uEha8d6}HBc@f8VFlsAt-)QFg2#Wak6b~?0k4sn0()n5 zrv*0+SqSm+`^2(anoINs;uek#u`fLdCaN z%-M~N#M@@uuIvx~v-9+xcdxy*U``3>Qx&Lqc&2PqECFuIJVk;VxES^U0b@raI;E=; zj$0S0xTZ;pW#uLe;pIm;t}7|NyWrX3i$ORN8^P@N%b$l?{i4Lbs5{&?{S6AKKm9XG zO`DU67zd_p#28d=($d^vhDesu($aOV$2m7pq{(hT(l%;-%eFAuSiR3b^^1+lQg*9JcZT=mzAjHJ*{#n>mRRH0QU1G}wG zE9~xMxuk(XHuwyXkB(x_nIfVkGO=&}9DfG`JD^GJ@kNiylgq|b9qy0YpN)>tBE{dB z3+G_}aP+IU;N~@GU)>0m?-!N(SkwF4-(+xw-Atpthb$toOnE?AMi7ZTOfxiepv{HD zo6aZqdFE%P6Pk*c2TFF0W_K2ODXH`PY49PqzTrYT!lHq@r4o3Fs#%%c5SvO6rq7Ch zchV^mi%H6C&z$Yce{OW@9aNPYAj5m`T2rIc&uzZ1OuHV-`u{ZdmSIu7;nyf3C5=iB zj1q#RAV`BqN+}p1EeHtGoijAjAOb2Kk^+Nt4m~JR(mC`XokPR>;P3xl=X^Qm!~5yw z8n|Zm#oo`J9nW6(y4SsKJG;6Vv&E&QJ3`!yMTz_&)eD4+ak?r^Pr5Q|w!e-xyr)RA z&oS7Pl2YlX}rA1##CLy!Z*^*Fdsv*Me z*tDI{%Z&8j*>~7%4{mcj&{nM(R(+eZr#4H!!_UL?(55+8Bl#00O&^U|s0SxQQ)(yX zBk1DE>5)2b3_B(ON(5FEO$~qT-hAECdy$WAK5JeV4QT4wA0*;C)J{?ai(1O4K-9}2 zqrd?9PnX&ZiBu4(fXkB$_?xK9((6U%%en-6ua0_K`_wL@foTL|?;Grn<*zqQJ@)O! zC8*Dz=|vFp^~zvA6N8Twqy5Nvk_zP(6OSAO(*_@jr#!K>TxvznuFso_g^r^u-;cHq z4-Y?+anuC(wV)+r0J3cM`qAr#s1fo#_~p5~h}?ZW3!%!<^a9z)@%54uWx+JO-2(JM zg>gg&DQ(-JC}d#g3vqzJiSZ;&;-OCP zplQv1P7R5RM8ZYm&&cmUg+O-);@tt1ETrgFY0G4_v8>YZDs9C?>}BsQ?FG5nV?UV& zCdIxbTK0ZoVl(%Qhqn_w^tP9Qx6KnbR!tF+`3*@k(&D`by0BMW)vi$!{awB<5)v{R z|Kgl8CIbgct%#&HkE!X9uI>A6eSKrSY0^bXkyW}1x?Fa~@3M|&uJmckG9jC8to-aa z0>%t**hs$z-f6em{a?w)dv{m+T-&YASY#R+Vmeo~UyKgrPg*NQF8r$RS_f63y8@k& z!9$5X^j=)-;fK}&b6i%wEM!f*=;{ROHOrFj}L;P~r&j*hEX%x^tFXd5dl|MYDMtwHDX0Oj`WoyLCG8!<+} zBY-l0s$2SScBA}thfU!Zfj8jwT6m9x*B6_PrFn%(;Qzk!HMFqED*vyF@^FH1k%>`9 zhl0Y*y20O;^9%^B2ga>G?3UGZcO%rFziA?n{{I3609ptFtkCukfc%3mu>U~Fg=sEM zGM>%Ae^})o?f`(|#|MpIU|R@a#nrz7%wYpI%p~+5LPCe!Yi0zCCBQoNxj1m9{{bTZ zhj``xXV;8L5Y@?~N~M+fG4@)akH{4%(BNTn7 zsT&@S)qswk7nr&}};o4@K1e#!MGCtV1aeQnr)%@0}mouV>jX+SpF*Yel z*7L4eXRFiR-KA1FGr5IZy^)r*qgLezd0ebxi7leV2Xvx}GIJIwUWt@9oe9qV(EW&re*#Vpk7` z4M<4A;Ba7QHUGlUz%;Q#Wt)m6kCK-w%cL)%neZQV;4IWr!n}g?rlZ_M>->CAei-I{ zinXm&;&C531CZ3?$l)fPfN@J=1v{jWyJf*&^B>c}Hrl(ey5qaOyW74Y=}wk#dbDE( zk@9#ZLZzt((3qK-**12+{fqod`VCt;FmKIvDjL`og(B-8oRpyNFA8iqwMzcHY0jRR zy~L%_&mU&4j(;qwl7(awC8+iEq-SKL=@am`ENOUg2R%MZaC%(F0XVC5|4~9r^oKqU zNA_(BVNi)5ke;6Y)n5&wW+Fo>I?8uB!eoYx>EIG#g>bstqt2Nm7Sw7_@{#zQ*aS8K zX@;IW{e-J0RR4q%p&GMg=Fy95s(M+^T)6*mhleFi(&Hh8CD}Rd7JP|uu~VC^TkIk6 zNbHzr1*4gSS3g}e`v$+Ht@$0$%KB+3XLkAc#?Y2=tXW|T@zQo0FOaJNBe8*_r8I z$tP{SoqEInLatwPsKYvkj2}28Wh7!l9=Ob-TMIrIKYo{ea<=*myv(?JHDj(sboEiWy`a_C**#PG}M>cq{+A1=cj4=i8m{o5S0}*Ze8rH8v!`(-oH;Swp2(CmA!&4%&OTHfePz2 zqIxnYXYuV@3yVUAED_M;(FR!MKCfS1k&cc_O$|mM9C(c@s5af+$EH&8gJKFcZk3J4 zdu_j=WXIjJ2LYar*eeqvfqV)6vcD1ut*I zxL~_esXW)>de;7X(qZKmwmGX zfFy4<5zh2;Zo{P*bas~0tASeQm$Z9aAJciAQ}xBg{fDxIYrs0FvEazb{bt&B5|uw* zNk?=DZSnUFEuNo+U2NTHS3F{p~;5_Q3w736x2@o{oISbBiPW!w1 zxw=JMd`jY|A@b9D+ex>|Zx&ik{~i&V^0e43UL}`U&WE;RL1T*sHxq_$SHH{SznSpz z9<@Q`2(BkbLKn{r$8JRzS}!C8V1XS?J7cSo6 zEqmCLTQu5E1zYG3l+dObmz5&@erwSj|L8D7c@G^n>7#98Y397Ro9mK0DbKdb76M<) z^L$!nU)V3W+u&{QBg($%VC(5?G5XSrgjHT3LDW4<6s)CJRQ-Z~sol4avds|kkKr_7vY$i26HJHiPb=8;n z3KqKUkr{4~k3H84X<`CEb=MZwD-Uj^NhZ=PzRo~%eRugE2TNIBrMyT9VH^P7GP0Zcss==*`3v;$GZBF9jCx`{2!*( zjL5v$9@J`PZCdiq%x;$1@s(x`&aLL()-F!Cr#D7}J^v+%{|-g20R2 z#6NoINoBbpPiHx*Hl!l?f+w3L_g4AhyJs;?M#*gs1(;kf7{~!j`H&dY=DLgK6y@Q< z1{2X_Be*c{^7R$qhdTqJ&ahzpBk|2J;dbc;`+6k}LgVS8fV^|7*_$d&3z_sy)g zY7aG`Qw1|z=Agz}qsn4jyMJp#W?yi{eV^&N%pQ=zn_F;r$$$K z^yHDT&&zs-HB`rm^w`&=s9ydBd%3;thdyil`8dctIVVHI)SkdD_yOO_XsIW@xY?^( zXS%|0=k5K8+OTSuZ=bC*oIX!zI;sj&K*g;G_4|D|QHfx{R1$r3z_R7i(b@*;1w`0abZ=~8q|9u`Jz9(Uxg z;V%HVlpHAFcrbx4!lUtvOM8COTiN)FfzoIXYL#y#_knbc^qCT%f*rRwzD|~cuBg6O zE-}8Ka3ZJgVo*kYKKiS@DB~@YrY70vexS!ulP##cK!+SNZv*Pjrt3dO@_&w1LdYj&3*MGS2DojRO8y*VqpAZfzUtfS&b4kJ3VB)$*MFGq6~ zc(3ROjl}_6b4VW=_mULvHyU@6wfQm(e7Mux2^3Tht{ur9N}AA^tU|weXtrUt{PKwJ zM_3zQKF1@;y0z`zoKEl=iQgo6pMSUF85;L+$Gy3}$%n{iBf3eb5{-*yfUyBb$DvbZ zL`*%;K{?$$F?WAX_x-uy`*i|o3Mt6EuN-9=0LXY?$Rab@AFybUA9(B~j&cmxPmMc$ z6crVH3W5r9iYODz$m100rkId}n7g2uYiNF4T59E;oX5KlASj4Z{@eg74bsK4?lQ+Ja^+>{G9E z^E|dkAAoF$sF7gU=x!xPXl*0ta1@rE@n5H;ZUNiG7h%0`6FeBxUHiLHExBlAn*Fnc1;2Lj& zeyRONpI2gK@?zOqaR2jNJ2v~-W#-6o9lLqlp0uk*e2sq}V{jULd^oeQSAbAc5T(K7 z@S}<*HIHI}yQgYDBkzD7`|@V9`Sf)IyQvt8MpT-ZpA5~WgR#yc1~Yf|t$QVFz(-l9 z`sH>$@_dS*y}dItKj%d;A;{@%V{K84nztWHU0d?JSL0Tq1$55&xW-JR5z}`iK`FD= z@tuS_nR%s@=9ArX7^ojpwOs^6ZKWPYN`b}ZPbbFo#)m4P*8sNOBg1pe|RwB!3HMwVNvY@ra1q)fYO?F-5#P~PK z&fk)Qur!NxnK8r9VZDP_fy9J2R?IrQoQjS*9Mo%M9!|KHkx{2kkI4rzL5+=5L}Nj1 z?i%o9m2*(xDnSds5^Z>!+ZY&FSM=fc$s zDS5Ra7g<2a{HZNTZGO z_w1py1|>RlbfT`)fI6#@-QCBwL>F?)yABRdM^ru7Kvb8@o4qW^Y`UDNy}{M}BxBt9 zc9qWXoQE0_g=pGn@IsFcRs3i2r|4%xsbVqN8gzCBp4j9}a*(JpP&TQlbttI52xJXiT$A08i>-K3H!X-RH^H+Gt3% zy!4$kE_r(P2aKcXbnQ|Ok(ZrmW`@_evlfFkJ8tzP-raem;3v>}=KGyB#X~MxdS`7t z9pUtsRe|srG)2{Ffo(hdXq$R1YuXmB_#yX8JuuKFu6r1xQM6Nic}RE79;5-XmKI+P?IN&-c$A zuXA40rZ_(kxD4)L;pd(KX$MTq4RY;^okOHH>nAL8O#l<0GOrdP%N(?kzmP@L8j)$LU1XaD0+v+x@bcH=(3 zPySkdpIjlNOn+A6LAZkF>?xYf@Br?gY)NI%hzBkqDQ{Po=}2Rk{s*Y#IU)2?1zfhG za0jQoHu(7x@~1If&FM8zzO#-d^cLmSZ-SH>`JS)r7BL{or-CO*8dp!G z{AkDBIL=JW;~R`vJ7v>YO780AjIC9x-KEd#*|e5S!zbS~hmKRzrIdgct+JeaHSv{S zJ)50@6}5Px!@25%l#$Zr0cOP&u+hD4Jg;8Sx%RR~>&eopK*<3`SGH6*6|*IydR5++{Sr(H)z32 zxoB5$-nzwgY`_J_t(z{Z7Dj1U)MQ|~{}Fl06ER!&=2l6%Jy3DIOLPhJA=`Gysnf_o zYF#`hQz#)!S=-=K9`dVp^Jb~bFUjrD#;Z(z|4G)H=X$KVxQ~gYpqD`EA84L4sthTt zoZvkdc>#GP#hoq87ZNn4VOTvQ#NdlzoI_YJQ0OFSQLO!ze=NGBurO!nU{HH4m6K9) zsJuCuaCgJYl1Do$F!ly>z+MzlzlMy@Ej6`SNG^k(DS|TmdG>%D%C+LUIq`}(98Y6t zL|gv+nfgZRDP5!EJa*hGgNA=CG5cHDE4Vku{qMPa<)s)T)$ne+Tet?C@OR(okvJPVZ!|DTekHdz@Q`|$&h_Xx3~Y3OPy3vc zt5^L|TM11A%Vx4i$oA)SYTcGW+y)O1rpX^P{S|o-4-wWq_6A6c;i^vbTNnM4WZpn@|i-H2p%>>I`9YWIEi@BU#u8}MEIuqzjtN1IY)uk4s0(abFVb7d~c zct)xp${Fs+N$&Q%U`oe8!0Vi2hLihLL4(2Rx#^JW8h`wbDb*d}y;{$L*T=V=*s0tR zTX+Fhv3q}I4ye7(&C&Vr@s}S1^%&nFYewZU^C_Pr7pfltQOGa8z9*06U*40E$*UVk zZu_*w)`-zcNDAqkNG)Xk8+~JGJ$t77!@g@ro4=iz_}PBRi7M;YyTaC%e1J?Gf^rOG z9I}#+hzlr2Uz?Yyhs$peNKFhs^!$D|5oE2|3eD5FkG0X3qf+?T)ky1 zifnqYwz312C>o^$i?rt9$G#y7D8ibFg(Z{Hi}xJcOh2PUCi53aQ@Ebb>f(u(m^|gQ zHX({iD3Fnth?=!X45j@X{<#L2 zKQ5xREcKt5Z{}*oOWHQNwk<`Y>&T#?2Y_WAg%@9A5&OaAn9_U!dbmP3Y1W6j9zi(Y zcs)fPj8I~>_x$V(G7>SQKieA9nDxM#9o=cMo5ZD?>#IO{)VU_piXeE;r3)HJEaNz786psc+1KVimTi>n#X zZ8)TW5QqS%JT6`!;Q#M1Nl1s(PW`_ON%vG~v-wvLYe6`l`?)b_n*Y$YQ6va2f3uh#qP{b$J)FmS!+i&(a>_lP6R)hx0Yk> zCp998h_;=mH{9p~xq${q=OdI=C2!770%Fs2u_ysS*8cY|j^2BBjgp`ao?&8$n#ZAu z6UTQ#GxLuhU`8Zsae5@(&8i|$mW7o?Ro(0<2B73M;2Toa#TTn8*9|*tSJiEBif$eb zU|c$SgaMzH8fa)sS#!$mYNj&#c-|Ne!;8tnpC5iXxySQ{1WZIs$6{qPBbt@kpEgf2 z4Nkl`cvE+lgl1%#Uo!4*WJT-34^m|P#q(y`dtYnON-zf;`EhUV_#k6& zYnrPYl0;Msee$3oEGS4>t2y16j-7!Y`MvB;oPYF}wqm`gxj=f-HFKk%|C2eV=~9ES zgQ?lHqZ=M;m6@5}jQ?Xw9sg}`!;h?^{<^7;Fd$7mC{+uD;ZYMLj*K@SW zV$K=gat6)WOxx|6CwC2JnZpSR_q5AAdSk4m|61TXN@$EG(k@e;CPY{fJ_epGYGOJ% zf!~}hGb2G4u+v{a8ahbiX3|$>z0-kb17~*a*~=@JG{+5M(WR>jEIpyj08%W zmk{=NcRT*5!V`qqZM*7*KK}>d}9ni5RSud>8W4@AjyMb<%g|18>(+@+5s^5&a(g zgr)M<@fARR%+wKPRzH6@E|$F~A-f<2w98)^mDm=fCtXGY*l!`y&#EPp8 ztVJ#J7r0fULQ2o|YKPms3PW}}* zZWdg2D>qa7s8{tIK#G(x!>>__<(Bhe2h;|AH1>>LI-AA;QV=SodBf`LXYLoy3>u52 zlpUh{&Grk5G^|t%OqpT{14Pl<)r4162O^`_cuOtc$ek{y2n~khVzG?bP_j_RNnuWj zjYHxOS8{4;IjhqZzE7TIq7QaWo_bcBhbu`8vec>GF=p?VaBI9nP2%I}uu#ds@KuSp zqK@cka;`~FdSLjd;AJOXh)t*Rq;Xppk6u4h{jS%T_zAnV@ft~d-#&VU?bPqX}0=qwX!-z2Ya0eR_AAiHZz+gq}sVjdNXTXuq_o9gM%!SWubDJg6uFkH( zqM(;Dd;WXZ!)N;0j>j}8p@yG2I${!H;JAtleeTnT)oP`DgI8a3EoNCS#Xld_^%3Vc z5a{jg-Oh2Qj}jauMUAaE8l|xms?!C;)oFPuyP7IHn!**M2^?xS?KT}U#2C2an_U-H zR&eNae!V%dUGy3^Ci+FBBl=7JFPhKKchO+>$Z7HcqZxlpH=x7QyJu4zT%3ec+Sbb( zQyZIGn7nP|%pB2I z#nQKP?vA++ML7z2@nWc;Jm<+G2;`+|q^)#f%t8Y~M6>EsH%bb2=AmtMd6n@M9#ntO s1OA*IUTG`8SbVk0{era@oxQ|gHoNhevyF%h2mCxy)Kn;WY!dLl0ASmjp#T5? literal 0 HcmV?d00001 diff --git a/docs/assets/images/sparse_self_attention_backward_pass.png b/docs/assets/images/sparse_self_attention_backward_pass.png deleted file mode 100644 index 1b0a2a0f188ab0af04b48a6818dc0c36dcde0351..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18207 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 WzkAa75csMKnw*rfWTE(zH~$wqK47f? diff --git a/docs/assets/images/sparse_self_attention_forward_pass.png b/docs/assets/images/sparse_self_attention_forward_pass.png deleted file mode 100644 index d6affbd4f1e925d02326686388a97db48db51711..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13237 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 diff --git a/docs/assets/images/st_bert_base_result.png b/docs/assets/images/st_bert_base_result.png deleted file mode 100644 index 0638950f71f6bc57d3f446db6dea0e0edbb8a70c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41819 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 diff --git a/docs/assets/images/st_deepthink_result.png b/docs/assets/images/st_deepthink_result.png deleted file mode 100644 index 36b7f9f2b3362e5fba50bffb2f233002844aa426..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25294 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 diff --git a/requirements.txt b/requirements.txt index 9ca0fd6e511b..ba1deab48f91 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,4 @@ pytest pytest-forked pre-commit clang-format -triton>=0.2.1 +triton>=0.2.2 From 770345f208a29f3e2fc7e712dafa1890acc18e97 Mon Sep 17 00:00:00 2001 From: Jeff Rasley Date: Tue, 1 Sep 2020 15:53:59 -0700 Subject: [PATCH 15/16] Add backwards compatibility for deepspeed.pt (#79) * add fake pt module to expose old deepspeed_utils and config * switch to sys.modules instead of import to make it more explicit what we're doing --- deepspeed/__init__.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/deepspeed/__init__.py b/deepspeed/__init__.py index 5f55b49fece8..1583b429266b 100755 --- a/deepspeed/__init__.py +++ b/deepspeed/__init__.py @@ -1,6 +1,8 @@ ''' Copyright 2020 The Microsoft DeepSpeed Team ''' +import sys +import types from deepspeed.runtime.engine import DeepSpeedEngine from deepspeed.runtime.engine import ADAM_OPTIMIZER, LAMB_OPTIMIZER @@ -28,6 +30,16 @@ __git_hash__ = git_hash __git_branch__ = git_branch +# Provide backwards compatability with old deepspeed.pt module structure, should hopefully not be used +pt = types.ModuleType('pt', 'dummy pt module for backwards compatability') +deepspeed = sys.modules[__name__] +setattr(deepspeed, 'pt', pt) +setattr(deepspeed.pt, 'deepspeed_utils', deepspeed.runtime.utils) +sys.modules['deepspeed.pt'] = deepspeed.pt +sys.modules['deepspeed.pt.deepspeed_utils'] = deepspeed.runtime.utils +setattr(deepspeed.pt, 'deepspeed_config', deepspeed.runtime.config) +sys.modules['deepspeed.pt.deepspeed_config'] = deepspeed.runtime.config + def initialize(args, model, From 6d3f168158d352bb1c607491411d01f13a34d036 Mon Sep 17 00:00:00 2001 From: Jeff Rasley Date: Tue, 1 Sep 2020 16:00:20 -0700 Subject: [PATCH 16/16] conditional builds and updated version info (#77) * conditional builds and updated version info * formatting * add mask for conditional builds, address other comments * update to use shaden's updated test env * log install requires list * force local only build * update torch 1.5+cuda10.1 * fix torch version * turn off sparse-attn build by default, must opt-in for now * turn off -I on python, maybe breaking with conda? * turn off basic test in pipeline, just use in install.sh * fail unit tests fast * switch back to torch 1.2 * remove torch instal link * skip sparse attention tests for now --- .clang-format | 2 +- azure-pipelines.yml | 128 +++++---- deepspeed/__init__.py | 11 +- deepspeed/ops/sparse_attention/matmul.py | 6 +- deepspeed/ops/sparse_attention/softmax.py | 6 +- install.sh | 23 +- requirements/requirements-dev.txt | 4 + requirements/requirements-sparse-attn.txt | 1 + .../requirements.txt | 5 - setup.py | 261 ++++++++++++------ ..._attention.py => skip_sparse_attention.py} | 0 11 files changed, 290 insertions(+), 157 deletions(-) create mode 100644 requirements/requirements-dev.txt create mode 100644 requirements/requirements-sparse-attn.txt rename requirements.txt => requirements/requirements.txt (50%) rename tests/unit/{test_sparse_attention.py => skip_sparse_attention.py} (100%) diff --git a/.clang-format b/.clang-format index 9b547c1a18fe..9f90836e1f2a 100755 --- a/.clang-format +++ b/.clang-format @@ -20,7 +20,7 @@ AllowShortLoopsOnASingleLine: true AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: Yes +AlwaysBreakTemplateDeclarations: true BinPackArguments: false BinPackParameters: false BraceWrapping: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ba6502606ee8..207b00de543c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,49 +1,83 @@ jobs: -- job: Default +- job: DeepSpeed_Tests timeoutInMinutes: 360 pool: - name: 'GPU_testing' + name: 'DS_testing' strategy: matrix: - Python36: + PyTorch12-CUDA100: python.version: '3.6' - #Python35: - # python.version: '3.5' - #Python37: + cuda.version: '10.0' + pytorch.version: '1.2' + torchvision.version: '0.4.0' + runmodeltests: true + #PyTorch15-CUDA101: # python.version: '3.7' - #Python38: - # python.version: '3.8' + # cuda.version: '10.1' + # pytorch.version: '1.5.0+cu101' + # torchvision.version: '0.6.0+cu101' + # runmodeltests: true + ##PyTorch15-CUDA102: + # python.version: '3.7' + # cuda.version: '10.2' + # pytorch.version: '1.5' + # torchvision.version: '0.6.1' + # runmodeltests: true + variables: + conda_env: 'ds_test_py$(python.version)_cuda$(cuda.version)_pytorch$(pytorch.version)' steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' - addToPath: true - architecture: 'x64' - displayName: 'Use Python $(python.version)' + # Unfortunately nvidia's nvcc_linux-64= seems to install 10.1 regardless? + # Most of this complexity is a workaround to get the compiler toolchain to match the + # cudatoolkit runtime + - script: | + conda create --force --yes -n $(conda_env) python=$(python.version) cudatoolkit=$(cuda.version) + source activate $(conda_env) + conda install -q --yes conda + conda install -q --yes pip + conda install -q --yes gxx_linux-64 + if [[ $(cuda.version) != "10.2" ]]; then conda install --yes -c conda-forge cudatoolkit-dev=$(cuda.version) ; fi + displayName: 'Setup environment python=$(python.version) pytorch=$(pytorch.version) cuda=$(cuda.version)' + # Manually install torch/torchvision first to enforce versioning. - script: | - python -m pip install --upgrade pip - pip install --user -r requirements.txt - ./install.sh --pip_sudo - displayName: 'Install dependencies' + source activate $(conda_env) + pip install --progress-bar=off torch==$(pytorch.version) torchvision==$(torchvision.version) + #-f https://download.pytorch.org/whl/torch_stable.html + ./install.sh --local_only + #python -I basic_install_test.py + displayName: 'Install DeepSpeed' - script: | - pre-commit run --all-files - displayName: 'Formatting checks' + source activate $(conda_env) + which python + python --version + which nvcc + nvcc --version + which deepspeed + python -c "import torch; print('torch:', torch.__version__, torch)" + python -c "import torch; print('CUDA available:', torch.cuda.is_available())" + python -c "import deepspeed; print('deepspeed:', deepspeed.__version__)" + displayName: 'Show environment' + - script: | - pytest --forked --verbose tests/unit/ + source activate $(conda_env) + pytest --durations=0 --forked --verbose -x tests/unit/ displayName: 'Unit tests' - script: | + source activate $(conda_env) ln -s /data/Megatron-LM/data DeepSpeedExamples/Megatron-LM/ - pip install --user -r DeepSpeedExamples/Megatron-LM/requirements.txt + pip install --progress-bar=off -r DeepSpeedExamples/Megatron-LM/requirements.txt cd tests/model/ - pytest -s run_sanity_check.py + rm -rf BingBertSquad/baseline + rm -rf Megatron_GPT2/baseline + pytest --durations=0 -s run_sanity_check.py + condition: and(succeeded(), eq(variables['runmodeltests'], true)) displayName: 'Model tests' #BingBertSquad logs @@ -52,35 +86,29 @@ jobs: targetPath: '$(Build.SourcesDirectory)/tests/model/BingBertSquad/test/' artifactName: BingBertSquad_logs displayName: 'BingBertSquad log uploads' - condition: always() + condition: eq(variables['runmodeltests'], true) - # Megatron test logs - #- task: PublishPipelineArtifact@1 - # inputs: - # targetPath: '$(Build.SourcesDirectory)/tests/model/Megatron_GPT2/test/' - # artifactName: Megatron_GPT2_logs - # displayName: 'Megatron GPT2 log uploads' - # condition: always() - #- task: PublishPipelineArtifact@1 - # inputs: - # targetPath: '$(Build.SourcesDirectory)/tests/model/Megatron_GPT2/checkpoint_test_logs/' - # artifactName: Megatron_GPT2_checkpoint_logs - # displayName: 'Megatron GPT2 checkpoint log uploads' - # condition: always() +- job: Code_Quality_Checks + pool: + name: 'DS_testing' + variables: + conda_env: 'ds_codetest' + steps: + - script: | + conda create --force --yes -n $(conda_env) python=3.7 + source activate $(conda_env) + displayName: 'Create code test environment' - #BingBert logs - #- task: PublishPipelineArtifact@1 - # inputs: - # targetPath: '$(Build.SourcesDirectory)/tests/model/bing_bert/pretrain_test/' - # artifactName: BingBert_pretrain_logs - # displayName: 'BingBert pretrain logs' - # condition: always() + - script: | + source activate $(conda_env) + pip install pre-commit + pre-commit run --all-files + displayName: 'Formatting checks' - #- task: PublishPipelineArtifact@1 - # inputs: - # targetPath: '$(Build.SourcesDirectory)/tests/model/bing_bert/checkpoint_test_logs/' - # artifactName: BingBert_checkpoint_logs - # displayName: 'BingBert checkpoint logs' - # condition: always() + - script: | + source activate $(conda_env) + pip install pylint + pylint --exit-zero deepspeed/ + displayName: 'Code linter' diff --git a/deepspeed/__init__.py b/deepspeed/__init__.py index 1583b429266b..de5d1efcd1aa 100755 --- a/deepspeed/__init__.py +++ b/deepspeed/__init__.py @@ -13,20 +13,23 @@ from deepspeed.utils import logger try: - from deepspeed.git_version_info import git_hash, git_branch + from deepspeed.git_version_info import version, git_hash, git_branch except ImportError: + version = "0.0.0+unknown" git_hash = None git_branch = None # Export version information -__version_major__ = 0 -__version_minor__ = 3 -__version_patch__ = 0 +version, __version_tag__ = version.split('+') +__version_major__ = int(version.split('.')[0]) +__version_minor__ = int(version.split('.')[1]) +__version_patch__ = int(version.split('.')[2]) __version__ = '.'.join( map(str, [__version_major__, __version_minor__, __version_patch__])) +__version__ = f"{__version__}+{__version_tag__}" __git_hash__ = git_hash __git_branch__ = git_branch diff --git a/deepspeed/ops/sparse_attention/matmul.py b/deepspeed/ops/sparse_attention/matmul.py index db4ce1399594..d60f967d38f3 100644 --- a/deepspeed/ops/sparse_attention/matmul.py +++ b/deepspeed/ops/sparse_attention/matmul.py @@ -1,7 +1,11 @@ # DeepSpeed note, code taken & adapted from commit 9aa94789f13ada713af36cfd8cca2fc9a7f6b79a # https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py import importlib -import triton +import warnings +try: + import triton +except ImportError: + warnings.warn("Unable to import triton, sparse attention will not be accessible") import torch import math from deepspeed.ops.sparse_attention.trsrc import matmul diff --git a/deepspeed/ops/sparse_attention/softmax.py b/deepspeed/ops/sparse_attention/softmax.py index b722fb32a2d8..814e9cc50e19 100644 --- a/deepspeed/ops/sparse_attention/softmax.py +++ b/deepspeed/ops/sparse_attention/softmax.py @@ -1,7 +1,11 @@ # DeepSpeed note, code taken & adapted from commit 9aa94789f13ada713af36cfd8cca2fc9a7f6b79a # https://github.com/ptillet/torch-blocksparse/blob/master/torch_blocksparse/matmul.py -import triton +import warnings +try: + import triton +except ImportError: + warnings.warn("Unable to import triton, sparse attention will not be accessible") import torch import math from deepspeed.ops.sparse_attention.trsrc import softmax_fwd, softmax_bwd diff --git a/install.sh b/install.sh index 6acedda5e5f7..3dae80b4033b 100755 --- a/install.sh +++ b/install.sh @@ -147,11 +147,6 @@ if [ "$no_clean" == "0" ]; then rm_if_exist third_party/apex/apex.egg-info fi -echo "Updating git hash/branch info" -echo "git_hash = '$(git rev-parse --short HEAD)'" > deepspeed/git_version_info.py -echo "git_branch = '$(git rev-parse --abbrev-ref HEAD)'" >> deepspeed/git_version_info.py -cat deepspeed/git_version_info.py - if [ "$pip_sudo" == "1" ]; then PIP_SUDO="sudo -H" else @@ -159,7 +154,7 @@ else fi if [ "$pip_mirror" != "" ]; then - PIP_INSTALL="pip install -v -i $pip_mirror" + PIP_INSTALL="pip install --use-feature=2020-resolver -v -i $pip_mirror" else PIP_INSTALL="pip install -v" fi @@ -169,10 +164,10 @@ if [ ! -f $hostfile ]; then local_only=1 fi -if [ "$skip_requirements" == "0" ]; then - # Ensure dependencies are installed locally - $PIP_SUDO $PIP_INSTALL -r requirements.txt -fi +#if [ "$skip_requirements" == "0" ]; then +# # Ensure dependencies are installed locally +# $PIP_SUDO $PIP_INSTALL -r requirements.txt +#fi # Build wheels if [ "$third_party_install" == "1" ]; then @@ -225,10 +220,10 @@ else tmp_wheel_path="/tmp/deepspeed_wheels" pdsh -w $hosts "if [ -d $tmp_wheel_path ]; then rm $tmp_wheel_path/*.whl; else mkdir -pv $tmp_wheel_path; fi" - pdcp -w $hosts requirements.txt ${tmp_wheel_path}/ - if [ "$skip_requirements" == "0" ]; then - pdsh -w $hosts "$PIP_SUDO $PIP_INSTALL -r ${tmp_wheel_path}/requirements.txt" - fi + #pdcp -w $hosts requirements/*.txt ${tmp_wheel_path}/ + #if [ "$skip_requirements" == "0" ]; then + # pdsh -w $hosts "$PIP_SUDO $PIP_INSTALL -r ${tmp_wheel_path}/requirements.txt" + #fi if [ "$third_party_install" == "1" ]; then pdsh -w $hosts "$PIP_SUDO pip uninstall -y apex" pdcp -w $hosts third_party/apex/dist/apex*.whl $tmp_wheel_path/ diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt new file mode 100644 index 000000000000..b6a873656eac --- /dev/null +++ b/requirements/requirements-dev.txt @@ -0,0 +1,4 @@ +pytest +pytest-forked +pre-commit +clang-format diff --git a/requirements/requirements-sparse-attn.txt b/requirements/requirements-sparse-attn.txt new file mode 100644 index 000000000000..5a012208c26b --- /dev/null +++ b/requirements/requirements-sparse-attn.txt @@ -0,0 +1 @@ +triton>=0.2.2 diff --git a/requirements.txt b/requirements/requirements.txt similarity index 50% rename from requirements.txt rename to requirements/requirements.txt index ba1deab48f91..63f0022b314d 100644 --- a/requirements.txt +++ b/requirements/requirements.txt @@ -3,8 +3,3 @@ torchvision>=0.4.0 tqdm psutil tensorboardX==1.8 -pytest -pytest-forked -pre-commit -clang-format -triton>=0.2.2 diff --git a/setup.py b/setup.py index d2f90e678c83..3d57e8791da8 100755 --- a/setup.py +++ b/setup.py @@ -10,9 +10,54 @@ import os import torch +import subprocess +import warnings from setuptools import setup, find_packages from torch.utils.cpp_extension import CUDAExtension, BuildExtension, CppExtension +VERSION = "0.3.0" + + +def fetch_requirements(path): + with open(path, 'r') as fd: + return [r.strip() for r in fd.readlines()] + + +install_requires = fetch_requirements('requirements/requirements.txt') +dev_requires = fetch_requirements('requirements/requirements-dev.txt') +sparse_attn_requires = fetch_requirements('requirements/requirements-sparse-attn.txt') + +# Build environment variables for custom builds +DS_BUILD_LAMB_MASK = 1 +DS_BUILD_TRANSFORMER_MASK = 10 +DS_BUILD_SPARSE_ATTN_MASK = 100 + +# Allow for build_cuda to turn on or off all ops +DS_BUILD_ALL_OPS = DS_BUILD_LAMB_MASK | DS_BUILD_TRANSFORMER_MASK | DS_BUILD_SPARSE_ATTN_MASK +DS_BUILD_CUDA = int(os.environ.get('DS_BUILD_CUDA', 1)) * DS_BUILD_ALL_OPS + +# Set default of each op based on if build_cuda is set +OP_DEFAULT = DS_BUILD_CUDA == DS_BUILD_ALL_OPS +DS_BUILD_LAMB = int(os.environ.get('DS_BUILD_LAMB', OP_DEFAULT)) * DS_BUILD_LAMB_MASK +DS_BUILD_TRANSFORMER = int(os.environ.get('DS_BUILD_TRANSFORMER', + OP_DEFAULT)) * DS_BUILD_TRANSFORMER_MASK +DS_BUILD_SPARSE_ATTN = int(os.environ.get('DS_BUILD_SPARSE_ATTN', + 0)) * DS_BUILD_SPARSE_ATTN_MASK + +# Final effective mask is the bitwise OR of each op +BUILD_MASK = (DS_BUILD_LAMB | DS_BUILD_TRANSFORMER | DS_BUILD_SPARSE_ATTN) + +install_ops = [] +if BUILD_MASK & DS_BUILD_LAMB: + install_ops.append('lamb') +if BUILD_MASK & DS_BUILD_TRANSFORMER: + install_ops.append('transformer') +if BUILD_MASK & DS_BUILD_SPARSE_ATTN: + install_ops.append('sparse-attn') +if len(install_ops) == 0: + print("Building without any cuda/cpp extensions") +print(f'BUILD_MASK={BUILD_MASK}, install_ops={install_ops}') + cmdclass = {} cmdclass['build_ext'] = BuildExtension.with_options(use_ninja=False) @@ -43,98 +88,147 @@ ext_modules = [] ## Lamb ## -ext_modules.append( - CUDAExtension( - name='deepspeed.ops.lamb.fused_lamb_cuda', - sources=['csrc/lamb/fused_lamb_cuda.cpp', - 'csrc/lamb/fused_lamb_cuda_kernel.cu'], - include_dirs=['csrc/includes'], - extra_compile_args={ - 'cxx': [ - '-O3', - ] + version_dependent_macros, - 'nvcc': ['-O3', - '--use_fast_math'] + version_dependent_macros - })) +if BUILD_MASK & DS_BUILD_LAMB: + ext_modules.append( + CUDAExtension(name='deepspeed.ops.lamb.fused_lamb_cuda', + sources=[ + 'csrc/lamb/fused_lamb_cuda.cpp', + 'csrc/lamb/fused_lamb_cuda_kernel.cu' + ], + include_dirs=['csrc/includes'], + extra_compile_args={ + 'cxx': [ + '-O3', + ] + version_dependent_macros, + 'nvcc': ['-O3', + '--use_fast_math'] + version_dependent_macros + })) ## Transformer ## -ext_modules.append( - CUDAExtension(name='deepspeed.ops.transformer.transformer_cuda', - sources=[ - 'csrc/transformer/ds_transformer_cuda.cpp', - 'csrc/transformer/cublas_wrappers.cu', - 'csrc/transformer/transform_kernels.cu', - 'csrc/transformer/gelu_kernels.cu', - 'csrc/transformer/dropout_kernels.cu', - 'csrc/transformer/normalize_kernels.cu', - 'csrc/transformer/softmax_kernels.cu', - 'csrc/transformer/general_kernels.cu' - ], - include_dirs=['csrc/includes'], - extra_compile_args={ - 'cxx': ['-O3', +if BUILD_MASK & DS_BUILD_TRANSFORMER: + ext_modules.append( + CUDAExtension(name='deepspeed.ops.transformer.transformer_cuda', + sources=[ + 'csrc/transformer/ds_transformer_cuda.cpp', + 'csrc/transformer/cublas_wrappers.cu', + 'csrc/transformer/transform_kernels.cu', + 'csrc/transformer/gelu_kernels.cu', + 'csrc/transformer/dropout_kernels.cu', + 'csrc/transformer/normalize_kernels.cu', + 'csrc/transformer/softmax_kernels.cu', + 'csrc/transformer/general_kernels.cu' + ], + include_dirs=['csrc/includes'], + extra_compile_args={ + 'cxx': ['-O3', + '-std=c++14', + '-g', + '-Wno-reorder'], + 'nvcc': [ + '-O3', + '--use_fast_math', + '-gencode', + 'arch=compute_61,code=compute_61', + '-gencode', + 'arch=compute_70,code=compute_70', '-std=c++14', - '-g', - '-Wno-reorder'], - 'nvcc': [ - '-O3', - '--use_fast_math', - '-gencode', - 'arch=compute_61,code=compute_61', - '-gencode', - 'arch=compute_70,code=compute_70', - '-std=c++14', - '-U__CUDA_NO_HALF_OPERATORS__', - '-U__CUDA_NO_HALF_CONVERSIONS__', - '-U__CUDA_NO_HALF2_OPERATORS__' - ] - })) -ext_modules.append( - CUDAExtension(name='deepspeed.ops.transformer.stochastic_transformer_cuda', - sources=[ - 'csrc/transformer/ds_transformer_cuda.cpp', - 'csrc/transformer/cublas_wrappers.cu', - 'csrc/transformer/transform_kernels.cu', - 'csrc/transformer/gelu_kernels.cu', - 'csrc/transformer/dropout_kernels.cu', - 'csrc/transformer/normalize_kernels.cu', - 'csrc/transformer/softmax_kernels.cu', - 'csrc/transformer/general_kernels.cu' - ], - include_dirs=['csrc/includes'], - extra_compile_args={ - 'cxx': ['-O3', + '-U__CUDA_NO_HALF_OPERATORS__', + '-U__CUDA_NO_HALF_CONVERSIONS__', + '-U__CUDA_NO_HALF2_OPERATORS__' + ] + })) + ext_modules.append( + CUDAExtension(name='deepspeed.ops.transformer.stochastic_transformer_cuda', + sources=[ + 'csrc/transformer/ds_transformer_cuda.cpp', + 'csrc/transformer/cublas_wrappers.cu', + 'csrc/transformer/transform_kernels.cu', + 'csrc/transformer/gelu_kernels.cu', + 'csrc/transformer/dropout_kernels.cu', + 'csrc/transformer/normalize_kernels.cu', + 'csrc/transformer/softmax_kernels.cu', + 'csrc/transformer/general_kernels.cu' + ], + include_dirs=['csrc/includes'], + extra_compile_args={ + 'cxx': ['-O3', + '-std=c++14', + '-g', + '-Wno-reorder'], + 'nvcc': [ + '-O3', + '--use_fast_math', + '-gencode', + 'arch=compute_61,code=compute_61', + '-gencode', + 'arch=compute_70,code=compute_70', '-std=c++14', - '-g', - '-Wno-reorder'], - 'nvcc': [ - '-O3', - '--use_fast_math', - '-gencode', - 'arch=compute_61,code=compute_61', - '-gencode', - 'arch=compute_70,code=compute_70', - '-std=c++14', - '-U__CUDA_NO_HALF_OPERATORS__', - '-U__CUDA_NO_HALF_CONVERSIONS__', - '-U__CUDA_NO_HALF2_OPERATORS__', - '-D__STOCHASTIC_MODE__' - ] - })) + '-U__CUDA_NO_HALF_OPERATORS__', + '-U__CUDA_NO_HALF_CONVERSIONS__', + '-U__CUDA_NO_HALF2_OPERATORS__', + '-D__STOCHASTIC_MODE__' + ] + })) + + +def command_exists(cmd): + result = subprocess.Popen(f'type {cmd}', stdout=subprocess.PIPE, shell=True) + return result.wait() == 0 + ## Sparse transformer ## -ext_modules.append( - CppExtension(name='deepspeed.ops.sparse_attention.cpp_utils', - sources=['csrc/sparse_attention/utils.cpp'], - extra_compile_args={'cxx': ['-O2', - '-fopenmp']})) +if BUILD_MASK & DS_BUILD_SPARSE_ATTN: + # Check to see if llvm and cmake are installed since they are dependencies + required_commands = ['llc-9', 'cmake'] + + command_status = list(map(command_exists, required_commands)) + if not all(command_status): + zipped_status = list(zip(required_commands, command_status)) + warnings.warn( + f'Missing non-python requirements, please install the missing packages: {zipped_status}' + ) + warnings.warn( + 'Skipping sparse attention installation due to missing required packages') + elif TORCH_MAJOR == 1 and TORCH_MINOR >= 5: + ext_modules.append( + CppExtension(name='deepspeed.ops.sparse_attention.cpp_utils', + sources=['csrc/sparse_attention/utils.cpp'], + extra_compile_args={'cxx': ['-O2', + '-fopenmp']})) + # Add sparse attention requirements + install_requires += sparse_attn_requires + else: + warnings.warn('Unable to meet requirements to install sparse attention') + +# Add development requirements +install_requires += dev_requires + +# Write out version/git info +git_hash_cmd = "git rev-parse --short HEAD" +git_branch_cmd = "git rev-parse --abbrev-ref HEAD" +if command_exists('git'): + result = subprocess.check_output(git_hash_cmd, shell=True) + git_hash = result.decode('utf-8').strip() + result = subprocess.check_output(git_branch_cmd, shell=True) + git_branch = result.decode('utf-8').strip() +else: + git_hash = "unknown" + git_branch = "unknown" +print(f"version={VERSION}+{git_hash}, git_hash={git_hash}, git_branch={git_branch}") +with open('deepspeed/git_version_info.py', 'w') as fd: + fd.write(f"version='{VERSION}+{git_hash}'\n") + fd.write(f"git_hash='{git_hash}'\n") + fd.write(f"git_branch='{git_branch}'\n") + +print(f'install_requires={install_requires}') setup(name='deepspeed', - version='0.3.0', + version=f"{VERSION}+{git_hash}", description='DeepSpeed library', author='DeepSpeed Team', author_email='deepspeed@microsoft.com', url='http://aka.ms/deepspeed', + install_requires=install_requires, packages=find_packages(exclude=["docker", "third_party", "csrc"]), @@ -143,6 +237,11 @@ 'bin/deepspeed.pt', 'bin/ds', 'bin/ds_ssh'], - classifiers=['Programming Language :: Python :: 3.6'], + classifiers=[ + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8' + ], + license='MIT', ext_modules=ext_modules, cmdclass=cmdclass) diff --git a/tests/unit/test_sparse_attention.py b/tests/unit/skip_sparse_attention.py similarity index 100% rename from tests/unit/test_sparse_attention.py rename to tests/unit/skip_sparse_attention.py

P)M0bkw(-xuH4LdjkCEu)3VkPZ4Fy}CDC{+O2X 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