<p>style_prompt_applied: true</p>
<h1 class="wp-block-heading"> </h1>
<p>本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">QLoRAとLoRAによるLLM効率化:GPUメモリと計算資源を劇的に削減する技術詳細</h1>
<h2 class="wp-block-heading">【要点サマリ】</h2>
<p>LLMのファインチューニングにおける莫大なVRAMと計算コストの課題を解決します。
解決した課題: 全パラメータ更新の非効率性と、それに伴う大規模な計算資源の要求。
改善指標1: ベースモデルの重みを4-bit量子化し、学習に必要なVRAMを大幅に削減(例: 65Bモデルを1枚のGPUでチューニング可能に)。
改善指標2: 訓練対象パラメータ数をベースモデルの0.01%〜数%に抑え、学習時間を短縮。</p>
<h2 class="wp-block-heading">【背景と最新動向】</h2>
<p>近年、GPT-3やLLaMAのような大規模言語モデル(LLM)の性能向上は目覚ましいですが、特定のタスクに特化させるためのファインチューニング(FT)は、依然として高いGPUリソースを要求します。</p>
<p>従来のフルファインチューニング(Full Fine-Tuning)では、数億から数百億に及ぶ全てのパラメータを更新する必要があり、例えば65Bモデルの学習には数百GBのVRAMが必要でした。</p>
<p>この課題に対し、Parameter-Efficient Fine-Tuning (PEFT)と呼ばれる手法群が登場しました。代表的な先行研究として、AdapterやPrefix Tuningがありますが、特に高い性能と実装の容易さから主流となったのが<strong>LoRA (Low-Rank Adaptation)</strong>です(Hu et al., 2021 [1])。</p>
<h3 class="wp-block-heading">LoRAからQLoRAへの進化</h3>
<p>LoRAは訓練対象のパラメータ数を削減する手法でしたが、ベースモデル自体の重み(例えば16-bitやBF16)をメモリに保持する必要がありました。</p>
<p>2023年5月に発表された<strong>QLoRA (Quantized LoRA)</strong>(Dettmers et al., 2023 [2])は、このメモリ効率を劇的に改善しました。</p>
<p>QLoRAは、以下の技術革新を組み合わせています。</p>
<ol class="wp-block-list">
<li><p><strong>4-bit NormalFloat (NF4) Quantization</strong>:情報損失を最小限に抑えつつ、ニューラルネットワークの重みを効率的に4-bitに量子化する新しいデータ型。</p></li>
<li><p><strong>Double Quantization (DQ)</strong>:量子化定数(スケールとオフセット)自体も量子化することで、さらなるメモリ削減(平均で約0.5ビット/パラメータ)を実現。</p></li>
<li><p><strong>Paged Optimizers</strong>:GPUメモリ不足による訓練の中断を防ぐため、CPU/GPU間でメモリを自動的にページングする技術(CUDAの統一メモリに着想を得る)。</p></li>
</ol>
<p>これにより、QLoRAは<strong>精度を維持しつつ、65Bモデルを単一の48GB GPUでファインチューニング可能</strong>にし、PEFTの利用可能性を大きく広げました [2]。この技術は、Hugging FaceのPEFTライブラリや<code>bitsandbytes</code>ライブラリに統合され、直近のトレンド(2023年後半以降)として広く採用されています。</p>
<h2 class="wp-block-heading">【アーキテクチャ・仕組み】</h2>
<p>LoRAおよびQLoRAの核となる概念は、大規模な重み行列の更新を低ランク行列分解で近似することです。</p>
<h3 class="wp-block-heading">LoRAの仕組み</h3>
<p>元の事前学習済み重み行列 $W_0 \in \mathbb{R}^{d \times k}$ に対し、学習中に加える更新 $\Delta W$ を低ランク行列の積 $B A$ で近似します。</p>
<p>$$
W \leftarrow W_0 + \Delta W = W_0 + B A
$$</p>
<p>ここで、$B \in \mathbb{R}^{d \times r}$、$A \in \mathbb{R}^{r \times k}$ であり、$r$ はランクと呼ばれる小さな整数です($r \ll \min(d, k)$)。訓練時には$W_0$は固定し、低ランク行列の$A$と$B$のみを更新します。</p>
<p>総訓練パラメータ数: $d \cdot r + r \cdot k$</p>
<p>例えば、$d=4096, k=4096$ の行列に対し、$r=64$ を採用した場合、元のパラメータ数(約1670万)に対し、訓練パラメータはわずか約52万となり、パラメータ数を約3%に削減できます。</p>
<h3 class="wp-block-heading">LoRAの適用レイヤー</h3>
<p>LoRAは通常、Transformerモデルの主要な計算資源であるアテンション機構内の重み行列に適用されます(Query, Key, Value, Output投影)。</p>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
Input["入力埋め込み"] --> Attention_Block
Attention_Block --> Output["出力"]
subgraph Attention_Block
Q["Query Projection W_Q"]
K["Key Projection W_K"]
V["Value Projection W_V"]
O["Output Projection W_O"]
end
Q --> |LoRA Adapter("B_Q A_Q")| Q_LoRA
K --> |LoRA Adapter("B_K A_K")| K_LoRA
V --> |LoRA Adapter("B_V A_V")| V_LoRA
Q_LoRA & K_LoRA & V_LoRA --> Calculation["Self-Attention Calculation"]
style Q_LoRA fill:#ccffcc,stroke:#66ff66
style K_LoRA fill:#ccffcc,stroke:#66ff66
style V_LoRA fill:#ccffcc,stroke:#66ff66
</pre></div>
<h3 class="wp-block-heading">QLoRAの統合</h3>
<p>QLoRAでは、$W_0$自体が4-bit NormalFloat (NF4)形式でメモリに格納されます。ファインチューニング時には、この量子化された$W_0$をデ量子化(de-quantize)して計算に使用しますが、勾配計算(バックプロパゲーション)は低ランクアダプター $B A$ のみに対して行われます。これにより、ベースモデルの重みにかかるメモリ負荷を極限まで抑えます。</p>
<p>$$
W_{FP16} = \text{dequantize}(W_{NF4}) + B A
$$
(注釈: $W_{FP16}$ は計算時に使用される高精度な重み。$\text{dequantize}(W_{NF4})$ は固定されており、勾配は $B$ と $A$ にのみ流れる。)</p>
<h2 class="wp-block-heading">【実装イメージ】</h2>
<p>Hugging FaceのPEFTライブラリと<code>bitsandbytes</code>ライブラリを使用することで、LoRA/QLoRAの設定は非常に簡潔に行えます。</p>
<p>ここでは、4-bit量子化を有効にしたQLoRAの設定例(Llama-7Bなどを想定)を示します。</p>
<div class="codehilite">
<pre data-enlighter-language="generic">import torch
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
# 1. 量子化設定 (QLoRAの核)
bnb_config = BitsAndBytesConfig(
load_in_4bit=True, # 4-bit量子化を有効化
bnb_4bit_use_double_quant=True, # Double Quantizationを有効化
bnb_4bit_quant_type="nf4", # 4-bit NormalFloatを使用
bnb_4bit_compute_dtype=torch.bfloat16 # 計算精度
)
# 2. ベースモデルのロード
model_id = "meta-llama/Llama-2-7b-hf"
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=bnb_config,
device_map="auto"
)
# 3. LoRA設定
# Llamaの場合、通常 'q_proj', 'k_proj', 'v_proj', 'o_proj' に適用
# r: ランク(低ければ低いほどパラメータは少ない)
# lora_alpha: スケーリングファクター
lora_config = LoraConfig(
r=64,
lora_alpha=16,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
# 4. QLoRA向けの前処理とPEFTモデルの取得
# 4-bitモデルは勾配チェックポイント対応のために前処理が必要
model = prepare_model_for_kbit_training(model)
model = get_peft_model(model, lora_config)
# 訓練可能なパラメータ数を確認 (例: ベースモデルの約0.1%)
model.print_trainable_parameters()
# trainable params: 41,943,040 || all params: 6,781,770,240 || trainable%: 0.6184
</pre>
</div>
<h2 class="wp-block-heading">【実験結果と考察】</h2>
<p>QLoRAの最も重要な貢献は、大規模モデルのファインチューニングを実用的なハードウェア(コンシューマー向けGPUを含む)で可能にした点です。</p>
<h3 class="wp-block-heading">メモリ消費量の比較 (Llama 65Bモデル)</h3>
<figure class="wp-block-table"><table>
<thead>
<tr>
<th style="text-align:left;">ファインチューニング手法</th>
<th style="text-align:left;">量子化ビット数</th>
<th style="text-align:left;">VRAM消費量(65Bモデル)</th>
<th style="text-align:left;">必要なGPU枚数(48GB VRAM前提)</th>
<th style="text-align:left;">根拠 [2]</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;">Full Fine-Tuning</td>
<td style="text-align:left;">BF16 (16-bit)</td>
<td style="text-align:left;">約130 GB</td>
<td style="text-align:left;">3枚以上</td>
<td style="text-align:left;">理論値</td>
</tr>
<tr>
<td style="text-align:left;">LoRA</td>
<td style="text-align:left;">BF16 (16-bit)</td>
<td style="text-align:left;">約130 GB</td>
<td style="text-align:left;">3枚以上</td>
<td style="text-align:left;">ベースモデルのロードが必要</td>
</tr>
<tr>
<td style="text-align:left;">QLoRA</td>
<td style="text-align:left;">NF4 (4-bit)</td>
<td style="text-align:left;">約44 GB</td>
<td style="text-align:left;">1枚</td>
<td style="text-align:left;">Dettmers et al. (2023)</td>
</tr>
</tbody>
</table></figure>
<p><strong>考察:</strong>
LoRAは学習パラメータ数を削減しますが、ベースモデルの重みを高精度(BF16/FP16)で保持するため、メモリ消費量の削減効果は限定的でした。
一方、QLoRAはベースモデルの重みを4-bit NF4で保持し、メモリ消費を約3分の1以下に抑えることに成功しました。これにより、研究室レベルや企業内の単一ハイエンドGPUでも最先端のLLMチューニングが可能になりました。</p>
<h3 class="wp-block-heading">精度への影響</h3>
<p>QLoRAは、4-bit量子化を用いながらも、BF16でフルファインチューニングしたモデルと比較して、ベンチマーク(SuperGLUEなど)において同等かそれ以上の精度を達成することが示されています [2]。これは、NF4量子化とDouble Quantizationが非常に効率的であり、低ランクアダプター(LoRA)がモデルの知識を維持しつつ、新しいタスクに適応させる能力を効果的に担っているためと考えられます。</p>
<h2 class="wp-block-heading">【限界と今後の展望】</h2>
<h3 class="wp-block-heading">現在の制約事項(限界)</h3>
<ol class="wp-block-list">
<li><p><strong>量子化による微細な精度ロス</strong>: ほとんどのタスクでは無視できるレベルですが、極めて精度が要求される特定のタスクや、非常に小さなデータセットでのチューニングにおいては、わずかな精度劣化が発生する可能性があります。</p></li>
<li><p><strong>ハードウェアとライブラリへの依存</strong>: QLoRAの性能は、主に<code>bitsandbytes</code>ライブラリと特定のGPUアーキテクチャ(CUDA)に強く依存しており、最適化されていない環境や異なるハードウェアでは十分な性能が出ない場合があります。特にPaged OptimizersはCUDAの機能に深く関わっています。</p></li>
<li><p><strong>計算負荷の増加(デ量子化)</strong>: 訓練ループのフォワードパスでは、4-bit重みを計算に使用するために16-bitにデ量子化する工程($W_{FP16}$の生成)が必要となり、これがわずかな計算オーバーヘッドを引き起こします。</p></li>
</ol>
<h3 class="wp-block-heading">今後の展望</h3>
<ol class="wp-block-list">
<li><p><strong>高効率なアライメントチューニング</strong>: QLoRAは、SFT(Supervised Fine-Tuning)だけでなく、DPO(Direct Preference Optimization)やPPO(Proximal Policy Optimization)のような人間とのアライメントを目的とした学習手法にも広く適用され始めています。これにより、メモリ効率の良いアライメントプロセスが標準化されるでしょう。</p></li>
<li><p><strong>その他のPEFT手法との統合</strong>: LoRA以外にも、AdapterやPrompt Tuningなど、他のPEFT手法とのハイブリッド利用や、さらなる低コスト化を目指す研究が進む可能性があります。</p></li>
<li><p><strong>ストリーミング量子化</strong>: 学習時に必要に応じて重みをロードする「ストリーミング量子化」など、更なるメモリ管理技術の統合により、将来的にさらに大きなモデルを扱うことが可能になるかもしれません。</p></li>
</ol>
<h2 class="wp-block-heading">参考文献</h2>
<ol class="wp-block-list">
<li><p>Hu, E. J., et al. (2021). <em>LoRA: Low-Rank Adaptation of Large Language Models</em>. arXiv:2106.09685.</p></li>
<li><p>Dettmers, T., et al. (2023). <em>QLoRA: Efficient Finetuning of Quantized LLMs</em>. arXiv:2305.14314.</p></li>
<li><p>Hugging Face PEFT Library Documentation. [URL省略] (LoRA/QLoRA実装の標準化)</p></li>
<li><p>Tim Dettmers’s GitHub Repository (bitsandbytes). [URL省略]</p></li>
</ol>
style_prompt_applied: true
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
QLoRAとLoRAによるLLM効率化:GPUメモリと計算資源を劇的に削減する技術詳細
【要点サマリ】
LLMのファインチューニングにおける莫大なVRAMと計算コストの課題を解決します。
解決した課題: 全パラメータ更新の非効率性と、それに伴う大規模な計算資源の要求。
改善指標1: ベースモデルの重みを4-bit量子化し、学習に必要なVRAMを大幅に削減(例: 65Bモデルを1枚のGPUでチューニング可能に)。
改善指標2: 訓練対象パラメータ数をベースモデルの0.01%〜数%に抑え、学習時間を短縮。
【背景と最新動向】
近年、GPT-3やLLaMAのような大規模言語モデル(LLM)の性能向上は目覚ましいですが、特定のタスクに特化させるためのファインチューニング(FT)は、依然として高いGPUリソースを要求します。
従来のフルファインチューニング(Full Fine-Tuning)では、数億から数百億に及ぶ全てのパラメータを更新する必要があり、例えば65Bモデルの学習には数百GBのVRAMが必要でした。
この課題に対し、Parameter-Efficient Fine-Tuning (PEFT)と呼ばれる手法群が登場しました。代表的な先行研究として、AdapterやPrefix Tuningがありますが、特に高い性能と実装の容易さから主流となったのがLoRA (Low-Rank Adaptation)です(Hu et al., 2021 [1])。
LoRAからQLoRAへの進化
LoRAは訓練対象のパラメータ数を削減する手法でしたが、ベースモデル自体の重み(例えば16-bitやBF16)をメモリに保持する必要がありました。
2023年5月に発表されたQLoRA (Quantized LoRA)(Dettmers et al., 2023 [2])は、このメモリ効率を劇的に改善しました。
QLoRAは、以下の技術革新を組み合わせています。
4-bit NormalFloat (NF4) Quantization:情報損失を最小限に抑えつつ、ニューラルネットワークの重みを効率的に4-bitに量子化する新しいデータ型。
Double Quantization (DQ):量子化定数(スケールとオフセット)自体も量子化することで、さらなるメモリ削減(平均で約0.5ビット/パラメータ)を実現。
Paged Optimizers:GPUメモリ不足による訓練の中断を防ぐため、CPU/GPU間でメモリを自動的にページングする技術(CUDAの統一メモリに着想を得る)。
これにより、QLoRAは精度を維持しつつ、65Bモデルを単一の48GB GPUでファインチューニング可能にし、PEFTの利用可能性を大きく広げました [2]。この技術は、Hugging FaceのPEFTライブラリやbitsandbytesライブラリに統合され、直近のトレンド(2023年後半以降)として広く採用されています。
【アーキテクチャ・仕組み】
LoRAおよびQLoRAの核となる概念は、大規模な重み行列の更新を低ランク行列分解で近似することです。
LoRAの仕組み
元の事前学習済み重み行列 $W_0 \in \mathbb{R}^{d \times k}$ に対し、学習中に加える更新 $\Delta W$ を低ランク行列の積 $B A$ で近似します。
$$
W \leftarrow W_0 + \Delta W = W_0 + B A
$$
ここで、$B \in \mathbb{R}^{d \times r}$、$A \in \mathbb{R}^{r \times k}$ であり、$r$ はランクと呼ばれる小さな整数です($r \ll \min(d, k)$)。訓練時には$W_0$は固定し、低ランク行列の$A$と$B$のみを更新します。
総訓練パラメータ数: $d \cdot r + r \cdot k$
例えば、$d=4096, k=4096$ の行列に対し、$r=64$ を採用した場合、元のパラメータ数(約1670万)に対し、訓練パラメータはわずか約52万となり、パラメータ数を約3%に削減できます。
LoRAの適用レイヤー
LoRAは通常、Transformerモデルの主要な計算資源であるアテンション機構内の重み行列に適用されます(Query, Key, Value, Output投影)。
graph TD
Input["入力埋め込み"] --> Attention_Block
Attention_Block --> Output["出力"]
subgraph Attention_Block
Q["Query Projection W_Q"]
K["Key Projection W_K"]
V["Value Projection W_V"]
O["Output Projection W_O"]
end
Q --> |LoRA Adapter("B_Q A_Q")| Q_LoRA
K --> |LoRA Adapter("B_K A_K")| K_LoRA
V --> |LoRA Adapter("B_V A_V")| V_LoRA
Q_LoRA & K_LoRA & V_LoRA --> Calculation["Self-Attention Calculation"]
style Q_LoRA fill:#ccffcc,stroke:#66ff66
style K_LoRA fill:#ccffcc,stroke:#66ff66
style V_LoRA fill:#ccffcc,stroke:#66ff66
QLoRAの統合
QLoRAでは、$W_0$自体が4-bit NormalFloat (NF4)形式でメモリに格納されます。ファインチューニング時には、この量子化された$W_0$をデ量子化(de-quantize)して計算に使用しますが、勾配計算(バックプロパゲーション)は低ランクアダプター $B A$ のみに対して行われます。これにより、ベースモデルの重みにかかるメモリ負荷を極限まで抑えます。
$$
W_{FP16} = \text{dequantize}(W_{NF4}) + B A
$$
(注釈: $W_{FP16}$ は計算時に使用される高精度な重み。$\text{dequantize}(W_{NF4})$ は固定されており、勾配は $B$ と $A$ にのみ流れる。)
【実装イメージ】
Hugging FaceのPEFTライブラリとbitsandbytesライブラリを使用することで、LoRA/QLoRAの設定は非常に簡潔に行えます。
ここでは、4-bit量子化を有効にしたQLoRAの設定例(Llama-7Bなどを想定)を示します。
import torch
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
# 1. 量子化設定 (QLoRAの核)
bnb_config = BitsAndBytesConfig(
load_in_4bit=True, # 4-bit量子化を有効化
bnb_4bit_use_double_quant=True, # Double Quantizationを有効化
bnb_4bit_quant_type="nf4", # 4-bit NormalFloatを使用
bnb_4bit_compute_dtype=torch.bfloat16 # 計算精度
)
# 2. ベースモデルのロード
model_id = "meta-llama/Llama-2-7b-hf"
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=bnb_config,
device_map="auto"
)
# 3. LoRA設定
# Llamaの場合、通常 'q_proj', 'k_proj', 'v_proj', 'o_proj' に適用
# r: ランク(低ければ低いほどパラメータは少ない)
# lora_alpha: スケーリングファクター
lora_config = LoraConfig(
r=64,
lora_alpha=16,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
# 4. QLoRA向けの前処理とPEFTモデルの取得
# 4-bitモデルは勾配チェックポイント対応のために前処理が必要
model = prepare_model_for_kbit_training(model)
model = get_peft_model(model, lora_config)
# 訓練可能なパラメータ数を確認 (例: ベースモデルの約0.1%)
model.print_trainable_parameters()
# trainable params: 41,943,040 || all params: 6,781,770,240 || trainable%: 0.6184
【実験結果と考察】
QLoRAの最も重要な貢献は、大規模モデルのファインチューニングを実用的なハードウェア(コンシューマー向けGPUを含む)で可能にした点です。
メモリ消費量の比較 (Llama 65Bモデル)
| ファインチューニング手法 |
量子化ビット数 |
VRAM消費量(65Bモデル) |
必要なGPU枚数(48GB VRAM前提) |
根拠 [2] |
| Full Fine-Tuning |
BF16 (16-bit) |
約130 GB |
3枚以上 |
理論値 |
| LoRA |
BF16 (16-bit) |
約130 GB |
3枚以上 |
ベースモデルのロードが必要 |
| QLoRA |
NF4 (4-bit) |
約44 GB |
1枚 |
Dettmers et al. (2023) |
考察:
LoRAは学習パラメータ数を削減しますが、ベースモデルの重みを高精度(BF16/FP16)で保持するため、メモリ消費量の削減効果は限定的でした。
一方、QLoRAはベースモデルの重みを4-bit NF4で保持し、メモリ消費を約3分の1以下に抑えることに成功しました。これにより、研究室レベルや企業内の単一ハイエンドGPUでも最先端のLLMチューニングが可能になりました。
精度への影響
QLoRAは、4-bit量子化を用いながらも、BF16でフルファインチューニングしたモデルと比較して、ベンチマーク(SuperGLUEなど)において同等かそれ以上の精度を達成することが示されています [2]。これは、NF4量子化とDouble Quantizationが非常に効率的であり、低ランクアダプター(LoRA)がモデルの知識を維持しつつ、新しいタスクに適応させる能力を効果的に担っているためと考えられます。
【限界と今後の展望】
現在の制約事項(限界)
量子化による微細な精度ロス: ほとんどのタスクでは無視できるレベルですが、極めて精度が要求される特定のタスクや、非常に小さなデータセットでのチューニングにおいては、わずかな精度劣化が発生する可能性があります。
ハードウェアとライブラリへの依存: QLoRAの性能は、主にbitsandbytesライブラリと特定のGPUアーキテクチャ(CUDA)に強く依存しており、最適化されていない環境や異なるハードウェアでは十分な性能が出ない場合があります。特にPaged OptimizersはCUDAの機能に深く関わっています。
計算負荷の増加(デ量子化): 訓練ループのフォワードパスでは、4-bit重みを計算に使用するために16-bitにデ量子化する工程($W_{FP16}$の生成)が必要となり、これがわずかな計算オーバーヘッドを引き起こします。
今後の展望
高効率なアライメントチューニング: QLoRAは、SFT(Supervised Fine-Tuning)だけでなく、DPO(Direct Preference Optimization)やPPO(Proximal Policy Optimization)のような人間とのアライメントを目的とした学習手法にも広く適用され始めています。これにより、メモリ効率の良いアライメントプロセスが標準化されるでしょう。
その他のPEFT手法との統合: LoRA以外にも、AdapterやPrompt Tuningなど、他のPEFT手法とのハイブリッド利用や、さらなる低コスト化を目指す研究が進む可能性があります。
ストリーミング量子化: 学習時に必要に応じて重みをロードする「ストリーミング量子化」など、更なるメモリ管理技術の統合により、将来的にさらに大きなモデルを扱うことが可能になるかもしれません。
参考文献
Hu, E. J., et al. (2021). LoRA: Low-Rank Adaptation of Large Language Models. arXiv:2106.09685.
Dettmers, T., et al. (2023). QLoRA: Efficient Finetuning of Quantized LLMs. arXiv:2305.14314.
Hugging Face PEFT Library Documentation. [URL省略] (LoRA/QLoRA実装の標準化)
Tim Dettmers’s GitHub Repository (bitsandbytes). [URL省略]
コメント