解析QAnything啟動命令過程

一.啟動命令過程日志

啟動命令bash ./run.sh -c local -i 0 -b hf -m Qwen-1_8B-Chat -t qwen-7b-chat。輸入日志如下所示:

root@MM-202203161213:/mnt/l/20230918_RAG方向/QAnything# bash ./run.sh -c local -i 0 -b hf -m Qwen-1_8B-Chat -t qwen-7b-chat
From https://github.com/ai408/QAnything* branch            master     -> FETCH_HEAD
當前master分支已是最新,無需更新。
請輸入您使用的大模型B數(示例:1.8B/3B/7B): 1.8B
model_size=1.8B
GPUID1=0, GPUID2=0, device_id=0
llm_api is set to [local]
device_id is set to [0]
runtime_backend is set to [hf]
model_name is set to [Qwen-1_8B-Chat]
conv_template is set to [qwen-7b-chat]
tensor_parallel is set to [1]
gpu_memory_utilization is set to [0.81]
Do you want to use the previous ip: localhost? (yes/no) 是否使用上次的ip: ?(yes/no) 回車默認選yes,請輸入:yes
Running under WSL
[+] Building 0.0s (0/0)                                
[+] Running 1/1
......? Container qanything-container-local   Started                        
qanything-container-local  |
qanything-container-local  | =============================
qanything-container-local  | == Triton Inference Server ==
qanything-container-local  | =============================
qanything-container-local  |
qanything-container-local  | NVIDIA Release 23.05 (build 61161506)
qanything-container-local  | Triton Server Version 2.34.0
qanything-container-local  |
qanything-container-local  | Copyright (c) 2018-2023, NVIDIA CORPORATION & AFFILIATES.  All rights reserved.
qanything-container-local  |
qanything-container-local  | Various files include modifications (c) NVIDIA CORPORATION & AFFILIATES.  All rights reserved.
qanything-container-local  |
qanything-container-local  | This container image and its contents are governed by the NVIDIA Deep Learning Container License.
qanything-container-local  | By pulling and using the container, you accept the terms and conditions of this license:
qanything-container-local  | https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license
qanything-container-local  |
qanything-container-local  | llm_api is set to [local]
qanything-container-local  | device_id is set to [0]
qanything-container-local  | runtime_backend is set to [hf]
qanything-container-local  | model_name is set to [Qwen-1_8B-Chat]
qanything-container-local  | conv_template is set to [qwen-7b-chat]
qanything-container-local  | tensor_parallel is set to [1]
qanything-container-local  | gpu_memory_utilization is set to [0.81]
qanything-container-local  | checksum de2530187992077db2c08276fcdc8bce
qanything-container-local  | default_checksum de2530187992077db2c08276fcdc8bce
qanything-container-local  |
qanything-container-local  | [notice] A new release of pip is available: 23.3.2 -> 24.0
qanything-container-local  | [notice] To update, run: python3 -m pip install --upgrade pip
qanything-container-local  | GPU ID: 0, 0
qanything-container-local  | GPU1 Model: NVIDIA GeForce RTX 3090
qanything-container-local  | Compute Capability: 8.6
qanything-container-local  | OCR_USE_GPU=True because 8.6 >= 7.5
qanything-container-local  | ====================================================
qanything-container-local  | ******************** 重要提示 ********************
qanything-container-local  | ====================================================
qanything-container-local  |
qanything-container-local  | /workspace/qanything_local/scripts/run_for_local_option.sh: line 208: [: 1.8: integer expression expected
qanything-container-local  | 您當前的顯存為 24576 MiB 推薦部署7B模型
qanything-container-local  | /workspace/qanything_local/scripts/run_for_local_option.sh: line 276: [: 1.8: integer expression expected
qanything-container-local  | The triton server for embedding and reranker will start on 0 GPUs
qanything-container-local  | Executing hf runtime_backend
qanything-container-local  | The rerank service is ready! (2/8)
qanything-container-local  | rerank服務已就緒! (2/8)
qanything-container-local  | The ocr service is ready! (3/8)
qanything-container-local  | OCR服務已就緒! (3/8)
qanything-container-local  | The qanything backend service is ready! (4/8)
qanything-container-local  | qanything后端服務已就緒! (4/8)
qanything-container-local  | Dependencies related to npm are obtained. (5/8)
qanything-container-local  | The front_end/dist folder already exists, no need to build the front end again.(6/8)
qanything-container-local  | Waiting for the front-end service to start...
qanything-container-local  | 等待啟動前端服務
qanything-container-local  |
qanything-container-local  | > ai-demo@1.0.1 serve
qanything-container-local  | > vite preview --port 5052
qanything-container-local  |
qanything-container-local  | The CJS build of Vite's Node API is deprecated. See https://vitejs.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.
qanything-container-local  |   ?  Local:   http://localhost:5052/qanything
qanything-container-local  |   ?  Network: http://172.21.0.6:5052/qanything
qanything-container-local  | The front-end service is ready!...(7/8)
qanything-container-local  | 前端服務已就緒!...(7/8)
qanything-container-local  | I0416 16:38:03.654302 131 grpc_server.cc:377] Thread started for CommonHandler
qanything-container-local  | I0416 16:38:03.654861 131 infer_handler.cc:629] New request handler for ModelInferHandler, 0
qanything-container-local  | I0416 16:38:03.655310 131 infer_handler.h:1025] Thread started for ModelInferHandler
qanything-container-local  | I0416 16:38:03.655832 131 infer_handler.cc:629] New request handler for ModelInferHandler, 0
qanything-container-local  | I0416 16:38:03.656273 131 infer_handler.h:1025] Thread started for ModelInferHandler
qanything-container-local  | I0416 16:38:03.656863 131 stream_infer_handler.cc:122] New request handler for ModelStreamInferHandler, 0
qanything-container-local  | I0416 16:38:03.657257 131 infer_handler.h:1025] Thread started for ModelStreamInferHandler
qanything-container-local  | I0416 16:38:03.657673 131 grpc_server.cc:2450] Started GRPCInferenceService at 0.0.0.0:9001
qanything-container-local  | I0416 16:38:03.658368 131 http_server.cc:3555] Started HTTPService at 0.0.0.0:9000
qanything-container-local  | I0416 16:38:03.700441 131 http_server.cc:185] Started Metrics Service at 0.0.0.0:9002
qanything-container-local  | I0416 16:38:47.479318 131 http_server.cc:3449] HTTP request: 0 /v2/health/ready
qanything-container-local  | The embedding and rerank service is ready!. (7.5/8)
qanything-container-local  | Embedding 和 Rerank 服務已準備就緒!(7.5/8)
qanything-container-local  | 2024-04-17 00:38:07 | INFO | model_worker | args: Namespace(host='0.0.0.0', port=7801, worker_address='http://0.0.0.0:7801', controller_address='http://0.0.0.0:7800', model_path='/model_repos/CustomLLM/Qwen-1_8B-Chat', revision='main', device='cuda', gpus='0', num_gpus=1, max_gpu_memory=None, dtype='bfloat16', load_8bit=True, cpu_offloading=False, gptq_ckpt=None, gptq_wbits=16, gptq_groupsize=-1, gptq_act_order=False, awq_ckpt=None, awq_wbits=16, awq_groupsize=-1, enable_exllama=False, exllama_max_seq_len=4096, exllama_gpu_split=None, exllama_cache_8bit=False, enable_xft=False, xft_max_seq_len=4096, xft_dtype=None, model_names=None, conv_template='qwen-7b-chat', embed_in_truncate=False, limit_worker_concurrency=5, stream_interval=2, no_register=False, seed=None, debug=False, ssl=False)
qanything-container-local  | 2024-04-17 00:38:07 | INFO | model_worker | Loading the model ['Qwen-1_8B-Chat'] on worker 138d0217 ...
qanything-container-local  | 2024-04-17 00:38:09 | WARNING | transformers_modules.Qwen-1_8B-Chat.modeling_qwen | The model is automatically converting to bf16 for faster inference. If you want to disable the automatic precision, please manually add bf16/fp16/fp32=True to "AutoModelForCausalLM.from_pretrained".
qanything-container-local  | 2024-04-17 00:38:09 | WARNING | transformers_modules.Qwen-1_8B-Chat.modeling_qwen | Try importing flash-attention for faster inference...
qanything-container-local  | 2024-04-17 00:38:10 | WARNING | transformers_modules.Qwen-1_8B-Chat.modeling_qwen | Warning: import flash_attn rms_norm fail, please install FlashAttention layer_norm to get higher efficiency https://github.com/Dao-AILab/flash-attention/tree/main/csrc/layer_norm0%|          | 0/2 [00:00<?, ?it/s]17 00:38:11 | ERROR | stderr |
qanything-container-local  |   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
qanything-container-local  |                                  Dload  Upload   Total   Spent    Left  Speed
100    13  100    13    0     0   3004      0 --:--:-- --:--:-- --:--:--  3250
qanything-container-local  | The llm service is starting up, it can be long... you have time to make a coffee :)
qanything-container-local  | LLM 服務正在啟動,可能需要一段時間...你有時間去沖杯咖啡 :)
......
qanything-container-local  | The llm service is starting up, it can be long... you have time to make a coffee :)
qanything-container-local  | LLM 服務正在啟動,可能需要一段時間...你有時間去沖杯咖啡 :)
100%|██████████| 2/2 [06:35<00:00, 206.00s/it]46 | ERROR | stderr |
100%|██████████| 2/2 [06:35<00:00, 197.69s/it]46 | ERROR | stderr |
qanything-container-local  | 2024-04-17 00:44:46 | ERROR | stderr |
qanything-container-local  | 2024-04-17 00:44:46 | INFO | model_worker | Register to controller
qanything-container-local  | 2024-04-17 00:44:46 | ERROR | stderr | INFO:     Started server process [148]
qanything-container-local  | 2024-04-17 00:44:46 | ERROR | stderr | INFO:     Waiting for application startup.
qanything-container-local  | 2024-04-17 00:44:46 | ERROR | stderr | INFO:     Application startup complete.
qanything-container-local  | 2024-04-17 00:44:46 | ERROR | stderr | INFO:     Uvicorn running on http://0.0.0.0:7801 (Press CTRL+C to quit)
qanything-container-local  |   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
qanything-container-local  |                                  Dload  Upload   Total   Spent    Left  Speed
100    29  100    29    0     0   8638      0 --:--:-- --:--:-- --:--:--  9666
qanything-container-local  | The llm service is ready!, now you can use the qanything service. (8/8)
qanything-container-local  | LLM 服務已準備就緒!現在您可以使用qanything服務。(8/8)
qanything-container-local  | 開始檢查日志文件中的錯誤信息...
qanything-container-local  | /workspace/qanything_local/logs/debug_logs/rerank_server.log 中未檢測到明確的錯誤信息。請手動排查 /workspace/qanything_local/logs/debug_logs/rerank_server.log 以獲取更多信息。
qanything-container-local  | /workspace/qanything_local/logs/debug_logs/ocr_server.log 中未檢測到明確的錯誤信息。請手動排查 /workspace/qanything_local/logs/debug_logs/ocr_server.log 以獲取更多信息。
qanything-container-local  | /workspace/qanything_local/logs/debug_logs/sanic_api.log 中未檢測到明確的錯誤信息。請手動排查 /workspace/qanything_local/logs/debug_logs/sanic_api.log 以獲取更多信息。
qanything-container-local  | Time elapsed: 408 seconds.
qanything-container-local  | 已耗時: 408 秒.
qanything-container-local  | Please visit the front-end service at [http://localhost:5052/qanything/] to conduct Q&A.
qanything-container-local  | 請在[http://localhost:5052/qanything/]下訪問前端服務來進行問答,如果前端報錯,請在瀏覽器按F12以獲取更多報錯信息

二. run.sh腳本

1.update_or_append_to_env()函數

更新或追加鍵值對到.env文件:

update_or_append_to_env() {local key=$1local value=$2local env_file=".env"# 檢查鍵是否存在于.env文件中if grep -q "^${key}=" "$env_file"; then# 如果鍵存在,則更新它的值sed -i "/^${key}=/c\\${key}=${value}" "$env_file"else# 如果鍵不存在,則追加鍵值對到文件echo "${key}=${value}" >> "$env_file"fi
}

.env文件內容:

MODEL_SIZE=1.8B
GPUID1=0
GPUID2=0
LLM_API=local
DEVICE_ID=0
RUNTIME_BACKEND=hf
MODEL_NAME=Qwen-1_8B-Chat
CONV_TEMPLATE=qwen-7b-chat
TP=1
GPU_MEM_UTILI=0.81
USER_IP=localhost
WIN_VERSION=WIN11
OCR_USE_GPU=True
OFFCUT_TOKEN=0
RERANK_PORT=9001
EMBED_PORT=9001
LLM_API_SERVE_PORT=7802
LLM_API_SERVE_MODEL=Qwen-1_8B-Chat
LLM_API_SERVE_CONV_TEMPLATE=qwen-7b-chat

2.script_name=$(basename “$0”)

解析:

(1)這行代碼是在 Bash 腳本中獲取當前腳本文件的名稱。

(2)$0 是一個特殊變量,它在 Bash 腳本中表示當前腳本的文件名。

(3)basename 是一個命令行工具,它從輸入的文件路徑中去除目錄和后綴,只返回文件名。

(4)basename "$0" 就是獲取當前腳本的文件名,不包括路徑和后綴。

(5)script_name=$(basename "$0") 就是將這個文件名賦值給變量 script_name

3.usage()函數

解析:可以根據自己的設備條件選擇最合適的服務啟動命令:

(1)當設置 -i 0,1 時,本地嵌入/重排將在設備 gpu_id_1 上運行,否則默認使用 gpu_id_0。

(2)設置 -c cloud 將使用本地嵌入/重排和 OpenAI LLM API,這僅需要大約 4GB VRAM(推薦給 GPU 設備 VRAM <= 8GB 的情況)。

(3)當使用 OpenAI LLM API 時,將立即要求輸入 {OPENAI_API_KEY, OPENAI_API_BASE, OPENAI_API_MODEL_NAME, OPENAI_API_CONTEXT_LENGTH}。

(4)-b hf 是運行公共 LLM 推理最推薦的方式,因為它的兼容性好,但性能較差。

(5)當為 QAnything 系統選擇一個公共聊天 LLM 時,應該考慮到一個更合適的 **PROMPT_TEMPLATE**(路徑/到/QAnything/qanything_kernel/configs/model_config.py)設置,考慮到不同的 LLM 模型。

usage() {echo "Usage: $script_name [-c <llm_api>] [-i <device_id>] [-b <runtime_backend>] [-m <model_name>] [-t <conv_template>] [-p <tensor_parallel>] [-r <gpu_memory_utilization>] [-h]"echo "  -c : Options {local, cloud} to specify the llm API mode, default is 'local'. If set to '-c cloud', please mannually set the environments {OPENAI_API_KEY, OPENAI_API_BASE, OPENAI_API_MODEL_NAME, OPENAI_API_CONTEXT_LENGTH} into .env fisrt in run.sh"echo "  -i <device_id>: Specify argument GPU device_id"echo "  -b <runtime_backend>: Specify argument LLM inference runtime backend, options={default, hf, vllm}"echo "  -m <model_name>: Specify argument the path to load LLM model using FastChat serve API, options={Qwen-7B-Chat, deepseek-llm-7b-chat, ...}"echo "  -t <conv_template>: Specify argument the conversation template according to the LLM model when using FastChat serve API, options={qwen-7b-chat, deepseek-chat, ...}"echo "  -p <tensor_parallel>: Use options {1, 2} to set tensor parallel parameters for vllm backend when using FastChat serve API, default tensor_parallel=1"echo "  -r <gpu_memory_utilization>: Specify argument gpu_memory_utilization (0,1] for vllm backend when using FastChat serve API, default gpu_memory_utilization=0.81"echo "  -h: Display help usage message. For more information, please refer to docs/QAnything_Startup_Usage_README.md"echo '
| Service Startup Command                                                                 | GPUs | LLM Runtime Backend      | LLM model                        |
| --------------------------------------------------------------------------------------- | -----|--------------------------| -------------------------------- |
| ```bash ./run.sh -c cloud -i 0 -b default```                                    | 1    | OpenAI API               | OpenAI API                       |
| ```bash ./run.sh -c local -i 0 -b default```                                    | 1    | FasterTransformer        | Qwen-7B-QAnything                |
| ```bash ./run.sh -c local -i 0 -b hf -m MiniChat-2-3B -t minichat```            | 1    | Huggingface Transformers | Public LLM (e.g., MiniChat-2-3B) |
| ```bash ./run.sh -c local -i 0 -b vllm -m MiniChat-2-3B -t minichat -p 1 -r 0.81```| 1    | vllm                     | Public LLM (e.g., MiniChat-2-3B) |
| ```bash ./run.sh -c local -i 0,1 -b default```                                  | 2    | FasterTransformer        | Qwen-7B-QAnything                |
| ```bash ./run.sh -c local -i 0,1 -b hf -m MiniChat-2-3B -t minichat```          | 2    | Huggingface Transformers | Public LLM (e.g., MiniChat-2-3B) |
| ```bash ./run.sh -c local -i 0,1 -b vllm -m MiniChat-2-3B -t minichat -p 1 -r 0.81```| 2    | vllm                     | Public LLM (e.g., MiniChat-2-3B) |
| ```bash ./run.sh -c local -i 0,1 -b vllm -m MiniChat-2-3B -t minichat -p 2 -r 0.81```| 2    | vllm                     | Public LLM (e.g., MiniChat-2-3B) |Note: You can choose the most suitable Service Startup Command based on your own device conditions.
(1) Local Embedding/Rerank will run on device gpu_id_1 when setting "-i 0,1", otherwise using gpu_id_0 as default.
(2) When setting "-c cloud" that will use local Embedding/Rerank and OpenAI LLM API, which only requires about 4GB VRAM (recommend for GPU device VRAM <= 8GB).
(3) When you use OpenAI LLM API, you will be required to enter {OPENAI_API_KEY, OPENAI_API_BASE, OPENAI_API_MODEL_NAME, OPENAI_API_CONTEXT_LENGTH} immediately.
(4) "-b hf" is the most recommended way for running public LLM inference for its compatibility but with poor performance.
(5) When you choose a public Chat LLM for QAnything system, you should take care of a more suitable **PROMPT_TEMPLATE** (/path/to/QAnything/qanything_kernel/configs/model_config.py) setting considering different LLM models.
'exit 1
}

4.解析命令行參數

解析:這段代碼的主要作用是解析命令行參數,并將參數的值賦給相應的變量,這些變量后續可以在腳本中使用。

(1)這段代碼是在 Bash 腳本中使用 getopts 函數來解析命令行參數。

(2)getopts 是一個用于解析位置參數的工具。在這個例子中,getopts ":c:i:b:m:t:p:r:h" 表示接受的參數有 -c-i-b-m-t-p-r-h。每個參數后面都跟著一個冒號,表示這個參數需要一個值。

(3)while getopts 循環會依次處理每個參數。每次循環,getopts 會將當前參數的值賦給 opt 變量,如果該參數需要一個值,那么這個值會被賦給 OPTARG 變量。

(4)case $opt in 語句用于根據 opt 的值來執行不同的操作。例如,如果 opt 的值為 c,那么 llm_api=$OPTARG 會被執行,這行代碼將參數 c 的值賦給 llm_api 變量。

while getopts ":c:i:b:m:t:p:r:h" opt; docase $opt inc) llm_api=$OPTARG ;;i) device_id=$OPTARG ;;b) runtime_backend=$OPTARG ;;m) model_name=$OPTARG ;;t) conv_template=$OPTARG ;;p) tensor_parallel=$OPTARG ;;r) gpu_memory_utilization=$OPTARG ;;h) usage ;;*) usage ;;esac
done

5.接下來的過程

解析:

(1)設置大模型的B數

(2)設置GPUID1和GPUID2

(3)設置USER_IP=localhost

(4)Windows 11支持Qwen-7B-QAnything模型

(5)檢測到 Docker Compose 版本

(6)啟動docker-compose-windows.yaml

三.docker-compose-windows.yaml

1.etcd服務

解析:

etcd:container_name: milvus-etcd-localimage: quay.io/coreos/etcd:v3.5.5environment:- ETCD_AUTO_COMPACTION_MODE=revision- ETCD_AUTO_COMPACTION_RETENTION=1000- ETCD_QUOTA_BACKEND_BYTES=4294967296- ETCD_SNAPSHOT_COUNT=50000volumes:- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcdcommand: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcdhealthcheck:test: ["CMD", "etcdctl", "endpoint", "health"]interval: 30stimeout: 20sretries: 3

(1)environment

ETCD_AUTO_COMPACTION_MODE=revision:這是自動壓縮模式,設置為 `revision`,表示按版本進行自動壓縮。
ETCD_AUTO_COMPACTION_RETENTION=1000:這是自動壓縮保留的版本數,設置為 1000,表示保留最近的 1000 個版本。
ETCD_QUOTA_BACKEND_BYTES=4294967296:這是后端數據庫的配額,以字節為單位。設置為 4294967296,即 4GB,表示后端數據庫的最大大小為 4GB。
ETCD_SNAPSHOT_COUNT=50000:這是觸發新快照的提交事務數。設置為 50000,表示每當提交的事務數達到 50000 時,就會觸發一個新的快照。

(2)volumes

  • ${DOCKER_VOLUME_DIRECTORY:-.} 是一個 Bash 參數擴展,它表示如果環境變量 DOCKER_VOLUME_DIRECTORY 已設置并且非空,那么就使用它的值,否則使用默認值 .(即當前目錄)。

  • 將宿主機上的${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd目錄,掛載到容器內部的/etcd目錄。

(3)command

這段代碼是用于配置etcd服務器的命令行參數。etcd是一個分布式鍵值存儲系統,通常用于提供一致性和高可用性的數據存儲。下面是對每個參數的解釋:

  • -advertise-client-urls:這個參數指定了etcd服務器用于客戶端通信的URL。在這個例子中,它被設置為http://127.0.0.1:2379,意味著etcd服務器將通過回環地址(即本地機器的IP地址)上的2379端口接受客戶端的連接請求。

  • -listen-client-urls:這個參數定義了etcd服務器監聽的客戶端請求的URL。這里設置為http://0.0.0.0:2379,表示etcd服務器將監聽所有網絡接口上的2379端口,允許任何來源的連接。

  • --data-dir:這個參數指定了etcd存儲其數據的目錄。在這個例子中,數據將被存儲在容器內部的/etcd目錄下。

綜合來看,這個命令是用來啟動一個etcd實例,它將在所有網絡接口上監聽2379端口,接受來自任何IP的客戶端連接。使用回環地址(127.0.0.1)上的2379端口作為客戶端訪問的正式URL。將持久化數據存儲在容器內部的/etcd目錄。這種配置通常用在Docker容器中,其中-listen-client-urls允許容器外的客戶端連接到etcd實例,而-advertise-client-urls提供了一個穩定的URL,以便客戶端知道如何連接到etcd實例。--data-dir確保了etcd的數據可以持久化存儲,即使容器重啟,數據也不會丟失。

(4)healthcheck

這段代碼是一個Docker容器中使用的測試命令,通常用于健康檢查或驗證容器內部服務是否正常運行:

  • “CMD”:這是Docker健康檢查指令中指定的指令類型。使用CMD意味著接下來的參數將作為一個整體命令來執行。

  • “etcdctl”:這是一個命令行工具,用于與etcd服務器進行交互。etcdctl可以用來執行多種操作,如獲取etcd集群狀態、管理鍵值對等。

  • “endpoint”:這是etcdctl工具的一個子命令,用于指定與etcd集群交互的端點。

  • “health”:這是endpoint子命令的一個參數,用于檢查etcd集群的健康狀況。

將這些元素組合起來,[“CMD”, “etcdctl”, “endpoint”, “health”] 定義了一個健康檢查命令,該命令使用etcdctl工具來檢查etcd服務的健康狀況。當這個命令被Docker的健康檢查機制執行時,它會返回0(表示健康)或非0值(表示不健康)。如果容器不健康,Docker將根據容器的重啟策略采取行動,可能包括重啟容器。

2.minio服務

解析:

minio:container_name: milvus-minio-localimage: minio/minio:RELEASE.2023-03-20T20-16-18Zenvironment:MINIO_ACCESS_KEY: minioadminMINIO_SECRET_KEY: minioadmin# ports:#   - "9001:9001"#       - "9000:9000"volumes:- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_datacommand: minio server /minio_data --console-address ":9001"healthcheck:test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]interval: 30stimeout: 20sretries: 3

(1)command

這段代碼是用來啟動MinIO服務器的命令行指令。MinIO是一個高性能的分布式對象存儲服務。下面是對命令及其參數的解釋:

  • minio server:這是啟動MinIO服務器的命令。

  • /minio_data:這是在宿主機上的一個目錄路徑,它將被用作MinIO數據的存儲位置。當MinIO服務器啟動時,它會在這個目錄中存儲所有數據。在Docker容器環境中,這通常是一個掛載的卷,將容器內部的存儲掛載到宿主機的某個目錄上。

  • --console-address ":9001":這是MinIO服務器的控制臺或管理界面的配置參數。--console-address指定了控制臺監聽的地址和端口。

整個命令的作用是啟動MinIO服務器,使用宿主機上的/minio_data目錄作為數據存儲,并且設置MinIO控制臺在9001端口上可用。這樣配置后,用戶可以通過瀏覽器訪問http://<host-ip>:9001來使用MinIO的Web界面進行數據管理和監控。

(2)healthcheck

這段代碼是Docker容器中定義的健康檢查(health check)指令,用于確定容器是否處于健康狀態。綜合來看,這個健康檢查命令會嘗試使用curl工具向MinIO服務的健康狀況檢查端點發送一個請求。如果請求失敗(例如,如果MinIO服務沒有運行或不可達),健康檢查也會失敗,Docker會認為容器處于不健康狀態。這可以觸發Docker根據預設的重啟策略嘗試重啟容器。

在Docker容器的配置中,這個指令通常與HEALTHCHECK指令一起使用:

HEALTHCHECK --interval=30s --timeout=30s --retries=3 \test ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
  • 每30秒執行一次健康檢查(–interval=30s)。

  • 如果健康檢查超過30秒沒有響應,則超時(–timeout=30s)。

  • 如果連續3次健康檢查失敗,Docker將認為容器不健康,并根據容器的重啟策略采取行動(–retries=3)。

3.milvus服務

解析:

standalone:container_name: milvus-standalone-localimage: milvusdb/milvus:v2.3.4logging:driver: "json-file"options:max-size: "100m"max-file: "3"command: ["milvus", "run", "standalone"]security_opt:- seccomp:unconfinedenvironment:ETCD_ENDPOINTS: etcd:2379MINIO_ADDRESS: minio:9000volumes:- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvushealthcheck:test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]interval: 30sstart_period: 90stimeout: 20sretries: 3# ports:#       - "19530:19530"#       - "9091:9091"depends_on:- "etcd"- "minio"

(1)logging

  • logging: 這部分是Docker容器日志配置的開始,指定了日志記錄的配置項。

  • driver: “json-file”:這指定了日志記錄的驅動程序。json-file驅動是Docker默認的日志驅動,它會將容器的日志信息以JSON格式存儲在磁盤上。

  • options: 這是json-file驅動的配置選項。

  • max-size: “100m”:這是一個配置選項,指定了每個日志文件的最大大小。在這個例子中,每個日志文件的大小被限制在100兆字節(M是兆字節的縮寫)。當單個日志文件的大小達到這個限制時,Docker會創建一個新的日志文件來繼續記錄日志。

  • max-file: “3”:這也是一個配置選項,指定了保留的日志文件的最大數量。這里設置為3意味著Docker會保留最新的3個日志文件。一旦超過這個數量,最舊的日志文件將被刪除以騰出空間給新的日志文件。

(2)command

這個命令用于啟動一個名為Milvus的服務,并讓它以獨立模式運行。Milvus是一個開源的向量數據庫,用于嵌入向量的存儲、檢索和分析。在Docker容器中,這個命令會替換掉容器鏡像中默認的啟動命令,使得容器啟動時直接運行Milvus服務。

(3)security_opt

  • seccomp:是"secure computing"的縮寫,它是一個在Linux內核中實現的安全模塊,用于控制和限制容器內進程可以進行的系統調用。通過限制容器內的應用能夠調用的系統調用,seccomp可以減少容器逃逸攻擊的風險。

  • unconfined:是seccomp的一個配置模式,表示容器將不會被限制在系統調用層面。在Docker中,如果一個容器配置為seccomp: unconfined,那么它將能夠執行任何系統調用,而不會受到一定程度的限制或過濾。

4.mysql服務

解析:

mysql:container_name: mysql-container-localprivileged: trueimage: mysql#     ports:#       - "3306:3306"environment:- MYSQL_ROOT_PASSWORD=123456volumes:- qanything_mysql_data:/var/lib/mysql

(1)privileged: true

當在Docker容器中設置privileged: true時,容器將獲得以下額外的權限:

  • 訪問所有設備:特權容器可以訪問宿主機上的所有設備節點,例如/dev目錄下的設備文件。

  • 監聽所有端口:非特權容器默認只能監聽高于1024的端口,而特權容器可以監聽所有端口。

  • 掛載文件系統:特權容器可以掛載任何文件系統,包括/proc、/sys、/dev等,這些在非特權容器中通常是受限的。

  • 操作網絡棧:特權容器可以修改宿主機的網絡棧,例如添加路由規則或修改網絡接口。

  • 擁有更多的系統調用:特權容器可以執行一些通常受限的系統調用。

(2)volumes

將名為qanything_mysql_data的數據卷掛載到容器內部的/var/lib/mysql目錄。這種配置通常用在Docker容器中運行MySQL數據庫時:

  • 將MySQL的數據文件存儲在數據卷中,而不是容器的臨時文件系統中。

  • 確保MySQL的數據在容器重啟或刪除后依然被保留。

  • 允許在多個MySQL容器之間共享或遷移數據。

5.qanything服務

解析:

qanything_local:container_name: qanything-container-localimage: freeren/qanything-win:v1.2.1# runtime: nvidiadeploy:resources:reservations:devices:- driver: nvidiacount: "all"capabilities: ["gpu"]command: sh -c 'if [ "${LLM_API}" = "local" ]; then /workspace/qanything_local/scripts/run_for_local_option.sh -c $LLM_API -i $DEVICE_ID -b $RUNTIME_BACKEND -m $MODEL_NAME -t $CONV_TEMPLATE -p $TP -r $GPU_MEM_UTILI; else /workspace/qanything_local/scripts/run_for_cloud_option.sh -c $LLM_API -i $DEVICE_ID -b $RUNTIME_BACKEND; fi; while true; do sleep 5; done'privileged: trueshm_size: '8gb'volumes:- ${DOCKER_VOLUME_DIRECTORY:-.}/assets/custom_models:/model_repos/CustomLLM- ${DOCKER_VOLUME_DIRECTORY:-.}/:/workspace/qanything_local/ports:- "5052:5052"- "8777:8777"environment:- NCCL_LAUNCH_MODE=PARALLEL- GPUID1=${GPUID1:-0}- GPUID2=${GPUID2:-0}- MODEL_SIZE=${MODEL_SIZE:-0B}- USER_IP=${USER_IP:-localhost}depends_on:- "standalone"- "mysql"tty: truestdin_open: true

(1)runtime: nvidia

在Docker容器的配置中,runtime: nvidia是用來指定容器應該使用NVIDIA GPU運行時的配置選項。這個選項通常與NVIDIA Docker(現在被集成到Docker 19.03及以上版本中)一起使用,它允許容器訪問和利用宿主機上的NVIDIA GPU資源。

(2)shm_size: ‘8gb’

設置容器的共享內存(Shared Memory)的大小。共享內存是進程間通信(IPC)的一種方式,允許兩個或多個進程共享一個給定的內存區域。

(3)tty: true

用于分配一個偽終端(pseudo-TTY)給容器。docker run -it my_image這個命令中:

  • -i 表示以交互式模式運行容器,保持標準輸入(STDIN)打開,即使不附加到終端。

  • -t 就相當于在容器的創建命令中設置了 tty: true,它會分配一個TTY。

(4)stdin_open: true

用于控制容器的標準輸入(STDIN)是否在容器啟動時打開。在Docker中,可以通過在 docker run 命令中添加 -i 標志來設置 stdin_open: true。

(5)command

command: sh -c 'if [ "${LLM_API}" = "local" ]; then /workspace/qanything_local/scripts/run_for_local_option.sh -c $LLM_API -i $DEVICE_ID -b $RUNTIME_BACKEND -m $MODEL_NAME -t $CONV_TEMPLATE -p $TP -r $GPU_MEM_UTILI; else /workspace/qanything_local/scripts/run_for_cloud_option.sh -c $LLM_API -i $DEVICE_ID -b $RUNTIME_BACKEND; fi; while true; do sleep 5; done'

這段代碼是Docker容器的command配置,它定義了容器啟動時執行的命令。這個命令是一個復雜的shell腳本,用于根據環境變量LLM_API的值來決定執行哪個腳本。下面是對整個命令的解釋:

  • command: 這是Docker容器配置中用于指定容器啟動時要運行的命令的字段。

  • sh -c:這表示使用sh(Shell)來執行后面的命令字符串。-c參數允許傳遞一個字符串作為Shell命令執行。

  • if [ "${LLM_API}" = "local" ]; then ...; else ...; fi:這是一個條件語句,用于檢查環境變量LLM_API的值是否等于"local"

  • 如果LLM_API等于"local",則執行then部分的命令。

  • 如果不等于"local",則執行else部分的命令。

  • .../run_for_local_option.sh -c $LLM_API -i $DEVICE_ID -b $RUNTIME_BACKEND -m $MODEL_NAME -t $CONV_TEMPLATE -p $TP -r $GPU_MEM_UTILI;:這是當LLM_API等于"local"時執行的腳本及其參數。該腳本可能用于配置和啟動一個本地運行的LLM(大型語言模型)服務。參數傳遞了多個環境變量,這些變量可能用于配置服務。

  • .../run_for_cloud_option.sh -c $LLM_API -i $DEVICE_ID -b $RUNTIME_BACKEND;:這是當LLM_API不等于"local"時執行的腳本及其參數。該腳本可能用于配置和啟動一個基于云的LLM服務。

  • while true; do sleep 5; done:這是一個無限循環,用于保持容器運行狀態。sleep 5命令使容器在每次循環迭代中暫停5秒。這個循環確保容器不會因為執行完前面的命令而退出,從而保持容器的持續運行。

綜上這個命令用于根據LLM_API的值來決定是運行本地模式的LLM服務還是云模式的LLM服務,并在執行完相應的啟動腳本后,通過無限循環保持容器活躍。這種方式常用于確保容器作為一個長期運行的服務容器,即使在沒有持續操作的情況下也保持運行狀態。

(6)deploy

  • deploy: 這是Kubernetes部署(Deployment)配置的開始,它定義了如何部署和管理容器化的應用程序。

  • resources: 這是指定部署所需的計算資源的字段,如CPU、內存和設備。

  • reservations: 在resources內部,reservations用于定義資源的預留要求,以確保部署的Pods有足夠資源運行。

  • devices: reservations下的devices字段用于定義需要預留的設備類型和數量。

  • driver: nvidia:這是一個設備定義,指定了設備驅動為nvidia。這告訴Kubernetes調度器,需要預留裝有NVIDIA驅動的GPU設備。

  • count: “all”:這指定了需要預留的NVIDIA GPU的數量。在這個例子中,"all"意味著應預留集群中所有可用的NVIDIA GPU設備。

  • capabilities: [“gpu”]:這是設備的能力列表,指定了設備應支持的功能。在這里,"gpu"表示設備應具備GPU計算能力。

6.數據卷

解析:

volumes:qanything_mysql_data:
  • volumes: 這是Docker Compose 文件中定義數據卷的開始。

  • qanything_mysql_data: 這是數據卷的名稱。在Docker Compose 文件中定義后,可以在 services 下的對應服務中通過 volumes 選項來引用它。

7.默認網絡名字

解析:

networks:default:name: qanything_milvus_mysql_local
  • networks: 這是Docker Compose文件中定義網絡的開始。

  • default: Docker Compose中的服務默認連接到一個名為default的網絡。如果不指定服務連接到哪個網絡,它將自動使用default網絡。

  • name: qanything_milvus_mysql_local 這里為default網絡指定了一個自定義名稱。在Docker Compose中,網絡名稱是區分不同網絡環境的重要標識。

四.run_for_local_option.sh腳本

1.檢查FastChat的MD5

解析:這段shell腳本的功能是檢查FastChat文件夾下所有文件的MD5校驗和,并與預先保存的默認校驗和進行比較。以下是對腳本功能的總結:

(1)獲取默認的MD5校驗和:腳本從/workspace/qanything_local/third_party/checksum.config文件中讀取默認的MD5校驗和,將其存儲在變量default_checksum中。

(2)計算FastChat文件夾下所有文件的MD5校驗和:使用find命令結合md5sum工具計算/workspace/qanything_local/third_party/FastChat目錄下所有文件的MD5校驗和。計算出的校驗和列表通過sort排序,然后再計算這些校驗和行的總的MD5校驗和,最終結果存儲在變量checksum中。

(3)輸出校驗和:腳本打印出計算得到的checksum和默認的default_checksum,以便于用戶或開發者進行查看或調試。

(4)檢查校驗和是否一致:使用if語句比較default_checksumchecksum。如果兩者不相等,意味著FastChat目錄下的文件發生了變化。

(5)重新安裝依賴:如果校驗和不相等,腳本會進入/workspace/qanything_local/third_party/FastChat目錄,并使用pip install -e .命令重新安裝該目錄下的所有Python依賴。這通常用于當源代碼發生變化時,需要重新安裝以反映這些變化。

(6)更新默認校驗和:重新計算安裝依賴后的MD5校驗和,并將新計算出的校驗和寫入/workspace/qanything_local/third_party/checksum.config文件中,更新默認校驗和。

2.檢查vllm依賴是否安裝

(1)使用pip list | grep vllm命令檢查vllm依賴是否已經安裝在Python環境中。

(2)如果沒有找到vllm(即install_deps變量為空或者不包含vllm),則打印出"vllm deps not found"

3.安裝FastChat依賴并更新校驗和

(1)如果vllm依賴未找到,腳本會進入FastChat目錄,并使用pip install -e .命令安裝當前目錄下的Python包。

(2)然后重新計算該目錄下所有文件的MD5校驗和,并將新校驗和寫入checksum.config文件中。

4.創建模型倉庫和日志目錄

(1)使用mkdir -p命令創建所需的目錄結構,包括模型倉庫和日志目錄。-p參數確保了即使父目錄不存在,也能創建完整的路徑。

5.設置符號鏈接

(1)腳本檢查QAEnsemble_baseQAEnsemble_embed_rerank目錄中是否已經存在名為basererankembed的符號鏈接。

(2)如果這些符號鏈接不存在,腳本會在QAEnsemble_baseQAEnsemble_embed_rerank目錄下創建它們,分別指向/model_repos/QAEnsemble/base/model_repos/QAEnsemble/rerank/model_repos/QAEnsemble/embed

6.默認后端選擇

默認后端為FasterTransformer,僅支持Nvidia RTX 30系列或40系列顯卡。還可以選擇vllm和hf后端。

7.根據GPU顯存和模型尺寸提供建議

(1)檢查顯存大小:腳本首先檢查環境變量GPU1_MEMORY_SIZE的值,這個值代表第一個GPU的顯存大小(單位是MiB)。

(2)顯存小于4GB:如果顯存小于4GB,腳本會建議用戶升級顯卡,因為當前顯存不足以部署項目,并退出程序。

(3)使用OpenAI API:如果顯存大小為0B(表示使用在線的OpenAI API),腳本會打印出當前顯存可以使用OpenAI API。

(4)顯存小于8GB:如果顯存在4GB到8GB之間,腳本推薦使用在線的OpenAI API,并且如果模型大小超過顯存容量,腳本會提示用戶重新選擇模型大小,并退出。

(5)顯存在8GB到10GB之間:對于8GB到10GB的顯存,推薦部署1.8B的大模型,并包括使用OpenAI API。如果模型大小超過2B,腳本會提示用戶顯存不足,并退出。

(6)顯存在10GB到16GB之間:對于10GB到16GB的顯存,推薦部署3B及3B以下的模型,并包括使用OpenAI API。如果模型大小超過3B,腳本會提示用戶顯存不足,并退出。

(7)顯存在16GB到22GB之間:對于16GB到22GB的顯存,推薦部署小于等于7B的大模型。根據使用的后端(Qwen-7B-QAnything+FasterTransformer、Huggingface Transformers、VLLM),腳本會設置不同的tokens上限以避免顯存溢出,并退出如果模型大小不兼容。

(8)顯存在22GB到25GB之間:對于22GB到25GB的顯存,推薦部署7B模型。如果模型大小超過7B,腳本會提示用戶顯存不足,并退出。

(9)顯存大于25GB:對于大于25GB的顯存,腳本不會設置tokens上限。

腳本中還包含了一些邏輯來處理不同后端(如defaulthfvllm)的特定情況,并根據這些后端和顯存大小來設置OFFCUT_TOKEN環境變量,這個變量可能用于控制程序中的某些內存限制。

8.核心服務啟動過程

大模型中轉服務已就緒 (1/8)
rerank服務已就緒 (2/8)
OCR服務已就緒 (3/8)
qanything后端服務已就緒 (4/8)
Dependencies related to npm are obtained (5/8)
[npm run build] build successfully (6/8)
前端服務已就緒 (7/8)
Embedding和Rerank服務已準備就緒 (7.5/8)
LLM 服務已準備就緒,現在您可以使用qanything服務 (8/8)

說明:run_for_cloud_option.sh不再講解。

五.啟動的容器

1.qanything-container-local

這個容器運行 QAnything 服務,這是一個基于深度學習的問答系統。它可以處理各種類型的文件和數據,并提供問答功能。這個容器依賴于 “standalone” 和 “mysql” 容器。

2.milvus-standalone-local

這個容器運行 Milvus 服務,Milvus 是一個開源的向量數據庫,用于處理大規模的向量數據。它提供了高效的向量索引和查詢功能。這個容器依賴于 “etcd” 和 “minio” 容器。

3.milvus-minio-local

這個容器運行 MinIO 服務,MinIO 是一個高性能的對象存儲服務,用于存儲和管理大量的非結構化數據,如圖片、視頻、日志文件等。

4.mysql-container-local

這個容器運行 MySQL 服務,MySQL 是一個關系型數據庫管理系統,用于存儲和管理結構化數據。

5.milvus-etcd-local

這個容器運行 etcd 服務,etcd 是一個分布式鍵值存儲系統,用于共享配置和服務發現。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/37779.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37779.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37779.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Leetcode Java學習記錄——棧和隊列 IDEA

文章目錄 棧和隊列stack Classqueue InterfaceDeque Interfaceadd 和 push Priority Queue -- Class題目 codestyleIDEA 操作快捷鍵選擇代碼生成類 棧和隊列 stack Class google stack java 8/12 empty() peek() pop() push(E item) search(Object o) 最近相關性會用到棧 …

湘潭大學軟件工程數據庫總結

文章目錄 前言試卷結構給學弟學妹的一些參考自己的一些總結 前言 自己可能很早很早之前就準備復習了&#xff0c;但是感覺還是沒有學到要點&#xff0c;主要還是沒啥緊迫的壓力&#xff0c;我們是三月份開學&#xff0c;那時候實驗室有朋友挺認真開始學習數據庫了&#xff0c;…

理性決策的藝術:從購房到擇偶的數學智慧;37% 規則,做出最佳決策的秘訣;用數學模型解決人生難題

在面對人生重大決策時&#xff0c;如購房或擇偶&#xff0c;我們常常感到迷茫和困惑。然而&#xff0c;如果我們能夠將這些看似復雜的問題簡化為數學模型&#xff0c;我們就能以更加理性和系統的方式做出決策。 37%規則 1950年代&#xff0c;當時幾位數學家開始研究這樣一個問…

值得收藏!盤點那些適合普通人方便又好用的AIGC工具!(下)

【導讀】接上一篇文章&#xff0c;盤點國內外適合普通人能夠輕松上手的AIGC工具&#xff08;上&#xff09;。今天又為大家整理了一些好用又方便的AI設計工具、AI辦公工具、AI編程工具、AI指令工具和AI檢測工具&#xff0c;如果有沒更新到的工具也歡迎大家評論區交流。 一 、A…

Kafka 入門指南

Kafka 入門指南 簡介 Kafka 是一個由 Apache 軟件基金會開發的開源流處理平臺。它最初由 LinkedIn 開發&#xff0c;并在 2011 年作為開源項目發布。Kafka 是一個分布式、可擴展、高吞吐量的消息隊列系統&#xff0c;廣泛應用于實時數據流處理場景。 主要概念 1. 主題 (Top…

C#/WPF 自制截圖工具

在日常使用電腦辦公時&#xff0c;我們經常遇到需要截圖然后保存圖片&#xff0c;我們往往需要借助安裝截圖工具才能實現&#xff0c;現在我們通過C#自制截圖工具&#xff0c;也能夠輕松進行截圖。 我們可以通過C#調用WindousAPI來實現截圖&#xff0c;實例代碼如下&#xff1a…

AI基本概念(人工智能、機器學習、深度學習)

人工智能 、 機器學習、 深度學習的概念和關系 人工智能 &#xff08;Artificial Intelligence&#xff09;AI- 機器展現出人類智慧機器學習 &#xff08;Machine Learning) ML, 達到人工智能的方法深度學習 &#xff08;Deep Learning&#xff09;DL,執行機器學習的技術 從范圍…

算法 —— 滑動窗口

目錄 長度最小的子數組 無重復字符的最長子串 最大連續1的個數 將x減到0的最小操作數 找到字符串中所有字母異位詞 長度最小的子數組 sum比target小就進窗口&#xff0c;sum比target大就出窗口&#xff0c;由于數組是正數&#xff0c;所以相加會使sum變大&#xff0c;相減…

關于redis的運維面試題-1

1. 什么是Redis&#xff1f; Redis&#xff08;Remote Dictionary Server&#xff09;是一個開源的內存數據結構存儲&#xff0c;通常用作數據庫、緩存和消息代理。它支持多種數據結構&#xff0c;如字符串&#xff08;strings&#xff09;、哈希&#xff08;hashes&#xff0…

大二暑假 + 大三上

希望&#xff0c;暑假能早睡早起&#xff0c;胸圍達到 95&#xff0c;腰圍保持 72&#xff0c;大臂 36&#xff0c;小臂 32&#xff0c;小腿 38&#x1f36d;&#x1f36d; 目錄 &#x1f348;暑假計劃 &#x1f339;每周進度 &#x1f923;寒假每日進度&#x1f602; &…

DiskGeniusV5.6.0.1565發布!

DiskGenius是一款功能強大的磁盤管理和數據恢復工具&#xff0c;V5.6.0.1565上線。新版本變化比較大&#xff0c;增加新的功能&#xff0c;修正已經問題&#xff0c;值得試一下。提醒大家&#xff0c;磁盤管理軟件涉及數據安全&#xff0c;請始終使用最新版本&#xff01; 下面…

JS hook

參照&#xff1a; JS 逆向之 Hook JS Hook 與 過 debugger 一、常用Hook 1. eval (function() {let _eval eval;eval function(val) {if (val.indexof(debugger) -1) {_eval_cache(obj);}} })(); 2. JSON.parse() (function () {var parse_ JSON.parse;JSON.parse …

C++ initializer_list類型推導

目錄 initializer_list C自動類型推斷 auto typeid decltype initializer_list<T> C支持統一初始化{ }&#xff0c;出現了一個新的類型initializer_list<T>&#xff0c;一切類型都可以用列表初始化。提供了一種更加靈活、安全和明確的方式來初始化對象。 class…

IO-Link OD介紹

IO-Link OD&#xff08;On-request Data&#xff0c;按需數據&#xff09;是IO-Link通信中的一種重要數據類型&#xff0c;主要用于參數讀寫、指令交互、事件上傳等動作。以下是關于IO-Link OD的結構、構成以及功能使用的詳細說明&#xff1a; 結構與構成 定義&#xff1a;OD…

堆排序(Heap Sort)

堆排序是一種高效的排序算法&#xff0c;它利用了堆的數據結構來實現。堆是一種特殊的完全二叉樹&#xff0c;分為最大堆和最小堆兩種類型。在最大堆中&#xff0c;父節點的值大于等于其子節點的值&#xff1b;而在最小堆中&#xff0c;父節點的值小于等于其子節點的值。 堆排…

【C命名規范】遵循良好的命名規范,提高代碼的可讀性、可維護性和可復用性

/******************************************************************** * brief param return author date version是代碼書寫的一種規范 * brief &#xff1a;簡介&#xff0c;簡單介紹函數作用 * param &#xff1a;介紹函數參數 * return&#xff1a;函數返回類型說明 * …

同一個excel表格,為什么在有的電腦上會顯示#NAME?

一、哪些情況會產生#NAME?的報錯 1.公式名稱拼寫錯誤 比如求和函數SUM&#xff0c;如果寫成SUN就會提示#NAME&#xff1f;報錯。 2.公式中的文本值未添加雙引號 如下圖&#xff1a; VLOOKUP(丙,A:B,2,0) 公式的計算結果會返回錯誤值#NAME?&#xff0c;這是因為公式中文本…

【PLC】三菱PLC如何和匯川伺服實現485通信

前言 一開始選用的是匯川SV660P脈沖型伺服&#xff0c;由于生產需求需要對伺服的個別參數進行讀取和寫入操作&#xff0c;但是SV660P并不支持這種情況&#xff0c;因此需要使用485通信來滿足。PLC這邊選用的是三菱FX5U。 開始 1、首先準備按照下圖的引腳提示準備好一根帶屏蔽…

全志H616交叉編譯工具鏈的安裝與使用

交叉編譯的概念 1. 什么是交叉編譯&#xff1f; 交叉編譯是指在一個平臺上生成可以在另一個平臺上運行的可執行代碼。例如&#xff0c;在Ubuntu Linux上編寫代碼&#xff0c;并編譯生成可在Orange Pi Zero2上運行的可執行文件。這個過程是通過使用一個專門的交叉編譯工具鏈來…

(七)glDrawArry繪制

幾何數據&#xff1a;vao和vbo 材質程序&#xff1a;vs和fs(頂點著色器和片元著色器) 接下來只需要告訴GPU&#xff0c;使用幾何數據和材質程序來進行繪制。 #include <glad/glad.h>//glad必須在glfw頭文件之前包含 #include <GLFW/glfw3.h> #include <iostrea…