大福餅

大福餅

人工言語による事前学習を用いた言語間転移可能な知識の分析

www.jstage.jst.go.jp

 

昨日、ベッドの上で寝ながら読んでいたが面白かった。

 

概要

  • 人工言語を用いた事前学習をTransformerのエンコーダに学習させ、そのエンコーダを自然言語の言語モデリングに転移したときの性能を測定させた論文。
  • 先行研究の結果から、NNは言語タスクを解くための特徴に、言語非依存なものがあることが示唆されている。
    • 複数の言語のテキストで学習したマルチリンガル事前学習モデルは、様々な言語のタスクで高い性能が出せることが分かっている。
    • また英語のデータのみを事前学習させたTransformerエンコーダは、他の言語にも転用可能だと分かっている。
    • 更には、楽譜やプログラミングコードなどの非依存言語データで訓練させたLSTM言語モデルが、自然言語の言語モデリングのタスクに転用できることも示されている。
  • つまり、言語間に共通する特徴をNNが学習によって得ており、その結果、学習した言語以外の言語タスクでも精度がある程度保たれているということ。
  • 本研究では、人工言語を用いて、その特徴が何なのかを調べている。
  • 結果として、トークンの頻度文法、トークンの種類す、系列のランダム性などの要素そのものは、転移可能性に余り影響を与えず系列中の位置を考慮した統計的依存性が重要であると示された。
    • 文章の文脈などが、言語間を超えた共通の特徴に当てはまると示唆された。
  • 先行研究の結果も、系列の位置を考慮した統計的依存性や、複数の言語の意味空間の構造の共通性が関係していると考察された。

 

所感

  • 先行研究の結果が言語間で共通する特徴によって得られている、ということについて、人工言語を用いてその特徴が何なのかを示唆したことが新規性と言える。
  • 人工言語を用意するやり方が、実験心理学の刺激を作る感じに似ていて、そのデータセットを作る意義を感じられて、面白いなと思った。
  • 人間の言語学習にも、ある言語を知っていると別の言語も覚えやすいみたいな話をよく聞く。
    • 例えば、英語とドイツ語は語順が似ているので覚えやすいとか。
  • 楽譜・プログラミングコードについては、個人的には直感的にはピンとこない。
    • プログラミングコードは英語だから、という点で未だ理解できなくはないが……
    • 位置というのが、大事な要素の一つなのだろうか。
    • 楽譜は音符の並び (位置) がパターンを形成してはいる。
  • そもそも、言語の転移学習というのをこの論文を読むまでは知らなかったので、この分野に興味が湧いた。

アルツハイマー病研究、失敗の構造

 

読み終えたので所感を。

 

所感

  • アルツハイマー病の特効薬がなぜ出来ないのか、というテーマを基に、アルツハイマー病の歴史、それらにまつわる主題な研究、定義も含めたこれまでの歴史の問題点、そして作者等によるアルツハイマー解明のための新たなモデルの提案と、研究に関わる組織・政策について提言をしている。
  • 脳の堆積物によってアルツハイマーが引き起こされる「アミロイドカスケード仮説」によって、他の仮説が冷遇されたり、アミロイドカスケード仮説を否定するデータを無視し、成果を求めてその仮説に固執したりした、などの問題点が語られていた。
  • 特に他の考えを否定する危うさに、私は共感した。音声の分野でも、似たような話を聞いたことがあったからだ。
    • 人が音を認識する際に、音情報だけで認識している考えと、口の動きのイメージも参照しているという考えがあり、前者が優遇され、後者が冷遇されたという話。
  • ある仮説が正しい、という流れで盛り上がっているときに、実は分野全体が間違った方向に向かっている可能性がある、と思ったら少し恐怖を覚えた。
  • 主流の考えが他の考えによってひっくり返る、というのは個人的には面白い流れだと思っているが、この本の状況だとそれが許されない。
    • 国・企業・研究所の様々な思惑によって、研究の正しい方法が行われないことの理不尽さがよく伝わる
  • 自分も他人の考えを気づかないうちに、頭ごなしに否定していて、それが長期的には不利益に繋げている可能性があるかもしれない
    • 視野を狭めないようにしたいが、外的な要因で気づかないうちにそうなっている可能性が怖い
    • 著者も、何故これほどまで、分野全体がアミロイドカスケード仮説に固執してしまったのか、というところに疑問を抱いていた
    • 後になって振り返ったり、外部の人間が見たりしないと分からないものなのかもしれない

E資格 2024 #1 受験レポ

www.jdla.org

 

受験し合格したのでレポート。

(追記:Qiitaにも初投稿、このブログ記事の内容を少し修正した)

qiita.com

背景

  • 受験理由:会社の業務の都合上、必要となったため。
  • 勉強期間:10月~2月上旬
  • 勉強開始前の状態:G検定を取ったばかり。それ以外の知見は、触れたり触れなかったり。

勉強について

  • 全体で4ヶ月程度。学習時間は200~300時間ぐらいか。
    • 業務用の学習もあったので、E資格専用の学習だけだと多分150~200時間ぐらい?
  • 10月~11月
    • 会社の業務で「ゼロから作るシリーズ①、②」を学習する。

 

 

    • ①でCNN、②でword2vec、RNN、LSTM、Seq2Seqを学習
      • 因みに①は既に数年前に買っていたので、①についてはほとんど省略した。
    • 知識だけではなく実装の仕方を学ぶ上でも重要だと思う。
      • E資格ではコードの問題があるので、非常に為になった。
    • 基礎を身につける上では、必要だと思う。
    • 単純にこのシリーズは読み物としても面白いのでオススメ。
      • ③以降も読みたい。
  • 12月~1月
  1. E資格認定プログラム (キカガク) を受講する

    • 認定プログラムを受けて、受験資格を取得する。
    • 会社から指定された「キカガク」の講習を受ける。

www.kikagaku.co.jp

    • 流れとしては以下の通り
      1. 「3日間の講習コースを受ける」
      2. E資格用のオンデマンドコース (動画・ドキュメントでの学習) を受ける
      3. プレテストコースの問題を全て正解にする
    • プレテストコースを完了させると、修了した証として文字列コードが何かしらの形で送られてくるので、それを記してキカガクに送りなおす (フォームでの回答だったかもしれない)。
    • 修了コードを送ることで「E資格受験用のコード」が送られてくるので、これで受験申込みができるようになる (受験申し込みの際に、E資格受験用のコードを入力する箇所がある)。
      • 受験日の1ヶ月前までにコースを修了したことを伝えないと、申込みまでに受験用コードの取得が間に合わないとのことだった。
      • しかし、受験日1ヶ月前から1週間前ぐらいにメールを送り、次の日にはコードが送られてきた (偶々?)。
      • いずれにせよ早めにコースは修了した方が良いかもしれない。
    • キカガクのコースの内容については、可もなく不可もなく。新シラバスに対応した内容であったが、提供されたコースだけを受けていれば、合格できるとは言えない。
      • 筆者は後述の黒本とキカガクのオンデマンドコースをベースに学習したが、試験後学習が足りていないなあと痛感した。
      • SNSを見ていると、別のサービスの名前を良く聞くので、個人で受ける場合はよく調べたほうが良いと感じた。
      • 但しキカガクのコースも、基礎をつけるという点では悪くはなかった。
  1. 黒本
    • シラバス改訂前の内容に対応した問題集
    • 受験前までに3週は行った
      • 1週目の時点で7割弱、2週目で8割程度。
      • 解説を読みながら、間違えたところを補完。
      • 基礎をつけるにはやって良かったと思う反面、今のシラバスに対応するための学習は、別の方法で行う必要があると思う。
      • 第3版が出る予定があるのかは不明だが、確実に取りたいのならば待つ、というのもアリかもしれない。
  1. Pytorch 実践入門
    • 業務の関係上、会社から提供されたもの。
    • E資格では「Pytorch」を選んだが、この本は大して読んでいなかった。
    • 実装するのには使える。
  • 2月~受験日前
    • キカガクのコースや黒本の解き直しなど。
      • 今思うと、新シラバスに対応するモデルの論文とか読んでたほうが良かったかもしれない。
      • 一応GPT、BERT、強化学習系の論文は読んだ。

受験について

問題については言及してはいけないとのことなので、それ以外の部分を述べる。

受験申込みについて

  • 金~日の3日間 (2024 #1 は2/16 ~ 2/18) のどれか1日を選んで申し込むのだが、1ヶ月前の時点で自分の地域では、土曜日 (2/17) の昼しか選べなかった。
    • 地域依存なのか、全国的にそうなのかは不明。
    • 日時を選びたいのならば、早めの申込みをオススメをする。

受験会場について

  • 会場につくと、身分証明が行われる。2点の身分証明書が必要。
  • 同意書などの記入をし、荷物をロッカーなどに入れる。この時、ポケットの中身も含めて、いかなる私物も試験部屋内に持ち込むことは出来ない。
    • ペンタブ的なものでサインもしたのだが、非常に書きにくかった。
    • 写真も撮られた。
  • 自分の会場では、プラスチックボード+2本の水性ペンを渡され、指定されたPCの前に座るよう、別部屋に誘導された。
    • プラスチックボードは計算用のボードだったのだが、ツルツルしてて非常に書きにくかった。
    • ペンもインクが切れてて、筆圧高めで書かないといけず、余計なことに時間や気が取られた。
    • 机には試験管を呼ぶスイッチみたいなのがある (会場による?) ので、気になる人は交換したほうが良い (自分は計算問題以外では使わなかったので、交換しなかった)。

受験について

  • 120分100問程度。
    • 1分1問ぐらいを意識して解いていった。
  • 画面の左端に電卓ボタンがあったが、試験の途中まで気づかず、それにより計算問題にやたら時間を取られた。
    • その結果、見直し途中で試験が終わった。
  • 難易度としては、黒本を初めて解いた程度?
  • 恐らく7~8割程度ぐらいかな、と思ったがあまり手応えは感じなかった。
  • 暗記だけでは駄目で、モデル内部のモジュールが何をしているのか、といった深い理解をしておくことが重要。

所感

  • 結果は予測通り全体で7割
    • 応用数学が6割程度、と思った以上にできていなくなっていて個人的にショック。
    • 自分の知識不足を痛感させられた。
    • 因みに合格ラインは公開されていない。
  • 個人的には、資金の面を無視すればAIの基礎固めには良い試験だと思う。
    • 講習と受験費用だけで10万円以上かかるため、個人で受けようとするとコストパフォーマンスは正直微妙 (無理して受ける必要があるかと言うと……)
    • 自分は会社が全て負担してくれたため、資金面に関しては何も悩まず。
      • 但し落ちたらどうしよう、というプレッシャーはあった。
  • 個人的には積本だった「深層学習 改訂第2版」をすらすら読めるようになったのが一番嬉しい
    • 勉強前にも読んでいたのだが、余り理解できず積本に……
    • 今再読しているが、E資格の学習内容に補完する形で、スムーズに読み進めている
      • 分からなかったことが分かるようになったのが楽しい

 

 

  • 次の試験ではシラバスが改訂されるので、シラバスを良く読んで対応をすべきと思われる
    • 自分はシラバスの確認をちゃんとしてなかったが、今思うと初期の方でよく確認しておくべきだったと痛感。
    • 一方で、新規分野の対応方法があまり無いのも現状。
      • 評判の良いプログラムを選びつつ、シラバスに書いてあるモデルの論文を読む、とかしておくと安定して点数が取れるかもしれない。
  • 因みにこの資格で、実装が出来るようになる……というわけではない。
    • 但し何かを実装するときに、どうすれば良いかのイメージが少しはつきやすくなった
    • 実装のためには別途学習や経験が必要で、飽くまでも基礎のための資格として受ける感じ。

GCPのメモ 2/n

概要

  • Cloud Audit Logs: リソースの作成・データの読み取りなどの操作がログとして記録
    • 不正アクセス・データ漏えいなどの有無
    • プロジェクト、フォルダ、組織ごとに保管される
  • 種類:
    • 管理アクティビティ監査ログ:リソース構成やメタデータの更新に関するログ
    • データアクセス監査ログ:リソース構成やメタデータの読み取り、ユーザが実行した操作に関するログ。有効化推奨。但しデータ量が膨大になる可能性があるため注意。
    • システムイベント監査ログ:Google Cloud 側で実行された操作に関するログ。
    • ポリシー拒否監査ログ:VPC Service Controls というプロダクトによって定義されたルールに決められる。保存対象のログはフィルタで制御可能。
  • 監査ログの保存先・保持期間
    • _Required:管理アクティビティ監査ログ・システムイベント監査ログ。デフォルトは400日。設定の変更は不可。
    • _Default :データアクセス監査ログ・ポリシー拒否監査ログ。デフォルトは30日。設定の変更は可。
      • 1~3650日で変更可能
  • 監査ログのシンク
    • ログを他の保管場所へ転送できる。転送先は「Google Storage」「BigQuery」「Pub/Sub」「ユーザー定義のログバケット
    • 集約シンク:組織は以下のプロジェクトにおける監査ログを1箇所に集約し、ログ分析を行うことも可能。

GCPのメモ Compute Engine 1/n

概要

  • Compute Engine: 仮想増しをコンピューティングリソースとして提供するプロダクト。個々の仮想マシンインスタンスと表される。
  • マシンファミリーの種類
    • 汎用のワークロード:コストパフォーマンスのバランスが良い。webアプリケーションやデータベースなど幅広く用いられる。
    • コンピューティング最適化:負荷が高く、高速な演算処理が必要な場合に用いる
    • メモリ最適化:大容量データを処理する場合に用いる
    • アクセラレータ最適化:機械学習などGPUが必要な場合に用いる
  • ストレージの種類
    • ゾーン永続ディスク:単一ゾーンにデータを保存。書き込み読み取りの性能はそこそこ。ハードウェアはHDD, SDD。可用性と性能の両方を求めている場合に用いる。
    • リージョン永続ディスク:リージョン内の2つのゾーンにデータを保存。書き込み読み取りの性能はゾーンより低い。ハードウェアはHDD, SDD。冗長性を重視する場合に用いる。
    • ローカルSDD:冗長性なし。インスタンスが停止すると削除される。読み取り書き込みの性能は高い。ハードウェアはSDDのみ。高い性能が必要で、一時的に用いる際に選択する。
    • Cloud Storage バケット:複数のゾーン・リージョンに保存するため可用性が大。読み込み書き込みは低い。高い性能を求めておらず、複数のインスタンスやゾーン・リージョン間でデータ共有する場合に用いる。

Langchain を触ってみる

www.udemy.com

 

LangChain を触っている。学習途中ではあるが、簡単にメモ。

 

概要

  • 講義元では「gpt-3.5-turbo」を使っているが、それ以外のモデルでも使うことは可能
    • 但し記述を少し変えなくてはならない
    • 例えばhuggingfaceのモデルではhuggingface 用のライブラリを用いる
    • from langchain.llms import HuggingFacePipeline
      from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
      import torch

      # GPUの確認
      device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
       
      model_id = "google/gemma-7b-it"
      tokenizer = AutoTokenizer.from_pretrained(model_id)
      model = AutoModelForCausalLM.from_pretrained(model_id).to(device)
      pipe = pipeline(
          "text-generation",
          model = model,
          tokenizer = tokenizer,
          max_new_tokens = 512,
      )
      llm = HuggingFacePipeline(pipeline=pipe)

       

  • プロンプトのテンプレートを作っておき、ユーザーの入力部分を変数にしておく
    • template = '''
      <bos><start_of_turn>user
      次のコマンドの概要を説明してください。
      コマンド:{command}
      <end_of_turn><start_of_turn>model
      '''

       commandがそれにあたる。

  • 最新のバージョンでは、LCEL」(LangChain Expression Language) という記述でプロンプトとモデルを結びつける。
    • qa_chain = (
          {'command': RunnablePassthrough()}
          | PromptTemplate.from_template(template)
          | llm
          | StrOutputParser()
      )
    • 1行目:入力部分 (commandにユーザーが入力したテキストが代入される)
    • 2行目:テンプレート (先程作ったもの)
    • 3行目:モデル (llm = HuggingFacePipeline(pipeline=pipe))
    • 4行目:恐らく出力
  • .invoke()で入力
  • プロンプトを繋げたい場合は、以下のように記述する。

    • cot_summarize_chain = (
          {'question': RunnablePassthrough()}
          | PromptTemplate.from_template(cot_template)
          | llm
          | {'input': StrOutputParser()} # 1つ目のプロンプトの出力を代入
          | PromptTemplate.from_template(summarize_template)
          | llm
          | StrOutputParser()
      )

       

    • 1つ目のプロンプトの出力 (StrOutputParser() ) を2つ目のプロンプトの入力に入れる。
    • このようにしてプロンプトを繋げていくことができる
    • 1つ目のプロンプトの出力を、2つ目のプロンプトで要約させる、といった使い方がある
  • vectorDB を作る際にも、プラットフォームに合わせて関数を変えなくてはならない
    • 講義ではOpenAI embedding を使っていた 
    • 多分、APIを使えるのならばこれが簡単だし知見もたくさんある
    • 自分はFAISS (Facebook のembedding)を用いた
    • from langchain.document_loaders import DirectoryLoader
      from langchain.indexes import VectorstoreIndexCreator
      from langchain_community.vectorstores.faiss import FAISS
      from langchain.embeddings import HuggingFaceEmbeddings
      from langchain.text_splitter import RecursiveCharacterTextSplitter

      loader = DirectoryLoader("./langchain/docs", glob="**/*.md")
      docs = loader.load()

      # チャンクの分割
      text_splitter = RecursiveCharacterTextSplitter(
          chunk_size=100,  # チャンクの最大文字数
          chunk_overlap=10,  # オーバーラップの最大文字数
      )

      vectorstore = FAISS.from_documents(
          docs,
          embedding=HuggingFaceEmbeddings(
              model_name='intfloat/multilingual-e5-base'
          )
      )

       

  • ドキュメントとモデルを結びつけるのも1行で可能
    • qa_chain = (
          {'context': vectorstore.as_retriever(search_kwargs={'k': 3}), 'question': RunnablePassthrough()}
          | PromptTemplate.from_template(template)
          | llm
          | StrOutputParser()
      )

       1行目:vectorstore.as_retrieverを追加

      • search_kwargsはよく分かってない (パラメータ用の設定?多分 'k' はtop_k?)
      • zenn.dev

  • チャットボットのように会話するためには、ConversationChainで良いらしい
    • import langchain
      from langchain.chains import LLMChain
      from langchain.prompts import PromptTemplate
      from langchain.schema.runnable import RunnablePassthrough
      from langchain.schema import StrOutputParser
      from langchain.chains import ConversationChain
      from langchain.memory import ConversationBufferMemory

      template = '''
      <bos><start_of_turn>user
      以下は、人間とAIが会話している様子です。AIは会話内容を考慮し、人間の質問に対して回答してください。AIは質問に対する答えを知らない場合は「知らない」と答えてください。
      会話内容:
      人間: {input}
      AI:
      <end_of_turn><start_of_turn>model
      '''
      prompt = PromptTemplate(
          input_variables=['history', 'input'],
          template=template
      )

      conversation = ConversationChain(llm = llm,prompt=prompt, memory=ConversationBufferMemory())

      while True:
        user_message = input("You: ")
        ai_message = conversation.predict(input=user_message)
        print(f"AI:{ai_message}")

       

所感

  • 講義元がgptモデルを使っていたので、huggingface用に変えるのが大変だったが、分かれば数行で設定できるを実感した
  • 所謂RAGの設定も、複雑ではなく、数行のコードを実行すればモデルがドキュメントを基にした回答をしてくれることを確認した
    • 個人的にもう少し難しいものだと思っていたから、実際に触って容易だったので、驚いた
    • 利用用途も多いので、これは基本的な知識として覚えておきたい
  • LangChainは現在もバージョンアップが頻繁に起きているため、記法などが頻繁に変わっているようである
    • GPTモデル使えるなら、講義元と同様のバージョンを使うのが無難
    • ただLCELはデフォルトスタンダードになっていく可能性があるようで、ここはあえて最近のバージョンをつかって書いて学習するというのもアリだと思う
  • 講義の目的は、Webアプリケーションに組み込む、またSlackのチャットボットを作るの2つ
    • なので、ここから形にしていくのが楽しみである。
    • 分かりやすく説明してくださっているので、やってて楽しい

gemma を使ってみた

cloud.google.com

 

Geminiと同様の方法で作られた軽量モデル「Gemma」を使ったという話。

 

  • IgakuQA と呼ばれる医師国家試験用のデータセットを使って、Gemmaに解かせてみた
    • 使ったモデルはgemma-7b-it
  • 参考したページは以下の通り
    • 特定のモデルでデータセット使って検証するまでのページ

       

    • GemmaをGoogle colab で使うための設定
    • 基本的には上記のページ達を参考にすればよい

  • しかし3点ほど問題があった

1.     'ascii' codec can't decode byte 0xe7 in position 41

  • IgakuQAにあるデータセット読み込みのscriptで引っ掛かる
  • import locale
    locale.getpreferredencoding = lambda: "UTF-8"

     

  • 文字コードを指定してやることで解決した
  • 但し、もう一度行ったところ再現性が無かったので、2.だけの対応で良いかもしれない

2.  モデルにデータセットを入力すると以下のエラー文が出る

probability tensor contains either `inf`, `nan` or element < 0

  • 確率テンソルにinf , nan, 要素が0 のどれかがあると判定されてエラーが出る模様
    • 同様の問題が以下のページにもあった
    • model = model.bfloat16() を設定することで解決
    • 原因は不明 (半精度浮動小数点数を指定してやるのが重要?)

3. gemmaの出力と回答の比較

  • gemmaの回答に無駄な出力が多かったため、うまく正答率を出すことが出来なかった
    • 【LLM入門~】 のページで、出力から不要な文字を削除する処理がある
    • def reshape_ans(input):
          reshaped = input.strip()
          reshaped = reshaped.split("(")[0]
          reshaped = reshaped.split("です")[0]
          reshaped = reshaped.split("は")[0]
          reshaped = reshaped.split("に")[0]
          reshaped = reshaped.split(" ")[0]
          reshaped = reshaped.replace("、", ",")
          reshaped = reshaped.lower()
          return reshaped

      preds_reshaped =
      for k in preds:
          k = reshape_ans(k)
        preds_reshaped.append(k)
    •  サンプルコードだと、不要な文字を上手く削除できていない
    • gemmaの出力の各行の1文字目が選択肢から選んだアルファベットなので、そこだけを取り出せば良い
    • preds_reshaped =
      for k in preds:
          k = reshape_ans(k)
          preds_reshaped.append(k[0])
  • 結果はgemma-7b-itで30%程度の正答率であった

所感

  • google colab で取り敢えず試しにgemmaを使ってみた
    • colabの無料版ではRAMの上限を超えたため、proに課金しなければならなかった
  • 業務に向けた学習にはなった
    • modelの設定
    • データセットからLLMの入力用にテキストを切り出し
    • 正答率を正しく求めるための処理
    • その他エラーの対応