-
Notifications
You must be signed in to change notification settings - Fork 544
docs: add announcements landing page #1971
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5a65c03
aa8b97c
e1cac48
337dc44
5e93042
bc12fad
8210c3b
139452e
231b20b
485356b
7713d5f
238ad0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to also require a ModelOpt commit hash / version and container used in case of tutorial blogs / experimental results?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that will be a next step. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| # Technical blog review guideline | ||
|
|
||
| Use this rubric when a pull-request comment requests a **technical blog** or | ||
| **technical announcement** review. It applies to public-facing documentation | ||
| such as `docs/source/announcements/` and complements the repository's normal | ||
| code-review guidance. | ||
|
|
||
| ## Review scope | ||
|
|
||
| Review the changed announcement and its landing-page card together. Do not | ||
| review unrelated source files unless they provide evidence for a claim in the | ||
| post. | ||
|
|
||
| ## Checks | ||
|
|
||
| 1. **Factual support** — Every technical claim, performance number, and | ||
| comparison must be supported by a cited public source, a clearly identified | ||
| reproducible measurement, or a qualified statement. Flag claims that | ||
| overstate what the cited source establishes. | ||
| 2. **Citation integrity** — Check that cited papers, repositories, checkpoints, | ||
| and issue or PR links exist and match the surrounding claim. Publication | ||
| dates must not precede the cited source's availability. | ||
| 3. **Technical precision** — Preserve meaningful distinctions: measured versus | ||
| inferred results, training versus serving behavior, throughput versus | ||
| latency, architecture versus implementation detail, and public facts versus | ||
| internal context. | ||
| 4. **Figure provenance** — Images need an accurate alt text and a source or | ||
| provenance that makes their public use appropriate. Captions and nearby | ||
| text must not imply a result the figure does not show. | ||
| 5. **Public-release suitability** — Do not expose private infrastructure, | ||
| unreleased products, confidential benchmark data, credentials, internal | ||
| URLs, or claims that cannot be independently supported by public material. | ||
| 6. **Reader clarity** — Verify the title, date, author, summary, tags, and | ||
| announcement-card metadata agree. Prefer precise terminology over marketing | ||
| shorthand when the two could be confused. | ||
|
|
||
| ## Findings | ||
|
|
||
| Raise only material findings. Each finding should identify the exact claim, | ||
| explain the public-facing risk, and propose a concrete correction. Do not | ||
| duplicate routine style, spelling, or formatting feedback already handled by | ||
| CodeRabbit. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| /* Scoped announcement styles for the Sphinx RTD theme. */ | ||
|
|
||
| #announcements > h1, | ||
| #announcements > p, | ||
| .announcement-section { | ||
| max-width: 860px; | ||
| margin-left: auto; | ||
| margin-right: auto; | ||
| } | ||
|
|
||
| .announcement-section { | ||
| width: 100%; | ||
| } | ||
|
|
||
| .announcement-toolbar { | ||
| border: 1px solid #d6d8dc; | ||
| border-radius: 4px; | ||
| margin: 1.5rem 0; | ||
| padding: 1rem; | ||
| background: #f8f9fb; | ||
| } | ||
|
|
||
| .announcement-search-label { | ||
| display: block; | ||
| font-weight: 700; | ||
| margin-bottom: 0.35rem; | ||
| } | ||
|
|
||
| .announcement-search { | ||
| box-sizing: border-box; | ||
| width: 100%; | ||
| padding: 0.55rem 0.65rem; | ||
| border: 1px solid #b8bdc6; | ||
| border-radius: 4px; | ||
| font-size: 1rem; | ||
| } | ||
|
|
||
| .announcement-tags { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 0.45rem; | ||
| margin-top: 0.75rem; | ||
| } | ||
|
|
||
| .announcement-tag { | ||
| border: 1px solid #9aa1ad; | ||
| border-radius: 999px; | ||
| padding: 0.28rem 0.65rem; | ||
| background: #fff; | ||
| color: #2f343d; | ||
| cursor: pointer; | ||
| font-size: 0.86rem; | ||
| } | ||
|
|
||
| .announcement-tag.is-active, | ||
| .announcement-tag:hover { | ||
| border-color: #76b900; | ||
| background: #76b900; | ||
| color: #111; | ||
| } | ||
|
|
||
| .announcement-grid { | ||
| display: grid; | ||
| grid-template-columns: minmax(0, 1fr); | ||
| gap: 1rem; | ||
| margin: 1rem 0 1.25rem; | ||
| } | ||
|
|
||
| .announcement-card { | ||
| border-bottom: 1px solid #d6d8dc; | ||
| padding: 0 0 1rem; | ||
| } | ||
|
|
||
| .announcement-card:last-child { | ||
| border-bottom: 0; | ||
| } | ||
|
|
||
| .announcement-card h2 { | ||
| margin-top: 0.25rem; | ||
| font-size: 1.2rem; | ||
| line-height: 1.35; | ||
| } | ||
|
|
||
| .announcement-card p { | ||
| margin-bottom: 0.75rem; | ||
| } | ||
|
|
||
| .announcement-card-meta { | ||
| color: #6b7280; | ||
| font-size: 0.85rem; | ||
| } | ||
|
|
||
| .announcement-card-tags { | ||
| display: flex; | ||
| flex-wrap: wrap; | ||
| gap: 0.35rem; | ||
| } | ||
|
|
||
| .announcement-card-tags span { | ||
| border: 1px solid #d6d8dc; | ||
| border-radius: 999px; | ||
| color: #4b5563; | ||
| font-size: 0.78rem; | ||
| padding: 0.15rem 0.45rem; | ||
| } | ||
|
|
||
| .announcement-empty { | ||
| border-left: 4px solid #76b900; | ||
| padding-left: 0.75rem; | ||
| } | ||
|
|
||
|
|
||
| .announcement-pager { | ||
| align-items: center; | ||
| display: flex; | ||
| gap: 0.75rem; | ||
| justify-content: flex-end; | ||
| margin: 0 0 2rem; | ||
| } | ||
|
|
||
| .announcement-page-button { | ||
| border: 1px solid #9aa1ad; | ||
| border-radius: 4px; | ||
| background: #fff; | ||
| color: #2f343d; | ||
| cursor: pointer; | ||
| padding: 0.35rem 0.7rem; | ||
| } | ||
|
|
||
| .announcement-page-button:disabled { | ||
| cursor: not-allowed; | ||
| opacity: 0.45; | ||
| } | ||
|
|
||
| .announcement-page-status { | ||
| color: #4b5563; | ||
| font-size: 0.9rem; | ||
| } | ||
|
|
||
| .toctree-wrapper.compound:empty { | ||
| display: none; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| document.addEventListener('DOMContentLoaded', () => { | ||
| const search = document.querySelector('#announcement-search'); | ||
| const cards = Array.from(document.querySelectorAll('.announcement-card')).sort((left, right) => { | ||
| return (right.dataset.date || '').localeCompare(left.dataset.date || ''); | ||
| }); | ||
| const tags = Array.from(document.querySelectorAll('.announcement-tag')); | ||
| const empty = document.querySelector('#announcement-empty'); | ||
| const pager = document.querySelector('#announcement-pager'); | ||
| const prev = document.querySelector('#announcement-prev'); | ||
| const next = document.querySelector('#announcement-next'); | ||
| const status = document.querySelector('#announcement-page-status'); | ||
| const pageSize = 5; | ||
|
|
||
| cards.forEach((card) => card.parentNode.appendChild(card)); | ||
| let activeTag = 'all'; | ||
| let currentPage = 1; | ||
|
|
||
| if (!search || cards.length === 0) { | ||
| return; | ||
| } | ||
|
|
||
| const matchingCards = () => { | ||
| const query = search.value.trim().toLowerCase(); | ||
| return cards.filter((card) => { | ||
| const haystack = | ||
| [ card.dataset.title, card.dataset.summary, card.dataset.tags ].join(' ').toLowerCase(); | ||
| const tagMatch = | ||
| activeTag === 'all' || (card.dataset.tags || '').split(' ').includes(activeTag); | ||
| const searchMatch = !query || haystack.includes(query); | ||
| return tagMatch && searchMatch; | ||
| }); | ||
| }; | ||
|
|
||
| const update = () => { | ||
| const matches = matchingCards(); | ||
| const pageCount = Math.max(1, Math.ceil(matches.length / pageSize)); | ||
| currentPage = Math.min(currentPage, pageCount); | ||
| const start = (currentPage - 1) * pageSize; | ||
| const pageCards = new Set(matches.slice(start, start + pageSize)); | ||
|
|
||
| cards.forEach((card) => { card.hidden = !pageCards.has(card); }); | ||
|
|
||
| if (empty) { | ||
| empty.hidden = matches.length !== 0; | ||
| } | ||
|
|
||
| if (pager && prev && next && status) { | ||
| pager.hidden = matches.length <= pageSize; | ||
| prev.disabled = currentPage <= 1; | ||
| next.disabled = currentPage >= pageCount; | ||
| status.textContent = `Page ${currentPage} of ${pageCount}`; | ||
| } | ||
| }; | ||
|
|
||
| tags.forEach((button) => { | ||
| button.addEventListener('click', () => { | ||
| activeTag = button.dataset.tag || 'all'; | ||
| currentPage = 1; | ||
| tags.forEach((tag) => { | ||
| const selected = tag === button; | ||
| tag.classList.toggle('is-active', selected); | ||
| tag.setAttribute('aria-pressed', selected ? 'true' : 'false'); | ||
| }); | ||
| update(); | ||
| }); | ||
| }); | ||
|
|
||
| search.addEventListener('input', () => { | ||
| currentPage = 1; | ||
| update(); | ||
| }); | ||
|
|
||
| if (prev) { | ||
| prev.addEventListener('click', () => { | ||
| currentPage -= 1; | ||
| update(); | ||
| }); | ||
| } | ||
|
|
||
| if (next) { | ||
| next.addEventListener('click', () => { | ||
| currentPage += 1; | ||
| update(); | ||
| }); | ||
| } | ||
|
|
||
| update(); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| :orphan: | ||
|
|
||
| DSpark vs Domino: Same DFlash Backbone, Different Correction Heads | ||
| ################################################################## | ||
|
|
||
| :Author: Model Optimizer Team | ||
| :Date: July 13, 2026 | ||
| :Tags: speculative-decoding, dflash, dspark, domino, architecture | ||
|
|
||
| DSpark (DeepSpec) and Domino both build on block-parallel DFlash draft generation but diverge in their token-level correction heads. DSpark's default head is a stateless first-order Markov transition; Domino's is a GRU that conditions on the draft prefix. Both must unroll sequentially at inference, so the tradeoff is per-step cost against how much prefix context the correction can use. During teacher-forced training, DSpark's Markov transition can also be parallelized over positions. | ||
| See the DSpark and Domino papers in :ref:`dspark-domino-references` for the original method descriptions. | ||
|
|
||
| Highlights | ||
| ********** | ||
|
|
||
| * Both systems share the DFlash block-parallel backbone, so their parallel draft throughput starts from a similar foundation. | ||
| * In ModelOpt, DSpark defaults to ``markov_head_type="vanilla"``: stateless ``W1`` and ``W2`` embedding lookups with no hidden state to thread through. | ||
| * Domino uses ``nn.GRU`` and carries recurrent state across draft positions. | ||
| * Both correction heads are sequential at inference because ``x_{k-1}`` must be sampled before step ``k``. | ||
|
|
||
| Shared Foundation: DFlash Block-Parallel Backbone | ||
| ************************************************* | ||
|
|
||
| Both systems use DFlash: a draft backbone that runs a single causal attention forward pass over all draft positions in parallel, producing per-position hidden states and base draft logits. This is the expensive step; the correction head adds token-level adjustment on top of those outputs. | ||
|
|
||
| Where They Diverge: The Correction Head | ||
| *************************************** | ||
|
|
||
| DSpark uses a first-order Markov transition. For each draft position ``k``: | ||
|
|
||
| .. code-block:: text | ||
|
|
||
| e_{k-1} = W1[x_{k-1}] | ||
| bias_k = W2 * e_{k-1} | ||
| p_k = softmax(U_k + bias_k) | ||
| x_k ~ p_k | ||
|
|
||
| The correction at position ``k`` depends only on ``x_{k-1}``; no RNN hidden state threads across steps. The dominant work is a table lookup and projection rather than a recurrent rollout. | ||
|
|
||
| Domino uses a GRU correction head. A recurrent hidden state accumulates information about the draft prefix and is concatenated at readout: | ||
|
|
||
| .. code-block:: text | ||
|
|
||
| gru_h_k = GRU(input_k, gru_h_{k-1}) | ||
| p_k = softmax(U_k + W * [h_k; gru_h_k]) | ||
| x_k ~ p_k | ||
|
|
||
| These descriptions compare the underlying architectures. ModelOpt's Domino support is currently training-only, so it does not apply the correction head in serving. | ||
|
|
||
| Correction Head Comparison | ||
| ************************** | ||
|
|
||
| .. list-table:: | ||
| :header-rows: 1 | ||
|
|
||
| * - System | ||
| - Per-step compute | ||
| - State carried | ||
| * - DSpark ``markov_head_type="vanilla"`` | ||
| - ``W1[x_{k-1}]`` plus transition projection | ||
| - None | ||
| * - Domino GRU | ||
| - Full GRU cell over a high-dimensional input | ||
| - Recurrent hidden state | ||
|
|
||
| Both heads must unroll left-to-right at inference. The practical distinction is qualitative: the vanilla Markov head uses only the prior sampled token, while the GRU carries a prefix-dependent recurrent state. | ||
|
|
||
| Takeaways | ||
| ********* | ||
|
|
||
| #. DFlash draft generation is shared; the correction head is the main differentiator. | ||
| #. Both default correction heads are sequential at inference; their tradeoff is local transition structure versus prefix-dependent state. | ||
| #. ModelOpt exposes the DSpark variants through ``markov_head_type``: ``vanilla`` (the default), ``gated``, and ``rnn``. The ``rnn`` option is the closest analogue to Domino's GRU. | ||
| #. Architectural comparisons do not establish a universal quality or throughput ranking; evaluate the chosen head on the target model and serving configuration. | ||
|
|
||
| .. _dspark-domino-references: | ||
|
|
||
| References | ||
| ********** | ||
|
|
||
| * Xin Cheng et al., `DSpark: Confidence-Scheduled Speculative Decoding with Semi-Autoregressive Generation <https://arxiv.org/abs/2607.05147>`_, | ||
| arXiv:2607.05147, 2026. | ||
| * Jianuo Huang et al., `Domino: Decoupling Causal Modeling from Autoregressive Drafting in Speculative Decoding <https://arxiv.org/abs/2605.29707>`_, | ||
| arXiv:2605.29707, 2026. | ||
|
Comment on lines
+81
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [IMPORTANT Compatibility] Internal date inconsistency between the post and its citation. What: The post is dated Why it matters: This is a public-facing NVIDIA technical blog. A post that cites a paper dated after its own publication date is an internal contradiction that undercuts the post's credibility, and it's the kind of thing readers notice immediately. Fix: Reconcile the two — either bump the post Additionally (SUGGESTION): I was unable to verify that the external references resolve (web access wasn't available in this review). Before publishing, please confirm each link actually loads — the two arXiv IDs ( |
||
|
|
||
| Resources | ||
| ********* | ||
|
|
||
| * `DeepSpec / DSpark repo <https://github.com/deepseek-ai/DeepSpec>`_ | ||
| * `DeepSeek-V4-Pro-DSpark checkpoint <https://huggingface.co/deepseek-ai/DeepSeek-V4-Pro-DSpark>`_ | ||
| * `Domino repo <https://github.com/jianuo-huang/Domino>`_ | ||
| * `Domino checkpoint: Qwen3-8B-Domino-b16 <https://huggingface.co/Huang2020/Qwen3-8B-Domino-b16>`_ | ||
| * `ModelOpt PR #1710 <https://github.com/NVIDIA/Model-Optimizer/pull/1710>`_ | ||
|
Comment on lines
+81
to
+93
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [SUGGESTION] Since this post publishes to the public |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| :orphan: | ||
|
|
||
| Model Optimizer Announcements Are Moving to GitHub Pages | ||
| ######################################################### | ||
|
|
||
| :Author: Model Optimizer Team | ||
| :Date: August 13, 2026 | ||
| :Tags: release, docs, github-pages | ||
|
|
||
| The Model Optimizer GitHub Pages site is expanding from API documentation into a lightweight announcement hub. The goal is to make releases, technical notes, examples, and deployment writeups easier to discover without introducing a separate publishing system. | ||
|
|
||
| What Changes | ||
| ************ | ||
|
|
||
| * Announcements live in the documentation source and are reviewed through pull requests. | ||
| * The landing page defaults to announcements. | ||
| * Existing API documentation remains available from the Sphinx left navigation. | ||
| * Announcement pages support tags, search, filtering, and embedded images. | ||
|
|
||
| Authoring Flow | ||
| ************** | ||
|
|
||
| Add a Sphinx page under ``docs/source/announcements/``, add its ``.announcement-card`` metadata and link to ``docs/source/index.rst``, and link it from the announcements toctree when applicable. The GitHub Pages workflow rebuilds the static site from committed source, so every announcement follows the same review path as code and docs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this file need to be linked in top-level AGENTS.md or its automatically picked up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have to mention explicitly. I will add some simple instructions for folks to trigger the technical blog review.