0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Qwen3-235Bの事後学習を1ノードで試す:4bit QLoRA+GRPOの実行構成と報酬設計

0
Last updated at Posted at 2026-11-01

はじめに

医療LLMのプロジェクトで、Qwen3-235B級モデルに対する強化学習による事後学習に取り組みました。

結論から言うと、H100 80GB×8の1ノードで、4bit QLoRAとms-swiftを使い、GRPOの100ステップの生成・重み更新からチェックポイント保存まで実行しました。一方、評価ではベースモデルを上回る明確な精度改善は確認できませんでした。

本記事では、235B級モデルの生成と重み更新を1ノードで実行した構成と所要時間、複数正解のある問題に部分点を与えるF1報酬の設計、そして同様の実験を行う際の確認項目を紹介します。

第5章の評価結果には、評価担当から共有されたスコアを掲載しています。報酬計算時に別の問題の正解を参照していた可能性があり、当時の対応関係を照合できなかったため、今回の結果からF1報酬とGRPOの有効性は判定できませんでした。詳しくは同章で説明します。

1. 背景と目的:少ないノード数で235B級のRLを試す

計算資源は他のチームと共有しており、事前学習なども並行して進んでいました。自分が実験するタイミングでは、複数ノードをまとめて確保するよりも、空いている1ノードを1〜2日使う方が調整しやすい状況でした。そこで、量子化とLoRAで必要なメモリを抑え、ms-swiftを使ってH100×8の1ノードで実行する構成を検討しました。

当時、参照できる235B級モデルへのRL適用事例は限られていました。小規模モデルで試した手法がこの規模でも動くのか、事後学習による改善につながるのかを確認したいという動機がありました。

取り組みの目的は、次の二つでした。

  • 確保しやすい1ノードで、235B級モデルのRLによる事後学習を実行する。
  • 医療の多肢選択問題に合わせたルールベース報酬で、精度改善が得られるかを確認する。

2. 4bit QLoRAで、更新対象を絞る

Qwen3-235B-A22Bは、総パラメータ数約235B、1トークンの処理に使うパラメータ数約22BのMoEモデルです。トークンごとに使うExpertは変わりますが、モデル全体としては全Expertの重みが必要です。今回は、それらを含むモデルを8GPUに分割して保持しました。出発点には、プロジェクト内で用意されたチェックポイントQwen3-235B-A22B-Instruct-exp10-Base-Instructionを使用しました。

メモリを抑えるため、ベースモデルを4bitで保持し、Attention層に追加したLoRAアダプタのみを更新しました。Expertの重みは固定しました。QLoRAは、ベースモデルを低ビットで保持して重みを固定したまま、追加した小さなLoRAアダプタを学習する方法で、ベースモデルの保持と更新対象の両方でメモリを抑えられます。

今回使用した構成は、次のとおりです。

要素 今回の設定・役割
ベースモデル Qwen3-235B-A22B-Instruct-exp10-Base-Instruction
フレームワーク ms-swift
ベースモデルの量子化 4bit、NF4、double quantization
計算精度 bf16
LoRAの対象 Attentionのq_proj、k_proj、v_proj、o_proj
LoRA rank / alpha 8 / 16
LoRA dropout 0.05
学習方法 GRPO
GPU H100 80GB×8、1ノード

重みの保持には主に4bit、演算にはbf16を使用しました。量子化の除外リストにはmlp.gate、mlp.shared_expert_gate、lm_headを指定しました(mlp.shared_expert_gateはTransformers 4.56.2のQwen3-MoE実装には存在しないため、実際に該当するのはmlp.gateとlm_headです)。

LoRAの学習対象は、94層のq/k/v/o投影とrank 8から計算すると**25,411,584パラメータ(約25.4M、総235Bの約0.011%)**でした。更新対象を絞ることで、勾配やOptimizer状態に必要なメモリを抑えました。

ms-swiftは、この量子化とRLの組み合わせを扱えたため採用しました。回答生成と学習は同じ1ノード内で実行し、主なRL設定はloss_type: grpo、importance_sampling_level: token、num_generations: 2、beta: 0.0、use_vllm: falseでした。betaは参照方策(学習前のモデル)とのKLダイバージェンスにかける係数で、beta=0ではこのペナルティを用いず、参照モデルの順伝播も不要になります。

8GPUをどう使ったか

Slurmで1ノード・8GPU・1タスクを確保し、Pythonスクリプトを直接起動しました。環境構築やパス設定を省いた起動部分の抜粋は次のとおりです。

#!/bin/bash
#SBATCH --nodes=1
#SBATCH --gpus-per-node=8
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=64

export CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
python grpo_qwen3_235b_training.py

学習コードではswift.llmのRLHFArgumentsとrlhf_mainを使用しました(主要引数は付録に掲載)。この起動方法で、ms-swift 3.8.1は1プロセスから8GPUを使い、device_map="auto"でモデルを分割配置しました。GPUごとにモデル全体を複製するデータ並列とは異なり、一つのモデルを複数GPUに分けて保持する構成でした。

まとめると、ベースモデルを4bitで保持すること、モデルを8GPUに分割すること、更新対象をAttentionのLoRAに絞ることの組み合わせで、1ノードに収めました。

使用したライブラリ

W&Bに記録されたrequirementsから、学習に関わる主要ライブラリを抜粋します。

ライブラリ 記録されたバージョン
ms-swift 3.8.1
PyTorch 2.3.0+cu121
Transformers 4.56.2
TRL 0.20.0
PEFT 0.17.1
Accelerate 1.10.1
bitsandbytes 0.47.0
datasets 3.6.0
W&B 0.23.1

3. 多肢選択問題の報酬にF1を使う

報酬関数は、モデルの回答を採点し、学習に使う点数を返す仕組みです。GRPOは、同じ問題に対して複数の回答を生成し、回答群の中での相対的な評価から、更新に使う指標を計算します。どの回答を高く採点するかが学習の方向を決めるため、報酬の設計が重要になります。今回は、1問に対して2件の回答を生成しました。

データの形式と、採点したい対象

確認したデータ例は、日本語の医療問題とa〜eの5つの選択肢からなり、正解を選択肢の記号で持つ形式でした。単一選択に加えて、「2つ選べ」「3つ選べ」のように正解数を指定して複数の選択肢を選ぶ問題も含まれていました。

要素 データ例の形式 報酬設計との関係
入力 問題文と5つの選択肢 モデルが選択肢を選んで回答する
正解 一つ、または複数の選択肢記号 正解と予測を集合として比較できる
採点対象 最終的に選んだ選択肢 解説の文章評価を追加せずにルールで採点できる

単一選択で正解も回答も一つなら、F1は正解で1、不正解で0になります。複数の選択肢を扱うときに、部分一致を点数にできることが今回の用途に合っていました。以下では、説明用の選択肢記号だけを使って採点を示します。

同じ0点でも、回答の内容には差がある

例えば、a〜eから正しいものを「2つ選べ」という問題で、正解が**「aとc」**で、モデルが次の2件の回答を生成したとします。

  • 回答A:aを選択。正解の一つを当てたが、cを取りこぼした。
  • 回答B:b、dを選択。正解の選択肢を一つも選べなかった。

完全一致で採点すると、どちらも0点です。同じ形式で出力されていれば形式点も同じなので、この2件の間に報酬差がつきません。

GRPOは同じ問題に対する複数回答の報酬を比較して学習します。そこで、「一部は正解している回答」を「すべて外した回答」より高く評価するため、F1による部分点を導入しました。

なぜF1なのか:取りこぼしと選びすぎの両方を評価する

正解した選択肢の数だけを数えると、すべての選択肢を選ぶ回答も高得点になってしまいます。そこで、次の二つを組み合わせるF1を使いました。

  • 適合率(Precision):選んだ選択肢のうち、正解だった割合。余分な選択を減点できる。
  • 再現率(Recall):正解の選択肢のうち、選べた割合。正解の取りこぼしを減点できる。

F1は適合率と再現率の調和平均で、次の式で計算します。

F1 = \frac{2 \times \mathrm{Precision} \times \mathrm{Recall}}{\mathrm{Precision} + \mathrm{Recall}}

例えば、正解が「a、c」で回答が「a」なら、選んだ1個は正解なので適合率は1、正解2個のうち1個を選べたので再現率は0.5です。F1は2 × 1 × 0.5 ÷ (1 + 0.5) ≒ 0.667となります。正解との重なりがない回答は0点です。

正解が{a, c}の場合、内容に対する点数は次のようになります。

モデルの回答 回答の状態 完全一致 F1による部分点
a, c 正解を過不足なく選択 1 1.000
a 正解を一つ取りこぼした 0 0.667
a, c, d 正解に加えて余分な選択肢を選んだ 0 0.800
a, b, d 正解が一つ、誤選択が二つ 0 0.400
b, d 正解との重なりがない 0 0.000

先ほどの回答AとBは、F1ならそれぞれ0.667点と0点になります。完全正解に届いていない段階でも、正解との重なりに応じた優劣を学習に渡せることが、F1を選んだ理由です。

ここでのF1は学習用の部分点であり、試験としての正答判定とは区別します。例えば「2つ選べ」に対する「a」や「a, c, d」にも部分点を与えますが、これらを正解と判定するわけではありません。F1だけで、指定された選択数や解説文の医学的な妥当性を保証することもできません。

F1を報酬に使う先行例として、読解QAのReinforced Mnemonic Reader(IJCAI 2018)があります。同研究では回答テキストの重なりを採点していました。今回は、選択肢の集合の重なりを採点する設計にしました。

生成と回答抽出の設定

システム指示では、医学的な考察を行った後に、最後に[ans]と[/ans]で囲んで選択肢の記号のみを出力するよう指定しました(単一選択は[ans]a[/ans]、複数選択は[ans]a,c,e[/ans]の形式)。この回答形式は評価時と揃えました。生成時はtemperature=0.7、top_p=0.9、最大生成長3500としました。

回答抽出では、a〜eとカンマ・空白に合致する最初の[ans]...[/ans]を優先し、該当するタグがなければ「答え:」などの表記、続いて末尾200文字の選択肢記号を調べました。形式点は内容の抽出成否とは別に、開始・終了タグの有無で判定しました。

回答形式にも0.05点を加えた

報酬は、選択肢のF1に、タグ形式を満たした場合の0.05点を加える設計にしました。

報酬 = 選択肢のF1 + 形式点(指定タグがあれば0.05、なければ0)

報酬の最大値は1.05で、タグがあれば内容が不正解でも形式点は得られます。形式点は回答抽出をしやすくするために設けましたが、係数が0.05でも標準化後の学習信号への影響が小さいとは限りません。この点を次に説明します。

2回答のGRPOでは、点差より順位が使われる

今回の設定はnum_generations=2、scale_rewards=Trueでした。ms-swift 3.8.1は、同じ問題の回答群で平均を引き、標準偏差に1e-4を加えた値で割って、更新に使う指標(advantage)を求めます。

2回答の点差をd(0以上)とすると、各回答の平均からの偏差は±d/2です。分散の分母をn−1とする標準偏差を用いるため、2件の標準偏差はd/√2となり、advantageは ±(d/2) / (d/√2 + 1e-4) で計算されます。dが1e-4より十分大きい場合、高得点側はほぼ+0.707、低得点側はほぼ−0.707となり、同点なら両方とも0です。例えば、次の報酬差は標準化後にはほぼ同じ大きさになります。

2回答の報酬 元の点差 高得点側のadvantage
0.00と0.05 0.05 約0.705
0.400と0.667 約0.267 約0.707
0.00と1.00 1.00 約0.707

したがって今回のF1に期待した役割は、完全一致では同点になる回答に順位をつけることでした。部分点の差を大きくした分だけ、学習に使う重みが大きくなるわけではありません。また、advantageは更新に使う重みであり、実際のパラメータ更新量そのものではありません。

形式点も同様です。F1が同じ2回答に形式点だけで差がつけば、標準化後には内容の正誤で差がついた場合と近いadvantageになります。形式点の係数が0.05でも、学習上の影響まで小さくなるとは限らない点が、この設定の注意点です。

ルールベースで採点した理由

今回は正解の選択肢が与えられていたため、選んだ内容と正解を照合して報酬を計算する設計にしました。採点用LLMの推論や採点プロンプトの調整を省けることから、コストと実装の手軽さを重視してルールベースを選びました。

参考にしたのは、DeepSeek-R1論文のDeepSeek-R1-Zeroの報酬設計(§2.2.2)でした。正解と出力形式をルールで評価し、ニューラル報酬モデルの学習に伴う追加資源や処理の複雑化を避けています。今回も、機械的に採点できるタスクの性質を利用しました。

4. 1ノードで約31.5時間、100ステップを実行

実行記録から確認できる主な設定と結果は、以下のとおりです。

項目 記録
ノード数 / GPU数 1ノード / H100 80GB×8
学習ステップ数 100
学習率 1e-5
スケジューラ cosine
warmup_ratio 0.05
per_device_train_batch_size 1
gradient_accumulation_steps 4
num_generations 2
generation_batch_size 4
steps_per_generation 4
num_iterations 1
max_completion_length 3500
vLLM 使用なし
学習時間 113,521.8秒、約31時間32分
出力 checkpoint-100を保存

1ステップ当たり約18.9分、全体で約31.5時間で、空いている1ノードを1〜2日使えるという運用条件に収まりました。

100ステップで処理した量

生成バッチは4回答で、1問当たり2回答を生成したため、1回の生成で扱った問題は2問でした。この4回答を4回の勾配蓄積で処理し、1回の学習ステップを進めました。num_iterations=1としたため、生成1回と学習1ステップが対応していました。

項目 設定・ログから整理した値
1ステップ当たり 2問 × 2回答 = 4回答
100ステップの処理問題数 延べ200問
100ステップの生成回答数 400回答
平均出力長 約628トークン(各ステップの平均出力長を集計)
GPUの割り当て時間 約252 GPU時間(8GPU × 約31.5時間)

今回の構成での処理速度

device_mapによる分割配置は、モデルを収容するための方法です。Accelerateの説明にあるように、単純なモデル分割ではGPUが順に動くため待ち時間が生じ、8GPUに載せただけでは8GPU分の計算能力を同時には使えません。今回はvLLMなどの推論エンジンも使用しませんでした。ただし、生成と重み更新の時間内訳やGPU別の使用率は記録しておらず、各要因が所要時間にどれだけ影響したかは確認していません。生成エンジンや並列方式を変える場合は、速度に加えてモデルの複製・同期に必要なメモリも考慮が必要です。

今回の構成・入力・生成条件では、1ノードで延べ200問・400回答を処理し、100ステップを約31.5時間で実行しました。

メモリの記録

ログのmemory(GiB)の最大値は236.79 GiBでした。ms-swift 3.8.1の実装では、モデル分割時のこの指標は各GPUのPyTorch予約メモリの過去最大値を合計した値です。GPU別の負荷の偏りを知るには、GPUごとの記録を別途取る必要があります。

100ステップの報酬推移

全100ステップの平均報酬と、直近10ステップの移動平均を示します。

全100ステップの平均報酬と10ステップ移動平均

平均報酬はステップごとに上下しました。勾配ノルムが非ゼロだった54ステップでは中央値は約0.062で、残る46ステップでは2回答グループがどちらも同点のため、advantageと勾配ノルムは0でした。frac_reward_zero_stdから集計すると、全200グループ中、点差があったのは62グループ(31%)で、この62グループが上記の54ステップに分布していました。このログを見ると、平均報酬だけでなく、比較する回答間に点差が生じていたかも確認できます。

学習中の平均報酬は、100ステップ平均で約0.341でした。この値には、学習データの難易度や生成・採点条件が影響します。また、次章で述べるように、別の問題の正解を参照していた可能性もあります。これらの影響を切り分けられなかったため、平均報酬だけから学習データの難易度を判定することはできませんでした。学習前のモデルを同じ学習問題・生成条件で採点して基準値を得ることは、報酬や回答抽出の妥当性を点検する手がかりになります(第6章)。

5. 評価結果:明確な精度改善は確認できなかった

学習したLoRAアダプタをベースモデルにマージし、評価担当から共有された結果で比較しました。比較対象は、同じ事後学習の出発点であるQwen3-235B-A22B-Instruct-exp10-Base-Instructionでした。評価セット名は提供時の名称を使用し、差分は百分率に換算したポイント差で示しています。評価セットごとの問題数と詳細な推論条件は未確認のため、ここでは共有された表示値の比較を示します。IgakuQAは、日本の医師国家試験(2018〜2022年)の問題と正解を収録した公開ベンチマークです。

評価セット ベースモデル 事後学習後 差分
igakuqa 0.939 0.939 0.0ポイント
specialist_exam_test_v2 0.794 0.785 −0.9ポイント
specialist_exam_v2 0.782 0.782 0.0ポイント
specialist_exam_question_book 0.778 0.778 0.0ポイント
combined_dataset 0.757 0.755 −0.2ポイント

表示値では同程度、または若干低下しており、ベースモデルを上回る明確な改善は確認できませんでした。

記事執筆時のコードとログの点検では、報酬関数が別の問題の正解を参照する「正解取得の不具合」の可能性が見つかりました。当時の問題・生成回答・参照した正解を照合できず、不具合が実際に発生したかは確認できませんでした。報酬が対応する問題の正解に基づいて計算されたことを確認できないため、今回の結果からF1報酬とGRPOの有効性は判定できませんでした。

この振り返りを通じて、問題・回答・正解・報酬の対応を保存し、学習前に採点の整合性を検証する手順の必要性が明確になりました。次章では、確認できた実行条件と、同様の実験に必要な条件を整理します。

6. 得られた知見:同様の実験を行う際の確認項目

再学習の前に、同じ回答で報酬を比較する

同じ問題・生成回答に完全一致とF1の両方を適用すれば、モデルを再学習せずに採点方式の違いを調べられます。 問題・回答・正解を対応づけて保存した回答群について、次の順に比較します。

  1. 各回答を完全一致とF1でそれぞれ採点する。
  2. 同じ問題の回答群について、同点になる割合や順位の変化を集計する。
  3. 形式点も加え、標準化後のadvantageがどう変わるかを確認する。

この比較で分かるのは、部分点によって回答間にどのような差が生まれるかです。これは学習信号の違いを調べるもので、同点が減っても精度改善につながるとは限らないため、精度への効果は学習後に別途評価する必要があります。第3章のとおり、今回の2回答を標準化する設定では、点差が1e-4より十分大きい場合、点差の大小によらずadvantageの絶対値がほぼ同じになります。そのため、報酬関数の係数だけで学習への影響を判断せず、生成数とadvantageの計算まで含めて設計する必要があります。

生成数を増やすことも比較候補ですが、生成コストも増えます。同じ計算時間の中で「1問当たりの回答数を増やす」か「より多くの問題を扱う」かを比較すると、資源制約に合った設計につながります。

1ノードで試すための資源と時間の目安が得られた

今回の条件では、4bit量子化、8GPUへのモデル分割、AttentionのLoRAを組み合わせ、H100 80GB×8の1ノードで、235B級モデルの生成・重み更新・チェックポイント保存まで実行できる構成を確認しました。100ステップ・延べ200問・400回答を約31.5時間で処理した記録は、同様の構成で実験時間を見積もる際の目安になります。ただし、所要時間は入力・出力長や設定に依存します。

同様の構成で処理速度を検討する際には、生成と重み更新それぞれの時間とGPU別の使用率を記録し、時間を要する処理を確認する必要があります。

学習データと評価課題の適合性を、学習前に確認する

学習データの質には、ラベルの正確さに加えて、評価で必要な能力を学べる問題が含まれているかという観点があります。同じ医療問題でも、分野・難易度・回答形式によって、学習で扱う内容と評価で問われる内容は変わります。

同様の実験を行うなら、ベースモデルを学習問題の一部に対して、学習時と同じプロンプト・生成条件で実行することが出発点になります。そこで完全一致率、F1、形式点、回答の打ち切りを分けて集計すれば、学習前から解ける問題と、改善対象にしたい問題を把握できます。

今回のログでは、打ち切りは400回答中1件相当(0.25%)でした。このように生成状態も記録しておくと、正答率だけでは分からない回答形式や長さ制限の影響を調べられます。

同様の実験を行う際の確認項目を、次のように整理しました。

比較・確認すること 確かめたいこと
問題ID・生成回答・正解・報酬を対応づけて保存 報酬の計算と問題との対応を、後から追跡できるか
同じ回答に完全一致とF1を適用 部分点によって同点がどれだけ解消するか
形式点の有無と標準化後のadvantageを比較 回答内容と形式のどちらが更新の方向を決めるか
ベースモデルの誤答を分野・難易度・形式で整理 学習問題が評価で改善したい能力に対応するか
採点条件を固定し、LoRAの更新範囲や学習量を比較 更新対象と実行量の変更が、評価精度にどう影響するか
正解を指定タグで囲んだテスト回答を用意し、並べ替え・複数回答への展開を含む実際の受け渡し経路で確認 報酬関数が、その問題IDに対応する正解を参照し、F1が1、形式点込みで1.05になるか

比較の前提を揃え、変更の効果を判別しやすくすることが、これらの確認の目的です。

7. まとめ

今回、H100 80GB×8の1ノードで、235B級モデルに対する4bit QLoRA+GRPOの100ステップの生成・重み更新を約31.5時間で実行し、チェックポイントを保存しました。

  • 実行構成と所要時間:4bit量子化、8GPUへのモデル分割、AttentionのLoRAを組み合わせ、1ノードで試すための設定と処理量を記録できた。
  • 報酬設計の検討事項:F1は部分一致を順位に反映できる。2回答のGRPOでは、形式点を含めて標準化後の影響を考える必要がある。
  • 同様の実験に向けた条件:学習後モデルの明確な精度改善は確認できなかった。正解取得の不具合の有無を確認できず、F1報酬とGRPOの有効性は今回の結果では判定できなかった。同様の実験を行う際には、問題・回答・正解・報酬の対応を保存し、学習前の基準値を取得したうえで、報酬・生成数・学習データ・更新範囲を比較する必要があると整理した。

本記事の構成例と所要時間・処理量の記録を、複数ノードを確保しにくい環境で235B級モデルの事後学習を試す際の参考にしていただければと思います。

付録:主要なRLHFArguments

以下は、今回の100ステップ実行に合わせ、保存コードとW&B設定から整理した主要引数です。MODEL_PATHなどのパス、SYSTEM_PROMPT、reward_functionは説明用の未定義変数です。ms-swift 3.8.1のGRPOTrainerは、swift.plugin.ormsの登録名に加えて呼び出し可能なオブジェクトも受け付けるため、保存コードと同様に__call__を実装した報酬クラスのインスタンスをreward_funcsへ渡しています。コードで明示的に指定していない引数(loss_type、importance_sampling_level、scale_rewards、num_iterations、use_vllm、steps_per_generation、lr_scheduler_type、bnb_4bit_compute_dtype)は、ms-swift 3.8.1のデフォルト値を実行時の設定として記載しています。

from swift.llm import RLHFArguments, rlhf_main

args = RLHFArguments(
    model=MODEL_PATH,
    model_type="qwen3_moe",
    dataset=DATASET_PATH,
    output_dir=OUTPUT_DIR,
    rlhf_type="grpo",
    train_type="lora",
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
    lora_rank=8,
    lora_alpha=16,
    lora_dropout=0.05,
    quant_method="bnb",
    quant_bits=4,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_use_double_quant=True,
    bnb_4bit_compute_dtype="bfloat16",
    bf16=True,
    loss_type="grpo",
    importance_sampling_level="token",
    scale_rewards=True,
    num_generations=2,
    num_iterations=1,
    beta=0.0,
    use_vllm=False,
    per_device_train_batch_size=1,
    gradient_accumulation_steps=4,
    steps_per_generation=4,
    max_length=4000,
    max_completion_length=3500,
    temperature=0.7,
    top_p=0.9,
    max_steps=100,
    learning_rate=1e-5,
    lr_scheduler_type="cosine",
    warmup_ratio=0.05,
    weight_decay=0.01,
    template="qwen2_5",
    system=SYSTEM_PROMPT,
    reward_funcs=[reward_function],
    reward_weights=[1.0],
    seed=42,
)

rlhf_main(args)

参考資料

謝辞

この成果は、NEDO(国立研究開発法人新エネルギー・産業技術総合開発機構)の委託業務(JPNP25006)の結果得られたものです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?