Skip to content

[New Model]Add DeepSeek V4 model support#3634

Open
Matrix-Z97 wants to merge 8 commits into
pytorch:mainfrom
Matrix-Z97:deepseek_v4
Open

[New Model]Add DeepSeek V4 model support#3634
Matrix-Z97 wants to merge 8 commits into
pytorch:mainfrom
Matrix-Z97:deepseek_v4

Conversation

@Matrix-Z97

Copy link
Copy Markdown
Contributor

Description

This PR adds deepseek_v4 model support and registers it in TorchTitan’s supported model list.

Main Changes

  • Add the new torchtitan/models/deepseek_v4/ model directory
  • Implement the DeepSeek V4 model architecture, sparse attention, compressor, MoE, mHC, sharding, parallelization, and state dict adapter
  • Add a deepseek_v4 debug model configuration
  • Register deepseek_v4 in torchtitan/models/init.py

Parallelism Support

  • FSDP is currently supported
  • EP (Expert Parallel) is currently supported
  • TP (Tensor Parallel) is currently supported
  • CP (Context Parallel) is not supported yet and explicitly raises NotImplementedError

Additional Notes

  • The attention implementation is currently based on small operators rather than a fused/custom kernel.
  • Only the debug model configuration is included for now.

If needed, I can further improve and complete this implementation.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jun 11, 2026
@pytorch-bot

pytorch-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

The following ciflow label(s) have been added but CI has not been triggered yet because the workflows are awaiting approval:

  • ciflow/8gpu

Once a maintainer approves the workflows (scroll to the bottom of the PR page), the corresponding CI jobs will be triggered automatically. Please ping one of the reviewers if you do not have access to approve and run workflows.

@Matrix-Z97

Copy link
Copy Markdown
Contributor Author

@tianyu-l I noticed that you added deepseek_v4 to the roadmap. However, I'm sorry that I just force-pushed a new version of the code, which caused the roadmap content to disappear. Could you please add it back?

@tianyu-l tianyu-l moved this from Done to In Progress in 26H1 TorchTitan Development Jun 12, 2026
@tianyu-l

Copy link
Copy Markdown
Contributor

@Matrix-Z97 you mean the "26H1 TorchTitan Development"?

Oh that's not a roadmap but just for tracking what this repo is doing. I re-marked the status from "Done" to "In Progress".

@Matrix-Z97

Copy link
Copy Markdown
Contributor Author

@tianyu-l Understood, thanks for the correction! Out of curiosity, are you interested in the deepseek_v4 model?

@tianyu-l

Copy link
Copy Markdown
Contributor

Yes, of course. We have plans, but were lacking bandwidth.

This PR comes in very timely, and the quality looks very high. We just need some time to review. Many thanks!

Btw @shuhuayu is working on adding latest Kimi model.

@Matrix-Z97

Copy link
Copy Markdown
Contributor Author

Thanks a lot for the feedback! Happy to help with the bandwidth. Let me know if there's anything I can do to help move this PR forward or if you need any adjustments. And awesome news about the latest Kimi model @shuhuayu.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @drisspg to review the attention part

Comment thread torchtitan/models/deepseek_v4/compressor.py Outdated
Matrix-Z97 and others added 4 commits June 27, 2026 09:37
Co-authored-by: Jonathan Zhou <96200235+floatingtrees@users.noreply.github.com>
Adds model/loss-agnostic machinery for model-internal auxiliary losses:

- AuxLossInjection / inject_aux_loss — identity-forward autograd.Function
  that injects an auxiliary loss gradient into a carrier tensor without
  changing the forward value (PP-safe, fullgraph-compile-safe,
  single-tensor output contract). SPMD-typed via
  @spmd.register_autograd_function.

- reduce_to_replicate — backend-agnostic differentiable Partial->Replicate
  reduction over named mesh axes (cp/tp). Dispatches on tensor type:
  DTensor -> full_dtensor redistribute; plain -> spmd_types redistribute.
  Single-process / no-mesh calls are pure-local no-ops.

- ModelSpec.metrics_fn — generic optional callback for model-internal
  metrics collection, called by the trainer during metrics collection.
  Default None (no behavior change for existing models).
@floatingtrees

Copy link
Copy Markdown

@Matrix-Z97 Are you planning to add MTP support for this model? If not, I’d be happy to add it.

@Matrix-Z97

Copy link
Copy Markdown
Contributor Author

@floatingtrees Thanks, MTP has definitely been on our roadmap, and we’ve also been iterating on it continuously in our internal versions. Our current thinking is more along the lines of providing DeepSeek-V3 support in the spirit of #3392. Do you have any better ideas or suggestions?

@tianyu-l tianyu-l left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having some high level feedback before looking into details

({parallel_dims.tp}) and 2 * CP degree ({parallel_dims.cp}).
"""

if parallelism.spmd_backend in ("full_dtensor", "spmd_types"):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are in the migration to "spmd_types". Could you remove "default" and "full_dtensor" support from this new model?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. So this new model only needs to support the spmd backend for now? Does this mean all torchtitan models will transition to supporting only the spmd backend in the future?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Comment on lines +584 to +586
deepseek_v4_configs = {
"debugmodel": _debugmodel,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why only debug model, can we include the full set?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've included deepseek_v4_flash and deepseek_v4_pro now to expand the set. Just a heads-up: due to hardware constraints, I haven't actually tested them yet.

pipelining_fn: Callable | None
post_optimizer_build_fn: Callable | None
state_dict_adapter: type[BaseStateDictAdapter] | None
metrics_fn: Callable | None = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felipemello1 do you have a plan on in-model metric logging that we could share?

Let's add a TODO in dsv4 model code, and remove the model logging in this PR.

Comment thread torchtitan/distributed/aux_loss.py Outdated


@spmd.register_autograd_function
class AuxLossInjection(torch.autograd.Function):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see similar contribution in #3864

Can we make sure the design in #3000 suits the need for both?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this implementation was referenced from #3864. I'll need to look closer into #3000 to see if the design can cover both use cases. Will update this thread once I have more clarity.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a quick look, #3000 seems more like a MoE-specific interface, while here we would like to call the aux-loss capability through a common/shared interface that can also cover non-MoE losses such as the DSA indexer loss.

So for the current DeepSeek V4 use case, the #3864-style implementation seems more suitable to me.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look at both

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please add verification (e.g. at least in PR summary) following https://github.com/pytorch/torchtitan/tree/main/scripts/checkpoint_conversion#comprehensive-check-kl-divergence

cc @shuhuayu

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. Running the KL check with deepseek_v4_flash or deepseek_v4_pro as the baseline is not feasible for me due to hardware limits.

Would it be acceptable to run the same HF-vs-TorchTitan KL / max-diff comparison on a custom small DeepSeek V4 config instead?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. @shuhuayu since you've done it for Kimi, could you help verify this PR gets to similar level of numerical parity?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be acceptable to run the same HF-vs-TorchTitan KL / max-diff comparison on a custom small DeepSeek V4 config instead?

We also did a customized 16b kimi configs to compare numerics so it sounds good to me to do the same for dsv4. @tianyu-l, do you think we need to test it in the original 862b configs, doable but needs some additional setups.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Could you share what config was used for the customized 16B Kimi numerical test? In particular, which dimensions were reduced, e.g. number of layers, hidden size, heads/head dim, MoE experts, or sequence length?
I can follow the same strategy for DSV4 and build a smaller custom config for the KL/numerical comparison.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Small scale verification sounds fine.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Could you share what config was used for the customized 16B Kimi numerical test?

I used the kimi-vl variant, see https://github.com/pytorch/torchtitan/pull/3532/changes#diff-5a13a40a31333dd8b095a114b15d9580c2744ac09211c6b551a02c2989032c9b

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return torch.cat((-x2, x1), dim=-1)


class SingleComplexRoPE(ComplexRoPE):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tianyu-l Hi, it looks like the existing community RoPE interface only supports (query, key) pair inputs, while some DeepSeek V4 RoPE call sites operate on a single tensor, such as in the compressor and indexer. Without a single-tensor API, these paths would need awkward patterns like rope(x, x)[0].

To avoid that, we added SingleComplexRoPE for explicit single-tensor complex RoPE usage. It also supports inverse=True, which is needed to match the HF inference logic in the DeepSeek V4 attention post phase.

Does this form of change look acceptable to the community?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shuhuayu I vaguely remember there's a model using single-field rope, but I couldn't find it any more. My worry is that after recent refactor the single-field rope is gone. Was it originally added by you or do you have clue?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I searched and did not find a single field one neither. rather than a new SingleComplexRoPE class, how about just make key optional in the existing RoPE.forward / apply_rotary_emb (return a single tensor when key is None) and add an inverse=False flag ? That covers both the single-tensor call sites and the inverse-rope post-phase without a parallel class, sharing one implementation, and a no-op for existing models.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shuhuayu
my only concern is that it also need to work with the helion kernels (https://github.com/pytorch/torchtitan/blob/main/torchtitan/overrides/helion_rope.py), but maybe AI can just do it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not urgent for dsv4 since it uses ComplexRoPE and helion kernels is only for CosSineRoPE now. but it leaves the work to people who wants to add helion ComplexRoPE kernels.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shuhuayu
See #3767

I think at least we shouldn't break existing key, query pair version of Helion override.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciflow/8gpu CLA Signed This label is managed by the Meta Open Source bot.

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

5 participants