
텍스트 적대적 공격을 위한 오픈소스 패키지
문서 • 기능 및 사용 • 사용 예시 • 공격 모델 • 도구 키트 디자인
OpenAttack는 텍스트 적대적 공격(adversarial attack)의 전체 과정(텍스트 전처리, 피해자 모델 접근, 적대적 예제 생성 및 평가)을 처리하는 오픈소스 Python 기반 텍스트 적대적 공격 도구 키트입니다.
⭐️ 모든 공격 유형 지원. OpenAttack는 문장/단어/문자 수준의 변조(perturbation) 및 그래디언트/점수/결정 기반/블라인드 공격 모델 등 모든 유형의 공격을 지원합니다.
⭐️ 다국어 지원. OpenAttack는 현재 영어와 중국어를 지원합니다. 확장 가능한 설계로 더 많은 언어를 신속하게 지원할 수 있습니다.
⭐️ 병렬 처리. OpenAttack는 공격 모델의 멀티프로세스 실행을 지원하여 공격 효율성을 향상시킵니다.
⭐️ 🤗 Hugging Face 호환성. OpenAttack는 🤗 Transformers 및 Datasets 라이브러리와 완전히 통합됩니다.
⭐️ 뛰어난 확장성. 사용자 정의 피해자 모델을 사용자 정의 데이터셋에서 쉽게 공격하거나 사용자 정의 공격 모델을 개발 및 평가할 수 있습니다.
✅ 공격 모델을 위한 다양한 편리한 베이스라인 제공
✅ 포괄적인 평가 지표를 사용한 공격 모델의 철저한 평가
✅ 공통 공격 구성 요소를 활용한 새로운 공격 모델의 신속한 개발 지원
✅ 다양한 적대적 공격에 대한 기계 학습 모델의 견고성(robustness) 평가
✅ 생성된 적대적 예제로 훈련 데이터를 보강하여 기계 학습 모델의 견고성을 향상시키는 적대적 훈련(adversarial training) 수행
pip 사용 (권장)```bashpip install OpenAttack
#### 2. 이 저장소 클론하기```bash
git clone https://github.com/thunlp/OpenAttack.git
cd OpenAttack
python setup.py install
설치 후, demo.py를 실행하여 OpenAttack이 제대로 작동하는지 확인할 수 있습니다:```
python demo.py

## 사용 예제
#### 내장 피해자 모델 공격
OpenAttack는 일반적으로 사용되는 NLP 모델인 BERT ([Devlin et al. 2018](https://arxiv.org/abs/1810.04805)) 및 RoBERTa ([Liu et al. 2019](https://arxiv.org/abs/1907.11692))를 내장하고 있으며, 이들은 일반적으로 사용되는 데이터셋(예: [SST-2](https://nlp.stanford.edu/sentiment/treebank.html))에 대해 미세 조정되었습니다. 이러한 내장 피해자 모델에 대해 손쉽게 적대적 공격을 수행할 수 있습니다.
다음 코드 스니펫은 SST-2 데이터셋에서 BERT를 공격하기 위해 탐욕 알고리즘 기반의 공격 모델인 PWWS ([Ren et al., 2019](https://www.aclweb.org/anthology/P19-1103.pdf))를 사용하는 방법을 보여줍니다 (전체 실행 가능 코드는 [여기](https://github.com/thunlp/openattack/blob/HEAD/examples/workflow.py)에 있습니다).```python
import OpenAttack as oa
import datasets # use the Hugging Face's datasets library
# change the SST dataset into 2-class
def dataset_mapping(x):
return {
"x": x["sentence"],
"y": 1 if x["label"] > 0.5 else 0,
}
# choose a trained victim classification model
victim = oa.DataManager.loadVictim("BERT.SST")
# choose 20 examples from SST-2 as the evaluation data
dataset = datasets.load_dataset("sst", split="train[:20]").map(function=dataset_mapping)
# choose PWWS as the attacker and initialize it with default parameters
attacker = oa.attackers.PWWSAttacker()
# prepare for attacking
attack_eval = OpenAttack.AttackEval(attacker, victim)
# launch attacks and print attack results
attack_eval.eval(dataset, visualize=True)
다음 코드 조각은 SST-2에서 사용자 정의 감정 분석 모델(NLTK로 구축된 통계 모델)을 공격하기 위해 PWWS를 사용하는 방법을 보여줍니다 (전체 실행 가능 코드는 여기에 있습니다).```python import OpenAttack as oa import numpy as np import datasets import nltk from nltk.sentiment.vader import SentimentIntensityAnalyzer
class MyClassifier(oa.Classifier): def init(self): # nltk.sentiment.vader.SentimentIntensityAnalyzer is a traditional sentiment classification model. nltk.download('vader_lexicon') self.model = SentimentIntensityAnalyzer()
def get_pred(self, input_):
return self.get_prob(input_).argmax(axis=1)
# access to the classification probability scores with respect input sentences
def get_prob(self, input_):
ret = []
for sent in input_:
# SentimentIntensityAnalyzer calculates scores of “neg” and “pos” for each instance
res = self.model.polarity_scores(sent)
# we use 𝑠𝑜𝑐𝑟𝑒_𝑝𝑜𝑠 / (𝑠𝑐𝑜𝑟𝑒_𝑛𝑒𝑔 + 𝑠𝑐𝑜𝑟𝑒_𝑝𝑜𝑠) to represent the probability of positive sentiment
# Adding 10^−6 is a trick to avoid dividing by zero.
prob = (res["pos"] + 1e-6) / (res["neg"] + res["pos"] + 2e-6)
ret.append(np.array([1 - prob, prob]))
# The get_prob method finally returns a np.ndarray of shape (len(input_), 2). See Classifier for detail.
return np.array(ret)
def dataset_mapping(x): return { "x": x["sentence"], "y": 1 if x["label"] > 0.5 else 0, }
OpenAttack는 적대적 공격 프로세스를 가속화하기 위한 편리한 멀티프로세싱을 지원합니다. 다음 코드 스니펫은 유전 알고리즘 기반 공격 모델인 Genetic(Alzantot et al. 2018)을 사용한 적대적 공격에서 멀티프로세싱을 사용하는 방법을 보여줍니다 (전체 실행 가능 코드는 여기에 있습니다).```python import OpenAttack as oa import datasets
def dataset_mapping(x): return { "x": x["sentence"], "y": 1 if x["label"] > 0.5 else 0, }
victim = oa.loadVictim("BERT.SST") dataset = datasets.load_dataset("sst", split="train[:20]").map(function=dataset_mapping) attacker = oa.attackers.GeneticAttacker() attack_eval = oa.AttackEval(attacker, victim)
attack_eval.eval(dataset, visualize=True, num_workers=4)
</details>
<details>
<summary><strong>중국어 공격</strong></summary>
OpenAttack은 이제 영어 및 중국어 피해자 모델에 대한 적대적 공격을 지원합니다. [여기](https://github.com/thunlp/openattack/blob/HEAD/examples/chinese.py)는 PWWS를 사용하여 중국어 리뷰 분류 모델에 대한 적대적 공격을 수행하는 예제 코드입니다.
</details>
<details>
<summary><strong>사용자 정의 공격 모델</strong></summary>
OpenAttack은 새로운 공격 모델에 쉽게 조립할 수 있는 많은 편리한 구성 요소를 포함합니다. [여기](https://github.com/thunlp/openattack/blob/HEAD/examples/custom_attacker.py)는 원본 문장의 토큰을 섞는 간단한 공격 모델을 설계하는 방법에 대한 예제를 제공합니다.
</details>
<details>
<summary><strong>적대적 훈련</strong></summary>
OpenAttack은 훈련 세트의 인스턴스를 공격하여 적대적 예제를 쉽게 생성할 수 있으며, 이를 원본 훈련 데이터 세트에 추가하여 더 강력한 피해자 모델, 즉 적대적 훈련을 다시 훈련할 수 있습니다. [여기](https://github.com/thunlp/openattack/blob/HEAD/examples/adversarial_training.py)는 OpenAttack으로 적대적 훈련을 수행하는 방법에 대한 예제를 제공합니다.
</details>
<details>
<summary><strong>더 많은 예제</strong></summary>
- 문장 쌍 분류 모델 공격. 단일 문장 분류 모델 외에도 OpenAttack은 문장 쌍 분류 모델에 대한 공격을 지원합니다. [여기](https://github.com/thunlp/openattack/blob/HEAD/examples/nli_attack.py)는 OpenAttack으로 NLI 모델에 대한 적대적 공격을 수행하는 예제 코드입니다.
- 사용자 정의 평가 지표. OpenAttack은 사용자 정의 적대적 공격 평가 지표 설계를 지원합니다. [여기](https://github.com/thunlp/openattack/blob/HEAD/examples/custom_eval.py)는 사용자 정의 평가 지표를 추가하고 이를 사용하여 적대적 공격을 평가하는 방법에 대한 예제를 제공합니다.
</details>
## 공격 모델
원본 입력에 가해지는 교란 수준에 따라 텍스트 적대적 공격 모델은 문장 수준, 단어 수준, 문자 수준 공격 모델로 분류할 수 있습니다.
피해자 모델에 대한 접근성에 따라 텍스트 적대적 공격 모델은 `gradient` 기반, `score` 기반, `decision` 기반 및 `blind` 공격 모델로 분류할 수 있습니다.
> [TAADPapers](https://github.com/thunlp/TAADpapers)는 텍스트 적대적 공격 및 방어에 관한 거의 모든 논문을 요약한 논문 목록입니다. 이 목록을 살펴보면 더 많은 공격 모델을 찾을 수 있습니다.
현재 OpenAttack은 **모든** 공격 유형을 포괄하는 텍스트 분류 모델에 대한 15개의 대표적인 공격 모델을 포함합니다.
다음은 현재 포함된 공격 모델 목록입니다.
- 문장 수준
- (SEA) **Semantically Equivalent Adversarial Rules for Debugging NLP Models**. *Marco Tulio Ribeiro, Sameer Singh, Carlos Guestrin*. ACL 2018. `decision` [[pdf](https://aclweb.org/anthology/P18-1079)] [[code](https://github.com/marcotcr/sears)]
- (SCPN) **Adversarial Example Generation with Syntactically Controlled Paraphrase Networks**. *Mohit Iyyer, John Wieting, Kevin Gimpel, Luke Zettlemoyer*. NAACL-HLT 2018. `blind` [[pdf](https://www.aclweb.org/anthology/N18-1170)] [[code&data](https://github.com/miyyer/scpn)]
- (GAN) **Generating Natural Adversarial Examples**. *Zhengli Zhao, Dheeru Dua, Sameer Singh*. ICLR 2018. `decision` [[pdf](https://arxiv.org/pdf/1710.11342.pdf)] [[code](https://github.com/zhengliz/natural-adversary)]
- 단어 수준
- (TextFooler) **Is BERT Really Robust? A Strong Baseline for Natural Language Attack on Text Classification and Entailment**. *Di Jin, Zhijing Jin, Joey Tianyi Zhou, Peter Szolovits*. AAAI-20. `score` [[pdf](https://arxiv.org/pdf/1907.11932v4)] [[code](https://github.com/wqj111186/TextFooler)]
- (PWWS) **Generating Natural Language Adversarial Examples through Probability Weighted Word Saliency**. *Shuhuai Ren, Yihe Deng, Kun He, Wanxiang Che*. ACL 2019. `score` [[pdf](https://www.aclweb.org/anthology/P19-1103.pdf)] [[code](https://github.com/JHL-HUST/PWWS/)]
- (Genetic) **Generating Natural Language Adversarial Examples**. *Moustafa Alzantot, Yash Sharma, Ahmed Elgohary, Bo-Jhang Ho, Mani Srivastava, Kai-Wei Chang*. EMNLP 2018. `score` [[pdf](https://www.aclweb.org/anthology/D18-1316)] [[code](https://github.com/nesl/nlp_adversarial_examples)]
- (SememePSO) **Word-level Textual Adversarial Attacking as Combinatorial Optimization**. *Yuan Zang, Fanchao Qi, Chenghao Yang, Zhiyuan Liu, Meng Zhang, Qun Liu and Maosong Sun*. ACL 2020. `score` [[pdf](https://www.aclweb.org/anthology/2020.acl-main.540.pdf)] [[code](https://github.com/thunlp/SememePSO-Attack)]
- (BERT-ATTACK) **BERT-ATTACK: Adversarial Attack Against BERT Using BERT**. *Linyang Li, Ruotian Ma, Qipeng Guo, Xiangyang Xue, Xipeng Qiu*. EMNLP 2020. `score` [[pdf](https://www.aclweb.org/anthology/2020.emnlp-main.500.pdf)] [[code](https://github.com/LinyangLee/BERT-Attack)]
- (BAE) **BAE: BERT-based Adversarial Examples for Text Classification**. *Siddhant Garg, Goutham Ramakrishnan. EMNLP 2020*. `score` [[pdf](https://www.aclweb.org/anthology/2020.emnlp-main.498.pdf)] [[code](https://github.com/QData/TextAttack/blob/master/textattack/attack_recipes/bae_garg_2019.py)]
- (FD) **Crafting Adversarial Input Sequences For Recurrent Neural Networks**. *Nicolas Papernot, Patrick McDaniel, Ananthram Swami, Richard Harang*. MILCOM 2016. `gradient` [[pdf](https://arxiv.org/pdf/1604.08275.pdf)]
- 단어/문자 수준
- (TextBugger) **TEXTBUGGER: Generating Adversarial Text Against Real-world Applications**. *Jinfeng Li, Shouling Ji, Tianyu Du, Bo Li, Ting Wang*. NDSS 2019. `gradient` `score` [[pdf](https://arxiv.org/pdf/1812.05271.pdf)]
- (UAT) **Universal Adversarial Triggers for Attacking and Analyzing NLP.** *Eric Wallace, Shi Feng, Nikhil Kandpal, Matt Gardner, Sameer Singh*. EMNLP-IJCNLP 2019. `gradient` [[pdf](https://arxiv.org/pdf/1908.07125.pdf)] [[code](https://github.com/Eric-Wallace/universal-triggers)] [[website](http://www.ericswallace.com/triggers)]
- (HotFlip) **HotFlip: White-Box Adversarial Examples for Text Classification**. *Javid Ebrahimi, Anyi Rao, Daniel Lowd, Dejing Dou*. ACL 2018. `gradient` [[pdf](https://www.aclweb.org/anthology/P18-2006)] [[code](https://github.com/AnyiRao/WordAdver)]
- 문자 수준
- (VIPER) **Text Processing Like Humans Do: Visually Attacking and Shielding NLP Systems**. *Steffen Eger, Gözde Gül ¸Sahin, Andreas Rücklé, Ji-Ung Lee, Claudia Schulz, Mohsen Mesgar, Krishnkant Swarnkar, Edwin Simpson, Iryna Gurevych*. NAACL-HLT 2019. `score` [[pdf](https://www.aclweb.org/anthology/N19-1165)] [[code&data](https://github.com/UKPLab/naacl2019-like-humans-visual-attacks)]
- (DeepWordBug) **Black-box Generation of Adversarial Text Sequences to Evade Deep Learning Classifiers**. *Ji Gao, Jack Lanchantin, Mary Lou Soffa, Yanjun Qi*. IEEE SPW 2018. `score` [[pdf](https://ieeexplore.ieee.org/document/8424632)] [[code](https://github.com/QData/deepWordBug)]
다음 표는 공격 모델의 비교를 보여줍니다.
| 모델 | 접근성 | 교란 | 주요 아이디어 |
| :---------: | :-------------: | :----------: | :-------------------------------------------------- |
| SEA | Decision | 문장 | 규칙 기반 패러프레이징 |
| SCPN | Blind | 문장 | 패러프레이징 |
| GAN | Decision | 문장 | 인코더-디코더에 의한 텍스트 생성 |
| TextFooler | Score | 단어 | 탐욕적 단어 대체 |
| PWWS | Score | 단어 | 탐욕적 단어 대체 |
| Genetic | Score | 단어 | 유전 알고리즘 기반 단어 대체 |
| SememePSO | Score | 단어 | 입자 떼 최적화 기반 단어 대체 |
| BERT-ATTACK | Score | 단어 | 탐욕적 맥락화 단어 대체 |
| BAE | Score | 단어 | 탐욕적 맥락화 단어 대체 및 삽입 |
| FD | Gradient | 단어 | 그래디언트 기반 단어 대체 |
| TextBugger | Gradient, Score | 단어+문자 | 탐욕적 단어 대체 및 문자 조작 |
| UAT | Gradient | 단어, 문자 | 그래디언트 기반 단어 또는 문자 조작 |
| HotFlip | Gradient | 단어, 문자 | 그래디언트 기반 단어 또는 문자 대체 |
| VIPER | Blind | 문자 | 시각적으로 유사한 문자 대체 |
| DeepWordBug | Score | 문자 | 탐욕적 문자 조작 |
## 툴킷 디자인
서로 다른 공격 모델 간의 상당한 차이를 고려하여 공격 모델의 골격 설계에 상당한 자유도를 남겨두고, 적대적 공격의 일반적인 처리 과정과 공격 모델에 사용되는 공통 구성 요소를 간소화하는 데 더 중점을 둡니다.
OpenAttack에는 7개의 주요 모듈이 있습니다.
<img src="https://assets.kitploit.com/production/public/readmes/4421/3c70579cf4ea406c82bd3bf407eb9c1e1e8b8ffb3b3c4eede4fe2812ff76eebf.png" alt="toolkit_framework" style="zoom:40%;" />
* **TextProcessor**: 원본 텍스트 시퀀스를 처리하여 공격 모델이 적대적 예제를 생성하는 데 도움을 줍니다.
* **Victim**: 피해자 모델을 래핑합니다.
* **Attacker**: 다양한 공격 모델을 포함합니다.
* **AttackAssist**: 단어/문자 수준 공격 모델에서 사용되는 다양한 단어/문자 대체 방법 및 문장 수준 공격 모델에서 사용되는 패러프레이징 모델과 같은 기타 구성 요소를 패키징합니다.
* **Metric**: 공격 중 적대적 예제에 대한 제약 조건 또는 적대적 공격 평가를 위한 평가 지표 역할을 할 수 있는 여러 적대적 예제 품질 지표를 제공합니다.
* **AttackEval**: 공격 효과, 적대적 예제 품질 및 공격 효율성 측면에서 텍스트 적대적 공격을 평가합니다.
* **DataManager**: 다른 모듈에서 사용되는 모든 데이터와 저장된 모델을 관리합니다.
## 인용
이 툴킷을 사용하는 경우 당사의 [논문](https://aclanthology.org/2021.acl-demo.43.pdf)을 인용해 주시기 바랍니다.```
@inproceedings{zeng2020openattack,
title={{Openattack: An open-source textual adversarial attack toolkit}},
author={Zeng, Guoyang and Qi, Fanchao and Zhou, Qianrui and Zhang, Tingji and Hou, Bairu and Zang, Yuan and Liu, Zhiyuan and Sun, Maosong},
booktitle={Proceedings of the 59th Annual Meeting of the Association for Computational Linguistics and the 11th International Joint Conference on Natural Language Processing: System Demonstrations},
pages={363--371},
year={2021},
url={https://aclanthology.org/2021.acl-demo.43},
doi={10.18653/v1/2021.acl-demo.43}
}
dataset = datasets.load_dataset("sst", split="train[:20]").map(function=dataset_mapping)
victim = MyClassifier()
attacker = oa.attackers.PWWSAttacker()
attack_eval = oa.AttackEval(attacker, victim)
attack_eval.eval(dataset, visualize=True)
</details>
<details>
<summary><strong>사용자 정의 데이터셋</strong></summary>
다음 코드 스니펫은 **사용자 정의** 데이터셋에서 기존의 미세 조정된 감정 분석 모델을 공격하기 위해 PWWS를 사용하는 방법을 보여줍니다 (전체 실행 코드는 [여기](https://github.com/thunlp/openattack/blob/HEAD/examples/custom_dataset.py)에 있습니다).```python
import OpenAttack as oa
import transformers
import datasets
# load a fine-tuned sentiment analysis model from Transformers (you can also use our fine-tuned Victim.BERT.SST)
tokenizer = transformers.AutoTokenizer.from_pretrained("echarlaix/bert-base-uncased-sst2-acc91.1-d37-hybrid")
model = transformers.AutoModelForSequenceClassification.from_pretrained("echarlaix/bert-base-uncased-sst2-acc91.1-d37-hybrid", num_labels=2, output_hidden_states=False)
victim = oa.classifiers.TransformersClassifier(model, tokenizer, model.bert.embeddings.word_embeddings)
# choose PWWS as the attacker and initialize it with default parameters
attacker = oa.attackers.PWWSAttacker()
# create your customized dataset
dataset = datasets.Dataset.from_dict({
"x": [
"I hate this movie.",
"I like this apple."
],
"y": [
0, # 0 for negative
1, # 1 for positive
]
})
# prepare for attacking
attack_eval = oa.AttackEval(attacker, victim, metrics = [oa.metric.EditDistance(), oa.metric.ModificationRate()])
# launch attacks and print attack results
attack_eval.eval(dataset, visualize=True)
이 프로젝트의 모든 기여자분들께 감사드립니다. 더 많은 기여를 환영합니다.