質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

LLM

LLM(大規模言語モデル)は、膨大なデータセットとディープラーニング技術により構築された言語モデル。データ量・計算量・パラメータ量の3つの要素が従来の言語モデルよりも大幅に強化され、より高精度な言語処理が可能です。

Q&A

解決済

1回答

218閲覧

llama.cppにおけるtensorの構造がわからない

salmonyukke

総合スコア3

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

LLM

LLM(大規模言語モデル)は、膨大なデータセットとディープラーニング技術により構築された言語モデル。データ量・計算量・パラメータ量の3つの要素が従来の言語モデルよりも大幅に強化され、より高精度な言語処理が可能です。

0グッド

0クリップ

投稿2024/11/06 13:13

編集2024/11/06 13:16

実現したいこと

llama.cppで使用されているtensorの構造を把握したいです。

前提

https://github.com/ggerganov/llama.cpp/blob/master/ggml/src/ggml.c
gitページを添付しておきます。

以下のソースコードは、
llama.cpp/ggml/src/ggml.c
下のggml_compute_forward関数です。
tensorの状態?で条件分岐しているのはわかるのですが、tensorの構造が分からず、どのようにしてggml_compute_forward_dup関数等が呼ばれているのかがわかりません。

そもそもllama.cppの演算部を理解する上で、見るべきポイント・関数はあっているのか
tensorの状態はどのような検証を行えば可視化できるのか
以上の2点を教えていただきたいです。
よろしくお願いいたします。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

static void ggml_compute_forward(struct ggml_compute_params * params, struct ggml_tensor * tensor) {
GGML_ASSERT(params);
if (tensor->op == GGML_OP_NONE || ggml_is_empty(tensor)) {
return;
}
switch (tensor->op) {
case GGML_OP_DUP:
{
ggml_compute_forward_dup(params, tensor);
} break;
case GGML_OP_ADD:
{
ggml_compute_forward_add(params, tensor);
} break;
case GGML_OP_ADD1:
{
ggml_compute_forward_add1(params, tensor);
} break;
case GGML_OP_ACC:
{
ggml_compute_forward_acc(params, tensor);
} break;
case GGML_OP_SUB:
{
ggml_compute_forward_sub(params, tensor);
} break;
case GGML_OP_MUL:
{
ggml_compute_forward_mul(params, tensor);
} break;
case GGML_OP_DIV:
{
ggml_compute_forward_div(params, tensor);
} break;
......

試したこと

この質問後、printf関数などで、実際にggml_compute_forward_mul_mat関数等が呼ばれているのかを確認するつもりです。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

まずstruct ggml_tensorの定義(584~619行)です

struct ggml_tensor { enum ggml_type type; GGML_DEPRECATED(enum ggml_backend_type backend, "use the buffer type to find the storage location of the tensor"); struct ggml_backend_buffer * buffer; int64_t ne[GGML_MAX_DIMS]; // number of elements size_t nb[GGML_MAX_DIMS]; // stride in bytes: // nb[0] = ggml_type_size(type) // nb[1] = nb[0] * (ne[0] / ggml_blck_size(type)) + padding // nb[i] = nb[i-1] * ne[i-1] // compute data enum ggml_op op; // op params - allocated as int32_t for alignment int32_t op_params[GGML_MAX_OP_PARAMS / sizeof(int32_t)]; int32_t flags; struct ggml_tensor * grad; struct ggml_tensor * src[GGML_MAX_SRC]; // source tensor and offset for views struct ggml_tensor * view_src; size_t view_offs; void * data; char name[GGML_MAX_NAME]; void * extra; // extra things e.g. for ggml-cuda.cu // char padding[4]; };

enum ggml_op opが持つggml_opの定義(439~532行)は以下です

enum ggml_op { GGML_OP_NONE = 0, GGML_OP_DUP, GGML_OP_ADD, GGML_OP_ADD1, GGML_OP_ACC, GGML_OP_SUB, GGML_OP_MUL, GGML_OP_DIV, GGML_OP_SQR, GGML_OP_SQRT, GGML_OP_LOG, GGML_OP_SIN, GGML_OP_COS, GGML_OP_SUM, GGML_OP_SUM_ROWS, GGML_OP_MEAN, GGML_OP_ARGMAX, GGML_OP_COUNT_EQUAL, GGML_OP_REPEAT, GGML_OP_REPEAT_BACK, GGML_OP_CONCAT, GGML_OP_SILU_BACK, GGML_OP_NORM, // normalize GGML_OP_RMS_NORM, GGML_OP_RMS_NORM_BACK, GGML_OP_GROUP_NORM, GGML_OP_MUL_MAT, GGML_OP_MUL_MAT_ID, GGML_OP_OUT_PROD, GGML_OP_SCALE, GGML_OP_SET, GGML_OP_CPY, GGML_OP_CONT, GGML_OP_RESHAPE, GGML_OP_VIEW, GGML_OP_PERMUTE, GGML_OP_TRANSPOSE, GGML_OP_GET_ROWS, GGML_OP_GET_ROWS_BACK, GGML_OP_DIAG, GGML_OP_DIAG_MASK_INF, GGML_OP_DIAG_MASK_ZERO, GGML_OP_SOFT_MAX, GGML_OP_SOFT_MAX_BACK, GGML_OP_ROPE, GGML_OP_ROPE_BACK, GGML_OP_CLAMP, GGML_OP_CONV_TRANSPOSE_1D, GGML_OP_IM2COL, GGML_OP_IM2COL_BACK, GGML_OP_CONV_TRANSPOSE_2D, GGML_OP_POOL_1D, GGML_OP_POOL_2D, GGML_OP_POOL_2D_BACK, GGML_OP_UPSCALE, // nearest interpolate GGML_OP_PAD, GGML_OP_ARANGE, GGML_OP_TIMESTEP_EMBEDDING, GGML_OP_ARGSORT, GGML_OP_LEAKY_RELU, GGML_OP_FLASH_ATTN_EXT, GGML_OP_FLASH_ATTN_BACK, GGML_OP_SSM_CONV, GGML_OP_SSM_SCAN, GGML_OP_WIN_PART, GGML_OP_WIN_UNPART, GGML_OP_GET_REL_POS, GGML_OP_ADD_REL_POS, GGML_OP_RWKV_WKV, GGML_OP_UNARY, GGML_OP_MAP_UNARY, GGML_OP_MAP_BINARY, GGML_OP_MAP_CUSTOM1_F32, GGML_OP_MAP_CUSTOM2_F32, GGML_OP_MAP_CUSTOM3_F32, GGML_OP_MAP_CUSTOM1, GGML_OP_MAP_CUSTOM2, GGML_OP_MAP_CUSTOM3, GGML_OP_CROSS_ENTROPY_LOSS, GGML_OP_CROSS_ENTROPY_LOSS_BACK, GGML_OP_OPT_STEP_ADAMW, GGML_OP_COUNT, };

当然enumなのでtensor->opからは定数が取得されます
これをswitch(tensor->op)で分岐させる機構となります

あとはggml_compute_forward(struct ggml_compute_params * params, struct ggml_tensor * tensor)が呼ばれる箇所を追っていけば読解が前進するでしょう

ソースコードは揃っているようなので、ローカル環境にクローンすれば、検証についてはggml.hをインクルードしたcppファイル自体をインクルードするか、ビルドでマージすれば対応可能かと思います

投稿2024/11/06 15:15

nanashi123

総合スコア89

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

salmonyukke

2024/11/06 15:54

回答ありがとうございます。 もう一点質問なのですが、このtensorを生成している部分がどこの箇所か教えていただけると嬉しいです。 また、ビルドでマージとは何でしょうか、素人のためわからず、そちらも簡単に教えていただけると嬉しいです。 よろしくお願いします。
nanashi123

2024/11/06 23:47

tensorは仮引数です ポインタなので、元のインスタンスは関数の外部で生成されます ただ、こちらの環境ではggml_compute_forwardの実装がggml.cには見当たらないため、この関数の定義箇所や呼び出し位置を追うことは現状困難です 演算部に用いられているのなら、その前後を調べることで、実引数の生成部が見つかるでしょう どのファイルの何行目に記述されているかを挙げて頂ければもう少し追えるかもしれません マージというのは、ソースコードを統合することです プロトタイプ宣言された関数の実装を通じて内部のstaticな関数群を利用しているはずなので、主にヘッダーファイルを調べてみることをお勧めします
salmonyukke

2024/11/07 14:48

ご回答ありがとうございます。 ソースコードの件ですが、手元にあるファイルだとggml.cの17245行目にありますが、gitにはないようですね、、、 git cloneでcloneしただけなので、もしお時間が許すのであれば見ていただけると嬉しいです。 マージの件、多少なりとも理解できたので、調べつつ検証してみようと思います。 何度も丁寧にご回答ありがとうございました。
nanashi123

2024/11/07 23:27

8379行が限界みたいですね 解決済みにはなっていますが、一度こちらもクローンして調べてみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問