sglang icon indicating copy to clipboard operation
sglang copied to clipboard

[Bug] MLA slower than default for small context long outputs *and* generating bad output reproducibly

Open pseudotensor opened this issue 10 months ago • 11 comments

Checklist

  • [x] 1. I have searched related issues but cannot get the expected help.
  • [x] 2. The bug has not been fixed in the latest version.
  • [x] 3. Please note that if the bug-related issue you submitted lacks corresponding environment info and a minimal reproducible demo, it will be challenging for us to reproduce and resolve the issue, reducing the likelihood of receiving feedback.
  • [x] 4. If the issue you raised is not a bug but a question, please raise a discussion at https://github.com/sgl-project/sglang/discussions/new/choose Otherwise, it will be closed.
  • [x] 5. Please use English, otherwise it will be closed.

Describe the bug

Enabling MLA is much slower. I show 2 benchmarks, one is concurrency and the other is token input size (since MLA is supposed to be better there).

Reproduction

docker stop v3 ; docker remove v3
docker run -d --gpus all --shm-size 32g -p 5000:5000 --name v3 -v ~/.cache/huggingface:/root/.cache/huggingface --ipc=host lmsysorg/sglang:v0.4.3.post2-cu125 \
    python3 -m sglang.launch_server --model deepseek-ai/DeepSeek-V3 --tp 8 \
    --enable-torch-compile \
    --enable-flashinfer-mla \
    --trust-remote-code --port 5000 --host 0.0.0.0 \
    --api-key EMPTY  --random-seed 1234

or:

docker stop r1 ; docker remove r1
docker run -d --gpus all --shm-size 32g -p 5000:5000 --name r1 -v ~/.cache/huggingface:/root/.cache/huggingface --ipc=host lmsysorg/sglang:v0.4.3.post2-cu125 \
    python3 -m sglang.launch_server --model deepseek-ai/DeepSeek-R1 --tp 8 \
    --enable-torch-compile \
    --enable-flashinfer-mla \
    --trust-remote-code --port 5000 --host 0.0.0.0 \
    --api-key EMPTY  --random-seed 1234

Then on client:

import os
os.environ['HUGGING_FACE_HUB_TOKEN'] = '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'

import time
import openai
import concurrent.futures
from transformers import AutoTokenizer
from datetime import datetime


def count_tokens(prompt, model_name="deepseek-ai/DeepSeek-V3"):
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    return len(tokenizer.encode(prompt))

def measure_performance(prompt, max_tokens=8192):
    url = 'SET'
    api_key = 'SET'
    client = openai.Client(base_url=f"http://{url}:5000/v1", api_key=api_key)

    token_count = count_tokens(prompt)
    start_time = time.time()

    response = client.chat.completions.create(
        model="deepseek-ai/DeepSeek-R1",
        messages=[{"role": "user", "content": prompt}],
        temperature=0,
        max_tokens=max_tokens,
        stream=True  # Enable streaming mode
    )

    first_token_time = None
    total_tokens = 0
    first_token_received = False

    for chunk in response:
        if not first_token_received:
            first_token_time = time.time() - start_time
            first_token_received = True
        total_tokens += len(chunk.choices[0].delta.content.split())

    total_time = time.time() - start_time
    tps = total_tokens / total_time if total_time > 0 else 0

    return {
        "concurrent_requests": None,  # Placeholder, to be updated in multi-run function
        "prompt_length": token_count,
        "max_tokens": max_tokens,
        "time_to_first_token": first_token_time,
        "tokens_per_second": tps,
        "total_time": total_time,
        "total_tokens": total_tokens,
    }

def run_concurrent_tests(prompt, num_requests_list, max_tokens=8192):
    results = []

    for num_requests in num_requests_list:
        print("num_requests: %s" % num_requests, flush=True)
        with concurrent.futures.ThreadPoolExecutor(max_workers=num_requests) as executor:
            futures = [executor.submit(measure_performance, prompt, max_tokens) for _ in range(num_requests)]
            concurrent_results = [future.result() for future in concurrent.futures.as_completed(futures)]

            avg_time_to_first_token = sum(res["time_to_first_token"] for res in concurrent_results) / num_requests
            avg_tokens_per_second = sum(res["tokens_per_second"] for res in concurrent_results) / num_requests
            avg_total_time = sum(res["total_time"] for res in concurrent_results) / num_requests
            total_tokens = sum(res["total_tokens"] for res in concurrent_results)

            results.append({
                "concurrent_requests": num_requests,
                "prompt_length": concurrent_results[0]["prompt_length"],
                "max_tokens": max_tokens,
                "time_to_first_token": avg_time_to_first_token,
                "tokens_per_second": avg_tokens_per_second,
                "total_time": avg_total_time,
                "total_tokens": total_tokens,
            })

    return results

def generate_markdown(results):
    md_report = """# Concurrent Request Performance Analysis

## Summary of Response Time and Throughput

| Concurrent Requests | Prompt Length | Max Tokens | Time to First Token (s) | Tokens per Second | Total Time (s) | Total Tokens |
|--------------------|--------------|------------|-------------------------|-------------------|---------------|-------------|
"""

    for res in results:
        md_report += f"| {res['concurrent_requests']} | {res['prompt_length']} | {res['max_tokens']} | {res['time_to_first_token']:.4f} | {res['tokens_per_second']:.4f} | {res['total_time']:.4f} | {res['total_tokens']} |\n"

    return md_report

def main():
    prompt = "Write an extremely long story."
    num_requests_list = [1, 8, 16, 32]  # Different levels of concurrency

    results = run_concurrent_tests(prompt, num_requests_list)

    markdown_report = generate_markdown(results)

    with open("concurrent_performance_report.md", "w") as f:
        f.write(markdown_report)

    print("Concurrent performance report generated: concurrent_performance_report.md")

if __name__ == "__main__":
    main()

gives:

Image

Compared to without MHA on 0.4.2:

https://github.com/sgl-project/sglang/issues/3196#issuecomment-2645916906

i.e.

Image

Then for context testing:

import time
import openai
from transformers import AutoTokenizer
from datetime import datetime

def count_tokens(prompt, model_name="deepseek-ai/DeepSeek-V3"):
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    return len(tokenizer.encode(prompt))

def measure_performance(prompt, model="deepseek-ai/DeepSeek-V3", max_tokens=64):
    url = 'SET'
    api_key = 'SET'
    client = openai.Client(base_url=f"http://{url}:5000/v1", api_key=api_key)

    token_count = count_tokens(prompt, model)
    start_time = time.time()

    response = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": prompt}],
        temperature=0,
        max_tokens=max_tokens,
        stream=True  # Enable streaming mode
    )

    first_token_time = None
    total_tokens = 0
    first_token_received = False

    for chunk in response:
        if not first_token_received:
            first_token_time = time.time() - start_time
            first_token_received = True
        total_tokens += len(chunk.choices[0].delta.content.split())

    total_time = time.time() - start_time
    tps = total_tokens / total_time if total_time > 0 else 0

    return {
        "prompt_length": token_count,
        "max_tokens": max_tokens,
        "time_to_first_token": first_token_time,
        "tokens_per_second": tps,
        "total_time": total_time,
        "total_tokens": total_tokens,
    }

def generate_markdown(results):
    md_report = """# Token Performance Analysis

## Summary of Response Time and Throughput

| Prompt Length | Max Tokens | Time to First Token (s) | Tokens per Second | Total Time (s) | Total Tokens |
|--------------|------------|-------------------------|-------------------|---------------|-------------|
"""

    for res in results:
        md_report += f"| {res['prompt_length']} | {res['max_tokens']} | {res['time_to_first_token']:.4f} | {res['tokens_per_second']:.4f} | {res['total_time']:.4f} | {res['total_tokens']} |\n"

    return md_report

def main():
    test_cases = [
        ("Write an extremely long story.", 8192),
        ("word " * 8000 + "Write an extremely long story.", 8192),
        ("word " * 118000 + "Write an extremely long story.", 8192)
    ]

    results = []
    for prompt, max_tokens in test_cases:
        res = measure_performance(prompt, max_tokens=max_tokens)
        results.append(res)

    markdown_report = generate_markdown(results)

    with open("performance_report.md", "w") as f:
        f.write(markdown_report)

    print("Performance report generated: performance_report.md")

if __name__ == "__main__":
    main()

One gets:

Image

Before without MHA on 0.4.2 gave: https://github.com/sgl-project/sglang/issues/3196#issuecomment-2645912237 i.e.

Image

i.e. in particular, long context is much faster, about 3x at longer contexts compared to 0.4.2.

However, for small context inputs, it dropped from 47 tokens/sec to 40 tokens/sec.

Environment

INFO 02-20 03:00:02 __init__.py:190] Automatically detected platform cuda.
Python: 3.10.12 (main, Jan 17 2025, 14:35:34) [GCC 11.4.0]
CUDA available: True
GPU 0,1,2,3,4,5,6,7: NVIDIA H200
GPU 0,1,2,3,4,5,6,7 Compute Capability: 9.0
CUDA_HOME: /usr/local/cuda
NVCC: Cuda compilation tools, release 12.4, V12.4.131
CUDA Driver Version: 550.144.03
PyTorch: 2.5.1+cu124
sgl_kernel: 0.0.3.post6
flashinfer: 0.2.1.post2+cu124torch2.5
triton: 3.1.0
transformers: 4.48.3
torchao: 0.8.0
numpy: 1.26.4
aiohttp: 3.11.12
fastapi: 0.115.8
hf_transfer: 0.1.9
huggingface_hub: 0.28.1
interegular: 0.3.3
modelscope: 1.23.0
orjson: 3.10.15
packaging: 24.2
psutil: 7.0.0
pydantic: 2.10.6
multipart: 0.0.20
zmq: 26.2.1
uvicorn: 0.34.0
uvloop: 0.21.0
vllm: 0.7.2
openai: 1.63.2
tiktoken: 0.9.0
anthropic: 0.45.2
decord: 0.6.0
NVIDIA Topology: 
        GPU0    GPU1    GPU2    GPU3    GPU4    GPU5    GPU6    GPU7    NIC0    NIC1    NIC2    NIC3    NIC4    NIC5    NIC6    NIC7    NIC8    NIC9    NIC10   NIC11   CPU Affinity    NUMA Affinity   GPU NUMA ID
GPU0     X      NV18    NV18    NV18    NV18    NV18    NV18    NV18    NODE    NODE    NODE    NODE    SYS     NODE    PIX     SYS     SYS     SYS     SYS     SYS     0-95,192-287    0               N/A
GPU1    NV18     X      NV18    NV18    NV18    NV18    NV18    NV18    NODE    PIX     PHB     PHB     SYS     NODE    NODE    SYS     SYS     SYS     SYS     SYS     0-95,192-287    0               N/A
GPU2    NV18    NV18     X      NV18    NV18    NV18    NV18    NV18    PIX     NODE    NODE    NODE    SYS     NODE    NODE    SYS     SYS     SYS     SYS     SYS     0-95,192-287    0               N/A
GPU3    NV18    NV18    NV18     X      NV18    NV18    NV18    NV18    NODE    NODE    NODE    NODE    SYS     PIX     NODE    SYS     SYS     SYS     SYS     SYS     0-95,192-287    0               N/A
GPU4    NV18    NV18    NV18    NV18     X      NV18    NV18    NV18    SYS     SYS     SYS     SYS     NODE    SYS     SYS     NODE    NODE    NODE    PIX     NODE    96-191,288-383  1               N/A
GPU5    NV18    NV18    NV18    NV18    NV18     X      NV18    NV18    SYS     SYS     SYS     SYS     NODE    SYS     SYS     NODE    NODE    NODE    NODE    PIX     96-191,288-383  1               N/A
GPU6    NV18    NV18    NV18    NV18    NV18    NV18     X      NV18    SYS     SYS     SYS     SYS     NODE    SYS     SYS     PIX     PHB     PHB     NODE    NODE    96-191,288-383  1               N/A
GPU7    NV18    NV18    NV18    NV18    NV18    NV18    NV18     X      SYS     SYS     SYS     SYS     PIX     SYS     SYS     NODE    NODE    NODE    NODE    NODE    96-191,288-383  1               N/A
NIC0    NODE    NODE    PIX     NODE    SYS     SYS     SYS     SYS      X      NODE    NODE    NODE    SYS     NODE    NODE    SYS     SYS     SYS     SYS     SYS
NIC1    NODE    PIX     NODE    NODE    SYS     SYS     SYS     SYS     NODE     X      PHB     PHB     SYS     NODE    NODE    SYS     SYS     SYS     SYS     SYS
NIC2    NODE    PHB     NODE    NODE    SYS     SYS     SYS     SYS     NODE    PHB      X      PIX     SYS     NODE    NODE    SYS     SYS     SYS     SYS     SYS
NIC3    NODE    PHB     NODE    NODE    SYS     SYS     SYS     SYS     NODE    PHB     PIX      X      SYS     NODE    NODE    SYS     SYS     SYS     SYS     SYS
NIC4    SYS     SYS     SYS     SYS     NODE    NODE    NODE    PIX     SYS     SYS     SYS     SYS      X      SYS     SYS     NODE    NODE    NODE    NODE    NODE
NIC5    NODE    NODE    NODE    PIX     SYS     SYS     SYS     SYS     NODE    NODE    NODE    NODE    SYS      X      NODE    SYS     SYS     SYS     SYS     SYS
NIC6    PIX     NODE    NODE    NODE    SYS     SYS     SYS     SYS     NODE    NODE    NODE    NODE    SYS     NODE     X      SYS     SYS     SYS     SYS     SYS
NIC7    SYS     SYS     SYS     SYS     NODE    NODE    PIX     NODE    SYS     SYS     SYS     SYS     NODE    SYS     SYS      X      PHB     PHB     NODE    NODE
NIC8    SYS     SYS     SYS     SYS     NODE    NODE    PHB     NODE    SYS     SYS     SYS     SYS     NODE    SYS     SYS     PHB      X      PIX     NODE    NODE
NIC9    SYS     SYS     SYS     SYS     NODE    NODE    PHB     NODE    SYS     SYS     SYS     SYS     NODE    SYS     SYS     PHB     PIX      X      NODE    NODE
NIC10   SYS     SYS     SYS     SYS     PIX     NODE    NODE    NODE    SYS     SYS     SYS     SYS     NODE    SYS     SYS     NODE    NODE    NODE     X      NODE
NIC11   SYS     SYS     SYS     SYS     NODE    PIX     NODE    NODE    SYS     SYS     SYS     SYS     NODE    SYS     SYS     NODE    NODE    NODE    NODE     X 

Legend:

  X    = Self
  SYS  = Connection traversing PCIe as well as the SMP interconnect between NUMA nodes (e.g., QPI/UPI)
  NODE = Connection traversing PCIe as well as the interconnect between PCIe Host Bridges within a NUMA node
  PHB  = Connection traversing PCIe as well as a PCIe Host Bridge (typically the CPU)
  PXB  = Connection traversing multiple PCIe bridges (without traversing the PCIe Host Bridge)
  PIX  = Connection traversing at most a single PCIe bridge
  NV#  = Connection traversing a bonded set of # NVLinks

NIC Legend:

  NIC0: mlx5_0
  NIC1: mlx5_1
  NIC2: mlx5_2
  NIC3: mlx5_3
  NIC4: mlx5_4
  NIC5: mlx5_5
  NIC6: mlx5_6
  NIC7: mlx5_7
  NIC8: mlx5_8
  NIC9: mlx5_9
  NIC10: mlx5_10
  NIC11: mlx5_11


ulimit soft: 1048576

pseudotensor avatar Feb 20 '25 03:02 pseudotensor

Also notice some strange behavior for 8007 token "long-context" case. The output is just:

> <think> 
>> 2020x

That seems bad output and didn't happen before.

pseudotensor avatar Feb 20 '25 03:02 pseudotensor

cc @zhyncs Could you please have a look.

Fridge003 avatar Feb 20 '25 03:02 Fridge003

To be clear, the long input context performance is amazingly faster. I'm just concerned about the odd (repeatable) flaw with 8007 token input that wasn't ever there before and the slower low-input token limit.

In particular the flawed output is probably most concerning.

pseudotensor avatar Feb 20 '25 03:02 pseudotensor

I also see this in output sometimes for what normally would be trivial and work fine:

<.1.0.
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<3.0.1.0.1.0.1.0.1.0.1.0.1.0.1.0.1.1.0.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<|>
<3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.<|>
<|>
<|>
<1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.<|>
<|>
<|>
<|>
<|>
<|>
<|>
<3.3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.<
<|>
<|>
<1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1

pseudotensor avatar Feb 20 '25 03:02 pseudotensor

FYI here is same exact operations with same new version, just not passing the option for MLA:

Image

pseudotensor avatar Feb 20 '25 04:02 pseudotensor

Without MLA I'm not noticing any odd outputs.

pseudotensor avatar Feb 20 '25 04:02 pseudotensor

@pseudotensor , thank you for your report. We also noticed the strange output bug and we are trying to fix it.

For the small throughput on small contexts, we are still investigating whether it's bug or normal behavior.

Fridge003 avatar Feb 21 '25 06:02 Fridge003

Without MLA I'm not noticing any odd outputs.

@pseudotensor If you add --enable-flashinfer-mla, it will use MLA with flashinfer backend. If you remove the option, it will use MLA with Triton backend by default. Do you mean the odd output is for flashinfer MLA or for both backends?

ispobock avatar Feb 21 '25 09:02 ispobock

flashinfer MLA only.

pseudotensor avatar Feb 21 '25 09:02 pseudotensor

I have the same problem,I also added two parameters,

              --enable-torch-compile
              --enable-flashinfer-mla

Error log:

Image Image

Concurrent Performance Test Results:

Image

Hugh-yw avatar Feb 22 '25 10:02 Hugh-yw

I have the same problem, when I open flashinfer MLA.

lambert0312 avatar Feb 22 '25 23:02 lambert0312

@pseudotensor @Hugh-yw @lambert0312 The issue of bad output should be fixed by #3785, please stay tuned!

Fridge003 avatar Feb 23 '25 23:02 Fridge003

@pseudotensor @Hugh-yw @lambert0312 The issue of bad output should be fixed by #3785, please stay tuned!

Great work @Fridge003

lambert0312 avatar Feb 25 '25 14:02 lambert0312