数据科学基础开发环境

基于 Docker Compose 搭建了常用的大数据工具,可以作为大数据及 AI 相关的开发环境。

Spark

pyspark 创建 session

1
spark = pyspark.sql.SparkSession.builder.master("spark://datascience-spark:7077").getOrCreate()

访问 Hadoop

1
2
3
# 只需要指定 hadoop name node 的地址即可
# namenode 是 hadoop namenode 的机器名,这里可以反解出 ip
df = spark.read.json("hdfs://namenode/sample.json")

vcpkg

使用模式

项目使用 vcpkg 解决依赖问题

参考这里

项目作为 port 供其他项目使用

创建内部 registry 供组织内使用

添加 port 到内部 registry

安装

参考

安装依赖

1
2
# arch
$ sudo pacman -S curl zip unzip tar cmake ninja

安装 vcpkg

1
2
$ git clone https://github.com/Microsoft/vcpkg.git
$ ./vcpkg/bootstrap-vcpkg.sh

概念

使用

引入 CMAKE_TOOLCHAINE_FILE

1
2
3
4
5
6
# 命令行
cmake ... -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake

# CMakeLists.txt 内
## NOTE: 要在 project 之前
set(CMAKE_TOOLCHAIN_FILE /path/to/vcpkg/scripts/buildsystems/vcpkg.cmake)

vcpkg-configuration.json

example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-configuration.schema.json",
"default-registry": {
"kind": "git",
"repository": "https://internal/mirror/of/github.com/Microsoft/vcpkg",
"baseline": "eefee7408133f3a0fef711ef9c6a3677b7e06fd7"
},
"registries": [
{
"kind": "git",
"repository": "https://github.com/northwindtraders/vcpkg-registry",
"baseline": "dacf4de488094a384ca2c202b923ccc097956e0c",
"packages": [ "beicode", "beison" ]
}
],
"overlay-ports": [
"./team-ports",
"./custom-ports"
],
"overlay-triplets": [ "./my-triplets" ]
}

软件包搜索

Manifest 模式

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"name": "cook-cpp",
"version": "0.0.1",
"dependencies": [
"boost",
"fmt",
"spdlog"
],
"overrides": [
{
"name": "boost",
"version": "1.82.0"
},
{
"name": "fmt",
"version": "9.1.0"
},
{
"name": "spdlog",
"version": "1.11.0"
}
],
"builtin-baseline": "21bbb14c4113b89cd06402e852e075341722304f"
}
  • buildin-baseline
    • vcpkg 的 commit id
    • 如果要制定版本(使用 overrides),则必须设置该项

配置文件

  • vcpkg.json
  • vcpkg-configuration.json

添加内部库

项目使用 vcpkg

官方文档

Makefile 工程

1
2
3
4
5
6
set(MAKE_OPTS "")
if(VCPKG_LIBRARY_LINKAGE STREQUAL "static")
list(APPEND MAKE_OPTS "STATIC=1")
else()
list(APPEND MAKE_OPTS "SHARED=1")
endif()
1
2
3
4
5
6
# Configure
# 1. 如果没有 configure.ac 等自动化配置,需要 SKIP_CONFIGURE,且 COPY_SOURCE
# vcpkg_configure_make(SOURCE_PATH "${SOURCE_PATH}" OPTIONS ${MAKE_OPTS} COPY_SOURCE SKIP_CONFIGURE)
vcpkg_configure_make(SOURCE_PATH "${SOURCE_PATH}" OPTIONS ${MAKE_OPTS})
vcpkg_build_make()
vcpkg_fixup_pkgconfig()

自定义克隆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
set(GIT_REF 7.0.3)
set(GIT_URL https://github.com/aerospike/aerospike-client-c.git)

# custome clone git repo
set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/${GIT_REF})
file(MAKE_DIRECTORY ${SOURCE_PATH})
if (NOT EXISTS "${SOURCE_PATH}/.git")
message(STATUS "Cloning")
vcpkg_execute_required_process(
COMMAND ${GIT} clone ${GIT_URL} ${SOURCE_PATH}
WORKING_DIRECTORY ${SOURCE_PATH}
LOGNAME clone
)
endif ()

message(STATUS "Checkout revision ${GIT_REF}")
vcpkg_execute_required_process(
COMMAND ${GIT} checkout ${GIT_REF}
WORKING_DIRECTORY ${SOURCE_PATH}
LOGNAME checkout
)

message(STATUS "Fetching submodules")
vcpkg_execute_required_process(
COMMAND ${GIT} submodule update --init
WORKING_DIRECTORY ${SOURCE_PATH}
LOGNAME submodule
)

Registries

获取 SHA512

1
vcpkg hash /path/to/source.tar.gz

获取 versions 的 git-tree

  • 添加 ports/<library> 目录及配置(profile.cmake、vcpkg.json) 等
  • 提交 commit
  • 使用如下命令获取 git-tree
1
git rev-parse HEAD:ports/<library>

Patch

1
2
3
4
# 生成
git diff > patch
# 应用
git apply patch

注意

  • 不要直接复制 patch 内容,容易出现 error: corrupt patch at line * 的问题

引入包

cmake targets

通过 CMake Targets 引入目标,适用于基于 CMake 编译的库,且导出目标配置文件({target}Config.cmake)。

1
2
find_package(target CONFIG REQUIRED)
target_link_libraries(main PRIVATE target)

find_library

针对未提供 CMake 和 PkgConfig 引入方式的库,可使用此方法。

1
2
find_library(TargetVar NAMES target REQUIRED)
target_link_libraries(main PRIVATE ${TargetVar})

示例。

1
2
find_library(PolarisApi NAMES libpolaris_api.a REQUIRED)
target_link_libraries(main ${PolarisApi})

pkgconfig

1
2
3
include(FindPkgConfig)
pkg_check_modules(target REQUIRED IMPORTED_TARGET target)
target_link_libraries(main PRIVATE PkgConfig::brpc)

thrift 示例。

1
2
3
4
5
6
find_package(PkgConfig REQUIRED)
find_package(Thrift CONFIG)
if(NOT TARGET thrift::thrift)
pkg_search_module(THRIFT REQUIRED IMPORTED_TARGET GLOBAL thrift)
add_library(thrift::thrift ALIAS PkgConfig::THRIFT)
endif()

Trouble Shooting

OUT_SOURCE_PATH

压缩包解压路径在 {VCPKG_HOME}/buildtrees/{library}/src/ar-{version}-{whatever}.clean

清除安装的包

1
2
rm -r {VCPKG_HOME}/buildtrees/{library}
rm -r {VCPKG_HOME}/packages/{library}

patch failed: error: corrupt patch at line

  • patch 文件过期,内容不对,需要重新生成 patch 文件
  • 不可见字符问题
    • 不要直接拷贝 patch 内容,要复制 patch 文件
      • 复制粘贴有可能导致不可见字符变更
      • 部分 IDE 会自动优化不可见字符,导致 patch 文件失效

pkg_check_modules 无法找到包

错误信息

1
2
3
4
-- Checking for module 'cassandra_static'
-- No package 'cassandra_static' found
CMake Error at /snap/cmake/1328/share/cmake-3.27/Modules/FindPkgConfig.cmake:607 (message):
A required package was not found

解决

正常来说,vcpkg 安装的包,如果有 pkgconfig 是可以通过 pkg_check_modules 找到的。出现问题的原因是 find_package 引入包时意外导致 pkg_check_modules 不可用,解决方案有两个。

  • 找到出现问题的 find_package 语句,并移到后面
  • 遍历 CMAKE_PREFIX_PATH 并追加 lib/pkgconfig 后加入到 ENV{PKG_CONFIG_PATH}

或者设置如下内容。

1
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)

以 tcmalloc 为例。

1
2
3
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
include(FindPkgConfig)
pkg_check_modules(gperftools REQUIRED IMPORTED_TARGET GLOBAL libtcmalloc)

Boost

head only library

vcpkg.json

1
2
3
4
5
6
7
8
9
10
{
"name": "feature-generator-server",
"version": "0.0.1",
"dependencies": [
"boost-core",
"boost-stacktrace",
"boost-pfr",
"boost-..."
]
}

CMakeLists.txt

1
2
find_package(Boost REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
1
2
find_package(Boost REQUIRED COMPONENTS locale)
set(THIRD_LIBRARIES Boost::locale)

patch failed

在更新版本之后出现 patch failed 异常,尝试删除对应的缓存解决。

1
$ rm -r {VCPKG_HOME}/buildtrees/protobuf

引用问题

case 1 通过查看 share/{lib}/{lib}Config.cmake 查看

1
2
include_directories(${JSON11_INCLUDE_DIRS})
target_link_libraries({target} ${JSON11_LIBRARIES})

unable to find “Ninja”

full message

1
CMake Error: CMake was unable to find a build program corresponding to "Ninja".  CMAKE_MAKE_PROGRAM is not set.  You probably need to select a different build tool.

可能的原因

  • 没有或不是最新的 ninja,从 这里 下载最新 ninja 程序
  • 使用的是 ninja-build 程序,需要把 ninja 复制或软链称 ninja-build
  • 其他原因,排查错误信息的 vcpkg-manifest-install.log 文件
    • git 权限问题
    • 磁盘内存不足

submodule

在使用 vcpkg_from_git 时,不会初始化 submodule,需要自己处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
set(GIT_URL {git-or-http-url})
set(GIT_REF {commit-id-or-tag})

set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/${GIT_REF})
file(MAKE_DIRECTORY ${SOURCE_PATH})
message(STATUS "build {lib} [CURRENT_BUILDTREES_DIR=${CURRENT_BUILDTREES_DIR}, SOURCE_PATH=${SOURCE_PATH}]")
if (NOT EXISTS "${SOURCE_PATH}/.git")
message(STATUS "Cloning")
vcpkg_execute_required_process(
COMMAND ${GIT} clone ${GIT_URL} ${SOURCE_PATH}
WORKING_DIRECTORY ${SOURCE_PATH}
LOGNAME clone
)
endif ()

message(STATUS "Fetching submodules")
vcpkg_execute_required_process(
COMMAND ${GIT} submodule update --init
WORKING_DIRECTORY ${SOURCE_PATH}
LOGNAME submodule
)

message(STATUS "Checkout revision ${GIT_REF}")
vcpkg_execute_required_process(
COMMAND ${GIT} checkout ${GIT_REF}
WORKING_DIRECTORY ${SOURCE_PATH}
LOGNAME checkout
)

Checkout Git Tree

检出并保存在其他路径

1
2
mkdir /tmp/<tree-ish>
git archive <tree-ish> | tar -x -C /tmp/<tree-ish>

从 remote 检出

1
git archive --remote=https://github.com/user/repo.git <tree-ish> | tar -x -C /tmp/<tree-ish>

示例

从 vcpkg 检出 gRPC 1.22.0 的 port 文件到当前目录。

1
2
3
4
5
# 从本地检出
git -C ~/.local/vcpkg archive f9ee8bb31f04f4e6a8c0d3e96fbb98deeb448d45 | tar -x -C .

# 从 remote 检出 (不一定能行)
git archive --remote=git@github.com:grpc/grpc.git f9ee8bb31f04f4e6a8c0d3e96fbb98deeb448d45 | tar -x -C .

--host 问题

起因是使用镜像编译,设置如下变量。

1
2
export CC=/usr/bin/gcc10-cc
export CXX=/usr/bin/gcc10-c++

编译的时候,有些依赖库会报错。看 config 日志在调用库的 configure 中传入 --host=gcc10,部分信息如下。

1
2
config-x64-linux-dbg-err.log:invalid configuration `gcc10': machine `gcc10-unknown' not recognized
config-x64-linux-dbg-config.log:host=gcc10

这显然是 vcpkg 在获取 host 时出错了。具体原因未知,解决方式是把 CC 和 CXX 设置为 /usr/bin/{cc/cxx}

1
2
3
4
ln -s /usr/bin/gcc10-cc /usr/bin/cc
ln -s /usr/bin/gcc10-c++ /usr/bin/c++
export CC=/usr/bin/cc
export CXX=/usr/bin/c++

Makefile 工程 build 失败

  1. vcpkg_build_make 默认会构建目标 all
1
2
CMake Error at scripts/cmake/vcpkg_execute_build_process.cmake:134 (message):
Command failed: /usr/bin/make STATIC=1 SHARED=0 V=1 -j 1 -f Makefile all

可以通过如下命令指定目标。

1
vcpkg_build_make(OPTIONS STATIC=1 SHARED=0 DISABLE_PARALLEL BUILD_TARGET build INSTALL_TARGET install)
  1. 尝试添加 DISABLE_PARALLEL,关闭并行编译

AR 命令错误

makefile

1
2
3
4
5
6
AR= ar rc
...
$(CORE_T): $(CORE_O) $(AUX_O) $(LIB_O)
$(info CKPT2 : $(AR))
$(AR) $@ $(sort $?)
$(RANLIB) $@

使用 vcpkg 编译时,命令如下。

1
CKPT2 : ar

但是手动运行命令时,输入如下。

1
CKPT2 : ar rc

可以看到,在使用 vcpkg 编译时(vcpkg_build_make),makefile 中指定的 AR 变量没生效。

在 AR 重新定义前,添加打印。

1
2
3
$(info CKPT3 AR=$(AR))
AR= ar rc
$(info CKPT4 AR=$(AR))

输入如下。

1
2
3
4
5
6
7
# vcpkg 输出:
CKPT3 AR=ar
CKPT4 AR=ar

# 手动运行输出:
CKPT3 AR=ar
CKPT4 AR=ar rc

可以看到,vcpkg 运行时,AR 变量没有修改成功。再去检查 AR 的来源。

1
2
3
4
5
6
7
# 打印代码
$(info CKPT6 AR 的来源: $(origin AR))

# vcpkg 运行
CKPT6 AR 的来源: environment override
# 手动运行
CKPT6 AR 的来源: default

可以看到,vcpkg 在运行时,定义了环境变量 AR。

解决方案 一

1
2
# 修改 makefile 中的赋值语句,添加 override 强制赋值
override AR= ar rc

解决方案 二

1
2
# 在父 makefile 中添加 unexport
unexport AR

解决方案 三

1
2
# 定义 AR 参数
vcpkg_build_make(DISABLE_PARALLEL OPTIONS "AR=ar rc")

这种方案有可能可以解决问题,但是需要知道的是对所有 ar 命令都加了 rc,可能会造成其他问题。

Make 工程跳过配置编译出错

1
2
3
4
5
6
7
8
9
10
# install prefix fixup: 由于 aerospike client 没有 configure 脚本,所以需要手动设置安装路径 INSTALL_PREFIX
# INSTALL_PREFIX 是代码文件 pkg/install 内定义的
# 这里的 INSTALL_PREFIX 是 {prefix_dir}/{install_dir}
# vcpkg_configure_make 默认会指定 --prefix, 但是这里没有 configure 脚本,添加了 SKIP_CONFIGURE 选项
# 因此这里修复 INSTALL_PREFIX 为 {prefix_dir}/{install_dir}
# 不然这里会报错: https://github.com/microsoft/vcpkg/blob/master/scripts/cmake/vcpkg_build_make.cmake#L177C8-L177C102
# 报错代码: file(RENAME "${CURRENT_PACKAGES_DIR}_tmp${Z_VCPKG_INSTALL_PREFIX}" "${CURRENT_PACKAGES_DIR}")
string(REGEX REPLACE "([a-zA-Z]):/" "/\\1/" Z_VCPKG_INSTALL_PREFIX "${CURRENT_INSTALLED_DIR}")
set(ENV_INSTALL_PREFIX_ "$ENV{INSTALL_PREFIX}")
set(ENV{INSTALL_PREFIX} "${CURRENT_PACKAGES_DIR}${Z_VCPKG_INSTALL_PREFIX}")

INSTALL_PREFIX 和库有关

二进制缓存

vcpkg 默认使用文件类型的缓存,在编译时默认也会查找默认位置的缓存。如果需要指定新的位置,可以使用下面的配置。

1
vcpkg install {package} --binarysource="files,/root/.cache/vcpkg/archives --dry-run --debug

但是,有时候不使用缓存,重新编译,这种一般是因为 vcpkg 记录的 ABI 有变动,下面是 package 的示例 ABI 信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[DEBUG] <abientries for zlib:x86-windows>
[DEBUG] 0001-Prevent-invalid-inclusions-when-HAVE_-is-set-to-0.patch|750b9542cb55e6328cca01d3ca997f1373b9530afa95e04213168676936e7bfa
[DEBUG] 0002-skip-building-examples.patch|835ddecfed752e0f49be9b0f8ff7ba76541cb0a150044327316e22ca84f8d0c2
[DEBUG] 0003-build-static-or-shared-not-both.patch|d6026271dcb3d8fc74b41e235620ae31576a798e77aa411c3af8cd9e948c02b1
[DEBUG] 0004-android-and-mingw-fixes.patch|37a43eddbcb1b7dde49e7659ae895dfd0ff1df66666c1371ba7d5bfc49d8b438
[DEBUG] cmake|3.26.2
[DEBUG] features|core
[DEBUG] portfile.cmake|ac63047b644fa758860dd7ba48ff9a13b058c6f240b8e8d675b8fbba035976be
[DEBUG] ports.cmake|5a8e00cedff0c898b1f90f7d129329d0288801bc9056562b039698caf31ff3f3
[DEBUG] post_build_checks|2
[DEBUG] powershell|7.3.6
[DEBUG] triplet|x86-windows
[DEBUG] triplet_abi|3e71dd1d4afa622894ae367adbbb1ecbd42c57c51428a86b675fa1c8cad3a581-36b818778ba6f2c16962495caedb9a7b221d5be4c60de1cd3060f549319a9931-f5d02a6542664cfbd4a38db478133cbb1a18f315
[DEBUG] usage|be22662327df993eebc437495add75acb365ab18d37c7e5de735d4ea4f5d3083
[DEBUG] vcpkg-cmake|1b3dac4b9b0bcbef227c954b495174863feebe3900b2a6bdef0cd1cf04ca1213
[DEBUG] vcpkg-cmake-wrapper.cmake|5d49ef2ee6448479c2aad0e5f732e2676eaba0411860f9bebabe6002d66f57d1
[DEBUG] vcpkg.json|bc94e2540efabe36130a806381a001c57194e7de67454ab7ff1e30aa15e6ce23
[DEBUG] vcpkg_copy_pdbs|d57e4f196c82dc562a9968c6155073094513c31e2de475694143d3aa47954b1c
[DEBUG] vcpkg_fixup_pkgconfig|588d833ff057d3ca99c14616c7ecfb5948b5e2a9e4fc02517dceb8b803473457
[DEBUG] vcpkg_from_git|8f27bff0d01c6d15a3e691758df52bfbb0b1b929da45c4ebba02ef76b54b1881
[DEBUG] vcpkg_from_github|b743742296a114ea1b18ae99672e02f142c4eb2bef7f57d36c038bedbfb0502f
[DEBUG] vcpkg_replace_string|d43c8699ce27e25d47367c970d1c546f6bc36b6df8fb0be0c3986eb5830bd4f1
[DEBUG] </abientries>
  • 常见的变动原因
    • gcc/g++ 不一致
    • cmake 版本有变动,在使用 vcpkg install 时,如果没有 cmake 或者版本不满足, vcpkg 会下载新版本的 cmake

minikube usage

文档

安装

  • minikube install

  • docker install

    • 需要配置当前用户操作权限
  • kubectl 安装

    • ubuntu sudo snap install kubectl --classic
    • arch sudo pamac install kubectl

archilinux

driver=virtualbox

1
2
3
4
5
6
7
$ sudo pamac install virtualbox
$ sudo modprobe vboxdrv
$ sudo modprobe vboxnetadp
$ sudo modprobe vboxnetflt

# 启动 minikube
$ minikube start --driver=virtualbox

配置

启用私有仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ minikube addons configure registry-creds

Do you want to enable AWS Elastic Container Registry? [y/n]: n

Do you want to enable Google Container Registry? [y/n]: n

Do you want to enable Docker Registry? [y/n]: y
-- Enter docker registry server url: registry.cn-hangzhou.aliyuncs.com
-- Enter docker registry username: <username>
-- Enter docker registry password:

Do you want to enable Azure Container Registry? [y/n]: n
✅ registry-creds was successfully configured
$ minikube addons enable registry-creds

注册

1
2
3
4
5
6
7
8
9
10
11
$ kubectl create secret generic regcred \
--from-file=.dockerconfigjson=$HOME/.docker/config.json \
--type=kubernetes.io/dockerconfigjson \
--namespace=default

# 在 deployment.yml 中添加如下内容
spec:
...
spec:
imagePullSecrets:
- name: regcred

问题

driver=docker 时无法通过宿主机 ip 访问 service

  • service type 设置为 NodePort
  • 无法通过宿主机的 ip 或者 127.0.0.1 + service node port 访问服务

cuda

概念

核函数

核函数是运行在 GPU 设备上的函数,使用 __global__ 定义,且返回类型必须是 void

硬件相关

Streaming Multiprocessor(SM)

  • 多个 SP 加上其他资源组成一个 SM
  • 其他资源包括
    • warp scheduler
    • register
    • shared memery

Streaming Processor(SP)

  • 也称为 CUDA core
  • 最基本的处理单元

img

GPU 中的内存

  • 全局内存(Global Memory)
    • GPU 上所有线程共享访问
  • 共享内存(Shared Memory)
    • 位于 SM 中的一块高速缓存内存
    • 由线程块中的线程共享
  • 寄存器(Register)
    • 每个线程都有对应的本地寄存器缓存

通信

  • block 内的线程可以同步也可以通过 shared memory 通信
  • grid 内的线程共享 global memory

线程组织

  • thread
    • 最小任务单元
  • block
    • 分配给 SM 执行
    • 每个线程块最多有 1024 个线程
    • 可以是一维、二维、三维
  • warp
    • block 中的线程以 warp 为单位进行分组
    • warp 大小为 32(当前)
    • 同一个 warp 中的 thread 以不同数据资源执行相同指令(SIMT,单指令多线程)
    • GPU 执行程序时的调度、执行的基本单元
    • 由 SM 的硬件 warp scheduler 负责调度
  • grid
    • 单独的 kernel 启动的所有线程组成一个 grid
    • grid 中所有线程共享 global memory
    • 多个 block 组成一个线程网格 grid
    • 可以是一维、二维、三维

其他

  • 核函数中 <grid, block>
    • grid
      • block 的组织方式
      • 可以是一至三维
    • block
      • thread 的组织方式
      • 可以是一至三维
  • 指定网格结构
    • dim3 grid(8, 4, 2);

CHATGPT

如何提高 gpu 的吞吐能力

要提高 GPU 的吞吐能力,可以考虑以下几个方面的优化:

  1. 并行化和向量化:利用 GPU 的并行处理能力和 SIMD(Single Instruction, Multiple Data)特性,尽可能将任务划分为独立的子任务,并对数据进行向量化操作。这样可以最大程度地利用 GPU 的计算资源。
  2. 内存访问优化:合理管理数据的访问模式,尽量减少内存访问的延迟和带宽消耗。可以使用共享内存来提高访问速度,通过数据重用和局部性原则减少全局内存访问次数。
  3. 内核函数设计:设计高效的内核函数,在保持功能完整性的同时,最大限度地减少同步和分支等开销。避免线程间冲突和竞争条件,提高执行效率。
  4. 内存传输优化:尽量减少 CPU 和 GPU 之间的数据传输,可以通过使用异步内存传输、数据压缩、数据预取等技术来减少传输时间和带宽占用。
  5. 算法选择和优化:针对具体的问题和数据特点,选择适合 GPU 并行计算的算法和数据结构。根据硬件架构的特点,对算法进行调整和优化,例如减少不必要的计算步骤、减少数据依赖等。
  6. 合理利用异构计算:除了 GPU,可以结合 CPU 和其他加速器(如FPGA)进行协同计算,充分利用不同硬件之间的优势来提高整体系统的吞吐能力。
  7. 使用专门的优化工具和库:针对特定的 GPU 架构和编程模型,使用专门的优化工具和库,例如 NVIDIA 的 CUDA Toolkit 提供的性能分析工具和优化指南。

以上是一些常见的方法,但具体的优化策略会取决于具体的应用场景和问题需求。在实际优化过程中,通过性能分析和测试来识别瓶颈,并基于具体情况采取相应的优化手段是非常重要的。

manjaro usage

包管理工具

  • pacman / pamac (GUI)
  • AUR
  • snap
  • flatpak
  • homebrew

搜索包

初始化

1
2
3
4
# 安装并启用 sshd.service
$ sudo pacman install openssl openssh
$ sudo systemctl enable sshd.service
$ sudo systemctl start sshd.service

pacman

查看帮助

1
2
$ pacman -h
$ pacman -S -h

切换源

1
2
3
4
5
6
# manjaro
# 1. 刷新
$ sudo pacman-mirrors -i -c China -m rank
# 选择合适的源
# 2. 更新
$ sudo pacman -Syy

或选择最近源。

1
$ sudo pacman-mirrors --geoip && sudo pacman -Syyu

参数

1
2
3
4
5
6
7
# -S
-S 安装
-S --needed --noconfirm
--needed: 跳过已经安装到最新版本的包
--noconfirm: 跳过确认

-R 卸载

查看安装的包

1
2
3
4
# 所有安装的包
$ pacman -Q
# 查询指定包
$ pacman -Q vim

搜索包

1
$ pacman -Ss vim

AUR

AUR(Arch User Repository),通常使用 AUR Helpers 安装 AUR 的包。

AUR Helpers

AUR helpers 可以帮助我们搜索、下载、编译 AUR 包,常见的 AUR helpers 有 yay、paru等。

Yay

1
2
3
4
5
sudo pacman -S --needed git base-devel
cd /tmp
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

Paru

安装

1
2
3
4
$ sudo pacman -S --needed base-devel
$ git clone https://aur.archlinux.org/paru.git
$ cd paru
$ makepkg -si

使用示例

1
2
# 搜索
$ paru -Ss gcc7
1
2
3
4
5
6
7
8
9
10
paru <target> -- Interactively search and install <target>.
paru -- Alias for paru -Syu.
paru -S <target> -- Install a specific package.
paru -Sua -- Upgrade AUR packages.
paru -Qua -- Print available AUR updates.
paru -G <target> -- Download the PKGBUILD and related files of <target>.
paru -Gp <target> -- Print the PKGBUILD of <target>.
paru -Gc <target> -- Print the AUR comments of <target>.
paru --gendb -- Generate the devel database for tracking *-git packages. This is only needed when you initially start using paru.
paru -Bi . -- Build and install a PKGBUILD in the current directory.

其他

可以手动搜索包,然后使用 git clone,并使用命令 makepkg -s 编译,使用命令 makepkg -i 安装,或直接使用 makepkg -is 命令编译安装。也可以通过 pamac 命令使用 aur。

1
2
3
4
5
6
# 安装 pamac
$ pacman -S pamac-cli
# 搜索 aur 包
$ pamac search ttf-ms-fonts --aur
# 安装
$ pamac build ttf-ms-fonts

安装 AUR 包

pamac build pkgp

安装官方包

pamac install pkg

Hyprland

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
sudo pacman -S hyprland 
# yay -S hyprland-git

# tools
## mako 通知
## xdg-desktop-portal-hyprland 通讯
## dolphin 文件管理器
## sddm 桌面显示管理器
## pipewire、wireplumber 屏幕共享
## waybar 状态栏
## hyprpaper 设置壁纸
## brightnessctl 调整亮度
## playerctl 播放控制
## network-manager-applet 网络图形界面
## polkit-kde-agent 权限认证界面
## wl-clipboard 粘贴板
sudo pacman -S sddm dolphin mako pipewire wireplumber xdg-desktop-portal-hyprland waybar hyprpaper brightnessctl playerctl network-manager-applet polkit-kde-agent firefox wl-clipboard uwsm
yay -S cliphist wl-clip-persist eww

# start tools
sudo systemctl enable --now sddm.service

# fonts
sudo pacman -S ttf-dejavu ttf-liberation noto-fonts noto-fonts-cjk noto-fonts-emoji ttf-droid ttf-opensans ttf-fira-code ttf-font-awesome

大语言模型小试

Vicuna

VicunaGithub - FastChat

运行

安装依赖

1
2
3
4
5
6
$ pip3 install torch transformers fschat
# 安装 lfs
## ubuntu
sudo apt install git-lfs
# 验证
$ git lfs install

下载

1
2
3
4
# llama 原始模型
$ git clone https://huggingface.co/decapoda-research/llama-13b-hf
# vicuna 模型
$ git clone https://huggingface.co/lmsys/vicuna-13b-delta-v1.1

更新参数

1
2
3
4
$ python3 -m fastchat.model.apply_delta \
--base-model-path /data/llama-13b-hf \
--target-model-path /data/vicuna-13b \
--delta-path /data/vicuna-13b-delta-v1.1

Serving

1
2
3
nohup python3 -m fastchat.serve.controller &
nohup python3 -m fastchat.serve.model_worker --model-path /data/vicuna-13b --device cpu &
nohup python3 -m fastchat.serve.gradio_web_server &

LLM - startup

问题排查

nvidia-container-cli: initialization error: load library failed: libnvidia-ml.so.1 #154

详见这里

1
2
3
4
5
6
sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl restart docker

no compatible GPUs were discovered / Failed to initialize NVML: Unknown Error

Ollama docker 容器找不到 GPU。

如果使用 docker compose,配置如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
services:
ollama:
image: ollama/ollama:latest
restart: always
hostname: ollama
runtime: nvidia
user: root
ports:
- '11434:11434'
volumes:
- /data/docker/llm/ollama:/root/.ollama
networks:
- default
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]

解决。宿主机编辑 /etc/nvidia-container-runtime/config.toml

1
no-cgroups = false # 修改, true -> false

重启 docker。

1
sudo systemctl restart docker

vector

配置

source

file

1
2
3
4
5
6
7
[sources.test]
type = "file"
include = [ "/tmp/test.log" ]
line_delimiter = "$$\n"

# unicode
line_delimiter = "\u0003\u0004\n"

line_delimiter

1
2
3
4
5
6
7
8
9
\b         - backspace       (U+0008)
\t - tab (U+0009)
\n - linefeed (U+000A)
\f - form feed (U+000C)
\r - carriage return (U+000D)
\" - quote (U+0022)
\\ - backslash (U+005C)
\uXXXX - unicode (U+XXXX)
\UXXXXXXXX - unicode (U+XXXXXXXX)

example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[api]
enabled = true
address = "0.0.0.0:8686"

[sources.test]
type = "file"
include = [ "/tmp/test.log" ]
line_delimiter = "$$\n"

[sinks.console]
inputs = ["test"]
target = "stdout"
type = "console"
encoding.codec = "text"

安装

docker

文档

1
2
3
4
5
6
7
8
9
10
# pull image
$ docker pull timberio/vector:0.30.0-debian
# create container
$ docker run \
-d \
-v $PWD/vector.toml:/etc/vector/vector.toml:ro \
-v /tmp/test.log:/tmp/test.log \
--name vector \
-p 8686:8686 \
timberio/vector:0.30.0-debian

trouble shooting

日志滚动后无法更新

可能原因

vector 在日志文件轮转之后,默认会计算日志文件的前n个字节的 check sum, 如果值一直,则不会监听新的文件。如果日志文件有固定的前缀,那么每次日志轮转,check sum 会保持一致,那么会无法切换至新的文件。
比如,vector 一开始监听 debug.log 文件,文件到达一定条件后做轮转操作,移动 debug.logdebug.log.1,创建新的 debug.log 文件。如果 debug.logdebug.log.1 有相同的 check sum 值,那么 vector 不会监听新的文件。

解决方案

修改 fingerprinter 的计算策略为 device_and_inode

1
2
3
4
5
6
7
8
[sources.debug-log]
type = "file"
include = ["/app/name/debug.log"]
max_line_bytes = 409600 # optional, default, bytes
ignore_older = 10 #10s
line_delimiter = "\u001e\u001f\n"
[sources.debug-log.fingerprinting]
strategy = "device_and_inode"

相关 issues