# MiniMax-M1
MiniMax M1拥有超长的上下文能力，100万token输入，8万token输出，足以媲美Gemini 2.5 Pro的开源模型。

## 论文
`无`

## 模型结构
MiniMax采用通用的Decoder-Only结构，基于MOE，将大量Softmax Attention替换成包含线性注意力机制的Lightning Attention(7:1)节约计算量。
<div align=center>
    <img src="./doc/MiniMax.png"/>
</div>

## 算法原理
MiniMax引入Linear Attention节约计算量，同时，其RL训练引入自主提出的CISPO，比DAPO训练收敛速度约快一倍。

Lightning Attention：把注意力计算分成块内和块间两部分，块内用传统注意力计算，块间用线性注意力的核技巧，避免了累积求和操作（cumsum）拖慢速度；

CISPO：选择裁剪重要性采样权重，这样可以保留所有token的梯度贡献，特别是在长响应中至关重要；
<div align=center>
    <img src="./doc/Lightning_Attention.png"/>
</div>


## 环境配置
```
mv MiniMax-M1_vllm MiniMax-M1 # 去框架名后缀
```
### 硬件需求
DCU型号：BW1000，节点数量：2 台，卡数：2*8 张。

### 通信配置
一、节点间基础通信

`在本地机器上配置以下内容：`

1、关闭防火墙：
```
systemctl stop  firewalld # 若为centos 
ufw disable # 若为Ubuntu
```
2、设置amd_iommu=on:
```
vim /etc/default/grub
```
<div align=center>
    <img src="./doc/amd_iommu.png"/>
</div>

更新下配置:
```
grub2-mkconfig -o /boot/efi/EFI/rocky/grub.cfg
```
重启机器后校验是否生效(检查是否存在imxxx=pt)：
```
BOOT_IMAGE=(hd0,gpt3)/vmlinuz-4.18.0-372.9.1.el8.x86_64 root=UUID=80974f58-7d23-49bb-bd8b-8e299eb0d188 ro crashkernel=auto rhgb quiet systemd.unified_cgroup_hierachy=1 systemd.unified_cgroup_hierarchy=1 amd_iommu=on iommu=pt
```

`在后面步骤启动的容器里面配置以下内容：`

```
apt update
apt install openssh-server -y
```
vim /etc/ssh/sshd_config # 修改下面PermitRootLogin为yes
```
# 取消以下4句命令的注释
RSAAuthentication yes #启用 RSA 认证
PubkeyAuthentication yes #启用公钥私钥配对认证方式
AuthorizedKeysFile ~/.ssh/authorized_keys #公钥文件路径（和下面生成的文件同）
PermitRootLogin yes #root能使用ssh登录
```

重启ssh服务，并设置开机启动：
```
service sshd restart
chkconfig sshd on

查看sshd状态：service ssh status
开启sshd服务：/etc/init.d/ssh restart
```

下面开始设置节点间免密通信的秘钥：

1、ssh-keygen生成秘钥
```
ssh-keygen -t ed25519 # 此处以ed25519为例，读者可自己设置为其它名字，遇到提问全部回车键确认
```
2、将需要使用的各个节点`~/.ssh/authorized_keys`里的秘钥收集复制到`~/.ssh/id_rsa.pub`，每个节点`~/.ssh/id_rsa.pub`里的所有秘钥最终一致。格式类似如下：
<div align=center>
    <img src="./doc/id_rsa.png"/>
</div>

3、设置节点间的通信端口号
```
/usr/sbin/sshd -p 10085 # 不同节点可以设置不同的端口号，打通秘钥和端口号之后可以用ssh -p之类的命令验证节点间是否通信已经通畅，否则需检查前面步骤是否设置成功。
```

以上设置非标准步骤，不同服务器或集群存在明显差异，无法完全复制此过程，请读者根据自己机器的实际情况灵活采用，总体目标是开启amd_iommu、打通节点间的容器内可以直接免密登录。

二、ray相关通信

`在后面步骤启动的容器里面配置以下内容：`
```
vim ~/.bashrc
```
在脚本`.bashrc`最后面添加以下命令（以BW200卡的集群为例）：
```
export ALLREDUCE_STREAM_WITH_COMPUTE=1
export VLLM_HOST_IP=x.x.x.x
export NCCL_SOCKET_IFNAME=enp33s0f3u1
export GLOO_SOCKET_IFNAME=enp33s0f3u1
unset NCCL_ALGO
export NCCL_MIN_NCHANNELS=16
export NCCL_MAX_NCHANNELS=16
export NCCL_NET_GDR_READ=1
export HIP_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
export VLLM_SPEC_DECODE_EAGER=1
export VLLM_MLA_DISABLE=0
export VLLM_USE_FLASH_MLA=1

# 若为BW卡，则添加以下信息：
export NCCL_NET_GDR_LEVEL=7
export NCCL_SDMA_COPY_ENABLE=0
export NCCL_IB_HCA=mlx5_2:1,mlx5_3:1,mlx5_4:1,mlx5_5:1,mlx5_6:1,mlx5_7:1,mlx5_8:1,mlx5_9:1
# 若为K100_AI卡，则添加以下信息(本步骤以BW卡为示例，故注释了以下信息。)：
# export VLLM_ENFORCE_EAGER_BS_THRESHOLD=44 
```
其中`VLLM_HOST_IP`和`NCCL_SOCKET_IFNAME`需要替换成每个自己机器上查到的信息，每个节点的ip不同，查询方式如下：
```
通信口和ip查询方法：ifconfig
VLLM_HOST_IP： 节点本地通信口ip
NCCL_SOCKET_IFNAME和GLOO_SOCKET_IFNAME： 节点本地通信网口名
```
`示例：`
<div align=center>
    <img src="./doc/ip.png"/>
</div>
带BW卡的集群VLLM_HOST_IP需要设置为ib网卡对应的IP，避免出现rccl超时问题：
<div align=center>
    <img src="./doc/ip_bw.png"/>
</div>

注意：添加完以上信息后必须退出容器，然后重启容器，最后重新进入容器后以上环境配置才能生效，否则后续会出现NCCL通信报错，重启容器的命令如下：
```
docker restart minimax # 必须
```

`Tips：由于通信配置方面属于运维人员的专业内容，其它人员可能了解很少，以上关于通信的配置建议读者让运维人员进行配置。`

### Docker（方法一）

```
docker pull image.sourcefind.cn:5000/dcu/admin/base/custom:vllm0.8.5-ubuntu22.04-dtk25.04.1-rc4-das1.6-py3.10-20250620-fixpy
# <your IMAGE ID>为以上拉取的docker的镜像ID替换，本镜像为：e99e26dbb33b
docker run -it --shm-size=192G --network=host --ipc=host -p 8000:8000 -v $PWD/MiniMax-M1:/home/MiniMax-M1 -v /opt/hyhal:/opt/hyhal:ro --privileged=true --device=/dev/kfd --device=//dev/dri/ --group-add video --name minimax <your IMAGE ID> bash
```
### Dockerfile（方法二）
```
cd /home/MiniMax-M1/docker
docker build --no-cache -t minimax:latest .
docker run --shm-size=192G --name minimax --network=host --ipc=host -p 8000:8000 -v /opt/hyhal:/opt/hyhal:ro --privileged=true --device=/dev/kfd --device=/dev/dri/ --group-add video -v $PWD/../../MiniMax-M1:/home/MiniMax-M1 -it minimax bash
# 若遇到Dockerfile启动的方式安装环境需要长时间等待，可注释掉里面的pip安装，启动容器后再安装python库：pip install -r requirements.txt。
```
### Anaconda（方法三）
1、关于本项目DCU显卡所需的特殊深度学习库可从光合开发者社区下载安装：
- https://developer.hpccube.com/tool/
```
DTK驱动:dtk2504
python:python3.10
torch:2.4.1
torchvision:0.19.1
triton:3.0.0
vllm:0.8.5
flash-attn:2.6.1
deepspeed:0.14.2
apex:1.4.0
transformers:4.51.1
```

`Tips：以上dtk驱动、python、torch等DCU相关工具版本需要严格一一对应。`

2、其它非特殊库参照requirements.txt安装
`无`

## 数据集
`无`

## 训练
`无`

## 推理
预训练权重目录结构：
```
/home/MiniMax-M1/
    └── MiniMax/MiniMax-M1-40k

``` 
权重下载完成后，请将`MiniMax/MiniMax-M1-40k/config.json`中的`architectures`修改为：
```
"architectures": [
    "MiniMaxText01ForCausalLM"
  ],
```

### 多机多卡
```
cd /home/MiniMax-M1

# 启动ray
ray start --head --node-ip-address=x.x.x.x --port=6379 --num-gpus=8 --num-cpus=16 # 启动主节点的ray, x.x.x.x 为前面步骤中ifconfig查到的主节点ip（VLLM_HOST_IP）。
ray start --address='x.x.x.x:6379' --num-gpus=8 --num-cpus=16 # 启动其它节点的ray, x.x.x.x 为前面步骤中ifconfig查到的主节点ip（VLLM_HOST_IP）。
# 可用ray status 查看ray的集群启动状态。
# 本项目以MiniMax-M1-40k示例，其它MiniMax-M1模型以此类推，MiniMax-M1-80k对卡数的需求更多。

# 方法一：vllm在线推理
export SAFETENSORS_FAST_GPU=1
export VLLM_USE_V1=0
# 启动服务端
vllm serve MiniMax/MiniMax-M1-40k --distributed-executor-backend ray --host 0.0.0.0 --port 8000 --tensor-parallel-size 16 --max_model_len 4096 --dtype bfloat16 --enforce-eager --gpu-memory-utilization 0.99 --trust-remote-code
# 客户端测试命令示例：
curl http://0.0.0.0:8000/v1/chat/completions     -H "Content-Type: application/json"     -d '{
        "model": "MiniMax/MiniMax-M1-40k",
        "messages": [
            {"role": "system", "content": [{"type": "text", "text": "You are a helpful assistant."}]},
            {"role": "user", "content": [{"type": "text", "text": "美国的国土面积多大?"}]}
        ]
    }'

方法二：vllm离线推理
python infer_vllm.py # 此处以MiniMax-M1-40k进行示例，MiniMax-M1-80k的推理方式同理，MiniMax-M1-80k的最低硬件需求与MiniMax-M1-40k几乎一致。
# 对于报错：AttributeError: 'NoneType' object has no attribute 'info'
# 注释掉此行原始代码的logger日志打印即可："/usr/local/lib/python3.10/dist-packages/vllm/executor/ray_distributed_executor.py", line 127
```

更多资料可参考源项目中的[`README_origin`](./README_origin.md)。

## result
vllm推理效果示例：

`输入: `
```
prompt: "美国的国土面积多大?"
```

`输出:`
```
Generated text: '<think>\n好的，我现在需要回答用户的问题：“美国的国土面积多大？”首先，我得确认自己对这个问题的了解程度。我记得美国是世界上面积较大的国家之一，但具体数字可能记不太准了。可能需要查证一下。\n\n首先，我应该回想一下美国的基本地理知识。美国位于北美洲，东临大西洋，西接太平洋，北边加拿大，南接墨西哥。国土面积包括本土的48个州和阿拉斯加、夏威夷两个州，以及一些海外领土。不过通常所说的国土面积可能指的是陆地和水域的总面积，或者只是陆地面积？\n\n接下来，我需要确定正确的单位。通常国    国土面积会用平方公里或者平方英里来表示。比如，中国是约960万平方公里，美国可能比中国小一些？或者更大？我记得之前学过的数据可能有些混淆，需要确认。\n\n然后，可能需要考虑不同的数据来源是否一致。比如维基百科的数据，或者其他权威网站的数据。另外，是否       有最新的数据，因为有时候国家的面积可能会有调整，比如通过领土争端解决或者测量技术的改进。\n\n另外，需要注意美国国土面积的组成部分。比如，本土48州的面积，阿拉斯加的面积，夏威夷的面积，以及其他海外领土如波多黎各、关岛等的面积是否包含在内。通常来说    说，国土面积可能指的是总领土，包括所有州和领土，但有时候可能只算主要部分。\n\n比如，根据我之前的记忆，美国的面积大约是9,833,517平方公里，或者约3,796,742平方英里。但不确定这个数字是否准确。或者可能更接近9.6 million平方公里？需要核实。\n\n另外，可       能存在不同的统计方式，比如总土地面积、水域面积等。例如，美国的陆地面积可能比总国土面积小，因为包括内陆水域如五大湖等。\n\n现在，我需要找到可靠的数据来源。比如，可以查阅世界银行的数据，或者美国政府官方网站的数据，或者权威的地理数据库。\n\n根据世    世界银行的数据，美国的国土面积是9,833,517平方公里。而中国的面积是9,388,210平方公里（可能不包括台湾？）。所以美国比中国稍大？或者可能我的记忆有误？\n\n不过，可能存在不同的数据来源，比如有的资料说美国面积约9.6百万平方公里，而中国约9.6百万，但可能统    统计方式不同。需要确认。\n\n另外，需要注意单位转换是否正确。比如，1平方英里等于2.58999平方公里。所以如果美国的面积是3,796,742平方英里，那么换算成平方公里就是3,796,742 × 2.58999 ≈ 9,833,517平方公里，这和世界银行的数据一致。\n\n所以，正确的答案应该    该是大约9,833'
```

### 精度
DCU与GPU精度一致，推理框架：vllm。

## 应用场景
### 算法类别
`对话问答`
### 热点应用行业
`制造,广媒,金融,能源,医疗,家居,教育`
## 预训练权重
HF下载地址为：[MiniMaxAI/MiniMax-M1-40k](https://huggingface.co/MiniMaxAI/MiniMax-M1-40k) 、[MiniMaxAI/MiniMax-M1-80k](https://huggingface.co/MiniMaxAI/MiniMax-M1-80k)
## 源码仓库及问题反馈
- http://developer.sourcefind.cn/codes/modelzoo/MiniMax-M1_vllm.git
## 参考资料
- https://github.com/MiniMax-AI/MiniMax-M1.git

