Qwen3シリーズの発表。小規模オープンウェイトながらなかなかの性能を示す。(公式)

こんにちは、makokonです。新しいモデルの発表も、相変わらず続いていますが、OpenAI、Google、Anthropicなどの独走は許さないとばかりに、Alibabaから、Qwen3シリーズが発表された(4/29)。公式によると小規模なモデルながら、「Qwen3-235B-A22B」は、OpenAIのo1やo3-miniなどと並ぶ性能をしめし、「Qwen3-4B」は「GPT-4o」を上回ると発表している。
一応、どんなだか押さえておきましょう。
公式発表はこちら。


概要

  • 新しい大規模言語モデルであるQwen3のリリース

  • このモデルは2つのMoEモデルと6つの密なモデルを含み、さまざまなサイズのバージョンを提供

  • 思考と非思考モードを組み合わせたハイブリッドな問題解決アプローチ

  • タスクの複雑さに基づいて柔軟な応答が可能

  • 119の言語と方言をサポートする広範な多言語機能

  • 強化されたコーディングとエージェント機能

  • モデルの開発プロセス利用方法についても説明

発表されたモデルバリエーションの特徴は

発表モデル 2つのMoEモデルと、6つのDenseモデル

全てのモデルがオープンウェイトになっています。

  • MoE モデル:

    • Qwen3-235B-A22B: 総パラメータ数 2350億、活性化パラメータ数 220億の大型モデルです。ベンチマーク評価で、コーディング、数学、一般的な能力などにおいて、他のトップティアモデルと比較して競争力のある結果を達成しています。

    • Qwen3-30B-A3B: 総パラメータ数 300億、活性化パラメータ数 30億の小型MoEモデルです。Qwen2.5のモデルと同等のパフォーマンスを、わずか10%の活性化パラメータで実現しており、トレーニングおよび推論コストを大幅に削減しています。QwQ-32Bを活性化パラメータ数の10倍で上回っています。

  • Dense モデル:
    これらの密なモデルはApache 2.0ライセンスの下で提供されています。Qwen3の密なベースモデルは、より少ないパラメータでQwen2.5のより大きな密なベースモデルと同等かそれ以上の性能を発揮します。特にSTEM、コーディング、推論の分野では、より大きなQwen2.5モデルを上回ることもあります。

    • Qwen3-32B

    • Qwen3-14B

    • Qwen3-8B

    • Qwen3-4B

    • Qwen3-1.7B

    • Qwen3-0.6B

Qwen3モデルファミリー全体の顕著な特徴

  • ハイブリッド思考モード: 問題解決のためのハイブリッドアプローチを導入しています。複雑な問題に対して段階的な推論を行う「Thinking Mode」と、簡単な質問に対して迅速な応答を提供する「Non-Thinking Mode」をサポートしており、ユーザーはタスクに応じてモデルの「思考」量を制御できます。これにより、コスト効率と推論品質のバランスをより最適に達成できます。

  • 多言語サポート: 119の言語と方言をサポートしており、国際的なアプリケーションの新たな可能性を開きます。

  • 改善されたエージェント機能: コーディングとエージェント機能が最適化され、MCPのサポートも強化されています。Qwen-Agentを使用することで、ツール呼び出し機能を活用できます。

  • 大規模な事前学習データ: Qwen2.5の約2倍にあたる、約36兆トークンのデータセットで事前学習されています。これには、ウェブデータ、PDFライクな文書からのテキスト、および合成された数学やコードデータが含まれます。


モデルの概要

Qwen3モデルは、ローカルで実行できますか

Qwen3モデルはオープンウェイトされており、Hugging Faceなどのプラットフォームから入手可能であり、さらにOllamaやllama.cppといったローカル実行に特化したツールや、Hugging Faceライブラリを通じて、ユーザーのローカル環境で実行できるように準備されていることがわかります。

ポストトレーニング済みのモデル(例:Qwen3-30B-A3B)が、Hugging Face、ModelScope、およびKaggleといったプラットフォームで利用可能になっていると言及しています。これらのプラットフォームからモデルを取得し、ローカル環境で利用することができます。

ローカルでの使用や開発のために、いくつかのツールとフレームワークが推奨されています。

  1. ローカル利用のための推奨ツール:

    • ソースでは、OllamaLMStudioMLXllama.cpp、およびKTransformersといったツールがローカルでの使用に強く推奨されています

    • Ollamaを使用してモデルを実行する簡単なコマンド例も提供されており、ollama run qwen3:30b-a3bのように実行できることが示されています。

  2. デプロイメント(ローカルサーバーを含む可能性)のための推奨フレームワーク:

    • SGLang バージョン 0.4.6.post1以降 または vLLM バージョン 0.8.4以降 を使用して、OpenAI互換のAPIエンドポイントを作成し、デプロイすることが推奨されています。これは、ローカルマシン上でAPIサーバーを構築する場合にも適用できます

  3. Hugging Face Transformersライブラリ:

    • Hugging Face transformersライブラリを使用してQwen3-30B-A3Bをロードし、利用するPythonコードの例が示されています。これは、多くのユーザーがローカル環境でモデルをロードして推論を実行する一般的な方法です。

モデルのトレーニング


Qwen3 モデルのトレーニングは、事前学習 (Pre-training) と、特定のモデルバリエーションに適用される事後学習 (Post-training) に分けられます。
Qwen3 のモデルは、大規模なデータセットを用いた共通の事前学習で強力な言語・知識基盤を築き、その上で特にハイブリッド思考モードやエージェント機能といった特定の高度な能力を、段階的な事後学習(ポストトレーニング)プロセスによって獲得しています。

共通部分:事前学習

Qwen3 モデルファミリー全体に共通する基盤は、大規模なデータセットを用いた事前学習によって構築されています。

  • データセット: Qwen3 の事前学習データセットは、Qwen2.5 の約2倍の規模となる、約36兆トークンに大幅に拡張されています。このデータセットは119の言語と方言をカバーしています。データの種類としては、ウェブデータだけでなく、PDF形式の文書から抽出されたテキストも含まれています。さらに、数学やコードデータの量を増やすために、Qwen2.5-Math や Qwen2.5-Coder を使用して教科書、質疑応答のペア、コードスニペットなどの合成データが生成されました。

  • 事前学習プロセス: 事前学習は3つの段階で構成されています。

    1. 第1段階 (S1): 30兆トークン以上のデータで、コンテキスト長4Kトークンでの事前学習が行われました。この段階で、モデルは基本的な言語スキルと一般知識を習得しました。

    2. 第2段階 (S2): STEM、コーディング、推論タスクなど、知識集約型データの割合を増やしてデータセットが改良され、さらに5兆トークンで事前学習が行われました。

    3. 第3段階: 高品質な長文コンテキストデータを使用して、コンテキスト長が32Kトークンに拡張されました。これにより、モデルはより長い入力を効果的に処理できるようになりました。

モデル固有部分:事後学習(ポストトレーニング)

事前学習で得られた基盤の上に、ポストトレーニングによってモデル固有の機能が付与されます。特に、ハイブリッド思考モードエージェント機能の強化が段階的な事後学習(ポストトレーニング)プロセスによっておこなわれます。

  • ハイブリッド思考モードの実現: 段階的な推論能力と迅速な応答能力の両方を持つハイブリッドモデルを開発するために、4段階のトレーニングパイプラインが実装されました。(密なモデルQwen3-32Bも提供された図面では、同じように4段階トレーニングをしているようですが、具体的な記載がなく、怪しいと思っている)

    1. 段階1: 数学、コーディング、論理推論、STEM問題など、多様な長文 Chain-of-Thought (CoT) データを使用してモデルがファインチューニングされました。これにより、モデルに基本的な推論能力を習得させることを目指しました。

    2. 段階2: 推論ベースの強化学習 (RL) のための計算リソースがスケールアップされ、ルールベースの報酬を利用してモデルの探索および活用能力が強化されました。

    3. 段階3: 長文 CoT データと一般的な指示チューニングデータの組み合わせでファインチューニングを行うことにより、非思考能力が思考モデルに統合されました。このデータは、第2段階で強化された思考モデルによって生成されたものが使用され、推論能力と迅速な応答能力のシームレスな融合が図られています。

    4. 段階4: 20以上の一般ドメインタスクでRLが適用され、モデルの一般的な能力をさらに強化し、望ましくない振る舞いを修正しました。これには、指示追従、フォーマット追従、エージェント能力などが含まれます。Qwen3-235B-A22B、(Qwen3-32B?)

    5. 軽量化:Qwen3-30B-A3Bは、この成果を蒸留して得られました。
      (その他の密なモデルもQwen3-32Bを蒸留している?)


MoEモデルの事後学習イメージ


Qwen3シリーズの性能

Qwen3シリーズは全体として、前世代のQwen2.5や同クラスの他社モデルと比較して、より効率的(少ないパラメータで同等以上の性能)であるか、あるいは同等以上の性能を発揮していることがわかります。特に、小型MoEモデルと密なモデルは、パラメータ数削減によるコスト効率と、特定の難しいタスク(STEM、コーディング、推論)における性能向上が強調されています。
表には、Qwen3シリーズの主要な各種ベンチマーク結果が紹介されています。モデルの性能は各社のフラグシップモデルと比較されています(表1)。また、モデルは、各社の有名なオープンソースモデルおよび、参考としてgpt-4oと比較されています(表2)。その性能を定性的にまとめます。

表1
表2
  • フラッグシップモデル Qwen3-235B-A22B: このモデルは、コーディング、数学、一般的な能力のベンチマーク評価において、DeepSeek-R1、o1、o3-mini、Grok-3、Gemini-2.5-Proといった他のトップティアのモデルと比較して、競争力のある結果を達成しています。

  • 小型MoEモデル Qwen3-30B-A3B: このモデルは、活性化パラメータが10分の1であるQwQ-32Bを凌駕し、Qwen2.5の密なベースモデルと同様の性能を達成しつつ、活性化パラメータはわずか10%にとどまっています。これにより、トレーニングコストと推論コストを大幅に削減できるとされています。

  • 密なモデル群: Qwen3の密なベースモデル(Qwen3-1.7B/4B/8B/14B/32B-Base)は、モデルアーキテクチャの進歩、トレーニングデータの増加、より効果的なトレーニング手法により、より多くのパラメータを持つQwen2.5のベースモデル(Qwen2.5-3B/7B/14B/32B/72B-Base)と同等の全体的な性能を発揮しています。

    • 特に、STEM、コーディング、推論といった分野では、Qwen3の密なベースモデルはより大きなQwen2.5モデルを凌駕する性能を発揮しています。

    • 小さなモデルであるQwen3-4Bでさえ、Qwen2.5-72B-Instructの性能に匹敵することがあります。

また、性能に関連する特徴として、複雑な問題には推論を行う「思考モード」と、簡単な問題には迅速に応答する「非思考モード」を持つハイブリッド思考モード をサポートし、これによりコスト効率と推論品質のバランスを最適化できる点 や、エージェント能力が最適化されている点 も挙げられています。多言語対応(119言語・方言) も、幅広いアプリケーションでの性能発揮に貢献します。

付録 Qwen3シリーズの使い方(サンプルコードの紹介)

サンプルコードを紹介します。簡単なコードなので解説はなしです。

シンプルな使い方 思考モードあり

from modelscope import AutoModelForCausalLM, AutoTokenizer

model_name = "Qwen/Qwen3-30B-A3B"

# load the tokenizer and the model
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto"
)

# prepare the model input
prompt = "Give me a short introduction to large language model."
messages = [
    {"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True,
    enable_thinking=True # Switch between thinking and non-thinking modes. Default is True.
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)

# conduct text completion
generated_ids = model.generate(
    **model_inputs,
    max_new_tokens=32768
)
output_ids = generated_ids[0][len(model_inputs.input_ids[0]):].tolist() 

# parsing thinking content
try:
    # rindex finding 151668 (</think>)
    index = len(output_ids) - output_ids[::-1].index(151668)
except ValueError:
    index = 0

thinking_content = tokenizer.decode(output_ids[:index], skip_special_tokens=True).strip("\n")
content = tokenizer.decode(output_ids[index:], skip_special_tokens=True).strip("\n")

print("thinking content:", thinking_content)
print("content:", content)

シンプルな使い方 思考モードなし

enable_thinking=Falseだけ

text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True,
    enable_thinking=False  # True is the default value for enable_thinking.
)

応用的な使い方 マルチターン

messagesだけケアすれば良さそう。一般的な使い方ですね。

from transformers import AutoModelForCausalLM, AutoTokenizer

class QwenChatbot:
    def __init__(self, model_name="Qwen/Qwen3-30B-A3B"):
        self.tokenizer = AutoTokenizer.from_pretrained(model_name)
        self.model = AutoModelForCausalLM.from_pretrained(model_name)
        self.history = []

    def generate_response(self, user_input):
        messages = self.history + [{"role": "user", "content": user_input}]

        text = self.tokenizer.apply_chat_template(
            messages,
            tokenize=False,
            add_generation_prompt=True
        )

        inputs = self.tokenizer(text, return_tensors="pt")
        response_ids = self.model.generate(**inputs, max_new_tokens=32768)[0][len(inputs.input_ids[0]):].tolist()
        response = self.tokenizer.decode(response_ids, skip_special_tokens=True)

        # Update history
        self.history.append({"role": "user", "content": user_input})
        self.history.append({"role": "assistant", "content": response})

        return response

# Example Usage
if __name__ == "__main__":
    chatbot = QwenChatbot()

    # First input (without /think or /no_think tags, thinking mode is enabled by default)
    user_input_1 = "How many r's in strawberries?"
    print(f"User: {user_input_1}")
    response_1 = chatbot.generate_response(user_input_1)
    print(f"Bot: {response_1}")
    print("----------------------")

    # Second input with /no_think
    user_input_2 = "Then, how many r's in blueberries? /no_think"
    print(f"User: {user_input_2}")
    response_2 = chatbot.generate_response(user_input_2)
    print(f"Bot: {response_2}") 
    print("----------------------")

    # Third input with /think
    user_input_3 = "Really? /think"
    print(f"User: {user_input_3}")
    response_3 = chatbot.generate_response(user_input_3)
    print(f"Bot: {response_3}")

エージェントの使い方

Qwen-Agent を使用することが推奨されています。
ツールコーリングの書き方もわかりやすいです。

from qwen_agent.agents import Assistant

# Define LLM
llm_cfg = {
    'model': 'Qwen3-30B-A3B',

    # Use the endpoint provided by Alibaba Model Studio:
    # 'model_type': 'qwen_dashscope',
    # 'api_key': os.getenv('DASHSCOPE_API_KEY'),

    # Use a custom endpoint compatible with OpenAI API:
    'model_server': 'http://localhost:8000/v1',  # api_base
    'api_key': 'EMPTY',

    # Other parameters:
    # 'generate_cfg': {
    #         # Add: When the response content is `<think>this is the thought</think>this is the answer;
    #         # Do not add: When the response has been separated by reasoning_content and content.
    #         'thought_in_content': True,
    #     },
}

# Define Tools
tools = [
    {'mcpServers': {  # You can specify the MCP configuration file
            'time': {
                'command': 'uvx',
                'args': ['mcp-server-time', '--local-timezone=Asia/Shanghai']
            },
            "fetch": {
                "command": "uvx",
                "args": ["mcp-server-fetch"]
            }
        }
    },
  'code_interpreter',  # Built-in tools
]

# Define Agent
bot = Assistant(llm=llm_cfg, function_list=tools)

# Streaming generation
messages = [{'role': 'user', 'content': 'https://qwenlm.github.io/blog/ Introduce the latest developments of Qwen'}]
for responses in bot.run(messages=messages):
    pass
print(responses)

ハッシュタグ


いいなと思ったら応援しよう!