installation.md 13.4 KB
Newer Older
Zaida Zhou's avatar
Zaida Zhou committed
1
2
3
4
## Installation

There are two versions of MMCV:

Zaida Zhou's avatar
Zaida Zhou committed
5
6
- **mmcv**: comprehensive, with full features and various CUDA ops out of box. It takes longer time to build.
- **mmcv-lite**: lite, without CUDA ops but all other features, similar to mmcv\<1.0.0. It is useful when you do not need those CUDA ops.
Zaida Zhou's avatar
Zaida Zhou committed
7

Zaida Zhou's avatar
Zaida Zhou committed
8
```{warning}
9
Do not install both versions in the same environment, otherwise you may encounter errors like `ModuleNotFound`. You need to uninstall one before installing the other. `Installing the full version is highly recommended if CUDA is avaliable`.
Zaida Zhou's avatar
Zaida Zhou committed
10
```
Zaida Zhou's avatar
Zaida Zhou committed
11

12
### Install mmcv
Zaida Zhou's avatar
Zaida Zhou committed
13

14
Before installing mmcv, make sure that PyTorch has been successfully installed following the [PyTorch official installation guide](https://pytorch.org/get-started/locally/#start-locally). This can be verified using the following command
Zaida Zhou's avatar
Zaida Zhou committed
15

16
17
18
```bash
python -c 'import torch;print(torch.__version__)'
```
Zaida Zhou's avatar
Zaida Zhou committed
19

20
If version information is output, then PyTorch is installed.
Zaida Zhou's avatar
Zaida Zhou committed
21

22
#### Install with mim (recommended)
Zaida Zhou's avatar
Zaida Zhou committed
23

24
[mim](https://github.com/open-mmlab/mim) is the package management tool for the OpenMMLab projects, which makes it easy to install mmcv
Zaida Zhou's avatar
Zaida Zhou committed
25

26
27
```bash
pip install -U openmim
limm's avatar
limm committed
28
mim install mmcv
Zaida Zhou's avatar
Zaida Zhou committed
29
30
```

31
32
33
34
35
36
37
If you find that the above installation command does not use a pre-built package ending with `.whl` but a source package ending with `.tar.gz`, you may not have a pre-build package corresponding to the PyTorch or CUDA or mmcv version, in which case you can [build mmcv from source](build.md).

<details>
<summary>Installation log using pre-built packages</summary>

Looking in links: https://download.openmmlab.com/mmcv/dist/cu102/torch1.8.0/index.html<br />
Collecting mmcv<br />
limm's avatar
limm committed
38
<b>Downloading https://download.openmmlab.com/mmcv/dist/cu102/torch1.8.0/mmcv-2.0.0-cp38-cp38-manylinux1_x86_64.whl</b>
39
40
41
42
43
44
45

</details>

<details>
<summary>Installation log using source packages</summary>

Looking in links: https://download.openmmlab.com/mmcv/dist/cu102/torch1.8.0/index.html<br />
limm's avatar
limm committed
46
47
Collecting mmcv==2.0.0<br />
<b>Downloading mmcv-2.0.0.tar.gz</b>
Zaida Zhou's avatar
Zaida Zhou committed
48

49
</details>
Zaida Zhou's avatar
Zaida Zhou committed
50

limm's avatar
limm committed
51
To install a specific version of mmcv, for example, mmcv version 2.0.0, you can use the following command
Zaida Zhou's avatar
Zaida Zhou committed
52

53
```bash
limm's avatar
limm committed
54
mim install mmcv==2.0.0
Zaida Zhou's avatar
Zaida Zhou committed
55
56
```

57
58
59
60
:::{note}
If you would like to use `opencv-python-headless` instead of `opencv-python`,
e.g., in a minimum container environment or servers without GUI,
you can first install it before installing MMCV to skip the installation of `opencv-python`.
Zaida Zhou's avatar
Zaida Zhou committed
61

62
63
64
Alternatively, if it takes too long to install a dependency library, you can specify the pypi source

```bash
limm's avatar
limm committed
65
mim install mmcv -i https://pypi.tuna.tsinghua.edu.cn/simple
Zaida Zhou's avatar
Zaida Zhou committed
66
67
```

68
69
:::

limm's avatar
limm committed
70
You can run [check_installation.py](https://github.com/open-mmlab/mmcv/blob/main/.dev_scripts/check_installation.py) to check the installation of mmcv-full after running the installation commands.
71
72
73
74
75
76
77
78
79
80
81
82
83

#### Install with pip

Use the following command to check the version of CUDA and PyTorch

```bash
python -c 'import torch;print(torch.__version__);print(torch.version.cuda)'
```

Select the appropriate installation command depending on the type of system, CUDA version, PyTorch version, and MMCV version

<html>
<body>
limm's avatar
limm committed
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<style>
    select {
        /*z-index: 1000;*/
        position: absolute;
        top: 10px;
        width: 6.7rem;
    }
    #select-container {
        position: relative;
        height: 30px;
    }
    #select-cmd {
        background-color: #f5f6f7;
        font-size: 14px;
        margin-top: 20px;
    }
    /* 让每一个都间隔1.3rem */
    #select-os {
        /* left: 1.375rem; */
        left: 0;
    }
    #select-cuda {
        /* left: 9.375rem;    9.375 = 1.375 + 6.7 + 1.3 */
        left: 8rem;
    }
    #select-torch {
        /* left: 17.375rem;    17.375 = 9.375 + 6.7 + 1.3 */
        left: 16rem;
    }
    #select-mmcv {
        /* left: 25.375rem;    25.375 = 17.375 + 6.7 + 1.3 */
        left: 24rem;
    }
</style>
<div id="select-container">
    <select
            size="1"
121
            onmousedown="handleSelectMouseDown(this.id)"
limm's avatar
limm committed
122
            onclick="clickOutside(this, () => handleSelectBlur(this.id))"
123
124
            onchange="changeOS(this.value)"
            id="select-os">
limm's avatar
limm committed
125
126
127
    </select>
    <select
            size="1"
128
            onmousedown="handleSelectMouseDown(this.id)"
limm's avatar
limm committed
129
            onclick="clickOutside(this, () => handleSelectBlur(this.is))"
130
131
            onchange="changeCUDA(this.value)"
            id="select-cuda">
limm's avatar
limm committed
132
133
134
    </select>
    <select
            size="1"
135
            onmousedown="handleSelectMouseDown(this.id)"
limm's avatar
limm committed
136
            onclick="clickOutside(this, () => handleSelectBlur(this.is))"
137
138
            onchange="changeTorch(this.value)"
            id="select-torch">
limm's avatar
limm committed
139
140
141
    </select>
    <select
            size="1"
142
            onmousedown="handleSelectMouseDown(this.id)"
limm's avatar
limm committed
143
            onclick="clickOutside(this, () => handleSelectBlur(this.is))"
144
145
            onchange="changeMMCV(this.value)"
            id="select-mmcv">
limm's avatar
limm committed
146
147
148
    </select>
</div>
<pre id="select-cmd"></pre>
149
150
</body>
<script>
limm's avatar
limm committed
151
    // 各个select当前的值
152
    let osVal, cudaVal, torchVal, mmcvVal;
limm's avatar
limm committed
153
154
155
156
157
158
159
160
    function clickOutside(targetDom, handler) {
        const clickHandler = (e) => {
            if (!targetDom || targetDom.contains(e.target)) return;
            handler?.();
            document.removeEventListener('click', clickHandler, false);
        };
        document.addEventListener('click', clickHandler, false);
    }
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    function changeMMCV(val) {
        mmcvVal = val;
        change("select-mmcv");
    }
    function changeTorch(val) {
        torchVal = val;
        change("select-torch");
    }
    function changeCUDA(val) {
        cudaVal = val;
        change("select-cuda");
    }
    function changeOS(val) {
        osVal = val;
        change("select-os");
    }
limm's avatar
limm committed
177
    // 控制size大小相关的几个方法
178
179
180
181
    function handleSelectMouseDown(id) {
        const dom = document.getElementById(id);
        if (!dom) return;
        const len = dom?.options?.length;
limm's avatar
limm committed
182
        if (len >= 10) {
183
184
185
186
187
188
189
190
191
192
193
194
195
            dom.size = 10;
            dom.style.zIndex = 100;
        }
    }
    function handleSelectClick() {
        const selects = Array.from(document.getElementsByTagName("select"));
        selects.forEach(select => {
            select.size = 1;
        });
    }
    function handleSelectBlur(id) {
        const dom = document.getElementById(id);
        if (!dom) {
limm's avatar
limm committed
196
            // 如果没有指定特定的id,那就直接把所有的select都设置成size = 1
197
198
199
200
201
202
203
204
205
206
            handleSelectClick();
            return;
        }
        dom.size = 1;
        dom.style.zIndex = 1;
    }
    function changeCmd() {
        const cmd = document.getElementById("select-cmd");
        let cmdString = "pip install mmcv=={mmcv_version} -f https://download.openmmlab.com/mmcv/dist/{cu_version}/{torch_version}/index.html";
        // e.g: pip install mmcv==2.0.0rc1 -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.9/index.html
207
208
209
210
211
212
        let cudaVersion;
        if (cudaVal === "cpu" || cudaVal === "mps") {
            cudaVersion = "cpu";
        } else {
            cudaVersion = `cu${cudaVal.split(".").join("")}`;
        }
213
214
215
216
        const torchVersion = `torch${torchVal.substring(0, torchVal.length - 2)}`;
        cmdString = cmdString.replace("{cu_version}", cudaVersion).replace("{mmcv_version}", mmcvVal).replace("{torch_version}", torchVersion);
        cmd.textContent = cmdString;
    }
limm's avatar
limm committed
217
    // string数组去重
218
219
220
221
    function unique(arr) {
        if (!arr || !Array.isArray(arr)) return [];
        return [...new Set(arr)];
    }
limm's avatar
limm committed
222
    // 根据string数组生成option的DocumentFragment
223
224
225
226
227
228
    function genOptionFragment(data, id) {
        const name = id.includes("-")? id.split("-")[1] : id;
        const fragment = new DocumentFragment();
        data.forEach(option => {
            const ele = document.createElement("option");
            let text = `${name} ${option}`;
229
            if (name === "os" || option.toUpperCase() === "CPU" || option.toUpperCase() === "MPS") {
230
231
232
                text = `${option}`;
            }
            ele.textContent = text;
limm's avatar
limm committed
233
            // 添加value属性,方便下拉框选择时直接读到数据
234
            ele.value = option;
limm's avatar
limm committed
235
            // 添加点击事件监听
236
237
238
239
240
            ele.addEventListener('click', handleSelectClick);
            fragment.appendChild(ele);
        });
        return fragment;
    }
limm's avatar
limm committed
241
    // 在dom树中找到id对应的dom(select元素),并将生成的options添加到元素内
242
243
244
245
246
    function findAndAppend(data, id) {
        const fragment = genOptionFragment(data, id);
        const dom = document.getElementById(id);
        if (dom) dom.replaceChildren(fragment);
    }
limm's avatar
limm committed
247
248
249
250
251
252
    /**
     * change方法的重点在于
     * 1. 各个下拉框数据的联动
     *      OS ==> cuda ==> torch ==> mmcv
     * 2. 命令行的修改
     */
253
254
255
256
257
258
    function change(id) {
        const order = ["select-mmcv", "select-torch", "select-cuda", "select-os"];
        const idx = order.indexOf(id);
        if (idx === -1) return;
        const versionDetail = version[osVal];
        if (idx >= 3) {
limm's avatar
limm committed
259
            // 根据os修改cuda
260
261
262
263
264
265
266
267
268
            let cuda = [];
            versionDetail.forEach(v => {
                cuda.push(v.cuda);
            });
            cuda = unique(cuda);
            cudaVal = cuda[0];
            findAndAppend(cuda, "select-cuda");
        }
        if (idx >= 2) {
limm's avatar
limm committed
269
            // 根据cuda修改torch
270
271
272
273
274
275
276
277
            const torch = [];
            versionDetail.forEach(v => {
                if (v.cuda === cudaVal) torch.push(v.torch);
            });
            torchVal = torch[0];
            findAndAppend(torch, "select-torch");
        }
        if (idx >= 1) {
limm's avatar
limm committed
278
            // 根据torch修改mmcv
279
280
281
282
283
284
285
286
287
            let mmcv = [];
            versionDetail.forEach(v => {
                if (v.cuda === cudaVal && v.torch === torchVal) mmcv = v.mmcv;
            });
            mmcvVal = mmcv[0];
            findAndAppend(mmcv, "select-mmcv");
        }
        changeCmd();
    }
limm's avatar
limm committed
288
    // 初始化,处理version数据,并调用findAndAppend
289
    function init() {
limm's avatar
limm committed
290
291
        // 增加一个全局的click事件监听,作为select onBlur事件失效的兜底
        // document.addEventListener("click", handleSelectBlur);
292
        const version = window.version;
limm's avatar
limm committed
293
        // OS
294
295
296
297
298
299
        const os = Object.keys(version);
        osVal = os[0];
        findAndAppend(os, "select-os");
        change("select-os");
        changeCmd();
    }
limm's avatar
limm committed
300
    // 利用xhr获取本地version数据,如果作为html直接浏览的话需要使用本地服务器打开,否则会有跨域问题
301
302
    window.onload = function () {
        const url = "../_static/version.json"
limm's avatar
limm committed
303
        // 申明一个XMLHttpRequest
304
        const request = new XMLHttpRequest();
limm's avatar
limm committed
305
        // 设置请求方法与路径
306
        request.open("get", url);
limm's avatar
limm committed
307
        // 不发送数据到服务器
308
        request.send(null);
limm's avatar
limm committed
309
        //XHR对象获取到返回信息后执行
310
        request.onload = function () {
limm's avatar
limm committed
311
            // 返回状态为200,即为数据获取成功
312
313
314
315
316
317
318
319
320
321
322
323
            if (request.status !== 200) return;
            const data = JSON.parse(request.responseText);
            window.version = data;
            init();
        }
    }
</script>
</html>

If you do not find a corresponding version in the dropdown box above, you probably do not have a pre-built package corresponding to the PyTorch or CUDA or mmcv version, at which point you can [build mmcv from source](build.md).

:::{note}
Zaida Zhou's avatar
Zaida Zhou committed
324
mmcv is only compiled on PyTorch 1.x.0 because the compatibility
Zaida Zhou's avatar
Zaida Zhou committed
325
usually holds between 1.x.0 and 1.x.1. If your PyTorch version is 1.x.1, you
Zaida Zhou's avatar
Zaida Zhou committed
326
can install mmcv compiled with PyTorch 1.x.0 and it usually works well.
327
328
329
330
331
332
333
For example, if your PyTorch version is 1.8.1, you can feel free to choose 1.8.x.
:::

:::{note}
If you would like to use `opencv-python-headless` instead of `opencv-python`,
e.g., in a minimum container environment or servers without GUI,
you can first install it before installing MMCV to skip the installation of `opencv-python`.
Zaida Zhou's avatar
Zaida Zhou committed
334

335
336
337
Alternatively, if it takes too long to install a dependency library, you can specify the pypi source

```bash
limm's avatar
limm committed
338
mim install mmcv -i https://pypi.tuna.tsinghua.edu.cn/simple
Zaida Zhou's avatar
Zaida Zhou committed
339
340
```

341
:::
Zaida Zhou's avatar
Zaida Zhou committed
342

limm's avatar
limm committed
343
You can run [check_installation.py](https://github.com/open-mmlab/mmcv/blob/main/.dev_scripts/check_installation.py) to check the installation of mmcv after running the installation commands.
344
345
346
347
348
349
350
351

#### Using mmcv with Docker

Build with local repository

```bash
git clone https://github.com/open-mmlab/mmcv.git && cd mmcv
docker build -t mmcv -f docker/release/Dockerfile .
352
353
```

354
Or build with remote repository
Zaida Zhou's avatar
Zaida Zhou committed
355

356
```bash
limm's avatar
limm committed
357
docker build -t mmcv https://github.com/open-mmlab/mmcv.git#main:docker/release
Zaida Zhou's avatar
Zaida Zhou committed
358
359
```

360
The [Dockerfile](release/Dockerfile) installs latest released version of mmcv-full by default, but you can specify mmcv versions to install expected versions.
Zaida Zhou's avatar
Zaida Zhou committed
361

362
```bash
limm's avatar
limm committed
363
docker image build -t mmcv -f docker/release/Dockerfile --build-arg MMCV=2.0.0 .
364
365
366
367
368
369
370
371
372
373
374
```

If you also want to use other versions of PyTorch and CUDA, you can also pass them when building docker images.

An example to build an image with PyTorch 1.11 and CUDA 11.3.

```bash
docker build -t mmcv -f docker/release/Dockerfile \
    --build-arg PYTORCH=1.11.0 \
    --build-arg CUDA=11.3 \
    --build-arg CUDNN=8 \
limm's avatar
limm committed
375
    --build-arg MMCV=2.0.0 .
376
377
378
379
380
381
382
```

More available versions of PyTorch and CUDA can be found at [dockerhub/pytorch](https://hub.docker.com/r/pytorch/pytorch/tags).

### Install mmcv-lite

If you need to use PyTorch-related modules, make sure PyTorch has been successfully installed in your environment by referring to the [PyTorch official installation guide](https://github.com/pytorch/pytorch#installation).
Zaida Zhou's avatar
Zaida Zhou committed
383
384

```python
Zaida Zhou's avatar
Zaida Zhou committed
385
pip install mmcv-lite
Zaida Zhou's avatar
Zaida Zhou committed
386
```