Selected changesmerged Oct 29, 2026 – Nov 4, 2026
Keep overrides of the deprecated gradient checkpointing methods workingPython · 36 + / 2 −
Introduces 3 new declarations in src/transformers/modeling_utils.py.
Adds new core implementation rather than adjusting what was there. Tests changed with it, with code of their own.
src/transformers/modeling_utils.py ↗ · 2 files
@@ -3129,6 +3129,19 @@ def activation_checkpointing_enable( activation_checkpointing_kwargs (dict, *optional*): Additional keyword arguments passed along to the `torch.utils.checkpoint.checkpoint` function. """+ # Subclasses and wrappers of the deprecated `gradient_checkpointing_enable` stay the entry point until v6+ if self._is_overridden("gradient_checkpointing_enable"):+ self.gradient_checkpointing_enable(+ gradient_checkpointing_kwargs=activation_checkpointing_kwargs,+ every_n_layers=every_n_layers,+ offload=offload,+ )+ else:+ self._activation_checkpointing_enable(activation_checkpointing_kwargs, every_n_layers, offload)++ def _activation_checkpointing_enable(+ self, activation_checkpointing_kwargs=None, every_n_layers: int = 1, offload: bool = False+ ): if not self.supports_gradient_checkpointing: raise ValueError(f"{self.__class__.__name__} does not support activation checkpointing.")
Train adapters on top of FP8 weightsPython · 78 + / 43 −
Introduces 7 new declarations in src/transformers/integrations/finegrained_fp8.py.
Adds new core implementation rather than adjusting what was there. Tests changed with it, with code of their own.
src/transformers/integrations/finegrained_fp8.py ↗ · 3 files
@@ -282,6 +282,63 @@ def fp8_linear( return finegrained_fp8_linear(input, weight, weight_scale_inv, block_size, bias, activation_scale) +def _dequantize_fp8_weight(+ weight: torch.Tensor, weight_scale_inv: torch.Tensor, block_size: list[int] | None, dtype: torch.dtype+) -> torch.Tensor:+ """Dequantize `(..., N, K)` FP8 weights with their per-block (or per-tensor) scales, for the backward pass."""+ if weight.dtype == torch.int8:+ raise NotImplementedError("Backward through FP4 weights is not supported.")+ scale = weight_scale_inv.to(dtype)+ if block_size is not None:+ rows, cols = weight.shape[-2:]+ scale = scale.repeat_interleave(block_size[0], dim=-2)[..., :rows, :]+ scale = scale.repeat_interleave(block_size[1], dim=-1)[..., :cols]+ return weight.to(dtype).mul_(scale)+++class FP8LinearFunction(torch.autograd.Function):+ """+ `fp8_linear` with a backward for the input, so adapters (e.g. LoRA) can train on top of FP8 layers. The FP8 weights+ are frozen: the input gradient goes through the dequantized weight, and the weight, scales and bias get none.+ """++ @staticmethod+ def forward(ctx, input, weight, weight_scale_inv, block_size, bias, activation_scale, allow_deepgemm):+ ctx.save_for_backward(weight, weight_scale_inv)+ ctx.block_size = block_size+ return fp8_linear(input, weight, weight_scale_inv, block_size, bias, activation_scale, allow_deepgemm)++ @staticmethod+ def backward(ctx, grad_output):+ weight, weight_scale_inv = ctx.saved_tensors+ weight = _dequantize_fp8_weight(weight, weight_scale_inv, ctx.block_size, grad_output.dtype)
BUG: f2py: mask string literals in depend harvest and fix sort orderPython · 100 + / 17 −
Introduces 3 new declarations in numpy/f2py/crackfortran.py.
Adds new core implementation rather than adjusting what was there. Tests changed with it, with code of their own.
numpy/f2py/crackfortran.py ↗ · 8 files
@@ -2129,6 +2147,49 @@ def postcrack(block, args=None, tab=''): return block +def _sort_cyclic_dependents(dep, vars):+ """Order one cyclic depend group by real dependency edges.++ ``sortvarnames`` calls this only after a cycle has been reported.+ The usual f2py cycle is an input array dimensioned by hide scalars+ that are computed from that array (``n = shape(a, ...)``,+ ``lda = MAX(1, n)``). Those array-to-hide edges are dropped so+ ``getarrdims`` can blank them, and every remaining edge is honored+ by a topological sort. An initializer therefore runs after the+ names it uses, independent of declaration order.++ A cycle that is not one of those shape back-edges is left in+ ``dep`` order. The caller has already reported it. This function+ does not recurse.+ """+ remaining = set(dep)++ def blocking(name):+ var = vars[name]+ blocked_by = []+ for dep_name in var.get('depend') or []:+ if dep_name not in remaining or dep_name == name:+ continue+ target = vars.get(dep_name, {})+ # Dimension back-edge onto a hide value or an initializer.+ if (isarray(var) and isintent_nothide(var)+ and (isintent_hide(target) or '=' in target)):+ continue+ blocked_by.append(dep_name)+ return blocked_by
Implement `advance_back_by` on `Fuse`Rust · 41 + / 0 −
Introduces 4 new declarations in library/core/src/iter/adapters/fuse.rs.
Adds new language design rather than adjusting what was there. Tests changed with it, with code of their own.
library/core/src/iter/adapters/fuse.rs ↗ · 2 files
@@ -358,6 +366,25 @@ where and_then_or_clear(&mut self.iter, |iter| iter.next_back()) } + #[inline]+ default fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>+ where+ I: DoubleEndedIterator,+ {+ let Some(iter) = &mut self.iter else {+ return match NonZero::new(n) {+ Some(n) => Err(n),+ None => Ok(()),+ };+ };++ let res = iter.advance_back_by(n);+ if res.is_err() {+ self.iter = None;+ }+ res+ }+ #[inline] default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> where
Turbopack: fix trailing-slash package root resolutionRust · 118 + / 10 −
Introduces 3 new declarations in turbopack/crates/turbopack-core/src/resolve/mod.rs.
Adds new framework internals rather than adjusting what was there. Tests changed with it, with code of their own.
turbopack/crates/turbopack-core/src/resolve/mod.rs ↗ · 6 files
@@ -3908,6 +3914,108 @@ mod tests { .await; } + #[rstest::rstest]+ #[case::main(rcstr!("package").into(), r#"{"main":"./main.js"}"#, vec![("package", "main.js")])]+ #[case::main_trailing_slash(rcstr!("package/").into(), r#"{"main":"./main.js"}"#, vec![("package/", "main.js")])]+ #[case::index(rcstr!("package").into(), "{}", vec![("package", "index.js")])]+ #[case::index_trailing_slash(rcstr!("package/").into(), "{}", vec![("package/", "index.js")])]+ #[case::exports(rcstr!("package").into(), r#"{"exports":"./main.js"}"#, vec![("package", "main.js")])]+ #[case::exports_trailing_slash(rcstr!("package/").into(), r#"{"exports":"./main.js"}"#, vec![])]+ #[case::exports_subpath(rcstr!("package/subpath.js").into(), r#"{"exports":{"./subpath.js":"./main.js"}}"#, vec![("package/subpath.js", "main.js")])]+ #[case::dynamic_subpath(+ Pattern::concat([rcstr!("package/").into(), Pattern::Dynamic, rcstr!(".js").into()]),+ r#"{"main":"./main.js"}"#,+ vec![("package/index.js", "index.js"), ("package/main.js", "main.js"), ("package/subpath.js", "subpath.js")]+ )]+ #[case::dynamic_trailing_slash(+ Pattern::concat([rcstr!("package/").into(), Pattern::Dynamic]),+ r#"{"main":"./main.js"}"#,+ vec![+ ("package/", "main.js"),+ ("package/index", "index.js"), ("package/index.js", "index.js"),+ ("package/main", "main.js"), ("package/main.js", "main.js"),+ ("package/package", "package.json"), ("package/package.json", "package.json"),+ ("package/subpath", "subpath.js"), ("package/subpath.js", "subpath.js")+ ]+ )]+ #[case::dynamic_roots(+ Pattern::Alternatives(vec![+ rcstr!("package").into(),+ Pattern::concat([rcstr!("package/").into(), Pattern::Dynamic]),+ ]),+ r#"{"main":"./main.js"}"#,
fix: Protect math from markdown emphasis parsing in Markdown panePython · 58 + / 3 −
Introduces 10 new declarations in panel/pane/markup.py.
Adds new core implementation rather than adjusting what was there. Tests changed with it, with code of their own.
panel/pane/markup.py ↗ · 3 files
@@ -38,6 +38,54 @@ # links, definition lists) or which breaks line offsets (\r). _NON_LOCAL_SYNTAX = re.compile(r'\[\^|\]:|^ {0,3}[:~][ \t]|\r', re.MULTILINE) +def _math_plugin(md: MarkdownIt) -> None:+ """+ Keeps math delimited by $$ verbatim, since the client-side+ MathJax pass runs on the rendered HTML and would otherwise see+ markup generated from characters such as '*' inside the math.+ """+ from mdit_py_plugins.dollarmath import dollarmath_plugin+ from mdit_py_plugins.dollarmath.index import math_inline_dollar++ dollarmath_plugin(md, allow_labels=False, double_inline=True)++ # The client only typesets $$, so single $ must stay ordinary text+ # (e.g. currency) and keep its surrounding emphasis.+ inline_rule = math_inline_dollar(True, True, True)++ def double_only(state, silent):+ if state.src[state.pos:state.pos + 2] != '$$':+ return False+ return inline_rule(state, silent)++ md.inline.ruler.at('math_inline', double_only)++ def raw(delimiter, block=False):+ def render(self, tokens, idx, options, env):+ math = escape(tokens[idx].content, quote=False)+ return f'{delimiter}{math}{delimiter}\n' if block else f'{delimiter}{math}{delimiter}'+ return render++ md.add_render_rule('math_inline_double', raw('$$'))+ md.add_render_rule('math_block', raw('$$', block=True))
fix: Send updates from long running sync callbacks before they returnPython · 51 + / 2 −
Introduces 3 new declarations in panel/io/document.py.
Adds new core implementation rather than adjusting what was there. Tests changed with it, with code of their own.
panel/io/document.py ↗ · 2 files
@@ -651,6 +653,46 @@ def _suppress_property_callbacks( event.callback_invoker = None return events +async def _write_message(+ doc: Document, connections: list[ServerConnection], message: Message+) -> None:+ for conn in connections:+ lock = getattr(conn._socket, 'write_lock', None)+ with (await lock.acquire()) if lock is not None else nullcontext():+ await _await_writes(_socket_dispatcher(conn._socket)(conn, msg=message))++def _write_from_worker_thread(+ doc: Document,+ connections: Iterable[ServerConnection],+ events: list[DocumentChangedEvent]+) -> bool:+ """+ Writes events generated by a locked callback that bokeh runs on a+ worker thread right away, rather than leaving them to bokeh, which+ only writes them once the callback returns, so that a long running+ callback can still report progress.++ Only safe while bokeh has no pending writes of its own: the message+ is serialized here, while the callback holds the Document lock, and+ the write is scheduled on the event loop ahead of bokeh's, so the+ client always receives models before they are referenced.+ """+ patches = [e for e in events if isinstance(e, DocumentPatchedEvent)]+ if state._on_loop_thread or not patches or len(patches) != len(events):+ return False+ loop = state._document_loop(doc)+ asyncio_loop = t.cast(+ 'asyncio.AbstractEventLoop | None', getattr(loop, 'asyncio_loop', loop)
[`Moe`] Fix grouped mm fallbackPython · 36 + / 4 −
Introduces 3 new declarations in src/transformers/integrations/moe.py.
Adds new core implementation rather than adjusting what was there. Tests changed with it, with code of their own.
src/transformers/integrations/moe.py ↗ · 2 files
@@ -233,22 +233,43 @@ def _grouped_mm_fallback_setup_context(ctx, inputs, output): ctx.offs = inputs[2] -def _grouped_mm_fallback_backward(ctx, grad_output):- """Backward pass for `_grouped_mm_fallback`. Computes grad_input and grad_weight per expert group; offs has no gradient."""- input, weight = ctx.saved_tensors+def _grouped_mm_fallback_bwd(+ input: torch.Tensor,+ weight: torch.Tensor,+ offs: torch.Tensor,+ grad_output: torch.Tensor,+) -> tuple[torch.Tensor, torch.Tensor]:+ """Backward implementation for the grouped matmul fallback.""" grad_input = torch.zeros_like(input) grad_weight = torch.zeros_like(weight) start = 0 # single cpu<->gpu sync point here, # avoids multiple syncs inside the loop- for i, end in enumerate(ctx.offs.tolist()):+ for i, end in enumerate(offs.tolist()): if start == end: continue torch.mm(grad_output[start:end], weight[i].T, out=grad_input[start:end]) torch.mm(input[start:end].T, grad_output[start:end], out=grad_weight[i]) start = end + return grad_input, grad_weight+++def _grouped_mm_fallback_backward_fake(+ input: torch.Tensor,+ weight: torch.Tensor,
client-go/rest/watch: add concurrent watch event decoderGo · 225 + / 1 −
Introduces 14 new declarations in staging/src/k8s.io/client-go/rest/watch/concurrent_decoder.go.
Adds new systems design rather than adjusting what was there. Tests changed with it, with code of their own.
staging/src/k8s.io/client-go/rest/watch/concurrent_decoder.go ↗ · 6 files
@@ -0,0 +1,208 @@+/*+Copyright The Kubernetes Authors.++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++ http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+*/++package watch++import (+ "fmt"+ "io"+ "sync"++ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"+ "k8s.io/apimachinery/pkg/runtime"+ "k8s.io/apimachinery/pkg/runtime/serializer/streaming"+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"+ "k8s.io/apimachinery/pkg/watch"+)++type rawWatchEventResult struct {+ event *metav1.WatchEvent+ err error
Refactor box downcasting methodsRust · 52 + / 43 −
Introduces 6 new declarations in library/alloc/src/boxed/convert.rs.
Adds new language design rather than adjusting what was there. Tests changed with it, with code of their own.
library/alloc/src/boxed/convert.rs ↗ · 6 files
@@ -711,21 +717,24 @@ impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + 'a> { } } +impl<T: Error + ?Sized + 'static, A: Allocator> Box<T, A> {+ fn downcast_error<Dst: 'static>(this: Self) -> Result<Box<Dst, A>, Self> {+ if core::error::error_type_id::<T>(&this) == core::any::TypeId::of::<Dst>() {+ // SAFETY: The type is correct+ Ok(unsafe { Self::cast_unchecked(this) })+ } else {+ Err(this)+ }+ }+}+ impl dyn Error { /// Attempts to downcast the box to a concrete type. #[inline] #[stable(feature = "error_downcast", since = "1.3.0")] #[rustc_allow_incoherent_impl] pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {- if self.is::<T>() {- // SAFETY: Check ensures the type is correct.- unsafe {- let raw: *mut dyn Error = Box::into_raw(self);- Ok(Box::from_raw(raw as *mut T))- }- } else {- Err(self)- }+ Box::downcast_error(self) } }
feat(next/image): add internal image redirects (to match existing external image redirects)TypeScript · 131 + / 72 −
Introduces 3 new declarations in packages/next/src/server/image-optimizer.ts.
Adds new framework internals rather than adjusting what was there. Tests changed with it, with code of their own.
packages/next/src/server/image-optimizer.ts ↗ · 10 files
@@ -100,6 +100,77 @@ export interface ImageParamsResult { minimumCacheTTL: number } +type ImageUrlParamResult =+ | { href: string; isAbsolute: boolean }+ | { errorMessage: string }++function validateUrlParam(+ url: string | string[] | undefined,+ imageData: ImageConfigComplete,+ isRedirect = false+): ImageUrlParamResult {+ // Note - We intentionally skip validation for local/remotePatterns when+ // validating redirect locations so that we don't break a src img redirect+ // to a new domain (e.g. github.com => githubusercontent.com).+ const { domains = [], remotePatterns = [], localPatterns } = imageData++ if (!isRedirect && domains.length > 0) {+ Log.warnOnce(+ 'The "images.domains" configuration is deprecated. Please use "images.remotePatterns" configuration instead.'+ )+ }++ if (!url) {+ return { errorMessage: '"url" parameter is required' }+ } else if (Array.isArray(url)) {+ return { errorMessage: '"url" parameter cannot be an array' }+ }++ if (url.length > 3072) {+ return { errorMessage: '"url" parameter is too long' }+ }+
salm_automodel_ctc_10ms: calibrated 40 ms to 10 ms CTC timestampsPython · 961 + / 108 −
Introduces 23 new declarations in nemo/collections/speechlm2/parts/ctc_timestamp_utils.py.
Adds new core implementation rather than adjusting what was there. Tests changed with it, with code of their own.
nemo/collections/speechlm2/parts/ctc_timestamp_utils.py ↗ · 14 files
@@ -2207,14 +2681,229 @@ def _align_banded_ctc(aligner, prepared): diarization_frame_seconds=prepared['diarization_frame_seconds'], diarization_max_speaker_count=prepared['diarization_max_speaker_count'], )+ calibration = prepared['config'].get('boundary_interpolation')+ if calibration is not None:+ # Use raw DP edges, before any VAD snapping or extending.+ _interpolate_word_boundaries(+ rows,+ ctc,+ record['ctc_step'],+ record['time_offset'],+ record['audio_duration'],+ diarization,+ mapping,+ calibration,+ aligner=aligner,+ )+ result['speaker_word_timestamps'] = aligner._public_word_timestamps(rows)+ result['boundary_interpolation'] = {+ 'method': 'calibrated_edge_local_linear_interpolation',+ 'estimated_grid_seconds': aligner.boundary_grid_seconds,+ 'outside_words': sum(w.get('_outside_diarization', False) for w in rows),+ } result['speaker_assignment_mode'] = 'token_distribution' result['alignment_diagnostics']['failed_streams'] = failures result['alignment_diagnostics']['one_pass'] = True result['alignment_diagnostics']['banded'] = diagnostics- results.append(_refine_word_timestamps(result, prepared['config']['max_word_frames']))+ results.append(+ _refine_word_timestamps(+ result,+ prepared['config']['max_word_frames'],+ onset_snap_seconds=aligner.onset_snap_seconds,