파이톤과 GPT2가 달린 AI 트위터 로봇

21341 단어 showdevpythontwitterai
오늘날 인공지능을 운행하는 것은 갈수록 간단해지고 있다. 이는 개원 공헌자들의 부지런한 노력으로 일류 라이브러리가 생겼기 때문이다. 연구팀은 다른 사람들이 이를 바탕으로 계속 발전할 수 있도록 그들의 업무를 개방했다.하나의 관건적인 도서관은 허핑페이스의 트랜스포머 도서관이다.HuggingFace는 초창기 기업 건물이자 NLP와 관련된 다른 제품으로 도서관과 모델 생태계로 거의 누구나 인공지능이 지원하는 챗봇을 신속하고 쉽게 만들어 자연 언어를 사용하거나 생성할 수 있다.
이 글에서 나는 이 라이브러리를 어떻게 사용하여 트위터 로봇을 만드는지 보여줄 것이다. 트위터에서만 허구적인 (좀 이상한) 좋은 소식을 발표할 것이다

AIs 및 GPT2


이 블로그는 어떤 이론도 해석하기 위한 것이 아니지만 익숙하지 않은 사람들에게 이런 인공지능을 해석하는 가장 간단한 방법은 복잡한 패턴 식별 시스템이다.만약 당신이 그것에 충분한 데이터를 제공한다면 그것은 영어 언어 모델을 식별하는 능력을 구축할 수 있을 것이다. 만약 당신이 그것을 반복하도록 요구한다면, 그것은 기본적으로 정확한 영어 문법을 생성할 뿐만 아니라, 때때로 일관된 문장을 생성할 수도 있다.
그것은 언어의 패턴과 우리가 흔히 이야기하는 주제를 찾아내기 위해 대량의 데이터와 처리 능력을 필요로 한다.GPT2는 이러한 인공지능으로 OpenAI에 의해 개발되었고 우리가 자주 사용하는 모델(이 모든'공부'의 출력)을 인터넷의 수백만 페이지에서 훈련(그중 많은 것이 Reddit에서 온 것)을 복제하는 신기한 능력을 부여했다. 이것은 영어의 시작 자모나 단어를 주고 훈련 데이터에서 추출한 모델에 따라다음 몇 개의 단어를 써라.
이 모델에는 이러한 학습된 모든'모드'가 포함되어 있어 다운로드하여 직접 사용할 수 있다.HuggingFace는 일반 데스크톱 컴퓨터DistilGPT2에서 실행할 수 있도록 최적화된 자체 모델을 생산했다.이것은 우리가 사용할 것이다. 왜냐하면 나는 더 큰 GPT2 모델을 실행할 충분한 컴퓨터가 없기 때문이다. (그들의 사이트에서 다운로드할 수도 있다.)

데이터 출처 찾기


우리의 용례에 대해 말하자면 모델 자체는 그리 유용하지 않다.그것은 영어를 생산할 수 있지만 특정한 관심 주제는 없다.그것의 원천 재료는 다양하기 때문에 최종적으로 각종 주제에 관한 문장이 생길 수 있다.
우리가 하고 싶은 것은 뉴스 제목의 형식으로 텍스트를 만들어 좋은 소식이나 이상한 소식에 특히 관심을 가지도록 하는 것이다.따라서 우리는 이 기본 모델을 채택하여 새로운 데이터를 계속 학습하고 우리가 그에 대해 발생한 새로운 모델에 대해 흥미를 가지도록'미조정'을 진행하기를 희망한다.
따라서, 우리는 먼저 우리가 원하는 것들의 예인 좋은/이상한 뉴스 제목을 대량으로 얻어야 한다.
나는 어떻게 혹은 어디에 있는지에 관한 세부 사항을 너무 많이 이야기할 생각은 없다. 왜냐하면...많은 사람들이 서버에 많은 부담을 주기 때문에 데이터를 여러 사이트로 나누는 데 필요한 데이터의 양이 상당히 많습니다.그래서 이것은 네가 책임감 있고 합법적으로 해야 할 일이다.

가능한 데이터 출처: RSS Feed


RSS 구독보다 뉴스 제목 수집에 더 적합한 곳이 어디 있겠는가!RSS는 프로그램이 뉴스 원본에서 제목을 얻는 데 사용되는 표준화된 형식이기 때문에 뉴스 리더 등 프로그램은 다양한 뉴스 사이트에서 제목을 얻고 리더에서 정확하게 포맷할 수 있다.RSS는 팟캐스트 세계에서 매우 중요하다. 왜냐하면 이것은 이 용례에 매우 적합하기 때문이다. 모든 팟캐스트에는 RSS 요약이 있는데, 이것은 팟캐스트 프로그램이 요약을 구독할 수 있고, 최신 드라마가 사용 가능할 때 그것을 얻을 수 있도록 한다.
거의 모든 뉴스 사이트에서 RSS 피드를 생성하는데, 프로그래밍을 통해 쉽게 피드를 얻고 해석할 수 있다.예를 들어 파이썬에는 feedparser (pip install feedparser)라는 사용하기 쉬운 라이브러리가 있는데 이를 실현하는 코드는 매우 간단하다.
import feedparser
feed = feedparser.parse("http://example.com/rss")

for entry in feed.entries:
    print(entry.title)
이렇게 하는 장점은 그것이 매우 간단하고 쓰기 쉽다는 것이다.대부분의 뉴스 사이트는 하루 이틀의 제목만 제공할 뿐 역사적 뉴스를 얻는 방법을 제공하지 않는다는 단점이 있다.다행히도 뉴스 사이트는 사이트의 역사 스냅숏을 저장하는 데 자주 사용되는 압축 파일 도구로 캡처되기 때문에 RSS 요약은 보통 압축 파일에 포함된다. 이것은 10년 이상의 역사 RSS 요약을 어떻게 어디서 얻는지 알고 싶으면 큰 힌트를 얻을 수 있다는 것을 의미한다.

가능한 데이터 소스: Reddit


GPT2는 레드dit 이야기에서 훈련된 것처럼 (실제로는 그것들의 링크만 사용) 당신도 할 수 있습니다.Reddit는 자체 프로그래밍 액세스를 구축할 수 있는 API를 제공하며 추가 정보on Reddit's developer page를 찾을 수 있습니다.
Python을 사용하면 'PRAW' pip install praw 라는 패키지가 있고, Reddit API와 상호작용하기 쉬운 인터페이스를 제공합니다.Reddit의 개발자 페이지에서 가져올 수 있는 API 키가 여전히 필요합니다.코드는 간단합니다.
import praw

reddit = praw.Reddit(
    client_id=YOUR_TOKEN_ID,
    client_secret=YOUR_TOKEN_SECRET
    user_agent=YOUR_APP_NAME_OR_SOMETHING
)

subreddit = reddit.subreddit("example_subreddit")
for submission in subreddit.top(limit=None):
    print(submission.title)
마찬가지로 이런 방식으로 사용하는 것은 매우 쉬우나, 단점은 레드디트가 각subreddit당 최대 1000개의 이야기를 제공할 수 있다는 것이다.이것은 이미 훌륭하지만, 우리가 일반적으로 필요로 하는 것은 이것뿐만이 아닙니다. 비록 많은 하위 레디트가 사용할 수 있지만, 당신은 이러한 데이터를 충분히 수집할 수 있을 것입니다.
reddit 데이터의 또 다른 출처는 PushShift인데 이것은 대량의 reddit 데이터를 방문해야 하는 연구원들이 운영하는 서비스로 현재 지역사회에서 지원하는 1인 작업인 것 같다.PushShift의 API는 대량의 Reddit 데이터에 접근할 수 있으며, 그 역사는 공식 API가 제공할 1000개를 훨씬 넘는다.PushShift는 그들의 subreddit와 사이트에 더 많은 정보를 가지고 있는 매우 강력한 자원이다.

기타 가능한 데이터 출처


일반적인 인터넷에서 기어오르고 캡처하고 사용자가 생성한 내용부터 비용을 지불하는 것(또는 다른 방식으로 사람들이 인터넷을 보고 데이터를 찾도록 설득하는 것)까지 다른 몇 가지 데이터 출처도 있다.네가 어떻게 하든지 간에, 너는 수만 개의 예가 있어야만 그것을 잘 일하게 할 수 있을 것이다.

정서 분석


만약 네가 뉴스 사이트에서 많은 뉴스 보도를 수집했다면 많은 데이터가 긍정적이지 않았을 것이다. 사실 나의 연구 결과에 의하면 절대 다수(>66%)의 뉴스 기사는 모두 부정적이라고 한다.이것은 적극적인 인공지능 로봇이어야 하기 때문에 우리는 데이터에 대해 약간의 여과를 해야 한다.
다행히도 지난 몇 년간 NLP/AI 연구의 한 축으로 정서분석을 하는 방법도 잘 발전했다.Hugging Face의 변형 금강고에는 이미 sentiment-analysis 파이프가 하나 (BERT 기반, 이것은 매우 새로운 것) 있어서 이 임무를 쉽게 할 수 있다.설치 후(pip install transformerspip install torch) 코드는 다음과 같이 목록 이해를 통해 필터된 목록을 얻을 수 있습니다.
from transformers import pipeline
sentimentanalyzer = pipeline("sentiment-analysis")

sentiments_list = sentimentanalyzer(titles_list)

THRESH = 0.99
positive = [title for title, sentiment in zip(titles_list, sentiments_list) if sentiment["label"] == "POSITIVE" and sentiment["score"] > THRESH]
주의: 이것은 매우 큰 메모리가 필요합니다. 100k의 제목을 처리할 때, 나는 실제로 32GB의 메모리를 다 썼습니다.많은 상황에서 그것은 분할 처리를 필요로 한다.
32GB가 넘는 RAM으로 인해 스크립트가 손상되기 전에

데이터 준비


일단 필터 목록을 수집하면 특정한 방식으로 미세하게 조정할 준비가 필요하다.우리가 사용하고자 하는 모든 데이터를 포함하는 평면 텍스트 파일이 필요합니다. 제목마다 특별한 태그 "<|endoftext|>" 가 필요합니다.
또한 파일 제목을 여러 번 무작위로 만들어 인공지능이 연관성을 발견하지 않도록 하기 위해 임의의 순서로 데이터를 네 번 복사함으로써 이러한 상황을 피하고자 합니다.
import random

ENDTOKEN = "<|endoftext|>"
EPOCHS = 4

with open("data_train.txt", "w") as fp:
    fp.write(ENDTOKEN)
    for _ in range(EPOCHS):
        random.shuffle(positive)
        fp.write(ENDTOKEN.join(positive)+ENDTOKEN)
이것은 큰 평면 텍스트 파일 data_train.txt 을 생성할 것입니다. 우리는 지금 그것을 마이크로스피커에 입력할 수 있습니다.

소조


모형을 미세하게 조정하려면 Huggingfacedistilgpt2모형부터 시작하지만 다른 모형도 사용할 수 있습니다(훑어보세요!).
코드는 다음과 같습니다.
import os
import random
from transformers import (
    AutoTokenizer, AutoModelForCausalLM,
    TextDataset, DataCollatorForLanguageModeling,
    Trainer, TrainingArguments
)

tokenizer = AutoTokenizer.from_pretrained("distilgpt2")
model = AutoModelForCausalLM.from_pretrained("distilgpt2")
train_dataset = TextDataset(tokenizer=tokenizer, file_path="data_train.txt", block_size=tokenizer.model_max_length)
data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)

training_args = TrainingArguments(
    output_dir='./output',
    overwrite_output_dir=True,
    num_train_epochs=4,
    per_device_train_batch_size=1,
    prediction_loss_only=True,
    logging_steps=100,
    save_steps=0,
    seed=random.randint(0, 2**32-1),
)

trainer = Trainer(
    model=model,
    tokenizer=tokenizer,
    args=training_args,
    data_collator=data_collator,
    train_dataset=train_dataset,
)

trainer.train()
model.save_pretrained("./model")

결과는 하나의 교육 과정이다.6GB 이상의 VRAM GPU가 있기를 바랍니다. 그렇지 않으면 몇 주 동안 거기에 있을 것입니다.GPU에서 이 과정은 한두 시간이 걸린다.

모델 작업


완성되면 모델을 저장하고 사용할 수 있습니다!
import string
start_str = ENDTOKEN + random.choice(string.ascii_uppercase+string.digits)
encoded_prompt = tokenizer(start_str, add_special_tokens=False, return_tensors="pt").input_ids
encoded_prompt = encoded_prompt.to(model.device)

output_sequences = model.generate(
    input_ids=encoded_prompt,
    max_length=50,
    min_length=10,
    temperature=1.6,
    top_k=100,
    top_p=0.90,
    do_sample=True,
    num_return_sequences=5,
    pad_token_id=tokenizer.eos_token_id # gets rid of warning
    )

for generated_sequence in output_sequences:
    generated_sequence = generated_sequence.tolist()
    text = tokenizer.decode(generated_sequence, clean_up_tokenization_spaces=True, skip_special_tokens=True)
    print(text.strip())
여기서 우리는 모델에 무작위 시작 문자를 힌트로 한다.만약 이렇게 하지 않는다면 텍스트는 문장의 절반부터 시작할 수 있다. (실제로 위의 코드는 사용할 수 있는 태그 중에서 알파벳이 아닌 무작위로 태그를 선택할 수 있다.) 이렇게 하면 더욱 좋다.
모델 생성기에서temperature,top_ktop_p 매개 변수의 해석은 약간의 조정이 필요합니다. 위의 값은 출력을 매우 무작위로 하지만 이것은 바로 우리가 원하는 것입니다. 왜냐하면 우리는 출력이 좀 익살스러우기를 원하기 때문입니다.Hugingface 블로그a nice article on these parameters
출력은 다음과 같습니다.
  "HELP: The measles vaccine wins Malaysia competition",
  "Sarajevo aims to change Bolivia's infamous Montecito archipelago, abolishing devastating 20 mile wilderness area which includes most of",
  "0-year-old 'wonder' statue torn down in Richmond, helps replace statue in front of House Building burned to fire",
  "Elderly man finds treasure of \u00a33.7 million - goes under the tree's cheek - and RETURNS it to Wildlife Charities",
내 현재의 설정은 약간의 미친 짓을 일으킬 수 있지만, 이것이 바로 내가 원하는 것이다.더 합리적인 값은 온도 0.5, top k 50, top p 0.95일 수 있는데, 이것은 상당히 보수적인 (상상력 부족) 결과를 가져올 것이다.

인공 전시회


나는 트위터에 사람들이 비웃을 만한 것을 올리고 싶다. 그래서 나는 단지 이런 제목을 대량으로 만들어서 그것들을 일렬로 배열한 다음에 트위터에 올리고 싶지 않다. 이것은 곧 사람들의 구독원으로 하여금 무의미한 무작위 내용으로 가득 차게 할 것이다.그래서 저는 이런 것들을 기획하고 싶습니다. 그중의 랜덤성에서 수동으로 몇 가지 좋은 것을 선택하고 싶습니다.
다행히도, 이것이 바로 Curate Bot의 용무의 땅이다. 나의 이전 프로젝트이다.Curate Bot의 목적은 수천 수만 개의 이런 트윗을 불러와서 수동으로 나쁜 트윗을 훑어보고 빠르게 삭제한 다음에 좋은 트윗을 대기열에 보내서 최종적으로 보내는 것입니다.
다음은 @goodnews ai의 일부 대기 트윗입니다.

시간표

이로 인해 발생한 추문의 유래

지금 인공지능 트위터 로봇을 만드는 것이 얼마나 쉬운지 알 수 있기를 바랍니다!내가 이 글을 쓰는 목적은 너에게 깊이 있는 해석이나 지도를 주는 것이 아니라, 서로 다른 자원과 검색어를 찾도록 인도하는 것이다. 너는 그것으로 더 많은 자원을 찾을 수 있다.만약 네가 곧 시도할 수 있다면, 행운을 빌어라.

좋은 웹페이지 즐겨찾기