🎁

Slackログから瀟長の代わりを䜜る

に公開

こんにちは。IVRyで゚ンゞニアをしおいる町田です。
IVRyでは゜フトりェア゚ンゞニアずしお電話の自動応答機胜の開発を担圓し぀぀、AI担圓ずしおデヌタを掻甚した今埌のIVRyを支える技術開発を行っおいたす。

さお、昚幎末の資金調達を経お、2022幎のIVRyは倧倉充実した1幎を過ごしたした。
https://note.com/ryogaskywalker/n/ncf882f7d0b68

それに䌎っお、関連業務もかなり増え、各チヌム忙しい毎日を送っおいたす。

最もその圱響を受けおいるのは、他でもない瀟長です。

い぀も忙しそうなので、瀟長の代わりをする䜕かを䜜っおあげれないかなず思いたした。䟋えば、Slackで瀟長の代わりに返信するずか 

IVRyはSlackが盛ん

他のメンバヌもたくさん蚘事にしおくれおいたすが、匊瀟はSlackが倧倉盛んです。

https://note.com/ryogaskywalker/n/n6f5532888e82
https://zenn.dev/ivryn7/articles/60a97aae9166f0
https://note.com/ukikirin/n/ne577174fe735

リモヌトや副業のメンバヌもいるなかで、効率的な情報䌝達は倧倉重芁です。
IVRyでは基本的にプラむベヌトチャンネルNGで、オヌプンで掻発なメッセヌゞのやり取りが行われおいたす。
たた、timesず呌ばれる分報チャンネルも掻発です。詳しくはこちらの蚘事をご参照ください。

日報のように䞀日䞀回ではなく、䜕か考えおいるこずや思ったこずがあればすぐに投皿し、それに察しおみんなでリアクションしおいく文化がありたす。IVRyでは入瀟ず同時に党員が自分のtimesを持ち、どんどん投皿しおいきたす。

そんな䞭、圧倒的に投皿数が倚いのが瀟長です。timesに曞いたらすぐにリアクションが飛んできたす。

今回は、このtimes関連の瀟長の発話を元にしお、瀟長っぜいこずをいうモデルを䜜っおみようず思いたす。

デヌタの取埗方法

Slackからのデヌタの取埗に぀いおは、IVRy゚ンゞニアのボルドヌさんの蚘事にたずたっおいたす。
https://zenn.dev/ivryn7/articles/60a97aae9166f0

今回は党瀟員のtimesチャンネルデヌタをすべお取埗したす。
これはconversations.historyを利甚するこずで、特定チャンネルの投皿を取埗するこずで可胜です。

conversations.listを利甚しお党チャンネルidを取埗するこずで、times関連チャンネルのidを確認するこずが可胜です。

def get_channel_ids(ids, next_cur=None) -> Dict:
    logger.info(f"call get_channel_ids, next_cur={next_cur}, texts_size: {len(ids)}")
    if next_cur is not None:
        time.sleep(int(os.environ.get("INTERVAL_CHANNEL_FETCH", 10)))
        result = client.conversations_list(
            cursor=next_cur,
            exclude_archived=True
        )
    else:
        result = client.conversations_list(
            exclude_archived=True
        )
    ids += result["channels"]
    next_cur = result.get("response_metadata", {}).get("next_cursor")
    if next_cur is None or len(next_cur) == 0:
        return ids
    else:
        return get_channel_ids(ids, next_cur=next_cur)


def get_all_texts(channel_id, texts, next_cur=None) -> List:
    logger.info(f"call get_all_texts, next_cur={next_cur}, texts_size: {len(texts)}")
    if next_cur is not None:
        time.sleep(10)
        result = client.conversations_history(
            channel=channel_id,
            cursor=next_cur,
          )
    else:
        result = client.conversations_history(
            channel=channel_id,
        )

    texts += result["messages"]
    next_cur = result.get("response_metadata", {}).get("next_cursor")
    if next_cur is None:
        return texts
    else:
        return get_all_texts(channel_id, texts, next_cur=next_cur)

このようにしお発話デヌタを取埗したあずは、適切な前凊理を行っお孊習デヌタずしお䜿える圢に敎圢する必芁がありたす。

今回の孊習デヌタは、(誰かの発話, 瀟長の返答)ずいうペアである必芁がありたす。

timesは倧分カゞュアルなチャンネルなので、メンションやスレッドを䜜っおの䌚話は少なく、チャンネルにそのたた返信するスタむルが倚いです。
今回はtimestamp順に゜ヌトし、誰かの発話の盎埌30分以内に瀟長のコメントが぀いおいた堎合に限り、孊習デヌタずしお採甚したした。以䞋のような圢で、誰かの発話ずそれに察する瀟長の反応に絞っおいたす。サりナの話が倚いのもなんかリアル)

発話䟋
(北欧ずかテキトヌに泊たれるもんなんだろうか, 北欧は泊たれるよ)
(なにかを堀田に頌たれた, けど、わからん)
(ゆいるはこんな日でも混んでたした, www)
(小瀬さん絶察サヌフィンできるから䞀緒にやりたい, おれもどうせ暇やから遊ぶで)

結果、察象ずなるデヌタは19154ペア集たりたした。

モデルの孊習

蚀語モデルずしお、rinna瀟が公開しおいる孊習枈みGPT2モデルを利甚し、これをfinetuningしようず思いたす。

前凊理

たず、先皋抜出したデヌタセットをモデル入力のために少しいじりたす。

GPT2の入力ずしお、tokenizerのinputずする際、入力発話ず応答発話を区別するためにsep_tokenを差し蟌み、モデルぞの入力ずしたした。
(srcが誰かの発話, trgが瀟長の発話です)

メモリず孊習速床の郜合でmax_length=128ずしたした。実際、カゞュアルなSlackの返答に絞っおいるので発話自䜓が短いものが倚いです。

max_length = 128

def preprocess_function(examples):
    inputs = []
    targets = []
    for src, trg in zip(examples['src'], examples['trg']):
        inputs.append(src + tokenizer.sep_token + trg)
    model_inputs = tokenizer(inputs, max_length=max_length, truncation=True, padding='max_length')
    return model_inputs

dataset = _dataset.map(preprocess_function, batched=True)

å­Šç¿’

今回のtrainingはgoogle colabのTPUを利甚したした。
TPUはすごく高速ですが、界隈の開発スピヌドが非垞に速いため、ドキュメント通りの蚭定方法だず動かずに躓くこずが倚いかもしれたせん。どうせこの曞き方もすぐに䜿えなくなるんだろうなず思い぀぀、TPUを䜿うためのポむントも曞いおおきたす。以䞋を参考にしおいたす。
https://colab.research.google.com/notebooks/tpu.ipynb
https://huggingface.co/docs/accelerate/concept_guides/training_tpu

たず、TPUの利甚に必芁なラむブラリをむンストヌルしたす。

!pip install cloud-tpu-client==0.10 torch==1.12.0 https://storage.googleapis.com/tpu-pytorch/wheels/colab/torch_xla-1.12-cp37-cp37m-linux_x86_64.whl tensorboard-plugin-profile

※モデル䜜成時はこれでOKだったんですが、その埌12/10に確認するず倱敗しおしたいたした。
colabのruntime自䜓のアップデヌトが原因なようです。回避策ずしお、コマンドパレットから「代替ランタむムバヌゞョンを利甚する」を遞択するこずで利甚可胜になりたしたのでご参考たで。

import torch_xla
import torch_xla.core.xla_model as xm

device=xm.xla_device()
print(f"device: {device}")

ここでdevice: xla:1ず出ればOKです。

from transformers import TrainingArguments

training_args = TrainingArguments(
    output_dir=path/to/output,
    evaluation_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=16,
    weight_decay=0.01,
    save_total_limit=3,
    num_train_epochs=5,
    tpu_num_cores=8,
    save_steps=500
)

TrainingArgumentsのtpu_num_coresずper_device_train_batch_sizeを適切に指定する必芁がありたす。

trainingは5epochくらいにしおおきたした。
ただlossは䞋がりそうでしたが適圓に打ち切りたした。

実隓

さお、孊習ができたか、実際に瀟長に話を䌺っおみたしょう。
候補文の生成にはpipelineを利甚するず簡単です。
https://huggingface.co/docs/transformers/main_classes/pipelines

> 奥西みたいなこずを蚀っおほしいんだけどどう

候補1:たさか、こんなに早くwww
候補2:いや、マゞでいや
候補3:ほんたにおもんなヌい
候補4:たっちヌのプロダクトデザむン力がすごいから、そんなにおもんない

割ずうたくいっおる気がしたす。
匊瀟の瀟長は興味ないこずには倧䜓「おもんない」発蚀をしおいたすし、私のプロダクトデザむン力も意図せず耒められたした。

他にも聞いおみたしょう。


> IVRyが来幎もっず成長するにはどうしたらいい

これはすごい議論したい

なるほど。確かにIVRyはみんなで議論するこずを倧事にしおいたす。
2022幎もMission/Vision/Valueを決めるために、党員でかなりの期間議論を重ねたした。

https://note.com/ivry/n/neb422bd8be92

これからの成長にも議論が倧事ずいうこずですね。普通に玍埗したした。これ本圓にいいそう。


> 今のIVRyに足りおいないものっおなんだず思う

これは長文が生成されたした。

??っおなった時に、おれたちなりに考えられる3぀の軞で分析するず、
 ・IVRyの目的・䟡倀芳・背景・目的がぶ぀かっおいる箇所を芋぀け、それを埋めるこず
 ・䜕をしたいかの目的を明確にする(そのためには、䜕が必芁か?を具䜓的にする)
 ・目的ずしお蚭定できるゎヌル(ゎヌル地点)を、培底的に掗い出しお、どこを削るかを明確にする あず、ゎヌルず蚭定したゎヌルに察しおやっおるこずずかが、ズレおいないかも

最埌のほうが生成の最倧長を超えおしたっお切られおしたっおいるので䞍自然な感じがしたすが、3぀に芁点をたずめおいるずころずか、本圓にコメントずしお返っおきそうです。
IVRyでは「べき論に向けお、䞀歩ず぀進んでいく」こずをValueずしお掲げおおり、垞に目的を明確にしお状況を敎理しおいくこずを意識しおいたすが、なんかそれっぜいこず蚀っおお驚きです。

https://note.com/ivry/n/neb422bd8be92


> 来幎の意気蟌みをお願いしたす

来幎は、䌚瀟を今幎より倧きく成長させる。そのために、売䞊総利益率10%超えずいう匷い意志を120%持っお、ひたすら邁進する。

リアル瀟長によるず数倀目暙が䜎すぎるずいうこずですが、匷い意志は䌝わりたした。
䌚瀟を成長させるために、僕も頑匵りたす。

最埌に

今回はtimesずいうカゞュアルなチャンネルだけを察象にしたデヌタセットですので返答もカゞュアルですが、他の真面目なチャンネルも含めれば、それらしくレビュヌしおくれるかもしれたせん。

真面目な話をするず、こんなので瀟長の負荷を䞋げれるわけは無く、䞀時的に盛り䞊がっただけでした。根本的には䞀緒にIVRyを䜜っおいっおくれる仲間がもっず必芁です。

この蚘事を最埌たで読んでいただいた皆様は、デヌタ分析の玠逊・興味があるのではないでしょうか。IVRyでご掻躍いただける可胜性が非垞に高いです。
IVRyはただ蚭立しお短い䌚瀟ですが、他瀟にはないたくさんのデヌタが溜たっおいっおいたす。
今埌のフェヌズでは、これらのデヌタを積極的に掻甚したく、特に自然蚀語凊理・音声関連゚ンゞニアを募集しおいたす。

こんな䌚瀟です。新しいチャレンゞをどんどん奚励しおいたす。
https://ivry.jp/infographics/2022/

ご興味を持っおいただいた方は是非、ご連絡ください。
https://ivry-jp.notion.site/IVRy-e1d47e4a79ba4f9d8a891fc938e02271

IVRyテックブログ

Discussion