From 18eb98abc04a1a0db1325d16989830d26e5ae5f0 Mon Sep 17 00:00:00 2001 From: Luis A Lastras Date: Sat, 9 May 2026 23:11:41 -0400 Subject: [PATCH 01/10] Add interactive adapter catalog with compose cart Adds docs/adapter_catalog.html: a self-contained interactive page covering all 12 Granite Library adapters (RAG, Core, Guardian). Each adapter shows a description, flavor badges (LoRA/aLoRA), pipeline stage, and a grouped bar chart comparing prompted baselines, LoRA, and aLoRA adapters across all four model sizes, with dashed reference lines for external models (GPT-4o, GPT-OSS-120B) where benchmarked. Also adds a composition cart: users select adapters, choose a base model size, and get a ready-to-run compose_granite_switch command using --include-adapters to target exactly the selected adapters. The URL hash reflects the current adapter selection, making individual adapter views directly linkable (e.g. #hallucination-detection). Updates README.md to link to the catalog (landing on hallucination detection) from the Accurate bullet point. --- README.md | 2 +- docs/adapter_catalog.html | 956 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 957 insertions(+), 1 deletion(-) create mode 100644 docs/adapter_catalog.html diff --git a/README.md b/README.md index f8247f7..c8cf69c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Browse the full set of ready-to-use adapters in the [Granite Libraries collectio - **Composable** — Combine independently trained adapters into one checkpoint, whether IBM's or yours. Swap, upgrade, or customize without retraining. - **Fast** — Built on IBM's Activated LoRA technology for efficient KV cache reuse, low latency, and high inference throughput. -- **Accurate** — Task-specific adapters can match and even surpass the accuracy of significantly larger generalist models, while requiring only a fraction of the serving cost. For concrete benchmark example, see the [Hallucination Detection](https://huggingface.co/ibm-granite/granitelib-rag-r1.0/blob/main/hallucination_detection/README.md#evaluation) from the RAG adapter library. +- **Accurate** — Task-specific adapters can match and even surpass the accuracy of significantly larger generalist models, while requiring only a fraction of the serving cost. See the [adapter catalog](https://ibm-granite.github.io/granite-switch/adapter_catalog.html#hallucination-detection) for benchmark comparisons across all 12 adapters. - **Inference-ready** — Support for Hugging Face and vLLM. ## Quick Start diff --git a/docs/adapter_catalog.html b/docs/adapter_catalog.html new file mode 100644 index 0000000..96ae174 --- /dev/null +++ b/docs/adapter_catalog.html @@ -0,0 +1,956 @@ + + + + + + Granite Libraries — Adapter Catalog + + + + +
+
+

Granite Libraries — Adapter Catalog

+

12 fine-tuned LoRA / aLoRA adapters for IBM Granite 4.x models

+
+ +
+ + +
+ +
+ + +
+
+ + Composition + + +
+
+
+
+ + + + From 7a8d9e525da81b2bfc6fbb57b24b7ebdba1b21b3 Mon Sep 17 00:00:00 2001 From: Luis A Lastras Date: Sat, 9 May 2026 23:19:47 -0400 Subject: [PATCH 02/10] Fix GitHub Pages URL to use generative-computing org --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c8cf69c..4afe020 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Browse the full set of ready-to-use adapters in the [Granite Libraries collectio - **Composable** — Combine independently trained adapters into one checkpoint, whether IBM's or yours. Swap, upgrade, or customize without retraining. - **Fast** — Built on IBM's Activated LoRA technology for efficient KV cache reuse, low latency, and high inference throughput. -- **Accurate** — Task-specific adapters can match and even surpass the accuracy of significantly larger generalist models, while requiring only a fraction of the serving cost. See the [adapter catalog](https://ibm-granite.github.io/granite-switch/adapter_catalog.html#hallucination-detection) for benchmark comparisons across all 12 adapters. +- **Accurate** — Task-specific adapters can match and even surpass the accuracy of significantly larger generalist models, while requiring only a fraction of the serving cost. See the [adapter catalog](https://generative-computing.github.io/granite-switch/adapter_catalog.html#hallucination-detection) for benchmark comparisons across all 12 adapters. - **Inference-ready** — Support for Hugging Face and vLLM. ## Quick Start From 892e5525cdd81e2b09bed1183d886a7ae4ca7a09 Mon Sep 17 00:00:00 2001 From: Luis A Lastras Date: Sun, 10 May 2026 08:01:56 -0400 Subject: [PATCH 03/10] Add build type toggle (prefer aLoRA vs all LoRAs) to compose cart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cart now exposes a two-button toggle alongside the base model selector: Prefer aLoRA — default; aLoRA wins when both variants exist (no extra CLI flag needed, this is the default discovery behavior) All LoRAs — adds --technology-filter lora to the generated command, so only LoRA variants are selected even when an aLoRA counterpart is present --- docs/adapter_catalog.html | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/docs/adapter_catalog.html b/docs/adapter_catalog.html index 96ae174..34460ef 100644 --- a/docs/adapter_catalog.html +++ b/docs/adapter_catalog.html @@ -680,7 +680,8 @@

Granite Libraries — Adapter Catalog

// ── State ───────────────────────────────────────────────────────────────────── let chart = null; let cart = new Set(); -let selectedModel = 'ibm-granite/granite-4.1-3b'; // default +let selectedModel = 'ibm-granite/granite-4.1-3b'; // default +let selectedBuildType = 'prefer-alora'; // 'prefer-alora' | 'all-lora' // ── Cart ────────────────────────────────────────────────────────────────────── @@ -719,6 +720,11 @@

Granite Libraries — Adapter Catalog

renderCart(); } +function setBuildType(type) { + selectedBuildType = type; + renderCart(); +} + function generateCommand() { if (cart.size === 0) return null; @@ -746,6 +752,9 @@

Granite Libraries — Adapter Catalog

if (!allSelected) { lines.push(` --include-adapters ${includeNames.join(' ')} \\`); } + if (selectedBuildType === 'all-lora') { + lines.push(' --technology-filter lora \\'); + } lines.push(' --output ./my-model'); return lines.join('\n'); @@ -797,6 +806,15 @@

Granite Libraries — Adapter Catalog

onclick="setModel('${hfId}')">${label}` ).join(''); + // Build type buttons + const buildTypeBtnsHtml = [ + { value: 'prefer-alora', label: 'Prefer aLoRA' }, + { value: 'all-lora', label: 'All LoRAs' }, + ].map(opt => + `` + ).join(''); + // Command const cmd = generateCommand(); @@ -806,6 +824,10 @@

Granite Libraries — Adapter Catalog

Base model
${modelBtnsHtml}
+
+ Build type +
${buildTypeBtnsHtml}
+
${cmd}
@@ -367,6 +219,10 @@

Granite Libraries — Adapter Catalog

'4.1-30B': 'ibm-granite/granite-4.1-30b', }; +// Carbon tag type mappings +const LIB_TAG = { RAG: 'blue', Core: 'purple', Guardian: 'teal' }; +const FLAV_TAG = { lora: 'cool-gray', alora: 'green' }; + // ── Adapter data ────────────────────────────────────────────────────────────── // // adapterName: the directory name used with --include-adapters in the CLI. @@ -680,18 +536,18 @@

Granite Libraries — Adapter Catalog

// ── State ───────────────────────────────────────────────────────────────────── let chart = null; let cart = new Set(); -let selectedModel = 'ibm-granite/granite-4.1-3b'; // default -let selectedBuildType = 'prefer-alora'; // 'prefer-alora' | 'all-lora' +let currentId = 'query-rewrite'; +let selectedModel = 'ibm-granite/granite-4.1-3b'; +let selectedBuildType = 'prefer-alora'; // ── Cart ────────────────────────────────────────────────────────────────────── function toggleCart(id) { cart.has(id) ? cart.delete(id) : cart.add(id); - // Update the add button in place — no chart re-render needed. const btn = document.getElementById('add-btn'); if (btn) { const inCart = cart.has(id); - btn.className = 'add-btn' + (inCart ? ' in-cart' : ''); + btn.setAttribute('kind', inCart ? 'primary' : 'tertiary'); btn.textContent = inCart ? '✓ Added' : '+ Add to composition'; } renderCart(); @@ -699,10 +555,9 @@

Granite Libraries — Adapter Catalog

function removeFromCart(id) { cart.delete(id); - // Sync add button if this adapter is currently displayed. const btn = document.getElementById('add-btn'); - if (btn && sel.value === id) { - btn.className = 'add-btn'; + if (btn && currentId === id) { + btn.setAttribute('kind', 'tertiary'); btn.textContent = '+ Add to composition'; } renderCart(); @@ -711,7 +566,10 @@

Granite Libraries — Adapter Catalog

function clearCart() { cart.clear(); const btn = document.getElementById('add-btn'); - if (btn) { btn.className = 'add-btn'; btn.textContent = '+ Add to composition'; } + if (btn) { + btn.setAttribute('kind', 'tertiary'); + btn.textContent = '+ Add to composition'; + } renderCart(); } @@ -760,23 +618,21 @@

Granite Libraries — Adapter Catalog

return lines.join('\n'); } -function copyCommand() { - const cmd = generateCommand(); - if (!cmd) return; - navigator.clipboard.writeText(cmd).then(() => { - const btn = document.querySelector('.copy-btn'); - if (!btn) return; - btn.textContent = 'Copied!'; - btn.className = 'copy-btn copied'; - setTimeout(() => { btn.textContent = 'Copy'; btn.className = 'copy-btn'; }, 2000); +function attachCartListeners() { + const modelSw = document.querySelector('cds-content-switcher[data-role="model"]'); + modelSw?.addEventListener('cds-content-switcher-item-selected', e => { + setModel(e.detail.item.value); + }); + const buildSw = document.querySelector('cds-content-switcher[data-role="build"]'); + buildSw?.addEventListener('cds-content-switcher-item-selected', e => { + setBuildType(e.detail.item.value); }); } function renderCart() { - // Update header count and clear button visibility. - const countEl = document.getElementById('cart-count'); - const clearBtn = document.getElementById('cart-clear-btn'); - const bodyEl = document.getElementById('cart-body'); + const countEl = document.getElementById('cart-count'); + const clearBtn = document.getElementById('cart-clear-btn'); + const bodyEl = document.getElementById('cart-body'); if (countEl) countEl.textContent = cart.size > 0 ? ` (${cart.size})` : ''; if (clearBtn) clearBtn.style.display = cart.size > 0 ? '' : 'none'; @@ -788,31 +644,28 @@

Granite Libraries — Adapter Catalog

} // Adapter list - const libClass = { RAG: 'badge-rag', Core: 'badge-core', Guardian: 'badge-guardian' }; const itemsHtml = Object.keys(ADAPTERS) .filter(id => cart.has(id)) .map(id => { const a = ADAPTERS[id]; return `
- ${a.library} + ${a.library} ${a.name} - +
`; }).join(''); - // Model selector buttons - const modelBtnsHtml = Object.entries(MODEL_IDS).map(([label, hfId]) => - `` + // Model content-switcher + const modelItemsHtml = Object.entries(MODEL_IDS).map(([label, hfId]) => + `${label}` ).join(''); - // Build type buttons - const buildTypeBtnsHtml = [ + // Build type content-switcher + const buildItemsHtml = [ { value: 'prefer-alora', label: 'Prefer aLoRA' }, { value: 'all-lora', label: 'All LoRAs' }, ].map(opt => - `` + `${opt.label}` ).join(''); // Command @@ -820,50 +673,49 @@

Granite Libraries — Adapter Catalog

bodyEl.innerHTML = `
${itemsHtml}
-
- Base model -
${modelBtnsHtml}
+
+ Base model + ${modelItemsHtml}
-
- Build type -
${buildTypeBtnsHtml}
+
+ Build type + ${buildItemsHtml}
-
${cmd}
- + ${cmd}
`; + + attachCartListeners(); } // ── Adapter panel ───────────────────────────────────────────────────────────── function render(id) { + currentId = id; const a = ADAPTERS[id]; if (!a) return; - const libClass = { RAG: 'badge-rag', Core: 'badge-core', Guardian: 'badge-guardian' }[a.library]; - const inCart = cart.has(id); + const inCart = cart.has(id); const flavorHtml = a.flavors - .map(f => `${f === 'lora' ? 'LoRA' : 'aLoRA'}`) + .map(f => `${f === 'lora' ? 'LoRA' : 'aLoRA'}`) .join(''); document.getElementById('panel').innerHTML = `

${a.name}

- Adapter README ↗ - +
- ${a.library} Library - ${a.stage} + ${a.library} Library + ${a.stage} ${flavorHtml}

${a.description}

@@ -963,15 +815,19 @@

${a.name}

// ── Init ────────────────────────────────────────────────────────────────────── const sel = document.getElementById('adapter-select'); -sel.addEventListener('change', e => { - history.replaceState(null, '', '#' + e.target.value); - render(e.target.value); +sel.addEventListener('cds-select-changed', e => { + const val = e.detail.value; + history.replaceState(null, '', '#' + val); + render(val); }); const initial = window.location.hash.slice(1); -if (initial && ADAPTERS[initial]) sel.value = initial; +if (initial && ADAPTERS[initial]) { + sel.setAttribute('value', initial); + currentId = initial; +} -render(sel.value); +render(currentId); renderCart(); From 927cb240652e654663be063287b7acc5d5206c31 Mon Sep 17 00:00:00 2001 From: Luis A Lastras Date: Sun, 10 May 2026 09:06:39 -0400 Subject: [PATCH 05/10] Fix Carbon Web Components rendering: add styles CSS, drop tag size=sm Two fixes: - Add @carbon/styles@1 CSS from unpkg before the custom @@ -165,7 +213,7 @@

Granite Libraries — Adapter Catalog

- + Query Rewrite Query Clarification @@ -220,9 +268,9 @@

Granite Libraries — Adapter Catalog

'4.1-30B': 'ibm-granite/granite-4.1-30b', }; -// Carbon tag type mappings -const LIB_TAG = { RAG: 'blue', Core: 'purple', Guardian: 'teal' }; -const FLAV_TAG = { lora: 'cool-gray', alora: 'green' }; +// Badge CSS-class mappings (custom spans — cds-tag has a fixed internal max-width) +const LIB_BADGE = { RAG: 'badge-blue', Core: 'badge-purple', Guardian: 'badge-teal' }; +const FLAV_BADGE = { lora: 'badge-cool-gray', alora: 'badge-green' }; // ── Adapter data ────────────────────────────────────────────────────────────── // @@ -619,6 +667,18 @@

Granite Libraries — Adapter Catalog

return lines.join('\n'); } +function copyCommand() { + const cmd = generateCommand(); + if (!cmd) return; + navigator.clipboard.writeText(cmd).then(() => { + const btn = document.querySelector('.copy-btn'); + if (!btn) return; + btn.textContent = 'Copied!'; + btn.classList.add('copied'); + setTimeout(() => { btn.textContent = 'Copy'; btn.classList.remove('copied'); }, 2000); + }); +} + function attachCartListeners() { const modelSw = document.querySelector('cds-content-switcher[data-role="model"]'); modelSw?.addEventListener('cds-content-switcher-item-selected', e => { @@ -650,15 +710,17 @@

Granite Libraries — Adapter Catalog

.map(id => { const a = ADAPTERS[id]; return `
- ${a.library} + ${a.library} ${a.name}
`; }).join(''); - // Model content-switcher + // Model content-switcher — value on parent controls the highlighted item; + // onclick on each item is the primary interaction handler (more reliable than + // waiting for cds-content-switcher-item-selected after an innerHTML rebuild). const modelItemsHtml = Object.entries(MODEL_IDS).map(([label, hfId]) => - `${label}` + `${label}` ).join(''); // Build type content-switcher @@ -666,7 +728,7 @@

Granite Libraries — Adapter Catalog

{ value: 'prefer-alora', label: 'Prefer aLoRA' }, { value: 'all-lora', label: 'All LoRAs' }, ].map(opt => - `${opt.label}` + `${opt.label}` ).join(''); // Command @@ -676,14 +738,17 @@

Granite Libraries — Adapter Catalog

${itemsHtml}
Base model - ${modelItemsHtml} + ${modelItemsHtml}
Build type - ${buildItemsHtml} + ${buildItemsHtml}
- ${cmd} +
${cmd}
+
`; @@ -700,7 +765,7 @@

Granite Libraries — Adapter Catalog

const inCart = cart.has(id); const flavorHtml = a.flavors - .map(f => `${f === 'lora' ? 'LoRA' : 'aLoRA'}`) + .map(f => `${f === 'lora' ? 'LoRA' : 'aLoRA'}`) .join(''); document.getElementById('panel').innerHTML = ` @@ -714,8 +779,8 @@

${a.name}

- ${a.library} Library - ${a.stage} + ${a.library} Library + ${a.stage} ${flavorHtml}

${a.description}

@@ -815,16 +880,25 @@

${a.name}

// ── Init ────────────────────────────────────────────────────────────────────── const sel = document.getElementById('adapter-select'); -sel.addEventListener('cds-select-changed', e => { - const val = e.detail.value; +// Deduplicate: cds-select-changed and the native change event may both fire. +let _lastRenderedId = null; +function handleSelectChange(val) { + if (!val || !ADAPTERS[val] || val === _lastRenderedId) return; + _lastRenderedId = val; + currentId = val; history.replaceState(null, '', '#' + val); render(val); -}); +} + +sel.addEventListener('cds-select-changed', e => handleSelectChange(e.detail?.value || e.detail)); +sel.addEventListener('change', e => handleSelectChange(sel.value)); const initial = window.location.hash.slice(1); if (initial && ADAPTERS[initial]) { sel.setAttribute('value', initial); currentId = initial; + // Also set after cds-select upgrades (module scripts are deferred) + customElements.whenDefined('cds-select').then(() => { sel.value = initial; }); } render(currentId); From 2d867806ee26ecc353947fa1ee0b8a1f8a9c6a3c Mon Sep 17 00:00:00 2001 From: Luis A Lastras Date: Sun, 10 May 2026 11:34:23 -0400 Subject: [PATCH 07/10] Fix dropdown interaction and reorder chart datasets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dropdown: replace cds-select (unreliable custom event) with a native + + + + + + + + + + + + + + + + + + + + +
+
@@ -800,24 +808,11 @@

${a.name}

const n = a.models.length; const datasets = []; - if (a.prompted) { - datasets.push({ - type: 'bar', label: 'Prompted (zero-shot)', data: a.prompted, - backgroundColor: C.prompted.bg, borderColor: C.prompted.border, borderWidth: 1, order: 3, - }); - } - - datasets.push({ - type: 'bar', label: 'LoRA adapter', data: a.lora, - backgroundColor: C.lora.bg, borderColor: C.lora.border, borderWidth: 1, order: 2, - }); - - if (a.alora) { - datasets.push({ - type: 'bar', label: 'aLoRA adapter', data: a.alora, - backgroundColor: C.alora.bg, borderColor: C.alora.border, borderWidth: 1, order: 2, - }); - } + // Group order (left → right within each bar group): + // 1. Non-IBM baselines: external bar + reference lines + // 2. Prompted (IBM model, no adapter) + // 3. aLoRA adapter + // 4. LoRA adapter if (a.externalBar) { datasets.push({ @@ -827,8 +822,8 @@

${a.name}

}); } - // Flat horizontal reference lines via a hidden non-offset x-axis so they - // span the full chart width (not just center-to-center of bar groups). + // Flat horizontal reference lines span the full chart width via a hidden + // non-offset x-axis. order: 1 keeps them rendered on top of the bars. (a.external || []).forEach(ext => { datasets.push({ type: 'line', xAxisID: 'x2', label: ext.label, @@ -838,6 +833,25 @@

${a.name}

}); }); + if (a.prompted) { + datasets.push({ + type: 'bar', label: 'Prompted (zero-shot)', data: a.prompted, + backgroundColor: C.prompted.bg, borderColor: C.prompted.border, borderWidth: 1, order: 3, + }); + } + + if (a.alora) { + datasets.push({ + type: 'bar', label: 'aLoRA adapter', data: a.alora, + backgroundColor: C.alora.bg, borderColor: C.alora.border, borderWidth: 1, order: 2, + }); + } + + datasets.push({ + type: 'bar', label: 'LoRA adapter', data: a.lora, + backgroundColor: C.lora.bg, borderColor: C.lora.border, borderWidth: 1, order: 2, + }); + chart = new Chart(ctx, { type: 'bar', data: { labels: a.models, datasets }, @@ -880,25 +894,18 @@

${a.name}

// ── Init ────────────────────────────────────────────────────────────────────── const sel = document.getElementById('adapter-select'); -// Deduplicate: cds-select-changed and the native change event may both fire. -let _lastRenderedId = null; -function handleSelectChange(val) { - if (!val || !ADAPTERS[val] || val === _lastRenderedId) return; - _lastRenderedId = val; +sel.addEventListener('change', () => { + const val = sel.value; + if (!val || !ADAPTERS[val]) return; currentId = val; history.replaceState(null, '', '#' + val); render(val); -} - -sel.addEventListener('cds-select-changed', e => handleSelectChange(e.detail?.value || e.detail)); -sel.addEventListener('change', e => handleSelectChange(sel.value)); +}); const initial = window.location.hash.slice(1); if (initial && ADAPTERS[initial]) { - sel.setAttribute('value', initial); + sel.value = initial; currentId = initial; - // Also set after cds-select upgrades (module scripts are deferred) - customElements.whenDefined('cds-select').then(() => { sel.value = initial; }); } render(currentId); From 1ade1fe67068d2116915423d914f22de47e9aec7 Mon Sep 17 00:00:00 2001 From: Luis A Lastras Date: Sun, 10 May 2026 11:41:42 -0400 Subject: [PATCH 08/10] Remove oversized SVG arrow from native select The cds--select__arrow SVG was rendering at full unconstrained size due to our CSS reset interfering with Carbon's absolute positioning. The native - @@ -808,48 +804,51 @@

${a.name}

const n = a.models.length; const datasets = []; - // Group order (left → right within each bar group): - // 1. Non-IBM baselines: external bar + reference lines - // 2. Prompted (IBM model, no adapter) - // 3. aLoRA adapter - // 4. LoRA adapter + // Chart.js sorts datasets by `order` (ascending) to assign left-to-right + // bar positions within each group. Assign sequential order values so the + // bar-slot position matches the desired visual sequence: + // order 1 → external baseline bar (leftmost) + // order 2 → Prompted (IBM zero-shot) + // order 3 → aLoRA adapter + // order 4 → LoRA adapter (rightmost) + // order 9 → reference lines (rendered last = drawn on top of bars) if (a.externalBar) { datasets.push({ type: 'bar', label: a.externalBar.label, data: a.externalBar.data, backgroundColor: hexToRgba(a.externalBar.color, 0.45), - borderColor: a.externalBar.color, borderWidth: 1, order: 3, + borderColor: a.externalBar.color, borderWidth: 1, order: 1, }); } - // Flat horizontal reference lines span the full chart width via a hidden - // non-offset x-axis. order: 1 keeps them rendered on top of the bars. - (a.external || []).forEach(ext => { - datasets.push({ - type: 'line', xAxisID: 'x2', label: ext.label, - data: Array(n).fill(ext.value), - borderColor: ext.color, borderWidth: 2, borderDash: [7, 4], - pointRadius: 0, pointHoverRadius: 0, fill: false, order: 1, - }); - }); - if (a.prompted) { datasets.push({ type: 'bar', label: 'Prompted (zero-shot)', data: a.prompted, - backgroundColor: C.prompted.bg, borderColor: C.prompted.border, borderWidth: 1, order: 3, + backgroundColor: C.prompted.bg, borderColor: C.prompted.border, borderWidth: 1, order: 2, }); } if (a.alora) { datasets.push({ type: 'bar', label: 'aLoRA adapter', data: a.alora, - backgroundColor: C.alora.bg, borderColor: C.alora.border, borderWidth: 1, order: 2, + backgroundColor: C.alora.bg, borderColor: C.alora.border, borderWidth: 1, order: 3, }); } datasets.push({ type: 'bar', label: 'LoRA adapter', data: a.lora, - backgroundColor: C.lora.bg, borderColor: C.lora.border, borderWidth: 1, order: 2, + backgroundColor: C.lora.bg, borderColor: C.lora.border, borderWidth: 1, order: 4, + }); + + // Flat horizontal reference lines span the full chart width via a hidden + // non-offset x-axis. order: 9 renders them last so they appear on top. + (a.external || []).forEach(ext => { + datasets.push({ + type: 'line', xAxisID: 'x2', label: ext.label, + data: Array(n).fill(ext.value), + borderColor: ext.color, borderWidth: 2, borderDash: [7, 4], + pointRadius: 0, pointHoverRadius: 0, fill: false, order: 9, + }); }); chart = new Chart(ctx, { From 6530dd45c7f3b070ffb13f8bca13d9bbb1268fe7 Mon Sep 17 00:00:00 2001 From: Luis A Lastras Date: Sun, 10 May 2026 11:43:51 -0400 Subject: [PATCH 09/10] Retitle page to emphasize composer role --- docs/adapter_catalog.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/adapter_catalog.html b/docs/adapter_catalog.html index 90087c7..6404cfd 100644 --- a/docs/adapter_catalog.html +++ b/docs/adapter_catalog.html @@ -3,7 +3,7 @@ - Granite Libraries — Adapter Catalog + Granite Switch — Adapter Composer @@ -207,8 +207,8 @@
-

Granite Libraries — Adapter Catalog

-

12 fine-tuned LoRA / aLoRA adapters for IBM Granite 4.x models

+

Granite Switch — Adapter Composer

+

Browse the 12 Granite Libraries adapters, compare benchmarks, and generate your compose_granite_switch command.

From 4487e289bd069b434223706c8d295be195806669 Mon Sep 17 00:00:00 2001 From: Luis A Lastras Date: Sun, 10 May 2026 11:48:10 -0400 Subject: [PATCH 10/10] Add Adapter Composer link to README compose section Points readers to the interactive adapter catalog page where they can browse adapters, compare benchmarks, and generate a compose command. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4afe020..a070955 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ python -m granite_switch.composer.compose_granite_switch \ --output ./my-model ``` +Use the **[Adapter Composer](https://generative-computing.github.io/granite-switch/adapter_catalog.html)** to browse available adapters, compare benchmarks, and generate a ready-to-run compose command. + This downloads the base model, embeds compatible LoRA adapters (with a preference towards activated LoRA), adds control tokens and a chat template, and produces a model directory that works with both HuggingFace and vLLM. For convenience, you can find already composed Granite Switch models for the Granite 4.1 model family here: