CoolFace
Modelpublic

ikedachin/llm-jp-4-8b-thinking_imabari_qa_v4_reasoning_effort_v3

sourceHugging Faceotherupdated 1d agoView on Hugging Face
0likes1.5kdownloads
Model Card

LLM-jp-4-8B-thinking — Imabari & Standard Japanese (v3)

日本語の説明は下にあります。 Japanese description is available below.

Overview

This model is a fully merged model created by taking [llm-jp/llm-jp-4-8b-thinking](https://huggingface.co/llm-jp/llm-jp-4-8b-thinking) as the base model.

It is fine-tuned using QA data containing both Imabari dialect and standard Japanese reasoning text and answers. A custom chat template provides the analysis_imabari and final_imabari channels alongside the standard analysis and final channels.

Improvements from v2

valid_channels now works more reliably. However, when reasoning_effort="high", the output tends to loop on knowledge-based questions.

What This Repository Contains

This repository contains the merged full model, not a LoRA adapter. Therefore, you do not need to load the base model separately at inference time.

  • —Base model: llm-jp/llm-jp-4-8b-thinking
  • —Base model license: Apache-2.0
  • —Model files: Merged weights in Safetensors format
  • —Tokenizer: Saved with the custom chat template used for training
  • —Training data license: CC BY-SA 4.0; see License below

Changes from v2

This version makes two changes from v2:

Itemv2v3
Learning rate1e-42e-4
chat_templateBefore typo correctionTypo corrected

The base model, training datasets (Imabari dialect and standard Japanese), training method, other hyperparameters, merged-model format, and license notices are unchanged from v2. The learning rate for v2 is 1e-4; v3 uses 2e-4.

Use the Tokenizer distributed with v3 to load the corrected chat_template. The exact text of the template correction is not documented here. No v3 evaluation results or measured improvements over v2 are reported in this card.

Training Data

v3 uses the same two datasets as v2, containing Imabari dialect and standard Japanese QA respectively:

Both datasets were created by ikedachin. The Imabari dataset is the one listed in the v1 model card. The standard Japanese dataset is derived from it by converting thinking and answer into standard Japanese while retaining the questions and reasoning-effort labels. The conversion is intended to preserve meaning, conclusions, and supporting information.

QA data is formatted using the custom chat template with the v3 typo correction, supporting the standard analysis / final and Imabari analysis_imabari / final_imabari channels. The final training/validation sizes and mixing ratio for this model are not specified here.

The standard Japanese dataset was re-split independently of its source. When evaluating the combined data, check for shared source QA and articles across training and validation splits.

Training Method

This model was created through the following process:

  1. 1.Use llm-jp/llm-jp-4-8b-thinking as the base model
  2. 2.Format the QA data with the custom Imabari-channel chat template
  3. 3.Perform supervised fine-tuning with LoRA using Transformers / TRL / PEFT
  4. 4.Merge the trained LoRA adapter into the base model
  5. 5.Save the merged model and Tokenizer
  • —Method: LoRA fine-tuning + merged model export

The model was fine-tuned with the following settings:

SettingValue
Epochs1
Learning rate2e-4
Maximum sequence length8,192 tokens
Per-device training batch size2
Gradient accumulation steps8
OptimizerAdamW (adamw_torch)
Learning-rate schedulerCosine
Warmup steps0
Weight decay0.01
LoRA rank / alpha / dropout8 / 16 / 0.0
LoRA target modulesq_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
Gradient checkpointingEnabled
PackingDisabled

Reasoning-effort handling: All training prompts use `Reasoning: medium`, regardless of the original low, medium, or high label in the dataset. The inference template accepts all three values, but this training does not establish learning of the intended three-level conditioning.

Training Environment

  • —Libraries: PyTorch / Transformers / TRL / PEFT / Datasets
  • —Experiment tracking: Weights & Biases
  • —Model loading dtype: torch.float16
  • —Training precision setting: BF16 when supported by the CUDA device; otherwise FP16 on CUDA

Usage

Using high reasoning effort: The suitability of reasoning_effort="high" depends on the question. For some questions, it can produce repetitive output and lead to token-length errors. Choose the reasoning-effort setting according to the question and the observed output.

Load the model

bash
pip install transformers torch accelerate

Use the merged model directory, or replace model_name below with your uploaded Hugging Face repository ID. Always load the Tokenizer distributed with this fine-tuned model, because it contains the modified chat template.

The following example assumes an environment with sufficient memory for FP16 inference, such as the GPU environment used for training.

1. Default LLM-jp-4 behavior

The following describes the official chat template for llm-jp-4-8b-thinking, before the modifications made for this model.

  • —The system prompt lists `analysis`, `commentary`, and `final` as a fixed set of channels. The official template does not read a valid_channels argument.
  • —For ordinary assistant messages, the template uses analysis for reasoning and final for answers. It reads reasoning from thinking and the answer from content; historical reasoning is normally omitted during inference.
  • —reasoning_effort is an existing LLM-jp-4 template option. It supplies the value in Reasoning: ... and defaults to "medium".
  • —add_generation_prompt=True is a Transformers option used by the official template. The official template appends `<|start|>assistant`; it does not use generate_thinking, thinking_channel, or channel to choose a starting channel.

Thus, the default channel names and reasoning-effort option come from LLM-jp-4. The configurable channel list and explicit starting-channel controls described next are modifications made for this fine-tuned model.

2. Features added in this model's chat template

This model's chat template has been modified to add `valid_channels`, making the previously fixed channel list in the system prompt configurable. The modifications also introduce the Imabari-dialect channel names `analysis_imabari` and `final_imabari`, along with controls for selecting the generation-start header.

Added optionBehavior in this model's template
valid_channelsReplaces the fixed channel list with the supplied names. If omitted, it starts from analysis, commentary, and final. The template also inserts user and commentary when missing. This is prompt text, not a decoding constraint.
generate_thinkingWith True, starts in thinking_channel. With False or when omitted, starts in channel. This applies when add_generation_prompt=True.
thinking_channelSelects the initial reasoning channel; defaults to "analysis". Use "analysis_imabari" for Imabari reasoning.
channelSelects the initial answer channel when generate_thinking=False; defaults to "final". Use "final_imabari" for an Imabari answer.

The template retains the existing reasoning_effort option. The names analysis_imabari and final_imabari, and the arguments in the table above, are features of this repository's modified template, not additional standard LLM-jp-4 API options. Load this model's saved Tokenizer to use them.

The channel list and the starting channel are separate settings. valid_channels tells the model which channel names are available. thinking_channel or channel determines the header appended to the prompt. Setting only valid_channels does not change the starting channel.

This model's chat template also simplifies the official template for QA: it retains supplied historical reasoning, uses a fixed date, and does not include the official tool-call rendering. Selecting analysis and final in this modified template does not restore the complete official template behavior.

3. Using the added channel controls

First choose the channel list with valid_channels. Then choose whether to start with reasoning, and explicitly select the starting channel.

Requested style`valid_channels`
Imabari channels["analysis_imabari", "final_imabari", "commentary"]
Standard channels["analysis", "final", "commentary"]
Both sets available["analysis", "final", "analysis_imabari", "final_imabari", "commentary"]

These are suggested lists for this modified template. Keep role="assistant" for assistant messages; a channel does not replace the role.

For example, the Imabari list produces the following system-prompt declaration. user is inserted by the template:

text
# Valid channels: user, analysis_imabari, final_imabari, commentary. Channel must be included for every message.

Next, select the starting header. All rows below assume add_generation_prompt=True and use this model's modified template.

Requested start`generate_thinking``thinking_channel``channel`Prompt suffix
Imabari reasoningTrue"analysis_imabari"Not used`<\start\>assistant<\channel\>analysis_imabari<\message\>`
Standard reasoningTrue"analysis"Not used`<\start\>assistant<\channel\>analysis<\message\>`
Imabari answer directlyFalseNot used"final_imabari"`<\start\>assistant<\channel\>final_imabari<\message\>`
Standard answer directlyFalseNot used"final"`<\start\>assistant<\channel\>final<\message\>`

When `generate_thinking=True`, `channel="final_imabari"` does not force the later answer channel. The initial header uses only thinking_channel; the model generates subsequent channel transitions. To start directly in final_imabari, set generate_thinking=False and channel="final_imabari".

The following inference example uses the added Imabari controls together with the inherited reasoning_effort option. These prompt settings do not guarantee dialect consistency. See Reasoning-effort handling above for what this training run actually conditioned on.

Inference and inspecting outputs

This example prints the formatted prompt, input IDs, generated IDs before decoding, and decoded text with and without special tokens. The same chat_kwargs are used for prompt display and tokenization.

python
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

model_name = "ikedachin/llm-jp-4-8b-thinking_imabari_qa_v4_reasoning_effort_v3"

tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    dtype=torch.float16,
    device_map="auto",
)
model.eval()

messages = [{"role": "user", "content": "今治の特産品について教えてください。"}]
chat_kwargs = {
    # Existing LLM-jp-4 / Transformers options
    "reasoning_effort": "medium",  # "low", "medium", "high"
    "add_generation_prompt": True,
    # Options added in this model's modified template
    "valid_channels": ["analysis_imabari", "final_imabari", "commentary"],
    "generate_thinking": True,
    "thinking_channel": "analysis_imabari",
    "channel": "final_imabari",  # Used when generate_thinking=False
}

# 1. Formatted prompt
prompt = tokenizer.apply_chat_template(messages, tokenize=False, **chat_kwargs)
print("=== Prompt ===")
print(prompt)

# 2. Tokenize
inputs = tokenizer.apply_chat_template(
    messages,
    tokenize=True,
    return_tensors="pt",
    return_dict=True,
    **chat_kwargs,
)
print("=== Input token IDs ===")
print(inputs["input_ids"][0].tolist())
inputs = {key: value.to(model.device) for key, value in inputs.items()}

# 3. Generate
with torch.inference_mode():
    output_ids = model.generate(
        **inputs,
        max_new_tokens=512,
        do_sample=False,
        pad_token_id=tokenizer.eos_token_id,
    )

# output_ids includes the prompt
input_length = inputs["input_ids"].shape[1]
generated_ids = output_ids[0, input_length:]

# 4. Before decode
print("=== Full output token IDs (prompt + generation) ===")
print(output_ids[0].tolist())
print("=== Generated token IDs only ===")
print(generated_ids.tolist())

# 5. After decode
raw_text = tokenizer.decode(generated_ids, skip_special_tokens=False)
text = tokenizer.decode(generated_ids, skip_special_tokens=True)
print("=== Generated text: special tokens kept ===")
print(raw_text)
print("=== Generated text: special tokens removed ===")
print(text)

# 6. Entire conversation
print("=== Full conversation: special tokens kept ===")
print(tokenizer.decode(output_ids[0], skip_special_tokens=False))

To try another row of the channel table, change chat_kwargs and rerun from the prompt creation step. For example, set "generate_thinking": False and "channel": "final_imabari" to start directly in the Imabari answer channel.

Reading the output (standard Transformers behavior)

  • —Before decode: output_ids is a two-dimensional tensor with a batch dimension. output_ids[0] contains the prompt plus generated tokens; generated_ids contains only the new tokens. .tolist() displays their integer IDs.
  • —After decode, `skip_special_tokens=False`: Special-token markers remain visible, making message boundaries and channel transitions easier to inspect.
  • —After decode, `skip_special_tokens=True`: Registered special tokens are removed. This does not extract only the final answer: reasoning text, role names, and channel names may remain.

In this template, <|start|>, <|channel|>, <|message|>, <|end|>, and <|return|> delimit messages, headers, and turn endings. Names such as analysis_imabari are text between these markers. The initial assistant header is already part of the input, so it does not appear at the start of raw_text, which decodes only newly generated tokens. Decode output_ids[0] to see that header too. For multiple sequences, use tokenizer.batch_decode(output_ids, ...).

Standard Japanese generation settings

To start generation in the standard reasoning channel, replace chat_kwargs in the inference example with the following and rerun from prompt creation:

python
chat_kwargs = {
    "reasoning_effort": "medium",
    "add_generation_prompt": True,
    "valid_channels": ["analysis", "final", "commentary"],
    "generate_thinking": True,
    "thinking_channel": "analysis",
    "channel": "final",  # Used when generate_thinking=False
}

To start directly in the standard answer channel, set generate_thinking=False. These settings select prompt channels; they do not guarantee the language style of the generated text. Output samples from earlier versions are not reproduced as v3 results.

Conversation history in the modified template

In this modified template, for previous assistant messages, put thinking_channel and channel inside each message dictionary. These fields format existing history. The top-level arguments to apply_chat_template select the header for the next generation and do not rewrite historical messages.

python
# Illustrative history
history = [
    {"role": "user", "content": "今治の特産品について教えてください。"},
    {
        "role": "assistant",
        "thinking_channel": "analysis_imabari",
        "thinking": "今治の特産品として、タオルについて答えるんよ。",
        "channel": "final_imabari",
        "content": "今治タオルが有名なんよ。",
    },
    {"role": "user", "content": "もう少し詳しく教えてください。"},
]
print(tokenizer.apply_chat_template(history, tokenize=False, **chat_kwargs))

The template formats a nonempty thinking field as a reasoning message and content as an answer message. If the per-message channels are omitted, it uses analysis and final. For history containing an answer only, omit thinking and retain the answer's channel. Setting generate_thinking=False affects the next generation header; it does not remove reasoning already present in history.

References: Transformers chat templates, Tokenizer decoding API.

Notes

Channel-based style control: v1 reported frequent Imabari-dialect output even with standard channels. v3 retains the Imabari and standard Japanese data used in v2, but this card reports no evaluation establishing how reliably v3 separates the two styles.

  • —Generated answers and reasoning text may contain factual errors or inconsistent dialect expressions.
  • —No systematic v3 evaluation of factual accuracy, dialect control, or reasoning-effort control is reported here.
  • —The custom template contains a fixed Current date: 2026-09-19 string. It does not automatically reflect the inference date.
  • —When redistributing, continuing training, merging, using commercially, or publishing derivatives, review the base model's Apache-2.0 terms and the training data's CC BY-SA 4.0 terms, including applicable attribution and source notices.

Japanese Description / 日本語説明

概要

本モデルは、[llm-jp/llm-jp-4-8b-thinking](https://huggingface.co/llm-jp/llm-jp-4-8b-thinking) をベースモデルとしています。

今治弁と標準語の両方の思考文・回答を含むQAデータでファインチューニングしています。独自のチャットテンプレートにより、標準の analysis / final に加えて、今治弁用の analysis_imabari / final_imabari チャネルを指定できます。

v2からの改善点

valid_channelsが機能しやすくなりました。ただし、reasoning_effort="high"では知識問題では出力がループしがちです。

このリポジトリに含まれるもの

このリポジトリには LoRAアダプタではなく、マージ済みモデル本体 が含まれています。 そのため、推論時にベースモデルを別途読み込む必要はありません。

  • —Base model: llm-jp/llm-jp-4-8b-thinking
  • —ベースモデルのライセンス: Apache-2.0
  • —モデルファイル: Safetensors形式のマージ済み重み
  • —Tokenizer: 学習に使用した独自チャットテンプレートを保存
  • —学習データのライセンス: CC BY-SA 4.0。詳細は後述の License を参照してください。

v2からの変更点

v2 からの変更は、以下の2点です。

項目v2v3
学習率(learning rate)1e-42e-4
chat_template誤記修正前誤記を修正

ベースモデル、学習データセット(今治弁と標準語)、学習方法、その他のハイパーパラメータ、マージ済みモデルとしての提供形式、ライセンス表記はv2と同じです。v2の学習率は 1e-4、v3は 2e-4 です。

修正済みの chat_template を使用するため、v3に付属するTokenizerを読み込んでください。誤記の具体的な修正箇所は本カードでは記載していません。v3の評価結果や、v2に対する性能改善の実測結果は掲載していません。

学習データ

v3では、v2と同じ以下の今治弁と標準語の2種類のQAデータセットを使用しています。

文体データセットライセンス
今治弁ikedachin/imabari_wiki_qa_v4_reasoning_effort_llmjp4CC BY-SA 4.0
標準語ikedachin/std_lang_wiki_qa_v4_validated_w_reasoning_effort_llmjp4CC BY-SA 4.0

作成者はいずれも ikedachin です。今治弁データセットはv1のモデルカードに記載されたものです。標準語データセットは、その thinking(思考文)と answer(最終回答)を標準語の「です・ます調」に変換した派生版です。質問と reasoning effort ラベルを引き継ぎ、元の意味・結論・根拠を保持する方針で変換されています。

QAデータの整形には、v3で誤記を修正した独自チャットテンプレートを使用します。このテンプレートは標準の analysis / final と今治弁用の analysis_imabari / final_imabari に対応しています。本モデルで実際に使用した最終的な学習件数・検証件数・混合比率は、本カードでは記載していません。

標準語版は派生元と独立して再分割されています。両データセットを併用した評価では、学習用と検証用の間に同じ元QAや記事が含まれていないか確認が必要です。

学習方法

本モデルは以下の流れで作成しています。

  1. 1.llm-jp/llm-jp-4-8b-thinking をベースモデルとして使用
  2. 2.今治弁チャネルを含む独自チャットテンプレートでQAデータを整形
  3. 3.Transformers / TRL / PEFT を用いて LoRA による教師ありファインチューニングを実施
  4. 4.学習後の LoRA アダプタをベースモデルへマージ
  5. 5.マージ済みモデルとTokenizerを保存
  • —Method: LoRA fine-tuning + merged model export
  • —主な設定: 1 epoch、学習率 2e-4、最大系列長8,192トークン、デバイスあたりのバッチサイズ2、勾配累積8
  • —LoRA設定: rank 8、alpha 16、dropout 0.0。詳細は英語部分の設定表を参照してください。

reasoning effort の扱い: 学習時のプロンプトは、元データの low・medium・high のラベルにかかわらず、すべて `Reasoning: medium` に統一しています。推論時には3段階を指定できますが、この学習によって意図した3段階の条件付けを獲得したことを示すものではありません。

学習環境

  • —Libraries: PyTorch / Transformers / TRL / PEFT / Datasets
  • —実験記録: Weights & Biases
  • —モデル読み込み時のdtype: torch.float16
  • —学習時の精度設定: CUDAデバイスがBF16に対応する場合はBF16、それ以外のCUDA環境ではFP16

使用方法

推論時の設定について: reasoning_effort="high" は問題文を選びます。問題文によっては繰り返し出力が発生しやすく、トークン長エラーにつながる場合があります。問題文と実際の出力に応じて reasoning effort を選択してください。

モデルの読み込み

bash
pip install transformers torch accelerate

マージ済みモデルの保存先、またはアップロード先の Hugging Face リポジトリIDを指定します。独自チャットテンプレートを使うため、ベースモデルのTokenizerではなく、この学習済みモデルに付属するTokenizerを読み込んでください。

以下のコードは、学習時のGPU環境など、FP16でモデルを読み込める十分なメモリがある環境を想定しています。

1. LLM-jp-4の標準の動作

まず、今回の改造前にあたる llm-jp-4-8b-thinking の公式チャットテンプレート の動作を説明します。

  • —システムプロンプトの利用可能なチャネルは、`analysis`・`commentary`・`final` に固定されています。公式テンプレートは valid_channels 引数を参照しません。
  • —通常のassistantメッセージでは、思考文に analysis、回答に final を使います。思考文はメッセージ内の thinking、回答は content から読み込みます。推論時の過去の思考文は、通常は履歴に展開されません。
  • —reasoning_effort は LLM-jp-4にもともとある設定です。システムプロンプトの Reasoning: ... に値を設定し、省略時は "medium" になります。
  • —add_generation_prompt=True は、公式テンプレートでも使われるTransformersの指定です。公式テンプレートが付ける末尾は `<|start|>assistant` までで、generate_thinking・thinking_channel・channel による開始チャネルの指定は行いません。

つまり、標準のチャネル名や reasoning effort の指定はLLM-jp-4由来です。次に説明する「チャネル一覧の変更」と「生成開始チャネルの指定」は、今回のモデル用に加えた改造です。

2. 今回のchat_templateで追加した機能

このモデルのチャットテンプレートを改変し、固定だったシステムプロンプトのチャネル一覧を変更できるよう、`valid_channels` を追加しています。あわせて、今治弁用のチャネル名 `analysis_imabari`・`final_imabari` と、生成開始ヘッダーを選ぶ設定を追加しました。

追加した設定今回のテンプレートでの動作
valid_channelsシステムプロンプトのチャネル一覧を、指定した名前に変更します。省略時は analysis・commentary・final を使います。また、user と commentary がなければ自動で補います。プロンプトへの記載であり、生成トークンを強制的に制限する設定ではありません。
generate_thinkingTrue なら thinking_channel、False または省略時は channel から生成を開始します。add_generation_prompt=True の場合に使われます。
thinking_channel生成開始時の思考チャネルを選びます。省略時は "analysis"。今治弁の思考から始める場合は "analysis_imabari" を指定します。
channelgenerate_thinking=False のとき、生成開始時の回答チャネルを選びます。省略時は "final"。今治弁の回答から始める場合は "final_imabari" を指定します。

既存の reasoning_effort は引き続き利用できます。一方、analysis_imabari・final_imabari という名前と、上表の引数は、このリポジトリの改造テンプレートで使う機能です。LLM-jp-4の標準APIに追加されたものではないため、このモデルに保存されたTokenizerを読み込んで使用してください。

チャネル一覧と、開始チャネルは別の指定です。 valid_channels は「利用可能なチャネル名」をモデルに伝え、thinking_channel または channel は「入力末尾に付ける生成開始ヘッダー」を決めます。valid_channels だけを変更しても、開始チャネルは変わりません。

また、今回のテンプレートはQA向けに簡略化しており、履歴に渡した思考文を保持し、日付を固定しています。公式のツール呼び出し用の整形処理は含めていません。この改造テンプレートで analysis・final を指定しても、公式テンプレート全体の動作に戻るわけではありません。

3. 追加機能を使ったチャネルの指定方法

最初に valid_channels でチャネル一覧を選びます。続いて、思考から始めるかどうかと、実際に開始するチャネルを指定します。

使用したいチャネル`valid_channels`
今治弁用["analysis_imabari", "final_imabari", "commentary"]
標準チャネル用["analysis", "final", "commentary"]
両方を利用可能にする["analysis", "final", "analysis_imabari", "final_imabari", "commentary"]

上表は、この改造テンプレートで使う指定例です。assistantメッセージの role は "assistant" のままにします。チャネル名を role に指定するものではありません。

例えば今治弁用の一覧を渡すと、システムプロンプトには次の宣言が入ります。user はテンプレート側で補われます。

text
# Valid channels: user, analysis_imabari, final_imabari, commentary. Channel must be included for every message.

次に、生成開始ヘッダーを指定します。以下はすべて 今回の改造テンプレートで `add_generation_prompt=True` にした場合の動作です。

開始したい形式`generate_thinking``thinking_channel``channel`プロンプト末尾
今治弁の思考True"analysis_imabari"使用されない`<\start\>assistant<\channel\>analysis_imabari<\message\>`
標準の思考True"analysis"使用されない`<\start\>assistant<\channel\>analysis<\message\>`
今治弁の回答からFalse使用されない"final_imabari"`<\start\>assistant<\channel\>final_imabari<\message\>`
標準の回答からFalse使用されない"final"`<\start\>assistant<\channel\>final<\message\>`

`generate_thinking=True` のとき、`channel="final_imabari"` は思考後の回答チャネルを強制しません。 開始ヘッダーには thinking_channel だけが使われ、その後のチャネル遷移はモデルが生成します。final_imabari から直接始めたい場合は、generate_thinking=False と channel="final_imabari" を指定します。

次の推論例では、追加した今治弁用の設定と、標準から引き継いだ reasoning_effort を組み合わせています。これらのプロンプト指定は、方言表現の一貫性を保証するものではありません。今回の学習で reasoning effort をどのように扱ったかは、前述の 学習方法 を参照してください。

推論と出力の確認

以下では、整形済みプロンプト、入力トークンID、decode前の生成トークンID、特殊トークンを残した出力・除いた出力を順に表示します。表示用と推論用で条件が変わらないよう、同じ chat_kwargs を使います。

python
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

model_name = "ikedachin/llm-jp-4-8b-thinking_imabari_qa_v4_reasoning_effort_v3"

tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    dtype=torch.float16,
    device_map="auto",
)
model.eval()

messages = [{"role": "user", "content": "今治の特産品について教えてください。"}]
chat_kwargs = {
    # LLM-jp-4・Transformersの既存の設定
    "reasoning_effort": "medium",  # "low", "medium", "high"
    "add_generation_prompt": True,
    # 今回の改造テンプレートで追加した設定
    "valid_channels": ["analysis_imabari", "final_imabari", "commentary"],
    "generate_thinking": True,
    "thinking_channel": "analysis_imabari",
    "channel": "final_imabari",  # generate_thinking=False のときに使用
}

# 1. モデルに渡すプロンプト文字列
prompt = tokenizer.apply_chat_template(messages, tokenize=False, **chat_kwargs)
print("=== 入力プロンプト ===")
print(prompt)

# 2. プロンプトをトークンIDに変換
inputs = tokenizer.apply_chat_template(
    messages,
    tokenize=True,
    return_tensors="pt",
    return_dict=True,
    **chat_kwargs,
)
print("=== 入力トークンID ===")
print(inputs["input_ids"][0].tolist())
inputs = {key: value.to(model.device) for key, value in inputs.items()}

# 3. 続きのトークンを生成
with torch.inference_mode():
    output_ids = model.generate(
        **inputs,
        max_new_tokens=512,
        do_sample=False,
        pad_token_id=tokenizer.eos_token_id,
    )

# output_idsには入力プロンプトも含まれる
input_length = inputs["input_ids"].shape[1]
generated_ids = output_ids[0, input_length:]

# 4. decode前:整数のトークンID列
print("=== 入力と生成を含むトークンID ===")
print(output_ids[0].tolist())
print("=== 生成部分のみのトークンID ===")
print(generated_ids.tolist())

# 5. decode後:生成部分のみを文字列に戻す
raw_text = tokenizer.decode(generated_ids, skip_special_tokens=False)
text = tokenizer.decode(generated_ids, skip_special_tokens=True)
print("=== 生成テキスト:特殊トークンあり ===")
print(raw_text)
print("=== 生成テキスト:特殊トークンなし ===")
print(text)

# 6. 入力と生成をまとめて確認
print("=== 会話全体:特殊トークンあり ===")
print(tokenizer.decode(output_ids[0], skip_special_tokens=False))

別の形式を試す場合は、chat_kwargs を変更してプロンプト生成から再実行します。例えば "generate_thinking": False、"channel": "final_imabari" にすると、今治弁の回答チャネルから開始します。

出力の読み方(Transformers共通の動作)

  • —decode前: output_ids はバッチ次元を持つ2次元のテンソルです。output_ids[0] は入力と生成の両方を含み、generated_ids は新しく生成された部分だけです。.tolist() で整数のID列を表示します。
  • —`skip_special_tokens=False` でdecode: メッセージ区切りなどの特殊トークンが残るため、チャネル遷移を確認できます。
  • —`skip_special_tokens=True` でdecode: 登録済みの特殊トークンを取り除きます。最終回答だけを抽出する処理ではありません。 思考本文や assistant、final_imabari などの通常の文字列が残る場合があります。

このテンプレートでは、<|start|> はメッセージ開始、<|channel|> はチャネル指定、<|message|> は本文開始、<|end|> はメッセージ終了、<|return|> はassistantターンの終了を表します。analysis_imabari などの名前は、その間に置かれる文字列です。最初のassistantヘッダーは入力側に含まれるため、生成部分だけをdecodeした raw_text の先頭には出ません。開始チャネルも含めて確認するには output_ids[0] をdecodeします。複数系列をまとめて文字列に戻す場合は tokenizer.batch_decode(output_ids, ...) を使います。

標準語用の生成設定

標準の思考チャネルから生成を開始するには、推論例の chat_kwargs を次のように変更して、プロンプト生成から再実行します。

python
chat_kwargs = {
    "reasoning_effort": "medium",
    "add_generation_prompt": True,
    "valid_channels": ["analysis", "final", "commentary"],
    "generate_thinking": True,
    "thinking_channel": "analysis",
    "channel": "final",  # generate_thinking=False のときに使用
}

標準の回答チャネルから直接開始する場合は、generate_thinking=False に変更します。これらはプロンプトのチャネルを指定する設定であり、生成される文章の文体を保証するものではありません。過去のバージョンの生成例をv3の実測結果として掲載することはしていません。

改造テンプレートでの会話履歴のチャネル指定

今回の改造テンプレートでは、過去のassistantメッセージに対して、thinking_channel と channel を各メッセージの辞書内に指定します。これは履歴の整形に使う値です。apply_chat_template の引数として渡す同名の値は、次に生成するヘッダー用で、過去のメッセージのチャネルを書き換えません。

python
# 会話履歴の形式例(モデルの実測出力ではありません)
history = [
    {"role": "user", "content": "今治の特産品について教えてください。"},
    {
        "role": "assistant",
        "thinking_channel": "analysis_imabari",
        "thinking": "今治の特産品として、タオルについて答えるんよ。",
        "channel": "final_imabari",
        "content": "今治タオルが有名なんよ。",
    },
    {"role": "user", "content": "もう少し詳しく教えてください。"},
]
print(tokenizer.apply_chat_template(history, tokenize=False, **chat_kwargs))

thinking に内容がある場合は思考メッセージ、content は回答メッセージとして整形されます。メッセージ内のチャネルを省略すると analysis / final が使われます。回答だけの履歴では thinking を省略し、回答の channel を残します。generate_thinking=False は次の生成開始ヘッダーに作用するため、履歴に含まれる思考文は削除されません。

参考:Transformers chat templates, Tokenizer decoding API.

Qiita(v1カード記載の参考記事)

https://qiita.com/ikedachin/items/d4b85302db32e4bbb5cf

注意事項

チャネルによる文体の切り替えについて

v1では、標準の analysis・final チャネルを指定しても今治弁になることが多いと報告されていました。v3でもv2と同じ今治弁と標準語のデータを使用していますが、標準語と今治弁をどの程度安定して切り替えられるかについて、このカードでは評価結果を掲載していません。

  • —生成される回答・思考文には、事実誤認や方言表現の不一致が含まれる場合があります。
  • —v3の事実性・方言の制御・reasoning effort の制御に関する体系的な評価結果は未掲載です。
  • —独自テンプレートの日付は Current date: 2026-09-19 に固定されており、推論時の日付に自動更新されません。
  • —再配布、再学習、マージ、商用利用、派生モデルの公開時には、ベースモデルの Apache-2.0 条件と、学習データの CC BY-SA 4.0 条件、および必要な著作権表示・出典表示を確認してください。

License

This repository provides a fine-tuned model based on llm-jp/llm-jp-4-8b-thinking.

Base model

The base model is provided by llm-jp under the Apache License 2.0.

Training data notice

The following training datasets are provided by ikedachin under CC BY-SA 4.0, retaining the same training-data license as v1:

The standard Japanese dataset is derived from the Imabari dataset by standardizing the language of the reasoning text and final answers. Its modifications also include updating messages, recounting tokens, clearing evaluation values, updating record IDs, and recreating distribution splits.

The dataset cards identify the following upstream sources:

For v3, QA data containing Imabari dialect and standard Japanese was formatted using the custom chat template with the v3 typo correction and used for LoRA fine-tuning. The resulting adapter was merged into the base model. Refer to both dataset cards and their source cards for the original materials' attribution and modification history.

Practical interpretation

For transparency, this card uses license: other and describes the base model and training data terms separately.

Users should review:

  • —the Apache-2.0 terms applicable to the base model, and
  • —any attribution / ShareAlike obligations arising from the training data.

Creative Commons' guidance on AI training distinguishes a conservative approach to following ShareAlike from the legal question of whether copyright permission is required. Applicable obligations can depend on the use, distribution, and jurisdiction. The dataset license alone is not presented here as a definitive determination of the license governing the model weights.

Redistribution notice

If you redistribute this model, merge it into another model, publish derivatives, or use it commercially, review the applicable obligations of both the base model and the training data, including attribution, license notices, and source notices.

ベースモデルと学習データの条件を分けて記載しています。再配布や派生モデルの公開時には、両方の条件と、著作権表示・ライセンス表示・出典表示の要否を確認してください。

This section is provided for transparency and is not legal advice. この記載は法的助言ではなく、公開時の透明性を高めるための説明です。