Jetson AGX Orin 開発者キットで、Deep Seek R1 を動作させる詳細手順。エッジAIに向けて。
オートロ株式会社の代表をしております福田です。オートロとオープンでLLMの研究開発を行っております。チームでの研究開発活動を発表していきます。今回は、エッジAIの検証を行ってもらった結果を公開します。
概要
今回は、jetson AGX Orin 開発者キット 32GBを使用してローカルLLMを実装し、トークン生成速度やVRAM使用量について検証を行った。簡単なプロンプトを用いた検証により、Ollama経由でダウンロードした「DeepSeek-R1」「Qwen2.5」の2種類のモデル(パラメーター数:14B, 4bit量子化)については、どちらも問題なく動作することと、最大消費電力を増加させることで出力生成速度とVRAM使用量が増加する傾向があることを確認した。また、コンテキスト長を変化させて長文小説の要約を行う検証では、コンテキスト長が増えるほどトークン生成速度が低下し、VRAM使用量が増加する傾向があることを確認した。この記事では、Jetson AGX Orin 開発者キットを用いてLLMを動かす手順と今回行った動作検証の結果について共有する。
Jetson AGX Orin 開発者キットとは
Jetson AGX Orin 開発者キットは、NVIDIAが開発しているエッジコンピューティング向けの小型コンピュータである。エッジコンピューティングとは、データをクラウドに送らずに処理する技術のことであり、クラウドコンピューティングに比べて以下のような点で優れている。
- 低遅延
- データをクラウドに送信しないため、通信によって発生する遅延を軽減できる。
- プライバシー向上
- データをクラウドに送信しないため、個人情報や機密情報の漏洩リスクを軽減できる。
- オフライン環境でも動作可能
- インターネット接続が不要なため、通信環境の影響を受けない。
今回使用した端末について
今回は、Jetson AGX Orin 開発者キット 32GBを使用した。
端末情報
項目 | jetson AGX orin 開発者キット 32GB |
---|---|
価格 | 約25.5万円 |
AI パフォーマンス | 275 TOPS |
GPU | 2048基の NVIDIA® CUDA® コアと 64基の Tensor コア搭載 NVIDIA Ampere アーキテクチャー |
CPU | 12コア Arm Cortex-A78AE v8.2 64ビット CPU |
メモリ | 32GB 256ビット LPDDR5 204.8 GB/秒 |
ストレージ | 64GB eMMC 5.1 |
消費電力 | 15W ~ 60W |
サイズ | 110mm x 110mm x 71.65mm |
OS | Ubuntu 20.04.6 LTS |
優れた点として、以下のような点が挙げられる。
- 高性能:最大 275 TOPS(毎秒275兆回の演算) のAI推論性能を持つ。
- 省電力:15Wから60Wまでの電力設定が可能で、用途に応じた電力効率の最適化が可能。
- コンパクト:110mm x 110mm x 71.65mmとコンパクトなため、持ち運びがしやすい。
- 安価で大容量のVRAM:Jetson AGX Orin 開発者キットには、64GBと32GBの2種類があり、Nvidiaの基本的なGPUと比べて安価で大容量のVRAMを利用できるため、パラメータサイズが大きいLLMを動かせる。
一方で、以下のような点に対しては、導入時に課題となる可能性がある。
- ストレージ:64GBしかないため、状況に応じて追加する必要がある。
- OS:Ubuntuベースの専用OSを使用する必要がある。
Jetson AGX Orin 開発者キットのセットアップ
ここでは、端末のセットアップについて説明する。今回は、公式サイトの手順に沿って初期設定を行った。
1. Ubuntuのセットアップ
初めに、Ubuntuのセットアップを行う必要がある。セットアップ方法としては、
・ディスプレイ接続:ディスプレイ、キーボード、マウスを接続する方法
・ヘッドレス構成:別の (ホスト) コンピューターから接続する方法
の二種類が紹介されている。
今回は、ディスプレイ接続でセットアップを行ったため、その手順について説明する。ヘッドレス構成のセットアップ方法については、公式サイトから確認できる。
周辺機器を接続
画像のように、本体側部にある差込口に電源、マウス、キーボード(USB)、ディスプレイ(HDMI)を接続する。
電源を入れる
周辺機器の接続が終わると開発キットの電源が自動的に入る。入らない場合は、本体側部の電源ボタンで起動する。
ネットワーク接続
今回は、初回起動時点でアカウント作成等の設定が事前に行われていたため、画面右上をクリックし、Wi-Fiの設定のみを行った。
※起動後に初回起動時に設定が必要だった場合は、公式サイトを参照しながら設定を行う。
2. JetPackコンポーネントをインストール
Ubuntuのセットアップが完了したら、インターネットから L4T バージョンに対応する最新の JetPack コンポーネントをインストールする。
L4Tとは、Linuxカーネル、UEFIブートローダー、NVIDIAドライバー、フラッシュユーティリティ、Ubuntuベースのサンプルファイルシステムなど、Jetsonプラットフォーム用のさまざまなものが含まれているjetoson用のボードサポートパッケージのことである。
L4Tのバージョン確認
以下のコマンドを実行して、L4Tのバージョンを確認する。
cat /etc/nv_tegra_release
実行結果
# R35 (release), REVISION: 4.1, GCID: 33958178, BOARD: t186ref, EABI: aarch64, DATE: Tue Aug 1 19:57:35 UTC 2023
R34 (release), REVISION: 1.0
以降のバージョンは、aptソースリストがすでに最新の状態である。そのため、R35 (release), REVISION: 4.1
である今回は、特に追加の処理を行わずに次の手順へ移行した。
もし、R34 (release), REVISION: 1.0
以前のバージョンが表示された場合は、以下のコマンドを使用してL4Tを更新する必要がある。
sudo bash -c 'echo "deb https://repo.download.nvidia.com/jetson/common r34.1 main" >> /etc/apt/sources.list.d/nvidia-l4t-apt-source.list'
sudo bash -c 'echo "deb https://repo.download.nvidia.com/jetson/t234 r34.1 main" >> /etc/apt/sources.list.d/nvidia-l4t-apt-source.list'
JetPackコンポーネントのインストール
L4Tの更新が終わったら、以下のコマンドでJetPackコンポーネントをインストールする。
sudo apt update
sudo apt dist-upgrade
sudo reboot
sudo apt install nvidia-jetpack
※通信環境によっては、インストールに約1時間程度の時間がかかる場合がある。
その他の設定
そのほかに設定した項目についても、設定手順を紹介する。設定は画面右上をクリック → Settingsからアクセスできる。
タイムゾーンの設定
以下の手順で、日本時間に変更ができる。
Settings → Date & Time → Time Zone の順で選択し、JST (Tokyo, Japan)に変更
日本語入力の設定
画面左下にあるshow applicationをクリック → Language Supportを選択
Install / Remove Languagesを選択後、JapaneseにチェックしてApply
Settings → Region & Language → Input Sources +の順で選択
Other → Japanese(Mozc) の順で追加する。このとき、ロードに少し時間がかかるため注意。
上記の設定を行うことで、「windows+space」で入力形式を変更することができる。日本語入力ができない状態では、検証の際に不便になることが多いため事前に設定することを推奨する。
LLM環境構築
次に、LLMの環境構築に使用したOllamaとその導入手順ついて説明する。
Ollamaとは
Ollamaは、ローカル環境下でのLLMの管理や実行をサポートするオープンソースのツールである。ターミナルでコマンドを使用することで、モデルのダウンロード、チャット形式の会話、モデルに関する情報の確認などを行うことができる。また、Pythonライブラリも提供されており、Pythonプログラムでも手軽にローカルLLMを使用することができる。
Ollamaの導入
Ollamaのインストール
はじめに、以下のコマンドを実行してOllamaをインストールする
curl -fsSL https://ollama.com/install.sh | sh
インストールの確認
以下のコマンドで、Ollamaが実際にインストールされていることを確認する。
ollama --version
以下のようにバージョンが表示されれば、正常にインストールされている。
# ollama version is 0.5.13
Ollamaの利用
コマンド
Ollamaのインストールが完了したら、ターミナル上でコマンドを用いてモデルの管理や実行を行うことができる。以下に利用頻度の高い主要なコマンドについてまとめる。
コマンド名 | 内容 | 使用例 | コマンド |
---|---|---|---|
pull | モデルのダウンロード | Pythonで使用するモデルのダウンロード | ollama pull [モデル名] |
run | ターミナル上でのモデルの実行 | モデルの回答精度の確認 | ollama run [モデル名] |
list | ダウンロードしたモデルの一覧表示 | Pythonライブラリで使用する際のモデル名の確認 | ollama list |
rm | モデルの削除 | 不要なモデルの削除 | ollama rm [モデル名] |
LLMの動作確認
Ollamaが動作するかを確認するために、以下のようにrunコマンドを実行する。ここでは、モデルとして「deepseek-r1:1.5b」を使用する。
ollama run deepseek-r1:1.5b
正常に動作すれば、以下のようにモデルに対してメッセージの送信が可能になり、チャット形式で会話を行うことができる。また、/byeと送信する
or ctrl+D
で会話を終了することができる。
実際の動作例(deepseek-r1:1.5b)
Python環境構築
次に、検証用プログラムを作成するために必要なPythonの環境構築について説明する。
実行環境
今回構築した環境は、以下の通りである。
仮想環境 | venv |
Pythonのバージョン | Python 3.8.10 |
pipのバージョン | e-packages/pip (python 3.8) |
手順
ここでは、具体的な手順について説明する。
Pythonのインストール
以下のコマンドで、Pythonがインストールされているかを確認する。
python --version
今回は、Pythonが事前にインストールされていたため、そちらを仮想環境に使用した。インストールされていない場合は、こちらのサイトなどを参考にPythonをインストールする。
作業用フォルダの作成
今回の検証用に仮想環境用フォルダを作成する。
仮想環境の作成
仮想環境用フォルダ内でターミナルを開き、以下のコマンドを実行して仮想環境を作成する。
python -m venv [仮想環境名]
仮想環境の起動
以下のコマンドによって、仮想環境を起動する。
source ./[仮想環境名]/bin/activate
pipのインストール
仮想環境が起動出来たら、Python開発に使用するjupyter labを含むパッケージをインストールする。はじめに、以下のコマンドでpipがインストールされていることを確認する。
pip --version
インストールできていない場合は、こちらのサイトなどを参考にインストールする。
パッケージのインストール
pipのインストールが完了したら、インストールしたいパッケージを requirement.txt
にまとめて記載し、仮想環境用フォルダに保存する。以下に、今回使用したファイルを示す。
今回使用したrequirement.txt
pandas
numpy
jupyter
ollama
jupyterlab
langchain-community
torch
jetson-stats
requirement.txt
が作成できたら、仮想環境を起動した状態で以下のコマンドを実行し、パッケージをインストールする。
pip install -r requirements.txt
jupyter labの起動
以下のコマンドで、先ほどインストールしたjupyter labを起動する。
jupyter lab
ブラウザ上でjupyter labが起動すれば、正常に動作している。これにより、jupyter labを使用したPythonの開発が可能である。
検証
次に、今回行った検証の手順や結果について説明する。
基本動作
はじめに、ollamaを用いてLLMを動作させたPythonプログラムの概要について説明する。
コード全体(ollama_steram.py)
import ollama
import time
import sys
import threading
from queue import Queue
from dataclasses import dataclass
from typing import List, Dict
from jtop import jtop
@dataclass
class VRAMSnapshot:
timestamp: float
shared: float
def to_dict(self) -> Dict:
return {
"timestamp": self.timestamp,
"shared": self.shared
}
class VRAMMonitor:
def __init__(self, interval: float = 0.1):
self.interval = interval
self.running = False
self.snapshots: List[VRAMSnapshot] = []
self.peak: VRAMSnapshot = None
self._lock = threading.Lock()
self._stop_event = threading.Event()
self._thread = None
def start(self):
"""モニタリングを開始"""
with self._lock:
if self._thread is not None and self._thread.is_alive():
return
self.running = True
self._stop_event.clear()
self._thread = threading.Thread(target=self._monitor_loop, daemon=True)
self._thread.start()
def stop(self):
"""モニタリングを停止"""
self._stop_event.set()
if self._thread is not None:
self._thread.join()
self.running = False
def _monitor_loop(self):
"""VRAMモニタリングのメインループ"""
with jtop() as jetson:
while not self._stop_event.is_set():
try:
snapshot = get_current_vram(jetson)
with self._lock:
self.snapshots.append(snapshot)
if self.peak is None or snapshot.shared > self.peak.shared:
self.peak = snapshot
time.sleep(self.interval)
except Exception as e:
print(f"モニタリングエラー: {e}")
break
def get_current_vram(jetson) -> VRAMSnapshot:
"""現在のVRAM使用量をスナップショットとして取得"""
ram = jetson.memory["RAM"]
return VRAMSnapshot(
timestamp=time.time(),
shared=ram["shared"] / 1e6
)
def stream(model: str, prompt: str, debug: bool = False):
"""LLMを使用してテキスト生成を行い、VRAM使用状況を監視する"""
if debug:
print(f"--------\n使用モデル:{model}\nプロンプト:{prompt}\n回答")
monitor = VRAMMonitor(interval=0.1)
monitor.start()
with jtop() as jetson:
idle_vram = get_current_vram(jetson)
time.sleep(1)
message = ""
chunk = None
try:
stream = ollama.chat(
model=model,
messages=[{"role": "user", "content": prompt}],
stream=True,
keep_alive=2,
options={"num_ctx": 4096}
)
for chunk in stream:
try:
text = chunk.get("message", {}).get("content", "")
print(text, end="", flush=True)
message += text
except Exception as e:
print(f"\nストリームエラー: {e}")
break
finally:
monitor.stop()
time.sleep(2)
with jtop() as jetson:
final_vram = get_current_vram(jetson)
if chunk:
total_duration = chunk.get("total_duration", 0) / 1e9
load_duration = chunk.get("load_duration", 0) / 1e9
prompt_eval_count = chunk.get("prompt_eval_count", 0)
prompt_eval_duration = chunk.get("prompt_eval_duration", 1e9) / 1e9
eval_count = chunk.get("eval_count", 0)
eval_duration = chunk.get("eval_duration", 1e9) / 1e9
tps = eval_count / eval_duration if eval_duration > 0 else 0
else:
total_duration = load_duration = prompt_eval_count = prompt_eval_duration = eval_count = eval_duration = tps = 0
if debug:
print("\n--動作状況--")
print(f"モデル: {model}")
print(f"モデルのロード時間: {load_duration:.2f}秒")
print(f"生成トークン数: {count}")
print(f"生成にかかった時間: {eval_duration:.2f}秒")
print(f"生成トークン/秒: {tps:.2f}")
print("\n--VRAM使用状況--")
print(f"実行前: {idle_vram.shared:.2f}GB (shared)")
if monitor.peak:
print(f"ピーク時: {monitor.peak.shared:.2f}GB (shared)")
print(f"実行後: {final_vram.shared:.2f}GB (shared)")
if monitor.snapshots:
total_time = monitor.snapshots[-1].timestamp - monitor.snapshots[0].timestamp
print("\n--モニタリング詳細--")
print(f"サンプル数: {len(monitor.snapshots)}")
print(f"モニタリング時間: {total_time:.2f}秒")
print(f"サンプリング間隔: {monitor.interval*1000:.0f}ms")
return {
"model": model,
"prompt": prompt,
"message": message,
"total_duration": total_duration,
"load_duration": load_duration,
"prompt_eval_count": prompt_eval_count,
"prompt_eval_duration": prompt_eval_duration,
"eval_count": eval_count,
"eval_duration": eval_duration,
"tokens_per_second": tps,
"idle_vram": idle_vram.shared,
"peak_vram": monitor.peak.shared if monitor.peak else None,
"delta_vram" : (monitor.peak.shared) - (idle_vram.shared),
"final_vram": final_vram.shared
}
if __name__ == "__main__":
if len(sys.argv) < 3:
print("Usage: python script.py <model_name> <prompt>")
sys.exit(1)
_, model_name, prompt = sys.argv
stream(model_name, prompt, debug=True)
以下のコマンドを実行することで、プロンプトに対する指定したモデルでの回答と評価指標を表示される。
python ollama_stream.py [モデル名] [プロンプト]
評価指標の詳細については後述するため、ここでは回答の出力について説明する。
回答のストリーム出力
今回は、出力スピードを直感的に理解するため、回答はストリーム出力(一括ではなくチャンクごとに順番に表示するChatGPTなどで採用されている方法)で実装した。以下の部分がOllamaでの回答をストリーム形式で出力するプログラムである。
stream = ollama.chat(
model=model,
messages=[{"role": "user", "content": prompt}],
stream=True,
keep_alive=2,
options={"num_ctx": 4096}
)
使用した引数
引数 | 内容 |
---|---|
model | 使用するモデルの設定 |
messages | 入力プロンプトと役割の設定 |
stream | ストリーム出力の設定 |
keep_alive | モデルがVRAMにロードされた状態を維持する時間(秒)の設定。デフォルトは300 |
options(num_ctx) | 入力コンテキスト長(トークン)の設定。デフォルトは2048 |
上記で得たストリーム形式の出力を、以下の部分でfor文を利用して順番に表示する。
for chunk in stream:
try:
text = chunk.get("message", {}).get("content", "")
print(text, end="", flush=True)
message += text
except Exception as e:
print(f"\nストリームエラー: {e}")
break
評価指標
今回は、以下の評価指標に注目した。
- トークン生成速度(トークン/秒)
- VRAM使用量(GB)
ここからは、評価指標の詳細と取得方法について、実際に使用したプログラムを用いて説明する。
トークン生成速度(トークン/秒)
Ollamaのストリーム出力形式では、最後のチャンクから以下の情報を取得することができる。
変数名 | 内容 | 単位 |
---|---|---|
total_duration | 合計処理時間 | 秒 |
load_duration | モデルのロード時間 | |
prompt_eval_duration | 入力処理時間 | |
eval_duration | 出力生成時間 | |
prompt_eval_count | 入力トークン数 | トークン |
eval_count | 出力トークン数 |
コードでは、以下の部分で情報を取得している。
if chunk:
total_duration = chunk.get("total_duration", 0) / 1e9
load_duration = chunk.get("load_duration", 0) / 1e9
prompt_eval_count = chunk.get("prompt_eval_count", 0)
prompt_eval_duration = chunk.get("prompt_eval_duration", 1e9) / 1e9
eval_count = chunk.get("eval_count", 0)
eval_duration = chunk.get("eval_duration", 1e9) / 1e9
トークン生成速度(tokens/sec)は、Ollamaから直接取得できないため、取得した出力トークン数や出力生成時間のデータを用いて、以下のコードで計算する。
tps = eval_count / eval_duration if eval_duration > 0 else 0
VRAM使用量(GB)
jetson-statsのインストール
VRAM使用量については、jetson-stats
というjetsonデバイスのモニタリングツールをインストールし、Pythonライブラリのjtop
を用いてデータを取得する。
jetson-stats
のインストールが完了していない場合は、requirements.txt
に jetson-stats
を追記し、以下のコマンドでインストールする。
pip install -r requirements.txt
インストール後、一度再起動を行う。その後、ターミナルで jtop
というコマンドを実行し、問題なく起動すればインストールが完了している。
Pythonでの実装
jtop
を用いると、以下の関数で実行時点でのVRAM使用量を取得することができる。
def get_current_vram(jetson) -> VRAMSnapshot:
"""現在のVRAM使用量をスナップショットとして取得"""
ram = jetson.memory["RAM"]
return VRAMSnapshot(
timestamp=time.time(),
shared=ram["shared"] / 1e6
)
VRAM使用量を取得するためのクラスは、以下の部分で定義している。start
関数でモニタリングを開始し、stop
関数で終了するまでの間、_monitor_loop
関数でinterval
毎に get_current_vram
関数を実行して、VRAM使用量のピーク値を更新し続ける。
class VRAMMonitor:
def __init__(self, interval: float = 0.1):
self.interval = interval
self.running = False
self.snapshots: List[VRAMSnapshot] = []
self.peak: VRAMSnapshot = None
self._lock = threading.Lock()
self._stop_event = threading.Event()
self._thread = None
def start(self):
"""モニタリングを開始"""
with self._lock:
if self._thread is not None and self._thread.is_alive():
return
self.running = True
self._stop_event.clear()
self._thread = threading.Thread(target=self._monitor_loop, daemon=True)
self._thread.start()
def stop(self):
"""モニタリングを停止"""
self._stop_event.set()
if self._thread is not None:
self._thread.join()
self.running = False
def _monitor_loop(self):
"""VRAMモニタリングのメインループ"""
with jtop() as jetson:
while not self._stop_event.is_set():
try:
snapshot = get_current_vram(jetson)
with self._lock:
self.snapshots.append(snapshot)
if self.peak is None or snapshot.shared > self.peak.shared:
self.peak = snapshot
time.sleep(self.interval)
except Exception as e:
print(f"モニタリングエラー: {e}")
break
以下のように、LLM回答を生成中に並列処理でVRAM使用量のモニタリングを行い、VRAM使用量の初期値、ピーク値、最終値を記録する。
def stream(model: str, prompt: str, debug: bool = False):
*************
monitor = VRAMMonitor(interval=0.1)
monitor.start()
with jtop() as jetson:
idle_vram = get_current_vram(jetson)
*************
try:
# 回答の生成
finally:
monitor.stop()
with jtop() as jetson:
final_vram = get_current_vram(jetson)
このデータから、ピーク値と初期値の差分を計算し、LLM実行時のVRAM使用量とする。
使用モデル
今回の検証では、「Deepseek-R1」と「Qwen2.5」の2種類 × 各3サイズの計6つのモデルを使用した。
- Deepseek-R1(1.5B, 7B, 14B)
- DeepSeek-R1は、中国のAI企業DeepSeekが2025年1月に発表した大規模言語モデルである。強化学習を活用した独自のトレーニング手法により、複雑な問題解決に優れた推論能力を持ち、回答だけでなく思考の過程も出力する特徴がある。
- Qwen2.5(3B, 7B, 14B)
- Qwen2.5は、Alibaba CloudのAI研究チームであるQwenが2024年9月に発表した大規模言語モデルである。すべてのモデルが最大18 兆トークンを網羅する最新の大規模データセットで事前トレーニングされており、日本語を含む29以上の言語に対応している。
また、今回使用したモデルは、すべて4bit量子化されたモデルである。
検証方法と結果
今回は、以下に示す3種類の検証を行った。
- 簡単なプロンプトの実行時の評価
- 簡単なプロンプトを複数実行し、評価指標の平均値を検証する。
- 最大消費電力を変化させたときの評価
- 最大消費電力を変えて、1のプロンプトを実行したときの評価指標の平均値の変化を検証する。
- 入力コンテキスト長を変化させたときの評価
- 長文小説「こころ」の要約問題で、入力コンテキスト長による評価指標の変化を検証する。
1. 簡単なプロンプト実行時の評価
今回は、以下に示す4つのプロンプトを各モデルに入力し、評価指標の平均値を結果として出力した。
プロンプト一覧
プロンプト | 言語 | 内容 |
---|---|---|
Hello. | 英語 | 挨拶 |
List the days of the week. | 指示 | |
こんにちは! | 日本語 | 挨拶 |
りんごの色は何ですか? | 質問 |
結果(最大消費電力:30W)
Model | Parameters (B) | Output Speed (tokens/sec) | VRAM Usage (GB) |
---|---|---|---|
DeepSeek-R1 | 1.5 | 20.22 | 2.00 |
DeepSeek-R1 | 7 | 7.87 | 5.74 |
DeepSeek-R1 | 14 | 4.47 | 11.14 |
Qwen2.5 | 3 | 12.94 | 2.99 |
Qwen2.5 | 7 | 7.03 | 5.74 |
Qwen2.5 | 14 | 4.61 | 11.14 |
この結果から、以下のことがわかる。
- 検証したモデルは、すべて問題なく動作した。
- パラメータ数が増加すると、出力生成速度が低下し、VRAM使用量が増加する傾向がある。
- 出力生成速度とVRAM使用量は、モデルの種類よりもパラーメータ数による影響が大きい。
出力例
以下に、「りんごの色は何ですか?」に対する出力例を示す。
DeepSeek-R1:1.5B
<think>
</think>
りんご( RI-n-gu )は largely 蓑icolorの花を-haveなう。花の色は largely 水や汻や水体や空気などから source されan。
具体的な花の色は suivうの directionalに分 classified атьсяする:
- 蓑(Red)、
- 紫(Purples)、
- 白(White)、
- 紉色(Purple)、
- 淳 exempt(White)。
- 紙(Black)、
- 雾(Dust)。
具体的な花の例は suivうの directionalに分 classified атьсяan:
- 蓑花(Rimyaki),
- 紫花(Kaparyaki),
- 白花(Asakari),
- 紙花(Shikyuori),
- 離花(Etsunghi)。
DeepSeek-R1:14B
<think>
Okay, so I'm trying to figure out what color a red apple is. Hmm, that seems pretty straightforward, but let me think it through carefully.
First off, the question is in Japanese: "りんごの色は何ですか?" which translates directly to "What color is an apple?" So, I know that apples can come in different colors depending on the variety. The most common ones we see are red, but there are also green and even yellow apples.
But wait, the question specifically says "りんご," which is just the general term for apple. In many contexts, when someone refers to an apple without specifying, they often mean the red ones. So, I think the expected answer here would be red because that's the most typical association people have with apples.
Let me consider other possibilities. There are Granny Smith apples, which are green, and then there are varieties like Fuji or Gala, which can sometimes have a mix of colors but predominantly red. Then there are yellow apples, like the Golden Delicious variety. But since the question doesn't specify a particular type, I should stick with the most common color people associate with apples.
I've also heard that some apples might change color as they ripen. For example, green apples can turn red when they're ready to eat. So, if someone asks about an apple's color without more context, red is usually the safe answer because it's the default in many cultures and languages.
Another angle: thinking about how apples are often depicted in media, marketing, and even school materials—red is the dominant color used for apples. So, even though there are exceptions, red is the primary color people think of when they hear "apple."
Also, considering language nuances, sometimes color names can vary a bit, but in Japanese, "赤" (aka) clearly means red. So, if the answer were green or yellow, it would be different words like "緑" (midori) or "黄" (kiiro). Therefore, using "赤" for red makes sense here.
In conclusion, while apples can vary in color, the most common and expected answer when asked about an apple's color is red.
</think>
りんごの色は赤です。
Qwen2.5:3B
りんごの色は、さまざまな種類がありますが、主に赤や黄色、緑などが一般的です。また、これらの色の中にも様々なトーンがあります。例えば、完全な赤いりんごから、半分は黄くなるようなオレンジいろんごまで、それぞれ独特の色合いを持っています。
Qwen2.5:14B
りんごの色は主に赤、緑、黄などがあります。品種によっても異なるため、一概にいうことはできませんが、一般的にはこれらの色が代表的です。また、成長過程で変化するため、若いときは青みがかって見えることもあります。
今回は、DeepSeek-R1:1.5B以外のモデルからは正常な回答が得られた。
2. 最大消費電力を変化させたときの評価
今回は、1と同じプロンプトを30W, 60Wの最大消費電力で実行したときの評価指標の平均値を比較して、最大消費電力による評価指標の変化を検証する。
最大消費電力は、以下のように画面右上をクリック → Power mode から変更することができる。
結果(最大消費電力:30W, 60W)
Model | Parameters (B) | Max Power (W) | Output Speed (tokens/sec) | VRAM Usage (GB) |
---|---|---|---|---|
DeepSeek-R1 | 1.5 | 30 | 20.22 | 2.00 |
DeepSeek-R1 | 1.5 | 60 | 31.51 | 2.38 |
Qwen2.5 | 3 | 30 | 12.94 | 2.99 |
Qwen2.5 | 3 | 60 | 24.38 | 3.34 |
DeepSeek-R1 | 7 | 30 | 7.87 | 5.74 |
DeepSeek-R1 | 7 | 60 | 15.92 | 6.11 |
Qwen2.5 | 7 | 30 | 7.03 | 5.74 |
Qwen2.5 | 7 | 60 | 13.65 | 6.10 |
DeepSeek-R1 | 14 | 30 | 4.47 | 11.14 |
DeepSeek-R1 | 14 | 60 | 9.40 | 11.50 |
Qwen2.5 | 14 | 30 | 4.61 | 11.14 |
Qwen2.5 | 14 | 60 | 9.50 | 11.50 |
結果から、最大消費電力を大きくすると、出力生成速度とVRAM使用量が増加する傾向にあることがわかった。
3. 入力コンテキスト長を変化させたときの評価
夏目漱石作「こころ」を要約するように指示を出したときに、入力コンテキスト長(トークン数)を変化させた場合の評価指標と回答の変化を検証する。入力コンテキスト長は、【2048, 4096, 8192, 16384, 32768】で変化させた。「こころ」は、17万文字以上の長文小説であるため、すべてのケースにおいて小説の一部から要約を作成している。
結果
Model | Parameters (B) | Input Tokens | Output Speed (tokens/sec) | VRAM Usage (GB) |
---|---|---|---|---|
Qwen2.5 | 14 | 2,048 | 3.48 | 11.23 |
Qwen2.5 | 14 | 4,096 | 2.94 | 13.58 |
Qwen2.5 | 14 | 8,192 | 2.63 | 18.26 |
Qwen2.5 | 14 | 16,384 | 1.91 | 19.24 |
Qwen2.5 | 14 | 32,768 | 1.20 | 19.24 |
DeepSeek-R1 | 14 | 2,048 | 3.69 | 11.23 |
DeepSeek-R1 | 14 | 4,096 | 3.28 | 13.58 |
DeepSeek-R1 | 14 | 8,192 | 2.70 | 18.27 |
DeepSeek-R1 | 14 | 16,384 | 1.98 | 19.28 |
DeepSeek-R1 | 14 | 32,768 | 1.25 | 19.28 |
検証結果
この結果から、以下のことがわかる。
出力生成速度、VRAM利用量は、モデルサイズによっていてモデルの種類によらない(ほとんど)
電力を高くすると速度は速くなる。
低電力を100として、電力を高くした時の速度の比較。デカいモデルの方が、速くなる効果が高い気がする。
電力を高くしてもVRAM使用量にさほど変わりはない
出力生成速度とVRAM使用量は、モデルの種類よりもコンテキスト長による影響が大きい。
- コンテキスト長を大きくすると、出力生成速度は低下し、VRAM使用量は増加する傾向がある。
- コンテキスト長が16,384の場合のVRAM使用量が例外となっているが、原因は不明。
- 出力生成速度とVRAM使用量は、モデルの種類よりもコンテキスト長による影響が大きい。
また、以下に出力例を示す。
出力例
DeepSeek-R1:14B, コンテキスト長:2096
<think>
まず、いただいたテキストは太宰治の「こころ」です。この作品は、晩年の太宰が自殺を決意し、友人に宛てた手紙形式で自分の人生や思想を語るものです。
文中には、著者が自責の念や孤独感を強く感じていることが伺えます。特に、他人と比べて自分を劣等視している点が印象的です。例えば「私は私のできる限りこの不可思議な私というものを、あなたに解らせるように、今までの叙述で己を尽したつもりです」といった部分を通じて、著者の内省的な性格が表現されています。
また、自殺への葛藤も描かれており、「私は死んだ後で、妻から頓死したと思われたいのです。気が狂ったと思われても満足なのです」という文言は、著者の深い孤独と絶望感を物語っています。
全体的に、文体は非常に個人的な叙述で構成され、読者は著者の心の深層まで迫ることができます。ただし、自殺を含む内容ですので、情緒的な影響を受ける方もいるかもしれません。そういう方は、専門家の助言を参考にするべきでしょう。
この作品を通じて、太宰治が抱いていた精神的苦痛や哲学を垣間見ることができます。
</think>
このテキストは、太宰治(1906-1948)の短編小説「こころ」です。小説は、自殺を決意した主人公が友人に宛てた手紙形式で書かれており、彼の人生や思想について語っています。
以下に要約します:
### 主な内容
- **自殺の通告**: 主人は友人に対して、自分は近く自殺するつもりであることを告げます。
- **過去の叙述**: 主人はこれまでの人生を振り返り、自分が他人と比べて劣等感を持ち続けたことや、精神的な孤独さについて語ります。
- **妻への配慮**: 主人は、死ぬ際には静かにし、妻に血を見せず、突然死だと誤認されるようにしたいと考えています。また、妻が自分の秘密を知ることなく、純粋な記憶を保持するよう願っています。
- **文学的遺志**: 主人は、自分の過去を他人の参考とするため、この手紙(小説)を残すことを決めています。この作品は、彼自身の要求と友人への約束の結果生まれたものです。
### 主なテーマ
1. **孤独感と自責**: 主人は自分を劣等視し、他人に比べて自己否定的です。
2. **精神的な苦痛**: 自殺を考えるほどの深い絶望感と孤独感が描かれています。
3. **文学への情熱**: 主人は、自分の過去を偽らずに残すことで、人間の理解に役立つと考えています。
### 特徴
- **手紙形式**: 小説はすべて手紙で書かれており、非常に_personalな文体が特徴です。
- **内省的**: 主人の深い内面世界が詳細に描写されています。
この作品は、太宰治の代表作の一つであり、日本の近代文学史上重要な位置を占めています。
DeepSeek-R1:14B, コンテキスト長:32768
<think>
まず、ユーザーが投稿したテキストを見ると、「「こころ」という本を読んで感想を書け」と依頼されています。この本は夏目漱石による小説で、精神疾患を抱える主人公とその家族の交流を描いた作品です。
私は、感想を書く際にはまず作品内容を理解することが必要と考えています。夏目漱石は「こころ」を通じて、心の病を抱える人々に対する偏見や差別を指摘し、人間としての尊厳を取り戻すまでの葛藤を描いています。
次に、感想の要素を考えます。例えば、登場人物の心理描写やmensagem、現代への意義などについて考察します。また、主人公の行動や周りの人々の反応が現代社会とどのようにリンクするのかについても考えます。
さらに、テキスト中の引用を活用し、具体的な例を挙げて感想を深化させたいと考えています。例えば、手紙での交流や自殺シーンなど、印象的な場面を取り上げると良いでしょう。
全体的にみて、ユーザーが求めているのは「こころ」に対する深い理解と分析に基づいた感想です。そのため、テキストの背景知識や主題を掘り下げることが重要だと感じています。
</think>
夏目漱石の小説「こころ」は、精神疾患を抱える主人公とその家族との交流を描き、人間の心の奥深さと葛藤をテーマにした作品です。以下にその要約と感想を簡単に述べします。
---
### **作品内容の要約**
「こころ」は、精神疾患を抱える主人公・Kと、彼を取り巻く家族や周囲の人々との交流を描いた小説です。Kは自殺をしたのですが、死後も彼の遺影や手紙が周りの人々に影響を与えます。物語を通じて、偏見や差別、疎みなど、精神疾患を持つ人々に対する社会的な問題が浮き彫りになります。
- **K**:精神疾患を抱え、自殺をする人物。
- **奥さん**:Kの妻で、彼を看病し、献身的に支える。
- **お嬢さん(後の妻)**:Kとその後婚する女性。
- **叔父**:Kの家族の一員で、彼に不信感を持つ。
- **私**:Kの友人兼相談役的存在。
物語は、Kの病状や死、そして周りの人々が彼の死後どのように過ごすかを描いています。特に、Kの手紙や遺影が人々の心に残る様子を通じて、彼の存在価値が問われます。
---
### **感想**
「こころ」は、精神疾患を持つ人物を取り扱った小説として、現代でもなお深いメッセージを含んでいます。以下にいくつかのポイントで感想を述べします。
#### **1. 精神疾患への偏見と疎み**
物語を通じて、Kに対する周りの人々の反応が浮き彫りになります。叔父や他人たちが彼に対して抱く不信感や距離感は、精神疾患を持つ人々に対する社会的な偏見を反映しています。現代においても、このような偏見は根強いものがありますが、「こころ」はその問題を鋭く指摘します。
#### **2. 人間の心の複雑さ**
Kの心理描写が非常に深く、彼の苦悩や葛藤が丁寧に描かれています。例えば、彼が自殺を選ぶまでの心理状態や、周囲の人々との交流を通じて浮かぶ感情は、読者に深い共感を呼び起こします。また、奥さんやお嬢さんの心情も細かく描写され、人間の心の襞(ひだ)を垣間見ることができます。
#### **3. 死と遺跡**
Kが自殺した後、彼の遺影や手紙が人々に与える影響は、非常に印象的です。特に、Kの手紙が周囲の人々に届けるメッセ―ジは、彼の存在価値を問わせます。死後のKが生きている人々の心に残る形で、彼自身の尊厳や思いを表現しています。
#### **4. 友情と孤独**
主人公(私)がKとの交流を通じて学ぶことは多いですが、彼もまた孤独な存在です。Kだけでなく、周囲の人々にもそれぞれの問題や葛藤があり、物語は現代社会における人間関係の複雑さを浮き彫りにしています。
---
### **現代への意義**
「こころ」は、精神疾患を持つ人々に対する偏見や差別をなくすためのメッセージを含んでいます。また、人間が抱える孤独感や葛藤を描き、普遍的なテーマを扱っています。現代社会においても、本書は精神疾患への理解や、人間同士の相互尊重について考えさせる一助となり得ます。
---
### **結論**
「こころ」は、夏目漱石が描いた心に響く小説です。精神疾患や孤独、偏見など、現代社会でもなお重要なテーマを鋭く捉えています。物語を通じて、人間の心の深さと脆さを知ることができ、読後も深い印象が残ります。
Qwen2.5:14B, コンテキスト長:2096
この文章は、夏目漱石の小説「こころ」の中で重要な役割を果たす手紙の抜粋です。「こころ」は日本の文学史上にその名を残す重要な作品であり、人間の心の複雑さと葛藤を描いた心理描写が特徴的です。
この抜粋では、「私」という男性が自身の人生経験について長編の自叙伝のような形で書き留めています。彼は自分以外の誰もが知らない秘密を含む長い手紙を書き、それを友人(あるいは小説の登場人物)に遺す計画です。
以下はこの抜粋から読み取れるいくつかの重要なポイントです:
1. 「私」は妻に秘密を残したまま死ぬことを決意しています。彼は妻には何も知らせたくないと言っています。
2. 彼は自叙伝的な手紙で自分の過去を他人のために書き残そうとしています。「私」自身の心の内面や経験を詳細に記述することで、読者(友人)が「私」という人物を理解しようと試みています。
3. 「私」は自分の死後も妻が生きている間はその秘密を明かさないようにと、友人に強く頼んでいます。これは彼の心の葛藤や背徳感を示唆しています。
4. その一方で、「私」は自身の過去を他人にとっての参考に供することを希望しています。しかし妻だけは例外であり、彼女の純粋な記憶を守りたいと願っています。
5. 手紙の中で「私」は自分の人生や行動について自問自答しながら深く反省し、自己剖析を行っている様子が見て取れます。
この抜粋は「こころ」の重要な要素であり、物語全体を通して繰り返される精神的苦悩や人間関係の複雑さを象徴しています。夏目漱石独特の心理描写と内省的な文体を通じて、読者は主人公の心の奥底に迫ることができます。
Qwen2.5:14B, コンテキスト長:32768
この文章は、「こころ」という作品の一節であり、主人公が恋人である女性に宛てた長い手紙の内容を描いています。以下にその要点を要約します:
1. 主人公は亡くなった友人(K)と自身の過去について詳細な説明をしています。
2. Kは自殺し、それは主人公との恋愛関係が原因だと暗示されています。
3. 主人が妻(主人公の恋人)に対して未だに抱えている負の感情や罪悪感について語っています。
4. 本人が自分を理解できないことに悩んでおり、それが自己嫌悪につながっていると述べています。
5. 最終的に主人公は自殺する決心をし、その理由を説明しています。妻には何も知らせずに秘密にしたいと願っています。
6. この手紙の目的は、自分の過去と経験を他人のために記録することです。
7. 主人は最後まで妻に対する優しさを示しており、彼女が自分なしでも幸せになることを願っています。
この文章では、主人公の内面的な葛藤や罪悪感、そして自己犠牲的な性格が描かれています。非常に複雑な人間関係と心理状態が詳細に描写されています。
まとめ
今回は、jetson AGX Orin 開発者キット 32GBを使用して、Ollama経由でダウンロードした「DeepSeek-R1」「Qwen2.5」の2種類のモデル(パラメーター数:14b, 4bit量子化)を実装し、トークン生成速度やVRAM使用量について検証を行った。検証では、jetson AGX Orin 開発者キット 32GBを用いたLLM実装について、以下のことが分かった。
- パラメータ数14B程度のモデルであれば問題なく動作すること。
- パラメータ数やコンテキスト長を増加させると、出力生成速度は低下し、VRAM使用量が増加する傾向があること。
- 最大消費電力を増加させると、出力生成速度とVRAM使用量も増加する傾向があること。
- 出力生成速度とVRAM使用量については、モデルの種類よりもパラメータ数やコンテキスト長による影響が大きいこと。
参考文献
- Jetson AGX Orin 開発者キット端末情報
- Jetson AGX Orin 開発者キットセットアップ
- Python環境構築
- jetson-stats
- 利用モデル
Discussion