[ggerganov/llama.cpp]具有异步内存分配/释放功能的 CUDA 内存池

2024-03-22 142 views
1

内存池的自定义实现更改为 CUDA 设备内存池。如果设备由于某种原因不支持内存池,则会回退到旧的实现。

PS 我将 CUDA_CHECK 和 CUBLAS_CHECK 更改 iddev_id因为警告“声明隐藏局部变量”

回答

6

这比当前池慢一点,对于我来说 7B 会降低 TG 性能约 2%,但为了节省内存,这仍然是值得的。

最好的解决方案可能是使用虚拟内存来根据需要扩展分配大小,如此处所述。然后,由于我们可以保证释放以与分配相反的顺序发生,因此分配内存只需要增加头指针,并释放减少它。

9

我很好奇如果有多个 GPU 的话性能会怎样。您是否使用多个 GPU 进行了测试?

4

我没有一个好的方法来使用多个 GPU 进行测试。

6
自定义内存池:

主要:n_kv_max = 2048,is_pp_shared = 0,n_gpu_layers = 999,mmq = 0

聚丙烯 TG N_KV T_PP S_PP 吨/秒 T_TGs S_TG t/s 时间 吨/秒
128 128 1 256 0.090 1419.62 2.114 60.54 2.204 116.13
128 128 2 第512章 0.101 2538.85 2.710 94.45 2.811 182.13
128 128 4 1024 0.177 2893.67 2.780 184.16 2.957 346.28
128 128 8 2048 0.336 3043.48 4.028 254.24 4.364 469.27
128 256 1 第384章 0.078 1646.22 4.229 60.53 4.307 89.16
128 256 2 第768章 0.098 2603.29 5.443 94.06 5.542 138.59
128 256 4 1536 0.166 3078.05 5.530 185.17 5.696 269.64
256 128 1 第384章 0.099 2589.47 2.134 59.98 2.233 171.97
256 128 2 第768章 0.164 3124.62 2.740 93.44 2.904 264.50
256 128 4 1536 0.342 2993.52 2.774 184.59 3.116 492.96
256 256 1 第512章 0.099 2587.45 4.209 60.82 4.308 118.84
256 256 2 1024 0.163 3140.01 5.429 94.30 5.593 183.10
256 256 4 2048 0.344 2973.30 5.589 183.21 5.934 345.15
第512章 128 1 640 0.164 3121.09 2.104 60.85 2.268 282.24
第512章 128 2 1280 0.345 2967.24 2.760 92.75 3.105 412.22
第512章 256 1 第768章 0.163 3137.25 4.269 59.97 4.432 173.29
第512章 256 2 1536 0.343 2983.73 5.503 93.04 5.846 262.73

llama_print_timings:加载时间 = 3058.06 ms llama_print_timings:采样时间 = 0.00 ms / 1 次运行(每个令牌 0.00 ms,每秒 inf 令牌) llama_print_timings:提示评估时间 = 48646.15 ms / 15888 个令牌(每个令牌 3.06 ms,每秒 326.60 个令牌) llama_print_timings:评估时间 = 19057.85 ms / 1152 次运行(每个令牌 16.54 ms,每秒 60.45 个令牌) llama_print_timings:总时间 = 70679.85 ms

CUDA内存池

主要:n_kv_max = 2048,is_pp_shared = 0,n_gpu_layers = 999,mmq = 0

聚丙烯 TG N_KV T_PP S_PP 吨/秒 T_TGs S_TG t/s 时间 吨/秒
128 128 1 256 0.094 1363.41 2.097 61.04 2.191 116.84
128 128 2 第512章 0.102 2498.24 2.685 95.35 2.787 183.69
128 128 4 1024 0.169 3031.54 2.722 188.08 2.891 354.18
128 128 8 2048 0.332 3084.63 3.936 260.18 4.268 479.89
128 256 1 第384章 0.077 1664.54 4.141 61.82 4.218 91.04
128 256 2 第768章 0.097 2640.48 5.417 94.51 5.514 139.27
128 256 4 1536 0.163 3133.11 5.521 185.46 5.685 270.19
256 128 1 第384章 0.098 2616.49 2.165 59.13 2.263 169.71
256 128 2 第768章 0.160 3197.82 2.755 92.92 2.915 263.45
256 128 4 1536 0.347 2955.18 2.766 185.10 3.113 493.48
256 256 1 第512章 0.100 2558.06 4.213 60.76 4.314 118.70
256 256 2 1024 0.164 3127.84 5.456 93.84 5.620 182.21
256 256 4 2048 0.341 3002.69 5.574 183.71 5.915 346.23
第512章 128 1 640 0.165 3111.52 2.182 58.67 2.346 272.79
第512章 128 2 1280 0.339 3017.32 2.760 92.75 3.099 412.99
第512章 256 1 第768章 0.164 3124.96 4.254 60.18 4.418 173.84
第512章 256 2 1536 0.340 3008.84 5.458 93.81 5.798 264.91

llama_print_timings:加载时间 = 3078.71 ms llama_print_timings:采样时间 = 0.00 ms / 1 次运行(每个令牌 0.00 ms,每秒 inf 令牌) llama_print_timings:提示评估时间 = 48390.87 ms / 15888 个令牌(每个令牌 3.05 ms,每秒 328.33 个令牌) llama_print_timings:评估时间 = 19050.17 ms / 1152 次运行(每个令牌 16.54 ms,每秒 60.47 个令牌) llama_print_timings:总时间 = 70436.36 ms

8

当前的实现只是进行与请求大小相同的分配,然后在可能的情况下尝试重用这些分配。例如,对于 cuBLAS,它将分配足够的内存来将用于 F16 的第一个权重转换为 F16,但是当我们需要将更大的权重转换为 F16 时,此分配将太小,并且需要新的分配,几乎翻倍内存使用情况。最坏的情况可能是在使用越来越大的批量大小进行评估时,由于 src1/dst 的先前分配太小而无法重用,因此它将在每次评估时分配新的缓冲区。它真的很糟糕,而且用途远远超出了预期。

0

我们总是可以添加toogle 在两种实现之间切换。另一个优点是:如果 NVIDIA 对内存池性能等添加新的更改,我们无需任何更改即可获得它。

4

此 PR 在我的 GTX 970(Maxwell,计算 5.2)上破坏了 llama.cpp:

CUDA error 801 at ggml-cuda.cu:6792: operation not supported
current device: 0
7

我将尝试为 CUDA 池添加额外的检查。有检查,但由于某种原因你的 GPU 可以获取池但无法分配,所以我假设你的 GPU 不支持它,所以应该在需要时回退到旧的实现。我会查一下。

1

@cebtenzzre 我在设备属性中添加了额外的检查:#3931