環境に優しいAI:DeepSeek-R1が示す高効率学習の未来

先日発表された、DeepSeek-R1を色々調べています。まず、DeepSeek-V3を含めた諸元です。

NameDeepSeekDeepSeekQwen2.5Llama 3.1Claude 3.5GPT-4o
VersionV3V2.572B-Inst405B-InstSonnet-10220513
ArchitectureMoEMoEDenseDense
Activted Params37B21B72B405B
Total Params671B236B72B405B

まず、DeepSeekはMoE (Mixture of Expert)を利用したモデルであること。MoEは理論上、少ないパラメータ数でより精度の高いモデルを作れる可能性があります。この辺はLLMの未来: スケーリング則の限界と効率化の新アプローチで説明しています。そして、既に書いた、GPT-4以降のLLMスケーリング則の課題と解決策で説明したように、DeepSeek-R1では以下のような特徴があります。

  • 基本モデルに対する大規模強化学習(RL)の直接適用
  • 2つのRLステージと2つのSFTステージによる開発パイプライン

これらによって、DeepSeek-R1はかなり、効率のいい学習をしていると考えられます。学習データを導入したかは気にはなりますが、今はおいておきます。いかに大量のデータを入手しようと昨今の収穫逓減の状況にあってはうまい学習をさせないと性能には結びつかないためです。特に注目したのは最初のSFTステージで少量のコールドスタートデータを組み込みのところです。この部分はDeepSeek-R1を読むでも触れられていたので極めてセンスのいい部分だと思います。

聞くところによると、DeepSeek-R1はo1のようなモデルに比べて、1/10のコストで学習をしていると聞きます。これは、破格の高効率学習と言えます。

これらを踏まえると、DeepSeek-R1が普及するかとは別に、これがベンチマークとなって、AIモデルがゲームチェンジする可能性は十分あると見ています。今までは、大量の電力を使って、大量のGPUを買い集めてモデルを作っていました。しかし、それは環境的な持続性を考えても、コストを考えても常に適切だと考えるには無理があります。

いささか古い資料ではありますが、LLM(GPT-3)と人の消費電力の比較によれば、GPT-3において学習には約4.6TJのエネルギーを消費したと推定しています。それに対して、生体脳はたかだか一年で631.7MJです。全く、単位が違います。

生体脳と比べるべくもなく、コストが1/10になれば、チャレンジャーも増えることが想定できます。現状のLLMでは参入しているのはGoogle、Microsoft、metaと言った特に北米の超超大企業だけです。参入障壁は低いに越したことはありません。

私はゲームチェンジを歓迎します。

Janus Pro 1Bで実現する最新画像生成技術:GitHubリポジトリを活用した簡単ガイド

話題のJanus Pro 1Bを使ってみました。基本的にはレポジトリにあるコードベースで行っています。コードはGitHubで示します。

naoyaikeda/januspro1b

まあ、基本的にはやっていることは大したことはないです。レポジトリのコードでプロンプトを少しいじったくらいですね。Janusを使用している例はあったのでその延長上でやった感じです。コードとしては以下の感じです。

# Copyright (c) 2023-2024 DeepSeek.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
# the Software, and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import torch
from transformers import AutoModelForCausalLM

from janus.models import MultiModalityCausalLM, VLChatProcessor
import numpy as np
import os
import PIL.Image

# specify the path to the model
model_path = "deepseek-ai/Janus-Pro-1B"
vl_chat_processor: VLChatProcessor = VLChatProcessor.from_pretrained(model_path)
tokenizer = vl_chat_processor.tokenizer

vl_gpt: MultiModalityCausalLM = AutoModelForCausalLM.from_pretrained(
    model_path, trust_remote_code=True
)
vl_gpt = vl_gpt.to(torch.bfloat16).cuda().eval()

conversation = [
    {
        "role": "User",
        "content": "Toyota Sprinter AE86, White Car, (((Course out from curve))), (((Crashing))), , Dynamic Lighting, Dynamic Angle, (((Headlong into the valley)))",
    },
    {"role": "Assistant", "content": ""},
]

sft_format = vl_chat_processor.apply_sft_template_for_multi_turn_prompts(
    conversations=conversation,
    sft_format=vl_chat_processor.sft_format,
    system_prompt="",
)
prompt = sft_format + vl_chat_processor.image_start_tag


@torch.inference_mode()
def generate(
    mmgpt: MultiModalityCausalLM,
    vl_chat_processor: VLChatProcessor,
    prompt: str,
    temperature: float = 1,
    parallel_size: int = 16,
    cfg_weight: float = 5,
    image_token_num_per_image: int = 576,
    img_size: int = 384,
    patch_size: int = 16,
):
    input_ids = vl_chat_processor.tokenizer.encode(prompt)
    input_ids = torch.LongTensor(input_ids)

    tokens = torch.zeros((parallel_size*2, len(input_ids)), dtype=torch.int).cuda()
    for i in range(parallel_size*2):
        tokens[i, :] = input_ids
        if i % 2 != 0:
            tokens[i, 1:-1] = vl_chat_processor.pad_id

    inputs_embeds = mmgpt.language_model.get_input_embeddings()(tokens)

    generated_tokens = torch.zeros((parallel_size, image_token_num_per_image), dtype=torch.int).cuda()

    for i in range(image_token_num_per_image):
        outputs = mmgpt.language_model.model(inputs_embeds=inputs_embeds, use_cache=True, past_key_values=outputs.past_key_values if i != 0 else None)
        hidden_states = outputs.last_hidden_state

        logits = mmgpt.gen_head(hidden_states[:, -1, :])
        logit_cond = logits[0::2, :]
        logit_uncond = logits[1::2, :]

        logits = logit_uncond + cfg_weight * (logit_cond-logit_uncond)
        probs = torch.softmax(logits / temperature, dim=-1)

        next_token = torch.multinomial(probs, num_samples=1)
        generated_tokens[:, i] = next_token.squeeze(dim=-1)

        next_token = torch.cat([next_token.unsqueeze(dim=1), next_token.unsqueeze(dim=1)], dim=1).view(-1)
        img_embeds = mmgpt.prepare_gen_img_embeds(next_token)
        inputs_embeds = img_embeds.unsqueeze(dim=1)


    dec = mmgpt.gen_vision_model.decode_code(generated_tokens.to(dtype=torch.int), shape=[parallel_size, 8, img_size//patch_size, img_size//patch_size])
    dec = dec.to(torch.float32).cpu().numpy().transpose(0, 2, 3, 1)

    dec = np.clip((dec + 1) / 2 * 255, 0, 255)

    visual_img = np.zeros((parallel_size, img_size, img_size, 3), dtype=np.uint8)
    visual_img[:, :, :] = dec

    os.makedirs('generated_samples', exist_ok=True)
    for i in range(parallel_size):
        save_path = os.path.join('generated_samples', "img_{}.jpg".format(i))
        PIL.Image.fromarray(visual_img[i]).save(save_path)


generate(
    vl_gpt,
    vl_chat_processor,
    prompt,
)

作成した画像は以下の通りです。

コード中で画像のサイズが指定されていますが、そこだけの変更だともろもろ不整合を起こして正しく動きません。スライスとかを中心に考える必要があるかなと思います。プロンプトはとりあえず、入れたプロンプトは反映されてはいるようです。ただ、入れたプロンプトが、Stable Diffusion系列を当てにしているところがある、カッコによる強調とかですがその辺を見直す必要が恐らくあります。

1Bであればダウンロードしてモデルの規模感的には一般的な、GPUで動作できるのではないかとの所感を持っています。

コードのライセンスの文言はよくある、MITライセンスですが、PC Watchの記事によれば、画像生成の時のトークン処理にLlamaが使われているようなので、Llamaのリスクはありそうという感じはします。

ローカルでも動作させてみました、スクリプトは、DeepSeekの提供のものそのものです。瞬間的にVRAM消費はGeForce RTX3060 12GBのものをほとんど持ってっているので、Janus Pro 1Bがサイズ的にはローカルで動かすのには限界のように思えます。

作成した画像は以下のものです。

GPT-4以降のLLMスケーリング則の課題と解決策

まず、話を始める前にLLMにおけるスケーリング則を定義します。

AIのスケーリング則は限界を迎えたのか?進化の次のステージへによればスケーリング則は以下の3つからなるルールです。

  1. 計算データの量
  2. 計算リソース(計算量)
  3. モデルのパラメータ数

単純化して言えば、よりパラメータ数を増やした大規模モデルにすれば、性能はその分向上するというものです。そして、それには学習に用いるデータも関与しています。学習データを増やすことなく、パラメータ数だけを増やしていけば一般的には過学習に足を取られることが多いです。スケーリング則は、GPT-2からGPT-3へというところでは十分機能していたと言えます。

しかし、GPT-4 あたりからはスケーリング則は十分に機能したと言えない状況が見え始め、2023年にはサム・アルトマンは単に大きなモデルを作る時代は終わったとの発言に至っています。これはスケーリング則は経験則の領域で、それを支える法則には至ってはいないというところでもあります。この部分の壁は一般に収穫逓減の現象として知られています。

一方で物理的な壁は存在します。これは、GPUの計算リソースを増やし続けるには、無数にGPUを増やすほかなく、結果的には計算上、常に故障に悩まされますし、それらを考慮すればどんどんと、かかるコストは鰻上りになります。更に、必要な電力消費は全く軽視できないものになります。そもそも、LLMは人間の脳よりもエネルギー効率という点では全く及ばないのです。

その解決の一つは、MoEとBitNetです。この部分は昨年、LLMの未来: スケーリング則の限界と効率化の新アプローチにまとめています。

収穫逓減の現象そのものにも目を向けていますが、【AI基礎論】スケーリング則進化が加速した生成AI、競争過熱で"AI版ムーアの法則"に限界説も、2025年はどうなる?などいくつか目を通してはいますが、恐らくはスケーリング則そのものが法則という領域ではないということもあるとは思いますが、適切な説明はあまり見当たらないです。

とはいえ、新しい胎動もいくつか見受けられます。先のMoE、BitNetもそうですし、最近だと、DeepSeek-R1のように、学習過程に工夫を凝らすことで性能を向上しています。DeepSeek-R1とは?~推論特化のLLMで見る限りだと、1.と3.がポイントではないかと思われます。DeepSeek-R1について少し気になるところについては、DeepSeek-R1の実力とライセンス:知っておきたい重要ポイントで少しまとめています。

  • 基本モデルに対する大規模強化学習(RL)の直接適用
  • 2つのRLステージと2つのSFTステージによる開発パイプライン

恐らく、この辺の仕組みは参考にしたモデルが出てくるのではないかと思っているので、今後の流れを見ていけば、これらの価値は見通しがつくのではないかと思っています。

これらの成果をうまくまとめたモデルが出てくるのではないかと期待しています。

機械学習のアルゴリズム

機械学習のアルゴリズムは大きく分けて、教師付き学習、半教師付き学習、教師なし学習、強化学習に大別できます。本ドキュメントでは、機械学習のアルゴリズムを大別する方法について説明します。機械学習は、データからパターンを学習し、予測や意思決定を行うための技術であり、そのアルゴリズムは主に四つのカテゴリに分類されます。それぞれのカテゴリには独自の特性と適用範囲があり、理解することで適切なアルゴリズムを選択する手助けとなります。

教師付き学習

教師付き学習は、入力データとそれに対応する正解ラベルが与えられる学習方法です。このアルゴリズムは、与えられたデータを基にモデルを訓練し、新しいデータに対して予測を行います。代表的なアルゴリズムには、線形回帰、ロジスティック回帰、サポートベクターマシン(SVM)、決定木、ランダムフォレスト、ニューラルネットワークなどがあります。

SVMによる分類のサンプル

半教師付き学習

半教師付き学習は、教師付き学習と教師なし学習の中間に位置する手法です。少量のラベル付きデータと大量のラベルなしデータを使用してモデルを訓練します。このアプローチは、ラベル付けが困難または高コストな場合に特に有効です。半教師付き学習は、データの構造を利用して、ラベルなしデータからも情報を引き出すことができます。

半教師付き学習は大量のデータがあり、教師がついているデータと教師がついていないデータが混在している場合に有効です。例えば、医療データなどで診断自体を下すのが大変な場合、すべてのデータに教師をつけるのは現実的ではありません。しかし、データはあるのでそれをモデルに組み込めないかというのは当然の要求です。

半教師付き学習の例

1. 医療画像の分類

医療データでは、すべての画像に対して専門家によるラベル付けが非常に時間とコストがかかるため、半教師付き学習が有効です。例えば、X線画像の診断において、一部の画像に対して専門家が疾患の有無をラベル付けし、残りの多数の画像はラベルなしで使用します。半教師付き学習は、この少量のラベル付きデータを利用して、ラベルなしデータからも学習し、疾患の有無を分類するモデルを構築します。

2. スパムメールの検出

メールフィルターの構築では、ユーザーがスパムと判断したメールは少量ですが、多くのラベルなしメールデータがあります。半教師付き学習を使用して、少量のスパムラベル付きメールと大量のラベルなしメールデータを組み合わせ、スパム検出モデルを訓練することが可能です。

3. 商品レビューの感情分析

Eコマースの分野では、商品レビューの感情分析に半教師付き学習が利用されます。一部のレビューに対してポジティブ・ネガティブのラベルを付け、そのラベル付きデータと大量のラベルなしレビューを用いて感情分析モデルを構築します。これにより、すべてのレビューを自動的に分析し、顧客満足度を評価することができます

教師なし学習

教師なし学習は、ラベルなしのデータを用いてデータの構造やパターンを発見する手法です。このアルゴリズムは、クラスタリングや次元削減などのタスクに使用されます。代表的なアルゴリズムには、k-meansクラスタリング、階層的クラスタリング、主成分分析(PCA)、t-SNEなどがあります。

教師なし学習の例

強化学習

強化学習は、エージェントが環境と相互作用しながら最適な行動を学習する手法です。エージェントは、行動を選択し、その結果に基づいて報酬を受け取ります。報酬を最大化するために、エージェントは試行錯誤を通じて学習を進めます。強化学習は、ゲームプレイやロボット制御、自動運転車などの分野で広く応用されています。

セブンイレブンの蹄鉄

セブンイレブンの不振が色々と話題になっています。YouTubeとかでも色々とポストされています。このへんとか
セブン社長、”無能”で有名だったことが判明。客をフル無視した結果、客離れ深刻化して悲惨な結果に…【ゆっくり解説】、とはいえ見えてないことも色々あって、一つは2019年という年、これは今の社長とかの現政権が出来た年なんだけど、この辺にマジックがあると思っていて、まず、2018年これはセブンペイという問題案件が起きた年で、セブンペイの終焉が2019年です。このセブンペイを私はその後の惨劇も絡めて、SEVEN PAINと呼んでいます。

現状、最大の問題は元々、セブンイレブンは商品が評価されていましたが、現状、その商品で不満を呼んでいるということです。そして、買収騒動なども含めて、戦略的なカードを切るどころではないということです。恐らく、提携などを含めて、戦略的なカードは現在の騒動の中では難しいと考えざるを得ません。なぜなら、買収のターゲットになっている以上、いかに、提携などを進めても状況次第ではゼロクリアされかねず、足元を見られるからです。

さて、セブンペイでセブンイレブンは何をしたかったのか、今となっては過程でしかありませんが考えてみます。

    • 決済手数料の最小化
    • ラストワンマイルへのリーチ

決済手数料の最小化は説明の必要はないでしょう。ラストワンマイルへのリーチというのは、例えば、Suicaなどに頼れば、リアルタイムな決済情報は手に入りません。そして、決済時に例えば、クーポンを表示するなどの施策も困難です。恐らく、こういった施策の実現が目的だったと思います。そのため、Nanacoからの移管を図ったわけです。しかし、SEVEN PAINでこの構想は無残な夢想に終わりました。ここから一歩も抜け出せていないわけです。

今のままですと、ファミペイを進めるファミマ、auとの一体化を進めるローソンにはおいて行かれるだけでしょう。

Jupyer環境をWSL上に構築する 2020

本アーティクルのオリジナルはhttps://technow.grayrecord.com/2020/04/19/jupyter-environment-on-wsl/になります。

前提条件

項目内容
使用ディストリビューションUbuntu 18.04 LTS
Python 環境Anaconda

AnacondaでJupyter環境を構築する

Python環境の構築はデータサイエンティストを目指す人のpython環境構築 2016を参考にして、一部のステップをアップデートしています。

環境構築方法

  1. pyenvのインストール
    git clone https://github.com/yyuu/pyenv.git ~/.pyenv
    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
    echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
    echo 'eval "$(pyenv init -)"' >> ~/.bashrc
    source ~/.bashrc
    
  2. anacondaのインストール
    pyenv install -l | grep ana
    # 最新版を確認する
    pyenv install anaconda3-yyyy.MM
    # 先のステップで確認した最新版にする
    pyenv rehash
    pyenv global anaconda3-yyyy.MM
    conda update conda
    conda init bash
    # PowerShellの場合、powershellに変える
    source ~/.bashrc
    
  3. Windows Terminal Previewのインストール

MicrosoftストアからWindows Terminalをインストールする。

分析環境をWindows上に構築する 2020

本アーティクルはhttps://technow.grayrecord.com/2020/04/19/jupyter-environment-on-windows/からになります。

環境の選択

環境構築については、Windowsに限定しても、いくつかの選択肢があります。

Pythonについては、CPythonを標準の配布物から、Anaconda、Microsoft Storeなど
複数の入手経路があります、この文章ではいくつかの理由から、Anacondaを使用しています。
現在は、AnacondaをAnacondaのサイト上から入手していますが、
Anacondaはscoopのextraバケットにもあります。

scoopのインストール

  1. スタートからPowerShellを起動する
  2. PowerShellの設定変更
    Set-ExecutionPolicy RemoteSigned -scope CurrentUser
    
  3. PowerShellからのScoopのインストール
    iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
    

gitのインストール

scoop install git

Anacondaのインストール

Anaconda Individual Editionから最新版をインストールする。

Windows Terminalのインストール

MicrosoftストアからWindows Terminalをインストールする。

Visual Studio Codeのインストール

公式サイトから最新版をダウンロードしてインストールする。

SingularityのWSL2への構築

本記事はQiitaに投稿した記事になります。

SingularityコンテナをWSL2上に構築しました。構築環境はSingularityの公式サイトの記述に基づき、Ubuntu 22.04上とします。 参考となるドキュメントは https://docs.sylabs.io/guides/latest/admin-guide/installation.html#installation-on-windows-or-mac に存在します。このドキュメントに従えば、Singularity 4.0.0がインストールされます。

手順としては以下の通りになります。

wget https://github.com/sylabs/singularity/releases/download/v4.0.0/singularity-ce_4.0.0-jammy_amd64.deb
sudo apt install ./singularity-ce_4.0.0-jammy_amd64.deb

まず、Singularity 4.0.0のUbuntu 22.04用のdebファイルを取得します。しかる後に、debファイルをaptコマンドでインストールします。当方で実行したときにはいくつか気になるメッセージが出力されていましたがインストール自体は行われているようです。以下のメッセージの表示理由等は未解明です。

N: Download is performed unsandboxed as root as file ‘/home/gorn/singularity-ce_4.0.0-jammy_amd64.deb’ couldn’t be accessed by user ‘_apt’. – pkgAcquire::Run (13: Permission denied)

さて、Singularityがインストールできたので確認してみます。

以下のファイルをex001.defとして作成します。

Bootstrap: docker
From: ubuntu:22.04

%post
    apt-get -y update
    apt-get -y upgrade

%runscript
    echo "Hello, Ubuntu"

以下のコマンドでビルドします。

singularity build ubuntu.sif ex001.def

Ubuntu 22.04のイメージとなります。

Shellでコンテナの中に入ってみます。

singularity shell ubuntu.sif
とりあえず、動きは確認できました。