CMakeLists.txt 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. cmake_minimum_required(VERSION 3.21)
  2. project(aphrodite_extensions LANGUAGES CXX)
  3. option(APHRODITE_TARGET_DEVICE "Target device backend for Aphrodite" "cuda")
  4. message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
  5. message(STATUS "Target device: ${APHRODITE_TARGET_DEVICE}")
  6. include(${CMAKE_CURRENT_LIST_DIR}/cmake/utils.cmake)
  7. #
  8. # Supported python versions. These versions will be searched in order, the
  9. # first match will be selected. These should be kept in sync with setup.py.
  10. #
  11. set(PYTHON_SUPPORTED_VERSIONS "3.8" "3.9" "3.10" "3.11")
  12. # Supported NVIDIA architectures.
  13. set(CUDA_SUPPORTED_ARCHS "6.1;7.0;7.5;8.0;8.6;8.9;9.0")
  14. # Supported AMD GPU architectures.
  15. set(HIP_SUPPORTED_ARCHS "gfx906;gfx908;gfx90a;gfx940;gfx941;gfx942;gfx1030;gfx1100")
  16. #
  17. # Supported/expected torch versions for CUDA/ROCm.
  18. #
  19. # Currently, having an incorrect pytorch version results in a warning
  20. # rather than an error.
  21. #
  22. # Note: the CUDA torch version is derived from pyproject.toml and various
  23. # requirements.txt files and should be kept consistent. The ROCm torch
  24. # versions are derived from Dockerfile.rocm
  25. #
  26. set(TORCH_SUPPORTED_VERSION_CUDA "2.2.1")
  27. set(TORCH_SUPPORTED_VERSION_ROCM_5X "2.0.1")
  28. set(TORCH_SUPPORTED_VERSION_ROCM_6X "2.1.1")
  29. #
  30. # Try to find python package with an executable that exactly matches
  31. # `APHRODITE_PYTHON_EXECUTABLE` and is one of the supported versions.
  32. #
  33. if (APHRODITE_PYTHON_EXECUTABLE)
  34. find_python_from_executable(${APHRODITE_PYTHON_EXECUTABLE} "${PYTHON_SUPPORTED_VERSIONS}")
  35. else()
  36. message(FATAL_ERROR
  37. "Please set APHRODITE_PYTHON_EXECUTABLE to the path of the desired python version"
  38. " before running cmake configure.")
  39. endif()
  40. #
  41. # Update cmake's `CMAKE_PREFIX_PATH` with torch location.
  42. #
  43. append_cmake_prefix_path("torch" "torch.utils.cmake_prefix_path")
  44. # Ensure the 'nvcc' command is in the PATH
  45. find_program(NVCC_EXECUTABLE nvcc)
  46. if (CUDA_FOUND AND NOT NVCC_EXECUTABLE)
  47. message(FATAL_ERROR "nvcc not found")
  48. endif()
  49. #
  50. # Import torch cmake configuration.
  51. # Torch also imports CUDA (and partially HIP) languages with some customizations,
  52. # so there is no need to do this explicitly with check_language/enable_language,
  53. # etc.
  54. #
  55. find_package(Torch REQUIRED)
  56. #
  57. # Normally `torch.utils.cpp_extension.CUDAExtension` would add
  58. # `libtorch_python.so` for linking against an extension. Torch's cmake
  59. # configuration does not include this library (presumably since the cmake
  60. # config is used for standalone C++ binaries that link against torch).
  61. # The `libtorch_python.so` library defines some of the glue code between
  62. # torch/python via pybind and is required by APHRODITE extensions for this
  63. # reason. So, add it by manually using `append_torchlib_if_found` from
  64. # torch's cmake setup.
  65. #
  66. find_library(torch_python_LIBRARY torch_python PATHS
  67. "${TORCH_INSTALL_PREFIX}/lib")
  68. #
  69. # Forward the non-CUDA device extensions to external CMake scripts.
  70. #
  71. if (NOT APHRODITE_TARGET_DEVICE STREQUAL "cuda" AND
  72. NOT APHRODITE_TARGET_DEVICE STREQUAL "rocm")
  73. if (APHRODITE_TARGET_DEVICE STREQUAL "cpu")
  74. include(${CMAKE_CURRENT_LIST_DIR}/cmake/cpu_extension.cmake)
  75. else()
  76. message(FATAL_ERROR "Unsupported Aphrodite target device: ${APHRODITE_TARGET_DEVICE}")
  77. endif()
  78. return()
  79. endif()
  80. #
  81. # Set up GPU language and check the torch version and warn if it isn't
  82. # what is expected.
  83. #
  84. if (NOT HIP_FOUND AND CUDA_FOUND)
  85. set(APHRODITE_GPU_LANG "CUDA")
  86. if (NOT Torch_VERSION VERSION_EQUAL ${TORCH_SUPPORTED_VERSION_CUDA})
  87. message(WARNING "Pytorch version ${TORCH_SUPPORTED_VERSION_CUDA} "
  88. "expected for CUDA build, saw ${Torch_VERSION} instead.")
  89. endif()
  90. elseif(HIP_FOUND)
  91. set(APHRODITE_GPU_LANG "HIP")
  92. # Importing torch recognizes and sets up some HIP/ROCm configuration but does
  93. # not let cmake recognize .hip files. In order to get cmake to understand the
  94. # .hip extension automatically, HIP must be enabled explicitly.
  95. enable_language(HIP)
  96. # ROCm 5.x
  97. if (ROCM_VERSION_DEV_MAJOR EQUAL 5 AND
  98. NOT Torch_VERSION VERSION_EQUAL ${TORCH_SUPPORTED_VERSION_ROCM_5X})
  99. message(WARNING "Pytorch version ${TORCH_SUPPORTED_VERSION_ROCM_5X} "
  100. "expected for ROCMm 5.x build, saw ${Torch_VERSION} instead.")
  101. endif()
  102. # ROCm 6.x
  103. if (ROCM_VERSION_DEV_MAJOR EQUAL 6 AND
  104. NOT Torch_VERSION VERSION_EQUAL ${TORCH_SUPPORTED_VERSION_ROCM_6X})
  105. message(WARNING "Pytorch version ${TORCH_SUPPORTED_VERSION_ROCM_6X} "
  106. "expected for ROCMm 6.x build, saw ${Torch_VERSION} instead.")
  107. endif()
  108. else()
  109. message(FATAL_ERROR "Can't find CUDA or HIP installation.")
  110. endif()
  111. #
  112. # Override the GPU architectures detected by cmake/torch and filter them by
  113. # the supported versions for the current language.
  114. # The final set of arches is stored in `APHRODITE_GPU_ARCHES`.
  115. #
  116. override_gpu_arches(APHRODITE_GPU_ARCHES
  117. ${APHRODITE_GPU_LANG}
  118. "${${APHRODITE_GPU_LANG}_SUPPORTED_ARCHS}")
  119. #
  120. # Query torch for additional GPU compilation flags for the given
  121. # `APHRODITE_GPU_LANG`.
  122. # The final set of arches is stored in `APHRODITE_GPU_FLAGS`.
  123. #
  124. get_torch_gpu_compiler_flags(APHRODITE_GPU_FLAGS ${APHRODITE_GPU_LANG})
  125. #
  126. # Set nvcc parallelism.
  127. #
  128. if(NVCC_THREADS AND APHRODITE_GPU_LANG STREQUAL "CUDA")
  129. list(APPEND APHRODITE_GPU_FLAGS "--threads=${NVCC_THREADS}")
  130. endif()
  131. #
  132. # Define extension targets
  133. #
  134. #
  135. # _C extension
  136. #
  137. set(APHRODITE_EXT_SRC
  138. "kernels/cache_kernels.cu"
  139. "kernels/attention/attention_kernels.cu"
  140. "kernels/pos_encoding_kernels.cu"
  141. "kernels/activation_kernels.cu"
  142. "kernels/layernorm_kernels.cu"
  143. "kernels/quantization/squeezellm/quant_cuda_kernel.cu"
  144. "kernels/quantization/gptq/q_gemm.cu"
  145. "kernels/cuda_utils_kernels.cu"
  146. "kernels/moe/align_block_size_kernel.cu"
  147. "kernels/pybind.cpp")
  148. if(APHRODITE_GPU_LANG STREQUAL "CUDA")
  149. list(APPEND APHRODITE_EXT_SRC
  150. "kernels/quantization/gguf/gguf_kernel.cu"
  151. "kernels/quantization/awq/gemm_kernels.cu"
  152. "kernels/quantization/quip/origin_order.cu"
  153. "kernels/quantization/marlin/marlin_cuda_kernel.cu"
  154. "kernels/quantization/aqlm/aqlm_cuda_entry.cpp"
  155. "kernels/quantization/aqlm/aqlm_cuda_kernel.cu"
  156. "kernels/quantization/bitsandbytes/int4_fp16_gemm_kernels.cu"
  157. "kernels/quantization/bitsandbytes/format.cu"
  158. "kernels/quantization/bitsandbytes/gemm_s4_f16.cu"
  159. "kernels/quantization/exl2/q_matrix.cu"
  160. "kernels/quantization/exl2/q_gemm_exl2.cu"
  161. "kernels/all_reduce/custom_all_reduce.cu")
  162. endif()
  163. define_gpu_extension_target(
  164. _C
  165. DESTINATION aphrodite
  166. LANGUAGE ${APHRODITE_GPU_LANG}
  167. SOURCES ${APHRODITE_EXT_SRC}
  168. COMPILE_FLAGS ${APHRODITE_GPU_FLAGS}
  169. ARCHITECTURES ${APHRODITE_GPU_ARCHES}
  170. WITH_SOABI)
  171. #
  172. # _moe_C extension
  173. #
  174. set(APHRODITE_MOE_EXT_SRC
  175. "kernels/moe/moe_ops.cpp"
  176. "kernels/moe/softmax.cu")
  177. define_gpu_extension_target(
  178. _moe_C
  179. DESTINATION aphrodite
  180. LANGUAGE ${APHRODITE_GPU_LANG}
  181. SOURCES ${APHRODITE_MOE_EXT_SRC}
  182. COMPILE_FLAGS ${APHRODITE_GPU_FLAGS}
  183. ARCHITECTURES ${APHRODITE_GPU_ARCHES}
  184. WITH_SOABI)
  185. #
  186. # _punica_C extension
  187. #
  188. set(APHRODITE_PUNICA_EXT_SRC
  189. "kernels/punica/bgmv/bgmv_bf16_bf16_bf16.cu"
  190. "kernels/punica/bgmv/bgmv_bf16_bf16_fp16.cu"
  191. "kernels/punica/bgmv/bgmv_bf16_fp16_bf16.cu"
  192. "kernels/punica/bgmv/bgmv_bf16_fp16_fp16.cu"
  193. "kernels/punica/bgmv/bgmv_bf16_fp32_bf16.cu"
  194. "kernels/punica/bgmv/bgmv_bf16_fp32_fp16.cu"
  195. "kernels/punica/bgmv/bgmv_fp16_bf16_bf16.cu"
  196. "kernels/punica/bgmv/bgmv_fp16_bf16_fp16.cu"
  197. "kernels/punica/bgmv/bgmv_fp16_fp16_bf16.cu"
  198. "kernels/punica/bgmv/bgmv_fp16_fp16_fp16.cu"
  199. "kernels/punica/bgmv/bgmv_fp16_fp32_bf16.cu"
  200. "kernels/punica/bgmv/bgmv_fp16_fp32_fp16.cu"
  201. "kernels/punica/bgmv/bgmv_fp32_bf16_bf16.cu"
  202. "kernels/punica/bgmv/bgmv_fp32_bf16_fp16.cu"
  203. "kernels/punica/bgmv/bgmv_fp32_fp16_bf16.cu"
  204. "kernels/punica/bgmv/bgmv_fp32_fp16_fp16.cu"
  205. "kernels/punica/bgmv/bgmv_fp32_fp32_bf16.cu"
  206. "kernels/punica/bgmv/bgmv_fp32_fp32_fp16.cu"
  207. "kernels/punica/punica_ops.cc")
  208. #
  209. # Copy GPU compilation flags+update for punica
  210. #
  211. set(APHRODITE_PUNICA_GPU_FLAGS ${APHRODITE_GPU_FLAGS})
  212. list(REMOVE_ITEM APHRODITE_PUNICA_GPU_FLAGS
  213. "-D__CUDA_NO_HALF_OPERATORS__"
  214. "-D__CUDA_NO_HALF_CONVERSIONS__"
  215. "-D__CUDA_NO_BFLOAT16_CONVERSIONS__"
  216. "-D__CUDA_NO_HALF2_OPERATORS__")
  217. #
  218. # Filter out CUDA architectures < 8.0 for punica.
  219. #
  220. if (${APHRODITE_GPU_LANG} STREQUAL "CUDA")
  221. set(APHRODITE_PUNICA_GPU_ARCHES)
  222. foreach(ARCH ${APHRODITE_GPU_ARCHES})
  223. string_to_ver(CODE_VER ${ARCH})
  224. if (CODE_VER GREATER_EQUAL 8.0)
  225. list(APPEND APHRODITE_PUNICA_GPU_ARCHES ${ARCH})
  226. endif()
  227. endforeach()
  228. message(STATUS "Punica target arches: ${APHRODITE_PUNICA_GPU_ARCHES}")
  229. endif()
  230. if (APHRODITE_PUNICA_GPU_ARCHES)
  231. define_gpu_extension_target(
  232. _punica_C
  233. DESTINATION aphrodite
  234. LANGUAGE ${APHRODITE_GPU_LANG}
  235. SOURCES ${APHRODITE_PUNICA_EXT_SRC}
  236. COMPILE_FLAGS ${APHRODITE_PUNICA_GPU_FLAGS}
  237. ARCHITECTURES ${APHRODITE_PUNICA_GPU_ARCHES}
  238. WITH_SOABI)
  239. else()
  240. message(WARNING "Unable to create _punica_C target because none of the "
  241. "requested architectures (${APHRODITE_GPU_ARCHES}) are supported, i.e. >= 8.0")
  242. endif()
  243. #
  244. # _hadamard_C extension
  245. #
  246. set(APHRODITE_HADAMARD_EXT_SRC
  247. "kernels/hadamard/fast_hadamard_transform.cpp"
  248. "kernels/hadamard/fast_hadamard_transform_cuda.cu")
  249. #
  250. # Copy GPU compilation flags+update for hadamard
  251. #
  252. set(APHRODITE_HADAMARD_GPU_FLAGS ${APHRODITE_GPU_FLAGS})
  253. list(APPEND APHRODITE_HADAMARD_GPU_FLAGS
  254. "-U__CUDA_NO_HALF_OPERATORS__"
  255. "-U__CUDA_NO_HALF_CONVERSIONS__"
  256. "-U__CUDA_NO_BFLOAT16_OPERATORS__"
  257. "-U__CUDA_NO_BFLOAT16_CONVERSIONS__"
  258. "-U__CUDA_NO_BFLOAT162_OPERATORS__"
  259. "-U__CUDA_NO_BFLOAT162_CONVERSIONS__"
  260. "--expt-relaxed-constexpr"
  261. "--expt-extended-lambda"
  262. "--use_fast_math"
  263. "--ptxas-options=-v"
  264. "-lineinfo")
  265. #
  266. # Filter out CUDA architectures < 7.0 for hadamard.
  267. #
  268. if (${APHRODITE_GPU_LANG} STREQUAL "CUDA")
  269. set(APHRODITE_HADAMARD_GPU_ARCHES)
  270. foreach(ARCH ${APHRODITE_GPU_ARCHES})
  271. string_to_ver(CODE_VER ${ARCH})
  272. if (CODE_VER GREATER_EQUAL 7.0)
  273. list(APPEND APHRODITE_HADAMARD_GPU_ARCHES ${ARCH})
  274. endif()
  275. endforeach()
  276. message(STATUS "Hadamard target arches: ${APHRODITE_HADAMARD_GPU_ARCHES}")
  277. endif()
  278. if (APHRODITE_HADAMARD_GPU_ARCHES)
  279. define_gpu_extension_target(
  280. _hadamard_C
  281. DESTINATION aphrodite
  282. LANGUAGE ${APHRODITE_GPU_LANG}
  283. SOURCES ${APHRODITE_HADAMARD_EXT_SRC}
  284. COMPILE_FLAGS ${APHRODITE_HADAMARD_GPU_FLAGS}
  285. ARCHITECTURES ${APHRODITE_HADAMARD_GPU_ARCHES}
  286. WITH_SOABI)
  287. else()
  288. message(WARNING "Unable to create _hadamard_C target because none of the "
  289. "requested architectures (${APHRODITE_GPU_ARCHES}) are supported, i.e. >= 7.0")
  290. endif()
  291. #
  292. # _conv1d_C extension
  293. #
  294. set(APHRODITE_CONV1D_EXT_SRC
  295. "kernels/causal_conv1d/causal_conv1d.cpp"
  296. "kernels/causal_conv1d/causal_conv1d_fwd.cu"
  297. "kernels/causal_conv1d/causal_conv1d_update.cu")
  298. #
  299. # Use the hadamard compilation flags
  300. #
  301. set(APHRODITE_CONV1D_GPU_FLAGS ${APHRODITE_HADAMARD_GPU_FLAGS})
  302. #
  303. # Filter out arches < 5.3 for conv1d.
  304. #
  305. if (${APHRODITE_GPU_LANG} STREQUAL "CUDA")
  306. set(APHRODITE_CONV1D_GPU_ARCHES)
  307. foreach(ARCH ${APHRODITE_GPU_ARCHES})
  308. string_to_ver(CODE_VER ${ARCH})
  309. if (CODE_VER GREATER_EQUAL 5.3)
  310. list(APPEND APHRODITE_CONV1D_GPU_ARCHES ${ARCH})
  311. endif()
  312. endforeach()
  313. message(STATUS "Conv1d target arches: ${APHRODITE_CONV1D_GPU_ARCHES}")
  314. endif()
  315. if (APHRODITE_CONV1D_GPU_ARCHES)
  316. define_gpu_extension_target(
  317. _conv1d_C
  318. DESTINATION aphrodite
  319. LANGUAGE ${APHRODITE_GPU_LANG}
  320. SOURCES ${APHRODITE_CONV1D_EXT_SRC}
  321. COMPILE_FLAGS ${APHRODITE_CONV1D_GPU_FLAGS}
  322. ARCHITECTURES ${APHRODITE_CONV1D_GPU_ARCHES}
  323. WITH_SOABI)
  324. else()
  325. message(WARNING "Unable to create _conv1d_C target because none of the "
  326. "requested architectures (${APHRODITE_GPU_ARCHES}) are supported, i.e. >= 5.3")
  327. endif()
  328. #
  329. # _selective_scan_C extension
  330. #
  331. set(APHRODITE_SELECTIVE_SCAN_EXT_SRC
  332. "kernels/selective_scan/selective_scan.cpp"
  333. "kernels/selective_scan/selective_scan_fwd_fp32.cu"
  334. "kernels/selective_scan/selective_scan_fwd_fp16.cu"
  335. "kernels/selective_scan/selective_scan_fwd_bf16.cu")
  336. #
  337. # Use the hadamard compilation flags
  338. #
  339. set(APHRODITE_SELECTIVE_SCAN_GPU_FLAGS ${APHRODITE_HADAMARD_GPU_FLAGS})
  340. #
  341. # Filter out arches < 6.0 for selective_scan.
  342. #
  343. if (${APHRODITE_GPU_LANG} STREQUAL "CUDA")
  344. set(APHRODITE_SELECTIVE_SCAN_GPU_ARCHES)
  345. foreach(ARCH ${APHRODITE_GPU_ARCHES})
  346. string_to_ver(CODE_VER ${ARCH})
  347. if (CODE_VER GREATER_EQUAL 5.3)
  348. list(APPEND APHRODITE_SELECTIVE_SCAN_GPU_ARCHES ${ARCH})
  349. endif()
  350. endforeach()
  351. message(STATUS "Selective scan target arches: ${APHRODITE_SELECTIVE_SCAN_GPU_ARCHES}")
  352. endif()
  353. if (APHRODITE_SELECTIVE_SCAN_GPU_ARCHES)
  354. define_gpu_extension_target(
  355. _selective_scan_C
  356. DESTINATION aphrodite
  357. LANGUAGE ${APHRODITE_GPU_LANG}
  358. SOURCES ${APHRODITE_SELECTIVE_SCAN_EXT_SRC}
  359. COMPILE_FLAGS ${APHRODITE_SELECTIVE_SCAN_GPU_FLAGS}
  360. ARCHITECTURES ${APHRODITE_SELECTIVE_SCAN_GPU_ARCHES}
  361. WITH_SOABI)
  362. else()
  363. message(WARNING "Unable to create _selective_scan_C target because none of the "
  364. "requested architectures (${APHRODITE_GPU_ARCHES}) are supported, i.e. >= 5.3")
  365. endif()
  366. #
  367. # Add the `default` target which detects which extensions should be
  368. # built based on platform/architecture. This is the same logic that
  369. # setup.py uses to select which extensions should be built and should
  370. # be kept in sync.
  371. #
  372. # The `default` target makes direct use of cmake easier since knowledge
  373. # of which extensions are supported has been factored in, e.g.
  374. #
  375. # mkdir build && cd build
  376. # cmake -G Ninja -DAPHRODITE_PYTHON_EXECUTABLE=`which python3` -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=../aphrodite ..
  377. # cmake --build . --target default
  378. #
  379. add_custom_target(default)
  380. if(APHRODITE_GPU_LANG STREQUAL "CUDA" OR APHRODITE_GPU_LANG STREQUAL "HIP")
  381. message(STATUS "Enabling C extension.")
  382. add_dependencies(default _C)
  383. endif()
  384. if(APHRODITE_GPU_LANG STREQUAL "CUDA")
  385. message(STATUS "Enabling moe extension.")
  386. add_dependencies(default _moe_C)
  387. # Enable the extra kernels if the appropriate flags are set.
  388. if (APHRODITE_PUNICA_GPU_ARCHES AND
  389. (ENV{APHRODITE_INSTALL_PUNICA_KERNELS} OR APHRODITE_INSTALL_PUNICA_KERNELS))
  390. message(STATUS "Enabling punica extension.")
  391. add_dependencies(default _punica_C)
  392. endif()
  393. if (APHRODITE_HADAMARD_GPU_ARCHES AND
  394. (ENV{APHRODITE_INSTALL_HADAMARD_KERNELS} OR APHRODITE_INSTALL_HADAMARD_KERNELS))
  395. message(STATUS "Enabling hadamard extension.")
  396. add_dependencies(default _hadamard_C)
  397. endif()
  398. if (APHRODITE_CONV1D_GPU_ARCHES AND
  399. (ENV{APHRODITE_INSTALL_CONV1D_KERNELS} OR APHRODITE_INSTALL_CONV1D_KERNELS))
  400. message(STATUS "Enabling conv1d extension.")
  401. add_dependencies(default _conv1d_C)
  402. endif()
  403. if (APHRODITE_SELECTIVE_SCAN_GPU_ARCHES AND
  404. (ENV{APHRODITE_INSTALL_SELECTIVE_SCAN_KERNELS} OR APHRODITE_INSTALL_SELECTIVE_SCAN_KERNELS))
  405. message(STATUS "Enabling selective_scan extension.")
  406. add_dependencies(default _selective_scan_C)
  407. endif()
  408. endif()