dotnet/machinelearning · error · ArgumentException

This is not a causal mask

Error message

This is not a causal mask

What it means

AttentionMaskConverter.ToCausal4D throws ArgumentException when asked to build a 4D causal mask while the converter's _isCausal flag is false. ToCausal4D is the fallback path used when no 2D attention mask is supplied, and it only makes sense for causal attention.

Solutions

  1. Construct the AttentionMaskConverter with isCausal: true for decoder/causal models.
  2. Pass an explicit 2D attention mask so the To4D path is used instead.
  3. Verify the model config's is_causal/decoder flag matches the converter flags.
  4. For encoder-style models, don't call ToCausal4D — expand the 2D mask with ExpandMask instead.

Example fix

// before
var converter = new AttentionMaskConverter(isCausal: false);
var mask4d = converter.ToCausal4D(batchSize, qLen, kvLen, dType, device);
// after
var converter = new AttentionMaskConverter(isCausal: true);
var mask4d = converter.ToCausal4D(batchSize, qLen, kvLen, dType, device);
Defensive patterns

Strategy: validation

Validate before calling

if (!isCausal) throw new InvalidOperationException("ToCausal4D requires isCausal: true converter");

Type guard

bool CausalOk(bool isCausal) => isCausal;

Try / catch

try { var mask = converter.ToCausal4D(batch, qLen, kvLen, dType, device); }
catch (ArgumentException ex) when (ex.Message.Contains("not a causal mask")) { logger.LogError("Converter constructed with isCausal=false; use To4D/ExpandMask instead"); throw; }

Prevention

When it happens

Trigger: Calling Create4DCausalAttentionMask with attentionMask == null on a converter constructed with isCausal: false.

Common situations: Reusing a bidirectional (non-causal) mask converter in a decoder model where no explicit 2D mask is provided; copy-pasted converter setup from an encoder model into a causal LM pipeline.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11). Data as JSON: /api/errors/dacc67041218dc89. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.ML.GenAI.Core/Utility/AttentionMaskConverter.cs:80

        if (causal4dMask is not null)
        {
            var min = torch.finfo(dType).min;
            expandedAttnMask = causal4dMask.masked_fill(expandedAttnMask.to(ScalarType.Bool), min);
        }

        return expandedAttnMask;
    }

    public Tensor? ToCausal4D(
        int batchSize,
        int queryLength,
        int keyValueLength,
        ScalarType dType,
        Device device)
    {
        if (!_isCausal)
        {
            throw new ArgumentException("This is not a causal mask");
        }

        long[] inputShape = [batchSize, queryLength];
        var pastKeyValueLength = keyValueLength - queryLength;

        // create causal mask
        // [bsz, seq_len] -> [bsz, 1, tgt_seq_len, src_seq_len]
        Tensor? causal4DMask = null;
        if (queryLength > 1 || this._slidingWindow is int)
        {
            causal4DMask = MakeCausalMask(inputShape, dType, device, pastKeyValueLength, this._slidingWindow);
        }

        return causal4DMask;
    }

    public static Tensor MakeCausalMask(
        long[] inputIdsShape,

View on GitHub (pinned to 7b76e69cf9)