本地运行LLM大模型的5个必备工具
liuian 2025-01-01 21:34 121 浏览
在快速发展的人工智能领域,有效地服务大型语言模型 (LLM) 和视觉语言模型 (VLM) 对于充分发挥其潜力至关重要。随着这些模型变得越来越复杂,找到强大且可扩展的服务解决方案变得越来越重要。
在本指南中,我们将重点介绍5个在这一领域取得进展的著名项目:VLLM、LLAMA CPP Server 、SGLang、Ollama和TGI。
1、VLLM
VLLM 是一个高性能库,专为高效的 LLM 推理和服务而设计。它在吞吐量和灵活性方面表现出色,具有最先进的服务功能、通过 PagedAttention 实现的高效内存管理以及持续请求批处理等功能。 CUDA/HIP 图形执行和优化的 CUDA 内核提高了其性能。VLLM 支持各种量化方法,并与流行的 HuggingFace 模型无缝集成。它还提供高吞吐量服务,具有多种解码算法、张量和管道并行性、流式输出,并与 NVIDIA 和 AMD GPU 兼容。实验性功能包括前缀缓存和多 lora 支持。
1.1 使用说明
要安装 VLLM,请运行以下命令:
pip install vllm
安装后,你可以使用以下命令提供 LLM:
vllm serve Qwen/Qwen2-1.5B-Instruct --dtype auto --api-key token-abc123基本 vllm 参数:
- --host HOSTNAME:服务器主机名(默认值:localhost)
- --port PORT:服务器端口号(默认值:8000)
- --api-key KEY:用于服务器访问的 API 密钥(如果提供,服务器需要此密钥在标头中)
- --model MODEL:要使用的 HuggingFace 模型的名称或路径(例如,Qwen/Qwen2-1.5B-Instruct)
- --tokenizer TOKENIZER:要使用的标记器的名称或路径(例如,Qwen/Qwen2-1.5B-Instruct)
- --quantization METHOD:量化方法模型权重(例如,aqlm、awq、fp8、bitsandbytes、None)
- --dtype TYPE:模型权重和激活的数据类型(例如,auto、half、float16、bfloat16、float32)
- --device DEVICE:执行设备类型(例如,auto、cuda、cpu、tpu)
- --lora-modules MODULES:LoRA 模块配置(名称=路径对列表)
1.2 使用 Docker 部署
要使用 Docker 部署 VLLM,请运行以下命令:
docker pull vllm/vllm-openai:v0.5.4
docker run --runtime nvidia --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
--env "HUGGING_FACE_HUB_TOKEN=<secret>" \
-p 8000:8000 \
--ipc=host \
vllm/vllm-openai:latest \
--model Qwen/Qwen2-1.5B-Instruct要将端点与 openai 库一起使用:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="token-abc123",
)
completion = client.chat.completions.create(
model="Qwen/Qwen2-1.5B-Instruct",
messages=[
{"role": "user", "content": "Hello!"}
]
)
print(completion.choices[0].message)2、LLaMA.cpp HTTP 服务器
LLaMA.cpp HTTP 服务器是一个轻量级且快速的基于 C/C++ 的 HTTP 服务器,利用 httplib、nlohmann::json 和 llama.cpp。它提供了一组 LLM REST API 和一个简单的 Web 界面,用于与 llama.cpp 交互。主要功能包括支持 GPU 和 CPU 上的 F16 和量化模型、OpenAI API 兼容性、并行解码、连续批处理和监控端点。它还支持架构约束的 JSON 响应,并且正在开发多模式功能。
2.1 使用说明
要安装 LLaMA.cpp,请运行以下命令:
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp && make安装后,我们应该从 Hugging Face hub 下载 gguf 模型 (Mistral-7B-Instruct-v0.2-GGUF) 作为示例:
cd models && wget https://huggingface.co/TheBloke/Mistral-7B-Instruct-v0.2-GGUF/resolve/main/mistral-7b-instruct-v0.2.Q2_K.gguf要启动服务器,请运行以下命令:
cd ..
./llama-server -m models/mistral-7b-instruct-v0.2.Q2_K.gguf -c 20482.2 基本 vllm 参数
常规:
- -h、--help、--usage:打印使用情况并退出
- --version:显示版本和构建信息
- -v,--verbose:打印详细信息
- --verbosity N:设置特定详细程度(默认值:0)
- --color:为输出着色(默认值:false)
- -s,--seed SEED:RNG 种子(默认值:-1,小于 0 时使用随机种子)
- -t,--threads N:线程数(默认值:8)
- --ctx-size N:提示上下文的大小(默认值:0,0 = 从模型加载)
- -n,--predict N:要预测的标记数(默认值:-1,-1 = 无穷大,-2 = 直到上下文填满)
- --prompt PROMPT:开始生成的提示(默认值:'')
- --interactive:以交互模式运行(默认值:false)
采样:
- --temp N:温度(默认值:0.8)
- --top-k N:Top-k 采样(默认值:40,0 = 禁用)
- --top-p N:Top-p 采样(默认值:0.9,1.0 = 禁用)
- --mirostat N:使用 Mirostat 采样(默认值:0,0 = 禁用,1 = Mirostat,2 = Mirostat 2.0)
模型:
- -m,--model FNAME:模型路径(默认值:models/$filename)
- --lora FNAME:应用 LoRA 适配器(隐含 --no-mmap)
- --control-vector FNAME:添加控制向量
- --check-tensors:检查模型张量数据中是否存在无效值(默认值:false)
服务器:
- --host HOST:要监听的 IP 地址(默认值:127.0.0.1)
- --port PORT:要监听的端口(默认值:8080)
- --timeout N:服务器读写超时(秒)(默认值: 600)
日志记录:
- -ld,--logdir LOGDIR:保存 YAML 日志的路径(如果未设置则不记录)
- --log-enable:启用跟踪日志
上下文:
- --rope-scaling {none,linear,yarn}:RoPE 频率缩放方法(默认值:线性)
并行:
- -np,--parallel N:要解码的并行序列数(默认值:1)
嵌入: - --embd-normalize:嵌入的规范化(默认值:2)
2.3 使用 Docker 部署
要使用 Docker 部署 LLaMA.cpp,请运行以下命令:
docker run -p 8080:8080 -v /path/to/models:/models ghcr.io/ggerganov/llama.cpp:server
-m models/mistral-7b-instruct-v0.2.Q2_K.gguf
-c 512
--host 0.0.0.0
--port 8080
# or, with CUDA:
docker run -p 8080:8080
-v /path/to/models:/models
--gpus all ghcr.io/ggerganov/llama.cpp:server-cuda
-m models/mistral-7b-instruct-v0.2.Q2_K.gguf
-c 512
--host 0.0.0.0
--port 8080
--n-gpu-layers 99要将端点与 openai 库一起使用:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8081/v1",
api_key="token-abc123",
)
completion = client.chat.completions.create(
model="Mistral-7B-Instruct-v0.2-GGUF",
messages=[
{"role": "user", "content": "Hello!"}
]
)
print(completion.choices[0].message)3、SGLang
SGLang 是一个专为 LLM 和 VLM 设计的快速服务框架,专注于提高交互速度和控制。它具有高效的后端运行时,使用 RadixAttention 进行前缀缓存、前跳约束解码和各种量化技术。SGLang 还支持张量并行和高级内核以提高性能。灵活的前端语言允许轻松编程复杂的 LLM 应用程序,包括链式生成调用、高级提示和并行性,以及与多种模态和外部交互的集成。
3.1 使用说明
要安装 SGLang,请运行以下命令:
pip install --upgrade pip
pip install "sglang[all]"
# Install FlashInfer CUDA kernels
pip install flashinfer -i https://flashinfer.ai/whl/cu121/torch2.3/要启动服务器,请运行以下命令:
! python -m sglang.launch_server --model-path Qwen/Qwen2-1.5B-Instruct --port 300003.2 基本 vllm 参数
必需选项
- --model-path MODEL_PATH:模型权重路径(必需)。
可选关键选项
- --tokenizer-path TOKENIZER_PATH:tokenizer 路径。
- --host HOST:服务器主机(默认为 localhost)。
- --port PORT:服务器端口(默认为 8000 或其他常用端口)。
- --tokenizer-mode {auto,slow}:默认可能为自动。
- --load-format {auto,pt,safetensors,npcache,dummy}:默认可能为自动。
- --dtype {auto,half,float16,bfloat16,float,float32}:默认可能为自动。
- --context-length CONTEXT_LENGTH:默认为 None,使用模型的配置值。
性能和资源选项
- --mem-fraction-static MEM_FRACTION_STATIC:静态分配的内存分数。
- --max-prefill-tokens MAX_PREFILL_TOKENS:预填充批次中的最大令牌数。
- --max-running-requests MAX_RUNNING_REQUESTS:最大运行请求数。
- --max-num-reqs MAX_NUM_REQS:内存池中的最大请求数。
- --max-total-tokens MAX_TOTAL_TOKENS:内存池中的最大 token 数。
调度和并行性
- --schedule-policy {lpm,random,fcfs,dfs-weight}:调度策略,默认为 fcfs(先到先得)。
- --tp-size TP_SIZE:张量并行性大小。
- --dp-size DP_SIZE:数据并行性大小。
日志记录和调试
- --log-level LOG_LEVEL:日志记录级别。
- --log-requests:日志请求。
- --show-time-cost:显示自定义标记的时间成本。
高级选项
- --quantization {awq,fp8,gptq,marlin,gptq_marlin,awq_marlin,squeezellm,bitsandbytes}:量化方法。
- --load-balance-method {round_robin,shortest_queue}:负载平衡策略。
实验性或可选功能 - --enable-torch-compile:实验性优化功能。
- --disable-disk-cache:禁用磁盘缓存。
3.3 使用 Docker 部署
要使用 Docker 部署 SGLang,请运行以下命令:
docker pull lmsysorg/sglang:v0.2.10-cu124
docker run --gpus all \
-p 30000:30000 \
-v ~/.cache/huggingface:/root/.cache/huggingface \
--env "HF_TOKEN=<secret>" \
--ipc=host \
lmsysorg/sglang:latest \
python3 -m sglang.launch_server --model-path Qwen/Qwen2-1.5B-Instruct --host 0.0.0.0 --port 30000使用openai库访问端点:
import openai
client = openai.Client(
base_url="http://127.0.0.1:30000/v1", api_key="EMPTY")
# Text completion
response = client.completions.create(
model="default",
prompt="The capital of France is",
temperature=0,
max_tokens=32,
)
print(response)4、Ollama:简化本地 LLM 部署
Ollama 是一个开源平台,旨在简化在本地机器上部署大型语言模型的过程。它充当了 LLM 通常所需的复杂基础设施与寻求更易于访问和可定制的 AI 体验的用户之间的桥梁。凭借其与 OpenAI 兼容的 API,Ollama 可与现有工具和工作流程无缝集成。
该平台强调对量化模型的支持,这对于减少内存使用和提高性能至关重要。Ollama 提供了一个不断增长的预训练模型库,从多功能通用选项到用于小众任务的专用模型。可用的著名模型包括 Llama 3.1、Qwen、Mistral 和 deepseek-coder-v2 等专用变体。
Ollama 的用户友好型设置过程和直观的模型管理由其统一的 Modelfile 格式提供。它的跨平台支持(包括 Windows、macOS 和 Linux)进一步增强了可访问性。通过提供具有与 OpenAI 兼容的接口的本地模型服务,Ollama 是寻求本地部署灵活性以及标准 API 集成便利性的开发人员的强大选择。
4.1 安装依赖项和 Ollama
首先,我们需要安装 openai Python 包。该库提供了一个简单的接口来与任何 OpenAI 兼容的 API 进行交互,这在我们稍后连接到 Ollama 服务器时将至关重要。
pip install openai接下来,我们使用单个命令安装 Ollama(适用于 Linux)。Ollama 旨在简化运行本地 LLM 的过程,因此设置起来既快速又简单。
curl -fsSL https://ollama.com/install.sh | sh4.2 使用 Ollama 拉取和提供模型
安装 Ollama 后,我们拉取 qwen2:1.5b 模型。该模型是 Ollama 支持的众多模型之一,它展示了该工具在本地管理和运行各种大型语言模型的能力。
ollama pull qwen2:1.5b拉取模型后,我们启动 Ollama 服务器。这使我们能够在本地提供模型并通过 API 访问它。
4.3 使用 OpenAI 客户端向 Ollama 发出简单请求
在这里,我们设置 OpenAI 客户端与 Ollama 服务器进行通信。base_url 指向本地服务器,而 api_key 是必需的,但 Ollama 未使用。
ollama serve然后,我们向 qwen2:1.5b 模型(即我们上面拉取的模型)发送聊天完成请求。
from openai import OpenAI
client = OpenAI(
base_url = 'http://127.0.0.1:11434/v1',
api_key='ollama',
)
response = client.chat.completions.create(
model="qwen2:1.5b",
messages=[
{"role": "system", "content": "You are a helpful assistant." },
{"role": "user", "content": "What is deep learning?"}
]
)
print(response.choices[0].message.content)4.4 使用 OpenAI API 流式传输响应
客户端的配置方式相同,但这次我们在生成响应时对其进行流式传输。这对于需要在令牌进入时对其进行处理的实时应用程序特别有用。
from openai import OpenAI
# init the client but point it to TGI
client = OpenAI(
base_url="http://127.0.0.1:11434/v1",
api_key="ollama"
)
chat_completion = client.chat.completions.create(
model="qwen2:1.5b",
messages=[
{"role": "system", "content": "You are a helpful assistant." },
{"role": "user", "content": "What is deep learning?"}
],
stream=True
)
# iterate and print stream
for message in chat_completion:
print(message.choices[0].delta.content)5、TGI:高性能 LLM 服务
TGI (文本生成推理) 是一种可用于生产的用于部署和提供 LLM 的工具包,重点是高性能文本生成。与本系列中讨论的其他工具一样,TGI 提供了与 OpenAI 兼容的 API,可轻松将高级 LLM 集成到现有应用程序中。
TGI 支持流行的开源模型,如 gemma2、mistral-nemo、mistral-large、qwen 等,使其成为需要可扩展、高吞吐量 AI 解决方案的组织的诱人选择。主要功能包括张量并行性或跨多个 GPU 进行更快的推理、使用服务器发送事件 (SSE) 进行令牌流式传输以及连续批处理以最大化吞吐量。
除了这些功能之外,TGI 还实现了 Flash Attention 和 Paged Attention 等高级优化,这对于提高 Transformer 架构上的推理速度至关重要。它还通过 bitsandbytes 和 GPT-Q 等技术支持模型量化,从而实现高效部署,同时保持模型性能。对于定制任务,TGI 提供微调支持和指导功能,进一步增强输出的相关性和准确性。
凭借其强大的功能集,包括分布式跟踪和用于监控的 Prometheus 指标,TGI 是要求苛刻的生产环境中提供 LLM 的理想解决方案。
5.1 本地安装 TGI
首先,我们通过安装必要的依赖项(包括 libssl-dev 和 gcc)来设置环境。我们还下载并安装协议缓冲区 (protoc) 包,这对于编译 TGI 框架使用的 protobuf 文件至关重要。
sudo apt-get install libssl-dev gcc -y
PROTOC_ZIP=protoc-21.12-linux-x86_64.zip
curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v21.12/$PROTOC_ZIP
sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*'
rm -f $PROTOC_ZIP5.2 在本地构建和运行 TGI
要安装和运行 TGI,需要构建启用扩展(CUDA 内核)的存储库,以便在 GPU 上获得最佳性能。之后,你可以使用 Hugging Face 生态系统支持的任何模型(如 Mistral)启动文本生成服务。
BUILD_EXTENSIONS=True make install
text-generation-launcher --model-id mistralai/Mistral-Large-Instruct-2407要运行不同的模型,只需更改 --model-id 参数:
text-generation-launcher --model-id Qwen/Qwen2-1.5B-Instruct
5.3 使用量化运行
可以通过运行预量化权重或使用 AWQ、GPTQ 或 bitsandbytes 等动态量化选项来减少 VRAM 使用量。这在有限硬件上处理大型模型时特别有用。
text-generation-launcher --model-id Qwen/Qwen2-72B-Instruct-GPTQ-Int8 --sharded true --num-shard 2 --quantize gptq
5.4 使用 Docker 进行 TGI 部署
如果你更喜欢使用 Docker,可以通过安装模型数据卷并公开服务器的端口来轻松部署 TGI:
model=Qwen/Qwen2-1.5B-Instruct
volume=$PWD/data然后,运行具有 GPU 访问权限的 Docker 容器:
docker run --gpus all --shm-size 1g -p 8080:80 -v $volume:/data \
ghcr.io/huggingface/text-generation-inference:2.2.0 --model-id $model你可以通过发送生成文本的请求来测试部署:
curl 127.0.0.1:8080/generate_stream \
-X POST \
-d '{"inputs":"What is Deep Learning?","parameters":{"max_new_tokens":20}}' \
-H 'Content-Type: application/json'5.5 OpenAI 兼容 API 支持
TGI 的一项重要功能(从 1.4.0 版开始)是它与 OpenAI Chat Completion API 兼容。这允许你使用 OpenAI 的客户端库或其他期望相同架构的库与 TGI 的消息 API 进行交互。
发出同步请求
在这里,我们设置 OpenAI 客户端,但将其指向 TGI 端点。然后,我们创建一个类似于你使用 OpenAI API 执行的聊天完成请求。
from openai import OpenAI
# init the client but point it to TGI
client = OpenAI(
base_url="http://localhost:3000/v1",
api_key="-"
)
chat_completion = client.chat.completions.create(
model="tgi",
messages=[
{"role": "system", "content": "You are a helpful assistant." },
{"role": "user", "content": "What is deep learning?"}
],
stream=False
)
print(chat_completion.choices[0].message.content)发出流式请求
对于实时应用程序,你可以在生成响应时对其进行流式传输。OpenAI 客户端通过迭代流的每个部分来处理此问题,使你能够动态处理和显示结果。
from openai import OpenAI
# init the client but point it to TGI
client = OpenAI(
base_url="http://localhost:3000/v1",
api_key="-"
)
chat_completion = client.chat.completions.create(
model="tgi",
messages=[
{"role": "system", "content": "You are a helpful assistant." },
{"role": "user", "content": "What is deep learning?"}
],
stream=True
)
# iterate and print stream
for message in chat_completion:
print(message)原文链接:本地运行大模型的5个工具 - 汇智网
相关推荐
-
- 驱动网卡(怎么从新驱动网卡)
-
网卡一般是指为电脑主机提供有线无线网络功能的适配器。而网卡驱动指的就是电脑连接识别这些网卡型号的桥梁。网卡只有打上了网卡驱动才能正常使用。并不是说所有的网卡一插到电脑上面就能进行数据传输了,他都需要里面芯片组的驱动文件才能支持他进行数据传输...
-
2026-01-30 00:37 liuian
- win10更新助手装系统(微软win10更新助手)
-
1、点击首页“系统升级”的按钮,给出弹框,告诉用户需要上传IMEI码才能使用升级服务。同时给出同意和取消按钮。华为手机助手2、点击同意,则进入到“系统升级”功能华为手机助手华为手机助手3、在检测界面,...
- windows11专业版密钥最新(windows11专业版激活码永久)
-
Windows11专业版的正版密钥,我们是对windows的激活所必备的工具。该密钥我们可以通过微软商城或者通过计算机的硬件供应商去购买获得。获得了windows11专业版的正版密钥后,我...
-
- 手机删过的软件恢复(手机删除过的软件怎么恢复)
-
操作步骤:1、首先,我们需要先打开手机。然后在许多图标中找到带有[文件管理]文本的图标,然后单击“文件管理”进入页面。2、进入页面后,我们将在顶部看到一行文本:手机,最新信息,文档,视频,图片,音乐,收藏,最后是我们正在寻找的[更多],单击...
-
2026-01-29 23:55 liuian
- 一键ghost手动备份系统步骤(一键ghost 备份)
-
步骤1、首先把装有一键GHOST装系统的U盘插在电脑上,然后打开电脑马上按F2或DEL键入BIOS界面,然后就选择BOOT打USDHDD模式选择好,然后按F10键保存,电脑就会马上重启。 步骤...
- 怎么创建局域网(怎么创建局域网打游戏)
-
1、购买路由器一台。进入路由器把dhcp功能打开 2、购买一台交换机。从路由器lan端口拉出一条网线查到交换机的任意一个端口上。 3、两台以上电脑。从交换机任意端口拉出网线插到电脑上(电脑设置...
- 精灵驱动器官方下载(精灵驱动手机版下载)
-
是的。驱动精灵是一款集驱动管理和硬件检测于一体的、专业级的驱动管理和维护工具。驱动精灵为用户提供驱动备份、恢复、安装、删除、在线更新等实用功能。1、全新驱动精灵2012引擎,大幅提升硬件和驱动辨识能力...
- 一键还原系统步骤(一键还原系统有哪些)
-
1、首先需要下载安装一下Windows一键还原程序,在安装程序窗口中,点击“下一步”,弹出“用户许可协议”窗口,选择“我同意该许可协议的条款”,并点击“下一步”。 2、在弹出的“准备安装”窗口中,可...
- 电脑加速器哪个好(电脑加速器哪款好)
-
我认为pp加速器最好用,飞速土豆太懒,急速酷六根本不工作。pp加速器什么网页都加速,太任劳任怨了!以上是个人观点,具体性能请自己试。ps:我家电脑性能很好。迅游加速盒子是可以加速电脑的。因为有过之...
- 任何u盘都可以做启动盘吗(u盘必须做成启动盘才能装系统吗)
-
是的,需要注意,U盘的大小要在4G以上,最好是8G以上,因为启动盘里面需要装系统,内存小的话,不能用来安装系统。内存卡或者U盘或者移动硬盘都可以用来做启动盘安装系统。普通的U盘就可以,不过最好U盘...
- u盘怎么恢复文件(u盘文件恢复的方法)
-
开360安全卫士,点击上面的“功能大全”。点击文件恢复然后点击“数据”下的“文件恢复”功能。选择驱动接着选择需要恢复的驱动,选择接入的U盘。点击开始扫描选好就点击中间的“开始扫描”,开始扫描U盘数据。...
- 系统虚拟内存太低怎么办(系统虚拟内存占用过高什么原因)
-
1.检查系统虚拟内存使用情况,如果发现有大量的空闲内存,可以尝试释放一些不必要的进程,以释放内存空间。2.如果系统虚拟内存使用率较高,可以尝试增加系统虚拟内存的大小,以便更多的应用程序可以使用更多...
-
- 剪贴板权限设置方法(剪贴板访问权限)
-
1、首先打开iphone手机,触碰并按住单词或图像直到显示选择选项。2、其次,然后选取“拷贝”或“剪贴板”。3、勾选需要的“权限”,最后选择开启,即可完成苹果剪贴板权限设置。仅参考1.打开苹果手机设置按钮,点击【通用】。2.点击【键盘】,再...
-
2026-01-29 21:37 liuian
- 平板系统重装大师(平板重装win系统)
-
如果你的平板开不了机,但可以连接上电脑,那就能好办,楼主下载安装个平板刷机王到你的个人电脑上,然后连接你的平板,平板刷机王会自动识别你的平板,平板刷机王上有你平板的我刷机包,楼主点击下载一个,下载完成...
- 联想官网售后服务网点(联想官网售后服务热线)
-
联想3c服务中心是联想旗下的官方售后,是基于互联网O2O模式开发的全新服务平台。可以为终端用户提供多品牌手机、电脑以及其他3C类产品的维修、保养和保险服务。根据客户需求层次,联想服务针对个人及家庭客户...
- 一周热门
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)
