diff --git a/prototype_source/semi_structured_sparse.rst b/prototype_source/semi_structured_sparse.rst index c7b82fd43..f00839799 100644 --- a/prototype_source/semi_structured_sparse.rst +++ b/prototype_source/semi_structured_sparse.rst @@ -1,31 +1,32 @@ -(prototype) Accelerating BERT with semi-structured (2:4) sparsity +(프로토타입) 반정형적 (2:4) 희소성(semi-structured (2:4) sparsity)을 이용한 BERT 가속화하기 ================================================================= -**Author**: `Jesse Cai `_ +**저자**: `Jesse Cai `_ +**번역**: `Dabin Kang `_ -Like other forms of sparsity, **semi-structured sparsity** is a model optimization technique that seeks to reduce the memory overhead and latency of a neural network at the expense of some model accuracy. -It is also known as **fine-grained structured sparsity** or **2:4 structured sparsity**. +다른 형태의 희소성처럼, **반정형적 희소성(semi-structured sparsity)**은 메모리 오버헤드와 지연 시간을 줄이기 위한 모델 최적화 기법으로, 일부 모델 정확도를 희생하면서 이점을 얻습니다. +반정형적 희소성은 **fine-grained structured sparsity** 또는 **2:4 structured sparsity**라고도 불립니다. -Semi-structured sparsity derives its name from its unique sparsity pattern, where n out of every 2n elements are pruned. We most often see n=2, hence 2:4 sparsity -Semi-structured sparsity is particularly interesting because it can be efficiently accelerated on GPUs and doesn't degrade model accuracy as much as other sparsity patterns. +반정형적 희소성은 2n개의 요소 중 n개의 요소가 제거되는 독특한 희소성 패턴에서 그 이름을 따왔습니다. 가장 일반적으로 n=2가 적용되므로 2:4 희소성이라고 불립니다. +반정형적 희소성은 특히 GPU에서 효율적으로 가속화될 수 있고, 다른 희소성 패턴보다 모델의 정확도를 덜 저하시키기 때문에 흥미롭습니다. -With the introduction of `semi-structured sparsity support `_, it is possible to prune and accelerate a semi-structured sparse model without leaving PyTorch. -We will explain this process in this tutorial. +`반정형적 희소성 지원 `_으로, PyTorch 환경에서 반정형적 희소 모델을 가지치기하고 가속화할 수 있습니다. +이 튜토리얼에서 그 과정을 설명하겠습니다. .. image:: ../../_static/img/pruning_flow.jpg -By the end of this tutorial, we will have sparsified a BERT question-answering model to be 2:4 sparse, fine-tuning it to recover nearly all F1 loss (86.92 dense vs 86.48 sparse). -Finally, we will accelerate this 2:4 sparse model for inference, yielding a 1.3x speedup. +이 튜토리얼을 끝내면, 2:4 희소성으로 가지치기하고, 거의 모든 F1 손실(밀집 86.92 vs 희소 86.48)을 복구하도록 미세 조정한 BERT 질문-답변 모델이 완성됩니다. +마지막으로, 이 2:4 희소 모델을 추론 단계에서 가속화하여 1.3배의 속도 향상을 달성할 것입니다. -Requirements +요구 사항 -------------- * PyTorch >= 2.1. -* A NVIDIA GPU with semi-structured sparsity support (Compute Capability 8.0+). +* 반정형적 희소성을 지원하는 NVIDIA GPU (Compute Capability 8.0+). .. note:: - This tutorial is designed for beginners to semi-structured sparsity / sparsity in general. - For users with existing 2:4 sparse models, accelerating ``nn.Linear`` layers for inference with ``to_sparse_semi_structured`` is as easy as: + 이 튜토리얼은 반정형적 희소성 또는 일반적인 희소성에 익숙하지 않은 초보자를 위해 설계되었습니다. + 기존 2:4 희소 모델이 있다면, ``to_sparse_semi_structured``를 사용하여 ``nn.Linear`` 레이어를 추론을 위해 가속화하면 간단합니다 : .. code:: python @@ -34,7 +35,7 @@ Requirements from torch.utils.benchmark import Timer SparseSemiStructuredTensor._FORCE_CUTLASS = True - # mask Linear weight to be 2:4 sparse + # 2:4 희소성을 가지도록 Linear 가중치에 마스크 적용 mask = torch.Tensor([0, 0, 1, 1]).tile((3072, 2560)).cuda().bool() linear = torch.nn.Linear(10240, 3072).half().cuda().eval() linear.weight = torch.nn.Parameter(mask * linear.weight) @@ -47,7 +48,7 @@ Requirements globals={"linear": linear, "x": x}).blocked_autorange().median * 1e3 - # accelerate via SparseSemiStructuredTensor + # SparseSemiStructuredTensor로 가속화 linear.weight = torch.nn.Parameter(to_sparse_semi_structured(linear.weight)) sparse_output = linear(x) @@ -55,38 +56,38 @@ Requirements globals={"linear": linear, "x": x}).blocked_autorange().median * 1e3 - # sparse and dense matmul are numerically equivalent + # 희소성과 밀집 행렬 곱셈(dense matmul)은 수치적으로 동일 assert torch.allclose(sparse_output, dense_output, atol=1e-3) print(f"Dense: {dense_t:.3f}ms Sparse: {sparse_t:.3f}ms | Speedup: {(dense_t / sparse_t):.3f}x") - On an A100 80GB, we see: `Dense: 0.870ms Sparse: 0.630ms | Speedup: 1.382x` + A100 80GB에서의 결과 : `Dense: 0.870ms Sparse: 0.630ms | Speedup: 1.382x` -What problem does semi-structured sparsity solve? +반정형적 희소성이 해결하는 문제는 무엇인가? ------------------------------------------------- -The general motivation behind sparsity is simple: if there are zeros in your network, you can avoid storing / doing compute with those parameters. -However, the specifics of sparsity are tricky. Zeroing out parameters doesn't affect the latency / memory overhead of our model out of the box. +희소성의 일반적인 동기는 간단합니다: 네트워크에 0이 있는 경우 해당 매개변수를 저장하거나 계산하지 않도록 할 수 있습니다. +하지만 희소성의 구체적인 내용은 까다롭습니다. 매개변수를 0으로 만들면 별도의 과정 없이는 모델의 지연 시간이나 메모리 오버헤드에 영향을 미치지 않습니다. -This is because the dense tensor still contains the pruned (zero) elements, which the dense matrix multiplication kernel will still operate on this elements. -In order to realize performance gains, we need to swap out dense kernels for sparse kernels, which skip calculation involving pruned elements. +이는 밀집 tensor에 여전히 가지치기된(제로) 요소가 포함되어 있어, 밀집 행렬 곱셈 커널이 여전히 이러한 요소를 계산하기 때문입니다. +성능 향상을 얻으려면, 가지치기된 요소 계산을 건너뛰는 희소 커널로 밀집 커널을 교체해야 합니다. -To do this, these kernels work on sparse matrices, which do not store the pruned elements and store the specified elements in a compressed format. +이를 위해 이러한 커널은 가지치기된 요소를 저장하지 않고 지정된 요소를 압축된 형식으로 저장하는 희소 행렬에서 작동합니다. -For semi-structured sparsity, we store exactly half of the original parameters along with some compressed metadata about how the elements were arranged. +반정형적 희소성에서는 원래 매개변수의 정확히 절반을 압축된 메타데이터와 함께 저장하여 요소가 어떻게 배열되었는지에 대한 정보를 제공합니다. .. image:: https://developer-blogs.nvidia.com/wp-content/uploads/2023/06/2-4-structured-sparsity-pattern.png :align: center :width: 80% - Image sourced from `NVIDIA blog post `_ on semi-structured sparsity. + 이미지 출처는 반정형적 희소성에 대한 `NVIDIA blog post `_ 입니다. -There are many different sparse layouts, each with their own benefits and drawbacks. The 2:4 semi-structured sparse layout is particularly interesting for two reasons: -1. Unlike previous sparse formats, semi-structured sparsity was designed to be efficiently accelerated on GPUs. - In 2020, NVIDIA introduced hardware support for semi-structured sparsity with their Ampere architecture, and have also released fast sparse kernels via CUTLASS/`cuSPARSELt `_. -2. At the same time, semi-structured sparsity tends to have a milder impact on model accuracy compared to other sparse formats, especially when accounting for more advanced pruning / fine-tuning methods. - NVIDIA has shown in their `white paper `_ that a simple paradigm of magnitude pruning once to be 2:4 sparse and then retraining the model yields nearly identical model accuracies. +각기 다른 장단점을 가진 여러 가지 희소성 구조들이 있습니다. 특히 2:4 반정형적 희소 레이아웃은 두 가지 이유로 흥미롭습니다: +1. 이전의 희소 형식과 달리 반정형적 희소성은 GPU에서 효율적으로 가속화되도록 설계되었습니다. + 2020년, NVIDIA는 Ampere 아키텍처와 함께 반정형적 희소성을 지원하는 하드웨어를 도입했으며, CUTLASS/`cuSPARSELt `_를 통해 빠른 희소 커널도 출시했습니다. +2. 동시에, 특히 더 발전된 가지치기 및 미세 조정 방법을 고려할 때, 반정형적 희소성은 다른 희소 형식에 비해 모델 정확도에 미치는 영향이 적습니다. + NVIDIA는 `white paper `_에서 2:4 희소성을 위한 크기 기반 가지치기와 재학습하는 단순한 패러다임을 통해 거의 동일한 모델 정확도를 얻을 수 있음을 보여주었습니다. -Semi-structured exists in a sweet spot, providing a 2x (theoretical) speedup at a much lower sparsity level (50%), while still being granular enough to preserve model accuracy. +반정형적 희소성은 50%라는 낮은 희소성 수준에서 2배의 이론적인 속도 향상을 제공하며, 모델 정확도를 유지할 수 있을 만큼 충분히 세밀합니다. +---------------------+-------------+--------+------------+-------------+ @@ -107,11 +108,11 @@ Semi-structured exists in a sweet spot, providing a 2x (theoretical) speedup at | BERT-Large | SQuAD v1.1 | F1 | 91.9 | 91.9 | +---------------------+-------------+--------+------------+-------------+ -Semi-structured sparsity has an additional advantage from a workflow perspective. -Because the sparsity level is fixed at 50%, it is easier to decompose the problem of sparsifying a model into two distinct subproblems: +반정형적 희소성은 워크플로우 관점에서도 추가적인 이점이 있습니다. +희소성 수준이 50%로 고정되어 있어 모델을 희소화하는 문제를 두 가지 하위 문제로 분리하기가 더 쉬워집니다: -* Accuracy - How can we find a set of 2:4 sparse weights that minimize the accuracy degradation of our model? -* Performance - How can we accelerate our 2:4 sparse weights for inference and reduced memory overhead? +* 정확도 - 모델의 정확도 저하를 최소화할 수 있는 2:4 희소 가중치 세트를 어떻게 찾을 수 있을까요? +* 성능 - 추론을 위해 2:4 희소 가중치를 어떻게 가속화하고 메모리 오버헤드를 줄일 수 있을까요? .. math:: \begin{bmatrix} @@ -121,14 +122,14 @@ Because the sparsity level is fixed at 50%, it is easier to decompose the proble 0 & 0 & 1 & 1 \\ \end{bmatrix} -The natural handoff point between these two problems are zeroed-out dense tensors. Our inference solution is designed to compress and accelerate tensors in this format. -We anticipate many users coming up with custom masking solution, as this is an active area of research. +이 두 문제 사이의 자연스러운 핸드오프(handoff) 포인트는 0으로 된 밀집 tensor입니다. 이 형식의 tensor를 압축하고 가속화하도록 추론을 설계했습니다. +활발한 연구분야인 만큼 많은 사용자가 맞춤형 마스킹 해결책을 고안할 것으로 예상합니다. -Now that we've learned a little more about semi-structured sparsity, let's apply it to a BERT model trained on a question answering task, SQuAD. +이제 반정형적 희소성에 대해 조금 더 배웠으니, 질문 답변 작업인 SQuAD에서 학습된 BERT 모델에 이를 적용해 봅시다. -Intro & Setup +소개 & 설정 ------------- -Let's start by importing all the packages we need. +우선 필요한 모든 패키지를 불러옵시다. .. code:: python @@ -143,12 +144,12 @@ Let's start by importing all the packages we need. from torch.ao.pruning import WeightNormSparsifier import transformers - # force CUTLASS use if cuSPARSELt is not available + # cuSPARSELt가 사용 불가능한 경우 CUTLASS 사용을 강제 SparseSemiStructuredTensor._FORCE_CUTLASS = True torch.manual_seed(100) -We'll also need to define some helper functions that are specific to the dataset / task at hand. -These were adapted from `this `_ huggingface course as a reference. +또한 데이터셋과 작업에 특정한 몇 가지 함수를 직접 정의해야 합니다. +`이 `_ huggingface 코스에서 참조했습니다. .. code:: python @@ -198,7 +199,7 @@ These were adapted from `this end_char or offset[context_end][1] < start_char: start_positions.append(0) end_positions.append(0) else: - # Otherwise it's the start and end token positions + # 그렇지 않으면 시작 및 끝 토큰 위치로 라벨링하기 idx = context_start while idx <= context_end and offset[idx][0] <= start_char: idx += 1 @@ -244,7 +245,7 @@ These were adapted from `this max_answer_length + # 길이가 < 0 이거나 + # 또는 > 최대 답변 길이(max_answer_length)인 답변 건너뛰기 if ( end_index < start_index or end_index - start_index + 1 > max_answer_length @@ -273,7 +274,7 @@ These were adapted from `this 0: best_answer = max(answers, key=lambda x: x["logit_score"]) predicted_answers.append( @@ -287,7 +288,7 @@ These were adapted from `this `_, and the task-specific nn.Linear layers do not satisfy them. +또한, 어떤 레이어에 희소성을 적용할지 결정해야 하는데, 이 경우에는 작업 특화 헤드 출력 레이어를 제외한 모든 `nn.Linear` 레이어입니다. +이는 반정형적 희소성이 `형태 제약 `_이 있기 때문이며, 작업 특화 nn.Linear 레이어는 이러한 제약을 만족하지 못합니다. .. code:: python sparsifier = WeightNormSparsifier( - # apply sparsity to all blocks + # 모든 블록에 희소성을 적용 sparsity_level=1.0, - # shape of 4 elemens is a block + # 4개 요소의 블록 형태 sparse_block_shape=(1, 4), - # two zeros for every block of 4 + # 4 블록당 두 개의 0 zeros_per_block=2 ) - # add to config if nn.Linear and in the BERT model. + # BERT 모델에서 nn.Linear가 존재하는 경우 설정에 추가 sparse_config = [ {"tensor_fqn": f"{fqn}.weight"} for fqn, module in model.named_modules() if isinstance(module, nn.Linear) and "layer" in fqn ] -The first step for pruning the model is to insert paramterizations for masking the weights of the model. This is done by the prepare step. -Anytime we try to access the ``.weight`` we will get ``mask * weight`` instead. +모델을 가지치기하기 위한 첫 번째 단계는 가중치 마스킹을 위한 매개변수를 삽입하는 단계입니다. 이 단계는 준비 단계로 마무리됩니다. +``.weight``에 접근할 때마다 ``mask * weight``를 얻게 됩니다. .. code:: python - # Prepare the model, insert fake-sparsity parameterizations for training + # 모델 준비, 학습을 위한 가짜-희소성(fake-sparsity) 매개변수 삽입 sparsifier.prepare(model, sparse_config) print(model.bert.encoder.layer[0].output) @@ -436,10 +437,10 @@ Anytime we try to access the ``.weight`` we will get ``mask * weight`` instead. # (dropout): Dropout(p=0.1, inplace=False) # ) -Then, we'll take a single pruning step. All pruners implement a ``update_mask()`` method that updates the mask with the logic being determined by the pruner implementation. -The step method calls this ``update_mask`` functions for the weights specified in the sparse config. +그 다음 가지치기 단계를 한 번 실행합니다. 모든 가지치기는 ``update_mask()`` 메소드를 구현하여 가지치기 구현 논리에 따라 마스크를 업데이트합니다. +step 메소드는 희소 구성에서 지정된 가중치에 대해 이 ``update_mask`` 함수를 호출합니다. -We will also evaluate the model to show the accuracy degradation of zero-shot pruning, or pruning without fine-tuning / retraining. +또한, 미세 조정이나 재학습 없이 가지치기되거나 학습 없이 가지치기된 모델의 정확도 저하를 보여주기 위해 모델을 평가할 것입니다. .. code:: python @@ -455,8 +456,8 @@ We will also evaluate the model to show the accuracy degradation of zero-shot pr print("pruned eval metrics:", pruned) # pruned eval metrics: {'exact_match': 40.59602649006622, 'f1': 56.51610004515979} -In this state, we can start fine-tuning the model, updating the elements that wouldn't be pruned to better account for the accuracy loss. -Once we've reached a satisfied state, we can call ``squash_mask`` to fuse the mask and the weight together. This will remove the parameterizations and we are left with a zeroed-out 2:4 dense model. +이 상태에서 모델을 미세 조정하여 가지치기되지 않을 요소를 업데이트하고, 정확도 손실을 더 잘 반영하도록 합니다. +만족할 만한 상태에 도달하면 ``squash_mask``를 호출하여 마스크와 가중치를 함께 융합할 수 있습니다. 이렇게 하면 매개변수가 제거되고, 2:4로 밀집된 0이 있는 모델이 남게 됩니다. .. code:: python @@ -476,14 +477,14 @@ Once we've reached a satisfied state, we can call ``squash_mask`` to fuse the ma # [ 0.0244, 0.0921, -0.0000, -0.0000, ..., -0.0000, -0.0784, 0.0000, 0.0761], # [ 0.0000, 0.0225, -0.0395, -0.0000, ..., -0.0000, 0.0684, -0.0344, -0.0000]], device='cuda:0', requires_grad=True) -Accelerating 2:4 sparse models for inference +2:4 희소 모델을 추론 단계에서 가속화하기 --------i------------------------------------ -Now that we have a model in this format, we can accelerate it for inference just like in the QuickStart Guide. +이제 모델이 준비되었으므로 QuickStart Guide에서처럼 추론 단계에서 가속화할 수 있습니다. .. code:: python model = model.cuda().half() - # accelerate for sparsity + # 희소성으로 가속화 for fqn, module in model.named_modules(): if isinstance(module, nn.Linear) and "layer" in fqn: module.weight = nn.Parameter(to_sparse_semi_structured(module.weight)) @@ -508,8 +509,8 @@ Now that we have a model in this format, we can accelerate it for inference just # sparse eval metrics: {'exact_match': 78.43897824030275, 'f1': 86.48718950090766} # sparse perf metrics: {4: 12.621004460379481, 16: 15.368514601141214, 64: 58.702805917710066, 256: 244.19364519417286} -Retraining our model after magnitude pruning has recovered nearly all of the F1 that has been lost when the model was pruned. At the same time we have achieved a 1.28x speedup for bs=16. -Note that not all shapes are amenable to performance improvements. When batch sizes are small and limited time is spent in compute sparse kernels may be slower than their dense counterparts. +크기 기반 가지치기(magnitude pruning) 후 모델을 다시 학습하여 가지치기 후 모델에서 손실된 F1의 대부분을 복구할 수 있었습니다. 동시에 bs=16에서 1.28배의 속도 향상을 달성했습니다. +성능 개선에 적합하지 않은 형태도 있습니다. 배치 크기가 작고 계산 시간이 제한적일 때 희소 커널이 밀집 커널보다 느릴 수 있습니다. .. table:: results @@ -530,8 +531,8 @@ Note that not all shapes are amenable to performance improvements. When batch si +--------------------+----------------+--------------+---------------------+ -Conclusion +결론 ---------- -In this tutorial, we have shown how to prune BERT to be 2:4 sparse and how to accelerate a 2:4 sparse model for inference. -By taking advantage of our SparseSemiStructuredTensor subclass, we were able to achieve a 1.3x speedup over the fp16 baseline. -We also demonstrated the benefits of 2:4 sparsity by fine-tuning BERT to recover any lost F1 (86.92 dense vs 86.48 sparse). +이 튜토리얼에서는 BERT를 2:4 희소성으로 가지치기하고, 2:4 희소 모델을 추론 단계에서 가속화하는 방법을 보여주었습니다. +SparseSemiStructuredTensor 하위 클래스를 활용하여 fp16 기본값 대비 1.3배 속도 향상을 달성할 수 있었습니다. +또한 BERT를 미세 조정하여 손실된 F1(밀집 86.92 vs 희소 86.48)을 복구할 수 있음을 입증했습니다. \ No newline at end of file