コンテンツにスキップ

RKLLM モデル変換 API 紹介

修正履歴

NOバージョン修正内容修正日
1Ver1.0新規作成2026/06/21

この文書の情報は、文書を改善するため、事前の通知なく変更されることがあります。最新版は弊社ホームページからご参照ください。

株式会社日昇テクノロジーの書面による許可のない複製は、いかなる形態においても厳重に禁じられています。

1. RKLLMの初期化

  このセクションでは、ワークフロー全体の最初のステップとして、RKLLMオブジェクトを初期化する必要があります。サンプルコードでは、RKLLM()コンストラクタを使用してRKLLMオブジェクトを初期化しています。

2. モデルの読み込み

  RKLLMの初期化後、rkllm.load_huggingface()関数を呼び出し、モデルへの特定のパスを渡す必要があります。RKLLM-Toolkitは、指定されたパスに基づいて、Hugging Face形式またはGGUF形式の大規模言語モデルを正常に読み込み、後続の変換および量子化処理をスムーズに完了させることができます。具体的な関数定義は以下のとおりです。

  

表 1 load_huggingface 関数インターフェース仕様

関数名load_huggingface
説明オープンソースの Hugging Face 形式の大規模言語モデルをロードします。
パラメータmodel: LLM モデルのファイルパス。後続の変換・量子化処理のためにモデルをロードします。
model_lora: LoRA 重みのファイルパス。変換時、model は対応する base model のパスを指している必要があります。
device: モデル変換時に使用するデバイスを指定します。cuda と cpu の 2 種類をサポートします。
dtype: 重みのデータ型を指定します。指定可能な値は float32、float16、bfloat16 です。float16 と bfloat16 は VRAM 使用量を削減できますが、量子化精度が低下する可能性があります。
custom_config: カスタムモデルの設定ファイルです。詳細は「カスタムモデル変換」章を参照してください。
load_weight: 重みをロードするかどうかを指定します。False に設定した場合、実際の重みはロードされません。
戻り値0 はモデルロード成功、-1 はモデルロード失敗を表します。

サンプルコードは次のとおりです。

ret = rkllm.load_huggingface(
model = './huggingface_model_dir',
model_lora = './huggingface_lora_model_dir'
)
if ret != 0:
print('Load model failed!')

表 2 load_gguf 関数インターフェース仕様

関数名load_gguf
説明オープンソースの GGUF 形式の大規模言語モデルをロードします。対応する数値型は q4_0 と fp16 の 2 種類です。GGUF 形式の LoRA モデルも、このインターフェースを使用して RKLLM モデルへ変換できます。
パラメータmodel: GGUF モデルのファイルパス。
戻り値0 はモデルロード成功、-1 はモデルロード失敗を表します。

サンプルコードは次のとおりです。

ret = rkllm.load_gguf(model = './model-Q4_0.gguf')
if ret != 0:
print('Load model failed!')

3. モデルビルド

rkllm.load_huggingface() 関数で元モデルをロードした後、次のステップとして rkllm.build() 関数を使用し、RKLLM モデルをビルドします。ビルド時には量子化を行うかどうかを選択できます。量子化はモデルサイズの削減、および Rockchip NPU 上での推論性能向上に有効です。rkllm.build() 関数の定義は次のとおりです。

表 3 build 関数インターフェース仕様

関数名build
説明RKLLM モデルをビルドし、変換処理の中で具体的な量子化設定を定義します。
パラメータdo_quantization: モデルに量子化処理を適用するかどうかを制御します。True に設定することを推奨します。
optimization_level: 量子化精度最適化を行うかどうかを指定します。設定値は {0, 1} から選択します。0 は最適化なし、1 は精度最適化を表します。精度最適化により、モデルの推論性能が低下する可能性があります。
quantized_dtype: 量子化の具体的な型を指定します。現在サポートされる量子化型は “w4a16”, “w4a16_g32”, “w4a16_g64”, “w4a16_g128”, “w8a8”, “w8a8_g128”, “w8a8_g256”, “w8a8_g512” です。“w4a16” は重みを 4bit 量子化し、アクティベーションは量子化しないことを表します。“w4a16_g64” は重みを group size=64 の 4bit グループ量子化とし、アクティベーションは量子化しないことを表します。“w8a8” は重みとアクティベーションをいずれも 8bit 量子化することを表します。“w8a8_g128” は重みとアクティベーションをいずれも group size=128 の 8bit グループ量子化にすることを表します。現在、RK3576 と RV1126B プラットフォームでは “w4a16”, “w4a16_g32”, “w4a16_g64”, “w4a16_g128”, “w8a8” の 5 種類をサポートします。RK3588 では “w8a8”, “w8a8_g128”, “w8a8_g256”, “w8a8_g512” の 4 種類をサポートします。RK3562 では “w8a8”, “w4a16_g32”, “w4a16_g64”, “w4a16_g128”, “w4a8_g32” をサポートします。GGUF モデルの q4_0 に対応する量子化型は “w4a16_g32” です。なお、group size は線形層の出力次元で割り切れる必要があり、割り切れない場合はサポートされません。
quantized_algorithm: 量子化精度最適化アルゴリズムを指定します。選択可能な設定は “normal”, “grq”, “gdq” です。すべての量子化型で normal を選択できます。一方、gdq と grq は w4a16 および w4a16 グループ量子化のみをサポートします。gdq と grq は計算負荷が高いため、GPU による高速化が必須です。grq は gdq と比較して処理速度が速く、VRAM 使用量も少ないため、4bit 量子化では grq を優先的に試すことを推奨します。LoRA モジュールを利用して量子化精度をさらに向上させることもできます。他の LoRA モデルを読み込まない場合、“normal_r[164]”, “grq_r[164]”, “gdq_r[1~64]” などのアルゴリズムを使用できます。例として “normal_r8”, “grq_r8”, “gdq_r8” があります。最終的に量子化モデルと LoRA モデルがエクスポートされ、runtime は 2 つのモデルをロードして推論を実行します。
num_npu_core: モデル推論で使用する NPU コア数を指定します。“RK3576” の選択肢は [1,2]、“RK3588” の選択肢は [1,2,3]、“RK3562” の選択肢は [1]、“RV1126B” の選択肢は [1] です。
extra_qparams: gdq/grq アルゴリズムを使用すると、.qparams 拡張子の量子化重みキャッシュファイルが生成されます。このパラメータに *.qparams のパスを指定することで、モデルの再エクスポートが可能になります。
dataset: 量子化キャリブレーション用データセットを指定します。形式は JSON です。内容例では input が質問であり、プロンプトを付加する必要があります。target は回答です。複数データは {} の辞書形式でリストに保存します。例:[{“input”:“今日の天気はどうですか?”,“target”:“今日は晴れです。”},…]
hybrid_rate: グループ量子化と非グループ量子化のハイブリッド比率を指定します(範囲は [0,1))。量子化型が w4a16/w8a8 の場合、この比率に基づいて w4a16 グループ量子化 / w8a8 グループ量子化を混在させ、精度を向上させます。量子化型が w4a16 グループ / w8a8 グループの場合、この比率に基づいて w4a16/w8a8 を混在させ、推論性能を向上させます。hybrid_rate が 0 の場合、ハイブリッド量子化は行われません。
target_platform: モデルを実行するハードウェアプラットフォームを指定します。選択可能な設定は “RK3576”, “RK3588”, “RK3562”, “RV1126B” です。
max_context: コンテキスト長の上限値を指定します。最大 16384 までサポートされ、32 の倍数にアライメントされている必要があります。
戻り値0 はモデル変換・量子化成功、-1 はモデル変換失敗を表します。

サンプルコードは次のとおりです。

ret = rkllm.build(
do_quantization=True,
optimization_level=1,
quantized_dtype='w8a8',
quantized_algorithm="normal",
num_npu_core=3,
extra_qparams=None,
dataset="quant_data.json",
hybrid_rate=0,
target_platform='rk3588'
)
if ret != 0:
print('Build model failed!')

4. モデルエクスポート

rkllm.build() 関数で RKLLM モデルをビルドした後、rkllm.export_rkllm() 関数を使用して RKLLM モデルを .rkllm ファイルとして保存できます。保存されたモデルは、後続のデプロイおよび推論呼び出しに使用します。rkllm.export_rkllm() 関数のパラメータ定義は次のとおりです。

表 4 export_rkllm 関数インターフェース仕様

関数名export_rkllm
説明変換・量子化済みの RKLLM モデルを保存し、後続の推論呼び出しで使用できるようにします。
パラメータexport_path: エクスポートする RKLLM モデルファイルの保存パスを指定します。LoRA モデルは _lora サフィックス付きの RKLLM モデルとして自動保存されます。
戻り値0 はモデルのエクスポート・保存成功、-1 はモデルエクスポート失敗を表します。

サンプルコードは次のとおりです。

ret = rkllm.export_rkllm(export_path = './model.rkllm')
if ret != 0:
print('Export model failed!')

5. GPTQ モデル変換

上記ツールで提供される量子化アルゴリズムを使用してモデル変換を行うだけでなく、AutoGPTQ などのオープンソース量子化ツールを用いて、あらかじめ浮動小数点モデルを 4bit/8bit の重みに量子化し(Hugging Face 形式で保存する必要があります)、その後 RKLLM モデルへ変換することもできます。AutoGPTQ で浮動小数点モデルを量子化する際は、以下のパラメータ設定を確認してください。

bits=4
sym=true
group_size=32/64/128
desc_act=false
bits=8
sym=true
group_size=128/256/512
desc_act=false

Hugging Face 形式の GPTQ モデルを RKLLM へ変換するサンプルコードは次のとおりです。

modelpath = '/path/to/Model-Instruct-GPTQ-Int4'
llm = RKLLM()
ret = llm.load_huggingface(model=modelpath, model_lora = None,
device='cuda')
if ret != 0:
print('Load model failed!')
exit(ret)
## Build model
dataset = None
qparams = None
target_platform = "RK3576"
optimization_level = 1
quantized_dtype = "w4a16_g32" #w4a16_g64 or w4a16_g128
quantized_algorithm = "normal"
num_npu_core = 2
ret = llm.build(
do_quantization=True,
optimization_level=optimization_level,
quantized_dtype=quantized_dtype,
quantized_algorithm=quantized_algorithm,
target_platform=target_platform,
num_npu_core=num_npu_core,
extra_qparams=qparams,
dataset=dataset
)
if ret != 0:
print('Build model failed!')
exit(ret)
## Export rkllm model
ret = llm.export_rkllm(
f"./{os.path.basename(modelpath)}_{quantized_dtype}_{target_platform}.rkllm"
)
if ret != 0:
print('Export model failed!')
exit(ret)

6. カスタムモデル変換

モデル構造または名称を変更した場合でも、変更後の全体アーキテクチャが以下の構成に従っていれば、カスタムモデル変換機能を使用してモデルを変換できます。

TOKEN_EMBD

embd_scale(optional)

┌─ x
│ ↓
│ ATTN_NORM
│ ↓
│ attn
│ ↓
│ ATTN_POST_NORM(optional)
│ ↓
│ hidden_state_scale(optional)
│ ↓
│ cross attn(optional)
│ ↓
┌─└► +

│ ↓
│ FFN_NORM
│ ↓
│ MLP
│ ↓
│ FFN_POST_NORM(optional)
│ ↓
│ hidden_state_scale(optional)
│ ↓
└───► +
…↓
OUTPUT_NORM

lm_head_scale(optional)

OUTPUT

Qwen モデルを例として、Qwen モデルファイル modeling_qwen.py 内の対応する変数名を、次のようにカスタム設定ファイルへ記述します。

{
"BLOCKNAME": "QWenBlock",
"TOKEN_EMBD": "wte",
"ATTN_NORM": "ln_1",
"ATTN_Q_NORM": "",
"ATTN_K_NORM": "",
"CROSS_ATTN_NORM": "",
"CROSS_ATTN_Q": "",
"ATTN_Q": "",
"ATTN_K": "",
"ATTN_V": "",
"ATTN_QKV": "attn.c_attn",
"ATTN_KV": "",
"KV_CONTINUOUS": "true",
"ATTN_OUT": "attn.c_proj",
"CROSS_ATTN_OUT": "",
"ATTN_POST_NORM": "",
"FFN_NORM": "ln_2",
"FFN_UP": "mlp.w1",
"FFN_GATE": "mlp.w2",
"ACT_TYPE": "silu",
"FFN_DOWN": "mlp.c_proj",
"FFN_POST_NORM": "",
"OUTPUT_NORM": "ln_f",
"OUTPUT": "lm_head"
}

ACT_TYPE の選択肢は [“silu”, “gelu”, “relu”, “fatrelu”, “squarerelu”, “swiglu”] の 6 種類です。ATTN_NORM と FFN_NORM は RMSNorm のみをサポートします。

ATTN_QKV または ATTN_KV を使用する場合、重みを連続した K|V として分割できるかどうかを確認する必要があります。連続している場合は KV_CONTINUOUS を true に設定します。たとえば Qwen モデルの c_attn 重みは連続配置であり、Q, K, V のサイズに従って順番に分割できます。一方、InternLM2 モデルの wqkv 重みは連続配置ではなく、Q, K, V が head_dim 単位で交互に配置されています。

Qwen 1.8B モデルの modeling_qwen.py ファイル定義は次のとおりです。

class QWenLMHeadModel(QWenPreTrainedModel):
def __init__(self, config):
super().__init__(config)
self.transformer = QWenModel(config)
self.lm_head = nn.Linear(config.hidden_size,
config.vocab_size, bias=False)
class QWenModel(QWenPreTrainedModel):
_keys_to_ignore_on_load_missing = ["attn.masked_bias"]
def __init__(self, config):
super().__init__(config)
self.wte = nn.Embedding(self.vocab_size, self.embed_dim)
self.ln_f = RMSNorm(self.embed_dim,
eps=config.layer_norm_epsilon)
class QWenBlock(nn.Module):
def __init__(self, config):
super().__init__()
hidden_size = config.hidden_size
self.bf16 = config.bf16
self.ln_1 = RMSNorm(hidden_size,
eps=config.layer_norm_epsilon)
self.attn = QWenAttention(config)
self.ln_2 = RMSNorm(hidden_size,
eps=config.layer_norm_epsilon)
self.mlp = QWenMLP(config)
class QWenAttention(nn.Module):
def __init__(self, config):
super().__init__()
self.c_attn = nn.Linear(config.hidden_size, 3 *
self.projection_size)
self.c_proj = nn.Linear(config.hidden_size,
self.projection_size,
bias=not config.no_bias)
class QWenMLP(nn.Module):
def __init__(self, config):
super().__init__()
self.w1 = nn.Linear(config.hidden_size,
config.intermediate_size // 2,
bias=not config.no_bias)
self.w2 = nn.Linear(config.hidden_size,
config.intermediate_size // 2,
bias=not config.no_bias)
ff_dim_in = config.intermediate_size // 2
self.c_proj = nn.Linear(ff_dim_in, config.hidden_size,
bias=not config.no_bias)

cross attention をサポートするモデルを含むカスタムモデル変換については、参考用の Hugging Face モデル構造を提供しています。カスタム設定ファイルは次のとおりです。

{
"BLOCKNAME": "CustomDecoderLayer",
"TOKEN_EMBD": "embed_tokens",
"ATTN_NORM": "input_layernorm",
"ATTN_Q_NORM": "",
"ATTN_K_NORM": "",
"CROSS_ATTN_NORM": "cross_layernorm",
"CROSS_ATTN_Q": "cross_attn.cross_q_proj",
"ATTN_Q": "",
"ATTN_K": "",
"ATTN_V": "",
"ATTN_QKV": "self_attn.qkv_proj",
"ATTN_KV": "",
"KV_CONTINUOUS": "true",
"ATTN_OUT": "self_attn.o_proj",
"CROSS_ATTN_OUT": "cross_attn.cross_o_proj",
"ATTN_POST_NORM": "",
"FFN_NORM": "post_attention_layernorm",
"FFN_UP": "mlp.up_proj",
"FFN_GATE": "mlp.gate_proj",
"ACT_TYPE": "silu",
"FFN_DOWN": "mlp.down_proj",
"FFN_POST_NORM": "",
"OUTPUT_NORM": "norm",
"OUTPUT": "lm_head"
}

7. 旧バージョンモデル更新

バージョン 1.0.2 と 1.1 以降のバージョンには大きな差分があるため、1.0.2 版モデルを最新バージョンへ更新するための rkllm.update_rkllm() 関数が提供されています。モデル更新時は、前述のモデルロードおよびビルド手順を実行する必要はなく、このインターフェースを直接呼び出して更新できます。更新後も、モデルの量子化型などのパラメータは変更されません。rkllm.update_rkllm() 関数のパラメータ定義は次のとおりです。

表 5 update_rkllm 関数インターフェース仕様

関数名update_rkllm
説明バージョン 1.0.2 のモデルを最新バージョンへ更新します。
パラメータmodel: バージョン 1.0.2 の RKLLM モデルパス。
戻り値0 はモデル更新成功、-1 はモデル更新失敗を表します。

サンプルコードは次のとおりです。

ret = llm.update_rkllm(model = "./model_1.0.2version.rkllm")
if ret != 0:
print('Load model failed!')
exit(ret)

8. シミュレーション精度評価

rkllm.build() 関数で RKLLM モデルをビルドした後、rkllm.get_logits() 関数を使用して PC 上でシミュレーション精度評価を行うことができます。rkllm.get_logits() 関数のパラメータ定義は次のとおりです。

表 6 get_logits 関数インターフェース仕様

関数名get_logits
説明PC 上でシミュレーション精度評価を行うために使用します。
パラメータinputs: シミュレーション入力形式は Hugging Face モデル推論と同じです。例:
{“input_ids”:"", “top_k”:1, …}
戻り値モデル推論で得られた logits 値を返します。

この関数を使用して wikitext データセットの PPL を評価するサンプルコードは次のとおりです。

def eval_wikitext(llm):
seqlen = 512
tokenizer = AutoTokenizer.from_pretrained(
modelpath,
trust_remote_code=True
)
#Dataset download link:
#https://huggingface.co/datasets/Salesforce/wikitext/tree/main/wikitext-2-raw-v1
testenc = load_dataset(
"parquet",
data_files='./wikitext/wikitext-2-raw-1/test-00000-of-00001.parquet',
split='train'
)
testenc = tokenizer("\n\n".join(testenc['text']),
return_tensors="pt").input_ids
nsamples = testenc.numel() // seqlen
nlls = []
for i in tqdm(range(nsamples), desc="eval_wikitext: "):
batch = testenc[:, (i * seqlen): ((i + 1) * seqlen)]
inputs = {"input_ids": batch}
lm_logits = llm.get_logits(inputs)
if lm_logits is None:
print("get logits failed!")
return
shift_logits = lm_logits[:, :-1, :]
shift_labels = batch[:, 1:].to(lm_logits.device)
loss_fct = nn.CrossEntropyLoss().to(lm_logits.device)
loss = loss_fct(shift_logits.view(-1,
shift_logits.size(-1)),
shift_labels.view(-1))
neg_log_likelihood = loss.float() * seqlen
nlls.append(neg_log_likelihood)
ppl = torch.exp(torch.stack(nlls).sum() / (nsamples *
seqlen))
print(f'wikitext-2-raw-1-test ppl: {round(ppl.item(),
2)}')

9. シミュレーションモデル推論

rkllm.build() 関数で RKLLM モデルをビルドした後、rkllm.chat_model() 関数を使用して PC 上でシミュレーション推論を行うことができます。rkllm.chat_model() 関数のパラメータ定義は次のとおりです。

表 7 chat_model 関数インターフェース仕様

関数名chat_model
説明PC 上でシミュレーションモデル推論を行うために使用します。
パラメータmessages: テキスト入力です。対応するプロンプトを付加する必要があります。
args: 推論設定パラメータです。例として top_k などのサンプリング戦略パラメータを指定します。
戻り値モデルの推論結果を返します。

サンプルコードは次のとおりです。

args = {
"max_length":128,
"top_k":1,
"temperature":0.8,
"do_sample":True,
"repetition_penalty":1.1
}
mesg = "Human: 今日の天気はどうですか?\nAssistant:"
print(llm.chat_model(mesg, args))

以上の操作は、RKLLM-Toolkit によるモデル変換および量子化の全体手順を網羅しています。要件や適用シナリオに応じて、異なる設定オプションおよび量子化方式を選択し、後続のデプロイに向けて柔軟にカスタマイズできます。