その他のエッセイはこちら
要約
- Intel iGPU + OpenVINOという前提では、OpenVINOが配布しているINT4モデル群から選ぶのが最短でした。
- C言語リングバッファ生成では、関数単位の生成力だけでなく、CMake・include・リンク・テストまで含む複数ファイル作業で差が出ました。
- Qwen3-Coder-30Bは最も重い一方、周辺確認や複数ファイル理解が強く、CLIオーケストレータ的な役割にも可能性を感じました。
前回の関連記事
Windows11 CPUローカルLLM環境でOllama + Qwen2.5-Coder + Continue / Aider / OpenAI APIを試した記事
動作確認時の動画
動作確認時の画面キャプチャー動画です。(10倍速で再生しています。音などは出ません。)
検証環境
今回の検証環境は次のとおりです。
- OS: Windows 11
- CPU: Intel(R) Core(TM) Ultra 9 288V (3.30 GHz)
- RAM: 32.0 GB
- 推論基盤: OpenVINO Model Server
- エディタ: Visual Studio Code
- エージェント: Continue
- 比較対象: Qwen3-8B-int4-ov、Qwen3-14B-int4-ov、Qwen3-Coder-30B-A3B-Instruct-int4-ov、gpt-oss-20b-int4-ov
OpenVINO の Visual Studio Code Local Assistant は、Windows での bare-metal 利用と Continue 連携を案内しており、Intel Meteor Lake / Lunar Lake / Arrow Lake / Panther Lake を対象にしています。今回の Core Ultra 系環境は、この文脈にかなり近い前提です。 (OpenVINO Documentation)
検証方針
今回の出発点は、「Intel iGPU + OpenVINO で動くこと」を最優先にしたことです。
そのため、まず OpenVINO が配布している INT4 最適化済みモデルを候補にし、その上で Continue とつなぎ、C言語のリングバッファ生成、CMakeLists.txt の自動生成、ビルド、テスト実行まで見ました。OpenVINO の VS Code Local Assistant には、Qwen3-8B、gpt-oss-20b、Qwen3-Coder-30B の Windows / GPU 向け例が載っています。 (OpenVINO Documentation)
なお、Intel Core Ultra 系ということで NPU も試しましたが、今回の 14B / 30B 系では NPU 指定時に VPUX compiler の shape 不整合エラーが出て安定動作まで持ち込めませんでした。そのため本記事の主比較は GPU 実行に絞っています。OpenVINO / OVMS には NPU 向けの公式導線もありますが、現時点で分かりやすく案内されている代表例は Qwen3-8B-int4-cw-ov などの NPU 寄りモデルで、今回の比較対象とは少し前提が異なります。
cw は channel-wise quantization の略で、NPU 向けに寄せた INT4 OpenVINO モデル名でよく使われます。
モデル選定
今回選んだモデル
今回の本命候補は次の4つです。
- Qwen3-8B-int4-ov
- Qwen3-14B-int4-ov
- Qwen3-Coder-30B-A3B-Instruct-int4-ov
- gpt-oss-20b-int4-ov
選定理由は明快で、OpenVINO 側に配布済みの INT4 モデルがあり、Windows + GPU の導線が見えていたことです。Qwen3-8B は OpenVINO 2026.0.0 以降、Qwen3-14B は OpenVINO 2025.1.0 以降、Qwen3-Coder-30B と gpt-oss-20b は OpenVINO 2026.0.0 以降の互換が明記されています。 (Hugging Face)
Qwen3-8B-int4-ov を入れた理由
Qwen3-8B は OpenVINO 公式の VS Code Local Assistant に Windows GPU 起動例があり、推奨 GPU メモリも 6GB+ と最も軽く、比較の基準モデルとして置きやすかったです。 (OpenVINO Documentation)
Qwen3-14B-int4-ov を入れた理由
8B の次に試す中間候補として自然だったためです。OpenVINO 版が配布されており、8B より一段上の精度を見たい時の比較対象として扱いやすい位置にありました。互換バージョンも 2025.1.0 以降と明記されています。 (Hugging Face)
Qwen3-Coder-30B-A3B-Instruct-int4-ov を入れた理由
コード用途の本命候補だったからです。Continue の Edit モデル推奨では open model 上位に Qwen3 Coder 30B が入り、Qwen のモデルカードでも agentic coding、tool calling、256K 長文脈、repository-scale understanding を前面に出しています。OpenVINO 側でも INT4 版の配布があり、Windows / GPU 例もあります。 (Continue Docs)
gpt-oss-20b-int4-ov を入れた理由
OpenVINO 公式の VS Code Local Assistant に Windows GPU 起動例があり、Qwen 系以外の比較候補として一度は見ておきたかったためです。OpenVINO 版も公開されています。 (OpenVINO Documentation)
Qwen2.5-Coder 7B を今回の本命にしなかった理由
Qwen2.5-Coder 7B は過去に Ollama 環境で試していて、応答性が悪く、実用感がかなり低かったためです。
一方で今回の Intel iGPU + OpenVINO 環境では、Qwen3-8B、Qwen3-14B、Qwen3-Coder-30B の方が、少なくとも比較検証を進められるレベルには動きました。もちろん Codex や Claude Code と比べると、もっさり感は否めませんが、実験自体が難しいという段階ではありませんでした。
各モデルの比較表
| モデル | OpenVINO配布 | OpenVINO公式の推奨GPUメモリ目安 | 今回の主な役割 | 傾向 | リングバッファ生成の実測 |
|---|---|---|---|---|---|
| Qwen3-8B-int4-ov | あり | 6GB+ | 基準モデル | 単一関数・単一ファイル寄り。複数ファイル整合は弱め | 約3分 |
| Qwen3-14B-int4-ov | あり | 8Bと30Bの中間候補として使用 | 中間比較 | 8Bより少し広く見られるが、全体把握はまだ限定的 | 約3.5分 |
| Qwen3-Coder-30B-A3B-Instruct-int4-ov | あり | 19GB+ | 本命の coder 系 | 周辺確認、CMake、テスト、複数ファイル読取りが最も積極的 | 約4.2分 |
| gpt-oss-20b-int4-ov | あり | 16GB+ | 比較候補 | 疎通確認の段階で応答が長く、今回は本比較対象から外した | コード生成は未実施 |
| Qwen2.5-Coder 7B | 今回の OpenVINO 比較では未使用 | 該当なし | 過去比較 | Ollama 環境では応答性が悪く、実用感が低かった | 今回は未計測 |
OpenVINO 公式の VS Code Local Assistant では、Qwen3-8B-int4-ov に 6GB+、Qwen3-Coder-30B-A3B-Instruct-int4-ov に 19GB+、gpt-oss-20b-int4-ov に 16GB+ の推奨 GPU メモリが示されています。 (OpenVINO Documentation)
応答性の指標
今回のリングバッファコード生成では、応答時間は次のようになりました。
- 8B: 3分
- 14B: 3.5分
- 30B: 4.2分
印象としては、モデル規模に応じて単純に倍々で遅くなる感じではなく、かなり緩い傾斜でした。
もちろん、これは Intel iGPU に載る範囲という条件つきです。今回のような環境では、メモリ転送だけでなく、実際の推論時間の比率がやや大きい可能性があります。
この結果だけを見ると、30B になった瞬間に「遅すぎて実験不可能」という水準には入りませんでした。クラウドの Codex や Claude Code と比べると待ち時間は明らかに長いですが、少なくともローカルで比較検証を進めること自体は可能でした。
gpt-oss-20b の方は、疎通確認段階で Qwen 系が 10 秒未満で応答するような短い確認プロンプトに対して 1 分以上かかるケースがあり、今回はコード生成比較には進めませんでした。OpenVINO 公式でも gpt-oss-20b-int4-ov は推奨 GPU メモリ 16GB+ とされており、今回の条件ではかなり重いことが予想できます。 (OpenVINO Documentation)
実際に使った構成
OVMS の起動コマンド
Qwen3-8B の例です。
.\ovms\setupvars.ps1
ovms --model_repository_path C:\models `
--source_model OpenVINO/Qwen3-8B-int4-ov `
--task text_generation `
--target_device GPU `
--tool_parser hermes3 `
--reasoning_parser qwen3 `
--rest_port 8000 `
--cache_dir .ovcache `
--model_name Qwen3-8B
Qwen3-14B の例です。
.\ovms\setupvars.ps1
ovms --model_repository_path C:\models `
--source_model OpenVINO/Qwen3-14B-int4-ov `
--task text_generation `
--target_device GPU `
--tool_parser hermes3 `
--reasoning_parser qwen3 `
--rest_port 8000 `
--cache_dir .ovcache `
--model_name Qwen3-14B
Qwen3-Coder-30B の例です。
.\ovms\setupvars.ps1
ovms --model_repository_path C:\models `
--source_model OpenVINO/Qwen3-Coder-30B-A3B-Instruct-int4-ov `
--task text_generation `
--target_device GPU `
--tool_parser qwen3coder `
--rest_port 8000 `
--cache_dir .ovcache `
--model_name Qwen3-Coder-30B
gpt-oss-20b の例です。
.\ovms\setupvars.ps1
ovms --model_repository_path C:\models `
--source_model OpenVINO/gpt-oss-20b-int4-ov `
--task text_generation `
--target_device GPU `
--tool_parser gptoss `
--reasoning_parser gptoss `
--rest_port 8000 `
--cache_dir .ovcache `
--model_name gpt-oss-20b
これらの起動例は OpenVINO の VS Code Local Assistant が案内している形に沿っています。 (OpenVINO Documentation)
Continue の config.yaml
Qwen3-Coder-30B の config.yaml は次のようにしました。
name: Local Assistant
version: 1.0.0
schema: v1
models:
- name: OVMS Qwen3-Coder-30B
provider: openai
model: Qwen3-Coder-30B
apiKey: unused
apiBase: http://localhost:8000/v3
roles:
- chat
- edit
- apply
capabilities:
- tool_use
context:
- provider: code
- provider: docs
- provider: diff
- provider: terminal
- provider: problems
- provider: folder
- provider: codebase
Continue の Agent mode では、Plan mode に read-only ツールとして read_file、ls、glob_search、grep_search、codebase_tool などが用意されています。今回 30B coder だけが周辺確認をかなり積極的に行ったのは、この Agent mode の道具群に加えて、モデル側の agentic coding 志向が強かったためだと考えています。 (Continue Docs)
リングバッファ生成で使った指示
比較用に使ったゼロベース生成指示の骨子は次のようなものでした。
C言語で固定長リングバッファをゼロベースで実装して。
前提:
- 開発環境は Windows
- シェルは Windows PowerShell 5.1
- ビルドは CMake を使う
- コンパイラは MinGW GCC
- && と || は使わない
- コマンドは 1 行ずつ個別に実行すること
- ファイル本文には Markdown を入れないこと
作成するファイル:
- src/ring_buffer.h
- src/ring_buffer.c
- src/main.c
- tests/test_ring_buffer.c
- CMakeLists.txt
実装要件:
- malloc は使わない
- 外部から渡された int 配列を使う固定長リングバッファ
- API は ring_buffer_init / push / pop / is_empty / is_full / size に統一
- enable_testing() を使う
- add_test(NAME ring_buffer_tests COMMAND ring_buffer_tests) で登録
- add_test の COMMAND に build/... は書かない
実行コマンド:
cmake -S . -B build -G "MinGW Makefiles" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build
ctest --test-dir build --output-on-failure
この形にした理由は、小〜中規模モデルでは「include を自動補完する」「ヘッダ宣言の関数を自動で .c に実装する」「リンクエラーの真因を推測する」といった複数ファイル整合作業が弱く出やすかったためです。
対象ファイル、API 名、CMake 要件、PowerShell 5.1 の制約まで先に明示した方が安定しました。
30B が生成した実ファイル例
今回アップロードしたファイルは、Qwen3-Coder-30B が生成したものです。
要件としては「外部バッファ渡し方式」に寄せたい場面もありましたが、30B は malloc / free を使う設計を選びました。そのため、完成度は高い一方で、仕様の細部は人間側がさらに明示した方がよいことも分かりました。
src/ring_buffer.h
#ifndef RING_BUFFER_H
#define RING_BUFFER_H
#include <stdbool.h>
#include <stddef.h>
// Ring buffer structure
typedef struct {
int* data;
size_t capacity;
size_t head;
size_t tail;
size_t count;
} ring_buffer_t;
// Initialize a ring buffer
bool ring_buffer_init(ring_buffer_t* rb, size_t capacity);
// Deinitialize a ring buffer
void ring_buffer_deinit(ring_buffer_t* rb);
// Add an element to the ring buffer
bool ring_buffer_push(ring_buffer_t* rb, int value);
// Remove and return the oldest element from the ring buffer
bool ring_buffer_pop(ring_buffer_t* rb, int* value);
// Get the number of elements in the ring buffer
size_t ring_buffer_size(const ring_buffer_t* rb);
// Check if the ring buffer is empty
bool ring_buffer_is_empty(const ring_buffer_t* rb);
// Check if the ring buffer is full
bool ring_buffer_is_full(const ring_buffer_t* rb);
#endif // RING_BUFFER_H
このヘッダでは、ring_buffer_init が容量だけを受けて内部確保する API になっています。つまり、こちらが想定していた「外部配列を受ける関数シグネチャ」とは異なります。
src/ring_buffer.c
#include "ring_buffer.h"
#include <stdlib.h>
#include <stdbool.h>
// Initialize a ring buffer
bool ring_buffer_init(ring_buffer_t* rb, size_t capacity) {
if (rb == NULL || capacity == 0) {
return false;
}
rb->data = (int*)malloc(sizeof(int) * capacity);
if (rb->data == NULL) {
return false;
}
rb->capacity = capacity;
rb->head = 0;
rb->tail = 0;
rb->count = 0;
return true;
}
// Deinitialize a ring buffer
void ring_buffer_deinit(ring_buffer_t* rb) {
if (rb != NULL && rb->data != NULL) {
free(rb->data);
rb->data = NULL;
}
}
// Add an element to the ring buffer
bool ring_buffer_push(ring_buffer_t* rb, int value) {
if (rb == NULL || rb->data == NULL) {
return false;
}
if (ring_buffer_is_full(rb)) {
return false;
}
rb->data[rb->tail] = value;
rb->tail = (rb->tail + 1) % rb->capacity;
rb->count++;
return true;
}
// Remove and return the oldest element from the ring buffer
bool ring_buffer_pop(ring_buffer_t* rb, int* value) {
if (rb == NULL || rb->data == NULL || value == NULL) {
return false;
}
if (ring_buffer_is_empty(rb)) {
return false;
}
*value = rb->data[rb->head];
rb->head = (rb->head + 1) % rb->capacity;
rb->count--;
return true;
}
// Get the number of elements in the ring buffer
size_t ring_buffer_size(const ring_buffer_t* rb) {
if (rb == NULL) {
return 0;
}
return rb->count;
}
// Check if the ring buffer is empty
bool ring_buffer_is_empty(const ring_buffer_t* rb) {
if (rb == NULL) {
return true;
}
return rb->count == 0;
}
// Check if the ring buffer is full
bool ring_buffer_is_full(const ring_buffer_t* rb) {
if (rb == NULL) {
return false;
}
return rb->count == rb->capacity;
}
この .c では、満杯時 push が false を返す設計になっており、基本動作は素直です。ヘッダと実装の整合も取れています。
tests/test_ring_buffer.c
#include "ring_buffer.h"
#include <stdio.h>
#include <assert.h>
void test_basic_operations() {
ring_buffer_t rb;
assert(ring_buffer_init(&rb, 3));
// Test empty buffer
assert(ring_buffer_is_empty(&rb));
assert(!ring_buffer_is_full(&rb));
assert(ring_buffer_size(&rb) == 0);
// Test push
assert(ring_buffer_push(&rb, 1));
assert(!ring_buffer_is_empty(&rb));
assert(!ring_buffer_is_full(&rb));
assert(ring_buffer_size(&rb) == 1);
assert(ring_buffer_push(&rb, 2));
assert(ring_buffer_size(&rb) == 2);
// Test pop
int value;
assert(ring_buffer_pop(&rb, &value));
assert(value == 1);
assert(ring_buffer_size(&rb) == 1);
assert(ring_buffer_pop(&rb, &value));
assert(value == 2);
assert(ring_buffer_is_empty(&rb));
// Test push overflow
assert(ring_buffer_push(&rb, 3));
assert(ring_buffer_push(&rb, 4));
assert(ring_buffer_push(&rb, 5));
assert(ring_buffer_is_full(&rb));
// Try to push when full - should fail
assert(!ring_buffer_push(&rb, 6));
ring_buffer_deinit(&rb);
}
void test_overflow_behavior() {
ring_buffer_t rb;
assert(ring_buffer_init(&rb, 3));
// Fill the buffer completely
ring_buffer_push(&rb, 1);
ring_buffer_push(&rb, 2);
ring_buffer_push(&rb, 3);
// Try to add one more - should overwrite oldest element
int value;
ring_buffer_pop(&rb, &value); // Should get 1
assert(value == 1);
ring_buffer_push(&rb, 4); // Add new element
// Now the buffer should contain 2, 3, 4
assert(ring_buffer_size(&rb) == 3);
ring_buffer_deinit(&rb);
}
int main() {
test_basic_operations();
test_overflow_behavior();
printf("All tests passed!\n");
return 0;
}
このテストでは、基本操作、満杯時 push 失敗、テスト用 main() まで含まれており、最低限の CTest 実行に十分な形でした。
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(RingBuffer)
# Set C standard
set(CMAKE_C_STANDARD 11)
# Include directories
include_directories(src)
# Create library
add_library(ring_buffer_lib STATIC src/ring_buffer.c)
# Create executable for testing
add_executable(ring_buffer_tests tests/test_ring_buffer.c)
target_link_libraries(ring_buffer_tests ring_buffer_lib)
# Enable testing
enable_testing()
add_test(NAME ring_buffer_tests COMMAND ring_buffer_tests)
この CMakeLists.txt は最小限ですが、ring_buffer_lib、ring_buffer_tests、enable_testing()、add_test() まで入り、テスト実行に必要な骨格を備えています。
実際に試して見えた傾向
8B / 14B の傾向
Qwen3-8B と Qwen3-14B は、同一関数や同一ファイル内の辻褄合わせは比較的得意でした。
一方で、include 追加、ヘッダで宣言した関数を .c に実装する作業、CMake の include path、リンクエラー認識は弱めで、プロジェクト全体を通した整合を自律的に取るのはあまり得意ではありませんでした。
実際、関数名を列挙して「この宣言を実装して」と渡した方が安定し、ビルドエラーやリンクエラーを見て自力で API 全体を再構成するのは苦手でした。
30B coder の傾向
Qwen3-Coder-30B は、最初に ls や pwd に相当する状況確認を行い、周辺ファイルも見てから手を入れる傾向がかなり強く出ました。Continue の Agent mode はどのモデルにも同じようにツール一覧を渡しますが、8B / 14B や過去の Qwen2.5-Coder 3B / 7B では、そこまで探索的な挙動は目立ちませんでした。つまり今回観測した「まず周辺を見る」傾向は、Agent mode 共通の仕組みだけでなく、30B coder 側の性格もかなり強いと見ています。 (Continue Docs)
これは良い面もあり、CMake、テスト、複数ファイル API の整合には効きやすいです。
その一方で、探索回数が増えるので、当然ながら応答はさらに重くなります。
CLIオーケストレータとして見た適性
今回の検証では、Qwen3-Coder-30B は単にコードを書くモデルというより、既存のファイルや周辺状況を読んだ上で、次に何を触るべきかを判断する挙動が比較的はっきり見えました。
この特性は、コード生成そのものよりも、出来上がった CLI ツール群を順に呼び出すオーケストレータの簡易意思決定頭脳として使う場合に、むしろ相性が良い可能性があります。
特にローカル実行であり、しかも dGPU を前提にしない環境では、巨大モデルを常時フル性能で対話利用するより、比較的短い文脈で「次にどのコマンドを実行するか」「結果を見て次にどの確認をするか」を判断させる役割の方が現実的です。今回の検証でも、Qwen3-Coder-30B は周辺情報の確認を先に行う傾向があり、この性質はビルド、テスト、ログ確認、再実行のような逐次的な自動処理に向いています。Qwen 側のモデルカードでも tool calling と agentic coding が強調されています。 (Hugging Face)
今回対象にしたのは C 言語で、ヘッダ、実装、CMake、テストが相互に関係する、比較的相互作用の強い題材でした。
このタイプでは、宣言と定義、include、リンク、CMake の理解まで同時に求められるため、モデルの弱点も見えやすくなります。
一方で、Python のように単一言語・単一実行系でまとまりやすく、処理の流れがシーケンシャルに決まる自動化タスクであれば、今回より適用しやすい可能性があります。
たとえば、次のような用途では相性が良さそうです。
- テスト実行結果を読んで次の CLI を選ぶ
- ログを見て再試行、設定変更、別スクリプト実行を判断する
- 既存の自動処理パイプラインの簡易制御役として使う
- ローカル制約を前提に、短い判断を積み重ねる自動運転に使う
特に、環境制約をモデルに毎回推論させるのではなく、事前に利用可能コマンドや実行ルールを明示した上で、その範囲内で判断させる形にすると、ローカル環境でも実用性が上がりやすいです。今回の検証でも、PowerShell 5.1、CMake、MinGW、禁止コマンド、実行順序などを先に明示したときの方が挙動は安定しました。
どのモデルをどう使うか
今回の感触では、用途ごとの使い分けがかなり重要です。
- 単一関数の生成や軽い修正なら Qwen3-8B
- 少し広い範囲を見たいなら Qwen3-14B
- CMake、include、テスト、複数ファイル整合まで見たいなら Qwen3-Coder-30B
- gpt-oss-20b は比較候補だが、今回の環境では疎通段階の応答時間が長く、本比較の主役にはしづらかった
特に Intel iGPU では、単純なモデルサイズよりも「どこまで周辺情報を見に行くか」の差が体感に効いていました。
補足: NPUも少し試した
Intel Core Ultra 系なので、今回の構成で NPU も試しました。
ただし、少なくとも今回使った Qwen3-14B と Qwen3-Coder-30B では、--target_device NPU 指定時に VPUX compiler 側の shape 不整合エラーが発生し、比較検証を続けられる状態にはなりませんでした。
これは単に「重くて遅い」というより、NPU 向けのコンパイル経路に乗せた段階で詰まった感触です。今回の 14B / 30B 比較は GPU 実行を本筋にし、NPU は別テーマとして切り分けるのが自然だと判断しました。
代表的なエラーは次のようなものでした。
[ERROR] 17:57:52.517 [vpux-compiler] Got Diagnostic at loc(… "MatMul" … "as_convolution") :
Channels count of input tensor shape and filter shape must be the same: 0 != 40
FAQ
Q1. Intel iGPU + OpenVINO で最初に試すモデルはどれか
最初の1本は Qwen3-8B-int4-ov が無難です。OpenVINO 公式サンプルで Windows GPU 向けの起動例があり、推奨 GPU メモリも 6GB+ と最も軽いからです。 (OpenVINO Documentation)
Q2. 14B と 30B coder はどちらから試すべきか
単一ファイルの修正や軽量比較なら 14B、CMake や複数ファイル整合まで見たいなら 30B coder です。Continue の Edit 推奨でも Qwen3 Coder 30B は open model 上位に入っています。 (Continue Docs)
Q3. gpt-oss-20b は今回はどうだったか
OpenVINO の公式対象であり候補には入りますが、今回の環境では疎通確認段階の短いプロンプトでも Qwen 系よりかなり長く、コード生成比較には進めませんでした。OpenVINO 公式の推奨 GPU メモリもかなり大きいです。 (OpenVINO Documentation)
Q4. 日本語の手動疎通確認はどうするべきか
PowerShell 5.1 の Invoke-RestMethod より、curl.exe で UTF-8 JSON ファイルを --data-binary 送信する方が安定しました。これは今回の環境で最も再現性のある方法でした。
参考文献
- OpenVINO Visual Studio Code Local Assistant
https://docs.openvino.ai/2026/model-server/ovms_demos_code_completion_vsc.html - OpenVINO/Qwen3-8B-int4-ov
https://huggingface.co/OpenVINO/Qwen3-8B-int4-ov - OpenVINO/Qwen3-14B-int4-ov
https://huggingface.co/OpenVINO/Qwen3-14B-int4-ov - OpenVINO/Qwen3-Coder-30B-A3B-Instruct-int4-ov
https://huggingface.co/OpenVINO/Qwen3-Coder-30B-A3B-Instruct-int4-ov - OpenVINO/gpt-oss-20b-int4-ov
https://huggingface.co/OpenVINO/gpt-oss-20b-int4-ov - Continue Docs: How to Set Up Edit Models
https://docs.continue.dev/ide-extensions/edit/model-setup - Continue Docs: How Agent Mode Works
https://docs.continue.dev/ide-extensions/agent/how-it-works - Qwen/Qwen3-Coder-30B-A3B-Instruct
https://huggingface.co/Qwen/Qwen3-Coder-30B-A3B-Instruct
まとめ
Intel iGPU + OpenVINO でも、Qwen3 系のローカルLLMで C 言語コード生成とテスト通過までは十分狙えました。
一方で、モデルサイズが大きくなるほど単純に万能になるのではなく、周辺確認、複数ファイル整合、CMake 理解といった「見に行く力」の差がかなり効きました。
今回の環境では、軽さの 8B、バランスの 14B、全体把握の 30B coder という使い分けが最も納得しやすい結果でした。
- 最初の1本は Qwen3-8B-int4-ov が無難
- CMake や複数ファイル整合まで見たいなら Qwen3-Coder-30B が有力
- ローカルLLMの価値はコード生成だけでなく、CLI オーケストレータ的な逐次判断にも広がる
C言語の土台を固める
新・明解C言語 入門編 第2版
配列、関数、ポインタ、構造体、ファイル処理まで基礎を丁寧に押さえるタイプ。
「ローカルLLMが生成したCコードを自分で検証したい」層には最初の1冊としてかなり合う。
C言語 ポインタ完全制覇
リングバッファ、バッファ境界、配列・ポインタの扱いみたいな、Cで事故りやすい場所をちゃんと理解したい人向け。
LLMが吐いたCコードの危なさを見抜く力をつけたいなら効く。
新・明解C言語 実践編 第2版
型変換、ライブラリ開発、文字列処理、汎用ライブラリ、ファイル活用など、実装を“プロジェクトとして成立させる”方向に進める本。
こんな読者に向く。
「8B/14B/30B の出力差を見る前に、自分のC力を底上げしたい」「LLMのコードを鵜呑みにしたくない」人向け。
CMake / CTest / ビルドを固める
Professional CMake: A Practical Guide
定番。CMakeの基本だけでなく、テスト、インストール、パッケージング、他プロジェクト連携、ビルド性能改善まで含む。enable_testing() や add_test() の理解を深めるならかなり直球。最新版が継続更新されているのも強い。
Mastering CMake
Kitware系の本で、CMakeコードの書き方、既存プロジェクトの移行、CTest / CPack / CDash まで体系的に見られる。
CMakeを単なるビルドコマンドではなく、開発フロー全体の基盤として理解したい人向け。
CMake Cookbook
レシピ形式で、バイナリ・ライブラリの構成、外部ライブラリ連携、テスト、モジュール化まで具体例で追える。
「とにかく手を動かして build / test を通したい」人には読みやすい。
こんな読者に向く。
「モデル比較より、まずCMakeLists.txtが壊れないことのほうが大事」「Continueに任せた生成物を人間が最終調整する役割が多い」人向け。
LLMをコードアシスタントとして使いこなす
LLMのプロンプトエンジニアリング
Copilotの開発者による本で、LLMの特性理解、プロンプト設計、評価、設計判断まで扱う。
「対象ファイル、API名、禁止事項、PowerShell 5.1 制約を先に固定して安定化する」発想にかなり近い。
実践 LLMアプリケーション開発
モデルの限界、活用パターン、推論最適化、RAGまで含めて、PoCから実装へ進むための本。
「次はどんな検証軸を置くか」を考えるのに向いている。
AIエンジニアリング
生成AIアプリの設計・構築・運用を体系化した本で、RAG、エージェント、ワークフロー、評価、セキュリティ、ガバナンスまで広い。記事の後半で見えている「30Bを対話相手というよりオーケストレータとして見る」視点を深めやすい。
こんな読者に向く。
「どのモデルが速いか」より、「どういう指示設計だとローカルLLMが破綻しにくいか」を掘りたい人向け。
生成AIを開発プロセスへ組み込む
生成AIによるソフトウェア開発
要求、設計、実装、テスト、評価、エージェントによる自動化、マネジメントまでを一冊で見られる。「モデル比較」で終わらせず、開発工程全体の話に広げたいときにちょうどいい。
機械学習システムデザイン
LLM専用本ではないけれど、実運用の設計、反復、信頼性、拡張性、保守性をどう考えるかを学ぶのに向く。ローカル推論基盤やモデル切り替えを、単発実験ではなく“運用設計”として見る助けになる。
MLOps実装ガイド
データ取り込み、CI/CD、デプロイ、監視、ガバナンスまで、本番運用寄りの観点が強い。OpenVINO/OVMSを継続利用する道筋まで視野に入れるなら相性がいい。
こんな読者に向く。
「記事を読んで終わり」ではなく、「チーム内の検証フローやローカルAI基盤に落としたい」人向け。
OpenVINO寄りで読みたい人向けの補足
OpenVINO Inference and Deployment Techniques
OpenVINOのアーキテクチャ、対応フレームワーク、変換、量子化、圧縮、デプロイまでを扱う英語書籍。この記事の中心テーマにかなり近いが、日本語書籍ではなく英語本になる。
これはこんな人に向く。
「Qwen3 / gpt-oss 比較までは分かったので、次は OpenVINO 側の最適化や配備そのものを深掘りしたい」人向け。
迷ったらこの順で買うと外しにくい
- Cの実装を見抜く力をつけたいなら
新・明解C言語 入門編 → 新・明解C言語 実践編 → C言語 ポインタ完全制覇 - この記事の再現性を上げたいなら
Professional CMake → Mastering CMake - ローカルLLM活用を一段上に持っていきたいなら
LLMのプロンプトエンジニアリング → AIエンジニアリング → 実践 LLMアプリケーション開発 - チーム導入や継続運用まで見たいなら
生成AIによるソフトウェア開発 → MLOps実装ガイド


コメント