Repository: liguodongiot/llm-action Branch: main Commit: f97e03bc1ecb Files: 822 Total size: 6.2 MB Directory structure: gitextract_50r359j2/ ├── .gitignore ├── LICENSE ├── README.md ├── ai-compiler/ │ ├── README.md │ ├── Treebeard/ │ │ └── README.md │ ├── treelit/ │ │ ├── README.md │ │ └── xgb.md │ └── triton-lang/ │ └── README.md ├── ai-framework/ │ ├── README.md │ ├── TensorRT-Model-Optimizer.md │ ├── cuda/ │ │ └── README.md │ ├── deepspeed/ │ │ ├── 1.DeepSpeed入门.md │ │ ├── 2.安装DeepSpeed.md │ │ ├── 3.基于CIFAR-10使用DeepSpeed进行分布式训练 .md │ │ ├── DeepSpeed配置JSON文件.md │ │ ├── README.md │ │ ├── config-json/ │ │ │ ├── README.md │ │ │ └── deepspeed-nvme.md │ │ ├── deepspeed-slurm.md │ │ ├── hello_bert/ │ │ │ ├── README.md │ │ │ ├── train_bert.py │ │ │ └── train_bert_ds.py │ │ └── training/ │ │ └── pipeline_parallelism/ │ │ └── README.md │ ├── dlrover.md │ ├── huggingface-accelerate/ │ │ └── README.md │ ├── huggingface-peft/ │ │ └── README.md │ ├── huggingface-transformers/ │ │ ├── API.md │ │ ├── FSDP.md │ │ └── README.md │ ├── huggingface-trl/ │ │ └── README.md │ ├── jax/ │ │ ├── README.md │ │ └── reference.md │ ├── llama-cpp/ │ │ └── README.md │ ├── megatron-deepspeed/ │ │ └── README.md │ ├── megatron-lm/ │ │ └── README.md │ ├── mxnet/ │ │ ├── README.md │ │ ├── mnist.py │ │ ├── mxnet_cnn_mnist.py │ │ ├── mxnet_mlp_mnist.py │ │ ├── oneflow_cnn_mnist.py │ │ ├── oneflow_mlp_mnist.py │ │ └── reference.md │ ├── oneflow/ │ │ ├── README.md │ │ ├── oneflow_mlp_mnist.py │ │ └── reference.md │ ├── openai-triton/ │ │ └── README.md │ ├── paddlepaddle/ │ │ ├── README.md │ │ └── reference.md │ ├── pai-megatron-patch/ │ │ └── README.md │ ├── pai-torchacc.md │ ├── pytorch/ │ │ ├── README.md │ │ ├── install.md │ │ └── reference.md │ ├── tensorflow/ │ │ ├── README.md │ │ └── reference.md │ ├── transformer-engine/ │ │ └── mnist/ │ │ ├── README.md │ │ ├── main.py │ │ └── main_stat.py │ └── unsloth-微调.md ├── ai-infra/ │ ├── ai-cluster/ │ │ └── README.md │ ├── ai-hardware/ │ │ ├── AI芯片软件生态.md │ │ ├── CUDA.md │ │ ├── GPU-network.md │ │ ├── GPU相关环节变量.md │ │ ├── NIXL.md │ │ ├── OEM-DGX.md │ │ ├── README.md │ │ ├── TSMC-台积电.md │ │ ├── cuda镜像.md │ │ ├── gpudirect.md │ │ └── 硬件对比.md │ ├── communication.md │ ├── 存储/ │ │ ├── README.md │ │ ├── REF.md │ │ ├── nvme-ssd.md │ │ ├── 固态硬盘.md │ │ └── 存储.md │ ├── 算力/ │ │ ├── AI芯片.md │ │ ├── GPU工作原理.md │ │ ├── NVIDIA-GPU型号.md │ │ ├── 推理芯片.md │ │ └── 昇腾NPU.md │ └── 网络/ │ ├── HPC性能测试.md │ ├── IB-docker.md │ ├── IB流量监控.md │ ├── IB软件.md │ ├── InfiniBand.md │ ├── NCCL.md │ ├── README.md │ ├── REF.md │ ├── Spine-Leaf和InfiniBand网络架构区别简述.md │ ├── nccl-test-集合通讯的性能测试.md │ ├── nvbandwidth.md │ ├── roce.md │ ├── 网络硬件.md │ ├── 通信软件.md │ └── 集合通信原语.md ├── blog/ │ ├── TODO.md │ ├── ai-infra/ │ │ ├── AI 集群基础设施 InfiniBand 详解.md │ │ └── AI 集群基础设施 NVMe SSD 详解.md │ ├── distribution-parallelism/ │ │ ├── 大模型分布式训练并行技术(一)-概述.md │ │ ├── 大模型分布式训练并行技术(九)-总结.md │ │ └── 大模型分布式训练并行技术(六)-多维混合并行.md │ ├── llm-algo/ │ │ ├── moe.md │ │ └── 大白话Transformer架构.md │ ├── llm-compression/ │ │ ├── 大模型量化技术原理-ZeroQuant系列.md │ │ └── 大模型量化技术原理:QoQ量化及QServe推理服务系统.md │ ├── llm-inference/ │ │ └── 大模型推理框架概述.md │ ├── llm-localization/ │ │ ├── 大模型国产化适配1-华为昇腾AI全栈软硬件平台总结.md │ │ └── 大模型国产化适配4-基于昇腾910使用LLaMA-13B进行多机多卡训练.md │ ├── llm-peft/ │ │ ├── 大模型参数高效微调技术原理综述(一)-背景、参数高效微调简介.md │ │ └── 大模型参数高效微调技术原理综述(五)-LoRA、AdaLoRA、QLoRA.md │ └── reference/ │ └── 高性能 LLM 推理框架的设计与实现.md ├── docs/ │ ├── README.md │ ├── conda.md │ ├── flash-attention/ │ │ └── FlashAttention.md │ ├── llm-base/ │ │ ├── FLOPS.md │ │ ├── NVIDIA-Nsight-Systems性能分析.md │ │ ├── README.md │ │ ├── a800-env-install.md │ │ ├── ai-algo.md │ │ ├── autoregressive-lm-decoding-methods.md │ │ ├── dcgmi.md │ │ ├── distribution-parallelism/ │ │ │ ├── README.md │ │ │ ├── auto-parallel/ │ │ │ │ ├── Alpa.md │ │ │ │ ├── Flexflow.md │ │ │ │ ├── Galvatron.md │ │ │ │ ├── Mesh-Tensorflow.md │ │ │ │ ├── README.md │ │ │ │ ├── Unity.md │ │ │ │ ├── auto-parallel.md │ │ │ │ ├── gspmd.md │ │ │ │ ├── 分布式训练自动并行概述.md │ │ │ │ └── 飞桨面向异构场景下的自动并行设计与实践.md │ │ │ ├── data-parallelism/ │ │ │ │ └── README.md │ │ │ ├── moe-parallel/ │ │ │ │ ├── README.md │ │ │ │ ├── moe-framework.md │ │ │ │ ├── moe-parallel.md │ │ │ │ └── paddle_moe.py │ │ │ ├── multidimensional-hybrid-parallel/ │ │ │ │ └── README.md │ │ │ ├── pipeline-parallelism/ │ │ │ │ └── README.md │ │ │ ├── tensor-parallel/ │ │ │ │ ├── README.md │ │ │ │ └── tensor-parallel.md │ │ │ └── 并行技术.drawio │ │ ├── distribution-training/ │ │ │ ├── Bloom-176B训练经验.md │ │ │ ├── FP16-BF16.md │ │ │ ├── GLM-130B训练经验.md │ │ │ ├── OPT-175B训练经验.md │ │ │ ├── README.md │ │ │ └── 自动混合精度.md │ │ ├── gpu-env-var.md │ │ ├── h800-env-install.md │ │ ├── monitor.md │ │ ├── multimodal/ │ │ │ └── sora.md │ │ ├── nvidia-smi-dmon.md │ │ ├── nvidia-smi.md │ │ ├── rlhf/ │ │ │ └── README.md │ │ ├── scenes/ │ │ │ ├── README.md │ │ │ ├── cv/ │ │ │ │ ├── README.md │ │ │ │ ├── paddle/ │ │ │ │ │ └── README.md │ │ │ │ ├── pytorch/ │ │ │ │ │ └── README.md │ │ │ │ └── reference.md │ │ │ └── multi-modal/ │ │ │ ├── README.md │ │ │ └── reference.md │ │ ├── singularity命令.md │ │ ├── slurm.md │ │ ├── 分布式训练加速技术.md │ │ ├── 多机RDMA性能测试.txt │ │ └── 机器学习中常用的数据类型.md │ ├── llm-experience.md │ ├── llm-inference/ │ │ ├── DeepSpeed-Inference.md │ │ ├── KV-Cache.md │ │ ├── LLM服务框架对比.md │ │ ├── README.md │ │ ├── blog.md │ │ ├── flexflow/ │ │ │ └── 投机采样.md │ │ ├── llm推理优化技术.md │ │ ├── llm推理框架.md │ │ └── vllm.md │ ├── llm-peft/ │ │ ├── LoRA-FA.md │ │ ├── MAM_Adapter.md │ │ ├── README.md │ │ └── ReLoRA.md │ ├── llm-summarize/ │ │ ├── README.md │ │ ├── distribution_dl_roadmap.md │ │ ├── 大模型实践总结-20230930.md │ │ ├── 大模型实践总结.md │ │ ├── 文档大模型.md │ │ ├── 金融大模型.md │ │ └── 领域大模型.md │ └── transformer内存估算.md ├── faq/ │ └── FAQ.md ├── git-pull-push.sh ├── llm-algo/ │ ├── FLOPs.md │ ├── InternLM-20B.md │ ├── README.md │ ├── baichuan2/ │ │ └── baichuan.md │ ├── bert/ │ │ └── 模型架构.md │ ├── bert.md │ ├── bloom/ │ │ └── README.md │ ├── bloom.md │ ├── chatglm/ │ │ ├── README.md │ │ └── 模型架构.md │ ├── chatglm2/ │ │ ├── README.md │ │ └── 模型架构.md │ ├── chatglm3/ │ │ ├── README.md │ │ └── reference.md │ ├── chatgpt/ │ │ └── README.md │ ├── deepseek/ │ │ ├── DeepSeek-R1.md │ │ ├── DeepSeek-V2.md │ │ ├── DeepSeek-V3.md │ │ └── README.md │ ├── glm-130b/ │ │ └── README.md │ ├── glm4.md │ ├── gpt/ │ │ └── README.md │ ├── gpt2/ │ │ ├── README.md │ │ ├── hf_modeling_gpt2.py │ │ └── 模型架构.md │ ├── gpt3/ │ │ └── README.md │ ├── llama/ │ │ ├── README.md │ │ └── 模型架构.md │ ├── llama.md │ ├── mixtral/ │ │ └── README.md │ ├── mlp.md │ ├── moe/ │ │ └── README.md │ ├── qwen/ │ │ ├── README.md │ │ └── 参数说明及函数说明.md │ ├── qwen2.md │ ├── t5/ │ │ └── README.md │ ├── transformer/ │ │ ├── README.md │ │ ├── Transformer中FFN的记忆功能.md │ │ └── 模型架构.md │ ├── transformer.md │ ├── 基本概念.md │ ├── 旋转编码RoPE.md │ ├── 模型架构类图.drawio │ └── 训练范式.md ├── llm-alignment/ │ ├── DPO.md │ ├── README.md │ ├── RLHF.md │ └── 基本概念.md ├── llm-application/ │ ├── Higress.md │ ├── README.md │ ├── agent/ │ │ ├── OpenClaw.md │ │ └── OpenCode/ │ │ └── README.md │ ├── embbedding-model.md │ ├── gradio/ │ │ └── README.md │ ├── langchain/ │ │ ├── README.md │ │ ├── serve.py │ │ └── tutorials/ │ │ ├── client.py │ │ └── serve.py │ ├── one-api.md │ ├── pre-post-handle/ │ │ └── README.md │ ├── rag/ │ │ ├── README.md │ │ ├── embedding.md │ │ ├── 存在的一些问题.md │ │ └── 方案.md │ ├── vector-db/ │ │ ├── README.md │ │ └── reference.md │ └── 应用场景.md ├── llm-compression/ │ ├── PaddleSlim/ │ │ ├── quantization.md │ │ └── README.md │ ├── README.md │ ├── distillation/ │ │ ├── GKD.md │ │ ├── MINILLM.md │ │ ├── README.md │ │ ├── SCOTT.md │ │ └── 大模型蒸馏概述.md │ ├── gptqmodel/ │ │ └── README.md │ ├── llm-compressor/ │ │ ├── README.md │ │ ├── source-code.md │ │ ├── 剪枝.md │ │ └── 量化方案.md │ ├── quantization/ │ │ ├── FP6-LLM.md │ │ ├── GPTQ.md │ │ ├── LLM-int8.md │ │ ├── PEQA.md │ │ ├── QQQ-W4A8.md │ │ ├── README.md │ │ ├── SmoothQuant.md │ │ ├── SpinQuant.md │ │ ├── ZeroQuant(4+2).md │ │ ├── ZeroQuant.md │ │ ├── fp4.md │ │ ├── fp6.md │ │ ├── fp8.md │ │ ├── kv-cache-quant.md │ │ ├── llm-qat/ │ │ │ ├── LLM-QAT.md │ │ │ ├── README.md │ │ │ ├── cfd70ff/ │ │ │ │ ├── README.md │ │ │ │ ├── generate_data.py │ │ │ │ ├── inference.py │ │ │ │ ├── merge_gen_data.py │ │ │ │ ├── pip.conf │ │ │ │ ├── run_train.sh │ │ │ │ ├── train.py │ │ │ │ └── utils.py │ │ │ ├── f4d873a/ │ │ │ │ ├── datautils.py │ │ │ │ ├── run_train.sh │ │ │ │ └── train.py │ │ │ └── log.md │ │ ├── moe模型量化.md │ │ ├── tools.md │ │ ├── 可视化/ │ │ │ ├── README.md │ │ │ ├── qwen_activate_visual.ipynb │ │ │ └── qwen_visual.ipynb │ │ ├── 大模型量化概述.md │ │ └── 量化基础.md │ ├── sparsity/ │ │ └── README.md │ ├── tools.md │ ├── 大模型压缩综述.md │ └── 经验.md ├── llm-data-engineering/ │ ├── README.md │ ├── dataset/ │ │ ├── README.md │ │ ├── baichuan2.md │ │ ├── chinese-corpus-all.md │ │ └── english-corpus-all.md │ ├── reference.md │ └── sft-dataset/ │ ├── baichuan2_test.py │ ├── evol-instruct.md │ ├── firefly-template.py │ ├── jinja-demo.py │ ├── jinja-llm-baichuan.py │ ├── jinja-llm-baichuan2.py │ ├── jinja-llm-bloom.py │ ├── jinja-llm-chatglm3.py │ ├── jinja-llm.py │ ├── jinja.md │ ├── 数据格式设计.md │ └── 数据集格式.md ├── llm-eval/ │ ├── EvalScope.md │ ├── README.md │ ├── eval-data/ │ │ ├── longtext_L115433-question.txt │ │ ├── longtext_L115433.txt │ │ ├── longtext_L32503_answer.txt │ │ ├── longtext_L32503_question.txt │ │ ├── longtext_L64031.txt │ │ └── longtext_L64031_question.txt │ ├── llm-performance/ │ │ ├── AI芯片性能.md │ │ ├── README.md │ │ ├── hardware-performance/ │ │ │ ├── gpu-monitor-ui.py │ │ │ └── pynvml-stat-memory.py │ │ ├── llmperf.md │ │ ├── mindie/ │ │ │ ├── lantency/ │ │ │ │ ├── README.md │ │ │ │ ├── perfermance-stat.py │ │ │ │ ├── performance-stream-baichuan2.py │ │ │ │ ├── performance-stream-chatglm3.py │ │ │ │ ├── performance-stream-qwen1.5.py │ │ │ │ ├── performance-stream-qwen1.py │ │ │ │ ├── performance-stream.py │ │ │ │ └── stat_input_token.py │ │ │ └── locust-lantency-throughput/ │ │ │ ├── README.md │ │ │ ├── hello.py │ │ │ ├── llm-910b4-baichuan2-7b-2tp.py │ │ │ ├── llm-910b4-chatglm3-6b-2tp.py │ │ │ ├── llm-910b4-qwen-72b-8tp.py │ │ │ ├── llm-910b4-qwen1.5-4tp.py │ │ │ ├── qwen1.5-72b-8tp.html │ │ │ └── 示例.py │ │ ├── perfetto.md │ │ ├── stat_gpu_memory.py │ │ ├── tgi-benchmark.md │ │ ├── vllm/ │ │ │ ├── README.md │ │ │ ├── vllm-locust-qwen1.5-7b-long.py │ │ │ └── vllm-performance-stream-qwen1.5-long.py │ │ ├── vllm-benchmark.md │ │ ├── wrk-性能测试工具.md │ │ ├── 大模型场景下训练和推理性能指标名词解释.md │ │ ├── 推理性能测试.md │ │ └── 训练性能测试.md │ ├── llm-precision/ │ │ ├── C-Eval.md │ │ ├── README.md │ │ └── 模型质量评估.md │ ├── opencompass.md │ └── 大模型测评集.md ├── llm-inference/ │ ├── DeepSpeed-Inference.md │ ├── Flash-Decoding.md │ ├── FlashInfer.md │ ├── FlexFlow-Serve.md │ ├── GuidedGeneration.md │ ├── KV-Cache优化.md │ ├── Mooncake.md │ ├── NanoFlow.md │ ├── PD分离.md │ ├── README.md │ ├── RTP-LLM.md │ ├── ascend/ │ │ └── mindformers/ │ │ ├── README.md │ │ ├── baichuan2/ │ │ │ ├── README.md │ │ │ ├── baichuan-inference.py │ │ │ └── baichuan-stat.py │ │ ├── chatglm3/ │ │ │ ├── README.md │ │ │ ├── chatglm-gen.py │ │ │ ├── chatglm-inference.py │ │ │ └── chatglm-stat.py │ │ ├── mindsporelite-inference.py │ │ ├── mindsporelite-stat.py │ │ └── text_generator_infer.py │ ├── chatgpt.md │ ├── deepspeed-mii/ │ │ └── README.md │ ├── faster-transformer/ │ │ ├── README.md │ │ ├── bloom/ │ │ │ ├── README.md │ │ │ └── firefly_lambada_1w_stat_token.py │ │ ├── gpt/ │ │ │ └── README.md │ │ ├── llama/ │ │ │ └── README.md │ │ └── megatron-gpt2/ │ │ ├── gpt_summarization.py │ │ ├── gpt_summarization_stat.py │ │ └── megatron-gpt2-fp8.md │ ├── flexflow-serve/ │ │ └── benchmark-batch1.py │ ├── huggingface-tgi/ │ │ └── README.md │ ├── huggingface-transformer/ │ │ └── README.md │ ├── lightllm/ │ │ └── README.md │ ├── lmdeploy/ │ │ ├── README.md │ │ ├── 功能.md │ │ └── 服务启动参数.md │ ├── native-model/ │ │ └── chatglm3-6b/ │ │ └── cli_demo.py │ ├── offload.md │ ├── openai.md │ ├── sglang/ │ │ ├── README.md │ │ ├── source-code.md │ │ ├── 服务器启动参数.md │ │ └── 项目代码结构.md │ ├── tensorrt/ │ │ ├── README.md │ │ └── install.md │ ├── tensorrt-llm/ │ │ ├── FP8.md │ │ ├── Memory Usage of TensorRT-LLM.md │ │ ├── README.md │ │ ├── TRT-LLM引擎构建参数.md │ │ ├── Triton服务启动参数.md │ │ └── 安装.md │ ├── triton/ │ │ ├── REAEME.md │ │ ├── onnx/ │ │ │ └── README.md │ │ └── resnet50/ │ │ ├── client.py │ │ ├── config.pbtxt │ │ ├── labels.txt │ │ └── resnet50_convert_torchscript.py │ ├── vllm/ │ │ ├── FAQ.md │ │ ├── FP8.md │ │ ├── README.md │ │ ├── REF.md │ │ ├── api_client.py │ │ ├── cmd.md │ │ ├── vllm.md │ │ ├── 服务启动参数.md │ │ ├── 源码.md │ │ ├── 请求处理流程.md │ │ └── 长文本推理.md │ ├── web/ │ │ ├── fastapi/ │ │ │ ├── README.md │ │ │ └── llm-qwen-mindspore-lite.py │ │ ├── flask/ │ │ │ ├── README.md │ │ │ └── llm-qwen-mindspore-lite.py │ │ └── sanic/ │ │ └── README.md │ ├── xinference/ │ │ └── README.md │ ├── 分离式推理架构.md │ ├── 大模型推理张量并行.md │ └── 解码策略.md ├── llm-interview/ │ ├── README.md │ ├── base.md │ ├── comprehensive.md │ ├── llm-algo.md │ ├── llm-app.md │ ├── llm-compress.md │ ├── llm-eval.md │ ├── llm-ft.md │ ├── llm-inference.md │ ├── llm-rlhf.md │ └── llm-train.md ├── llm-localization/ │ ├── README.md │ ├── ascend/ │ │ ├── FAQ.md │ │ ├── README.md │ │ ├── ascend-c/ │ │ │ └── README.md │ │ ├── ascend-infra/ │ │ │ ├── HCCL.md │ │ │ ├── MacOS环境.md │ │ │ ├── ascend-dmi.md │ │ │ ├── ascend-docker-runtime.md │ │ │ ├── ascend-docker.md │ │ │ ├── ascend-llm下载.md │ │ │ ├── ascend-npu-smi.md │ │ │ ├── docker环境升级cann.md │ │ │ ├── network.md │ │ │ ├── npu监控.md │ │ │ ├── 操作系统.md │ │ │ ├── 昇腾卡-soc版本.md │ │ │ ├── 昇腾卡注意事项.md │ │ │ ├── 昇腾镜像.md │ │ │ ├── 服务器配置.md │ │ │ ├── 环境安装.md │ │ │ └── 达芬奇架构.md │ │ ├── ascend910-env-install.md │ │ ├── fabric-insight/ │ │ │ └── README.md │ │ ├── firefly-ascend.md │ │ ├── mindformers/ │ │ │ ├── README.md │ │ │ ├── baichuan2/ │ │ │ │ ├── baichuan2训练.md │ │ │ │ ├── run_baichuan2_7b.yaml │ │ │ │ ├── run_baichuan2_7b_910b.yaml │ │ │ │ └── run_baichuan2_7b_lora_910b.yaml │ │ │ ├── chatglm/ │ │ │ │ ├── README.md │ │ │ │ ├── chat_glm.py │ │ │ │ ├── glm_6b.yaml │ │ │ │ ├── glm_6b_chat.yaml │ │ │ │ ├── merge_ckpt.py │ │ │ │ ├── merge_ckpt_lora.py │ │ │ │ ├── pt2ms.py │ │ │ │ ├── run_glm_6b_finetune.yaml │ │ │ │ ├── run_glm_6b_infer.yaml │ │ │ │ ├── run_glm_6b_lora.yaml │ │ │ │ └── run_glm_6b_lora_infer.yaml │ │ │ ├── env.md │ │ │ ├── llama/ │ │ │ │ └── README.md │ │ │ ├── qwen/ │ │ │ │ ├── qwen1训练.md │ │ │ │ ├── run_qwen_7b.yaml │ │ │ │ └── run_qwen_7b_910b.yaml │ │ │ ├── qwen1.5/ │ │ │ │ ├── qwen1.5训练.md │ │ │ │ ├── run_qwen1_5_7b_finetune.yaml │ │ │ │ └── run_qwen1_5_7b_infer.yaml │ │ │ ├── trick.md │ │ │ └── 权重格式转换.md │ │ ├── mindie/ │ │ │ ├── 2.0.RC2/ │ │ │ │ └── qwen.md │ │ │ ├── README.md │ │ │ ├── config/ │ │ │ │ ├── chatglm3-6b.json │ │ │ │ ├── qwen-72b.json │ │ │ │ └── run.sh │ │ │ ├── config-1.0.RC1.json │ │ │ ├── docker/ │ │ │ │ ├── README.md │ │ │ │ ├── TEST.md │ │ │ │ ├── baichuan2-13b.json │ │ │ │ ├── baichuan2-7b.json │ │ │ │ ├── deploy.sh │ │ │ │ ├── install_and_enable_cann.sh │ │ │ │ ├── llm-server.sh │ │ │ │ ├── mindie-1.0.Dockerfile │ │ │ │ ├── mindie-all-1.0.Dockerfile │ │ │ │ ├── mindie-env-1.0.Dockerfile │ │ │ │ ├── qwen-72b.json │ │ │ │ ├── qwen1.5-14b.json │ │ │ │ ├── qwen1.5-72b.json │ │ │ │ └── qwen1.5-7b.json │ │ │ ├── llm-server.sh │ │ │ ├── mindid-1.0-offical.md │ │ │ ├── mindid-performance.md │ │ │ ├── mindie-1.0.Dockerfile │ │ │ ├── mindie-1.0.RC2.md │ │ │ ├── mindie-1.0.md │ │ │ ├── mindie-1.0.rc2-config.json │ │ │ ├── mindie-1.0.rc2-llm-server.sh │ │ │ ├── mindie-2.0.rc2.md │ │ │ ├── mindie-20240411.md │ │ │ ├── mindie-api.md │ │ │ ├── model-test.md │ │ │ ├── script/ │ │ │ │ ├── model-test.py │ │ │ │ └── run.sh │ │ │ ├── 性能调优.md │ │ │ └── 日志分析.txt │ │ ├── mindspore/ │ │ │ ├── MindSpore-note.md │ │ │ ├── README.md │ │ │ ├── bert.md │ │ │ ├── reference.md │ │ │ └── 镜像.md │ │ ├── modellink/ │ │ │ ├── README.md │ │ │ ├── dataset.md │ │ │ ├── llm.md │ │ │ ├── qwen.md │ │ │ ├── 环境-20240521.md │ │ │ └── 环境安装.md │ │ ├── msmodelslim/ │ │ │ ├── README.md │ │ │ └── llm_quant/ │ │ │ ├── baichuan2-w8a8.py │ │ │ ├── calib_set.json │ │ │ └── qwen1.5-72b-w8a16.py │ │ ├── openmind/ │ │ │ └── README.md │ │ ├── peft/ │ │ │ ├── README.md │ │ │ └── finetune-lora.py │ │ ├── pytorch/ │ │ │ ├── README.md │ │ │ └── llm-lora.py │ │ ├── standford-alpaca/ │ │ │ ├── README.md │ │ │ ├── ds_config_zero2.json │ │ │ ├── ds_config_zero3.json │ │ │ ├── requirements.txt │ │ │ ├── train.py │ │ │ └── utils.py │ │ ├── transformers/ │ │ │ └── README.md │ │ ├── vllm-ascend/ │ │ │ └── README.md │ │ ├── 优质学习资料.md │ │ ├── 昇腾LLM支持概览.md │ │ └── 昇腾卡注意事项.md │ ├── modelscope/ │ │ └── README.md │ ├── paddle/ │ │ └── PaddleNLP.md │ └── tianshuzhixin/ │ ├── README.md │ └── ixsmi.md ├── llm-maas/ │ ├── OpenAI-ChatGPT.md │ └── README.md ├── llm-optimizer/ │ ├── FlashAttention.md │ ├── README.md │ ├── SplitFuse.md │ ├── kv-cache.md │ ├── xformers.md │ └── 计算通信重叠.md ├── llm-pipeline/ │ └── REAEMD.md ├── llm-tools/ │ ├── Pytorch-Profiler.md │ ├── README.md │ ├── base-profiler.py │ ├── nsight/ │ │ └── README.md │ ├── nsight.md │ ├── nvtx.md │ ├── profiler-recipe.py │ ├── tensorboard-profiler.py │ └── 可视化.md ├── llm-train/ │ ├── README.md │ ├── alpa/ │ │ └── train/ │ │ ├── pipeshard_parallelism.ipynb │ │ └── pipeshard_parallelism.py │ ├── alpaca/ │ │ ├── README.md │ │ ├── ds_config.json │ │ ├── ds_config_zero2.json │ │ ├── ds_config_zero2_ddp.json │ │ ├── inference.py │ │ ├── train.py │ │ └── train_ddp.py │ ├── alpaca-lora/ │ │ ├── README.md │ │ ├── export_hf_checkpoint.py │ │ ├── export_state_dict_checkpoint.py │ │ ├── finetune.py │ │ ├── finetune_metrics_epoch.py │ │ ├── generate.py │ │ └── inference.py │ ├── chatglm/ │ │ ├── README.md │ │ ├── deepspeed.json │ │ ├── ds_train_finetune.sh │ │ ├── evaluate.sh │ │ ├── evaluate_finetune.sh │ │ ├── inference.py │ │ ├── main.py │ │ ├── train.sh │ │ └── train_ptuningv2_dp.sh │ ├── chatglm-lora/ │ │ ├── README.md │ │ ├── finetune.py │ │ ├── finetune_ddp.py │ │ └── inference.py │ ├── chinese-llama-alpaca/ │ │ ├── README.md │ │ ├── inference_hf.py │ │ ├── merge_llama_with_chinese_lora.py │ │ ├── merge_tokenizers.py │ │ ├── run_clm_pt_with_peft.py │ │ ├── run_clm_sft_with_peft.py │ │ ├── run_pt.sh │ │ └── run_sft.sh │ ├── deepspeedchat/ │ │ ├── README.md │ │ ├── llama/ │ │ │ └── README.md │ │ └── training/ │ │ ├── step1_supervised_finetuning/ │ │ │ └── training_scripts/ │ │ │ └── single_node/ │ │ │ └── run_13b.sh │ │ ├── step2_reward_model_finetuning/ │ │ │ └── training_scripts/ │ │ │ └── single_node/ │ │ │ └── run_350m.sh │ │ ├── step3_rlhf_finetuning/ │ │ │ └── training_scripts/ │ │ │ └── single_node/ │ │ │ └── run_13b.sh │ │ └── utils/ │ │ └── data/ │ │ └── raw_datasets.py │ ├── firefly/ │ │ ├── README.md │ │ ├── bootstrap-s3.sh │ │ ├── bootstrap.sh │ │ ├── dockerfile.md │ │ └── test_bash_getopts.sh │ ├── fp8.md │ ├── galore/ │ │ └── torchrun_main.py │ ├── megatron/ │ │ ├── README.md │ │ ├── codegeex/ │ │ │ └── README.md │ │ ├── gpt2/ │ │ │ ├── README.md │ │ │ ├── data/ │ │ │ │ ├── cMinhash.cpp │ │ │ │ ├── download.py │ │ │ │ ├── file_utils.py │ │ │ │ └── merge_data.py │ │ │ ├── gpt-data-preprocess.md │ │ │ ├── merge_ck_and_inference/ │ │ │ │ ├── README.md │ │ │ │ ├── checkpoint_loader_megatron.py │ │ │ │ ├── checkpoint_saver_megatron.py │ │ │ │ ├── checkpoint_util.py │ │ │ │ ├── eval_gpt2_lambada.sh │ │ │ │ ├── run_text_generation_server.py │ │ │ │ ├── run_text_generation_server_345M.sh │ │ │ │ ├── run_text_generation_server_345M_2tp_2dp.sh │ │ │ │ ├── run_text_generation_server_345M_4_tensor_parallel.sh │ │ │ │ └── text_generation_cli.py │ │ │ ├── model_merge_eval_inference.md │ │ │ ├── model_train.md │ │ │ ├── requirements.txt │ │ │ └── train/ │ │ │ ├── pretrain_gpt.sh │ │ │ ├── pretrain_gpt_distributed.sh │ │ │ ├── pretrain_gpt_distributed_with_4pp.sh │ │ │ ├── pretrain_gpt_distributed_with_4tp.sh │ │ │ └── pretrain_gpt_distributed_with_mp.sh │ │ ├── megatron.drawio │ │ ├── pretrain.xmind │ │ ├── project.md │ │ └── source-code.md │ ├── megatron-deepspeed/ │ │ ├── README.md │ │ ├── bigscience/ │ │ │ └── bloom-note.md │ │ ├── bloom-megatron-deepspeed.md │ │ ├── microsoft/ │ │ │ ├── H800多机多卡训练坑点.md │ │ │ ├── README.md │ │ │ ├── llama-note.md │ │ │ ├── pip.conf │ │ │ ├── pretrain_llama2_13b_distributed_fp16.sh │ │ │ ├── pretrain_llama2_distributed.sh │ │ │ ├── pretrain_llama_13b_distributed_fp16.sh │ │ │ ├── pretrain_llama_7b_distributed_fp16.sh │ │ │ ├── pretrain_llama_distributed_fp16.sh │ │ │ ├── slurm/ │ │ │ │ ├── README.md │ │ │ │ ├── llama-multinode-ib.sh │ │ │ │ ├── megatron-deepspeed-multinode-ib-part2-30b-fp16.slurm │ │ │ │ └── megatron-deepspeed-multinode-ib-part2-65b-fp16.slurm │ │ │ ├── 代码.md │ │ │ ├── 环境准备.md │ │ │ ├── 训练日志分析.md │ │ │ └── 项目结构-202312228.md │ │ └── source-code.md │ ├── paddle/ │ │ ├── README.md │ │ └── paddlenlp/ │ │ ├── README.md │ │ ├── baichuan2/ │ │ │ └── README.md │ │ └── bloom/ │ │ ├── README.md │ │ └── sft_argument.json │ ├── peft/ │ │ ├── LoRA-QLoRA.md │ │ ├── PEFT-API.md │ │ ├── Prefix-Tuning.md │ │ ├── Prompt-Tuning.md │ │ ├── README.md │ │ ├── clm/ │ │ │ ├── accelerate_ds_zero3_cpu_offload_config.yaml │ │ │ ├── peft_ia3_clm.ipynb │ │ │ ├── peft_lora_clm.ipynb │ │ │ ├── peft_lora_clm_accelerate_ds_zero3_offload.py │ │ │ ├── peft_p_tuning_clm.ipynb │ │ │ ├── peft_p_tuning_lstm_clm.ipynb │ │ │ ├── peft_p_tuning_v2_clm.ipynb │ │ │ ├── peft_prefix_tuning_clm.ipynb │ │ │ └── peft_prompt_tuning_clm.ipynb │ │ ├── conditional_generation/ │ │ │ └── README.md │ │ └── multimodal/ │ │ ├── blip2_lora_inference.py │ │ ├── blip2_lora_int8_fine_tune.py │ │ └── finetune_bloom_bnb_peft.ipynb │ ├── pytorch/ │ │ ├── Pytorch源码解读.md │ │ ├── README.md │ │ ├── api.md │ │ ├── distribution/ │ │ │ ├── README.md │ │ │ ├── api.md │ │ │ ├── data-parallel/ │ │ │ │ ├── README.md │ │ │ │ ├── ddp_launch.py │ │ │ │ ├── ddp_main.py │ │ │ │ ├── elastic_ddp.py │ │ │ │ ├── minGPT-ddp/ │ │ │ │ │ ├── README.md │ │ │ │ │ ├── multinode.sh │ │ │ │ │ ├── sbatch_run.sh │ │ │ │ │ ├── sbatch_run_sig.sh │ │ │ │ │ └── sbatch_run_sig_opt.sh │ │ │ │ ├── sbatch_run.sh │ │ │ │ └── 使用DDP训练真实世界的模型.md │ │ │ ├── pipeline-parallel/ │ │ │ │ ├── 1-流水线.md │ │ │ │ ├── 2-使用torchtext训练transformer模型.md │ │ │ │ ├── 3-使用流水线并行训练Transformer模型.md │ │ │ │ ├── 4-使用DDP与流水线并行训练Transformer模型.md │ │ │ │ ├── README.md │ │ │ │ ├── ddp_pipeline.py │ │ │ │ ├── pipeline_tutorial.ipynb │ │ │ │ └── transformer_tutorial.ipynb │ │ │ ├── rpc/ │ │ │ │ └── README.md │ │ │ ├── sequence-parallelism/ │ │ │ │ └── README.md │ │ │ ├── tensor-parallel/ │ │ │ │ ├── 2d_parallel_example.py │ │ │ │ ├── README.md │ │ │ │ ├── sequence_parallel_example.py │ │ │ │ ├── tensor_parallel_example.py │ │ │ │ └── utils.py │ │ │ ├── torchrun.md │ │ │ ├── 分布式通信包.md │ │ │ ├── 多机多卡.md │ │ │ └── 多机训练.md │ │ ├── resource.md │ │ └── torchrun.md │ ├── qlora/ │ │ ├── README.md │ │ ├── accuracy.py │ │ ├── export_hf_checkpoint.py │ │ ├── inference.py │ │ ├── inference_merge.py │ │ ├── inference_qlora.py │ │ └── qlora.py │ ├── slurm/ │ │ ├── README.md │ │ ├── deepspeed/ │ │ │ ├── pp-multinode-machine.slurm │ │ │ ├── pp-multinode-singularity.slurm │ │ │ ├── pp-mutinode-singularity-pmix.slurm │ │ │ ├── pp-standalone-singularity-v2.slurm │ │ │ └── pp-standalone-singularity.slurm │ │ ├── megatron-deepspeed/ │ │ │ └── megatron-deepspeed-multinode-ib-part2-65b-fp16.slurm │ │ └── pytorch/ │ │ ├── alpaca-docker.slurm │ │ ├── alpaca-machine.slurm │ │ ├── alpaca-singularity.slurm │ │ ├── mingpt-singularity-multinode-2.slurm │ │ └── mingpt-singularity-multinode.slurm │ └── vicuna/ │ └── README.md ├── llmops/ │ ├── FAQ.md │ ├── README.md │ ├── kubernetes.md │ ├── tq-llm/ │ │ └── train/ │ │ ├── FAQ.md │ │ ├── README.md │ │ ├── bootstrap-llm-zero3-offload.sh │ │ ├── bootstrap-llm.sh │ │ ├── bootstrap-llm2.sh │ │ ├── zero2-offload.json │ │ └── zero3-offload.json │ ├── 使用docker进行多机多卡训练.md │ ├── 千帆大模型平台.md │ └── 模型推理平台方案.md ├── mkdir-dir-file.sh ├── paper/ │ ├── A Survey on Efficient Training of Transformers.md │ ├── LESS-选择有影响力的数据进行目标指令精调.md │ ├── LLM增强LLMS.md │ ├── PagedAttention.md │ ├── README.md │ ├── data/ │ │ ├── LESS 实践:仅用少量的数据完成目标指令微调.md │ │ ├── LESS-选择有影响力的数据进行目标指令精调.md │ │ └── LESS.md │ ├── inference/ │ │ ├── llm-in-a-flash.md │ │ ├── orca.md │ │ └── 迈向高效的生成式大语言模型服务综述-从算法到系统.md │ ├── llm对齐综述.md │ ├── moe/ │ │ └── README.md │ ├── parameter-pruning/ │ │ ├── LLM-Pruner.md │ │ ├── SparseGPT.md │ │ ├── Wanda.md │ │ └── 公式.md │ └── training/ │ ├── A Survey on Efficient Training of Transformers.md │ ├── GaLore.md │ └── Reducing Activation Recomputation in Large Transformer Models.md └── template/ └── server.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ cover/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder .pybuilder/ target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv # For a library or package, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: # .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # poetry # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. # This is especially recommended for binary packages to ensure reproducibility, and is more # commonly ignored for libraries. # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control #poetry.lock # pdm # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. #pdm.lock # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it # in version control. # https://pdm.fming.dev/#use-with-ide .pdm.toml # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # pytype static type analyzer .pytype/ # Cython debug symbols cython_debug/ # PyCharm # JetBrains specific template is maintained in a separate JetBrains.gitignore that can # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================

## 目录 - :snail: [LLM训练](#llm训练) - 🐫 [LLM训练实战](#llm训练实战) - 🐼 [LLM参数高效微调技术原理](#llm微调技术原理) - 🐰 [LLM参数高效微调技术实战](#llm微调实战) - 🐘 [LLM分布式训练并行技术](#llm分布式训练并行技术) - 🌋 [分布式AI框架](#分布式ai框架) - 📡 [分布式训练网络通信](#分布式训练网络通信) - :herb: [LLM训练优化技术](#llm训练优化技术) - :hourglass: [LLM对齐技术](#llm对齐技术) - 🐎 [LLM推理](#llm推理) - 🚀 [LLM推理框架](#llm推理框架) - ✈️ [LLM推理优化技术](#llm推理优化技术) - ♻️ [LLM压缩](#llm压缩) - 📐 [LLM量化](#llm量化) - 🔰 [LLM剪枝](#llm剪枝) - 💹 [LLM知识蒸馏](#llm知识蒸馏) - ♑️ [低秩分解](#低秩分解) - :herb: [LLM测评](#llm测评) - 🔯 [LLM效果评测](#llm效果评测) - 🔘 [LLM推理性能压测](#llm推理性能压测) - :palm_tree: [LLM数据工程](#llm数据工程) - :dolphin: [LLM微调高效数据筛选技术](#llm微调高效数据筛选技术) - :cyclone: [提示工程](#提示工程) - ♍️ [LLM算法架构](#llm算法架构) - :jigsaw: [LLM应用开发](#llm应用开发) - 🀄️ [LLM国产化适配](#llm国产化适配) - 🔯 [AI编译器](#ai编译器) - 🔘 [AI基础设施](#ai基础设施) - :maple_leaf: [AI加速卡](#ai加速卡) - :octocat: [AI集群网络通信](#ai集群网络通信) - 💟 [LLMOps](#llmops) - 🍄 [LLM生态相关技术](#llm生态相关技术) - 💹 [LLM性能分析](#llm性能分析) - :dizzy: [LLM面试题](#llm面试题) - 🔨 [服务器基础环境安装及常用工具](#服务器基础环境安装及常用工具) - 💬 [LLM学习交流群](#llm学习交流群) - 👥 [微信公众号](#微信公众号) - ⭐️ [Star History](#star-history) - :link: [AI工程化课程推荐](#ai工程化课程推荐) ## 大模型实验室Lab4AI普惠算力 **基于大模型实验室的GPU算力实践** | 主题 | 实践 | 博客/视频 | |:------------ |:-----------------------------:|:--------:| | 基于ComfyUI调用Flux文生图模型生成动漫风格图像 | [链接](https://www.lab4ai.cn/project/detail?utm_source=guodong&id=f82ca14acda040ba8a3412feb541ba29&type=project) | [链接](https://mp.weixin.qq.com/s/OEDQO-IkT4uo_HMjBXGuCA) | | 告别传统客服:三步骤,LLaMA-Factory零代码打造会订票的专属大模型 | [链接](https://www.lab4ai.cn/project/detail?utm_source=guodong&id=a78043adcef84cd998516e1bcd39562f&type=project) | [链接](https://mp.weixin.qq.com/s/N_CQEBEjN0E31x4Vg31rEQ) | | 打造基于多模态AI的苏东坡数字人 | [链接](https://www.lab4ai.cn/project/detail?utm_source=guodong&id=1f1097f45ea64abca3359e4c0615720a&type=project) | - | | WeClone:从聊天记录创造数字分身的一站式解决方案 | [链接](https://www.lab4ai.cn/project/detail?utm_source=guodong&id=ab83d14684fa45d197f67eddb3d8316c&type=project) | [链接](https://mp.weixin.qq.com/s/2pOD8YexWtmuPhV4C7uKJA) | | LightX2V 4步蒸馏模型:20倍速的高质量视频生成革命 | [链接](https://www.lab4ai.cn/project/detail?utm_source=guodong&id=d5556b93078d4defbb58c9f722b674df&type=project) | [链接](https://mp.weixin.qq.com/s/kVz1dwthn3nOLT0jTeiQgg) | | 基于Qwen3-8B的沉浸式苏东坡角色扮演大模型 | [链接](https://www.lab4ai.cn/project/detail?utm_source=guodong&id=315457fba1b3432c935865d1c5aa1ffe&type=project) | [链接](https://mp.weixin.qq.com/s/bCCHa2RsKieJZizORU19dQ) | | LightLLM轻量化部署新范式,打造高性能法律智能体 | [链接](https://www.lab4ai.cn/project/detail?utm_source=guodong&id=b417085ae8cd4dd0bef7161c3d583b15&type=project) | [链接](https://mp.weixin.qq.com/s/j8rJyoBA02ypPEkxb9XSVg) | | RoboMIND——机器人多形态通用智能评测基准 | [链接](https://www.lab4ai.cn/project/detail?utm_source=guodong&id=492a471cd6054a179660c760f0026704&type=project) | [链接](https://mp.weixin.qq.com/s/i_QPGuqaXfql6cPELxlUVg) | | 经典论文复现:《Attention Is All You Need》 | [链接](https://www.lab4ai.cn/paper/detail?utm_source=guodong&id=e90aa38fdff9420e8902bc71909fa005&type=paper) | [链接](https://www.bilibili.com/video/BV1Fvp3zBEAN/?spm_id_from=333.1387.homepage.video_card.click) | | 经典论文复现:《SELF-INSTRUCT: Aligning Language Models
with Self-Generated Instructions》| [链接](https://www.lab4ai.cn/paper/detail?utm_source=guodong&id=2bbf2f4971f74c6e8def26879233f2fe&type=paper) | - | **GPU算力优惠活动** - 资源不够用,来 Lab4AI 享 H800 GPU,用 H800 比 4090 还划算: [详情](https://mp.weixin.qq.com/s/61OtlvP3N4vl0D67eCzSWA) **算力福利** - 大模型实验室Lab4AI:[免费领取50元GPU算力](https://www.lab4ai.cn/register?agentID=user-PqCML6LJZO) - 大模型实验室群:[点击加入](https://github.com/liguodongiot/liguodongiot/tree/main/images/lab4ai.png) **AI训练营** - AI应用开发工程师技能 & 春招面试训练营:[点击加入](https://www.lab4ai.cn/course/detail?utm_source=guodong&id=2b86361ed6a54611850c073defe04327) - 斯坦福CS336 从零手搓大语言模型实战:[点击加入](https://www.lab4ai.cn/course/detail?utm_source=guodong&id=49325466ca58436782b65a887883805f) - 7天AI智能体全栈开发实战集训营:[点击加入](https://www.lab4ai.cn/course/detail?utm_source=guodong&id=f3fba5d60b2542bf8783e59dcc24d836) ## LLM训练 ### LLM训练实战 下面汇总了我在大模型实践中训练相关的所有教程。从6B到65B,从全量微调到高效微调(LoRA,QLoRA,P-Tuning v2),再到RLHF(基于人工反馈的强化学习)。 | LLM | 预训练/SFT/RLHF... | 参数 | 教程 | 代码 | | --------------------------- | ----------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- | | Alpaca | full fine-turning | 7B | [从0到1复现斯坦福羊驼(Stanford Alpaca 7B)](https://zhuanlan.zhihu.com/p/618321077) | [配套代码](https://github.com/liguodongiot/llm-action/tree/main/llm-train/alpaca) | | Alpaca(LLaMA) | LoRA | 7B~65B | 1.[足够惊艳,使用Alpaca-Lora基于LLaMA(7B)二十分钟完成微调,效果比肩斯坦福羊驼](https://zhuanlan.zhihu.com/p/619426866)
2. [使用 LoRA 技术对 LLaMA 65B 大模型进行微调及推理](https://zhuanlan.zhihu.com/p/632492604) | [配套代码](https://github.com/liguodongiot/llm-action/tree/main/llm-train/alpaca-lora) | | BELLE(LLaMA/Bloom) | full fine-turning | 7B | 1.[基于LLaMA-7B/Bloomz-7B1-mt复现开源中文对话大模型BELLE及GPTQ量化](https://zhuanlan.zhihu.com/p/618876472)
2. [BELLE(LLaMA-7B/Bloomz-7B1-mt)大模型使用GPTQ量化后推理性能测试](https://zhuanlan.zhihu.com/p/621128368) | N/A | | ChatGLM | LoRA | 6B | [从0到1基于ChatGLM-6B使用LoRA进行参数高效微调](https://zhuanlan.zhihu.com/p/621793987) | [配套代码](https://github.com/liguodongiot/llm-action/tree/main/llm-train/chatglm-lora) | | ChatGLM | full fine-turning/P-Tuning v2 | 6B | [使用DeepSpeed/P-Tuning v2对ChatGLM-6B进行微调](https://zhuanlan.zhihu.com/p/622351059) | [配套代码](https://github.com/liguodongiot/llm-action/tree/main/llm-train/chatglm) | | Vicuna(LLaMA) | full fine-turning | 7B | [大模型也内卷,Vicuna训练及推理指南,效果碾压斯坦福羊驼](https://zhuanlan.zhihu.com/p/624012908) | N/A | | OPT | RLHF | 0.1B~66B | 1.[一键式 RLHF 训练 DeepSpeed Chat(一):理论篇](https://zhuanlan.zhihu.com/p/626159553) 
2. [一键式 RLHF 训练 DeepSpeed Chat(二):实践篇](https://zhuanlan.zhihu.com/p/626214655) | [配套代码](https://github.com/liguodongiot/llm-action/tree/main/llm-train/deepspeedchat) | | MiniGPT-4(LLaMA) | full fine-turning | 7B | [大杀器,多模态大模型MiniGPT-4入坑指南](https://zhuanlan.zhihu.com/p/627671257) | N/A | | Chinese-LLaMA-Alpaca(LLaMA) | LoRA(预训练+微调) | 7B | [中文LLaMA&Alpaca大语言模型词表扩充+预训练+指令精调](https://zhuanlan.zhihu.com/p/631360711) | [配套代码](https://github.com/liguodongiot/llm-action/tree/main/llm-train/chinese-llama-alpaca) | | LLaMA | QLoRA | 7B/65B | [高效微调技术QLoRA实战,基于LLaMA-65B微调仅需48G显存,真香](https://zhuanlan.zhihu.com/p/636644164) | [配套代码](https://github.com/liguodongiot/llm-action/tree/main/llm-train/qlora) | | LLaMA | GaLore | 60M/7B | [突破内存瓶颈,使用 GaLore 一张4090消费级显卡也能预训练LLaMA-7B](https://zhuanlan.zhihu.com/p/686686751) | [配套代码](https://github.com/liguodongiot/llm-action/blob/main/llm-train/galore/torchrun_main.py) | **[⬆ 一键返回目录](#目录)** ### LLM微调技术原理 对于普通大众来说,进行大模型的预训练或者全量微调遥不可及。由此,催生了各种参数高效微调技术,让科研人员或者普通开发者有机会尝试微调大模型。 因此,该技术值得我们进行深入分析其背后的机理,本系列大体分七篇文章进行讲解。 ![peft方法](./pic/llm/train/sft/peft方法.jpg) - [大模型参数高效微调技术原理综述(一)-背景、参数高效微调简介](https://zhuanlan.zhihu.com/p/635152813) - [大模型参数高效微调技术原理综述(二)-BitFit、Prefix Tuning、Prompt Tuning](https://zhuanlan.zhihu.com/p/635686756) - [大模型参数高效微调技术原理综述(三)-P-Tuning、P-Tuning v2](https://zhuanlan.zhihu.com/p/635848732) - [大模型参数高效微调技术原理综述(四)-Adapter Tuning及其变体](https://zhuanlan.zhihu.com/p/636038478) - [大模型参数高效微调技术原理综述(五)-LoRA、AdaLoRA、QLoRA](https://zhuanlan.zhihu.com/p/636215898) - [大模型参数高效微调技术原理综述(六)-MAM Adapter、UniPELT](https://zhuanlan.zhihu.com/p/636362246) - [大模型参数高效微调技术原理综述(七)-最佳实践、总结](https://zhuanlan.zhihu.com/p/649755252) ### LLM微调实战 下面给大家分享**大模型参数高效微调技术实战**,该系列主要针对 HuggingFace PEFT 框架支持的一些高效微调技术进行讲解。 | 教程 | 代码 | 框架 | | ------------- | --------------- | --------------- | | [大模型参数高效微调技术实战(一)-PEFT概述及环境搭建](https://zhuanlan.zhihu.com/p/651744834) | N/A | HuggingFace PEFT | | [大模型参数高效微调技术实战(二)-Prompt Tuning](https://zhuanlan.zhihu.com/p/646748939) | [配套代码](https://github.com/liguodongiot/llm-action/blob/main/llm-train/peft/clm/peft_prompt_tuning_clm.ipynb) | HuggingFace PEFT | | [大模型参数高效微调技术实战(三)-P-Tuning](https://zhuanlan.zhihu.com/p/646876256) | [配套代码](https://github.com/liguodongiot/llm-action/blob/main/llm-train/peft/clm/peft_p_tuning_clm.ipynb) | HuggingFace PEFT | | [大模型参数高效微调技术实战(四)-Prefix Tuning / P-Tuning v2](https://zhuanlan.zhihu.com/p/648156780) | [配套代码](https://github.com/liguodongiot/llm-action/blob/main/llm-train/peft/clm/peft_p_tuning_v2_clm.ipynb) | HuggingFace PEFT | | [大模型参数高效微调技术实战(五)-LoRA](https://zhuanlan.zhihu.com/p/649315197) | [配套代码](https://github.com/liguodongiot/llm-action/blob/main/llm-train/peft/clm/peft_lora_clm.ipynb) | HuggingFace PEFT | | [大模型参数高效微调技术实战(六)-IA3](https://zhuanlan.zhihu.com/p/649707359) | [配套代码](https://github.com/liguodongiot/llm-action/blob/main/llm-train/peft/clm/peft_ia3_clm.ipynb) | HuggingFace PEFT | | [大模型微调实战(七)-基于LoRA微调多模态大模型](https://zhuanlan.zhihu.com/p/670048482) | [配套代码](https://github.com/liguodongiot/llm-action/blob/main/llm-train/peft/multimodal/blip2_lora_int8_fine_tune.py) | HuggingFace PEFT | | [大模型微调实战(八)-使用INT8/FP4/NF4微调大模型](https://zhuanlan.zhihu.com/p/670116171) | [配套代码](https://github.com/liguodongiot/llm-action/blob/main/llm-train/peft/multimodal/finetune_bloom_bnb_peft.ipynb) | PEFT、bitsandbytes | **[⬆ 一键返回目录](#目录)** ### [LLM分布式训练并行技术](https://github.com/liguodongiot/llm-action/tree/main/docs/llm-base/distribution-parallelism) 近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,传统的单机单卡模式已经无法满足超大模型进行训练的要求。因此,我们需要基于单机多卡、甚至是多机多卡进行分布式大模型的训练。 而利用AI集群,使深度学习算法更好地从大量数据中高效地训练出性能优良的大模型是分布式机器学习的首要目标。为了实现该目标,一般需要根据硬件资源与数据/模型规模的匹配情况,考虑对计算任务、训练数据和模型进行划分,从而进行分布式训练。因此,分布式训练相关技术值得我们进行深入分析其背后的机理。 下面主要对大模型进行分布式训练的并行技术进行讲解,本系列大体分九篇文章进行讲解。 - [大模型分布式训练并行技术(一)-概述](https://zhuanlan.zhihu.com/p/598714869) - [大模型分布式训练并行技术(二)-数据并行](https://zhuanlan.zhihu.com/p/650002268) - [大模型分布式训练并行技术(三)-流水线并行](https://zhuanlan.zhihu.com/p/653860567) - [大模型分布式训练并行技术(四)-张量并行](https://zhuanlan.zhihu.com/p/657921100) - [大模型分布式训练并行技术(五)-序列并行](https://zhuanlan.zhihu.com/p/659792351) - [大模型分布式训练并行技术(六)-多维混合并行](https://zhuanlan.zhihu.com/p/661279318) - [大模型分布式训练并行技术(七)-自动并行](https://zhuanlan.zhihu.com/p/662517647) - [大模型分布式训练并行技术(八)-MOE并行](https://zhuanlan.zhihu.com/p/662518387) - [大模型分布式训练并行技术(九)-总结](https://zhuanlan.zhihu.com/p/667051845) **[⬆ 一键返回目录](#目录)** ### 分布式AI框架 - [PyTorch](https://github.com/liguodongiot/llm-action/tree/main/train/pytorch/) - PyTorch 单机多卡训练 - PyTorch 多机多卡训练 - [Megatron-LM](https://github.com/liguodongiot/llm-action/tree/main/train/megatron) - Megatron-LM 单机多卡训练 - Megatron-LM 多机多卡训练 - [基于Megatron-LM从0到1完成GPT2模型预训练、模型评估及推理](https://juejin.cn/post/7259682893648724029) - [DeepSpeed](https://github.com/liguodongiot/llm-action/tree/main/train/deepspeed) - DeepSpeed 单机多卡训练 - DeepSpeed 多机多卡训练 - [Megatron-DeepSpeed](https://github.com/liguodongiot/llm-action/tree/main/train/megatron-deepspeed) - 基于 Megatron-DeepSpeed 从 0 到1 完成 LLaMA 预训练 - 基于 Megatron-DeepSpeed 从 0 到1 完成 Bloom 预训练 ### 分布式训练网络通信 待更新... ### LLM训练优化技术 - FlashAttention V1、V2 - 混合精度训练 - 重计算 - MQA / GQA - 梯度累积 ### LLM对齐技术 - PPO(近端策略优化) - DPO - ORPO **[⬆ 一键返回目录](#目录)** ## [LLM推理](https://github.com/liguodongiot/llm-action/tree/main/inference) ### 推理引擎 - [大模型推理框架概述](https://www.zhihu.com/question/625415776/answer/3243562246) - [大模型的好伙伴,浅析推理加速引擎FasterTransformer](https://zhuanlan.zhihu.com/p/626008090) - [TensorRT-LLM保姆级教程(一)-快速入门](https://zhuanlan.zhihu.com/p/666849728) - [TensorRT-LLM保姆级教程(二)-离线环境搭建、模型量化及推理](https://zhuanlan.zhihu.com/p/667572720) - [TensorRT-LLM保姆级教程(三)-使用Triton推理服务框架部署模型](https://juejin.cn/post/7398122968200593419) - [一文搞懂大模型生成文本的解码策略](https://zhuanlan.zhihu.com/p/1921914053485376792) - [谈谈LLM生成文本的惩罚参数](https://zhuanlan.zhihu.com/p/1965476299419132173) - [LLM 确定性推理](https://zhuanlan.zhihu.com/p/1961192621759242664) 迷你LLM推理引擎(非常适合源码学习): - [Nano-vLLM源码注释](https://github.com/liguodongiot/nano-vllm):从头开始构建的轻量级 vLLM 实现。 - [Mini-SGLang](https://github.com/liguodongiot/mini-sglang):一个轻量但高性能的大型语言模型推理框架,SGLang 的紧凑实现。 生产级LLM推理引擎: - [vLLM](https://github.com/vllm-project/vllm) - [SGLang](https://github.com/sgl-project/sglang) 其他推理引擎: - [LMDeploy](https://github.com/InternLM/lmdeploy) - [LightLLM](https://github.com/ModelTC/lightllm):纯Python开发的大语言模型推理和服务框架 - [MNN-LLM](https://github.com/alibaba/MNN):基于MNN引擎开发的大型语言模型运行时解决方案 - [赤兔](https://github.com/thu-pacman/chitu) - [mllm](https://github.com/UbiquitousLearning/mllm):端侧多模态LLM推理引擎 ### 推理服务 - [模型推理服务工具综述](https://zhuanlan.zhihu.com/p/721395381) - [模型推理服务化框架Triton保姆式教程(一):快速入门](https://zhuanlan.zhihu.com/p/629336492) - [模型推理服务化框架Triton保姆式教程(二):架构解析](https://zhuanlan.zhihu.com/p/634143650) - [模型推理服务化框架Triton保姆式教程(三):开发实践](https://zhuanlan.zhihu.com/p/634444666) ### LLM推理优化技术 - [LLM推理优化技术-概述]() - [大模型推理优化技术-KV Cache](https://www.zhihu.com/question/653658936/answer/3569365986) - [大模型推理服务调度优化技术-Continuous batching](https://zhuanlan.zhihu.com/p/719610083) - [大模型低显存推理优化-Offload技术](https://juejin.cn/post/7405158045628596224) - [大模型推理优化技术-KV Cache量化](https://juejin.cn/post/7420231738558627874) - [大模型推理优化技术-张量并行]() - [大模型推理服务调度优化技术-Chunked Prefill]() - [大模型推理优化技术-KV Cache优化方法综述]() - 大模型吞吐优化技术-多LoRA推理服务 - 大模型推理服务调度优化技术-公平性调度 - 大模型访存优化技术-FlashAttention - 大模型显存优化技术-PagedAttention - 大模型解码优化-Speculative Decoding及其变体 - 大模型推理优化-结构化文本生成 - Flash Decoding - FlashDecoding++ ## LLM压缩 近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,从而导致模型变得越来越大,因此,我们需要一些大模型压缩技术来降低模型部署的成本,并提升模型的推理性能。 模型压缩主要分为如下几类: - 模型剪枝(Pruning) - 知识蒸馏(Knowledge Distillation) - 模型量化(Quantization) - 低秩分解(Low-Rank Factorization) ### [LLM量化](https://github.com/liguodongiot/llm-action/tree/main/model-compression/quantization) 本系列将针对一些常见大模型量化方案(GPTQ、LLM.int8()、SmoothQuant、AWQ等)进行讲述。 - [大模型量化概述](https://www.zhihu.com/question/627484732/answer/3261671478) - 量化感知训练: - [大模型量化感知训练技术原理:LLM-QAT](https://zhuanlan.zhihu.com/p/647589650) - [大模型量化感知微调技术原理:QLoRA]() - PEQA - 训练后量化: - [大模型量化技术原理:GPTQ、LLM.int8()](https://zhuanlan.zhihu.com/p/680212402) - [大模型量化技术原理:SmoothQuant](https://www.zhihu.com/question/576376372/answer/3388402085) - [大模型量化技术原理:AWQ、AutoAWQ](https://zhuanlan.zhihu.com/p/681578090) - [大模型量化技术原理:SpQR](https://zhuanlan.zhihu.com/p/682871823) - [大模型量化技术原理:ZeroQuant系列](https://zhuanlan.zhihu.com/p/683813769) - [大模型量化技术原理:FP8](https://www.zhihu.com/question/658712811/answer/3596678896) - [大模型量化技术原理:FP6](https://juejin.cn/post/7412893752090853386) - [大模型量化技术原理:KIVI、IntactKV、KVQuant](https://juejin.cn/post/7420231738558627874) - [大模型量化技术原理:Atom、QuaRot](https://juejin.cn/post/7424334647570513972) - [大模型量化技术原理:QoQ量化及QServe推理服务系统](https://zhuanlan.zhihu.com/p/8047106486) - 大模型量化技术原理:QuIP、QuIP#、OmniQuant - [大模型量化技术原理:FP4]() - [大模型量化技术原理:总结](https://zhuanlan.zhihu.com/p/11886909512) ### LLM稀疏化 - [万字长文谈深度神经网络剪枝综述](https://zhuanlan.zhihu.com/p/692858636?) 目前,大多数针对大模型模型的压缩技术都专注于模型量化领域,即降低单个权重的数值表示的精度。另一种模型压缩方法模型剪枝的研究相对较少,即删除网络元素,包括从单个权重(非结构化剪枝)到更高粒度的组件,如权重矩阵的整行/列(结构化剪枝)。 本系列将针对一些常见大模型稀疏化方案(LLM-Pruner、SliceGPT、SparseGPT、Wanda等)进行讲述。 - [大模型稀疏化技术原理:概述](https://www.zhihu.com/question/652126515/answer/3457652467) - [大模型稀疏化技术原理:Double Sparsity](https://zhuanlan.zhihu.com/p/1912877769827783344) - 大模型稀疏化技术原理:LLM-Pruner、SliceGPT - 大模型稀疏化技术原理:SparseGPT、Wanda - 大模型稀疏化技术原理:总结 **结构化剪枝**: - LLM-Pruner(LLM-Pruner: On the Structural Pruning of Large Language Models) - LLM-Shearing(Sheared LLaMA: Accelerating Language Model Pre-training via Structured Pruning) - SliceGPT: Compress Large Language Models by Deleting Rows and Columns - LoSparse **非结构化剪枝**: - SparseGPT(SparseGPT: Massive Language Models Can be Accurately Pruned in One-Shot) - LoRAPrune(LoRAPrune: Pruning Meets Low-Rank Parameter-Efficient Fine-Tuning) - Wanda(A Simple and Effective Pruning Approach for Large Language Models) - Flash-LLM(Flash-LLM: Enabling Cost-Effective and Highly-Efficient Large Generative Model Inference with Unstructured Sparsity) ### LLM知识蒸馏 - [大模型知识蒸馏概述](https://www.zhihu.com/question/625415893/answer/3243565375) **Standard KD**: 使学生模型学习教师模型(LLM)所拥有的常见知识,如输出分布和特征信息,这种方法类似于传统的KD。 - MINILLM - GKD **EA-based KD**: 不仅仅是将LLM的常见知识转移到学生模型中,还涵盖了蒸馏它们独特的涌现能力。具体来说,EA-based KD又分为了上下文学习(ICL)、思维链(CoT)和指令跟随(IF)。 In-Context Learning: - In-Context Learning distillation Chain-of-Thought: - MT-COT - Fine-tune-CoT - DISCO - SCOTT - SOCRATIC CoT Instruction Following: - Lion ### 低秩分解 低秩分解旨在通过将给定的权重矩阵分解成两个或多个较小维度的矩阵,从而对其进行近似。低秩分解背后的核心思想是找到一个大的权重矩阵W的分解,得到两个矩阵U和V,使得W≈U V,其中U是一个m×k矩阵,V是一个k×n矩阵,其中k远小于m和n。U和V的乘积近似于原始的权重矩阵,从而大幅减少了参数数量和计算开销。 在LLM研究的模型压缩领域,研究人员通常将多种技术与低秩分解相结合,包括修剪、量化等。 - ZeroQuant-FP(低秩分解+量化) - LoRAPrune(低秩分解+剪枝) ## LLM测评 ### LLM效果评测 - [C-Eval](https://github.com/liguodongiot/ceval):全面的中文基础模型评估套件,涵盖了52个不同学科的13948个多项选择题,分为四个难度级别。 - [CMMLU](https://github.com/liguodongiot/CMMLU):一个综合性的中文评估基准,专门用于评估语言模型在中文语境下的知识和推理能力。CMMLU涵盖了从基础学科到高级专业水平的67个主题。它包括:需要计算和推理的自然科学,需要知识的人文科学和社会科学,以及需要生活常识的中国驾驶规则等。此外,CMMLU中的许多任务具有中国特定的答案,可能在其他地区或语言中并不普遍适用。因此是一个完全中国化的中文测试基准。 - [LVEval](https://github.com/liguodongiot/LVEval):一个具备5个长度等级(16k、32k、64k、128k和256k)、最大文本测试长度达到256k的长文本评测基准。LV-Eval的平均文本长度达到102,380字,最小/最大文本长度为11,896/387,406字。LV-Eval主要有两类评测任务——单跳QA和多跳QA,共包含11个涵盖中英文的评测数据子集。LV-Eval设计时引入3个关键技术:干扰事实插入(Confusiong Facts Insertion,CFI)提高挑战性,关键词和短语替换(Keyword and Phrase Replacement,KPR)减少信息泄漏,以及基于关键词召回的评测指标(Answer Keywords,AK,指代结合答案关键词和字词黑名单的评价指标)提高评测数值客观性。 - [IFEval: Instruction Following Eval](https://github.com/google-research/google-research/tree/master/instruction_following_eval)/[Paper](https://arxiv.org/abs/2311.07911):专注评估大模型遵循指令的能力,包含关键词检测、标点控制、输出格式要求等25种任务。 - [SuperCLUE](https://github.com/CLUEbenchmark/SuperCLUE):一个综合性大模型评测基准,本次评测主要聚焦于大模型的四个能力象限,包括语言理解与生成、专业技能与知识、Agent智能体和安全性,进而细化为12项基础能力。 - [AGIEval](https://github.com/ruixiangcui/AGIEval/):用于评估基础模型在与人类认知和解决问题相关的任务中的能力。该基准源自 20 项面向普通考生的官方、公开、高标准的入学和资格考试,例如:普通大学入学考试(例如:中国高考(Gaokao)和美国 SAT)、法学院入学考试、数学竞赛、律师资格考试、国家公务员考试。 - [OpenCompass](https://github.com/open-compass/opencompass/blob/main/README_zh-CN.md):司南 2.0 大模型评测体系。 - [LongBench](https://github.com/THUDM/LongBench):一个双语(中英文)多任务基准数据集,旨在评估大语言模型的长上下文理解能力。它包含21个任务,涵盖单文档问答、多文档问答、摘要、小样本学习、合成任务和代码补全等。数据集平均任务长度范围为5k到15k,共包含4750个测试数据。LongBench 采用全自动评估方法,旨在以最低的成本衡量和评估模型理解长上下文的能力。 - [EvalScope](https://github.com/modelscope/evalscope):魔搭社区官方推出的模型评测与性能基准测试框架,专为多样化的模型评估需求而设计。它支持广泛的模型类型,包括但不限于大语言模型、多模态模型、Embedding 模型、Reranker 模型和 CLIP 模型。EvalScope还适用于多种评测场景,如端到端RAG评测、竞技场模式和模型推理性能压测等,其内置多个常用测试基准和评测指标,如MMLU、CMMLU、C-Eval、GSM8K等。 ### LLM推理性能压测 - [你真的搞懂了LLM性能压测的各项指标吗?](https://zhuanlan.zhihu.com/p/1989359577871954448) - [AIPerf](https://github.com/ai-dynamo/aiperf):英伟达开源的性能测试工具 - [GuideLLM](https://github.com/vllm-project/guidellm):vLLM开源的性能测试工具 - [EvalScope](https://github.com/modelscope/evalscope):魔搭社区开源的性能测试工具 - [Inference Perf](https://github.com/kubernetes-sigs/inference-perf) - [genai-bench](https://github.com/sgl-project/genai-bench):SGLang开源的性能测试工具 - [GenAI-Perf](https://github.com/liguodongiot/perf_analyzer/tree/main/genai-perf):英伟达开源的一个命令行工具(**已逐渐被淘汰,建议使用AIPerf**),用于测量通过推理服务提供生成式AI模型的吞吐量和延迟。GenAI-Perf 收集一组不同的指标来捕获推理服务的性能。 | 指标 | 描述 | Aggregations | | - | - | - | | Time to First Token | Time between when a request is sent and when its first response is received, one value per request in benchmark | Avg, min, max, p99, p90, p75 | | Time to Second Token | Time between when the first streaming response is received and when the second streaming response is received, one value per request in benchmark | Avg, min, max, p99, p90, p75 | | Inter Token Latency | Time between intermediate responses for a single request divided by the number of generated tokens of the latter response, one value per response per request in benchmark | Avg, min, max, p99, p90, p75 | | Request Latency | Time between when a request is sent and when its final response is received, one value per request in benchmark | Avg, min, max, p99, p90, p75 | | Output Sequence Length | Total number of output tokens of a request, one value per request in benchmark | Avg, min, max, p99, p90, p75 | | Input Sequence Length | Total number of input tokens of a request, one value per request in benchmark | Avg, min, max, p99, p90, p75 | | Output Token Throughput | Total number of output tokens from benchmark divided by benchmark duration | None–one value per benchmark | | Request Throughput | Number of final responses from benchmark divided by benchmark duration | None–one value per benchmark | ## LLM数据工程 LLM Data Engineering ### 预训练语料处理技术 ![llm-pretrain-pipeline](./pic/llm/train/pretrain/llm-pretrain-pipeline-v2.png) - 数据收集 - 数据处理 - 去重 - 过滤 - 选择 - 组合 ### LLM微调高效数据筛选技术 - [LLM微调高效数据筛选技术原理-DEITA]() - [LLM微调高效数据筛选技术原理-MoDS]() - [LLM微调高效数据筛选技术原理-IFD]() - [LLM微调高效数据筛选技术原理-CaR]() - [LESS:仅选择5%有影响力的数据优于全量数据集进行目标指令微调](https://zhuanlan.zhihu.com/p/686007325) - [LESS 实践:用少量的数据进行目标指令微调](https://zhuanlan.zhihu.com/p/686687923) ## 提示工程 - Zero-Shot Prompting - Few-Shot Prompting - Chain-of-Thought (CoT) Prompting - Automatic Chain-of-Thought (Auto-CoT) Prompting - Tree-of-Thoughts (ToT) Prompting ## [LLM算法架构](https://github.com/liguodongiot/llm-action/tree/main/docs/llm-base/ai-algo) ![llm-famliy](./pic/llm/model/llm-famliy.jpg) - [大模型算法演进](https://zhuanlan.zhihu.com/p/600016134) ![llm-famliy](./pic/llm/model/llm-timeline-v2.png) - [百川智能开源大模型baichuan-7B技术剖析](https://www.zhihu.com/question/606757218/answer/3075464500) - [百川智能开源大模型baichuan-13B技术剖析](https://www.zhihu.com/question/611507751/answer/3114988669) - [LLaMA3 技术剖析](https://www.zhihu.com/question/653374932/answer/3470909634) - [大模型算法架构:DeepSeek技术演进及剖析](https://zhuanlan.zhihu.com/p/1912877300439037789) - [大模型算法架构:QWen技术演进及剖析]() - ChatGLM / ChatGLM2 / ChatGLM3 大模型解析 - Bloom 大模型解析 - LLaMA / LLaMA2 大模型解析 - [DeepSeek 视觉语言大模型技术演进(从DeepSeek VL/VL2到DeepSeek OCR)](https://zhuanlan.zhihu.com/p/1976731060562842519) - Qwen3-Next ## LLM应用开发 大模型是基座,要想让其变成一款产品,我们还需要一些其他相关的技术,比如:向量数据库(Pinecone、Milvus、Vespa、Weaviate),LangChain等。 - [云原生向量数据库Milvus(一)-简述、系统架构及应用场景](https://zhuanlan.zhihu.com/p/476025527) - [云原生向量数据库Milvus(二)-数据与索引的处理流程、索引类型及Schema](https://zhuanlan.zhihu.com/p/477231485) - [关于大模型驱动的AI智能体Agent的一些思考](https://zhuanlan.zhihu.com/p/651921120) ### Agent应用 AI Assistant: - [OpenClaw](https://github.com/openclaw/openclaw):一款个人 AI 助手 Code Agent: - [OpenCode](https://github.com/anomalyco/opencode):一个开源代码智能体,[项目文档](https://opencode.ai/docs/zh-cn/) ## [LLM国产化适配](https://github.com/liguodongiot/llm-action/tree/main/docs/llm_localization) 随着 ChatGPT 的现象级走红,引领了AI大模型时代的变革,从而导致 AI 算力日益紧缺。与此同时,中美贸易战以及美国对华进行AI芯片相关的制裁导致 AI 算力的国产化适配势在必行。本系列将对一些国产化 AI 加速卡进行讲解。 - [大模型国产化适配1-华为昇腾AI全栈软硬件平台总结](https://zhuanlan.zhihu.com/p/637918406) - [大模型国产化适配2-基于昇腾910使用ChatGLM-6B进行模型推理](https://zhuanlan.zhihu.com/p/650730807) - [大模型国产化适配3-基于昇腾910使用ChatGLM-6B进行模型训练](https://zhuanlan.zhihu.com/p/651324599) - MindRecord数据格式说明、全量微调、LoRA微调 - [大模型国产化适配4-基于昇腾910使用LLaMA-13B进行多机多卡训练](https://zhuanlan.zhihu.com/p/655902796) - [大模型国产化适配5-百度飞浆PaddleNLP大语言模型工具链总结](https://zhuanlan.zhihu.com/p/665807431) - [大模型国产化适配6-基于昇腾910B快速验证ChatGLM3-6B/BaiChuan2-7B模型推理](https://zhuanlan.zhihu.com/p/677799157) - [大模型国产化适配7-华为昇腾LLM落地可选解决方案(MindFormers、ModelLink、MindIE)](https://zhuanlan.zhihu.com/p/692377206) - [MindIE 1.0.RC1 发布,华为昇腾终于推出了针对LLM的完整部署方案,结束小米加步枪时代](https://www.zhihu.com/question/654472145/answer/3482521709) - [大模型国产化适配8-基于昇腾MindIE推理工具部署Qwen-72B实战(推理引擎、推理服务化)](https://juejin.cn/post/7365879319598727180) - Qwen-72B、Baichuan2-7B、ChatGLM3-6B - [大模型国产化适配9-LLM推理框架MindIE-Service性能基准测试](https://zhuanlan.zhihu.com/p/704649189) - [大模型国产化适配10-快速迁移大模型到昇腾910B保姆级教程(Pytorch版)](https://juejin.cn/post/7375351908896866323) - [大模型国产化适配11-LLM训练性能基准测试(昇腾910B3)](https://juejin.cn/post/7380995631790964772) - [国产知名AI芯片厂商产品大揭秘-昇腾、海光、天数智芯...](https://f46522gm22.feishu.cn/docx/PfWfdMKo8oXYN6xi7uycuhgFnKg) - [国内AI芯片厂商的计算平台大揭秘-昇腾、海光、天数智芯...](https://f46522gm22.feishu.cn/docx/XnhcdXVDholUBpxYoMccS11Mnfc) - [【LLM国产化】量化技术在MindIE推理框架中的应用](https://juejin.cn/post/7416723051377377316) **[⬆ 一键返回目录](#目录)** ## [AI编译器](https://github.com/liguodongiot/llm-action/tree/main/ai-compiler) AI编译器是指将机器学习算法从开发阶段,通过变换和优化算法,使其变成部署状态。 - [AI编译器技术剖析(一)-概述](https://zhuanlan.zhihu.com/p/669347560) - [AI编译器技术剖析(二)-传统编译器](https://zhuanlan.zhihu.com/p/671477784) - [AI编译器技术剖析(三)-树模型编译工具 Treelite 详解](https://zhuanlan.zhihu.com/p/676723324) - [AI编译器技术剖析(四)-编译器前端]() - [AI编译器技术剖析(五)-编译器后端]() - [AI编译器技术剖析(六)-主流编译框架]() - [AI编译器技术剖析(七)-深度学习模型编译优化]() - [lleaves:使用 LLVM 编译梯度提升决策树将预测速度提升10+倍](https://zhuanlan.zhihu.com/p/672584013) 框架: - MLIR - XLA - TVM ## AI基础设施 - [AI 集群基础设施 NVMe SSD 详解](https://zhuanlan.zhihu.com/p/672098336) - [AI 集群基础设施 InfiniBand 详解](https://zhuanlan.zhihu.com/p/673903240) - [大模型训练基础设施:算力篇]() ### AI加速卡 - [AI芯片技术原理剖析(一):国内外AI芯片概述](https://zhuanlan.zhihu.com/p/667686665) - AI芯片技术原理剖析(二):英伟达GPU - AI芯片技术原理剖析(三):谷歌TPU ### AI集群 待更新... ### [AI集群网络通信](https://github.com/liguodongiot/llm-action/tree/main/docs/llm-base/network-communication) 待更新... - 分布式训练网络通讯原语 - AI 集群通信软硬件 ## LLMOps - [在 Kubernetes 上部署机器学习模型的指南](https://zhuanlan.zhihu.com/p/676389726) - [使用 Kubernetes 部署机器学习模型的优势](https://juejin.cn/post/7320513026188099619) ## LLM生态相关技术 - [大模型词表扩充必备工具SentencePiece](https://zhuanlan.zhihu.com/p/630696264) - [大模型实践总结](https://www.zhihu.com/question/601594836/answer/3032763174) - [ChatGLM 和 ChatGPT 的技术区别在哪里?](https://www.zhihu.com/question/604393963/answer/3061358152) - [现在为什么那么多人以清华大学的ChatGLM-6B为基座进行试验?](https://www.zhihu.com/question/602504880/answer/3041965998) - [为什么很多新发布的大模型默认使用BF16而不是FP16?](https://www.zhihu.com/question/616600181/answer/3195333332) - [大模型训练时ZeRO-2、ZeRO-3能否和Pipeline并行相结合?](https://www.zhihu.com/question/652836990/answer/3468210626) - [一文详解模型权重存储新格式 Safetensors](https://juejin.cn/post/7386360803039838235) - [一文搞懂大模型文件存储格式新宠GGUF](https://juejin.cn/post/7408858126042726435) - [DeepGEMM 技术剖析](https://juejin.cn/post/7520475965081813055) ## LLM性能分析 - PyTorch Profiler - NVIDIA Nsight Systems - NVIDIA Nsight Compute ## [LLM面试题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/README.md) 正在收集中... - [大模型基础常见面试题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/base.md) - [大模型算法常见面试题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-algo.md) - [大模型训练常见面试题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-train.md) - [大模型微调常见面试题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-ft.md) - [大模型评估常见面试题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-eval.md) - [大模型压缩常见面试题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-compress.md) - [大模型推理常见面试题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-inference.md) - [大模型应用常见面试题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-app.md) - [大模型综合性面试题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/comprehensive.md) **[⬆ 一键返回目录](#目录)** ## 服务器基础环境安装及常用工具 基础环境安装: - [英伟达A800加速卡常见软件包安装命令](https://github.com/liguodongiot/llm-action/blob/main/docs/llm-base/a800-env-install.md) - [英伟达H800加速卡常见软件包安装命令](https://github.com/liguodongiot/llm-action/blob/main/docs/llm-base/h800-env-install.md) - [昇腾910加速卡常见软件包安装命令](https://github.com/liguodongiot/llm-action/blob/main/llm_localization/ascend910-env-install.md) 常用工具: - [Linux 常见命令大全](https://juejin.cn/post/6992742028605915150) - [Conda 常用命令大全](https://juejin.cn/post/7089093437223338015) - [Poetry 常用命令大全](https://juejin.cn/post/6999405667261874183) - [Docker 常用命令大全](https://juejin.cn/post/7016238524286861325) - [Docker Dockerfile 指令大全](https://juejin.cn/post/7016595442062327844) - [Kubernetes 常用命令大全](https://juejin.cn/post/7031201391553019911) - [集群环境 GPU 管理和监控工具 DCGM 常用命令大全](https://github.com/liguodongiot/llm-action/blob/main/docs/llm-base/dcgmi.md) ## LLM学习交流群 我创建了大模型相关的学习交流群,供大家一起学习交流大模型相关的最新技术,目前已有5个群,每个群都有上百人的规模,**可加我微信进群**(加微信请备注来意,如:进大模型学习交流群+GitHub,进大模型推理加速交流群+GitHub、进大模型应用开发交流群+GitHub、进大模型校招交流群+GitHub等)。**一定要备注哟,否则不予通过**。 PS:**成都有个本地大模型交流群,想进可以另外单独备注下。**

## 微信公众号 微信公众号:**吃果冻不吐果冻皮**,该公众号主要分享AI工程化(大模型、MLOps等)相关实践经验,免费电子书籍、论文等。

**[⬆ 一键返回目录](#目录)** ## Star History [![Star History Chart](https://api.star-history.com/svg?repos=liguodongiot/llm-action&type=Date)](https://star-history.com/#liguodongiot/llm-action&Date) ## AI工程化课程推荐 如今人工智能的发展可谓是如火如荼,ChatGPT、Sora、文心一言等AI大模型如雨后春笋般纷纷涌现。AI大模型优势在于它能处理复杂性问题;因此,越来越多的企业需要具备**AI算法设计、AI应用开发、模型推理加速及模型压缩**等AI工程化落地的能力。这就导致行业内的工程师,需要快速提升自身的技术栈,以便于在行业内站稳脚跟。我在[llm-resource](https://github.com/liguodongiot/llm-resource) 和 [ai-system](https://github.com/liguodongiot/ai-system)梳理了一些大模型和AI工程化相关资料。 ================================================ FILE: ai-compiler/README.md ================================================ ## 树模型编译器 - https://mlsys.org/Conferences/doc/2018/196.pdf - https://github.com/dmlc/treelite - https://treelite.readthedocs.io/en/latest/ - https://zhuanlan.zhihu.com/p/347514385 - https://zhuanlan.zhihu.com/p/487539515 Treelite是用于有效部署决策树集合的模型编译器。 - 决策树Ensemble的编译优化:https://zhuanlan.zhihu.com/p/597511551 ## 深度学习编译器 ### 深度学习编译原理 #### AI 编译器前端优化 前端优化作为AI编译器的整体架构主要模块,主要优化的对象是计算图,而计算图是通过AI框架产生的,值得注意的是并不是所有的AI框架都会生成计算图,有了计算图就可以结合深度学习的原理知识进行图的优化。 - 计算图层(Graph IR) - 算子融合(OP Fusion) - 布局转换(Layout Transform) - 内存分配(Memory Allocation) - 常量折叠(Constant Fold) - 公共子表达式消除(CSE) - 死代码消除(DCE) - 代数简化(ARM) #### AI 编译器后端优化 后端优化作为AI编译器跟硬件之间的相连接的模块,更多的是算子或者Kernel进行优化,而优化之前需要把计算图转换称为调度树等IR格式,然后针对每一个算子/Kernel进行循环优化、指令优化和内存优化等技术。 - 算子循环优化 - 指令和内存优化 ### 深度学习编译工具 #### TVM #### XLA #### Glow ## 深度学习编译优化 - 深度学习框架的编译与优化:https://github.com/microsoft/AI-System/tree/main/Textbook/%E7%AC%AC5%E7%AB%A0-%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E6%A1%86%E6%9E%B6%E7%9A%84%E7%BC%96%E8%AF%91%E4%B8%8E%E4%BC%98%E5%8C%96 计算图优化:XLA、TVM、nGraph 算子生成:AutoTVM、TC、Halide ### 图优化 目标:通过图的等价变换化简计算图,从而降低计算复杂度或内存开销。 数据流图作为深度学习框架中的高层中间表示,可以允许任何等价图优化Pass去化简计算流图或提高执行效率 图优化 (1):算术表达式化简 通过代数运算等价变换化简计算图,如: ``` a * 0 -> 0 a * broadcast(0) -> broadcast(0) a * 1 -> a a * broadcast(1)-> a a + 0 -> a a + broadcast(O)-> a log(exp(x)/y)->x-log(y) ``` 图优化 (2):公共子表达式消除 目的是将相同输入的表达式进行消除,由一个节点来代替,复用计算结果 图优化 (3):常数传播 如果一个算子的所有输入张量都是常数的话,那么该算子的结果也为常数张量 在编译器计算并化简 例子:假设参数0和参数1为常数张量,最终的图可以化简为什么? 注意:常数传播可能会引起内存的扩张,如:Broadcast 图优化 (4): GEMM自动融合 Batch same-type operators to leverage GPU massive parallelism 图优化 (4): GEMM自动融合 通过将输入张量合并成一个大的张量来实现将相同的算子合并成一个更大的算子,从而更好的利用硬件并行度 图优化(5):算子融合 向量化的多个算子的操作可以合并成一个向量化操作 减少内核启动开销 减少内存的读取,提高计算密度 图优化 (6):子图替换 利用子图匹配识别出可替换的复杂子图,替换为更高效的合并算子 图优化 (6):随机子图替换 TASO: Optimizing Deep Learning Computation with Automatic Generation of Graph Substitutions 小结: 图优化的总结 计算图作为深度学习编译框架的第一层中间表示 ``` 基于计算图的优化算法: 算术表达式化简 公共子表达式消除 常数传播 矩阵合并 算子融合 子图替换/随机子图替换 思考: 你可以想到哪些其它的计算图上的优化? 计算图还有哪些其它的好处 ``` ### 内存优化 内存优化 目标:通过对计算图的变化以及张量的合理分配来降低内存使用的总量。 内存优化 (1):基于拓扑序的最小内存分配 将计算流图按照某种拓扑序进行排序。如BFS,ReverseDFS等 按照节点的拓扑顺序依次分配其使用到的输出张量。 当一个张量后面没有其它算子使用时, 则回收到内存池。 当所有张量分配完成后,内存池的最大分配空间就是该计算图需要的最小内存 拓扑序的选择会同时影响模型的计算时间和最大内存占用 内存优化 (2):根据整数线性规划求解最优内存放置 ``` 目标:给定任意的计算图最小化执行时间 约束:有限的快速内存,如GPU内存 变量:每一个张量是否放置在快速内存中,还是较慢的外存中,如CPU内存 过程:最优化张量的移动 需求:每个内核计算的测量时间 方法:将上述的优化问题建模为整数线性规划问题 ``` 内存优化 (3):张量换入换出与张量重计算 ``` 方法: DRAM存储量相对GPU显存来说比较大,可以将数据在GPU与DRAM之间进行转移,或者直接重新计算 发现: 在训练过程中张量的访问模式比较规律 核心思想 根据运行时的张量访问来动态管理内存 替换+预取 重新计算 ``` 小结: 内存优化的总结 ·基于计算图的内存优化算法: 基于拓扑序的最小内存分配 根据整数线性规划求解最优内存放置张量换入换出与张量重计算 ·思考: 你可以想到哪些其它的内存优化方法? ### 内核优化 问题: 每个后端平台针对每个算子都需要单独实现至少一个内核 考虑:编程模型、数据排布、线程模型、缓存大小等等 张量运算编译 ``` 核心思想:分离计算逻辑与调度逻辑 通过张量运算表达式表示每个算子的通用计算逻辑 通过调度语言描述算子在映射到具体硬件上时的调度空间 相关工作: TVM、 Halide、 TACO、 Tensor Comprehension, FlexTensor等 张量运算表达式:例:TVMIR C=A*B C= tvm.compute((m,n),lambda i,j:tvm.sum(A[i,k] * B[k,j], axis=k) ``` 其它张量运算表达式 ``` Affine Transformation out = tvm.compute((n,m),lambda i, j: tvm.sum(data[i, k] * w[j, k], k)) out = tvm.compute((n,m),lambda i, j: out[i, j]十bias[i]) Convolution out=tvm.compute(c, h, w), lambda i, x, y: tvm.sum(data[kc,x+kx,y+ky] * w[i, kx, ky], [kx, ky, kc])) ReLu out = tvm.compute(shape, lambda *i: tvm.max(0, out(*i)) ``` 其它算子调度优化 每一种优化都可能产生出多个内核代码的实现 利用自动机器学习 Auto Tuner 在给定时间内搜索出最高效的实现 小结: 内核优化的总结 内核优化与内核生成 算子表达式 算子表示与调度逻辑的分离 自动调度搜索与代码生成 调度优化 NNFusion:全局计算调度优化 目标:通过将多个算子进行协同调度以及精确映射每一个算子到硬件计算单元来充分利用硬件并行度 中间表示:数据流图+细粒度算子并行单元 结果:将每个子图编译成一个硬件计算内核 充分减少上层调度的开销 高效利用硬件并行度 通过引出新的调度原语来支持任务级调度 APEEND: 将一个算子中的一个任务调度到硬件的一个计算单元上 GROUP_SYNC: 维护任务间的依赖关系 ``` 挑战:调度算子的任务到GPU上的挑战 简单的任务级调度可能引起正确性问题 - 错误依赖 - 死锁 依赖关系的映射 通过将硬件计算单元抽象到软件可控计算单元,并引入细粒度任务级同步支持来保证计算正确性。 并行度的映射 任务级调度可以支持任意算子之间的并行调度,从而最大化硬件利用率。 ``` ``` 本次课程总结 深度神经网络编译器的概念与架构 中间表达、前端、后端、优化过程 计算图优化 算术表达式化简、 公共子表达式消除、 常数传播、矩阵合并、 算子融合、 子图替换/随机子图替换 内存优化 基于拓扑序的最小内存分配、 根据整数线性规划求解最优内存放置、 张量换入换出与张量重计算 内核优化 算子表达式、 算子表示与调度逻辑的分离、 自动调度搜索与代码生成 调度优化 ``` ================================================ FILE: ai-compiler/Treebeard/README.md ================================================ Treebeard: An Optimizing Compiler for Decision Tree Based ML Inference ## 流程 输入一个决策树数据结构,compiler通过一系列 IR 转化,将决策树数据结构转化为对CPU来说更加友好的数据结构,从而加速决策树上的推理过程。然后,因为自己有关于决策树的domain knowledge,因此在做codegen比如循环展开,循环交换的时候,可以选择到更好的codegen方式。整个项目基于MLIR实现,因此一些简单的优化比如使用 OpenMP 做并行,可以直接用MLIR。 ## 图片 TREEBEARD IR lowering 和 optimization 细节 显示了 TREEBEARD IR 中的三个抽象级别。 高级 IR 是基于树的 IR,用于执行模型级优化,中级 IR 用于独立于内存布局的循环优化,低级 IR 允许我们执行向量化和其他与内存布局相关的优化。 Figure 6: Sparse representation with tile size nt = 3. Leaves l4, l5, l6 and l7 are moved into the leaves array. Extra hops are added for l1, l2 and l3 as T2 is a non-leaf tile. The new leaves added as children of l1, l2 and l3 are moved to the leaves array. Figure 9: Geomean speedup (over all benchmarks) of TREEBEARD over XGBoost and Treelite on single-core over several batch sizes. Table I: List of benchmark datasets and their parameters. The column Leaf-biased reports the number of leaf-biased trees per benchmark with 〈α = 0.075,β = 0.9〉 . Table II: Space of optimizations explored. ================================================ FILE: ai-compiler/treelit/README.md ================================================ ``` conda create -n model-inference-venv python=3.9 -y conda activate model-inference-venv ``` - 机器学习:软件工程方法与实现:https://github.com/chansonZ/book-ml-sem/ ================================================ FILE: ai-compiler/treelit/xgb.md ================================================ ``` conda create -n model-server-venv python=3.9 -y ``` ================================================ FILE: ai-compiler/triton-lang/README.md ================================================ ================================================ FILE: ai-framework/README.md ================================================ ## 国外 ### PyTorch ## 国内 ### Oneflow ### PaddlePaddle ### MindSpore 自动混合精度 - https://github.com/Azure/MS-AMP - FP8-LM ================================================ FILE: ai-framework/TensorRT-Model-Optimizer.md ================================================ - 代码:https://github.com/NVIDIA/TensorRT-Model-Optimizer - 文档:https://nvidia.github.io/TensorRT-Model-Optimizer/ - 量化方法最佳实践:https://nvidia.github.io/TensorRT-Model-Optimizer/guides/_choosing_quant_methods.html ================================================ FILE: ai-framework/cuda/README.md ================================================ ================================================ FILE: ai-framework/deepspeed/1.DeepSpeed入门.md ================================================ ## DeepSpeed 通过简单三步将Pytorch DDP模型训练改造 DeepSpeed DP 模型训练。 第一步:**初始化DeepSpeed引擎**: ``` model_engine, optimizer, _, _ = deepspeed.initialize(args=cmd_args, model=model, model_parameters=params) ``` deepspeed.initialize确保在底层适当地完成了所需的分布式数据并行或混合精度训练所需的所有设置。 第二步:**初始化分布式环境**: ``` deepspeed.init_distributed() ``` DeepSpeed将在其初始化期间自动初始化分布式环境,因此,可以不使用此函数。 第三步,**模型训练** 使用三个简单的API来进行前向传播(callable object)、反向传播(backward)和权重更新(step)来训练模型。 ``` for step, batch in enumerate(data_loader): #forward() method loss = model_engine(batch) #runs backpropagation model_engine.backward(loss) #weight update model_engine.step() ``` - Gradient Averaging: 在分布式数据并行训练中,backward 确保在对一个 train_batch_size 进行训练后,梯度在数据并行进程间进行平均。 - Loss Scaling: 在FP16/混合精度训练中, DeepSpeed 引擎会自动处理缩放损失,以避免梯度中的精度损失。 - Learning Rate Scheduler: 当使用 DeepSpeed 的学习率调度器(在ds_config.json文件中指定)时, DeepSpeed 会在每次训练步骤(执行model_engine.step()时)调用调度器的step()方法。当不使用DeepSpeed的学习率调度器时: - 如果调度期望在每次训练步骤都执行, 那么用户可以在初始化 DeepSpeed 引擎时将调度器传递给 deepspeed.initialize, 让 DeepSpeed 进行管理、更新或保存/恢复。 - 如果调度应该在任何其它间隔(例如训练周期)执行,则用户在初始化期间不应将调度传递给 DeepSpeed,必须显式地管理它。 ## 多节点环境变量 当在多个节点上进行训练时,我们发现支持传播用户定义的环境变量非常有用。 默认情况下,DeepSpeed 将传播所有设置的 NCCL 和 PYTHON 相关环境变量。 如果您想传播其它变量,可以在名为 .deepspeed_env 的文件中指定它们,该文件包含一个行分隔的 VAR=VAL 条目列表。 DeepSpeed 启动器将查找你执行的本地路径以及你的主目录(~/)。 以一个具体的例子来说明,有些集群需要在训练之前设置特殊的 NCCL 变量。 用户可以简单地将这些变量添加到其主目录中的 `.deepspeed_env` 文件中,该文件如下所示: ``` NCCL_IB_DISABLE=1 NCCL_SOCKET_IFNAME=eth0 ``` DeepSpeed 然后会确保在启动每个进程时在整个训练工作的每个节点上设置这些环境变量。 ## 兼容MPI 如上所述,DeepSpeed 提供了自己的并行启动器来帮助启动多节点/多GPU训练作业。如果您喜欢使用MPI(例如: mpirun)启动训练作业,则我们提供对此的支持。 需要注意的是,DeepSpeed 仍将使用 torch 分布式 NCCL 后端,而不是 MPI 后端。 要使用 mpirun + DeepSpeed (使用 mpirun 作为启动器后端)启动你的训练作业,您只需要安装 mpi4py Python 包。DeepSpeed 将使用它来发现 MPI 环境,并将必要的状态(例如 world size、rank 等)传递给 torch 分布式后端。 如果你正在使用模型并行,流水线并行或者在调用 deepspeed.initialize(..) 之前需要使用 torch.distributed 调用,我们为你提供了额外的 DeepSpeed API 调用以支持相同的 MPI。请将您的初始 torch.distributed.init_process_group(..) 调用替换为:deepspeed.init_distributed() ## 资源配置(单节点) 如果我们只在单个节点上运行(具有一个或多个GPU),DeepSpeed不需要像上面描述的那样使用 hostfile。如果没有检测到或传递 hostfile,则 DeepSpeed 将查询本地计算机上的 GPU 数量来发现可用的插槽数。--include 和 --exclude 参数与正常工作相同,但用户应将“localhost”指定为主机名。 另外需要注意的是,CUDA_VISIBLE_DEVICES 不能用于 DeepSpeed 来控制应该使用哪些设备。 例如,要仅使用当前节点的 gpu1,请执行以下操作: ``` deepspeed --include localhost:1 ... ``` ================================================ FILE: ai-framework/deepspeed/2.安装DeepSpeed.md ================================================ ## 安装DeepSpeed 通过 pip 是最快捷的开始使用 DeepSpeed 的方式,这将安装最新版本的 DeepSpeed,不会与特定的 PyTorch 或 CUDA 版本绑定。DeepSpeed 包含若干个 C++/CUDA 扩展,我们通常称之为“ops”。默认情况下,所有这些 extensions/ops 将使用 torch 的 JIT C++ 扩展加载器即时构建(JIT)(https://pytorch.org/docs/stable/cpp_extension.html) ,该加载器依赖 ninja 在运行时进行动态链接。 ``` pip install deepspeed ``` 安装完DeepSpeed后,你可以使用 ds_report 或 python -m deepspeed.env_report 命令查看 DeepSpeed 环境报告,以验证你的安装并查看你的机器与哪些 ops 兼容。我们发现,在调试 DeepSpeed 安装或兼容性问题时,这个报告很有用 ``` ds_report -------------------------------------------------- DeepSpeed C++/CUDA extension op report -------------------------------------------------- NOTE: Ops not installed will be just-in-time (JIT) compiled at runtime if needed. Op compatibility means that your system meet the required dependencies to JIT install the op. -------------------------------------------------- JIT compiled ops requires ninja ninja .................. [OKAY] -------------------------------------------------- op name ................ installed .. compatible -------------------------------------------------- async_io ............... [NO] ....... [OKAY] cpu_adagrad ............ [NO] ....... [OKAY] cpu_adam ............... [NO] ....... [OKAY] fused_adam ............. [NO] ....... [OKAY] fused_lamb ............. [NO] ....... [OKAY] quantizer .............. [NO] ....... [OKAY] random_ltd ............. [NO] ....... [OKAY] [WARNING] please install triton==1.0.0 if you want to use sparse attention sparse_attn ............ [NO] ....... [NO] spatial_inference ...... [NO] ....... [OKAY] transformer ............ [NO] ....... [OKAY] stochastic_transformer . [NO] ....... [OKAY] transformer_inference .. [NO] ....... [OKAY] utils .................. [NO] ....... [OKAY] -------------------------------------------------- DeepSpeed general environment info: torch install path ............... ['/home/guodong.li/virtual-venv/llama-venv-py310-cu117/lib/python3.10/site-packages/torch'] torch version .................... 1.13.1+cu117 deepspeed install path ........... ['/home/guodong.li/virtual-venv/llama-venv-py310-cu117/lib/python3.10/site-packages/deepspeed'] deepspeed info ................... 0.8.0, unknown, unknown torch cuda version ............... 11.7 torch hip version ................ None nvcc version ..................... 11.7 deepspeed wheel compiled w. ...... torch 1.12, cuda 11.3 ``` ## 预安装DeepSpeed的Ops > 注意:在预编译任何 DeepSpeed 的 c++/cuda ops 之前,必须先安装 PyTorch。但是,如果使用 ops 的默认 JIT 编译模式,则不需要预编译安装。 有时我们发现,将一些或全部 DeepSpeed C++/CUDA ops 预先安装而不使用 JIT 编译路径是有用的。为了支持预安装,我们引入了构建环境标志以打开/关闭特定 ops 的构建。 您可以通过设置 DS_BUILD_OPS 环境变量为 1 来指示我们的安装程序(install.sh 或 pip install)尝试安装所有 ops,例如: DS_BUILD_OPS=1 pip install deepspeed DeepSpeed 只会安装与你的机器兼容的 ops。有关系统兼容性的更多详细信息,请尝试上面描述的 ds_report 工具。 如果你只想安装特定的 op(例如 FusedLamb),你可以在安装时使用 DS_BUILD 环境变量进行切换。例如,要仅安装带有 FusedLamb op 的 DeepSpeed,请使用: ``` DS_BUILD_FUSED_LAMB=1 pip install deepspeed ``` 可用的 DS_BUILD 选项包含: ``` DS_BUILD_OPS 切换所有 ops DS_BUILD_CPU_ADAM 构建 CPUAdam op DS_BUILD_FUSED_ADAM 构建 FusedAdam op (from apex) DS_BUILD_FUSED_LAMB 构建 FusedLamb op DS_BUILD_SPARSE_ATTN 构建 sparse attention op DS_BUILD_TRANSFORMER 构建 transformer op DS_BUILD_TRANSFORMER_INFERENCE 构建 transformer-inference op DS_BUILD_STOCHASTIC_TRANSFORMER 构建 stochastic transformer op DS_BUILD_UTILS 构建各种优化工具 DS_BUILD_AIO 构建异步 (NVMe) I/O op ``` 为了加速 build-all 过程,您可以使用以下方式并行编译: DS_BUILD_OPS=1 pip install deepspeed --global-option="build_ext" --global-option="-j8" 这应该可以使完整的构建过程加快 2-3 倍。您可以调整 -j 来指定在构建过程中使用多少个 CPU 核心。在此示例中,它设置为 8 个核心。 你还可以构建二进制 wheel,并在具有相同类型的 GPU 和相同软件环境(CUDA 工具包、PyTorch、Python 等)的多台机器上安装它。 DS_BUILD_OPS=1 python setup.py build_ext -j8 bdist_wheel 这将在 dist 目录下创建一个 PyPI 二进制轮,例如 dist/deepspeed-0.3.13+8cd046f-cp38-cp38-linux_x86_64.whl,然后你可以直接在多台机器上安装它,在我们的示例中: ``` pip install dist/deepspeed-0.3.13+8cd046f-cp38-cp38-linux_x86_64.whl ``` ## 源码安装 DeepSpeed 在从 GitHub 克隆 DeepSpeed 仓库后,您可以通过 pip 在 JIT 模式下安装 DeepSpeed(见下文)。由于不编译任何 C++/CUDA 源文件,此安装过程应该很快完成。 ``` pip install . ``` 对于跨多个节点的安装,我们发现使用 github 仓库中的 install.sh (https://github.com/microsoft/DeepSpeed/blob/master/install.sh) 脚本安装 DeepSpeed 很有用。这将在本地构建一个 Python whell,并将其复制到你的主机文件(通过 --hostfile 给出,或默认为 /job/hostfile)中列出的所有节点上。 当使用 DeepSpeed 的代码首次运行时,它将自动构建仅运行所需的 CUDA 扩展,并默认将它们放置在 ~/.cache/torch_extensions/ 目录下。下一次执行相同的程序时,这些已预编译的扩展将从该目录加载。 如果你使用多个虚拟环境,则可能会出现问题,因为默认情况下只有一个 torch_extensions 目录,但不同的虚拟环境可能使用不同的设置(例如,不同的 python 或 cuda 版本),然后加载另一个环境构建的 CUDA 扩展将失败。因此,如果需要,你可以使用 TORCH_EXTENSIONS_DIR 环境变量覆盖默认位置。因此,在每个虚拟环境中,你可以将其指向一个唯一的目录,并且 DeepSpeed 将使用它来保存和加载 CUDA 扩展。 你还可以在特定运行中更改它,使用: ``` TORCH_EXTENSIONS_DIR=./torch-extensions deepspeed ... ``` ## 选择正确的架构进行构建 如果你在运行 DeepSpeed 时遇到以下错误: ``` RuntimeError: CUDA error: no kernel image is available for execution on the device ``` 这意味着 CUDA 扩展没有为你尝试使用的卡构建。 从源代码构建 DeepSpeed 时,DeepSpeed 将尝试支持各种架构,但在 JIT 模式下,它只支持在构建时可见的架构。 你可以通过设置 TORCH_CUDA_ARCH_LIST 环境变量来专门为所需的一系列架构构建: ``` TORCH_CUDA_ARCH_LIST="6.1;7.5;8.6" pip install ... ``` 当你为更少的架构构建时,这也会使构建更快。 这也是为了确保使用你的确切架构而建议的。由于各种技术原因,分布式的 PyTorch 二进制文件没有完全支持所有架构,跳过兼容的二进制文件可能会导致未充分利用你的完整卡的计算能力。要查看 deepspeed 来源构建中包含哪些架构 - 保存日志并搜索 -gencode 参数。 完整的 NVIDIA GPU 列表及其计算能力可以在这里 (https://developer.nvidia.com/cuda-gpus) 找到。 ## CUDA 版本不匹配 如果在运行时碰到以下错误: ``` Exception: >- DeepSpeed Op Builder: Installed CUDA version {VERSION} does not match the version torch was compiled with {VERSION}, unable to compile cuda/cpp extensions without a matching cuda version. ``` 你安装的 CUDA 版本与用于编译 torch 的 CUDA 版本不匹配。我们仅需要主版本匹配(例如,11.1 和 11.8 是可以的)。但是,主版本不匹配可能会导致意外的行为和错误。 解决此错误的最简单方法是更改已安装的 CUDA 版本(使用 nvcc --version 检查)或更新 torch 版本以匹配已安装的 CUDA 版本(使用 python3 -c "import torch; print(torch.version)" 检查)。 如果你想跳过此检查并继续使用不匹配的 CUDA 版本,请使用以下环境变量: ``` DS_SKIP_CUDA_CHECK=1 ``` ## 针对特定功能的依赖项 一些 DeepSpeed 功能需要 DeepSpeed 的一般依赖项之外的特定依赖项。 有关每个功能/op 的 Python 包依赖项,请参阅我们的 requirements 目录(https://github.com/microsoft/DeepSpeed/tree/master/requirements)。 我们尽力将系统级依赖项最小化,但某些功能需要特殊的系统级软件包。请查看我们的 ds_report 工具输出,以查看您是否缺少给定功能的系统级软件包。 ================================================ FILE: ai-framework/deepspeed/3.基于CIFAR-10使用DeepSpeed进行分布式训练 .md ================================================ 在本教程中,我们将向 CIFAR-10 模型中添加 DeepSpeed,这是一个小型图像分类模型。 首先,我们将介绍如何运行原始的 CIFAR-10 模型。然后,我们将逐步启用此模型以在 DeepSpeed 中运行。 ## 运行原始的 CIFAR-10 CIFAR-10 教程的原始模型代码见(https://github.com/pytorch/tutorials/blob/main/beginner_source/blitz/cifar10_tutorial.py)。我们已将其复制到 DeepSpeedExamples/training/cifar/ (https://github.com/microsoft/DeepSpeedExamples/tree/master/training/cifar)下,并作为子模块提供。要下载,请执行: ``` git clone git@github.com:microsoft/DeepSpeedExamples.git ``` 安装 CIFAR-10 模型的 requirements: ``` cd DeepSpeedExamples/training/cifar pip install -r requirements.txt ``` 运行 python cifar10_tutorial.py,它会在第一次运行时下载训练数据集。 ``` Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data/cifar-10-python.tar.gz 170500096it [00:02, 61124868.24it/s] Extracting ./data/cifar-10-python.tar.gz to ./data Files already downloaded and verified cat frog frog frog [1, 2000] loss: 2.170 [1, 4000] loss: 1.879 [1, 6000] loss: 1.690 [1, 8000] loss: 1.591 [1, 10000] loss: 1.545 [1, 12000] loss: 1.467 [2, 2000] loss: 1.377 [2, 4000] loss: 1.374 [2, 6000] loss: 1.363 [2, 8000] loss: 1.322 [2, 10000] loss: 1.295 [2, 12000] loss: 1.287 Finished Training GroundTruth: cat ship ship plane Predicted: cat ship plane plane Accuracy of the network on the 10000 test images: 53 % Accuracy of plane : 69 % Accuracy of car : 59 % Accuracy of bird : 56 % Accuracy of cat : 36 % Accuracy of deer : 37 % Accuracy of dog : 26 % Accuracy of frog : 70 % Accuracy of horse : 61 % Accuracy of ship : 51 % Accuracy of truck : 63 % cuda:0 ``` ## 使能 DeepSpeed ### 参数解析 使能 DeepSpeed 的第一步是向 CIFAR-10 模型添加 DeepSpeed 参数,可以使用以下方式的 deepspeed.add_config_arguments() 函数: ``` import argparse import deepspeed def add_argument(): parser=argparse.ArgumentParser(description='CIFAR') # Data. # Cuda. parser.add_argument('--with_cuda', default=False, action='store_true', help='use CPU in case there\'s no GPU support') parser.add_argument('--use_ema', default=False, action='store_true', help='whether use exponential moving average') # Train. parser.add_argument('-b', '--batch_size', default=32, type=int, help='mini-batch size (default: 32)') parser.add_argument('-e', '--epochs', default=30, type=int, help='number of total epochs (default: 30)') parser.add_argument('--local_rank', type=int, default=-1, help='local rank passed from distributed launcher') # Include DeepSpeed configuration arguments. parser = deepspeed.add_config_arguments(parser) args=parser.parse_args() return args ``` ### 初始化 我们使用 deepspeed.initialize 创建 model_engine、optimizer 和 trainloader,deepspeed.initialize 的定义如下: ``` def initialize(args, model, optimizer=None, model_params=None, training_data=None, lr_scheduler=None, mpu=None, dist_init_required=True, collate_fn=None): ``` 在这里,我们使用 CIFAR-10 模型(net)、args、parameters 和 trainset 初始化 DeepSpeed: ``` parameters = filter(lambda p: p.requires_grad, net.parameters()) args=add_argument() # Initialize DeepSpeed to use the following features # 1) Distributed model. # 2) Distributed data loader. # 3) DeepSpeed optimizer. model_engine, optimizer, trainloader, _ = deepspeed.initialize(args=args, model=net, model_parameters=parameters, training_data=trainset) ``` 初始化 DeepSpeed 后,将原始 device 和 optimizer 删除: ``` #from deepspeed.accelerator import get_accelerator #device = torch.device(get_accelerator().device_name(0) if get_accelerator().is_available() else "cpu") #net.to(device) #optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) ``` ### 训练API deepspeed.initialize 返回的模型是 DeepSpeed 模型引擎,我们将使用它来使用 forward、backward 和 step API 训练模型。 ``` for i, data in enumerate(trainloader): # Get the inputs; data is a list of [inputs, labels]. inputs = data[0].to(model_engine.device) labels = data[1].to(model_engine.device) outputs = model_engine(inputs) loss = criterion(outputs, labels) model_engine.backward(loss) model_engine.step() ``` 在使用 mini-batch 更新权重之后,DeepSpeed 会自动处理梯度清零。 ### 配置 使用 DeepSpeed 的下一步是创建一个配置 JSON 文件 (ds_config.json)。该文件提供由用户定义的 DeepSpeed 特定参数,例如:批量大小、优化器、调度器和其他参数。 ``` { "train_batch_size": 4, "steps_per_print": 2000, "optimizer": { "type": "Adam", "params": { "lr": 0.001, "betas": [ 0.8, 0.999 ], "eps": 1e-8, "weight_decay": 3e-7 } }, "scheduler": { "type": "WarmupLR", "params": { "warmup_min_lr": 0, "warmup_max_lr": 0.001, "warmup_num_steps": 1000 } }, "wall_clock_breakdown": false } ``` ### 运行启用 DeepSpeed 的 CIFAR-10 模型 要使用 DeepSpeed 开始训练已应用 DeepSpeed 的 CIFAR-10 模型,请执行以下命令,默认情况下它将使用所有检测到的 GPU。 ``` deepspeed cifar10_deepspeed.py --deepspeed_config ds_config.json ``` DeepSpeed 通常会打印更多的训练细节供用户监视,包括训练设置、性能统计和损失趋势。 ``` deepspeed.pt cifar10_deepspeed.py --deepspeed_config ds_config.json Warning: Permanently added '[192.168.0.22]:42227' (ECDSA) to the list of known hosts. cmd=['pdsh', '-w', 'worker-0', 'export NCCL_VERSION=2.4.2; ', 'cd /data/users/deepscale/test/ds_v2/examples/cifar;', '/usr/bin/python', '-u', '-m', 'deepspeed.pt.deepspeed_launch', '--world_info=eyJ3b3JrZXItMCI6IFswXX0=', '--node_rank=%n', '--master_addr=192.168.0.22', '--master_port=29500', 'cifar10_deepspeed.py', '--deepspeed', '--deepspeed_config', 'ds_config.json'] worker-0: Warning: Permanently added '[192.168.0.22]:42227' (ECDSA) to the list of known hosts. worker-0: 0 NCCL_VERSION 2.4.2 worker-0: WORLD INFO DICT: {'worker-0': [0]} worker-0: nnodes=1, num_local_procs=1, node_rank=0 worker-0: global_rank_mapping=defaultdict(, {'worker-0': [0]}) worker-0: dist_world_size=1 worker-0: Setting CUDA_VISIBLE_DEVICES=0 worker-0: Files already downloaded and verified worker-0: Files already downloaded and verified worker-0: bird car horse ship worker-0: DeepSpeed info: version=2.1, git-hash=fa937e7, git-branch=master worker-0: [INFO 2020-02-06 19:53:49] Set device to local rank 0 within node. worker-0: 1 1 worker-0: [INFO 2020-02-06 19:53:56] Using DeepSpeed Optimizer param name adam as basic optimizer worker-0: [INFO 2020-02-06 19:53:56] DeepSpeed Basic Optimizer = FusedAdam ( worker-0: Parameter Group 0 worker-0: betas: [0.8, 0.999] worker-0: bias_correction: True worker-0: eps: 1e-08 worker-0: lr: 0.001 worker-0: max_grad_norm: 0.0 worker-0: weight_decay: 3e-07 worker-0: ) worker-0: [INFO 2020-02-06 19:53:56] DeepSpeed using configured LR scheduler = WarmupLR worker-0: [INFO 2020-02-06 19:53:56] DeepSpeed LR Scheduler = worker-0: [INFO 2020-02-06 19:53:56] rank:0 step=0, skipped=0, lr=[0.001], mom=[[0.8, 0.999]] worker-0: DeepSpeedLight configuration: worker-0: allgather_size ............... 500000000 worker-0: allreduce_always_fp32 ........ False worker-0: disable_allgather ............ False worker-0: dump_state ................... False worker-0: dynamic_loss_scale_args ...... None worker-0: fp16_enabled ................. False worker-0: global_rank .................. 0 worker-0: gradient_accumulation_steps .. 1 worker-0: gradient_clipping ............ 0.0 worker-0: initial_dynamic_scale ........ 4294967296 worker-0: loss_scale ................... 0 worker-0: optimizer_name ............... adam worker-0: optimizer_params ............. {'lr': 0.001, 'betas': [0.8, 0.999], 'eps': 1e-08, 'weight_decay': 3e-07} worker-0: prescale_gradients ........... False worker-0: scheduler_name ............... WarmupLR worker-0: scheduler_params ............. {'warmup_min_lr': 0, 'warmup_max_lr': 0.001, 'warmup_num_steps': 1000} worker-0: sparse_gradients_enabled ..... False worker-0: steps_per_print .............. 2000 worker-0: tensorboard_enabled .......... False worker-0: tensorboard_job_name ......... DeepSpeedJobName worker-0: tensorboard_output_path ...... worker-0: train_batch_size ............. 4 worker-0: train_micro_batch_size_per_gpu 4 worker-0: wall_clock_breakdown ......... False worker-0: world_size ................... 1 worker-0: zero_enabled ................. False worker-0: json = { worker-0: "optimizer":{ worker-0: "params":{ worker-0: "betas":[ worker-0: 0.8, worker-0: 0.999 worker-0: ], worker-0: "eps":1e-08, worker-0: "lr":0.001, worker-0: "weight_decay":3e-07 worker-0: }, worker-0: "type":"Adam" worker-0: }, worker-0: "scheduler":{ worker-0: "params":{ worker-0: "warmup_max_lr":0.001, worker-0: "warmup_min_lr":0, worker-0: "warmup_num_steps":1000 worker-0: }, worker-0: "type":"WarmupLR" worker-0: }, worker-0: "steps_per_print":2000, worker-0: "train_batch_size":4, worker-0: "wall_clock_breakdown":false worker-0: } worker-0: [INFO 2020-02-06 19:53:56] 0/50, SamplesPerSec=1292.6411179579866 worker-0: [INFO 2020-02-06 19:53:56] 0/100, SamplesPerSec=1303.6726433398537 worker-0: [INFO 2020-02-06 19:53:56] 0/150, SamplesPerSec=1304.4251022567403 ...... worker-0: [2, 12000] loss: 1.247 worker-0: [INFO 2020-02-06 20:35:23] 0/24550, SamplesPerSec=1284.4954513975558 worker-0: [INFO 2020-02-06 20:35:23] 0/24600, SamplesPerSec=1284.384033658866 worker-0: [INFO 2020-02-06 20:35:23] 0/24650, SamplesPerSec=1284.4433482972925 worker-0: [INFO 2020-02-06 20:35:23] 0/24700, SamplesPerSec=1284.4664449792422 worker-0: [INFO 2020-02-06 20:35:23] 0/24750, SamplesPerSec=1284.4950124403447 worker-0: [INFO 2020-02-06 20:35:23] 0/24800, SamplesPerSec=1284.4756105952233 worker-0: [INFO 2020-02-06 20:35:24] 0/24850, SamplesPerSec=1284.5251526215386 worker-0: [INFO 2020-02-06 20:35:24] 0/24900, SamplesPerSec=1284.531217073863 worker-0: [INFO 2020-02-06 20:35:24] 0/24950, SamplesPerSec=1284.5125323220368 worker-0: [INFO 2020-02-06 20:35:24] 0/25000, SamplesPerSec=1284.5698818883018 worker-0: Finished Training worker-0: GroundTruth: cat ship ship plane worker-0: Predicted: cat car car plane worker-0: Accuracy of the network on the 10000 test images: 57 % worker-0: Accuracy of plane : 61 % worker-0: Accuracy of car : 74 % worker-0: Accuracy of bird : 49 % worker-0: Accuracy of cat : 36 % worker-0: Accuracy of deer : 44 % worker-0: Accuracy of dog : 52 % worker-0: Accuracy of frog : 67 % worker-0: Accuracy of horse : 58 % worker-0: Accuracy of ship : 70 % worker-0: Accuracy of truck : 59 % ``` > 补充:你可以使用 --include localhost:1 类似的命令在单卡上运行模型。此外,--num_gpus可以指定使用多少张GPU来运行。 ================================================ FILE: ai-framework/deepspeed/DeepSpeed配置JSON文件.md ================================================ ## DeepSpeed Configuration JSON 地址:https://www.deepspeed.ai/docs/config-json/ ### FP16 训练的 ZeRO 优化 启用和配置 ZeRO 内存优化 - stage3_gather_16bit_weights_on_model_save: [boolean] > 在通过 save_16bit_model() 保存模型之前合并权重。 由于权重在 GPU 之间进行分区,因此它们不是 state_dict 的一部分,因此启用此选项时该函数会自动收集权重,然后保存 fp16 模型权重。 ================================================ FILE: ai-framework/deepspeed/README.md ================================================ - https://github.com/microsoft/DeepSpeedExamples - https://github.com/microsoft/DeepSpeedExamples.git ================================================ FILE: ai-framework/deepspeed/config-json/README.md ================================================ - https://www.deepspeed.ai/docs/config-json/ ## Batch Size 相关的参数 train_batch_size 必须等于 train_micro_batch_size_per_gpu * gradient_accumulation * gpu数量 ### train_batch_size ### train_micro_batch_size_per_gpu ### gradient_accumulation_steps 在平均和应用梯度之前进行累积梯度的训练step数。 此功能有时对于提高可扩展性很有用,因为它会降低step之间梯度通信的频率。 此功能的另一个影响是能够在每个 GPU 上使用更大的批量大小进行训练。 ## Optimizer 参数 - type:优化器名称。 DeepSpeed 原生支持 Adam、AdamW、OneBitAdam、Lamb 和 OneBitLamb 优化器,同时,也可以从 torch 中导入其他优化器。 - https://deepspeed.readthedocs.io/en/latest/optimizers.html#optimizers - https://pytorch.org/docs/stable/optim.html - params:用于实例化优化器的参数字典。参数名称必须与优化器构造函数签名匹配(例如,Adam)。 - https://pytorch.org/docs/stable/optim.html#algorithms - https://pytorch.org/docs/stable/generated/torch.optim.Adam.html Adam 优化器示例: ``` "optimizer": { "type": "Adam", "params": { "lr": 0.001, "betas": [ 0.8, 0.999 ], "eps": 1e-8, "weight_decay": 3e-7 } } ``` 参数: - torch_adam: Use torch’s implementation of adam instead of our fused adam implementation , 默认为false ## Scheduler 参数 当执行 model_engine.step() 时,DeepSpeed 在每个训练步骤调用 scheduler 的 step() 方法。 - type:学习率调度器名,DeepSpeed 提供了 LRRangeTest、OneCycle、WarmupLR、WarmupDecayLR 学习率调度器的实现。 - https://deepspeed.readthedocs.io/en/latest/schedulers.html - params:用于实例化调度器的参数字典。参数名称应与调度程序构造函数签名匹配。 scheduler 示例: ``` "scheduler": { "type": "WarmupLR", "params": { "warmup_min_lr": 0, "warmup_max_lr": 0.001, "warmup_num_steps": 1000 } } ``` ## 通讯选项 ### communication_data_type ### prescale_gradients ### gradient_predivide_factor ### sparse_gradients ## FP16 训练选项 - 注意:此模式不能与下述 amp 模式结合使用。 ``` "fp16": { "enabled": true, "auto_cast": false, "loss_scale": 0, "initial_scale_power": 16, "loss_scale_window": 1000, "hysteresis": 2, "consecutive_hysteresis": false, "min_loss_scale": 1 } ``` ## BFLOAT16 训练选项 - 注意:此模式不能与下述amp模式结合使用。 - 注意:该模式不能与上述fp16模式结合使用。 使用 bfloat16 浮点格式作为 FP16 替代方案。 BFLOAT16 需要硬件支持(例如:NVIDIA A100)。 使用 bfloat16 进行训练不需要损失缩放。 示例如下所示。 ``` "bf16": { "enabled": true } ``` ## 自动混合精度 (AMP) 训练选项 注意:该模式不能与上述fp16模式结合使用。 此外,该模式目前与 ZeRO 不兼容。 ``` "amp": { "enabled": true, ... "opt_level": "O1", ... } ``` ## 梯度裁剪(Gradient Clipping) - gradient_clipping ## 针对 FP16 训练的 ZeRO 优化 ## 参数卸载(Parameter offloading) 启用和配置 ZeRO 优化,将参数卸载到 CPU/NVMe。 仅适用于 ZeRO 阶段 3。 - 注意,如果"device"的值未指定或不支持,则会触发断言。 ``` "offload_param": { "device": "[cpu|nvme]", "nvme_path": "/local_nvme", "pin_memory": [true|false], "buffer_count": 5, "buffer_size": 1e8, "max_in_cpu": 1e9 } ``` ## 优化器卸载 启用和配置 ZeRO 优化,将优化器计算卸载到 CPU 并将优化器状态卸载到 CPU/NVMe。 CPU 卸载适用于 ZeRO 阶段 1、2、3。NVMe 卸载仅适用于 ZeRO 阶段 3。 - 注意,如果"device"的值未指定或不支持,则会触发断言。 ``` "offload_optimizer": { "device": "[cpu|nvme]", "nvme_path": "/local_nvme", "pin_memory": [true|false], "buffer_count": 4, "fast_init": false } ``` ## Activation Checkpointing ``` "activation_checkpointing": { "partition_activations": false, "cpu_checkpointing": false, "contiguous_memory_optimization": false, "number_checkpoints": null, "synchronize_checkpoint_boundary": false, "profile": false } ``` ## 稀疏注意力(Sparse Attention) ``` "sparse_attention": { "mode": "fixed", "block": 16, "different_layout_per_head": true, "num_local_blocks": 4, "num_global_blocks": 1, "attention": "bidirectional", "horizontal_global_attention": false, "num_different_global_patterns": 4, "num_random_blocks": 0, "local_window_blocks": [4], "global_block_indices": [0], "global_block_end_indices": None, "num_sliding_window_blocks": 3 } ``` ## Logging ### steps_per_print ### wall_clock_breakdown ### dump_state ## Flops 分析器(Flops Profiler) - detailed:是否打印详细的模型配置。 - output_file:输出文件的路径。 如果没有,Profiler 将打印到标准输出。 ``` { "flops_profiler": { "enabled": false, "profile_step": 1, "module_depth": -1, "top_modules": 1, "detailed": true, "output_file": null, } } ``` ## 监控模块(TensorBoard、WandB、CSV) ### tensorboard TensorBoard配置示例: ``` "tensorboard": { "enabled": true, "output_path": "output/ds_logs/", "job_name": "train_bert" } ``` ## 压缩(Compression) ### Layer Reduction ### 权重量化(Weight Quantization) ### 激活量化(Activation Quantization) ### 稀疏剪枝(Sparse Pruning) ### 头剪枝(Head Pruning) ### 通道剪枝(Channel Pruning) ## Checkpoint 选项 ``` "checkpoint": { "tag_validation"="Warn", "load_universal"=false, "use_node_local_storage"=false, "parallel_write":{ "pipeline_stage": false } } ``` ## 数据类型选项 ``` "data_types": { "grad_accum_dtype"=["fp32"|"fp16"|"bf16"] } } ``` ## Data Efficiency ================================================ FILE: ai-framework/deepspeed/config-json/deepspeed-nvme.md ================================================ - ZeRO-Infinity: Breaking the GPU Memory Wall for Extreme Scale Deep Learning ``` ``` ================================================ FILE: ai-framework/deepspeed/deepspeed-slurm.md ================================================ ## 支持的发布 PDSH_LAUNCHER = 'pdsh' PDSH_MAX_FAN_OUT = 1024 OPENMPI_LAUNCHER = 'openmpi' MPICH_LAUNCHER = 'mpich' IMPI_LAUNCHER = 'impi' SLURM_LAUNCHER = 'slurm' MVAPICH_LAUNCHER = 'mvapich' ## Slurm - https://hpclib.com/Scheduler/Slurm/mpi_guide.html - https://slurm.schedmd.com/mpi_guide.html ================================================ FILE: ai-framework/deepspeed/hello_bert/README.md ================================================ # HelloDeepSpeed - 源码:https://github.com/microsoft/DeepSpeedExamples/tree/master/training/HelloDeepSpeed ## HF ``` model = create_model( num_layers=num_layers, num_heads=num_heads, ff_dim=ff_dim, h_dim=h_dim, dropout=dropout, ) model.train() for step, batch in enumerate(data_iterator, start=start_step): optimizer.zero_grad() # Forward pass loss = model(**batch) # Backward pass loss.backward() # Optimizer Step optimizer.step() ``` 运行命令: ``` python train_bert.py --checkpoint_dir ./experiments --local_rank 0 ``` 模型输出权重文件: ``` tree experiments/ experiments/ └── bert_pretrain.2023.6.13.5.34.39.addjtvxg ├── checkpoint.iter_1000.pt ├── checkpoint.iter_2000.pt ├── checkpoint.iter_3000.pt ├── checkpoint.iter_4000.pt ├── checkpoint.iter_5000.pt ├── checkpoint.iter_6000.pt ├── checkpoint.iter_7000.pt ├── checkpoint.iter_8000.pt ├── checkpoint.iter_9000.pt ├── gitdiff.log ├── githash.log ├── hparams.json └── tb_dir └── events.out.tfevents.1686659679.ai-app-2-46.54673.0 ``` ## Deepspeed+HF ``` model = create_model( num_layers=num_layers, num_heads=num_heads, ff_dim=ff_dim, h_dim=h_dim, dropout=dropout, ) model, _, _, _ = deepspeed.initialize(model=model, model_parameters=model.parameters(), config=ds_config) model.train() for step, batch in enumerate(data_iterator, start=start_step): # Forward pass loss = model(**batch) # Backward pass model.backward(loss) # Optimizer Step model.step() ``` 运行命令及模型输出权重文件: ``` # 默认使用当前服务器所有GPU卡 deepspeed train_bert_ds.py --checkpoint_dir ./experiments_ds tree experiments_ds/ experiments_ds/ └── bert_pretrain.2023.6.13.18.58.44.addjtvxg ├── gitdiff.log ├── githash.log ├── global_step1000 │   ├── mp_rank_00_model_states.pt │   ├── zero_pp_rank_0_mp_rank_00_optim_states.pt ... │   └── zero_pp_rank_7_mp_rank_00_optim_states.pt ├── global_step9000 │   ├── mp_rank_00_model_states.pt │   ├── zero_pp_rank_0_mp_rank_00_optim_states.pt ... │   └── zero_pp_rank_7_mp_rank_00_optim_states.pt ├── hparams.json ├── latest ├── tb_dir │   └── events.out.tfevents.1686707924.ai-app-2-46.599.0 └── zero_to_fp32.py deepspeed --include localhost:2,3,4,5 train_bert_ds.py --checkpoint_dir ./experiments_multigpu --num_iterations=500 --checkpoint_every=250 tree -h ./experiments_multigpu ./experiments_multigpu ├── [ 36] bert_pretrain.2023.6.13.19.37.59.addjtvxg │   └── [ 63] global_step250 │   └── [ 47M] zero_pp_rank_3_mp_rank_00_optim_states.pt └── [ 169] bert_pretrain.2023.6.13.19.38.0.addjtvxg ├── [ 45K] gitdiff.log ├── [ 41] githash.log ├── [ 207] global_step250 │   ├── [ 31M] mp_rank_00_model_states.pt │   ├── [ 47M] zero_pp_rank_0_mp_rank_00_optim_states.pt │   ├── [ 47M] zero_pp_rank_1_mp_rank_00_optim_states.pt │   └── [ 47M] zero_pp_rank_2_mp_rank_00_optim_states.pt ├── [ 298] hparams.json ├── [ 14] latest ├── [ 77] tb_dir │   └── [2.4K] events.out.tfevents.1686710280.ai-app-2-46.14672.0 └── [ 18K] zero_to_fp32.py ``` ================================================ FILE: ai-framework/deepspeed/hello_bert/train_bert.py ================================================ import datetime import json import pathlib import re import string from functools import partial from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, TypeVar, Union import random import datasets import fire import loguru import numpy as np import pytz import sh import torch import torch.nn as nn from torch.utils.data import DataLoader, Dataset from torch.utils.tensorboard import SummaryWriter from transformers import AutoTokenizer, PreTrainedTokenizer, PreTrainedTokenizerFast from transformers.models.roberta import RobertaConfig, RobertaModel from transformers.models.roberta.modeling_roberta import ( RobertaLMHead, RobertaPreTrainedModel, ) logger = loguru.logger ###################################################################### ############### Dataset Creation Related Functions ################### ###################################################################### TokenizerType = Union[PreTrainedTokenizer, PreTrainedTokenizerFast] def collate_function(batch: List[Tuple[List[int], List[int]]], pad_token_id: int) -> Dict[str, torch.Tensor]: """Collect a list of masked token indices, and labels, and batch them, padding to max length in the batch. """ max_length = max(len(token_ids) for token_ids, _ in batch) padded_token_ids = [ token_ids + [pad_token_id for _ in range(0, max_length - len(token_ids))] for token_ids, _ in batch ] padded_labels = [ labels + [pad_token_id for _ in range(0, max_length - len(labels))] for _, labels in batch ] src_tokens = torch.LongTensor(padded_token_ids) tgt_tokens = torch.LongTensor(padded_labels) attention_mask = src_tokens.ne(pad_token_id).type_as(src_tokens) return { "src_tokens": src_tokens, "tgt_tokens": tgt_tokens, "attention_mask": attention_mask, } def masking_function( text: str, tokenizer: TokenizerType, mask_prob: float, random_replace_prob: float, unmask_replace_prob: float, max_length: int, ) -> Tuple[List[int], List[int]]: """Given a text string, randomly mask wordpieces for Bert MLM training. Args: text (str): The input text tokenizer (TokenizerType): The tokenizer for tokenization mask_prob (float): What fraction of tokens to mask random_replace_prob (float): Of the masked tokens, how many should be replaced with random tokens (improves performance) unmask_replace_prob (float): Of the masked tokens, how many should be replaced with the original token (improves performance) max_length (int): The maximum sequence length to consider. Note that for Bert style models, this is a function of the number of positional embeddings you learn Returns: Tuple[List[int], List[int]]: The masked token ids (based on the tokenizer passed), and the output labels (padded with `tokenizer.pad_token_id`) """ # Note: By default, encode does add the BOS and EOS token # Disabling that behaviour to make this more clear tokenized_ids = ([tokenizer.bos_token_id] + tokenizer.encode(text, add_special_tokens=False, truncation=True, max_length=max_length - 2) + [tokenizer.eos_token_id]) seq_len = len(tokenized_ids) tokenized_ids = np.array(tokenized_ids) subword_mask = np.full(len(tokenized_ids), False) # Masking the BOS and EOS token leads to slightly worse performance low = 1 high = len(subword_mask) - 1 mask_choices = np.arange(low, high) num_subwords_to_mask = max( int((mask_prob * (high - low)) + np.random.rand()), 1) subword_mask[np.random.choice(mask_choices, num_subwords_to_mask, replace=False)] = True # Create the labels first labels = np.full(seq_len, tokenizer.pad_token_id) labels[subword_mask] = tokenized_ids[subword_mask] tokenized_ids[subword_mask] = tokenizer.mask_token_id # Now of the masked tokens, choose how many to replace with random and how many to unmask rand_or_unmask_prob = random_replace_prob + unmask_replace_prob if rand_or_unmask_prob > 0: rand_or_unmask = subword_mask & (np.random.rand(len(tokenized_ids)) < rand_or_unmask_prob) if random_replace_prob == 0: unmask = rand_or_unmask rand_mask = None elif unmask_replace_prob == 0: unmask = None rand_mask = rand_or_unmask else: unmask_prob = unmask_replace_prob / rand_or_unmask_prob decision = np.random.rand(len(tokenized_ids)) < unmask_prob unmask = rand_or_unmask & decision rand_mask = rand_or_unmask & (~decision) if unmask is not None: tokenized_ids[unmask] = labels[unmask] if rand_mask is not None: weights = np.ones(tokenizer.vocab_size) weights[tokenizer.all_special_ids] = 0 probs = weights / weights.sum() num_rand = rand_mask.sum() tokenized_ids[rand_mask] = np.random.choice(tokenizer.vocab_size, num_rand, p=probs) return tokenized_ids.tolist(), labels.tolist() class WikiTextMLMDataset(Dataset): """A [Map style dataset](https://pytorch.org/docs/stable/data.html) for iterating over the wikitext dataset. Note that this assumes the dataset can fit in memory. For larger datasets you'd want to shard them and use an iterable dataset (eg: see [Infinibatch](https://github.com/microsoft/infinibatch)) Args: Dataset (datasets.arrow_dataset.Dataset): The wikitext dataset masking_function (Callable[[str], Tuple[List[int], List[int]]]) The masking function. To generate one training instance, the masking function is applied to the `text` of a dataset record """ def __init__( self, dataset: datasets.arrow_dataset.Dataset, masking_function: Callable[[str], Tuple[List[int], List[int]]], ) -> None: self.dataset = dataset self.masking_function = masking_function def __len__(self) -> int: return len(self.dataset) def __getitem__(self, idx: int) -> Tuple[List[int], List[int]]: tokens, labels = self.masking_function(self.dataset[idx]["text"]) return (tokens, labels) # TypeVar 声明类型变量T T = TypeVar("T") # 使用迭代器,用到的时候再取 class InfiniteIterator(object): def __init__(self, iterable: Iterable[T]) -> None: self._iterable = iterable self._iterator = iter(self._iterable) # 返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成。 def __iter__(self): return self # 会返回下一个迭代器对象。我们就可以通过next函数访问这个对象的下一个元素了, # 并且在你不想继续有迭代的情况下抛出一个StopIteration的异常 def __next__(self) -> T: next_item = None try: next_item = next(self._iterator) except StopIteration: self._iterator = iter(self._iterable) next_item = next(self._iterator) return next_item def create_data_iterator( mask_prob: float, random_replace_prob: float, unmask_replace_prob: float, batch_size: int, max_seq_length: int = 512, tokenizer: str = "roberta-base", ) -> InfiniteIterator: """Create the dataloader. Args: mask_prob (float): Fraction of tokens to mask random_replace_prob (float): Fraction of masked tokens to replace with random token unmask_replace_prob (float): Fraction of masked tokens to replace with the actual token batch_size (int): The batch size of the generated tensors max_seq_length (int, optional): The maximum sequence length for the MLM task. Defaults to 512. tokenizer (str, optional): The tokenizer to use. Defaults to "roberta-base". Returns: InfiniteIterator: The torch DataLoader, wrapped in an InfiniteIterator class, to be able to continuously generate samples """ #wikitext_dataset = datasets.load_dataset("wikitext", wikitext_dataset = datasets.load_dataset("/home/guodong.li/code/wikitext.py", "wikitext-2-v1", split="train") wikitext_dataset = wikitext_dataset.filter( lambda record: record["text"] != "").map( lambda record: {"text": record["text"].rstrip("\n")}) #tokenizer = AutoTokenizer.from_pretrained(tokenizer) tokenizer = AutoTokenizer.from_pretrained("/home/guodong.li/model/roberta-base") masking_function_partial = partial( masking_function, tokenizer=tokenizer, mask_prob=mask_prob, random_replace_prob=random_replace_prob, unmask_replace_prob=unmask_replace_prob, max_length=max_seq_length, ) dataset = WikiTextMLMDataset(wikitext_dataset, masking_function_partial) collate_fn_partial = partial(collate_function, pad_token_id=tokenizer.pad_token_id) # 加载数据 dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True, collate_fn=collate_fn_partial) return InfiniteIterator(dataloader) ###################################################################### ############### Model Creation Related Functions ##################### ###################################################################### class RobertaLMHeadWithMaskedPredict(RobertaLMHead): def __init__(self, config: RobertaConfig, embedding_weight: Optional[torch.Tensor] = None) -> None: super(RobertaLMHeadWithMaskedPredict, self).__init__(config) if embedding_weight is not None: self.decoder.weight = embedding_weight def forward( # pylint: disable=arguments-differ self, features: torch.Tensor, masked_token_indices: Optional[torch.Tensor] = None, **kwargs, ) -> torch.Tensor: """The current `transformers` library does not provide support for masked_token_indices. This function provides the support, by running the final forward pass only for the masked indices. This saves memory Args: features (torch.Tensor): The features to select from. Shape (batch, seq_len, h_dim) masked_token_indices (torch.Tensor, optional): The indices of masked tokens for index select. Defaults to None. Shape: (num_masked_tokens,) Returns: torch.Tensor: The index selected features. Shape (num_masked_tokens, h_dim) """ if masked_token_indices is not None: features = torch.index_select( features.view(-1, features.shape[-1]), 0, masked_token_indices) return super().forward(features) class RobertaMLMModel(RobertaPreTrainedModel): def __init__(self, config: RobertaConfig, encoder: RobertaModel) -> None: super().__init__(config) self.encoder = encoder self.lm_head = RobertaLMHeadWithMaskedPredict( config, self.encoder.embeddings.word_embeddings.weight) self.lm_head.apply(self._init_weights) def forward( self, src_tokens: torch.Tensor, attention_mask: torch.Tensor, tgt_tokens: torch.Tensor, ) -> torch.Tensor: """The forward pass for the MLM task Args: src_tokens (torch.Tensor): The masked token indices. Shape: (batch, seq_len) attention_mask (torch.Tensor): The attention mask, since the batches are padded to the largest sequence. Shape: (batch, seq_len) tgt_tokens (torch.Tensor): The output tokens (padded with `config.pad_token_id`) Returns: torch.Tensor: The MLM loss """ # shape: (batch, seq_len, h_dim) sequence_output, *_ = self.encoder(input_ids=src_tokens, attention_mask=attention_mask, return_dict=False) pad_token_id = self.config.pad_token_id # (labels have also been padded with pad_token_id) # filter out all masked labels # shape: (num_masked_tokens,) masked_token_indexes = torch.nonzero( (tgt_tokens != pad_token_id).view(-1)).view(-1) # shape: (num_masked_tokens, vocab_size) prediction_scores = self.lm_head(sequence_output, masked_token_indexes) # shape: (num_masked_tokens,) target = torch.index_select(tgt_tokens.view(-1), 0, masked_token_indexes) loss_fct = nn.CrossEntropyLoss(ignore_index=-1) masked_lm_loss = loss_fct( prediction_scores.view(-1, self.config.vocab_size), target) return masked_lm_loss def create_model(num_layers: int, num_heads: int, ff_dim: int, h_dim: int, dropout: float) -> RobertaMLMModel: """Create a Bert model with the specified `num_heads`, `ff_dim`, `h_dim` and `dropout` 创建一个bert模型 Args: num_layers (int): The number of layers num_heads (int): The number of attention heads ff_dim (int): The intermediate hidden size of the feed forward block of the transformer h_dim (int): The hidden dim of the intermediate representations of the transformer dropout (float): The value of dropout to be used. Note that we apply the same dropout to both the attention layers and the FF layers Returns: RobertaMLMModel: A Roberta model for MLM task """ roberta_config_dict = { "attention_probs_dropout_prob": dropout, "bos_token_id": 0, "eos_token_id": 2, "hidden_act": "gelu", "hidden_dropout_prob": dropout, "hidden_size": h_dim, "initializer_range": 0.02, "intermediate_size": ff_dim, "layer_norm_eps": 1e-05, "max_position_embeddings": 514, "model_type": "roberta", "num_attention_heads": num_heads, "num_hidden_layers": num_layers, "pad_token_id": 1, "type_vocab_size": 1, "vocab_size": 50265, } roberta_config = RobertaConfig.from_dict(roberta_config_dict) roberta_encoder = RobertaModel(roberta_config) roberta_model = RobertaMLMModel(roberta_config, roberta_encoder) return roberta_model ###################################################################### ########### Experiment Management Related Functions ################## ###################################################################### def get_unique_identifier(length: int = 8) -> str: """Create a unique identifier by choosing `length` random characters from list of ascii characters and numbers """ alphabet = string.ascii_lowercase + string.digits uuid = "".join(alphabet[ix] for ix in np.random.choice(len(alphabet), length)) return uuid def create_experiment_dir(checkpoint_dir: pathlib.Path, all_arguments: Dict[str, Any]) -> pathlib.Path: """Create an experiment directory and save all arguments in it. Additionally, also store the githash and gitdiff. Finally create a directory for `Tensorboard` logs. The structure would look something like checkpoint_dir `-experiment-name |- hparams.json |- githash.log |- gitdiff.log `- tb_dir/ Args: checkpoint_dir (pathlib.Path): The base checkpoint directory all_arguments (Dict[str, Any]): The arguments to save Returns: pathlib.Path: The experiment directory """ # experiment name follows the following convention # {exp_type}.{YYYY}.{MM}.{DD}.{HH}.{MM}.{SS}.{uuid} current_time = datetime.datetime.now(pytz.timezone("US/Pacific")) expname = "bert_pretrain.{0}.{1}.{2}.{3}.{4}.{5}.{6}".format( current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second, get_unique_identifier(), ) exp_dir = checkpoint_dir / expname exp_dir.mkdir(exist_ok=False) hparams_file = exp_dir / "hparams.json" with hparams_file.open("w") as handle: json.dump(obj=all_arguments, fp=handle, indent=2) # Save the git hash try: gitlog = sh.git.log("-1", format="%H", _tty_out=False, _fg=False) with (exp_dir / "githash.log").open("w") as handle: handle.write(gitlog.stdout.decode("utf-8")) except sh.ErrorReturnCode_128: logger.info("Seems like the code is not running from" " within a git repo, so hash will" " not be stored. However, it" " is strongly advised to use" " version control.") # And the git diff try: gitdiff = sh.git.diff(_fg=False, _tty_out=False) with (exp_dir / "gitdiff.log").open("w") as handle: handle.write(gitdiff.stdout.decode("utf-8")) except sh.ErrorReturnCode_129: logger.info("Seems like the code is not running from" " within a git repo, so diff will" " not be stored. However, it" " is strongly advised to use" " version control.") # Finally create the Tensorboard Dir tb_dir = exp_dir / "tb_dir" tb_dir.mkdir() return exp_dir ###################################################################### ################ Checkpoint Related Functions ######################## ###################################################################### def load_model_checkpoint( load_checkpoint_dir: pathlib.Path, model: torch.nn.Module, optimizer: torch.optim.Optimizer, ) -> Tuple[int, torch.nn.Module, torch.optim.Optimizer]: """Loads the optimizer state dict and model state dict from the load_checkpoint_dir into the passed model and optimizer. Searches for the most recent checkpoint to load from Args: load_checkpoint_dir (pathlib.Path): The base checkpoint directory to load from model (torch.nn.Module): The model to load the checkpoint weights into optimizer (torch.optim.Optimizer): The optimizer to load the checkpoint weigths into Returns: Tuple[int, torch.nn.Module, torch.optim.Optimizer]: The checkpoint step, model with state_dict loaded and optimizer with state_dict loaded """ logger.info( f"Loading model and optimizer checkpoint from {load_checkpoint_dir}") checkpoint_files = list( filter( lambda path: re.search(r"iter_(?P\d+)\.pt", path.name) is not None, load_checkpoint_dir.glob("*.pt"), )) assert len(checkpoint_files) > 0, "No checkpoints found in directory" checkpoint_files = sorted( checkpoint_files, key=lambda path: int( re.search(r"iter_(?P\d+)\.pt", path.name).group("iter_no") ), ) latest_checkpoint_path = checkpoint_files[-1] checkpoint_step = int( re.search(r"iter_(?P\d+)\.pt", latest_checkpoint_path.name).group("iter_no")) state_dict = torch.load(latest_checkpoint_path) model.load_state_dict(state_dict["model"], strict=True) optimizer.load_state_dict(state_dict["optimizer"]) logger.info( f"Loading model and optimizer checkpoints done. Loaded from {latest_checkpoint_path}" ) return checkpoint_step, model, optimizer ###################################################################### ######################## Driver Functions ############################ ###################################################################### def train( checkpoint_dir: str = None, load_checkpoint_dir: str = None, # Dataset Parameters mask_prob: float = 0.15, random_replace_prob: float = 0.1, unmask_replace_prob: float = 0.1, max_seq_length: int = 512, tokenizer: str = "roberta-base", # Model Parameters num_layers: int = 6, num_heads: int = 8, ff_dim: int = 512, h_dim: int = 256, dropout: float = 0.1, # Training Parameters batch_size: int = 8, num_iterations: int = 10000, checkpoint_every: int = 1000, log_every: int = 10, local_rank: int = -1, ) -> pathlib.Path: """Trains a [Bert style](https://arxiv.org/pdf/1810.04805.pdf) (transformer encoder only) model for MLM Task Args: checkpoint_dir (str): The base experiment directory to save experiments to mask_prob (float, optional): The fraction of tokens to mask. Defaults to 0.15. random_replace_prob (float, optional): The fraction of masked tokens to replace with random token. Defaults to 0.1. unmask_replace_prob (float, optional): The fraction of masked tokens to leave unchanged. Defaults to 0.1. max_seq_length (int, optional): The maximum sequence length of the examples. Defaults to 512. tokenizer (str, optional): The tokenizer to use. Defaults to "roberta-base". num_layers (int, optional): The number of layers in the Bert model. Defaults to 6. num_heads (int, optional): Number of attention heads to use. Defaults to 8. ff_dim (int, optional): Size of the intermediate dimension in the FF layer. Defaults to 512. h_dim (int, optional): Size of intermediate representations. Defaults to 256. dropout (float, optional): Amout of Dropout to use. Defaults to 0.1. batch_size (int, optional): The minibatch size. Defaults to 8. num_iterations (int, optional): Total number of iterations to run the model for. Defaults to 10000. checkpoint_every (int, optional): Save checkpoint after these many steps. ..note :: You want this to be frequent enough that you can resume training in case it crashes, but not so much that you fill up your entire storage ! Defaults to 1000. log_every (int, optional): Print logs after these many steps. Defaults to 10. local_rank (int, optional): Which GPU to run on (-1 for CPU). Defaults to -1. Returns: pathlib.Path: The final experiment directory """ device = (torch.device("cuda", local_rank) if (local_rank > -1) and torch.cuda.is_available() else torch.device("cpu")) ################################ ###### Create Exp. Dir ######### ################################ if checkpoint_dir is None and load_checkpoint_dir is None: logger.error("Need to specify one of checkpoint_dir" " or load_checkpoint_dir") return if checkpoint_dir is not None and load_checkpoint_dir is not None: logger.error("Cannot specify both checkpoint_dir" " and load_checkpoint_dir") return if checkpoint_dir: logger.info("Creating Experiment Directory") checkpoint_dir = pathlib.Path(checkpoint_dir) checkpoint_dir.mkdir(exist_ok=True) all_arguments = { # Dataset Params "mask_prob": mask_prob, "random_replace_prob": random_replace_prob, "unmask_replace_prob": unmask_replace_prob, "max_seq_length": max_seq_length, "tokenizer": tokenizer, # Model Params "num_layers": num_layers, "num_heads": num_heads, "ff_dim": ff_dim, "h_dim": h_dim, "dropout": dropout, # Training Params "batch_size": batch_size, "num_iterations": num_iterations, "checkpoint_every": checkpoint_every, } exp_dir = create_experiment_dir(checkpoint_dir, all_arguments) logger.info(f"Experiment Directory created at {exp_dir}") else: logger.info("Loading from Experiment Directory") load_checkpoint_dir = pathlib.Path(load_checkpoint_dir) assert load_checkpoint_dir.exists() with (load_checkpoint_dir / "hparams.json").open("r") as handle: hparams = json.load(handle) # Set the hparams # Dataset Params mask_prob = hparams.get("mask_prob", mask_prob) tokenizer = hparams.get("tokenizer", tokenizer) random_replace_prob = hparams.get("random_replace_prob", random_replace_prob) unmask_replace_prob = hparams.get("unmask_replace_prob", unmask_replace_prob) max_seq_length = hparams.get("max_seq_length", max_seq_length) # Model Params ff_dim = hparams.get("ff_dim", ff_dim) h_dim = hparams.get("h_dim", h_dim) dropout = hparams.get("dropout", dropout) num_layers = hparams.get("num_layers", num_layers) num_heads = hparams.get("num_heads", num_heads) # Training Params batch_size = hparams.get("batch_size", batch_size) _num_iterations = hparams.get("num_iterations", num_iterations) num_iterations = max(num_iterations, _num_iterations) checkpoint_every = hparams.get("checkpoint_every", checkpoint_every) exp_dir = load_checkpoint_dir # Tensorboard writer tb_dir = exp_dir / "tb_dir" assert tb_dir.exists() summary_writer = SummaryWriter(log_dir=tb_dir) ################################ ###### 创建数据集 ######### ################################ logger.info("Creating Datasets") data_iterator = create_data_iterator( mask_prob=mask_prob, random_replace_prob=random_replace_prob, unmask_replace_prob=unmask_replace_prob, tokenizer=tokenizer, max_seq_length=max_seq_length, batch_size=batch_size, ) logger.info("Dataset Creation Done") ################################ ###### 创建模型 ############ ################################ logger.info("Creating Model") model = create_model( num_layers=num_layers, num_heads=num_heads, ff_dim=ff_dim, h_dim=h_dim, dropout=dropout, ) model = model.to(device) logger.info("Model Creation Done") ################################ ###### 创建 Optimizer ####### ################################ logger.info("Creating Optimizer") optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) logger.info("Optimizer Creation Done") ################################ #### Load Model checkpoint ##### ################################ start_step = 1 if load_checkpoint_dir is not None: checkpoint_step, model, optimizer = load_model_checkpoint( load_checkpoint_dir, model, optimizer) start_step = checkpoint_step + 1 ################################ ####### The Training Loop ###### ################################ logger.info( f"Total number of model parameters: {sum([p.numel() for p in model.parameters()]):,d}" ) model.train() losses = [] for step, batch in enumerate(data_iterator, start=start_step): if step >= num_iterations: break optimizer.zero_grad() # Move the tensors to device for key, value in batch.items(): batch[key] = value.to(device) # Forward pass loss = model(**batch) # Backward pass loss.backward() # Optimizer Step optimizer.step() losses.append(loss.item()) if step % log_every == 0: logger.info("Loss: {0:.4f}".format(np.mean(losses))) summary_writer.add_scalar(f"Train/loss", np.mean(losses), step) if step % checkpoint_every == 0: state_dict = { "model": model.state_dict(), "optimizer": optimizer.state_dict(), } # 保存模型及优化器 torch.save(obj=state_dict, f=str(exp_dir / f"checkpoint.iter_{step}.pt")) logger.info("Saved model to {0}".format( (exp_dir / f"checkpoint.iter_{step}.pt"))) # Save the last checkpoint if not saved yet if step % checkpoint_every != 0: state_dict = { "model": model.state_dict(), "optimizer": optimizer.state_dict(), } torch.save(obj=state_dict, f=str(exp_dir / f"checkpoint.iter_{step}.pt")) logger.info("Saved model to {0}".format( (exp_dir / f"checkpoint.iter_{step}.pt"))) return exp_dir if __name__ == "__main__": torch.manual_seed(42) np.random.seed(0) random.seed(0) fire.Fire(train) ================================================ FILE: ai-framework/deepspeed/hello_bert/train_bert_ds.py ================================================ import datetime import json import pathlib import re import string from functools import partial from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, TypeVar, Union import random import datasets import fire import loguru import numpy as np import pytz import sh import torch import torch.nn as nn from torch.utils.data import DataLoader, Dataset from torch.utils.tensorboard import SummaryWriter from transformers import AutoTokenizer, PreTrainedTokenizer, PreTrainedTokenizerFast from transformers.models.roberta import RobertaConfig, RobertaModel from transformers.models.roberta.modeling_roberta import ( RobertaLMHead, RobertaPreTrainedModel, ) logger = loguru.logger ###################################################################### ############### Dataset Creation Related Functions ################### ###################################################################### TokenizerType = Union[PreTrainedTokenizer, PreTrainedTokenizerFast] def collate_function(batch: List[Tuple[List[int], List[int]]], pad_token_id: int) -> Dict[str, torch.Tensor]: """Collect a list of masked token indices, and labels, and batch them, padding to max length in the batch. """ max_length = max(len(token_ids) for token_ids, _ in batch) padded_token_ids = [ token_ids + [pad_token_id for _ in range(0, max_length - len(token_ids))] for token_ids, _ in batch ] padded_labels = [ labels + [pad_token_id for _ in range(0, max_length - len(labels))] for _, labels in batch ] src_tokens = torch.LongTensor(padded_token_ids) tgt_tokens = torch.LongTensor(padded_labels) attention_mask = src_tokens.ne(pad_token_id).type_as(src_tokens) return { "src_tokens": src_tokens, "tgt_tokens": tgt_tokens, "attention_mask": attention_mask, } def masking_function( text: str, tokenizer: TokenizerType, mask_prob: float, random_replace_prob: float, unmask_replace_prob: float, max_length: int, ) -> Tuple[List[int], List[int]]: """Given a text string, randomly mask wordpieces for Bert MLM training. Args: text (str): The input text tokenizer (TokenizerType): The tokenizer for tokenization mask_prob (float): What fraction of tokens to mask random_replace_prob (float): Of the masked tokens, how many should be replaced with random tokens (improves performance) unmask_replace_prob (float): Of the masked tokens, how many should be replaced with the original token (improves performance) max_length (int): The maximum sequence length to consider. Note that for Bert style models, this is a function of the number of positional embeddings you learn Returns: Tuple[List[int], List[int]]: The masked token ids (based on the tokenizer passed), and the output labels (padded with `tokenizer.pad_token_id`) """ # Note: By default, encode does add the BOS and EOS token # Disabling that behaviour to make this more clear tokenized_ids = ([tokenizer.bos_token_id] + tokenizer.encode(text, add_special_tokens=False, truncation=True, max_length=max_length - 2) + [tokenizer.eos_token_id]) seq_len = len(tokenized_ids) tokenized_ids = np.array(tokenized_ids) subword_mask = np.full(len(tokenized_ids), False) # Masking the BOS and EOS token leads to slightly worse performance low = 1 high = len(subword_mask) - 1 mask_choices = np.arange(low, high) num_subwords_to_mask = max( int((mask_prob * (high - low)) + np.random.rand()), 1) subword_mask[np.random.choice(mask_choices, num_subwords_to_mask, replace=False)] = True # Create the labels first labels = np.full(seq_len, tokenizer.pad_token_id) labels[subword_mask] = tokenized_ids[subword_mask] tokenized_ids[subword_mask] = tokenizer.mask_token_id # Now of the masked tokens, choose how many to replace with random and how many to unmask rand_or_unmask_prob = random_replace_prob + unmask_replace_prob if rand_or_unmask_prob > 0: rand_or_unmask = subword_mask & (np.random.rand(len(tokenized_ids)) < rand_or_unmask_prob) if random_replace_prob == 0: unmask = rand_or_unmask rand_mask = None elif unmask_replace_prob == 0: unmask = None rand_mask = rand_or_unmask else: unmask_prob = unmask_replace_prob / rand_or_unmask_prob decision = np.random.rand(len(tokenized_ids)) < unmask_prob unmask = rand_or_unmask & decision rand_mask = rand_or_unmask & (~decision) if unmask is not None: tokenized_ids[unmask] = labels[unmask] if rand_mask is not None: weights = np.ones(tokenizer.vocab_size) weights[tokenizer.all_special_ids] = 0 probs = weights / weights.sum() num_rand = rand_mask.sum() tokenized_ids[rand_mask] = np.random.choice(tokenizer.vocab_size, num_rand, p=probs) return tokenized_ids.tolist(), labels.tolist() class WikiTextMLMDataset(Dataset): """A [Map style dataset](https://pytorch.org/docs/stable/data.html) for iterating over the wikitext dataset. Note that this assumes the dataset can fit in memory. For larger datasets you'd want to shard them and use an iterable dataset (eg: see [Infinibatch](https://github.com/microsoft/infinibatch)) Args: Dataset (datasets.arrow_dataset.Dataset): The wikitext dataset masking_function (Callable[[str], Tuple[List[int], List[int]]]) The masking function. To generate one training instance, the masking function is applied to the `text` of a dataset record """ def __init__( self, dataset: datasets.arrow_dataset.Dataset, masking_function: Callable[[str], Tuple[List[int], List[int]]], ) -> None: self.dataset = dataset self.masking_function = masking_function def __len__(self) -> int: return len(self.dataset) def __getitem__(self, idx: int) -> Tuple[List[int], List[int]]: tokens, labels = self.masking_function(self.dataset[idx]["text"]) return (tokens, labels) T = TypeVar("T") class InfiniteIterator(object): def __init__(self, iterable: Iterable[T]) -> None: self._iterable = iterable self._iterator = iter(self._iterable) def __iter__(self): return self def __next__(self) -> T: next_item = None try: next_item = next(self._iterator) except StopIteration: self._iterator = iter(self._iterable) next_item = next(self._iterator) return next_item def create_data_iterator( mask_prob: float, random_replace_prob: float, unmask_replace_prob: float, batch_size: int, max_seq_length: int = 512, tokenizer: str = "roberta-base", ) -> InfiniteIterator: """Create the dataloader. Args: mask_prob (float): Fraction of tokens to mask random_replace_prob (float): Fraction of masked tokens to replace with random token unmask_replace_prob (float): Fraction of masked tokens to replace with the actual token batch_size (int): The batch size of the generated tensors max_seq_length (int, optional): The maximum sequence length for the MLM task. Defaults to 512. tokenizer (str, optional): The tokenizer to use. Defaults to "roberta-base". Returns: InfiniteIterator: The torch DataLoader, wrapped in an InfiniteIterator class, to be able to continuously generate samples """ #wikitext_dataset = datasets.load_dataset("wikitext", wikitext_dataset = datasets.load_dataset("/home/guodong.li/code/wikitext.py", "wikitext-2-v1", split="train") wikitext_dataset = wikitext_dataset.filter( lambda record: record["text"] != "").map( lambda record: {"text": record["text"].rstrip("\n")}) #tokenizer = AutoTokenizer.from_pretrained(tokenizer) tokenizer = AutoTokenizer.from_pretrained("/home/guodong.li/model/roberta-base") masking_function_partial = partial( masking_function, tokenizer=tokenizer, mask_prob=mask_prob, random_replace_prob=random_replace_prob, unmask_replace_prob=unmask_replace_prob, max_length=max_seq_length, ) dataset = WikiTextMLMDataset(wikitext_dataset, masking_function_partial) collate_fn_partial = partial(collate_function, pad_token_id=tokenizer.pad_token_id) dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True, collate_fn=collate_fn_partial) return InfiniteIterator(dataloader) ###################################################################### ############### Model Creation Related Functions ##################### ###################################################################### class RobertaLMHeadWithMaskedPredict(RobertaLMHead): def __init__(self, config: RobertaConfig, embedding_weight: Optional[torch.Tensor] = None) -> None: super(RobertaLMHeadWithMaskedPredict, self).__init__(config) if embedding_weight is not None: self.decoder.weight = embedding_weight def forward( # pylint: disable=arguments-differ self, features: torch.Tensor, masked_token_indices: Optional[torch.Tensor] = None, **kwargs, ) -> torch.Tensor: """The current `transformers` library does not provide support for masked_token_indices. This function provides the support, by running the final forward pass only for the masked indices. This saves memory Args: features (torch.Tensor): The features to select from. Shape (batch, seq_len, h_dim) masked_token_indices (torch.Tensor, optional): The indices of masked tokens for index select. Defaults to None. Shape: (num_masked_tokens,) Returns: torch.Tensor: The index selected features. Shape (num_masked_tokens, h_dim) """ if masked_token_indices is not None: features = torch.index_select( features.view(-1, features.shape[-1]), 0, masked_token_indices) return super().forward(features) class RobertaMLMModel(RobertaPreTrainedModel): def __init__(self, config: RobertaConfig, encoder: RobertaModel) -> None: super().__init__(config) self.encoder = encoder self.lm_head = RobertaLMHeadWithMaskedPredict( config, self.encoder.embeddings.word_embeddings.weight) self.lm_head.apply(self._init_weights) def forward( self, src_tokens: torch.Tensor, attention_mask: torch.Tensor, tgt_tokens: torch.Tensor, ) -> torch.Tensor: """The forward pass for the MLM task Args: src_tokens (torch.Tensor): The masked token indices. Shape: (batch, seq_len) attention_mask (torch.Tensor): The attention mask, since the batches are padded to the largest sequence. Shape: (batch, seq_len) tgt_tokens (torch.Tensor): The output tokens (padded with `config.pad_token_id`) Returns: torch.Tensor: The MLM loss """ # shape: (batch, seq_len, h_dim) sequence_output, *_ = self.encoder(input_ids=src_tokens, attention_mask=attention_mask, return_dict=False) pad_token_id = self.config.pad_token_id # (labels have also been padded with pad_token_id) # filter out all masked labels # shape: (num_masked_tokens,) masked_token_indexes = torch.nonzero( (tgt_tokens != pad_token_id).view(-1)).view(-1) # shape: (num_masked_tokens, vocab_size) prediction_scores = self.lm_head(sequence_output, masked_token_indexes) # shape: (num_masked_tokens,) target = torch.index_select(tgt_tokens.view(-1), 0, masked_token_indexes) loss_fct = nn.CrossEntropyLoss(ignore_index=-1) masked_lm_loss = loss_fct( prediction_scores.view(-1, self.config.vocab_size), target) return masked_lm_loss def create_model(num_layers: int, num_heads: int, ff_dim: int, h_dim: int, dropout: float) -> RobertaMLMModel: """Create a Bert model with the specified `num_heads`, `ff_dim`, `h_dim` and `dropout` Args: num_layers (int): The number of layers num_heads (int): The number of attention heads ff_dim (int): The intermediate hidden size of the feed forward block of the transformer h_dim (int): The hidden dim of the intermediate representations of the transformer dropout (float): The value of dropout to be used. Note that we apply the same dropout to both the attention layers and the FF layers Returns: RobertaMLMModel: A Roberta model for MLM task """ roberta_config_dict = { "attention_probs_dropout_prob": dropout, "bos_token_id": 0, "eos_token_id": 2, "hidden_act": "gelu", "hidden_dropout_prob": dropout, "hidden_size": h_dim, "initializer_range": 0.02, "intermediate_size": ff_dim, "layer_norm_eps": 1e-05, "max_position_embeddings": 514, "model_type": "roberta", "num_attention_heads": num_heads, "num_hidden_layers": num_layers, "pad_token_id": 1, "type_vocab_size": 1, "vocab_size": 50265, } roberta_config = RobertaConfig.from_dict(roberta_config_dict) roberta_encoder = RobertaModel(roberta_config) roberta_model = RobertaMLMModel(roberta_config, roberta_encoder) return roberta_model ###################################################################### ########### Experiment Management Related Functions ################## ###################################################################### def get_unique_identifier(length: int = 8) -> str: """Create a unique identifier by choosing `length` random characters from list of ascii characters and numbers """ alphabet = string.ascii_lowercase + string.digits uuid = "".join(alphabet[ix] for ix in np.random.choice(len(alphabet), length)) return uuid def create_experiment_dir(checkpoint_dir: pathlib.Path, all_arguments: Dict[str, Any]) -> pathlib.Path: """Create an experiment directory and save all arguments in it. Additionally, also store the githash and gitdiff. Finally create a directory for `Tensorboard` logs. The structure would look something like checkpoint_dir `-experiment-name |- hparams.json |- githash.log |- gitdiff.log `- tb_dir/ Args: checkpoint_dir (pathlib.Path): The base checkpoint directory all_arguments (Dict[str, Any]): The arguments to save Returns: pathlib.Path: The experiment directory """ # experiment name follows the following convention # {exp_type}.{YYYY}.{MM}.{DD}.{HH}.{MM}.{SS}.{uuid} current_time = datetime.datetime.now(pytz.timezone("US/Pacific")) expname = "bert_pretrain.{0}.{1}.{2}.{3}.{4}.{5}.{6}".format( current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second, get_unique_identifier(), ) exp_dir = checkpoint_dir / expname exp_dir.mkdir(exist_ok=False) hparams_file = exp_dir / "hparams.json" with hparams_file.open("w") as handle: json.dump(obj=all_arguments, fp=handle, indent=2) # Save the git hash try: gitlog = sh.git.log("-1", format="%H", _tty_out=False, _fg=False) with (exp_dir / "githash.log").open("w") as handle: handle.write(gitlog.stdout.decode("utf-8")) except sh.ErrorReturnCode_128: logger.info("Seems like the code is not running from" " within a git repo, so hash will" " not be stored. However, it" " is strongly advised to use" " version control.") # And the git diff try: gitdiff = sh.git.diff(_fg=False, _tty_out=False) with (exp_dir / "gitdiff.log").open("w") as handle: handle.write(gitdiff.stdout.decode("utf-8")) except sh.ErrorReturnCode_129: logger.info("Seems like the code is not running from" " within a git repo, so diff will" " not be stored. However, it" " is strongly advised to use" " version control.") # Finally create the Tensorboard Dir tb_dir = exp_dir / "tb_dir" tb_dir.mkdir() return exp_dir ###################################################################### ################ Checkpoint Related Functions ######################## ###################################################################### def load_model_checkpoint( load_checkpoint_dir: pathlib.Path, model: torch.nn.Module, optimizer: torch.optim.Optimizer, ) -> Tuple[int, torch.nn.Module, torch.optim.Optimizer]: """Loads the optimizer state dict and model state dict from the load_checkpoint_dir into the passed model and optimizer. Searches for the most recent checkpoint to load from Args: load_checkpoint_dir (pathlib.Path): The base checkpoint directory to load from model (torch.nn.Module): The model to load the checkpoint weights into optimizer (torch.optim.Optimizer): The optimizer to load the checkpoint weigths into Returns: Tuple[int, torch.nn.Module, torch.optim.Optimizer]: The checkpoint step, model with state_dict loaded and optimizer with state_dict loaded """ logger.info( f"Loading model and optimizer checkpoint from {load_checkpoint_dir}") checkpoint_files = list( filter( lambda path: re.search(r"iter_(?P\d+)\.pt", path.name) is not None, load_checkpoint_dir.glob("*.pt"), )) assert len(checkpoint_files) > 0, "No checkpoints found in directory" checkpoint_files = sorted( checkpoint_files, key=lambda path: int( re.search(r"iter_(?P\d+)\.pt", path.name).group("iter_no") ), ) latest_checkpoint_path = checkpoint_files[-1] checkpoint_step = int( re.search(r"iter_(?P\d+)\.pt", latest_checkpoint_path.name).group("iter_no")) state_dict = torch.load(latest_checkpoint_path) model.load_state_dict(state_dict["model"], strict=True) optimizer.load_state_dict(state_dict["optimizer"]) logger.info( f"Loading model and optimizer checkpoints done. Loaded from {latest_checkpoint_path}" ) return checkpoint_step, model, optimizer ###################################################################### ######################## Driver Functions ############################ ###################################################################### def train( checkpoint_dir: str = None, load_checkpoint_dir: str = None, # Dataset Parameters mask_prob: float = 0.15, random_replace_prob: float = 0.1, unmask_replace_prob: float = 0.1, max_seq_length: int = 512, tokenizer: str = "roberta-base", # Model Parameters num_layers: int = 6, num_heads: int = 8, ff_dim: int = 512, h_dim: int = 256, dropout: float = 0.1, # Training Parameters batch_size: int = 8, num_iterations: int = 10000, checkpoint_every: int = 1000, log_every: int = 10, local_rank: int = -1, ) -> pathlib.Path: """Trains a [Bert style](https://arxiv.org/pdf/1810.04805.pdf) (transformer encoder only) model for MLM Task Args: checkpoint_dir (str): The base experiment directory to save experiments to mask_prob (float, optional): The fraction of tokens to mask. Defaults to 0.15. random_replace_prob (float, optional): The fraction of masked tokens to replace with random token. Defaults to 0.1. unmask_replace_prob (float, optional): The fraction of masked tokens to leave unchanged. Defaults to 0.1. max_seq_length (int, optional): The maximum sequence length of the examples. Defaults to 512. tokenizer (str, optional): The tokenizer to use. Defaults to "roberta-base". num_layers (int, optional): The number of layers in the Bert model. Defaults to 6. num_heads (int, optional): Number of attention heads to use. Defaults to 8. ff_dim (int, optional): Size of the intermediate dimension in the FF layer. Defaults to 512. h_dim (int, optional): Size of intermediate representations. Defaults to 256. dropout (float, optional): Amout of Dropout to use. Defaults to 0.1. batch_size (int, optional): The minibatch size. Defaults to 8. num_iterations (int, optional): Total number of iterations to run the model for. Defaults to 10000. checkpoint_every (int, optional): Save checkpoint after these many steps. ..note :: You want this to be frequent enough that you can resume training in case it crashes, but not so much that you fill up your entire storage ! Defaults to 1000. log_every (int, optional): Print logs after these many steps. Defaults to 10. local_rank (int, optional): Which GPU to run on (-1 for CPU). Defaults to -1. Returns: pathlib.Path: The final experiment directory """ device = (torch.device("cuda", local_rank) if (local_rank > -1) and torch.cuda.is_available() else torch.device("cpu")) ################################ ###### Create Exp. Dir ######### ################################ if checkpoint_dir is None and load_checkpoint_dir is None: logger.error("Need to specify one of checkpoint_dir" " or load_checkpoint_dir") return if checkpoint_dir is not None and load_checkpoint_dir is not None: logger.error("Cannot specify both checkpoint_dir" " and load_checkpoint_dir") return if checkpoint_dir: logger.info("Creating Experiment Directory") checkpoint_dir = pathlib.Path(checkpoint_dir) checkpoint_dir.mkdir(exist_ok=True) all_arguments = { # Dataset Params "mask_prob": mask_prob, "random_replace_prob": random_replace_prob, "unmask_replace_prob": unmask_replace_prob, "max_seq_length": max_seq_length, "tokenizer": tokenizer, # Model Params "num_layers": num_layers, "num_heads": num_heads, "ff_dim": ff_dim, "h_dim": h_dim, "dropout": dropout, # Training Params "batch_size": batch_size, "num_iterations": num_iterations, "checkpoint_every": checkpoint_every, } exp_dir = create_experiment_dir(checkpoint_dir, all_arguments) logger.info(f"Experiment Directory created at {exp_dir}") else: logger.info("Loading from Experiment Directory") load_checkpoint_dir = pathlib.Path(load_checkpoint_dir) assert load_checkpoint_dir.exists() with (load_checkpoint_dir / "hparams.json").open("r") as handle: hparams = json.load(handle) # Set the hparams # Dataset Params mask_prob = hparams.get("mask_prob", mask_prob) tokenizer = hparams.get("tokenizer", tokenizer) random_replace_prob = hparams.get("random_replace_prob", random_replace_prob) unmask_replace_prob = hparams.get("unmask_replace_prob", unmask_replace_prob) max_seq_length = hparams.get("max_seq_length", max_seq_length) # Model Params ff_dim = hparams.get("ff_dim", ff_dim) h_dim = hparams.get("h_dim", h_dim) dropout = hparams.get("dropout", dropout) num_layers = hparams.get("num_layers", num_layers) num_heads = hparams.get("num_heads", num_heads) # Training Params batch_size = hparams.get("batch_size", batch_size) _num_iterations = hparams.get("num_iterations", num_iterations) num_iterations = max(num_iterations, _num_iterations) checkpoint_every = hparams.get("checkpoint_every", checkpoint_every) exp_dir = load_checkpoint_dir # Tensorboard writer tb_dir = exp_dir / "tb_dir" assert tb_dir.exists() summary_writer = SummaryWriter(log_dir=tb_dir) ################################ ###### Create Datasets ######### ################################ logger.info("Creating Datasets") data_iterator = create_data_iterator( mask_prob=mask_prob, random_replace_prob=random_replace_prob, unmask_replace_prob=unmask_replace_prob, tokenizer=tokenizer, max_seq_length=max_seq_length, batch_size=batch_size, ) logger.info("Dataset Creation Done") ################################ ###### Create Model ############ ################################ logger.info("Creating Model") model = create_model( num_layers=num_layers, num_heads=num_heads, ff_dim=ff_dim, h_dim=h_dim, dropout=dropout, ) model = model.to(device) logger.info("Model Creation Done") ################################ ###### Create Optimizer ####### ################################ logger.info("Creating Optimizer") optimizer = torch.optim.Adam(model.parameters(), lr=1e-4) logger.info("Optimizer Creation Done") ################################ #### Load Model checkpoint ##### ################################ start_step = 1 if load_checkpoint_dir is not None: checkpoint_step, model, optimizer = load_model_checkpoint( load_checkpoint_dir, model, optimizer) start_step = checkpoint_step + 1 ################################ ####### The Training Loop ###### ################################ logger.info( f"Total number of model parameters: {sum([p.numel() for p in model.parameters()]):,d}" ) model.train() losses = [] for step, batch in enumerate(data_iterator, start=start_step): if step >= num_iterations: break optimizer.zero_grad() # Move the tensors to device for key, value in batch.items(): batch[key] = value.to(device) # Forward pass loss = model(**batch) # Backward pass loss.backward() # Optimizer Step optimizer.step() losses.append(loss.item()) if step % log_every == 0: logger.info("Loss: {0:.4f}".format(np.mean(losses))) summary_writer.add_scalar(f"Train/loss", np.mean(losses), step) if step % checkpoint_every == 0: state_dict = { "model": model.state_dict(), "optimizer": optimizer.state_dict(), } torch.save(obj=state_dict, f=str(exp_dir / f"checkpoint.iter_{step}.pt")) logger.info("Saved model to {0}".format( (exp_dir / f"checkpoint.iter_{step}.pt"))) # Save the last checkpoint if not saved yet if step % checkpoint_every != 0: state_dict = { "model": model.state_dict(), "optimizer": optimizer.state_dict(), } torch.save(obj=state_dict, f=str(exp_dir / f"checkpoint.iter_{step}.pt")) logger.info("Saved model to {0}".format( (exp_dir / f"checkpoint.iter_{step}.pt"))) return exp_dir if __name__ == "__main__": torch.manual_seed(42) np.random.seed(0) random.seed(0) fire.Fire(train) (llama-venv-py310-cu117) [guodong.li@ai-app-2-46 HelloDeepSpeed]$ cat train_bert_ds.py """ Modified version of train_bert.py that adds DeepSpeed """ import os import datetime import json import pathlib import re import string from functools import partial from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, TypeVar, Union import random import datasets import fire import logging import loguru import numpy as np import pytz import sh import torch import torch.nn as nn import deepspeed from torch.utils.data import DataLoader, Dataset from torch.utils.tensorboard import SummaryWriter from transformers import AutoTokenizer, PreTrainedTokenizer, PreTrainedTokenizerFast from transformers.models.roberta import RobertaConfig, RobertaModel from transformers.models.roberta.modeling_roberta import ( RobertaLMHead, RobertaPreTrainedModel, ) def is_rank_0() -> bool: return int(os.environ.get("RANK", "0")) == 0 ###################################################################### ####################### Logging Functions ############################ ###################################################################### logger = loguru.logger def log_dist(message: str, ranks: List[int] = [], level: int = logging.INFO) -> None: """Log messages for specified ranks only""" my_rank = int(os.environ.get("RANK", "0")) if my_rank in ranks: if level == logging.INFO: logger.info(f'[Rank {my_rank}] {message}') if level == logging.ERROR: logger.error(f'[Rank {my_rank}] {message}') if level == logging.DEBUG: logger.debug(f'[Rank {my_rank}] {message}') ###################################################################### ############### Dataset Creation Related Functions ################### ###################################################################### TokenizerType = Union[PreTrainedTokenizer, PreTrainedTokenizerFast] def collate_function(batch: List[Tuple[List[int], List[int]]], pad_token_id: int) -> Dict[str, torch.Tensor]: """Collect a list of masked token indices, and labels, and batch them, padding to max length in the batch. """ max_length = max(len(token_ids) for token_ids, _ in batch) padded_token_ids = [ token_ids + [pad_token_id for _ in range(0, max_length - len(token_ids))] for token_ids, _ in batch ] padded_labels = [ labels + [pad_token_id for _ in range(0, max_length - len(labels))] for _, labels in batch ] src_tokens = torch.LongTensor(padded_token_ids) tgt_tokens = torch.LongTensor(padded_labels) attention_mask = src_tokens.ne(pad_token_id).type_as(src_tokens) return { "src_tokens": src_tokens, "tgt_tokens": tgt_tokens, "attention_mask": attention_mask, } def masking_function( text: str, tokenizer: TokenizerType, mask_prob: float, random_replace_prob: float, unmask_replace_prob: float, max_length: int, ) -> Tuple[List[int], List[int]]: """Given a text string, randomly mask wordpieces for Bert MLM training. Args: text (str): The input text tokenizer (TokenizerType): The tokenizer for tokenization mask_prob (float): What fraction of tokens to mask random_replace_prob (float): Of the masked tokens, how many should be replaced with random tokens (improves performance) unmask_replace_prob (float): Of the masked tokens, how many should be replaced with the original token (improves performance) max_length (int): The maximum sequence length to consider. Note that for Bert style models, this is a function of the number of positional embeddings you learn Returns: Tuple[List[int], List[int]]: The masked token ids (based on the tokenizer passed), and the output labels (padded with `tokenizer.pad_token_id`) """ # Note: By default, encode does add the BOS and EOS token # Disabling that behaviour to make this more clear tokenized_ids = ([tokenizer.bos_token_id] + tokenizer.encode(text, add_special_tokens=False, truncation=True, max_length=max_length - 2) + [tokenizer.eos_token_id]) seq_len = len(tokenized_ids) tokenized_ids = np.array(tokenized_ids) subword_mask = np.full(len(tokenized_ids), False) # Masking the BOS and EOS token leads to slightly worse performance low = 1 high = len(subword_mask) - 1 mask_choices = np.arange(low, high) num_subwords_to_mask = max( int((mask_prob * (high - low)) + np.random.rand()), 1) subword_mask[np.random.choice(mask_choices, num_subwords_to_mask, replace=False)] = True # Create the labels first labels = np.full(seq_len, tokenizer.pad_token_id) labels[subword_mask] = tokenized_ids[subword_mask] tokenized_ids[subword_mask] = tokenizer.mask_token_id # Now of the masked tokens, choose how many to replace with random and how many to unmask rand_or_unmask_prob = random_replace_prob + unmask_replace_prob if rand_or_unmask_prob > 0: rand_or_unmask = subword_mask & (np.random.rand(len(tokenized_ids)) < rand_or_unmask_prob) if random_replace_prob == 0: unmask = rand_or_unmask rand_mask = None elif unmask_replace_prob == 0: unmask = None rand_mask = rand_or_unmask else: unmask_prob = unmask_replace_prob / rand_or_unmask_prob decision = np.random.rand(len(tokenized_ids)) < unmask_prob unmask = rand_or_unmask & decision rand_mask = rand_or_unmask & (~decision) if unmask is not None: tokenized_ids[unmask] = labels[unmask] if rand_mask is not None: weights = np.ones(tokenizer.vocab_size) weights[tokenizer.all_special_ids] = 0 probs = weights / weights.sum() num_rand = rand_mask.sum() tokenized_ids[rand_mask] = np.random.choice(tokenizer.vocab_size, num_rand, p=probs) return tokenized_ids.tolist(), labels.tolist() class WikiTextMLMDataset(Dataset): """A [Map style dataset](https://pytorch.org/docs/stable/data.html) for iterating over the wikitext dataset. Note that this assumes the dataset can fit in memory. For larger datasets you'd want to shard them and use an iterable dataset (eg: see [Infinibatch](https://github.com/microsoft/infinibatch)) Args: Dataset (datasets.arrow_dataset.Dataset): The wikitext dataset masking_function (Callable[[str], Tuple[List[int], List[int]]]) The masking function. To generate one training instance, the masking function is applied to the `text` of a dataset record """ def __init__( self, dataset: datasets.arrow_dataset.Dataset, masking_function: Callable[[str], Tuple[List[int], List[int]]], ) -> None: self.dataset = dataset self.masking_function = masking_function def __len__(self) -> int: return len(self.dataset) def __getitem__(self, idx: int) -> Tuple[List[int], List[int]]: tokens, labels = self.masking_function(self.dataset[idx]["text"]) return (tokens, labels) T = TypeVar("T") class InfiniteIterator(object): def __init__(self, iterable: Iterable[T]) -> None: self._iterable = iterable self._iterator = iter(self._iterable) def __iter__(self): return self def __next__(self) -> T: next_item = None try: next_item = next(self._iterator) except StopIteration: self._iterator = iter(self._iterable) next_item = next(self._iterator) return next_item def create_data_iterator( mask_prob: float, random_replace_prob: float, unmask_replace_prob: float, batch_size: int, max_seq_length: int = 512, tokenizer: str = "roberta-base", ) -> InfiniteIterator: """Create the dataloader. Args: mask_prob (float): Fraction of tokens to mask random_replace_prob (float): Fraction of masked tokens to replace with random token unmask_replace_prob (float): Fraction of masked tokens to replace with the actual token batch_size (int): The batch size of the generated tensors max_seq_length (int, optional): The maximum sequence length for the MLM task. Defaults to 512. tokenizer (str, optional): The tokenizer to use. Defaults to "roberta-base". Returns: InfiniteIterator: The torch DataLoader, wrapped in an InfiniteIterator class, to be able to continuously generate samples """ #wikitext_dataset = datasets.load_dataset("wikitext", wikitext_dataset = datasets.load_dataset("/home/guodong.li/code/wikitext.py", "wikitext-2-v1", split="train") wikitext_dataset = wikitext_dataset.filter( lambda record: record["text"] != "").map( lambda record: {"text": record["text"].rstrip("\n")}) #tokenizer = AutoTokenizer.from_pretrained(tokenizer) tokenizer = AutoTokenizer.from_pretrained("/home/guodong.li/model/roberta-base") masking_function_partial = partial( masking_function, tokenizer=tokenizer, mask_prob=mask_prob, random_replace_prob=random_replace_prob, unmask_replace_prob=unmask_replace_prob, max_length=max_seq_length, ) dataset = WikiTextMLMDataset(wikitext_dataset, masking_function_partial) collate_fn_partial = partial(collate_function, pad_token_id=tokenizer.pad_token_id) dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True, collate_fn=collate_fn_partial) return InfiniteIterator(dataloader) ###################################################################### ############### Model Creation Related Functions ##################### ###################################################################### class RobertaLMHeadWithMaskedPredict(RobertaLMHead): def __init__(self, config: RobertaConfig, embedding_weight: Optional[torch.Tensor] = None) -> None: super(RobertaLMHeadWithMaskedPredict, self).__init__(config) if embedding_weight is not None: self.decoder.weight = embedding_weight def forward( # pylint: disable=arguments-differ self, features: torch.Tensor, masked_token_indices: Optional[torch.Tensor] = None, **kwargs, ) -> torch.Tensor: """The current `transformers` library does not provide support for masked_token_indices. This function provides the support, by running the final forward pass only for the masked indices. This saves memory Args: features (torch.Tensor): The features to select from. Shape (batch, seq_len, h_dim) masked_token_indices (torch.Tensor, optional): The indices of masked tokens for index select. Defaults to None. Shape: (num_masked_tokens,) Returns: torch.Tensor: The index selected features. Shape (num_masked_tokens, h_dim) """ if masked_token_indices is not None: features = torch.index_select( features.view(-1, features.shape[-1]), 0, masked_token_indices) return super().forward(features) class RobertaMLMModel(RobertaPreTrainedModel): def __init__(self, config: RobertaConfig, encoder: RobertaModel) -> None: super().__init__(config) self.encoder = encoder self.lm_head = RobertaLMHeadWithMaskedPredict( config, self.encoder.embeddings.word_embeddings.weight) self.lm_head.apply(self._init_weights) def forward( self, src_tokens: torch.Tensor, attention_mask: torch.Tensor, tgt_tokens: torch.Tensor, ) -> torch.Tensor: """The forward pass for the MLM task Args: src_tokens (torch.Tensor): The masked token indices. Shape: (batch, seq_len) attention_mask (torch.Tensor): The attention mask, since the batches are padded to the largest sequence. Shape: (batch, seq_len) tgt_tokens (torch.Tensor): The output tokens (padded with `config.pad_token_id`) Returns: torch.Tensor: The MLM loss """ # shape: (batch, seq_len, h_dim) sequence_output, *_ = self.encoder(input_ids=src_tokens, attention_mask=attention_mask, return_dict=False) pad_token_id = self.config.pad_token_id # (labels have also been padded with pad_token_id) # filter out all masked labels # shape: (num_masked_tokens,) masked_token_indexes = torch.nonzero( (tgt_tokens != pad_token_id).view(-1)).view(-1) # shape: (num_masked_tokens, vocab_size) prediction_scores = self.lm_head(sequence_output, masked_token_indexes) # shape: (num_masked_tokens,) target = torch.index_select(tgt_tokens.view(-1), 0, masked_token_indexes) loss_fct = nn.CrossEntropyLoss(ignore_index=-1) masked_lm_loss = loss_fct( prediction_scores.view(-1, self.config.vocab_size), target) return masked_lm_loss def create_model(num_layers: int, num_heads: int, ff_dim: int, h_dim: int, dropout: float) -> RobertaMLMModel: """Create a Bert model with the specified `num_heads`, `ff_dim`, `h_dim` and `dropout` Args: num_layers (int): The number of layers num_heads (int): The number of attention heads ff_dim (int): The intermediate hidden size of the feed forward block of the transformer h_dim (int): The hidden dim of the intermediate representations of the transformer dropout (float): The value of dropout to be used. Note that we apply the same dropout to both the attention layers and the FF layers Returns: RobertaMLMModel: A Roberta model for MLM task """ roberta_config_dict = { "attention_probs_dropout_prob": dropout, "bos_token_id": 0, "eos_token_id": 2, "hidden_act": "gelu", "hidden_dropout_prob": dropout, "hidden_size": h_dim, "initializer_range": 0.02, "intermediate_size": ff_dim, "layer_norm_eps": 1e-05, "max_position_embeddings": 514, "model_type": "roberta", "num_attention_heads": num_heads, "num_hidden_layers": num_layers, "pad_token_id": 1, "type_vocab_size": 1, "vocab_size": 50265, } roberta_config = RobertaConfig.from_dict(roberta_config_dict) roberta_encoder = RobertaModel(roberta_config) roberta_model = RobertaMLMModel(roberta_config, roberta_encoder) return roberta_model ###################################################################### ########### Experiment Management Related Functions ################## ###################################################################### def get_unique_identifier(length: int = 8) -> str: """Create a unique identifier by choosing `length` random characters from list of ascii characters and numbers """ alphabet = string.ascii_lowercase + string.digits uuid = "".join(alphabet[ix] for ix in np.random.choice(len(alphabet), length)) return uuid def create_experiment_dir(checkpoint_dir: pathlib.Path, all_arguments: Dict[str, Any]) -> pathlib.Path: """Create an experiment directory and save all arguments in it. Additionally, also store the githash and gitdiff. Finally create a directory for `Tensorboard` logs. The structure would look something like checkpoint_dir `-experiment-name |- hparams.json |- githash.log |- gitdiff.log `- tb_dir/ Args: checkpoint_dir (pathlib.Path): The base checkpoint directory all_arguments (Dict[str, Any]): The arguments to save Returns: pathlib.Path: The experiment directory """ # experiment name follows the following convention # {exp_type}.{YYYY}.{MM}.{DD}.{HH}.{MM}.{SS}.{uuid} current_time = datetime.datetime.now(pytz.timezone("US/Pacific")) expname = "bert_pretrain.{0}.{1}.{2}.{3}.{4}.{5}.{6}".format( current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second, get_unique_identifier(), ) exp_dir = checkpoint_dir / expname if not is_rank_0(): return exp_dir exp_dir.mkdir(exist_ok=False) hparams_file = exp_dir / "hparams.json" with hparams_file.open("w") as handle: json.dump(obj=all_arguments, fp=handle, indent=2) # Save the git hash try: gitlog = sh.git.log("-1", format="%H", _tty_out=False, _fg=False) with (exp_dir / "githash.log").open("w") as handle: handle.write(gitlog.stdout.decode("utf-8")) except sh.ErrorReturnCode_128: log_dist( "Seems like the code is not running from" " within a git repo, so hash will" " not be stored. However, it" " is strongly advised to use" " version control.", ranks=[0], level=logging.INFO) # And the git diff try: gitdiff = sh.git.diff(_fg=False, _tty_out=False) with (exp_dir / "gitdiff.log").open("w") as handle: handle.write(gitdiff.stdout.decode("utf-8")) except sh.ErrorReturnCode_129: log_dist( "Seems like the code is not running from" " within a git repo, so diff will" " not be stored. However, it" " is strongly advised to use" " version control.", ranks=[0], level=logging.INFO) # Finally create the Tensorboard Dir tb_dir = exp_dir / "tb_dir" tb_dir.mkdir(exist_ok=False) return exp_dir ###################################################################### ################ Checkpoint Related Functions ######################## ###################################################################### def load_model_checkpoint( load_checkpoint_dir: pathlib.Path, model: torch.nn.Module, optimizer: torch.optim.Optimizer, ) -> Tuple[int, torch.nn.Module, torch.optim.Optimizer]: """Loads the optimizer state dict and model state dict from the load_checkpoint_dir into the passed model and optimizer. Searches for the most recent checkpoint to load from Args: load_checkpoint_dir (pathlib.Path): The base checkpoint directory to load from model (torch.nn.Module): The model to load the checkpoint weights into optimizer (torch.optim.Optimizer): The optimizer to load the checkpoint weigths into Returns: Tuple[int, torch.nn.Module, torch.optim.Optimizer]: The checkpoint step, model with state_dict loaded and optimizer with state_dict loaded """ log_dist( f"Loading model and optimizer checkpoint from {load_checkpoint_dir}", ranks=[0], level=logging.INFO) checkpoint_files = list( filter( lambda path: re.search(r"iter_(?P\d+)\.pt", path.name) is not None, load_checkpoint_dir.glob("*.pt"), )) assert len(checkpoint_files) > 0, "No checkpoints found in directory" checkpoint_files = sorted( checkpoint_files, key=lambda path: int( re.search(r"iter_(?P\d+)\.pt", path.name).group("iter_no") ), ) latest_checkpoint_path = checkpoint_files[-1] checkpoint_step = int( re.search(r"iter_(?P\d+)\.pt", latest_checkpoint_path.name).group("iter_no")) state_dict = torch.load(latest_checkpoint_path) model.load_state_dict(state_dict["model"], strict=True) optimizer.load_state_dict(state_dict["optimizer"]) log_dist( f"Loading model and optimizer checkpoints done. Loaded from {latest_checkpoint_path}", ranks=[0], level=logging.INFO) return checkpoint_step, model, optimizer ###################################################################### ######################## Driver Functions ############################ ###################################################################### def train( checkpoint_dir: str = None, load_checkpoint_dir: str = None, # Dataset Parameters mask_prob: float = 0.15, random_replace_prob: float = 0.1, unmask_replace_prob: float = 0.1, max_seq_length: int = 512, tokenizer: str = "roberta-base", # Model Parameters num_layers: int = 6, num_heads: int = 8, ff_dim: int = 512, h_dim: int = 256, dropout: float = 0.1, # Training Parameters batch_size: int = 8, num_iterations: int = 10000, checkpoint_every: int = 1000, log_every: int = 10, local_rank: int = -1, ) -> pathlib.Path: """Trains a [Bert style](https://arxiv.org/pdf/1810.04805.pdf) (transformer encoder only) model for MLM Task Args: checkpoint_dir (str): The base experiment directory to save experiments to mask_prob (float, optional): The fraction of tokens to mask. Defaults to 0.15. random_replace_prob (float, optional): The fraction of masked tokens to replace with random token. Defaults to 0.1. unmask_replace_prob (float, optional): The fraction of masked tokens to leave unchanged. Defaults to 0.1. max_seq_length (int, optional): The maximum sequence length of the examples. Defaults to 512. tokenizer (str, optional): The tokenizer to use. Defaults to "roberta-base". num_layers (int, optional): The number of layers in the Bert model. Defaults to 6. num_heads (int, optional): Number of attention heads to use. Defaults to 8. ff_dim (int, optional): Size of the intermediate dimension in the FF layer. Defaults to 512. h_dim (int, optional): Size of intermediate representations. Defaults to 256. dropout (float, optional): Amout of Dropout to use. Defaults to 0.1. batch_size (int, optional): The minibatch size. Defaults to 8. num_iterations (int, optional): Total number of iterations to run the model for. Defaults to 10000. checkpoint_every (int, optional): Save checkpoint after these many steps. ..note :: You want this to be frequent enough that you can resume training in case it crashes, but not so much that you fill up your entire storage ! Defaults to 1000. log_every (int, optional): Print logs after these many steps. Defaults to 10. local_rank (int, optional): Which GPU to run on (-1 for CPU). Defaults to -1. Returns: pathlib.Path: The final experiment directory """ device = (torch.device("cuda", local_rank) if (local_rank > -1) and torch.cuda.is_available() else torch.device("cpu")) ################################ ###### Create Exp. Dir ######### ################################ if checkpoint_dir is None and load_checkpoint_dir is None: log_dist( "Need to specify one of checkpoint_dir" " or load_checkpoint_dir", ranks=[0], level=logging.ERROR) return if checkpoint_dir is not None and load_checkpoint_dir is not None: log_dist( "Cannot specify both checkpoint_dir" " and load_checkpoint_dir", ranks=[0], level=logging.ERROR) return if checkpoint_dir: log_dist("Creating Experiment Directory", ranks=[0], level=logging.INFO) checkpoint_dir = pathlib.Path(checkpoint_dir) checkpoint_dir.mkdir(exist_ok=True) all_arguments = { # Dataset Params "mask_prob": mask_prob, "random_replace_prob": random_replace_prob, "unmask_replace_prob": unmask_replace_prob, "max_seq_length": max_seq_length, "tokenizer": tokenizer, # Model Params "num_layers": num_layers, "num_heads": num_heads, "ff_dim": ff_dim, "h_dim": h_dim, "dropout": dropout, # Training Params "batch_size": batch_size, "num_iterations": num_iterations, "checkpoint_every": checkpoint_every, } exp_dir = create_experiment_dir(checkpoint_dir, all_arguments) log_dist(f"Experiment Directory created at {exp_dir}", ranks=[0], level=logging.INFO) else: log_dist("Loading from Experiment Directory", ranks=[0], level=logging.INFO) load_checkpoint_dir = pathlib.Path(load_checkpoint_dir) assert load_checkpoint_dir.exists() with (load_checkpoint_dir / "hparams.json").open("r") as handle: hparams = json.load(handle) # Set the hparams # Dataset Params mask_prob = hparams.get("mask_prob", mask_prob) tokenizer = hparams.get("tokenizer", tokenizer) random_replace_prob = hparams.get("random_replace_prob", random_replace_prob) unmask_replace_prob = hparams.get("unmask_replace_prob", unmask_replace_prob) max_seq_length = hparams.get("max_seq_length", max_seq_length) # Model Params ff_dim = hparams.get("ff_dim", ff_dim) h_dim = hparams.get("h_dim", h_dim) dropout = hparams.get("dropout", dropout) num_layers = hparams.get("num_layers", num_layers) num_heads = hparams.get("num_heads", num_heads) # Training Params batch_size = hparams.get("batch_size", batch_size) _num_iterations = hparams.get("num_iterations", num_iterations) num_iterations = max(num_iterations, _num_iterations) checkpoint_every = hparams.get("checkpoint_every", checkpoint_every) exp_dir = load_checkpoint_dir # Tensorboard writer if is_rank_0(): tb_dir = exp_dir / "tb_dir" assert tb_dir.exists() summary_writer = SummaryWriter(log_dir=tb_dir) ################################ ###### Create Datasets ######### ################################ log_dist("Creating Datasets", ranks=[0], level=logging.INFO) data_iterator = create_data_iterator( mask_prob=mask_prob, random_replace_prob=random_replace_prob, unmask_replace_prob=unmask_replace_prob, tokenizer=tokenizer, max_seq_length=max_seq_length, batch_size=batch_size, ) log_dist("Dataset Creation Done", ranks=[0], level=logging.INFO) ################################ ###### Create Model ############ ################################ log_dist("Creating Model", ranks=[0], level=logging.INFO) model = create_model( num_layers=num_layers, num_heads=num_heads, ff_dim=ff_dim, h_dim=h_dim, dropout=dropout, ) log_dist("Model Creation Done", ranks=[0], level=logging.INFO) ################################ ###### DeepSpeed engine ######## ################################ log_dist("Creating DeepSpeed engine", ranks=[0], level=logging.INFO) ds_config = { "train_micro_batch_size_per_gpu": batch_size, "optimizer": { "type": "Adam", "params": { "lr": 1e-4 } }, "fp16": { "enabled": True }, "zero_optimization": { "stage": 1, "offload_optimizer": { "device": "cpu" } } } log_dist("-----------------------", ranks=[0], level=logging.INFO) log_dist(str(ds_config), ranks=[0], level=logging.INFO) model, _, _, _ = deepspeed.initialize(model=model, model_parameters=model.parameters(), config=ds_config) log_dist("DeepSpeed engine created", ranks=[0], level=logging.INFO) ################################ #### Load Model checkpoint ##### ################################ start_step = 1 if load_checkpoint_dir is not None: _, client_state = model.load_checkpoint(load_dir=load_checkpoint_dir) checkpoint_step = client_state['checkpoint_step'] start_step = checkpoint_step + 1 ################################ ####### The Training Loop ###### ################################ log_dist( f"Total number of model parameters: {sum([p.numel() for p in model.parameters()]):,d}", ranks=[0], level=logging.INFO) model.train() losses = [] for step, batch in enumerate(data_iterator, start=start_step): if step >= num_iterations: break # Move the tensors to device for key, value in batch.items(): batch[key] = value.to(device) # Forward pass loss = model(**batch) # Backward pass model.backward(loss) # Optimizer Step model.step() losses.append(loss.item()) if step % log_every == 0: log_dist("Loss: {0:.4f}".format(np.mean(losses)), ranks=[0], level=logging.INFO) if is_rank_0(): summary_writer.add_scalar(f"Train/loss", np.mean(losses), step) if step % checkpoint_every == 0: model.save_checkpoint(save_dir=exp_dir, client_state={'checkpoint_step': step}) log_dist("Saved model to {0}".format(exp_dir), ranks=[0], level=logging.INFO) # Save the last checkpoint if not saved yet if step % checkpoint_every != 0: model.save_checkpoint(save_dir=exp_dir, client_state={'checkpoint_step': step}) log_dist("Saved model to {0}".format(exp_dir), ranks=[0], level=logging.INFO) return exp_dir if __name__ == "__main__": torch.manual_seed(42) np.random.seed(0) random.seed(0) fire.Fire(train) ================================================ FILE: ai-framework/deepspeed/training/pipeline_parallelism/README.md ================================================ ``` deepspeed --include localhost:3,4,5,6 train.py --deepspeed_config=ds_config.json -p 2 --steps=200 ``` ================================================ FILE: ai-framework/dlrover.md ================================================ https://github.com/intelligent-machine-learning/dlrover DLRover: An Automatic Distributed Deep Learning System ================================================ FILE: ai-framework/huggingface-accelerate/README.md ================================================ - https://huggingface.co/docs/accelerate/package_reference/cli ``` accelerate env # accelerate config default [arguments] accelerate config update --config_file ``` ## huggingface 加载大模型 - 使用HuggingFace的Accelerate库加载和运行超大模型: https://zhuanlan.zhihu.com/p/605640431 ``` import torch from transformers import AutoModelForCausalLM ​ checkpoint = "facebook/opt-13b" model = AutoModelForCausalLM.from_pretrained( checkpoint, device_map="auto", offload_folder="offload", offload_state_dict = True, torch_dtype=torch.float16 ) ``` ================================================ FILE: ai-framework/huggingface-peft/README.md ================================================ ================================================ FILE: ai-framework/huggingface-transformers/API.md ================================================ - https://github.com/huggingface/transformers/blob/main/src/transformers/training_args.py - TrainingArguments ## 保存模型 - model.save_pretrained('./path_to_model/') - model.config.to_json_file("config.json") ## RoPE rope_scaling ``` Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value accordingly. Expected contents: `rope_type` (`str`): The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope', 'llama3'], with 'default' being the original RoPE implementation. `factor` (`float`, *optional*): Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In most scaling types, a `factor` of x will enable the model to handle sequences of length x * original maximum pre-trained length. ``` ================================================ FILE: ai-framework/huggingface-transformers/FSDP.md ================================================ - https://pytorch.org/docs/stable/fsdp.html - https://huggingface.co/docs/accelerate/usage_guides/fsdp transformers - https://zhuanlan.zhihu.com/p/648094197 - https://github.com/ifromeast/LLMTrainer/blob/main/02_fsdp/fsdp.json accelerate - 使用 PyTorch FSDP 微调 Llama 2 70B:https://zhuanlan.zhihu.com/p/671742753 - https://huggingface.co/docs/transformers/v4.41.0/en/fsdp#fsdp-configuration - https://huggingface.co/docs/transformers/v4.41.0/en/main_classes/trainer#transformers.TrainingArguments - https://github.com/pacman100/LLM-Workshop/blob/main/chat_assistant/sft/training/configs/fsdp_config.yaml ================================================ FILE: ai-framework/huggingface-transformers/README.md ================================================ ## 量化 transformers 已经集成并 原生 支持了 bitsandbytes 和 auto-gptq 这两个量化库。 - https://huggingface.co/docs/transformers/v4.35.2/en/main_classes/quantization - 更多量化方案:https://github.com/huggingface/optimum ### GPTQ量化 ``` from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfig model_id = "facebook/opt-125m" quantization_config = GPTQConfig( bits=4, group_size=128, dataset="c4", desc_act=False, ) tokenizer = AutoTokenizer.from_pretrained(model_id) quant_model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=quantization_config, device_map='auto') ``` ### LLM.int8()-bitsandbytes ``` from transformers import AutoTokenizer, AutoModelForCausalLM model_name = "bigscience/bloomz-7b1-mt" tokenizer = AutoTokenizer.from_pretrained(model_name) model_8bit = AutoModelForCausalLM.from_pretrained(model_name, device_map="auto", load_in_8bit=True) ``` ``` from transformers import BitsAndBytesConfig double_quant_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_use_double_quant=True, ) model_double_quant = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=double_quant_config) ``` ================================================ FILE: ai-framework/huggingface-trl/README.md ================================================ ================================================ FILE: ai-framework/jax/README.md ================================================ Jax 是我看过那么多项目中,唯一一个让我看了之后觉得「哇,软件还可以这么写,一切都很有道理」的项目。我觉得 Google 还是吸取了很多 Tensorflow 的经验,把它们都用到了 Jax 里面。 ================================================ FILE: ai-framework/jax/reference.md ================================================ - https://jax.readthedocs.io/en/latest/notebooks/neural_network_with_tfds_data.html - https://github.com/google/jax ================================================ FILE: ai-framework/llama-cpp/README.md ================================================ - https://github.com/abetlen/llama-cpp-python?tab=readme-ov-file - https://github.com/ggerganov/llama.cpp GGUF量化格式 - ctransformers、llama.cpp ``` CMAKE_ARGS="-DGGML_METAL=on" pip install -U llama-cpp-python --no-cache-dir pip install 'llama-cpp-python[server]' ``` ``` export MODEL=/Users/liguodong/model/qwen2/qwen2-0_5b-instruct-q2_k.gguf python3 -m llama_cpp.server --model $MODEL --n_gpu_layers 1 ``` ## 量化 - https://github.com/ggerganov/llama.cpp/pull/1684 值得阅读 - 模型量化技术概述及 GGUF/GGML 文件格式解析,了解 Q4_0、Q4_1、Q4_K 和 Q4_K_M 的区别:https://blog.csdn.net/weixin_42426841/article/details/142706753 - LLM量化大比拼:哪种 LLM 量化最适合你?:https://zhuanlan.zhihu.com/p/8936080946 - llama.cpp中的量化方法简介:https://zhuanlan.zhihu.com/p/12729759086 - https://github.com/ggerganov/llama.cpp/blob/3e693197724c31d53a9b69018c2f1bd0b93ebab2/examples/quantize/quantize.cpp#L18 Q4_K_M, Q5_K_S and Q5_K_M are considered "recommended". 量化方法: ``` static const std::vector QUANT_OPTIONS = { { "Q4_0", LLAMA_FTYPE_MOSTLY_Q4_0, " 4.34G, +0.4685 ppl @ Llama-3-8B", }, { "Q4_1", LLAMA_FTYPE_MOSTLY_Q4_1, " 4.78G, +0.4511 ppl @ Llama-3-8B", }, { "Q5_0", LLAMA_FTYPE_MOSTLY_Q5_0, " 5.21G, +0.1316 ppl @ Llama-3-8B", }, { "Q5_1", LLAMA_FTYPE_MOSTLY_Q5_1, " 5.65G, +0.1062 ppl @ Llama-3-8B", }, { "IQ2_XXS", LLAMA_FTYPE_MOSTLY_IQ2_XXS, " 2.06 bpw quantization", }, { "IQ2_XS", LLAMA_FTYPE_MOSTLY_IQ2_XS, " 2.31 bpw quantization", }, { "IQ2_S", LLAMA_FTYPE_MOSTLY_IQ2_S, " 2.5 bpw quantization", }, { "IQ2_M", LLAMA_FTYPE_MOSTLY_IQ2_M, " 2.7 bpw quantization", }, { "IQ1_S", LLAMA_FTYPE_MOSTLY_IQ1_S, " 1.56 bpw quantization", }, { "IQ1_M", LLAMA_FTYPE_MOSTLY_IQ1_M, " 1.75 bpw quantization", }, { "TQ1_0", LLAMA_FTYPE_MOSTLY_TQ1_0, " 1.69 bpw ternarization", }, { "TQ2_0", LLAMA_FTYPE_MOSTLY_TQ2_0, " 2.06 bpw ternarization", }, { "Q2_K", LLAMA_FTYPE_MOSTLY_Q2_K, " 2.96G, +3.5199 ppl @ Llama-3-8B", }, { "Q2_K_S", LLAMA_FTYPE_MOSTLY_Q2_K_S, " 2.96G, +3.1836 ppl @ Llama-3-8B", }, { "IQ3_XXS", LLAMA_FTYPE_MOSTLY_IQ3_XXS, " 3.06 bpw quantization", }, { "IQ3_S", LLAMA_FTYPE_MOSTLY_IQ3_S, " 3.44 bpw quantization", }, { "IQ3_M", LLAMA_FTYPE_MOSTLY_IQ3_M, " 3.66 bpw quantization mix", }, { "Q3_K", LLAMA_FTYPE_MOSTLY_Q3_K_M, "alias for Q3_K_M" }, { "IQ3_XS", LLAMA_FTYPE_MOSTLY_IQ3_XS, " 3.3 bpw quantization", }, { "Q3_K_S", LLAMA_FTYPE_MOSTLY_Q3_K_S, " 3.41G, +1.6321 ppl @ Llama-3-8B", }, { "Q3_K_M", LLAMA_FTYPE_MOSTLY_Q3_K_M, " 3.74G, +0.6569 ppl @ Llama-3-8B", }, { "Q3_K_L", LLAMA_FTYPE_MOSTLY_Q3_K_L, " 4.03G, +0.5562 ppl @ Llama-3-8B", }, { "IQ4_NL", LLAMA_FTYPE_MOSTLY_IQ4_NL, " 4.50 bpw non-linear quantization", }, { "IQ4_XS", LLAMA_FTYPE_MOSTLY_IQ4_XS, " 4.25 bpw non-linear quantization", }, { "Q4_K", LLAMA_FTYPE_MOSTLY_Q4_K_M, "alias for Q4_K_M", }, { "Q4_K_S", LLAMA_FTYPE_MOSTLY_Q4_K_S, " 4.37G, +0.2689 ppl @ Llama-3-8B", }, { "Q4_K_M", LLAMA_FTYPE_MOSTLY_Q4_K_M, " 4.58G, +0.1754 ppl @ Llama-3-8B", }, { "Q5_K", LLAMA_FTYPE_MOSTLY_Q5_K_M, "alias for Q5_K_M", }, { "Q5_K_S", LLAMA_FTYPE_MOSTLY_Q5_K_S, " 5.21G, +0.1049 ppl @ Llama-3-8B", }, { "Q5_K_M", LLAMA_FTYPE_MOSTLY_Q5_K_M, " 5.33G, +0.0569 ppl @ Llama-3-8B", }, { "Q6_K", LLAMA_FTYPE_MOSTLY_Q6_K, " 6.14G, +0.0217 ppl @ Llama-3-8B", }, { "Q8_0", LLAMA_FTYPE_MOSTLY_Q8_0, " 7.96G, +0.0026 ppl @ Llama-3-8B", }, { "F16", LLAMA_FTYPE_MOSTLY_F16, "14.00G, +0.0020 ppl @ Mistral-7B", }, { "BF16", LLAMA_FTYPE_MOSTLY_BF16, "14.00G, -0.0050 ppl @ Mistral-7B", }, { "F32", LLAMA_FTYPE_ALL_F32, "26.00G @ 7B", }, // Note: Ensure COPY comes after F32 to avoid ftype 0 from matching. { "COPY", LLAMA_FTYPE_ALL_F32, "only copy tensors, no quantizing", }, }; ``` ================================================ FILE: ai-framework/megatron-deepspeed/README.md ================================================ ================================================ FILE: ai-framework/megatron-lm/README.md ================================================ ================================================ FILE: ai-framework/mxnet/README.md ================================================ ## 安装 ``` pip install --upgrade mxnet gluonnlp pip install mxnet==1.9.1 gluonnlp==0.10.0 ``` ## docker ``` # GPU Instance docker pull gluonai/gluon-nlp:gpu-latest docker run --gpus all --rm -it -p 8888:8888 -p 8787:8787 -p 8786:8786 --shm-size=2g gluonai/gluon-nlp:gpu-latest # CPU Instance docker pull gluonai/gluon-nlp:cpu-latest docker run --rm -it -p 8888:8888 -p 8787:8787 -p 8786:8786 --shm-size=2g gluonai/gluon-nlp:cpu-latest ``` ``` docker run --gpus all -itd \ --ipc=host \ --network host \ --shm-size=4g \ -v /home/guodong.li/workspace/:/workspace/ \ --name mxnet_dev \ gluonai/gluon-nlp:gpu-latest \ /bin/bash docker exec -it mxnet_dev bash pip uninstall mxnet-cu102 pip install mxnet==1.9.1 gluonnlp==0.10.0 -i http://nexus3.xxx.com/repository/pypi/simple --trusted-host nexus3.xxx.com ``` ================================================ FILE: ai-framework/mxnet/mnist.py ================================================ # pylint: skip-file from __future__ import print_function import argparse import logging logging.basicConfig(level=logging.DEBUG) import numpy as np import mxnet as mx from mxnet import gluon, autograd from mxnet.gluon import nn # Parse CLI arguments parser = argparse.ArgumentParser(description='MXNet Gluon MNIST Example') parser.add_argument('--batch-size', type=int, default=100, help='batch size for training and testing (default: 100)') parser.add_argument('--epochs', type=int, default=10, help='number of epochs to train (default: 10)') parser.add_argument('--lr', type=float, default=0.1, help='learning rate (default: 0.1)') parser.add_argument('--momentum', type=float, default=0.9, help='SGD momentum (default: 0.9)') parser.add_argument('--cuda', action='store_true', default=False, help='Train on GPU with CUDA') parser.add_argument('--log-interval', type=int, default=100, metavar='N', help='how many batches to wait before logging training status') opt = parser.parse_args() # define network net = nn.Sequential() with net.name_scope(): net.add(nn.Dense(128, activation='relu')) net.add(nn.Dense(64, activation='relu')) net.add(nn.Dense(10)) # data def transformer(data, label): data = data.reshape((-1,)).astype(np.float32)/255 return data, label train_data = gluon.data.DataLoader( gluon.data.vision.MNIST('./data', train=True, transform=transformer), batch_size=opt.batch_size, shuffle=True, last_batch='discard') val_data = gluon.data.DataLoader( gluon.data.vision.MNIST('./data', train=False, transform=transformer), batch_size=opt.batch_size, shuffle=False) # train def test(ctx): metric = mx.metric.Accuracy() for data, label in val_data: data = data.as_in_context(ctx) label = label.as_in_context(ctx) output = net(data) metric.update([label], [output]) return metric.get() def train(epochs, ctx): # Collect all parameters from net and its children, then initialize them. net.initialize(mx.init.Xavier(magnitude=2.24), ctx=ctx) # Trainer is for updating parameters with gradient. trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': opt.lr, 'momentum': opt.momentum}) metric = mx.metric.Accuracy() loss = gluon.loss.SoftmaxCrossEntropyLoss() for epoch in range(epochs): # reset data iterator and metric at begining of epoch. metric.reset() for i, (data, label) in enumerate(train_data): # Copy data to ctx if necessary data = data.as_in_context(ctx) label = label.as_in_context(ctx) # Start recording computation graph with record() section. # Recorded graphs can then be differentiated with backward. with autograd.record(): output = net(data) L = loss(output, label) L.backward() # take a gradient step with batch_size equal to data.shape[0] trainer.step(data.shape[0]) # update metric at last. metric.update([label], [output]) if i % opt.log_interval == 0 and i > 0: name, acc = metric.get() print('[Epoch %d Batch %d] Training: %s=%f'%(epoch, i, name, acc)) name, acc = metric.get() print('[Epoch %d] Training: %s=%f'%(epoch, name, acc)) name, val_acc = test(ctx) print('[Epoch %d] Validation: %s=%f'%(epoch, name, val_acc)) net.save_parameters('mnist.params') if __name__ == '__main__': if opt.cuda: ctx = mx.gpu(0) else: ctx = mx.cpu() train(opt.epochs, ctx) ================================================ FILE: ai-framework/mxnet/mxnet_cnn_mnist.py ================================================ from __future__ import print_function import argparse import logging logging.basicConfig(level=logging.INFO) import numpy as np import mxnet as mx from mxnet import gluon, autograd from mxnet.gluon import nn from mxnet.gluon.data.vision import transforms from mxnet import gluon, autograd as ag, nd import os """ python /workspace/code/mxnet_cnn_mnist.py \ --train-dataset-path '/workspace/data/mxnet/' \ --test-dataset-path '/workspace/data/mxnet/' \ --output-path "/workspace/output/mxnet_model" """ import struct import gzip import matplotlib.pyplot as plt from PIL import Image def get_mnist(path='data'): def read_data(label_url, image_url): if not os.path.isdir(path): os.makedirs(path) with gzip.open(label_url) as flbl: struct.unpack(">II", flbl.read(8)) label = np.frombuffer(flbl.read(), dtype=np.int8) with gzip.open(image_url, 'rb') as fimg: _, _, rows, cols = struct.unpack(">IIII", fimg.read(16)) image = np.frombuffer(fimg.read(), dtype=np.uint8).reshape(len(label), rows, cols) image = image.reshape(image.shape[0], 1, 28, 28).astype(np.float32)/255 return (label, image) # changed to mxnet.io for more stable hosting (train_lbl, train_img) = read_data( path+'train-labels-idx1-ubyte.gz', path+'train-images-idx3-ubyte.gz') (test_lbl, test_img) = read_data( path+'t10k-labels-idx1-ubyte.gz', path+'t10k-images-idx3-ubyte.gz') return {'train_data':train_img, 'train_label':train_lbl, 'test_data':test_img, 'test_label':test_lbl} transform = transforms.Compose([ # 将PIL Image或numpy.ndarray转换为tensor,并除255归一化到[0,1]之间 transforms.ToTensor(), # 标准化处理-->转换为标准正太分布,使模型更容易收敛 transforms.Normalize((0.5,),(0.5,)) ]) # define network class NeuralNetwork(gluon.Block): def __init__(self): super(NeuralNetwork, self).__init__() # 定义卷积层,输出特征通道out_channels设置为20,卷积核的大小kernel_size为5,卷积步长stride=1,padding=2 self.conv1 = nn.Conv2D(20, kernel_size=(5,5), strides=(1,1), padding=(2,2), activation='relu') # 定义池化层,池化核的大小kernel_size为2,池化步长为2 self.max_pool1 = nn.MaxPool2D(pool_size=(2,2), strides=(2,2)) # 定义卷积层,输出特征通道out_channels设置为20,卷积核的大小kernel_size为5,卷积步长stride=1,padding=2 self.conv2 = nn.Conv2D(20, kernel_size=5, strides=(1,1), padding=(2,2), activation='relu') # 定义池化层,池化核的大小kernel_size为2,池化步长为2 self.max_pool2 = nn.MaxPool2D(pool_size=(2,2), strides=(2,2)) # 定义一层全连接层,输出维度是10 self.fc = nn.Dense(10) def forward(self, x): x = self.conv1(x) x = self.max_pool1(x) x = self.conv2(x) x = self.max_pool2(x) x = x.reshape((x.shape[0], -1)) x = self.fc(x) return x net = NeuralNetwork() # train def test(ctx, val_data): metric = mx.metric.Accuracy() # 重置 val_data.reset() for batch in val_data: # data = data.as_in_context(ctx) # label = label.as_in_context(ctx) data = gluon.utils.split_and_load(batch.data[0], ctx_list=ctx, batch_axis=0) # Splits train labels into multiple slices along batch_axis # and copy each slice into a context. label = gluon.utils.split_and_load(batch.label[0], ctx_list=ctx, batch_axis=0) outputs = [] for x in data: output = net(x) outputs.append(output) metric.update(label, outputs) return metric.get() train_acc_list = [] val_acc_list = [] def train(args, ctx, train_data, val_data): # Collect all parameters from net and its children, then initialize them. net.initialize(mx.init.Xavier(magnitude=2.24), ctx=ctx) # Trainer is for updating parameters with gradient. trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': args.lr, 'momentum': args.momentum}) metric = mx.metric.Accuracy() loss = gluon.loss.SoftmaxCrossEntropyLoss() for epoch in range(args.epochs): # reset data iterator and metric at begining of epoch. # 每次迭代后需要重置 metric.reset() train_data.reset() # for i, batch in enumerate(train_data): # data = gluon.utils.split_and_load(batch.data[0], ctx_list=ctx, batch_axis=0) # # Splits train labels into multiple slices along batch_axis # # and copy each slice into a context. # label = gluon.utils.split_and_load(batch.label[0], ctx_list=ctx, batch_axis=0) for i, batch in enumerate(train_data): # Copy data to ctx if necessary # data = data.as_in_context(ctx) # label = label.as_in_context(ctx) data = gluon.utils.split_and_load(batch.data[0], ctx_list=ctx, batch_axis=0) # Splits train labels into multiple slices along batch_axis # and copy each slice into a context. label = gluon.utils.split_and_load(batch.label[0], ctx_list=ctx, batch_axis=0) outputs = [] # Start recording computation graph with record() section. # Recorded graphs can then be differentiated with backward. with autograd.record(): for x, y in zip(data, label): z = net(x) L = loss(z, y) L.backward() outputs.append(z) # take a gradient step with batch_size equal to data.shape[0] trainer.step(batch.data[0].shape[0]) # update metric at last. metric.update(label, outputs) if i % args.log_interval == 0 and i > 0: name, acc = metric.get() print('[Epoch %d Batch %d] Training: %s=%f'%(epoch, i, name, acc)) name, acc = metric.get() print('[Epoch %d] Training: %s=%f'%(epoch, name, acc)) name, val_acc = test(ctx, val_data) print('[Epoch %d] Validation: %s=%f'%(epoch, name, val_acc)) train_acc_list.append(acc) val_acc_list.append(val_acc) def plot(train_acc_list, val_acc_list, output_path): fig, ax = plt.subplots() train_freqs = [i for i in range(len(train_acc_list))] val_freqs = [i for i in range(len(val_acc_list))] # 绘制训练损失变化曲线 ax.plot(train_freqs, train_acc_list, color='#e4007f', label=" train/accuracy curve") ax.plot(val_freqs, val_acc_list, color='#fff000', label="val/accuracy curve") # 绘制坐标轴和图例 ax.set_ylabel("accuracy", fontsize='large') ax.set_xlabel("epoch", fontsize='large') ax.set_title("image classification") ax.legend(loc='upper right', fontsize='x-large') plt.savefig(output_path+'/mxnet_cnn_image_classification_accuracy_curve.png') # plt.show() def main(ctx): parser = argparse.ArgumentParser(description='MXNet Gluon MNIST Example') parser.add_argument("--pretrain-model-path", dest="pretrain_model_path", required=False, type=str, default=None, help="预训练模型路径") parser.add_argument("--train-dataset-path", type=str, default="/Users/liguodong/data/mnist", help="训练集路径") parser.add_argument("--test-dataset-path", type=str, default="/Users/liguodong/data/mnist", help="测试集路径") parser.add_argument("--output-path", type=str, default="/Users/liguodong/output/oneflow_model",help="模型输出路径") parser.add_argument('--batch-size', type=int, default=100, help='batch size for training and testing (default: 100)') parser.add_argument('--epochs', type=int, default=10, help='number of epochs to train (default: 10)') parser.add_argument('--lr', type=float, default=0.1, help='learning rate (default: 0.1)') parser.add_argument('--momentum', type=float, default=0.9, help='SGD momentum (default: 0.9)') parser.add_argument('--cuda', action='store_true', default=False, help='Train on GPU with CUDA') parser.add_argument('--log-interval', type=int, default=100, metavar='N', help='how many batches to wait before logging training status') args = parser.parse_args() train_dataset_path = args.train_dataset_path test_dataset_path = args.test_dataset_path output_path = args.output_path pretrain_model_path = args.pretrain_model_path if not os.path.exists(output_path): os.makedirs(output_path) # train_dataset = gluon.data.vision.MNIST(train_dataset_path, train=True) # train_data = gluon.data.DataLoader(train_dataset.transform_first(transform), batch_size=args.batch_size, shuffle=True, last_batch='discard') # test_dataset = gluon.data.vision.MNIST(test_dataset_path, train=False) # val_data = gluon.data.DataLoader(test_dataset.transform_first(transform), batch_size=args.batch_size, shuffle=False) mx.random.seed(42) mnist = get_mnist(path=train_dataset_path) batch_size = 64 train_data = mx.io.NDArrayIter(mnist['train_data'], mnist['train_label'], batch_size, shuffle=True) val_data = mx.io.NDArrayIter(mnist['test_data'], mnist['test_label'], batch_size) train(args, ctx,train_data,val_data) net.save_parameters(output_path+'/mnist.params') plot(train_acc_list, val_acc_list, output_path) if __name__ == '__main__': #ctx = mx.gpu(0) # ctx = mx.cpu() ctx = [mx.cpu()] # ctx = [mx.gpu(4)] # gpus = mx.test_utils.list_gpus() # ctx = [mx.gpu()] if gpus else [mx.cpu(0), mx.cpu(1)] main(ctx) ================================================ FILE: ai-framework/mxnet/mxnet_mlp_mnist.py ================================================ # pylint: skip-file from __future__ import print_function import argparse import logging logging.basicConfig(level=logging.DEBUG) import numpy as np import mxnet as mx from mxnet import gluon, autograd from mxnet.gluon import nn # Parse CLI arguments parser = argparse.ArgumentParser(description='MXNet Gluon MNIST Example') parser.add_argument('--batch-size', type=int, default=100, help='batch size for training and testing (default: 100)') parser.add_argument('--epochs', type=int, default=10, help='number of epochs to train (default: 10)') parser.add_argument('--lr', type=float, default=0.1, help='learning rate (default: 0.1)') parser.add_argument('--momentum', type=float, default=0.9, help='SGD momentum (default: 0.9)') parser.add_argument('--cuda', action='store_true', default=False, help='Train on GPU with CUDA') parser.add_argument('--log-interval', type=int, default=100, metavar='N', help='how many batches to wait before logging training status') opt = parser.parse_args() # define network net = nn.Sequential() with net.name_scope(): net.add(nn.Dense(128, activation='relu')) net.add(nn.Dense(64, activation='relu')) net.add(nn.Dense(10)) # data def transformer(data, label): data = data.reshape((-1,)).astype(np.float32)/255 return data, label train_data = gluon.data.DataLoader( gluon.data.vision.MNIST('/workspace/data/mxnet', train=True, transform=transformer), batch_size=opt.batch_size, shuffle=True, last_batch='discard') val_data = gluon.data.DataLoader( gluon.data.vision.MNIST('/workspace/data/mxnet', train=False, transform=transformer), batch_size=opt.batch_size, shuffle=False) # train def test(ctx): metric = mx.metric.Accuracy() for data, label in val_data: data = data.as_in_context(ctx) label = label.as_in_context(ctx) output = net(data) metric.update([label], [output]) return metric.get() def train(epochs, ctx): # Collect all parameters from net and its children, then initialize them. net.initialize(mx.init.Xavier(magnitude=2.24), ctx=ctx) # Trainer is for updating parameters with gradient. trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': opt.lr, 'momentum': opt.momentum}) metric = mx.metric.Accuracy() loss = gluon.loss.SoftmaxCrossEntropyLoss() for epoch in range(epochs): # reset data iterator and metric at begining of epoch. metric.reset() for i, (data, label) in enumerate(train_data): # Copy data to ctx if necessary data = data.as_in_context(ctx) label = label.as_in_context(ctx) # Start recording computation graph with record() section. # Recorded graphs can then be differentiated with backward. with autograd.record(): output = net(data) L = loss(output, label) L.backward() # take a gradient step with batch_size equal to data.shape[0] trainer.step(data.shape[0]) # update metric at last. metric.update([label], [output]) if i % opt.log_interval == 0 and i > 0: name, acc = metric.get() print('[Epoch %d Batch %d] Training: %s=%f'%(epoch, i, name, acc)) name, acc = metric.get() print('[Epoch %d] Training: %s=%f'%(epoch, name, acc)) name, val_acc = test(ctx) print('[Epoch %d] Validation: %s=%f'%(epoch, name, val_acc)) net.save_parameters('mnist.params') if __name__ == '__main__': if opt.cuda: ctx = mx.gpu(0) else: ctx = mx.cpu() train(opt.epochs, ctx) ================================================ FILE: ai-framework/mxnet/oneflow_cnn_mnist.py ================================================ import oneflow as flow import oneflow.nn as nn from flowvision import transforms from flowvision import datasets import matplotlib.pyplot as plt from PIL import Image import argparse import os """ python /workspace/code/oneflow/oneflow_cnn_mnist.py \ python /workspace/code/oneflow_cnn_mnist.py \ --train-dataset-path "/workspace/data/oneflow" \ --test-dataset-path "/workspace/data/oneflow" \ --output-path "/workspace/output/oneflow_model" """ transform = transforms.Compose([ # 将PIL Image或numpy.ndarray转换为tensor,并除255归一化到[0,1]之间 transforms.ToTensor(), # 标准化处理-->转换为标准正太分布,使模型更容易收敛 transforms.Normalize((0.5,),(0.5,)) ]) BATCH_SIZE=64 # DEVICE = "cpu" # "cuda" if flow.cuda.is_available() else "cpu" DEVICE = "cuda" if flow.cuda.is_available() else "cpu" print("Using {} device".format(DEVICE)) class NeuralNetwork(nn.Module): def __init__(self): super(NeuralNetwork, self).__init__() # 定义卷积层,输出特征通道out_channels设置为20,卷积核的大小kernel_size为5,卷积步长stride=1,padding=2 self.conv1 = nn.Conv2d(in_channels=1, out_channels=20, kernel_size=5, stride=1, padding=2) # 定义池化层,池化核的大小kernel_size为2,池化步长为2 self.max_pool1 = nn.MaxPool2d(kernel_size=2, stride=2) # 定义卷积层,输出特征通道out_channels设置为20,卷积核的大小kernel_size为5,卷积步长stride=1,padding=2 self.conv2 = nn.Conv2d(in_channels=20, out_channels=20, kernel_size=5, stride=1, padding=2) # 定义池化层,池化核的大小kernel_size为2,池化步长为2 self.max_pool2 = nn.MaxPool2d(kernel_size=2, stride=2) # 定义一层全连接层,输出维度是10 self.fc = nn.Linear(in_features=980, out_features=10) self.relu=nn.ReLU() def forward(self, x): x = self.conv1(x) x = self.relu(x) x = self.max_pool1(x) x = self.conv2(x) x = self.relu(x) x = self.max_pool2(x) x = flow.reshape(x, [x.shape[0], -1]) x = self.fc(x) return x loss_list = [] def train(epoch, iter, model, loss_fn, optimizer): size = len(iter.dataset) sum_loss = [] for batch, (x, y) in enumerate(iter): x = x.to(DEVICE) y = y.to(DEVICE) # Compute prediction error pred = model(x) loss = loss_fn(pred, y) # Backpropagation optimizer.zero_grad() loss.backward() optimizer.step() current = batch * BATCH_SIZE sum_loss.append(loss) if batch % 100 == 0: print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]") avg_loss = sum(sum_loss) / len(sum_loss) loss_list.append(float(avg_loss)) print("epoch: ", epoch, f"loss: {avg_loss:>7f}") def test(iter, model, loss_fn): size = len(iter.dataset) num_batches = len(iter) model.eval() test_loss, correct = 0, 0 with flow.no_grad(): for x, y in iter: x = x.to(DEVICE) y = y.to(DEVICE) pred = model(x) test_loss += loss_fn(pred, y) bool_value = (pred.argmax(1).to(dtype=flow.int64)==y) correct += float(bool_value.sum().numpy()) test_loss /= num_batches print("test_loss", test_loss, "num_batches ", num_batches) correct /= size print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}, Avg loss: {test_loss:>8f}") def plot(loss_list, output_path): plt.figure(figsize=(10,5)) freqs = [i for i in range(len(loss_list))] # 绘制训练损失变化曲线 plt.plot(freqs, loss_list, color='#e4007f', label="image classification train/loss curve") # 绘制坐标轴和图例 plt.ylabel("loss", fontsize='large') plt.xlabel("epoch", fontsize='large') plt.legend(loc='upper right', fontsize='x-large') plt.savefig(output_path+'/oneflow_cnn_image_classification_loss_curve.png') # plt.show() def main(): parser = argparse.ArgumentParser(description="PyTorch MNIST Example") parser.add_argument("--pretrain-model-path", dest="pretrain_model_path", required=False, type=str, default=None, help="预训练模型路径") parser.add_argument("--train-dataset-path", type=str, default="/Users/liguodong/data/mnist", help="训练集路径") parser.add_argument("--test-dataset-path", type=str, default="/Users/liguodong/data/mnist", help="测试集路径") parser.add_argument("--output-path", type=str, default="/Users/liguodong/output/oneflow_model",help="模型输出路径") args = parser.parse_args() train_dataset_path = args.train_dataset_path test_dataset_path = args.test_dataset_path output_path = args.output_path pretrain_model_path = args.pretrain_model_path if not os.path.exists(output_path): os.makedirs(output_path) training_data = datasets.MNIST( root=train_dataset_path, train=True, transform=transforms.ToTensor(), download=True, source_url="https://oneflow-public.oss-cn-beijing.aliyuncs.com/datasets/mnist/MNIST/", ) test_data = datasets.MNIST( root=test_dataset_path, train=False, transform=transforms.ToTensor(), download=True, source_url="https://oneflow-public.oss-cn-beijing.aliyuncs.com/datasets/mnist/MNIST/", ) train_dataloader = flow.utils.data.DataLoader( training_data, BATCH_SIZE, shuffle=True ) test_dataloader = flow.utils.data.DataLoader( test_data, BATCH_SIZE, shuffle=False ) for x, y in train_dataloader: print("x.shape:", x.shape) print("y.shape:", y.shape) break model = NeuralNetwork().to(DEVICE) print(model) loss_fn = nn.CrossEntropyLoss().to(DEVICE) optimizer = flow.optim.Adam(model.parameters(), lr=1e-3) # 定义5轮 epoch,每训练完一个 epoch 都使用 test 来评估一下网络的精度 epochs = 10 for t in range(epochs): train(t, train_dataloader, model, loss_fn, optimizer) test(test_dataloader, model, loss_fn) print("Done!") flow.save(model.state_dict(), output_path) plot(loss_list, output_path) if __name__ == "__main__": main() ================================================ FILE: ai-framework/mxnet/oneflow_mlp_mnist.py ================================================ import oneflow as flow import oneflow.nn as nn from flowvision import transforms from flowvision import datasets BATCH_SIZE=64 DEVICE = "cpu" # "cuda" if flow.cuda.is_available() else "cpu" print("Using {} device".format(DEVICE)) training_data = datasets.MNIST( root="/workspace/data/oneflow", train=True, transform=transforms.ToTensor(), download=True, source_url="https://oneflow-public.oss-cn-beijing.aliyuncs.com/datasets/mnist/MNIST/", ) test_data = datasets.MNIST( root="/workspace/data/oneflow", train=False, transform=transforms.ToTensor(), download=True, source_url="https://oneflow-public.oss-cn-beijing.aliyuncs.com/datasets/mnist/MNIST/", ) train_dataloader = flow.utils.data.DataLoader( training_data, BATCH_SIZE, shuffle=True ) test_dataloader = flow.utils.data.DataLoader( test_data, BATCH_SIZE, shuffle=False ) for x, y in train_dataloader: print("x.shape:", x.shape) print("y.shape:", y.shape) break class NeuralNetwork(nn.Module): def __init__(self): super(NeuralNetwork, self).__init__() self.flatten = nn.Flatten() self.linear_relu_stack = nn.Sequential( nn.Linear(28*28, 512), nn.ReLU(), nn.Linear(512, 512), nn.ReLU(), nn.Linear(512, 10), ) def forward(self, x): x = self.flatten(x) logits = self.linear_relu_stack(x) return logits model = NeuralNetwork().to(DEVICE) print(model) loss_fn = nn.CrossEntropyLoss().to(DEVICE) optimizer = flow.optim.SGD(model.parameters(), lr=1e-3) def train(iter, model, loss_fn, optimizer): size = len(iter.dataset) for batch, (x, y) in enumerate(iter): x = x.to(DEVICE) y = y.to(DEVICE) # Compute prediction error pred = model(x) loss = loss_fn(pred, y) # Backpropagation optimizer.zero_grad() loss.backward() optimizer.step() current = batch * BATCH_SIZE if batch % 100 == 0: print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]") def test(iter, model, loss_fn): size = len(iter.dataset) num_batches = len(iter) model.eval() test_loss, correct = 0, 0 with flow.no_grad(): for x, y in iter: x = x.to(DEVICE) y = y.to(DEVICE) pred = model(x) test_loss += loss_fn(pred, y) bool_value = (pred.argmax(1).to(dtype=flow.int64)==y) correct += float(bool_value.sum().numpy()) test_loss /= num_batches print("test_loss", test_loss, "num_batches ", num_batches) correct /= size print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}, Avg loss: {test_loss:>8f}") # 定义5轮 epoch,每训练完一个 epoch 都使用 test 来评估一下网络的精度 epochs = 5 for t in range(epochs): print(f"Epoch {t+1}\n-------------------------------") train(train_dataloader, model, loss_fn, optimizer) test(test_dataloader, model, loss_fn) print("Done!") flow.save(model.state_dict(), "/workspace/output/model") ================================================ FILE: ai-framework/mxnet/reference.md ================================================ - https://github.com/apache/mxnet - https://github.com/dmlc/gluon-nlp/ - https://nlp.gluon.ai/model_zoo/index.html ================================================ FILE: ai-framework/oneflow/README.md ================================================ ## oneflow ``` python3 -m pip install oneflow==0.9.0 python3 -m pip install -f https://release.oneflow.info oneflow==0.9.0+cu117 python3 -m pip install --find-links https://release.oneflow.info oneflow==0.9.0+cu118 docker pull oneflowinc/oneflow:nightly-cuda11.7 ``` ## flowvision ``` pip install flowvision==0.2.2 ``` ``` MNIST FashionMNIST ``` ## 数据 ``` tree /data/hpc/home/guodong.li/data /data/hpc/home/guodong.li/data ├── FashionMNIST │ └── raw ├── MNIST │ └── raw │ ├── t10k-images-idx3-ubyte │ ├── t10k-images-idx3-ubyte.gz │ ├── t10k-labels-idx1-ubyte │ ├── t10k-labels-idx1-ubyte.gz │ ├── train-images-idx3-ubyte │ ├── train-images-idx3-ubyte.gz │ ├── train-labels-idx1-ubyte │ └── train-labels-idx1-ubyte.gz ``` ================================================ FILE: ai-framework/oneflow/oneflow_mlp_mnist.py ================================================ import oneflow as flow import oneflow.nn as nn from flowvision import transforms from flowvision import datasets BATCH_SIZE=64 DEVICE = "cuda" if flow.cuda.is_available() else "cpu" print("Using {} device".format(DEVICE)) training_data = datasets.FashionMNIST( root="/home/guodong.li/data", train=True, transform=transforms.ToTensor(), download=True, source_url="https://oneflow-public.oss-cn-beijing.aliyuncs.com/datasets/mnist/Fashion-MNIST/", ) test_data = datasets.FashionMNIST( root="/home/guodong.li/data", train=False, transform=transforms.ToTensor(), download=True, source_url="https://oneflow-public.oss-cn-beijing.aliyuncs.com/datasets/mnist/Fashion-MNIST/", ) train_dataloader = flow.utils.data.DataLoader( training_data, BATCH_SIZE, shuffle=True ) test_dataloader = flow.utils.data.DataLoader( test_data, BATCH_SIZE, shuffle=False ) for x, y in train_dataloader: print("x.shape:", x.shape) print("y.shape:", y.shape) break class NeuralNetwork(nn.Module): def __init__(self): super(NeuralNetwork, self).__init__() self.flatten = nn.Flatten() self.linear_relu_stack = nn.Sequential( nn.Linear(28*28, 512), nn.ReLU(), nn.Linear(512, 512), nn.ReLU(), nn.Linear(512, 10), ) def forward(self, x): x = self.flatten(x) logits = self.linear_relu_stack(x) return logits model = NeuralNetwork().to(DEVICE) print(model) loss_fn = nn.CrossEntropyLoss().to(DEVICE) optimizer = flow.optim.SGD(model.parameters(), lr=1e-3) def train(iter, model, loss_fn, optimizer): size = len(iter.dataset) for batch, (x, y) in enumerate(iter): x = x.to(DEVICE) y = y.to(DEVICE) # Compute prediction error pred = model(x) loss = loss_fn(pred, y) # Backpropagation optimizer.zero_grad() loss.backward() optimizer.step() current = batch * BATCH_SIZE if batch % 100 == 0: print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]") def test(iter, model, loss_fn): size = len(iter.dataset) num_batches = len(iter) model.eval() test_loss, correct = 0, 0 with flow.no_grad(): for x, y in iter: x = x.to(DEVICE) y = y.to(DEVICE) pred = model(x) test_loss += loss_fn(pred, y) bool_value = (pred.argmax(1).to(dtype=flow.int64)==y) correct += float(bool_value.sum().numpy()) test_loss /= num_batches print("test_loss", test_loss, "num_batches ", num_batches) correct /= size print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}, Avg loss: {test_loss:>8f}") # 定义5轮 epoch,每训练完一个 epoch 都使用 test 来评估一下网络的精度 epochs = 5 for t in range(epochs): print(f"Epoch {t+1}\n-------------------------------") train(train_dataloader, model, loss_fn, optimizer) test(test_dataloader, model, loss_fn) print("Done!") flow.save(model.state_dict(), "./model") ================================================ FILE: ai-framework/oneflow/reference.md ================================================ - https://github.com/Oneflow-Inc/oneflow - https://docs.oneflow.org/master/basics/04_build_network.html - https://docs.oneflow.org/master/basics/01_quickstart.html ================================================ FILE: ai-framework/openai-triton/README.md ================================================ - https://github.com/openai/triton - OpenAI Triton 入门教程: https://zhuanlan.zhihu.com/p/684473453 ================================================ FILE: ai-framework/paddlepaddle/README.md ================================================ - https://www.paddlepaddle.org.cn/install/quick - https://github.com/PaddlePaddle/PaddleNLP ``` python -m pip install paddlepaddle==2.5.2 -i https://pypi.tuna.tsinghua.edu.cn/simple pip install --upgrade paddlenlp ``` ``` docker pull paddlepaddle/paddle:2.5.2-gpu-cuda11.7-cudnn8.4-trt8.4 docker pull paddlepaddle/paddle:2.5.2 ``` ## 可视化 ``` visualdl --logdir ./log ``` ================================================ FILE: ai-framework/paddlepaddle/reference.md ================================================ - paddle支持的硬件:https://www.paddlepaddle.org.cn/install/other - 【推荐】手写数字识别模型:https://www.paddlepaddle.org.cn/tutorials/projectdetail/3473063 - mnist数据下载:https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/vision/datasets/mnist.py - VisualDL可视化:https://www.paddlepaddle.org.cn/documentation/docs/zh/2.2/guides/03_VisualDL/visualdl_cn.html#qidongmianban - Paddle2.0 高层api调用VisualDL可视化:https://aistudio.baidu.com/projectdetail/1321602 - CV任务示例:https://www.paddlepaddle.org.cn/documentation/docs/zh/practices/cv/image_classification.html ================================================ FILE: ai-framework/pai-megatron-patch/README.md ================================================ - https://github.com/alibaba/Pai-Megatron-Patch/ ```bash git clone --recurse-submodules https://github.com/alibaba/Pai-Megatron-Patch.git ``` # 环境准备 ## 数据准备 ```bash mkdir /mnt/workspace/llama2-datasets/ cd /mnt/workspace/llama2-datasets/ wget https://atp-modelzoo.oss-cn-hangzhou.aliyuncs.com/release/datasets/WuDaoCorpus2.0_base_sample.tgz tar zxvf WuDaoCorpus2.0_base_sample.tgz ``` ```bash cd /mnt/workspace/llama2-datasets wget https://atp-modelzoo-wlcb-pai.oss-cn-wulanchabu.aliyuncs.com/release/models/pai-megatron-patch/llama2-datasets/wudao_train.json wget https://atp-modelzoo-wlcb-pai.oss-cn-wulanchabu.aliyuncs.com/release/models/pai-megatron-patch/llama2-datasets/wudao_valid.json mkdir -p /mnt/workspace/llama2-datasets/wudao cd /mnt/workspace/llama2-datasets/wudao wget https://atp-modelzoo-wlcb-pai.oss-cn-wulanchabu.aliyuncs.com/release/models/pai-megatron-patch/llama2-datasets/wudao_llamabpe_text_document.bin wget https://atp-modelzoo-wlcb-pai.oss-cn-wulanchabu.aliyuncs.com/release/models/pai-megatron-patch/llama2-datasets/wudao_llamabpe_text_document.idx ``` ## Huggingface&DeepSpeed训练流程 ## Megatron训练流程 1. 将Huggingface格式的模型文件转换为Megatron格式。 2. 继续预训练模型。 3. 有监督微调模型。 模型训练完成后,您可以离线推理模型来评估模型效果。根据上面不同的训练流程,PAI也提供了对应的HuggingFace&DeepSpeed和MegatronLM两种格式的推理链路。 --- 以Megatron训练流程获得的模型为例 将原始模型目录文件替换成训练获得的模型文件 ```bash cp /mnt/workspace/output_megatron_llama2/checkpoint/dswXXX/iter_XXX/mp_rank_00/model_rng.pt \ /mnt/workspace/llama2-ckpts/llama2-7b-hf-to-megatron-tp1-pp1/release/mp_rank_00/model_rng.pt ``` 如果需要部署使用Huggingface&DeepSpeed训练流程获得的模型文件,您需要将 `/mnt/workspace/output_llama2/checkpoint/dswXXX/checkpointXXX/global_stepXXX/mp_rank_00_model_states.pt`文件拷贝到上一层包含config.json文件的目录中,并重命名为pytorch_model.bin。然后参照上述操作步骤将 `/mnt/workspace/output_llama2/checkpoint/dswXXX/checkpointXXX/`目录下的文件上传到OSS Bucket存储空间。 部署模型服务 BladeLLM是阿里云PAI平台提供的大模型部署框架,支持主流LLM模型结构,并内置模型量化压缩、BladeDISC编译等优化技术用于加速模型推理。 使用BladeLLM的预构建镜像,能够便捷地在PAI-EAS平台部署大模型推理服务。本方案以使用Megatron训练流程获得的模型为例,来说明如何部署模型服务,具体操作步骤如下: ```bash #!/usr/bin/env python import json from websockets.sync.client import connect def hello(): headers = {"Authorization": ""} # URL 也从EAS控制台 - 查看调用信息处获取,把 http:// 换成 ws:// 即可。 url = "ws://xxxxx.cn-wulanchabu.pai-eas.aliyuncs.com/api/predict/" with connect(url, additional_headers=headers) as websocket: prompts = ["What's the capital of Canada?"] for p in prompts: print(f"Prompt : {p}") websocket.send(json.dumps({"prompt": p})) while True: msg = websocket.recv() msg = json.loads(msg) if msg['is_end']: break print(msg['text'], end="", flush=True) print() print("-" * 40) hello() ``` # 模型训练 ## Huggingface&DeepSpeed训练流程 ``` ENV=$1 # 运行环境配置:dsw(单机),dlc(分布式) MODEL_SIZE=$2 # 模型结构参数量级: 7B,13B BATCH_SIZE=$3 # 每卡训练一次迭代样本数: 4, 8 GA_STEPS=$4 # 梯度累积step数 LR=$5 # 学习率: 1e-5, 5e-5 SEQ_LEN=$6 # 序列长度: 2048 PR=$7 # 训练精度: fp16, bf16 ZERO=$8 # DeepSpeed ZERO降显存: 1,2,3 GC=$9 # 是否使用gradient-checkpointing: true, false TRAIN_DATASET_PATH=${10} # 训练集路径, 支持单一文件或者文件夹形式输入 VALID_DATASET_PATH=${11} # 验证集路径, 支持单一文件或者文件夹形式输入 PRETRAIN_CHECKPOINT_PATH=${12} # 预训练模型路径 EPOCH=${13} # 训练epoch数 OUTPUT_BASEPATH=${14} # 训练输出文件路径 ``` ``` cd /mnt/workspace mkdir test_llama2_hf cd test_llama2_hf export WORK_DIR=/mnt/workspace/ wget https://atp-modelzoo-wlcb-pai.oss-cn-wulanchabu.aliyuncs.com/release/models/pai-megatron-patch/llama2-codes/ds_config_TEMPLATE.json wget https://atp-modelzoo-wlcb-pai.oss-cn-wulanchabu.aliyuncs.com/release/models/pai-megatron-patch/llama2-codes/ds_train_huggingface_llama.py wget https://atp-modelzoo-wlcb-pai.oss-cn-wulanchabu.aliyuncs.com/release/models/pai-megatron-patch/llama2-codes/run_ds_train_huggingface_llama.sh bash run_ds_train_huggingface_llama.sh \ dsw \ 7B \ 1 \ 2 \ 1e-5 \ 2048 \ bf16 \ 2 \ true \ ${WORK_DIR}/llama2-datasets/wudao_train.json \ ${WORK_DIR}/llama2-datasets/wudao_valid.json \ ${WORK_DIR}/llama2-ckpts/Llama-2-7b-hf \ 2 \ ${WORK_DIR}/output_llama2 ``` ## Megatron训练流程 ``` cd /mnt/workspace/ mkdir llama2-ckpts cd llama2-ckpts wget https://atp-modelzoo-wlcb-pai.oss-cn-wulanchabu.aliyuncs.com/release/models/pai-megatron-patch/llama2-ckpts/Llama-2-7b-hf.tgz tar -zxf Llama-2-7b-hf.tgz mv Llama-2-7b-hf llama2-7b-hf cd /mnt/workspace/PAI-Megatron-Patch/toolkits/model_checkpoints_convertor/llama sh model_convertor.sh \ /root/Megatron-LM-230512 \ /mnt/workspace/llama2-ckpts/llama2-7b-hf \ /mnt/workspace/llama2-ckpts/llama2-7b-hf-to-megatron-tp1-pp1 \ 1 \ 1 \ llama-7b \ 0 \ false ``` ``` cd /mnt/workspace/ mkdir llama2-ckpts cd llama2-ckpts wget https://atp-modelzoo-wlcb-pai.oss-cn-wulanchabu.aliyuncs.com/release/models/pai-megatron-patch/llama2-ckpts/llama-2-7b-hf-to-megatron-tp1-pp1.tgz tar -zxf llama-2-7b-hf-to-megatron-tp1-pp1.tgz ``` --- 继续预训练 ``` ENV=$1 # 运行环境: dlc, dsw MEGATRON_PATH=$2 # 设置开源Megatron的代码路径 MEGATRON_PATCH_PATH=$3 # 设置Megatron Patch的代码路径 MODEL_SIZE=$4 # 模型结构参数量级:7B, 13B BATCH_SIZE=$5 # 每卡训练一次迭代样本数: 4, 8 GLOBAL_BATCH_SIZE=$6 # 全局batch size LR=$7 # 学习率: 1e-5, 5e-5 MIN_LR=$8 # 最小学习率: 1e-6, 5e-6 SEQ_LEN=$9 # 序列长度 PAD_LEN=${10} # Padding长度:100 EXTRA_VOCAB_SIZE=${11} # 词表扩充大小 PR=${12} # 训练精度: fp16, bf16 TP=${13} # 模型并行度 PP=${14} # 流水并行度 AC=${15} # 激活检查点模式: sel, full DO=${16} # 是否使用Megatron版Zero-1降显存优化器: true, false FL=${17} # 是否使用Flash Attention: true, false SP=${18} # 是否使用序列并行: true, false SAVE_INTERVAL=${19} # 保存ckpt的间隔 DATASET_PATH=${20} # 训练数据集路径 PRETRAIN_CHECKPOINT_PATH=${21} # 预训练模型路径 TRAIN_TOKENS=${22} # 训练token数 WARMUP_TOKENS=${23} # 预热token数 OUTPUT_BASEPATH=${24} # 训练输出文件路径 ``` ``` export WORK_DIR=/mnt/workspace cd ${WORK_DIR}/PAI-Megatron-Patch/examples/llama2 sh run_pretrain_megatron_llama.sh \ dsw \ /root/Megatron-LM-230512 \ ${WORK_DIR}/PAI-Megatron-Patch \ 7B \ 1 \ 8 \ 1e-5 \ 1e-6 \ 2048 \ 80 \ 0 \ fp16 \ 1 \ 1 \ sel \ true \ false \ false \ 100000 \ ${WORK_DIR}/llama2-datasets/wudao/wudao_llamabpe_text_document \ ${WORK_DIR}/llama2-ckpts/llama2-7b-hf-to-megatron-tp1-pp1 \ 100000000 \ 10000 \ ${WORK_DIR}/output_megatron_llama2/ ``` 有监督微调: ``` ENV=$1 # 运行环境: dlc, dsw MEGATRON_PATH=$2 # 设置开源Megatron的代码路径 MEGATRON_PATCH_PATH=$3 # 设置Megatron Patch的代码路径 MODEL_SIZE=$4 # 模型结构参数量级: 7B, 13B BATCH_SIZE=$5 # 每卡训练一次迭代样本数: 4, 8 LR=$6 # 学习率: 1e-5, 5e-5 MIN_LR=$7 # 最小学习率: 1e-6, 5e-6 SEQ_LEN=$8 # 序列长度 PAD_LEN=$9 # Padding长度:100 EXTRA_VOCAB_SIZE=${10} # 词表扩充大小 PR=${11} # 训练精度: fp16, bf16 TP=${12} # 模型并行度 PP=${13} # 流水并行度 AC=${14} # 激活检查点模式: sel, full DO=${15} # 是否使用Megatron版Zero-1降显存优化器: true, false FL=${16} # 是否使用Flash Attention: true, false SP=${17} # 是否使用序列并行: true, false TRAIN_DATASET_PATH=${18} # 训练数据集路径 VALID_DATASET_PATH=${19} # 验证数据集路径 PRETRAIN_CHECKPOINT_PATH=${20} # 预训练模型路径 EPOCH=${21} # 训练迭代轮次 OUTPUT_BASEPATH=${22} # 训练输出文件路径 ``` ``` export WORK_DIR=/mnt/workspace cd ${WORK_DIR}/PAI-Megatron-Patch/examples/llama2 sh run_finetune_megatron_llama.sh \ dsw \ /root/Megatron-LM-230512 \ ${WORK_DIR}/PAI-Megatron-Patch \ 7B \ 1 \ 1e-5 \ 1e-6 \ 2048 \ 80 \ 0 \ bf16 \ 1 \ 1 \ sel \ true \ false \ false \ ${WORK_DIR}/llama2-datasets/wudao_train.json \ ${WORK_DIR}/llama2-datasets/wudao_valid.json \ ${WORK_DIR}/llama2-ckpts/llama2-7b-hf-to-megatron-tp1-pp1 \ 2 \ ${WORK_DIR}/output_megatron_llama2/ ``` # 模型推理 ``` ENV=$1 # 运行环境: dlc, dsw MEGATRON_PATH=$2 # 设置开源Megatron的代码路径 MEGATRON_PATCH_PATH=$3 # 设置Megatron Patch的代码路径 CHECKPOINT_PATH=$4 # 模型微调阶段的模型保存路径 MODEL_SIZE=$5 # 模型结构参数量级: 1.1B, 1.7B, 7.1B TP=$6 # 模型并行度 BS=$7 # 每卡推理一次迭代样本数: 1, 4, 8 SEQ_LEN=$8 # 序列长度: 256, 512, 1024 PAD_LEN=$9 # PAD长度:需要将文本拼接到的长度 EXTRA_VOCAB_SIZE=${10} # 模型转换时增加的token数量 PR=${11} # 推理采用的精度: fp16, bf16 TOP_K=${12} # 采样策略中选择排在前面的候选词数量(0-n): 0, 5, 10, 20 INPUT_SEQ_LEN=${13} # 输入序列长度: 512 OUTPUT_SEQ_LEN=${14} # 输出序列长度: 256 INPUT_FILE=${15} # 需要推理的文本文件: input.txt, 每行为一个样本 OUTPUT_FILE=${16} # 推理输出的文件: output.txt # TOP_K和TOP_P必须有一个为0 TOP_P=${17} # 采样策略中选择排在前面的候选词百分比(0-1): 0, 0.85, 0.95 TEMPERATURE=${18} # 采样策略中温度惩罚: 1-n REPETITION_PENALTY=${19} # 避免生成是产生大量重复,可以设置为(1-2)默认为1.2 ``` ``` export WORK_DIR=/mnt/workspace cd ${WORK_DIR}/PAI-Megatron-Patch/examples/llama2 bash run_text_generation_megatron_llama.sh \ dsw \ /root/Megatron-LM-23.04 \ ${WORK_DIR}/PAI-Megatron-Patch \ ../../../llama2-train \ 7B \ 1 \ 1 \ 1024 \ 1024 \ 0 \ fp16 \ 10 \ 512 \ 512 \ ${WORK_DIR}/pred_input.jsonl \ ${WORK_DIR}/llama2_pred.txt \ 0 \ 1.0 \ 1.2 ``` **参考文档**: - 数据预处理: https://github.com/alibaba/Pai-Megatron-Patch/blob/main/toolkits/pretrain_data_preprocessing/README.md - Huggingface&DeepSpeed训练流程:https://github.com/alibaba/Pai-Megatron-Patch/blob/main/examples/hfds.md - Megatron训练流程:https://github.com/alibaba/Pai-Megatron-Patch/blob/main/examples/megatron.md - Megatron推理:https://github.com/alibaba/Pai-Megatron-Patch/blob/main/megatron_patch/generation/megatron.md ================================================ FILE: ai-framework/pai-torchacc.md ================================================ - https://help.aliyun.com/zh/pai/user-guide/torchacc-overview PAI-TorchAcc(Torch Accelerator)是基于PyTorch的训练加速框架,通过GraphCapture技术将PyTorch动态图转换为静态执行图,然后进一步基于计算图完成分布式优化、计算优化,从而提高PyTorch模型训练的效率,使其更加易于使用。 ================================================ FILE: ai-framework/pytorch/README.md ================================================ ## eager 模式 ## CUDA Graphs - Accelerating PyTorch with CUDA Graphs:https://pytorch.org/blog/accelerating-pytorch-with-cuda-graphs/ ## Dynamo PyTorch 2.0 之 Dynamo: eager 模式的救星,加速背后的真相:https://zhuanlan.zhihu.com/p/592357069 ================================================ FILE: ai-framework/pytorch/install.md ================================================ - 版本:https://pytorch.org/get-started/previous-versions/ - https://download.pytorch.org/whl/torch/ ``` conda install pytorch==2.2.0 torchvision==0.17.0 torchaudio==2.2.0 pytorch-cuda=11.8 -c pytorch -c nvidia conda install pytorch==2.1.0 torchvision==0.16.0 torchaudio==2.1.0 pytorch-cuda=11.8 -c pytorch -c nvidia ``` ``` https://download.pytorch.org/whl/cu121/torch-2.1.0%2Bcu121-cp310-cp310-linux_x86_64.whl#sha256=0d4e8c52a1fcf5ed6cfc256d9a370fcf4360958fc79d0b08a51d55e70914df46 https://download.pytorch.org/whl/cu121/torchvision-0.16.0%2Bcu121-cp310-cp310-linux_x86_64.whl#sha256=e76e78d0ad43636c9884b3084ffaea8a8b61f21129fbfa456a5fe734f0affea9 ``` ## NVIDIA 提供的 docker 镜像 - https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch - nvcr.io/nvidia/pytorch:24.05-py3 cuda 与 gpu 驱动 https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html# ================================================ FILE: ai-framework/pytorch/reference.md ================================================ ================================================ FILE: ai-framework/tensorflow/README.md ================================================ ================================================ FILE: ai-framework/tensorflow/reference.md ================================================ ================================================ FILE: ai-framework/transformer-engine/mnist/README.md ================================================ ``` docker rm -f transformer_engine nvidia-docker run -dti --name transformer_engine \ --restart=always --gpus all --network=host \ --shm-size 5g \ -v /home/h800/h800-work/h800-workspace:/workspace \ -w /workspace \ nvcr.io/nvidia/pytorch:23.05-py3 \ bash sudo docker exec -it transformer_engine bash git clone https://github.com/NVIDIA/TransformerEngine.git ``` ``` > python main.py Train Epoch: 1 [0/60000 (0%)] Loss: 2.310981 Train Epoch: 1 [640/60000 (1%)] Loss: 2.075975 Train Epoch: 1 [1280/60000 (2%)] Loss: 0.894793 Train Epoch: 1 [1920/60000 (3%)] Loss: 0.733659 Train Epoch: 1 [2560/60000 (4%)] Loss: 0.607289 Train Epoch: 1 [3200/60000 (5%)] Loss: 0.512597 Train Epoch: 1 [3840/60000 (6%)] Loss: 0.467567 Train Epoch: 1 [4480/60000 (7%)] Loss: 0.453665 Train Epoch: 1 [5120/60000 (9%)] Loss: 0.358288 Train Epoch: 1 [5760/60000 (10%)] Loss: 0.286079 Train Epoch: 1 [6400/60000 (11%)] Loss: 0.506863 Train Epoch: 1 [7040/60000 (12%)] Loss: 0.457581 Train Epoch: 1 [7680/60000 (13%)] Loss: 0.174460 Train Epoch: 1 [8320/60000 (14%)] Loss: 0.207888 Train Epoch: 1 [8960/60000 (15%)] Loss: 0.109221 Train Epoch: 1 [9600/60000 (16%)] Loss: 0.115240 Train Epoch: 1 [10240/60000 (17%)] Loss: 0.376108 Train Epoch: 1 [10880/60000 (18%)] Loss: 0.190710 Train Epoch: 1 [11520/60000 (19%)] Loss: 0.135155 Train Epoch: 1 [12160/60000 (20%)] Loss: 0.128043 Train Epoch: 1 [12800/60000 (21%)] Loss: 0.128150 Train Epoch: 1 [13440/60000 (22%)] Loss: 0.288093 Train Epoch: 1 [14080/60000 (23%)] Loss: 0.319398 Train Epoch: 1 [14720/60000 (25%)] Loss: 0.110766 Train Epoch: 1 [15360/60000 (26%)] Loss: 0.141596 Train Epoch: 1 [16000/60000 (27%)] Loss: 0.274476 Train Epoch: 1 [16640/60000 (28%)] Loss: 0.196867 Train Epoch: 1 [17280/60000 (29%)] Loss: 0.320345 Train Epoch: 1 [17920/60000 (30%)] Loss: 0.281575 Train Epoch: 1 [18560/60000 (31%)] Loss: 0.142241 Train Epoch: 1 [19200/60000 (32%)] Loss: 0.175851 Train Epoch: 1 [19840/60000 (33%)] Loss: 0.110049 Train Epoch: 1 [20480/60000 (34%)] Loss: 0.219275 Train Epoch: 1 [21120/60000 (35%)] Loss: 0.058848 Train Epoch: 1 [21760/60000 (36%)] Loss: 0.281849 Train Epoch: 1 [22400/60000 (37%)] Loss: 0.029589 Train Epoch: 1 [23040/60000 (38%)] Loss: 0.067243 Train Epoch: 1 [23680/60000 (39%)] Loss: 0.063093 Train Epoch: 1 [24320/60000 (41%)] Loss: 0.430286 Train Epoch: 1 [24960/60000 (42%)] Loss: 0.076447 Train Epoch: 1 [25600/60000 (43%)] Loss: 0.059815 Train Epoch: 1 [26240/60000 (44%)] Loss: 0.453320 Train Epoch: 1 [26880/60000 (45%)] Loss: 0.354056 Train Epoch: 1 [27520/60000 (46%)] Loss: 0.109220 Train Epoch: 1 [28160/60000 (47%)] Loss: 0.359484 Train Epoch: 1 [28800/60000 (48%)] Loss: 0.148566 Train Epoch: 1 [29440/60000 (49%)] Loss: 0.105767 Train Epoch: 1 [30080/60000 (50%)] Loss: 0.099680 Train Epoch: 1 [30720/60000 (51%)] Loss: 0.024636 Train Epoch: 1 [31360/60000 (52%)] Loss: 0.023627 Train Epoch: 1 [32000/60000 (53%)] Loss: 0.117661 Train Epoch: 1 [32640/60000 (54%)] Loss: 0.140753 Train Epoch: 1 [33280/60000 (55%)] Loss: 0.062557 Train Epoch: 1 [33920/60000 (57%)] Loss: 0.127518 Train Epoch: 1 [34560/60000 (58%)] Loss: 0.148100 Train Epoch: 1 [35200/60000 (59%)] Loss: 0.116498 Train Epoch: 1 [35840/60000 (60%)] Loss: 0.190453 Train Epoch: 1 [36480/60000 (61%)] Loss: 0.095069 Train Epoch: 1 [37120/60000 (62%)] Loss: 0.100426 Train Epoch: 1 [37760/60000 (63%)] Loss: 0.067289 Train Epoch: 1 [38400/60000 (64%)] Loss: 0.075233 Train Epoch: 1 [39040/60000 (65%)] Loss: 0.132019 Train Epoch: 1 [39680/60000 (66%)] Loss: 0.153820 Train Epoch: 1 [40320/60000 (67%)] Loss: 0.121976 Train Epoch: 1 [40960/60000 (68%)] Loss: 0.029021 Train Epoch: 1 [41600/60000 (69%)] Loss: 0.038629 Train Epoch: 1 [42240/60000 (70%)] Loss: 0.144574 Train Epoch: 1 [42880/60000 (71%)] Loss: 0.121906 Train Epoch: 1 [43520/60000 (72%)] Loss: 0.101441 Train Epoch: 1 [44160/60000 (74%)] Loss: 0.040515 Train Epoch: 1 [44800/60000 (75%)] Loss: 0.147051 Train Epoch: 1 [45440/60000 (76%)] Loss: 0.090034 Train Epoch: 1 [46080/60000 (77%)] Loss: 0.261030 Train Epoch: 1 [46720/60000 (78%)] Loss: 0.115955 Train Epoch: 1 [47360/60000 (79%)] Loss: 0.111859 Train Epoch: 1 [48000/60000 (80%)] Loss: 0.073982 Train Epoch: 1 [48640/60000 (81%)] Loss: 0.237517 Train Epoch: 1 [49280/60000 (82%)] Loss: 0.030576 Train Epoch: 1 [49920/60000 (83%)] Loss: 0.118248 Train Epoch: 1 [50560/60000 (84%)] Loss: 0.092839 Train Epoch: 1 [51200/60000 (85%)] Loss: 0.053416 Train Epoch: 1 [51840/60000 (86%)] Loss: 0.287856 Train Epoch: 1 [52480/60000 (87%)] Loss: 0.120020 Train Epoch: 1 [53120/60000 (88%)] Loss: 0.244491 Train Epoch: 1 [53760/60000 (90%)] Loss: 0.187061 Train Epoch: 1 [54400/60000 (91%)] Loss: 0.045214 Train Epoch: 1 [55040/60000 (92%)] Loss: 0.115131 Train Epoch: 1 [55680/60000 (93%)] Loss: 0.010176 Train Epoch: 1 [56320/60000 (94%)] Loss: 0.030591 Train Epoch: 1 [56960/60000 (95%)] Loss: 0.196713 Train Epoch: 1 [57600/60000 (96%)] Loss: 0.075411 Train Epoch: 1 [58240/60000 (97%)] Loss: 0.215062 Train Epoch: 1 [58880/60000 (98%)] Loss: 0.177358 Train Epoch: 1 [59520/60000 (99%)] Loss: 0.084014 Test set: Average loss: 0.0501, Accuracy: 9836/10000 (98%) Train Epoch: 2 [0/60000 (0%)] Loss: 0.064148 Train Epoch: 2 [640/60000 (1%)] Loss: 0.061523 ... Train Epoch: 2 [58240/60000 (97%)] Loss: 0.023575 Train Epoch: 2 [58880/60000 (98%)] Loss: 0.113758 Train Epoch: 2 [59520/60000 (99%)] Loss: 0.007068 Test set: Average loss: 0.0380, Accuracy: 9872/10000 (99%) Train Epoch: 3 [0/60000 (0%)] Loss: 0.173563 Train Epoch: 3 [640/60000 (1%)] Loss: 0.018026 Train Epoch: 3 [1280/60000 (2%)] Loss: 0.022182 Train Epoch: 3 [1920/60000 (3%)] Loss: 0.030231 ... Train Epoch: 3 [58240/60000 (97%)] Loss: 0.008527 Train Epoch: 3 [58880/60000 (98%)] Loss: 0.027886 Train Epoch: 3 [59520/60000 (99%)] Loss: 0.038440 Test set: Average loss: 0.0350, Accuracy: 9888/10000 (99%) Train Epoch: 4 [0/60000 (0%)] Loss: 0.035976 Train Epoch: 4 [640/60000 (1%)] Loss: 0.027167 Train Epoch: 4 [1280/60000 (2%)] Loss: 0.038828 Train Epoch: 4 [1920/60000 (3%)] Loss: 0.075179 Train Epoch: 4 [2560/60000 (4%)] Loss: 0.069215 Train Epoch: 4 [3200/60000 (5%)] Loss: 0.037071 ... Train Epoch: 4 [51200/60000 (85%)] Loss: 0.084609 Train Epoch: 4 [51840/60000 (86%)] Loss: 0.021072 Train Epoch: 4 [52480/60000 (87%)] Loss: 0.042509 Train Epoch: 4 [53120/60000 (88%)] Loss: 0.059584 Train Epoch: 4 [53760/60000 (90%)] Loss: 0.013509 Train Epoch: 4 [54400/60000 (91%)] Loss: 0.059899 Train Epoch: 4 [55040/60000 (92%)] Loss: 0.072503 Train Epoch: 4 [55680/60000 (93%)] Loss: 0.011318 Train Epoch: 4 [56320/60000 (94%)] Loss: 0.012140 Train Epoch: 4 [56960/60000 (95%)] Loss: 0.015528 Train Epoch: 4 [57600/60000 (96%)] Loss: 0.153004 Train Epoch: 4 [58240/60000 (97%)] Loss: 0.013440 Train Epoch: 4 [58880/60000 (98%)] Loss: 0.050854 Train Epoch: 4 [59520/60000 (99%)] Loss: 0.037339 Test set: Average loss: 0.0324, Accuracy: 9903/10000 (99%) Train Epoch: 5 [0/60000 (0%)] Loss: 0.074965 ... Train Epoch: 5 [58240/60000 (97%)] Loss: 0.007150 Train Epoch: 5 [58880/60000 (98%)] Loss: 0.005998 Train Epoch: 5 [59520/60000 (99%)] Loss: 0.020781 Test set: Average loss: 0.0290, Accuracy: 9911/10000 (99%) ... Train Epoch: 14 [0/60000 (0%)] Loss: 0.002542 Train Epoch: 14 [640/60000 (1%)] Loss: 0.034651 Train Epoch: 14 [1280/60000 (2%)] Loss: 0.006098 Train Epoch: 14 [1920/60000 (3%)] Loss: 0.008892 Train Epoch: 14 [2560/60000 (4%)] Loss: 0.000881 Train Epoch: 14 [3200/60000 (5%)] Loss: 0.005196 Train Epoch: 14 [3840/60000 (6%)] Loss: 0.116072 Train Epoch: 14 [4480/60000 (7%)] Loss: 0.004457 Train Epoch: 14 [5120/60000 (9%)] Loss: 0.075053 Train Epoch: 14 [5760/60000 (10%)] Loss: 0.002541 Train Epoch: 14 [6400/60000 (11%)] Loss: 0.008487 Train Epoch: 14 [7040/60000 (12%)] Loss: 0.010142 Train Epoch: 14 [7680/60000 (13%)] Loss: 0.018750 Train Epoch: 14 [8320/60000 (14%)] Loss: 0.022964 Train Epoch: 14 [8960/60000 (15%)] Loss: 0.018425 Train Epoch: 14 [9600/60000 (16%)] Loss: 0.083772 Train Epoch: 14 [10240/60000 (17%)] Loss: 0.005031 Train Epoch: 14 [10880/60000 (18%)] Loss: 0.006118 Train Epoch: 14 [11520/60000 (19%)] Loss: 0.012194 Train Epoch: 14 [12160/60000 (20%)] Loss: 0.026096 Train Epoch: 14 [12800/60000 (21%)] Loss: 0.005872 Train Epoch: 14 [13440/60000 (22%)] Loss: 0.002419 Train Epoch: 14 [14080/60000 (23%)] Loss: 0.004439 Train Epoch: 14 [14720/60000 (25%)] Loss: 0.000334 Train Epoch: 14 [15360/60000 (26%)] Loss: 0.001956 Train Epoch: 14 [16000/60000 (27%)] Loss: 0.023584 Train Epoch: 14 [16640/60000 (28%)] Loss: 0.032739 Train Epoch: 14 [17280/60000 (29%)] Loss: 0.001395 Train Epoch: 14 [17920/60000 (30%)] Loss: 0.052542 Train Epoch: 14 [18560/60000 (31%)] Loss: 0.003781 Train Epoch: 14 [19200/60000 (32%)] Loss: 0.002781 Train Epoch: 14 [19840/60000 (33%)] Loss: 0.040734 Train Epoch: 14 [20480/60000 (34%)] Loss: 0.002403 Train Epoch: 14 [21120/60000 (35%)] Loss: 0.009741 Train Epoch: 14 [21760/60000 (36%)] Loss: 0.003009 Train Epoch: 14 [22400/60000 (37%)] Loss: 0.001433 Train Epoch: 14 [23040/60000 (38%)] Loss: 0.017763 Train Epoch: 14 [23680/60000 (39%)] Loss: 0.032766 Train Epoch: 14 [24320/60000 (41%)] Loss: 0.055031 Train Epoch: 14 [24960/60000 (42%)] Loss: 0.014967 Train Epoch: 14 [25600/60000 (43%)] Loss: 0.097655 Train Epoch: 14 [26240/60000 (44%)] Loss: 0.011274 Train Epoch: 14 [26880/60000 (45%)] Loss: 0.045538 Train Epoch: 14 [27520/60000 (46%)] Loss: 0.073794 Train Epoch: 14 [28160/60000 (47%)] Loss: 0.002871 Train Epoch: 14 [28800/60000 (48%)] Loss: 0.104455 Train Epoch: 14 [29440/60000 (49%)] Loss: 0.046128 Train Epoch: 14 [30080/60000 (50%)] Loss: 0.027590 Train Epoch: 14 [30720/60000 (51%)] Loss: 0.023746 Train Epoch: 14 [31360/60000 (52%)] Loss: 0.029652 Train Epoch: 14 [32000/60000 (53%)] Loss: 0.014070 Train Epoch: 14 [32640/60000 (54%)] Loss: 0.003088 Train Epoch: 14 [33280/60000 (55%)] Loss: 0.001508 Train Epoch: 14 [33920/60000 (57%)] Loss: 0.008475 Train Epoch: 14 [34560/60000 (58%)] Loss: 0.013877 Train Epoch: 14 [35200/60000 (59%)] Loss: 0.011066 Train Epoch: 14 [35840/60000 (60%)] Loss: 0.047547 Train Epoch: 14 [36480/60000 (61%)] Loss: 0.068665 Train Epoch: 14 [37120/60000 (62%)] Loss: 0.006788 Train Epoch: 14 [37760/60000 (63%)] Loss: 0.013033 Train Epoch: 14 [38400/60000 (64%)] Loss: 0.002599 Train Epoch: 14 [39040/60000 (65%)] Loss: 0.036043 Train Epoch: 14 [39680/60000 (66%)] Loss: 0.028148 Train Epoch: 14 [40320/60000 (67%)] Loss: 0.157269 Train Epoch: 14 [40960/60000 (68%)] Loss: 0.054018 Train Epoch: 14 [41600/60000 (69%)] Loss: 0.061800 Train Epoch: 14 [42240/60000 (70%)] Loss: 0.013732 Train Epoch: 14 [42880/60000 (71%)] Loss: 0.003842 Train Epoch: 14 [43520/60000 (72%)] Loss: 0.003533 Train Epoch: 14 [44160/60000 (74%)] Loss: 0.101497 Train Epoch: 14 [44800/60000 (75%)] Loss: 0.004142 Train Epoch: 14 [45440/60000 (76%)] Loss: 0.026316 Train Epoch: 14 [46080/60000 (77%)] Loss: 0.006387 Train Epoch: 14 [46720/60000 (78%)] Loss: 0.130743 Train Epoch: 14 [47360/60000 (79%)] Loss: 0.005992 Train Epoch: 14 [48000/60000 (80%)] Loss: 0.002442 Train Epoch: 14 [48640/60000 (81%)] Loss: 0.069629 Train Epoch: 14 [49280/60000 (82%)] Loss: 0.002736 Train Epoch: 14 [49920/60000 (83%)] Loss: 0.003623 Train Epoch: 14 [50560/60000 (84%)] Loss: 0.002044 Train Epoch: 14 [51200/60000 (85%)] Loss: 0.017906 Train Epoch: 14 [51840/60000 (86%)] Loss: 0.067535 Train Epoch: 14 [52480/60000 (87%)] Loss: 0.078820 Train Epoch: 14 [53120/60000 (88%)] Loss: 0.004781 Train Epoch: 14 [53760/60000 (90%)] Loss: 0.111643 Train Epoch: 14 [54400/60000 (91%)] Loss: 0.003517 Train Epoch: 14 [55040/60000 (92%)] Loss: 0.048870 Train Epoch: 14 [55680/60000 (93%)] Loss: 0.001008 Train Epoch: 14 [56320/60000 (94%)] Loss: 0.003493 Train Epoch: 14 [56960/60000 (95%)] Loss: 0.007140 Train Epoch: 14 [57600/60000 (96%)] Loss: 0.019242 Train Epoch: 14 [58240/60000 (97%)] Loss: 0.000630 Train Epoch: 14 [58880/60000 (98%)] Loss: 0.014589 Train Epoch: 14 [59520/60000 (99%)] Loss: 0.079487 Test set: Average loss: 0.0294, Accuracy: 9912/10000 (99%) train time list: [7.174770716985222, 6.396849530981854, 6.700996204977855, 6.140903544030152, 6.5446675819694065, 6.775199636991601, 6.91574348002905, 6.429244890983682, 6.813953557983041, 6.112987361033447, 6.425478958000895, 6.353286882978864, 7.112901913002133, 7.050599466951098] inference time list: [1.042455518967472, 1.0501488799927756, 1.039717328036204, 1.0230632729944773, 1.0144481860334054, 0.9574590580305085, 0.9778538069804199, 1.0533951570396312, 1.0227251390460879, 0.9527524459990673, 1.0071292700013146, 1.041757729020901, 1.0557105189654976, 1.050325177027844] train time: 92.9475837268983 inference time: 14.288941488135606 ``` ``` > python main.py --use-te ... Train Epoch: 14 [58240/60000 (97%)] Loss: 0.001275 Train Epoch: 14 [58880/60000 (98%)] Loss: 0.018255 Train Epoch: 14 [59520/60000 (99%)] Loss: 0.190788 Test set: Average loss: 0.0258, Accuracy: 9921/10000 (99%) train time list: [6.391690019983798, 6.792517438996583, 6.072094923991244, 6.099119610036723, 6.473783936991822, 6.634461442998145, 6.545820511004422, 6.504633364034817, 5.760160473990254, 7.329169453005306, 6.647246962995268, 6.197783594019711, 6.261224630987272, 6.351588386984076] inference time list: [1.010965807014145, 0.9527024410199374, 1.0541439579683356, 0.9858089959598146, 1.0347943140077405, 1.0267179679940455, 0.9497789539746009, 0.9827587549807504, 0.9495672340271994, 1.0524603630183265, 1.040817208995577, 1.0367748150019906, 0.9209445589804091, 1.0245853600208648] train time: 90.06129475001944 inference time: 14.022820732963737 ``` ``` > python main.py --use-fp8 ... Train Epoch: 14 [55040/60000 (92%)] Loss: 0.000463 Train Epoch: 14 [55680/60000 (93%)] Loss: 0.002357 Train Epoch: 14 [56320/60000 (94%)] Loss: 0.079992 Train Epoch: 14 [56960/60000 (95%)] Loss: 0.010031 Train Epoch: 14 [57600/60000 (96%)] Loss: 0.012265 Train Epoch: 14 [58240/60000 (97%)] Loss: 0.002443 Train Epoch: 14 [58880/60000 (98%)] Loss: 0.054622 Train Epoch: 14 [59520/60000 (99%)] Loss: 0.126032 Test set: Average loss: 0.0250, Accuracy: 9925/10000 (99%) train time list: [7.210564187029377, 6.6171875660074875, 6.091605413996149, 5.305714985996019, 5.808578662981745, 6.6427561830496415, 6.510479367978405, 6.239163941005245, 6.416430394980125, 6.473377400950994, 6.813092800031882, 6.601396489015315, 6.405762499955017, 5.858293619006872] inference time list: [1.0294796290108934, 0.9135813339962624, 0.9606331089744344, 1.005576271971222, 1.0113011699868366, 1.0482170059694909, 0.9300815680180676, 1.048414018994663, 0.9391937680193223, 1.0117242050473578, 0.9825000909622759, 0.95032776996959, 0.934907581016887, 0.9126828419975936] train time: 88.99440351198427 inference time: 13.678620363934897 ``` ``` > python main_stat.py train time list: [7.087993178982288, 7.079371533007361, 7.364974033029284, 7.1193796820007265, 7.02183426899137, 5.9516880650189705, 6.674289498012513, 6.816586718952749, 6.995105146022979, 7.027234941022471, 6.648724443977699, 6.042013334052172, 6.5562196180108, 5.603573656990193] inference time list: [0.9502711769891903, 1.0733181409887038, 0.9475853049661964, 0.973363564000465, 0.9129067260073498, 1.0311341150081716, 1.0374468020163476, 1.0528108790167607, 1.05149551195791, 1.0637726149871014, 0.9370641469722614, 0.9356176999863237, 1.0465723529923707, 1.0388881860417314] train time: 93.98898811807157 inference time: 14.052247221930884 sum_train_time_list: [0.9921075316960923, 0.979746263648849, 1.295295728952624, 0.8635914049809799, 0.6020516679272987, 0.5717894238187, 0.8129167315200903, 0.7123352510388941, 0.9578135043848306, 0.8523455414106138, 0.4895935410168022, 0.6240919533884153, 0.6424971928354353, 0.699452716158703] sum_test_time_list: [0.022764541092328727, 0.010617257852572948, 0.011623128957580775, 0.008137622033245862, 0.008895464998204261, 0.005871215951628983, 0.010772994079161435, 0.00680145708611235, 0.006934473058208823, 0.013688619888853282, 0.00445437798043713, 0.006612447032239288, 0.01153424585936591, 0.006899168132804334] sum_train_time_list: 11.095628452778328 sum_test_time_list: 0.1356070140027441 ``` ``` > python main_stat.py --use-te train time list: [6.577109163044952, 6.456322034006007, 6.206114369968418, 6.317878360976465, 6.13362843496725, 6.5731987790204585, 6.681127022020519, 6.562263609026559, 5.871911644004285, 6.824332197022159, 6.278518081991933, 5.295758633001242, 6.421999779995531, 5.8961328599834815] inference time list: [1.0320385239901952, 1.0516188929905184, 1.03763318201527, 0.9469043670105748, 0.9094336919952184, 1.029361633991357, 0.9276270279660821, 0.9503992049722001, 0.9650351019809023, 1.0215440799947828, 1.0220137339783832, 0.9601732759620063, 1.0666903390083462, 0.9581517709884793] train time: 88.09629496902926 inference time: 13.878624826844316 sum_train_time_list: [1.2195107479346916, 0.7842218662262894, 0.620298806228675, 0.6155243891989812, 0.678798888984602, 1.4767131984699517, 0.6328003642847762, 0.7442239616648294, 0.8118451639311388, 0.9232772113755345, 0.6797919715172611, 1.3140820758999325, 0.493738787365146, 0.694927082862705] sum_test_time_list: [0.019329448929056525, 0.008496595080941916, 0.006880718923639506, 0.006158717966172844, 0.009659261035267264, 0.011841151979751885, 0.006156609044410288, 0.010696726909372956, 0.018550584965851158, 0.007702818897087127, 0.009280916943680495, 0.006388182984665036, 0.008835386077407748, 0.007065327954478562] sum_train_time_list: 11.689754515944514 sum_test_time_list: 0.1370424476917833 ``` ``` > python main_stat.py --use-fp8 ``` ================================================ FILE: ai-framework/transformer-engine/mnist/main.py ================================================ import argparse import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, transforms from torch.optim.lr_scheduler import StepLR from transformer_engine import pytorch as te import time class Net(nn.Module): def __init__(self, use_te=False): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 32, 3, 1) self.conv2 = nn.Conv2d(32, 64, 3, 1) self.dropout1 = nn.Dropout(0.25) self.dropout2 = nn.Dropout(0.5) if use_te: self.fc1 = te.Linear(9216, 128) self.fc2 = te.Linear(128, 16) else: self.fc1 = nn.Linear(9216, 128) self.fc2 = nn.Linear(128, 16) self.fc3 = nn.Linear(16, 10) def forward(self, x): """FWD""" x = self.conv1(x) x = F.relu(x) x = self.conv2(x) x = F.relu(x) x = F.max_pool2d(x, 2) x = self.dropout1(x) x = torch.flatten(x, 1) x = self.fc1(x) x = F.relu(x) x = self.dropout2(x) x = self.fc2(x) x = self.fc3(x) output = F.log_softmax(x, dim=1) return output def train(args, model, device, train_loader, optimizer, epoch, use_fp8): """Training function.""" model.train() for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device), target.to(device) optimizer.zero_grad() with te.fp8_autocast(enabled=use_fp8): output = model(data) loss = F.nll_loss(output, target) loss.backward() optimizer.step() if batch_idx % args.log_interval == 0: print( f"Train Epoch: {epoch} " f"[{batch_idx * len(data)}/{len(train_loader.dataset)} " f"({100. * batch_idx / len(train_loader):.0f}%)]\t" f"Loss: {loss.item():.6f}" ) if args.dry_run: break def calibrate(model, device, test_loader): """Calibration function.""" model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: data, target = data.to(device), target.to(device) with te.fp8_autocast(enabled=False, calibrating=True): output = model(data) def test(model, device, test_loader, use_fp8): """Testing function.""" model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: data, target = data.to(device), target.to(device) with te.fp8_autocast(enabled=use_fp8): output = model(data) test_loss += F.nll_loss( output, target, reduction="sum" ).item() # sum up batch loss pred = output.argmax( dim=1, keepdim=True ) # get the index of the max log-probability correct += pred.eq(target.view_as(pred)).sum().item() test_loss /= len(test_loader.dataset) print( f"\nTest set: Average loss: {test_loss:.4f}, " f"Accuracy: {correct}/{len(test_loader.dataset)} " f"({100. * correct / len(test_loader.dataset):.0f}%)\n" ) def main(): # Training settings parser = argparse.ArgumentParser(description="PyTorch MNIST Example") parser.add_argument( "--batch-size", type=int, default=64, metavar="N", help="input batch size for training (default: 64)", ) parser.add_argument( "--test-batch-size", type=int, default=1000, metavar="N", help="input batch size for testing (default: 1000)", ) parser.add_argument( "--epochs", type=int, default=14, metavar="N", help="number of epochs to train (default: 14)", ) parser.add_argument( "--lr", type=float, default=1.0, metavar="LR", help="learning rate (default: 1.0)", ) parser.add_argument( "--gamma", type=float, default=0.7, metavar="M", help="Learning rate step gamma (default: 0.7)", ) parser.add_argument( "--dry-run", action="store_true", default=False, help="quickly check a single pass", ) parser.add_argument( "--seed", type=int, default=1, metavar="S", help="random seed (default: 1)" ) parser.add_argument( "--log-interval", type=int, default=10, metavar="N", help="how many batches to wait before logging training status", ) parser.add_argument( "--save-model", action="store_true", default=False, help="For Saving the current Model", ) parser.add_argument( "--use-fp8", action="store_true", default=False, help="Use FP8 for inference and training without recalibration" ) parser.add_argument( "--use-fp8-infer", action="store_true", default=False, help="Use FP8 inference only" ) parser.add_argument( "--use-te", action="store_true", default=False, help="Use Transformer Engine" ) args = parser.parse_args() use_cuda = torch.cuda.is_available() if args.use_fp8 or args.use_fp8_infer: assert use_cuda, "CUDA needed for FP8 execution." args.use_te = True if args.use_fp8_infer: assert not args.use_fp8, "fp8-infer path currently only supports calibration from a bfloat checkpoint" torch.manual_seed(args.seed) device = torch.device("cuda" if use_cuda else "cpu") train_kwargs = {"batch_size": args.batch_size} test_kwargs = {"batch_size": args.test_batch_size} if use_cuda: cuda_kwargs = {"num_workers": 1, "pin_memory": True, "shuffle": True} train_kwargs.update(cuda_kwargs) test_kwargs.update(cuda_kwargs) transform = transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))] ) dataset1 = datasets.MNIST("../data", train=True, download=True, transform=transform) dataset2 = datasets.MNIST("../data", train=False, transform=transform) train_loader = torch.utils.data.DataLoader(dataset1, **train_kwargs) test_loader = torch.utils.data.DataLoader(dataset2, **test_kwargs) model = Net(use_te=args.use_te).to(device) optimizer = optim.Adadelta(model.parameters(), lr=args.lr) scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma) train_time_list = [] inference_time_list = [] for epoch in range(1, args.epochs + 1): start = time.perf_counter() train(args, model, device, train_loader, optimizer, epoch, args.use_fp8) mid = time.perf_counter() test(model, device, test_loader, args.use_fp8) end = time.perf_counter() scheduler.step() train_run_time = mid - start inference_run_time = end-mid train_time_list.append(train_run_time) inference_time_list.append(inference_run_time) print("train time list:",train_time_list) print("inference time list:", inference_time_list) print("train time:", sum(train_time_list)) print("inference time:", sum(inference_time_list)) if args.use_fp8_infer: calibrate(model, device, test_loader) if args.save_model or args.use_fp8_infer: torch.save(model.state_dict(), "mnist_cnn.pt") print('Eval with reloaded checkpoint : fp8='+str(args.use_fp8_infer)) weights = torch.load("mnist_cnn.pt") model.load_state_dict(weights) test(model, device, test_loader, args.use_fp8_infer) if __name__ == "__main__": main() ================================================ FILE: ai-framework/transformer-engine/mnist/main_stat.py ================================================ import argparse import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, transforms from torch.optim.lr_scheduler import StepLR from transformer_engine import pytorch as te import time class Net(nn.Module): def __init__(self, use_te=False): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 32, 3, 1) self.conv2 = nn.Conv2d(32, 64, 3, 1) self.dropout1 = nn.Dropout(0.25) self.dropout2 = nn.Dropout(0.5) if use_te: self.fc1 = te.Linear(9216, 128) self.fc2 = te.Linear(128, 16) else: self.fc1 = nn.Linear(9216, 128) self.fc2 = nn.Linear(128, 16) self.fc3 = nn.Linear(16, 10) def forward(self, x): """FWD""" x = self.conv1(x) x = F.relu(x) x = self.conv2(x) x = F.relu(x) x = F.max_pool2d(x, 2) x = self.dropout1(x) x = torch.flatten(x, 1) x = self.fc1(x) x = F.relu(x) x = self.dropout2(x) x = self.fc2(x) x = self.fc3(x) output = F.log_softmax(x, dim=1) return output sum_train_time_list = [] def train(args, model, device, train_loader, optimizer, epoch, use_fp8): """Training function.""" model.train() train_detail_time_list = [] for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device), target.to(device) optimizer.zero_grad() start_time = time.perf_counter() with te.fp8_autocast(enabled=use_fp8): output = model(data) end_time = time.perf_counter() train_detail_time= end_time-start_time train_detail_time_list.append(train_detail_time) loss = F.nll_loss(output, target) loss.backward() optimizer.step() if batch_idx % args.log_interval == 0: print( f"Train Epoch: {epoch} " f"[{batch_idx * len(data)}/{len(train_loader.dataset)} " f"({100. * batch_idx / len(train_loader):.0f}%)]\t" f"Loss: {loss.item():.6f}" ) if args.dry_run: break sum_train_time = sum(train_detail_time_list) sum_train_time_list.append(sum_train_time) def calibrate(model, device, test_loader): """Calibration function.""" model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: data, target = data.to(device), target.to(device) with te.fp8_autocast(enabled=False, calibrating=True): output = model(data) sum_test_time_list = [] def test(model, device, test_loader, use_fp8): """Testing function.""" model.eval() test_loss = 0 correct = 0 test_time_list = [] with torch.no_grad(): for data, target in test_loader: data, target = data.to(device), target.to(device) start_time = time.perf_counter() with te.fp8_autocast(enabled=use_fp8): output = model(data) end_time = time.perf_counter() test_loss += F.nll_loss( output, target, reduction="sum" ).item() # sum up batch loss pred = output.argmax( dim=1, keepdim=True ) # get the index of the max log-probability correct += pred.eq(target.view_as(pred)).sum().item() test_time= end_time-start_time test_time_list.append(test_time) sum_test_time = sum(test_time_list) sum_test_time_list.append(sum_test_time) test_loss /= len(test_loader.dataset) print( f"\nTest set: Average loss: {test_loss:.4f}, " f"Accuracy: {correct}/{len(test_loader.dataset)} " f"({100. * correct / len(test_loader.dataset):.0f}%)\n" ) def main(): # Training settings parser = argparse.ArgumentParser(description="PyTorch MNIST Example") parser.add_argument( "--batch-size", type=int, default=64, metavar="N", help="input batch size for training (default: 64)", ) parser.add_argument( "--test-batch-size", type=int, default=1000, metavar="N", help="input batch size for testing (default: 1000)", ) parser.add_argument( "--epochs", type=int, default=14, metavar="N", help="number of epochs to train (default: 14)", ) parser.add_argument( "--lr", type=float, default=1.0, metavar="LR", help="learning rate (default: 1.0)", ) parser.add_argument( "--gamma", type=float, default=0.7, metavar="M", help="Learning rate step gamma (default: 0.7)", ) parser.add_argument( "--dry-run", action="store_true", default=False, help="quickly check a single pass", ) parser.add_argument( "--seed", type=int, default=1, metavar="S", help="random seed (default: 1)" ) parser.add_argument( "--log-interval", type=int, default=10, metavar="N", help="how many batches to wait before logging training status", ) parser.add_argument( "--save-model", action="store_true", default=False, help="For Saving the current Model", ) parser.add_argument( "--use-fp8", action="store_true", default=False, help="Use FP8 for inference and training without recalibration" ) parser.add_argument( "--use-fp8-infer", action="store_true", default=False, help="Use FP8 inference only" ) parser.add_argument( "--use-te", action="store_true", default=False, help="Use Transformer Engine" ) args = parser.parse_args() use_cuda = torch.cuda.is_available() if args.use_fp8 or args.use_fp8_infer: assert use_cuda, "CUDA needed for FP8 execution." args.use_te = True if args.use_fp8_infer: assert not args.use_fp8, "fp8-infer path currently only supports calibration from a bfloat checkpoint" torch.manual_seed(args.seed) device = torch.device("cuda" if use_cuda else "cpu") train_kwargs = {"batch_size": args.batch_size} test_kwargs = {"batch_size": args.test_batch_size} if use_cuda: cuda_kwargs = {"num_workers": 1, "pin_memory": True, "shuffle": True} train_kwargs.update(cuda_kwargs) test_kwargs.update(cuda_kwargs) transform = transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))] ) dataset1 = datasets.MNIST("../data", train=True, download=True, transform=transform) dataset2 = datasets.MNIST("../data", train=False, transform=transform) train_loader = torch.utils.data.DataLoader(dataset1, **train_kwargs) test_loader = torch.utils.data.DataLoader(dataset2, **test_kwargs) model = Net(use_te=args.use_te).to(device) optimizer = optim.Adadelta(model.parameters(), lr=args.lr) scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma) train_time_list = [] inference_time_list = [] for epoch in range(1, args.epochs + 1): start = time.perf_counter() train(args, model, device, train_loader, optimizer, epoch, args.use_fp8) mid = time.perf_counter() test(model, device, test_loader, args.use_fp8) end = time.perf_counter() scheduler.step() train_run_time = mid - start inference_run_time = end-mid train_time_list.append(train_run_time) inference_time_list.append(inference_run_time) print("train time list: ",train_time_list) print("inference time list: ", inference_time_list) print("train time: ", sum(train_time_list)) print("inference time: ", sum(inference_time_list)) print("sum_train_time_list: ", sum_train_time_list) print("sum_test_time_list: ", sum_test_time_list) print("sum_train_time_list: ", sum(sum_train_time_list)) print("sum_test_time_list: ", sum(sum_test_time_list)) if args.use_fp8_infer: calibrate(model, device, test_loader) if args.save_model or args.use_fp8_infer: torch.save(model.state_dict(), "mnist_cnn.pt") print('Eval with reloaded checkpoint : fp8='+str(args.use_fp8_infer)) weights = torch.load("mnist_cnn.pt") model.load_state_dict(weights) test(model, device, test_loader, args.use_fp8_infer) if __name__ == "__main__": main() ================================================ FILE: ai-framework/unsloth-微调.md ================================================ - https://github.com/unslothai/unsloth Unsloth 模型的微调,全部用 Triton Kernel 重写。从技术角度来看,这个项目非常有意思,它推到了 PyTorch 目前无法达到的优化极致。 ================================================ FILE: ai-infra/ai-cluster/README.md ================================================ ## AI硬件 A800只是在A100的基础上,将NVLink高速互连总线的带宽从600GB/s降低到400GB/s,仅此而已。 ================================================ FILE: ai-infra/ai-hardware/AI芯片软件生态.md ================================================ ## cuda ``` wget https://developer.download.nvidia.com/compute/cuda/12.1.1/local_installers/cuda_12.1.1_530.30.02_linux.run sudo sh cuda_12.1.1_530.30.02_linux.run ``` ## 瑞芯微 RockX RKNN ## 昇腾 CANN ## 海光 ROCm ## 寒武纪 Neuware 自建生态是长久之道,国产头部算力生态厂商受益。全球来看主要的追赶者AMD和Intel均是走兼容模式为主,是以移植方式兼容CUDA生态,以此次报道的要求来看或短期不受影响。国内核心国产AI算力芯片技术路线中,华为昇腾自建CANN生态、寒武纪自建生态Neuware、海光使用AMD的ROCm平台,其中自建生态的华为昇腾和寒武纪在生态自主上走的更稳更远,而海光当前短期或不受影响且可借力AMD,报道中提到的登临科技、摩尔线程、壁仞科技等AI芯片创业或面临较大的AI算力生态压力。 ================================================ FILE: ai-infra/ai-hardware/CUDA.md ================================================ CUDA 库主要包括以下几个部分: CUDA Runtime API:这是CUDA的核心库,提供了运行时的设备初始化、内存管理、内核执行等功能。 CUDA Driver API:这是CUDA的底层驱动库,提供了与设备和操作系统底层交互的功能。 CUDA CUDART库:这是CUDA运行时库,提供了C语言的标准数学函数和其他功能的接口。 CUDA CUBLAS库:这是CUDA的线性代数库,提供了高效的矩阵和向量运算。 CUDA CUFFT库:这是CUDA的快速傅立叶变换库,用于进行傅立叶变换。 CUDA CURAND库:这是CUDA的随机数库,用于生成各种分布的随机数。 - https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html - https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#id4 CUDA Toolkit and Corresponding Driver Versions - https://docs.nvidia.com/cuda/cuda-c-programming-guide/ - CUDA 编程手册: https://github.com/HeKun-NVIDIA/CUDA-Programming-Guide-in-Chinese ================================================ FILE: ai-infra/ai-hardware/GPU-network.md ================================================ network - https://docs.nvidia.com/networking/display/mlnxofedv583070101/introduction nvme-of - https://docs.nvidia.com/networking/display/mlnxofedv583070101/nvme-of+-+nvm+express+over+fabrics NVIDIA Ada Lovelace Architecture - https://www.nvidia.cn/geforce/ada-lovelace-architecture/ - https://www.nvidia.com/en-us/geforce/ada-lovelace-architecture/ ================================================ FILE: ai-infra/ai-hardware/GPU相关环节变量.md ================================================ ## CUDA CUDA_VISIBLE_DEVICES=1 export CUDA_LAUNCH_BLOCKING=1 export CUDA_DEVICE_MAX_CONNECTIONS=1 ## NCCL export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 ================================================ FILE: ai-infra/ai-hardware/NIXL.md ================================================ https://github.com/ai-dynamo/nixl ================================================ FILE: ai-infra/ai-hardware/OEM-DGX.md ================================================ ## H3C H3C UniServer R5500LC G5服务器---全新A800 GPU的人工智能液冷服务器,支持HGX A800 8-GPU模组,8块A800 GPU通过6个NVSWITCH实现400GB/s的全互联,AI算力较上一代可提升多达20倍。 - https://www.h3c.com/cn/Products_And_Solution/Server/H3C/Products/GPU_Server/Products_Series/Application_Optimization_GPU/R5500LC_G5/ H3C UniServer R5500 G6 服务器---NVIDIA HGX H800 8-GPU模组的人工智能服务器 - https://www.h3c.com/cn/Products_And_Solution/Server/H3C/Products/GPU_Server/Products_Series/Application_Optimization_GPU/R5500_G6/ ================================================ FILE: ai-infra/ai-hardware/README.md ================================================ ## Nvidia GPU NVIDIA A100 80GB PCIe GPU: https://www.edomtech.com.cn/product-detail/nvidia-a100-80gb-pcie-gpu/ - RTX : https://images.nvidia.com/aem-dam/Solutions/geforce/blackwell/nvidia-rtx-blackwell-gpu-architecture.pdf ## Google TPU ## Ascend NPU ## 特斯拉 DOJO - NVIDIA GPUDirect: https://developer.nvidia.com/gpudirect ## 国产AI芯片 - 百度昆仑芯:https://www.kunlunxin.com/ - 阿里含光https://zhuanlan.zhihu.com/p/593171726 - 平头哥:https://www.t-head.cn/ - 昇腾:https://zhuanlan.zhihu.com/p/593202259 ================================================ FILE: ai-infra/ai-hardware/TSMC-台积电.md ================================================ TSMC N7(7纳米工艺)-DUV(深紫外线)光刻技术 TSMC N4(4纳米工艺)-EUV(极紫外线)光刻技术 ================================================ FILE: ai-infra/ai-hardware/cuda镜像.md ================================================ ``` https://catalog.ngc.nvidia.com/orgs/nvidia/containers/cuda https://gitlab.com/nvidia/container-images/cuda/-/tree/master/dist https://gitlab.com/nvidia/container-images/cuda/-/blob/master/dist/12.1.1/centos7/devel/Dockerfile nvcr.io/nvidia/cuda:12.1.0-cudnn8-runtime-centos7 ``` ================================================ FILE: ai-infra/ai-hardware/gpudirect.md ================================================ - https://docs.nvidia.com/gpudirect-storage/design-guide/index.html - https://docs.nvidia.com/gpudirect-storage/overview-guide/index.html - https://docs.nvidia.com/gpudirect-storage/getting-started/index.html 随着 AI 和 HPC 数据集的大小不断增加,为给定应用程序加载数据所花费的时间开始对整个应用程序的性能造成压力。 在考虑端到端应用程序性能时,快速的 GPU 通过缓慢的 I/O 将显著降低GPU的利用率。 I/O 是将数据从存储加载到 GPU 进行处理的过程,历来由 CPU 控制。 随着计算从较慢的 CPU 转移到更快的 GPU,I/O 越来越成为整体应用程序性能的瓶颈。 正如 GPUDirect RDMA(远程直接内存地址)在网络接口卡 (NIC) 和 GPU 内存之间直接移动数据时改善了带宽和延迟一样,一种名为 GPUDirect Storage 的新技术支持本地或远程存储(例如:NVMe 或 NVMe over Fabric (NVMe-oF))与GPU内存之间的直接移动数据。 ## GPUDirect Storage 在GPU加速系统当中,所有的IO操作都会先经过主机端,也就是需要经过CPU指令把数据传到主机内存里,然后才会到达GPU,CPU通常会通过“bounce buffer”来实现数据传输,“bounce buffer”是系统内存中的一块区域,数据在传输到GPU之前会在这里保存一个副本。很明显,这种中转会引额外延迟和内存消耗,降低运行在GPU上的应用程序的性能,还会占用CPU资源,这就是GPUDirect Storage要解决的问题。 ## GDS 的工作原理 NVIDIA 力求尽可能采用现有标准,并在必要时扩展这些标准。 POSIX 标准的 pread 和 pwrite 提供存储和 CPU 缓冲区之间的复制,但尚未启用到 GPU 缓冲区的复制。 Linux 内核中不支持 GPU 缓冲区的缺点将随着时间的推移得到解决。 一种名为 dma_buf 的解决方案正在开发中,该解决方案可以在 NIC 或 NVMe 和 GPU 等 PCIe 总线上的对等设备之间进行复制,以解决这一问题。 与此同时,GDS 的性能提升空间太大,无法等待上游解决方案传播给所有用户。 许多供应商都提供了支持 GDS 的替代解决方案,如:MLNX_OFED。 GDS 解决方案涉及新的 API:cuFileRead 或 cuFileWrite,它们与 POSIX pread 和 pwrite 类似。 动态路由、NVLink 的使用以及只能从 GDS 获得的用于 CUDA 流的异步 API 等优化使得 cuFile API 成为 CUDA 编程模型的持久特性,即使在解决了 Linux 文件系统中的缺陷之后也是如此。 以下是 GDS 实施的作用。 首先,当前 Linux 实现的根本问题是将 GPU 缓冲区地址作为 DMA 目标向下通过虚拟文件系统 (VFS) 传递,以便本地 NVMe 或网络适配器中的 DMA 引擎可以执行与 GPU 内存之间的传输。 这会导致错误情况。 我们现在有一个解决这个问题的方法:传递 CPU 内存中缓冲区的地址。 当使用 cuFileRead 或 cuFileWrite 等 cuFile API 时,libcufile.so 用户级库捕获 GPU 缓冲区地址并替换传递给 VFS 的代理 CPU 缓冲区地址。 就在缓冲区地址用于 DMA 之前,启用 GDS 的驱动程序对 nvidia-fs.ko 的调用会识别 CPU 缓冲区地址并再次提供替代 GPU 缓冲区地址,以便 DMA 可以正确进行。 libcufile.so 中的逻辑执行前面描述的各种优化,例如:动态路由、预固定缓冲区的使用和对齐。 图 2 显示了用于此优化的堆栈。 cuFile API 是 Magnum IO 灵活抽象架构原则的一个示例,可实现特定于平台的创新和优化,例如选择性缓冲和 NVLink 的使用。 图 2. GDS 软件堆栈,其中应用程序使用 cuFile API,并且支持 GDS 的存储驱动程序调用 nvidia-fs.ko 内核驱动程序来获取正确的 DMA 地址。 ================================================ FILE: ai-infra/ai-hardware/硬件对比.md ================================================ FPGA 相比同等面积和工艺 ASIC 的算力差着数量级 大多数大模型 16-bit 权重真的可以量化到 8-bit 而不太损失精度。但要压缩到 4-bit,精度一般就会有比较大的损失了。 NVIDIA 的 Tensor Core 也可以很高效地执行 16-bit 和 8-bit 的计算,8-bit 的算力基本上是 16-bit 的两倍。 FPGA 还是适合用来做智能网卡,也适合做存储编码、压缩、加密等特定算法的加速。AI 大模型还是 ASIC 更在行。 ================================================ FILE: ai-infra/communication.md ================================================ - MoE 通信优化技术 COMET 开源: https://zhuanlan.zhihu.com/p/29264560896 - https://github.com/bytedance/flux ================================================ FILE: ai-infra/存储/README.md ================================================ - [GDDR6 vs DDR4 vs HBM2?为什么CPU还不用GDDR?异构内存的未来在哪里?](https://www.zhihu.com/tardis/zm/art/83935084?source_id=1003) ================================================ FILE: ai-infra/存储/REF.md ================================================ ================================================ FILE: ai-infra/存储/nvme-ssd.md ================================================ - ChatGPT一路狂飙,NVMe SSD能否应对性能挑战?:https://blog.csdn.net/Memblaze_2011/article/details/129040963 - NVMe 2.0 简介:https://blog.csdn.net/Memblaze_2011/article/details/134402001 - NVMe over Fabric网络技术介绍:https://zhuanlan.zhihu.com/p/596081274 ================================================ FILE: ai-infra/存储/固态硬盘.md ================================================ - NVME高端固态硬盘推荐(PCIE3.0篇): https://zhuanlan.zhihu.com/p/455414014 ## 固态硬盘组成 固态硬盘一般由四个部分组成:控制单元(主控)、存储单元(颗粒)、缓存单元、电路板。不过为了节省成本,很多固态硬盘都不使用缓存芯片了。 主控芯片:相当于固态硬盘的大脑,数据处理能力、算法上都要靠它,现在的主流商家有(马牌Marvell、三星、慧荣Silicon Motion、群联Phison、智微Jmicron、英韧InnoGrit等) 闪存颗粒:相当于一个仓库,根据密度差异可以分为SLC、MLC、TLC、QLC、PLC,PLC还没有面世,由于固态硬盘的使用寿命比较长,所以按照主流来购买就可以。 闪存颗粒按照数据稳定性、速度以及价格排序为SLC>MLC>TLC>QLC>PLC,现主流的固态基本采用TLC和QLC居多,当然为了区分品质,还有着闪存颗粒等级区分。 闪存颗粒等级区分:正片、白片、黑片。 正片:分为两种,一种是闪存颗粒生产商(原厂)封装的好颗粒,另一种是由品牌方向原厂直接采购晶圆,之后再由品牌方进行封装而成,这种品质与原厂封装没什么区别无异,原厂封装型号可参考金士顿KC2500。 白片:就是正片中的一些多次检测中有小瑕疵,实际的使用中可能好,也可能一般般,但好在基本问题不大,这种的话不建议当主盘,这种固态硬盘价格会便宜一些,可当游戏副盘使用。 黑片:就是刚检测就有问题的固态硬盘,简单的说就是次品,然后一些厂商便宜的价格收过去,再包装一下,做成固态硬盘,实际体验容易翻车,数据丢失几率大。 缓存芯片:固态硬盘缓存虽然不是主要的参数,但是还是有存在的意义的,特别是常用文件的随机性读写上,主要品牌有南亚,现在市场反而是无外置缓存卖的都特别好,所以很多厂商也都取消了缓存芯片,毕竟更省成本啊,实际缓存带来的提升普通用户体验不出来。 PCB板:主控芯片、闪存颗粒、缓存芯片这三样结合到一块PCB板上,就形成了一个M.2固态硬盘。 ## M.2固态硬盘规格 现在市场主流的规格是M.2 2280规格,同样是M.2接口,那怎么区分NVMe协议和SATA协议呢?最简单的区分方法就是看接口的位置,NVME协议只有一个口,而SATA协议拥有两个口,但也有一些个别品牌喜欢搞另类,比如把NVME协议的固态硬盘搞成两口的。 M.2:实际也就是NGFF接口,这其中分为B Key和M Key,目前M Key是主流,也就是现在的NVME协议固态硬盘。 M.2 (NGFF)接口的两种类型 M.2接口固态硬盘体积小,适用于台式机与笔记本,(单面颗粒台式笔记本都可用,双面颗粒不兼容一些笔记本),而NVME协议读写入速度高于SATA协议几倍,所以,现在几乎没人选择B Key类型了。 ## 固态硬盘品牌 那PCIE3.0固态硬盘的品牌这么多,需要怎么选择呢? 固态硬盘的品牌主要是分自产颗粒和贴牌。 自产颗粒:三星、西数(闪迪)、致钛(长江存储)、英特尔、海力士、铠侠(东芝)、英睿达(美光)等等 其它品牌:金士顿、威刚、影驰、雷克沙、浦科特、爱国者、海康威视、大华等等。 避坑品牌:某胜、某速、某维、某储、其它杂牌 ##PCIE固态硬盘优点 1、读写入速度高于SATA协议几倍 2、体积小,适用于台式机与笔记本 ================================================ FILE: ai-infra/存储/存储.md ================================================ - [硬盘科普,M.2,PCI-E,NVMe 傻傻分不清](https://zhuanlan.zhihu.com/p/396745362) 物理接口,通道,协议 - [NVMe、AHCI、PCIe、SATA、NGFF接口、协议小结](https://blog.csdn.net/wujinglin7/article/details/122826608) 通讯协议、物理接口标准(规范)、传输通道 - 详解:什么是NVMe?:https://zhuanlan.zhihu.com/p/363589126 机械硬盘 ————> SATA M.2 固态硬盘 ----> NVMe M.2 固态硬盘 ================================================ FILE: ai-infra/算力/AI芯片.md ================================================ ## 摩尔线程 2022年,摩尔线程就推出了GPU统一系统架构MUSA,发布并量产“苏堤”和“春晓”两颗全功能GPU芯片,这也是国内采用现代GPU架构 ## 主流 AI 芯片配置 | 厂商 | 型号 | 图形处理器 | 架构 | 显存 | FP16 算力 | BF16 算力 | INT8 算力 | FP32算力 | TF32 算力 | FP8算力 | CUDA Core | Tensor Core | | --- | --------------------------- | ------------ | ------------ | ------------ | ------------------------------------- | ---------------------------- | ------------------------- | ------------ | --------------------------- | ---------------------------- | --------- | ----------- | | 英伟达 | RTX 3090 | GA102-300-A1 | Ampere | 24GB(GDDR6X) | 35.58 TFLOPS | - | - | 35.58 TFLOPS | - | 不支持 | 10496 | 328 | | 英伟达 | RTX 3090 Ti | GA102-350-A1 | Ampere | 24GB(GDDR6X) | 40.00 TFLOPS | - | - | 40.00 TFLOPS | - | 不支持 | 10752 | 336 | | 英伟达 | RTX 4090 | AD102-300-A1 | Ada Lovelace | 24GB(GDDR6X) | 369.7 TFLOPS(Tensor Core)82.58 TFLOPS | 369.7 TFLOPS(Tensor Core) | 739.4 TFLOPS(Tensor Core) | 82.58 TFLOPS | - | - | 16384 | 512 | | 英伟达 | RTX 4090 Ti | AD102-400-A1 | Ada Lovelace | 24GB(GDDR6X) | 93.24 TFLOPS | - | - | 93.24 TFLOPS | - | - | 18176 | 568 | | 英伟达 | RTX 4090D-特供-消费级 | AD102-250-A1 | Ada Lovelace | 24GB(GDDR6X) | 329.3 TFLOPS(Tensor Core)73.54 TFLOPS | 329.3 TFLOPS(Tensor Core) | 658.6 TFLOPS(Tensor Core) | 73.54 TFLOPS | - | - | 14592 | 456 | | 英伟达 | L20(PCIe)-特供-推理(PCIe) | AD102 | Ada Lovelace | 48GB(GDDR6) | 119.5 TFLOPS(Tensor Core) | 119.5 TFLOPS(Tensor Core) | 239 TOPS(Tensor Core) | 59.8 TFLOPS | 59.8 TFLOPS(Tensor Core) | 239 TFOPS(Tensor Core) | 11776 | 368 | | 英伟达 | H20-特供-训练(PCIe、Nvlink) | - | Hopper | 96GB(HBM3) | 148 TFLOPS(Tensor Core) | 148 TFLOPS(Tensor Core) | 296 TOPS(Tensor Core) | 44 TFLOPS | 74 TFLOPS(Tensor Core) | 296 TFOPS(Tensor Core) | - | - | | 英伟达 | A800(PCIe) | GA100 | Ampere | 80GB(HBM2e) | 312 TFLOPS(Tensor Core)77.97 TFLOPS | 312 TFLOPS(Tensor Core) | 624 TOPS(Tensor Core) | 19.5 TFLOPS | 156 TFLOPS(Tensor Core) | 不支持 | 6912 | 432 | | 英伟达 | H800( SXM) | GH100 | Hopper | 80GB(HBM3) | 1,979 TFLOPS(Tensor Core) | 1,979 teraFLOPS(Tensor Core) | 3,958 TOPS(Tensor Core) | 67 teraFLOPS | 989 teraFLOPS (Tensor Core) | 3,958 teraFLOPS(Tensor Core) | 18,432 | 640 | | 昇腾 | Atlas 800T A2训练(910B3-HCCS) | - | 达芬奇 | 64GB(HBM2e) | 313 TFLOPS | 313 TFLOPS | 640 TOPS | 75 TFLOPS | 141 TFLOPS(HF) | 不支持 | - | - | | 昇腾 | Atlas 800I 推理(910B4) | - | 达芬奇 | 32GB(HBM2e) | 280 TFLOPS | 280 TFLOPS | 550 TOPS | 75 TFLOPS | 141 TFLOPS(HF) | 不支持 | - | - | ================================================ FILE: ai-infra/算力/GPU工作原理.md ================================================ - [GPU 工作原理解析](https://zhuanlan.zhihu.com/p/697694330) - [GPU 架构与 CUDA 关系](https://zhuanlan.zhihu.com/p/697746975) ================================================ FILE: ai-infra/算力/NVIDIA-GPU型号.md ================================================ Nvidia下游市场分为四类:游戏、专业可视化、数据中心、汽车,各市场重点产品如下: 游戏:GeForce RTX/GTX系列GPU(PCs)、GeForce NOW(云游戏)、SHIELD(游戏主机); 专业可视化:Quadro/RTX GPU(企业工作站); 数据中心:基于GPU的计算平台和系统,包括DGX(AI服务器)、HGX(超算)、EGX(边缘计算)、AGX(自动设备); 汽车:NVIDIA DRIVE计算平台,包括AGX Xavier(SoC芯片)、DRIVE AV(自动驾驶)、DRIVE IX(驾驶舱软件)、Constellation(仿真软件) 消费级:https://www.nvidia.cn/geforce/graphics-cards/40-series/rtx-4090/ 生产级:https://www.nvidia.cn/data-center/a100/ ## 计算能力(Compute Capability) 标识设备的核心架构、gpu硬件支持的功能和指令 不同GPU型号的计算能力:https://developer.nvidia.com/cuda-gpus#compute 计算能力包括主修订号X和次修订号Y来表示, 主修订号标明核心架构,次修订号标识在此核心架构上的增量更新。 ## DGX - https://docs.nvidia.com/dgx-systems/ - https://docs.nvidia.com/dgx/pdf/dgx2-user-guide.pdf ## DGX-H100 - 官网详细介绍:https://docs.nvidia.com/dgx/dgxh100-user-guide/introduction-to-dgxh100.html - AI芯片白皮书下载:https://www.nvidia.cn/data-center/dgx-a100/ HGX H100 8-GPU 是新一代 Hopper GPU 服务器的关键组成部分。它拥有八个 H100 张量核 GPU 和四个第三代 NV 交换机。每个 H100 GPU 都有多个第四代 NVLink 端口,并连接到所有四个 NVLink 交换机。每个 NVSwitch 都是一个完全无阻塞的交换机,完全连接所有八个 H100 Tensor Core GPU 。 NVSwitch 的这种完全连接的拓扑结构使任何 H100 都可以同时与任何其他 H100 通信。值得注意的是,这种通信以每秒 900 千兆字节( GB/s )的 NVLink 双向速度运行,这是当前 PCIe Gen4 x16 总线带宽的 14 倍多。 第三代 NVSwitch 还为集体运营提供了新的硬件加速,多播和 NVIDIA 的网络规模大幅缩减。结合更快的 NVLink 速度,像all-reduce这样的普通人工智能集体操作的有效带宽比 HGX A100 增加了 3 倍。集体的 NVSwitch 加速也显著降低了 GPU 上的负载。 HGX H100 拥有八个 H100 Tensor Core GPU 和 四个第三代 NV 交换机。每个 H100 GPU 都有多个第四代 NVLink 端口,并连接到所有四个 NVLink 交换机。每个 NVSwitch 都是一个完全无阻塞的交换机,完全连接所有八个 H100 Tensor Core GPU 。 NVSwitch 的这种完全连接的拓扑结构使任何 H100 都可以同时与任何其他 H100 通信。值得注意的是,这种通信以每秒 900 千兆字节( GB/s )的 NVLink 双向速度运行,这是当前 PCIe Gen4 x16 总线带宽的 14 倍多。 ## DGX-A100 - https://docs.nvidia.com/dgx/dgxa100-user-guide/introduction-to-dgxa100.html - [NVIDIA GPU A100 Ampere(安培) 架构深度解析](https://blog.csdn.net/han2529386161/article/details/106411138) - [GPU 进阶笔记(一):高性能 GPU 服务器硬件拓扑与集群组网(2023)](https://arthurchiao.art/blog/gpu-advanced-notes-1-zh/) - [GPU 进阶笔记(二):华为 GPU 相关(2023)](https://arthurchiao.art/blog/gpu-advanced-notes-2-zh/) - [NVIDIA DGX H100 介绍](https://www.foresine.com/news/465-cn.html) ## H200 - https://www.nvidia.com/en-us/data-center/h200/ ================================================ FILE: ai-infra/算力/推理芯片.md ================================================ 如果说大模型「上半场」是技术的较量,那么「下半场」则是商业化的比拼。一旦大模型成熟,与之而来的便是落地应用,滋生对推理芯片的庞大需求。 ================================================ FILE: ai-infra/算力/昇腾NPU.md ================================================ Atlas 800-9000A2 ================================================ FILE: ai-infra/网络/HPC性能测试.md ================================================ - HPC-单机&多机点对点RDMA网络性能测试:https://www.volcengine.com/docs/6419/164863 ``` apt update && apt install -y infiniband-diags yum install infiniband-diags ibstatus ``` 单机测试: ``` dpkg -l perftest ibverbs-providers libibumad3 libibverbs1 libnl-3-200 libnl-route-3-200 librdmacm1 ib_write_bw -d mlx5_1 & ib_write_bw -d mlx5_1 127.0.0.1 --report_gbits ``` 多机测试: ``` 进行多机测试时,请确认两台实例已加入同一高性能计算集群。 在 A 实例中执行ib_write_bw -d mlx5_1 -x 3命令。 ib_write_bw -d mlx5_1 -x 3 在 B 实例中输入如下命令, 请替换为 A 实例的 RDMA 网卡 IP,本文以名为mlx5_1的RDMA网卡为例。 ib_write_bw -d mlx5_1 -x 3 --report_gbits 回显如下,带宽值接近 200Gb/s。 ``` - https://github.com/linux-rdma/infiniband-diags - 【分布式】入门级NCCL多机并行实践 - 02:https://blog.csdn.net/u013013023/article/details/133950028 - 通过 RDMA 网络加速训练:https://www.volcengine.com/docs/6459/96563 - 验证镜像是否支持 RDMA:https://www.volcengine.com/docs/6459/119595#centos-2 ================================================ FILE: ai-infra/网络/IB-docker.md ================================================ ``` yum install libibverbs ``` ================================================ FILE: ai-infra/网络/IB流量监控.md ================================================ ifstat,nload 这些工具都只能监控 TCP/IP 的流量,因此虽然其上面能显示出 IB 卡,但其实并不能监控到出入 IB 的流量数据,结果中对应部分一直都是 0。 ================================================ FILE: ai-infra/网络/IB软件.md ================================================ - centos.install.mellanox.gpudirect.md - Assueme NVIDIA Driver and CUDA already successfully installed. - https://gist.github.com/1duo/666d749ac7bf24ac4cc4f67984756edf - InfiniBand Software:https://developer.nvidia.com/networking/infiniband-software ## Linux Drivers ### NVIDIA MLNX_OFED OpenFabrics Alliance (www.openfabrics.org) 的 OFED 通过高性能 I/O 供应商的协作开发和测试得到了强化。 MLNX_OFED 是经过 NVIDIA 测试和封装的 OFED 版本,支持两种使用相同 RDMA(远程 DMA)的互连类型和称为 OFED verbs 的内核旁路 API – InfiniBand 和以太网。 支持高达 400Gb/s 的 InfiniBand 和超过 10/25/40/50/100/200/400GbE 的 RoCE(基于融合以太网标准的 RDMA)。 ### Linux 内置驱动程序 适用于以太网和 InfiniBand 适配器的 Linux 驱动程序,也可在所有主要发行版(RHEL、SLES、Ubuntu 等)的收件箱中找到。 ## libibverbs libibverbs:用于直接用户空间使用 RDMA (InfiniBand/iWARP/RoCE) 硬件的库和驱动程序 libibverbs 是一个库,允许程序使用 RDMA "verbs 从用户空间直接访问 RDMA(当前是 InfiniBand 和 iWARP)硬件。 ## MLNX_OFED GPUDirect RDMA nvidia-peer-memory GPU-GPU 通信的最新进展是 GPUDirect RDMA。 该技术在 GPU 内存与 NVIDIA 网络适配器设备之间提供直接的 P2P(点对点)数据路径。 这显着减少了 GPU-GPU 通信延迟,并完全卸载了 CPU,将其从网络上的所有 GPU-GPU 通信中移除。 GPU Direct 利用 NVIDIA 网络适配器的 PeerDirect RDMA 和 PeerDirect ASYNC™ 功能。 ## NVIDIA HPC-X 提高消息通信的可扩展性和性能。 NVIDIA® HPC-X® 是一个综合软件包,包括消息传递接口 (MPI)、对称分层内存 (SHMEM) 和分区全局地址空间 (PGAS) 通信库以及各种加速包。 这个功能齐全、经过测试和打包的工具包使 MPI 和 SHMEM/PGAS 编程语言能够实现高性能、可扩展性和效率,并确保通信库通过 NVIDIA Quantum InfiniBand 网络解决方案得到全面优化。 ================================================ FILE: ai-infra/网络/InfiniBand.md ================================================ InfiniBand网络接口的一种分类方式,按照数据传输速率的的不同进行区分。具体如下: SDR(Single Data Rate):单倍数据率,即8Gb/s 。 DDR(Double Data Rate):双倍数据率,即16Gb/s。 QDR(Quad Data Rate):四倍数据率,即32Gb/s。 FDR(Fourteen Data Rate):十四倍数据率,即56Gb/s。 EDR(Enhanced Data Rate):100 Gb/s。 HDR(High Data Rate):200 Gb/s。 NDR(Next Data Rate):400 Gb/s+。 这些技术指标主要是根据实际的数据传输速率来区分的,而且每种技术都有自己的编码方式以提高数据传输的效率和稳定性。 例如,对于SDR、DDR、QDR、FDR、EDR、HDR和NDR,它们采用的数据编码方式分别为8b/10b、8b/10b、8b/10b、64b/66b(仅FDR和EDR)、64b/66b(仅HDR)和自定义编码方式。 - 态路小课堂丨关于InfiniBand网络相关内容简介!:https://baijiahao.baidu.com/s?id=1760941961023057651&wfr=spider&for=pc - Infiniband Verbs 性能测试:https://github.com/linux-rdma/perftest ================================================ FILE: ai-infra/网络/NCCL.md ================================================ NCCL 通信库仅针对 Nvidia Spectrum-X 和 Nvidia InfiniBand 进行了优化。 博通 Tomahawk 5 以太网方案,客户需要有足够的工程能力来为 Tomahawk 5 适配及优化英伟达的 NCCL 通信库。 - 环境变量:https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/env.html NCCL_DEBUG=WARN NCCL_SOCKET_IFNAME==ens1f0 ldconfig -p | grep libnccl export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH ``` yum install libnccl libnccl-devel libnccl-static ``` ================================================ FILE: ai-infra/网络/README.md ================================================ - 聊透 GPU 通信技术——GPU Direct、NVLink、RDMA: https://zhuanlan.zhihu.com/p/654417967 - 腾讯机智团队分享--GPU数据传输概览: https://zhuanlan.zhihu.com/p/74217534 ## PCIe - https://blogs.synopsys.com/expressyourself/2017/08/15/1-2-3-4-5-its-official-pcie-5-0-is-announced/ - https://www.zhihu.com/question/618932114/answer/3192465335 ## NVLink ## NVSwitch 第三代 NVIDIA NVSwitch™ 基于 NVLink 的高级通信能力构建,可为计算密集型工作负载提供更高带宽和更低延迟。为了支持高速集合运算,每个 NVSwitch 都有 64 个 NVLink 端口,并配有 NVIDIA SHARP™ 引擎,可用于网络内归约和组播加速。 NVLink 是一种 GPU 之间的直接互连,可扩展服务器内的多 GPU 输入/输出 (IO)。NVSwitch 可连接多个 NVLink,在单节点内和节点间实现以 NVLink 能够达到的最高速度进行多对多 GPU 通信。 ================================================ FILE: ai-infra/网络/REF.md ================================================ - [RoCE、IB和TCP等网络的基本知识及差异对比](https://support.huawei.com/enterprise/zh/doc/EDOC1100203347) ================================================ FILE: ai-infra/网络/Spine-Leaf和InfiniBand网络架构区别简述.md ================================================ Spine-Leaf和InfiniBand是两种不同的网络架构和技术,它们在设计和应用上有一些区别。 1. Spine-Leaf网络架构: - Spine-Leaf是一种扁平化(flat)的网络架构,通常应用于数据中心网络。它由两个主要组件组成:Spine交换机和Leaf交换机。 - Spine-Leaf架构具有低延迟、高带宽和可扩展性的特点。每个Leaf交换机与所有Spine交换机直接连接,形成一个无阻塞的全互连网络。 - Spine-Leaf网络架构适用于云计算、大规模数据中心和虚拟化环境,可以提供高效的数据传输和负载均衡。 2. InfiniBand网络技术: - InfiniBand是一种高性能计算和数据通信网络技术,通常用于构建超级计算机和高性能计算环境。 - InfiniBand具有低延迟、高带宽和高度并行性的特点。它支持点对点连接和多播通信,通过RDMA(远程直接内存访问)技术实现高效的数据传输。 - InfiniBand网络通常用于需要大规模并行计算的应用,如科学计算、数据分析和模拟等领域。它可以提供低延迟和高吞吐量的数据传输,以满足高性能计算需求。 在区别方面: - Spine-Leaf网络架构更适用于数据中心环境,而InfiniBand更常见于超级计算机和高性能计算环境。 - Spine-Leaf网络更注重网络的扁平化和可扩展性,以满足数据中心的高带宽和负载均衡需求。而InfiniBand更注重低延迟和高并行性,以支持大规模并行计算和数据传输。 - InfiniBand通常支持更高的数据传输速率(如HDR InfiniBand可达到200 Gbps),而Spine-Leaf网络常常采用Ethernet作为传输协议,速率一般在10 Gbps或更高。 - 在成本方面,Spine-Leaf网络通常较为经济实惠,而InfiniBand网络则相对较昂贵。 总之,Spine-Leaf和InfiniBand是不同的网络架构和技术,应根据实际应用场景和需求选择适合的网络方案。 | Spine-Leaf网络 | InfiniBand网络 | | ------------------------------------------- | --------------------------------------- | | 适用于数据中心网络 | 适用于超级计算机和高性能计算环境 | | 扁平化的网络架构 | 高性能计算和数据通信技术 | | 由Spine和Leaf交换机组成 | 点对点连接和多播通信 | | 提供低延迟、高带宽和可扩展性 | 低延迟、高带宽和高并行性 | | 用于云计算、大规模数据中心和虚拟化环境 | 用于科学计算、数据分析和模拟等领域 | | 以Ethernet为传输协议 | 支持RDMA技术 | | 常用厂商:Cisco、Arista Networks、Juniper Networks | 常用厂商:Mellanox Technologies、Intel、Cavium| ================================================ FILE: ai-infra/网络/nccl-test-集合通讯的性能测试.md ================================================ - https://github.com/NVIDIA/nccl-tests - https://cloud.baidu.com/doc/GPU/s/Yl3mr0ren - HPC-基于NCCL通信库的多机RDMA网络性能测试: https://www.volcengine.com/docs/6419/105002 ------ 要构建测试,只需键入make。 如果CUDA未安装在/usr/local/cuda中,则指定CUDA_HOME。同样,如果NCCL未安装在/usr中,则指定NCCL_HOME。 ``` $ make CUDA_HOME=/path/to/cuda NCCL_HOME=/path/to/nccl ``` NCCL tests rely on MPI to work on multiple processes, hence multiple nodes. If you want to compile the tests with MPI support, you need to set MPI=1 and set MPI_HOME to the path where MPI is installed. NCCL tests 依赖于MPI来处理多个进程,从而处理多个节点。如果要使用支持MPI编译 tests,则需要将MPI设置为1,并将MPI_HOME设置为安装MPI的路径。 ``` $ make MPI=1 MPI_HOME=/path/to/mpi CUDA_HOME=/path/to/cuda NCCL_HOME=/path/to/nccl ``` ``` Run on 8 GPUs (-g 8), scanning from 8 Bytes to 128MBytes : $ ./build/all_reduce_perf -b 8 -e 128M -f 2 -g 8 Run with MPI on 10 processes (potentially on multiple nodes) with 4 GPUs each, for a total of 40 GPUs: $ mpirun -np 10 ./build/all_reduce_perf -b 8 -e 128M -f 2 -g 4 ``` ================================================ FILE: ai-infra/网络/nvbandwidth.md ================================================ # nvbandwidth 用于测量 NVIDIA GPU 带宽的工具。 使用copy engine或kernel copy方法测量不同链路上各种 memcpy 模式的带宽。 nvbandwidth 报告系统上当前测量的带宽。 可能需要额外的系统特定调整才能实现最大峰值带宽。 ## 安装 ``` > sh ./debian_install.sh ```
详细输出

``` Reading package lists... Done Building dependency tree Reading state information... Done build-essential is already the newest version (12.8ubuntu1.1). 0 upgraded, 0 newly installed, 0 to remove and 94 not upgraded. Reading package lists... Done Building dependency tree Reading state information... Done libboost-program-options-dev is already the newest version (1.71.0.0ubuntu2). 0 upgraded, 0 newly installed, 0 to remove and 94 not upgraded. Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: cmake-data libarchive13 libicu66 libjsoncpp1 librhash0 libuv1 libxml2 tzdata Suggested packages: cmake-doc ninja-build lrzip The following NEW packages will be installed: cmake cmake-data libarchive13 libicu66 libjsoncpp1 librhash0 libuv1 libxml2 tzdata 0 upgraded, 9 newly installed, 0 to remove and 94 not upgraded. Need to get 15.3 MB of archives. ... Setting up libuv1:amd64 (1.34.2-1ubuntu1.3) ... Setting up librhash0:amd64 (1.3.9-1) ... Setting up cmake-data (3.16.3-1ubuntu1.20.04.1) ... Setting up libjsoncpp1:amd64 (1.7.4-3.1ubuntu2) ... Setting up libicu66:amd64 (66.1-2ubuntu2.1) ... Setting up libxml2:amd64 (2.9.10+dfsg-5ubuntu0.20.04.6) ... Setting up libarchive13:amd64 (3.4.0-2ubuntu1.2) ... Setting up cmake (3.16.3-1ubuntu1.20.04.1) ... Processing triggers for libc-bin (2.31-0ubuntu9.9) ... -- The CUDA compiler identification is NVIDIA 11.8.89 -- The CXX compiler identification is GNU 9.4.0 -- Detecting CUDA compiler ABI info -- Detecting CUDA compiler ABI info - done -- Check for working CUDA compiler: /usr/local/cuda/bin/nvcc - skipped -- Detecting CUDA compile features -- Detecting CUDA compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Found Boost: /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake (found version "1.71.0") found components: program_options -- Configuring done -- Generating done -- Build files have been written to: /root/nvbandwidth [ 14%] Building CXX object CMakeFiles/nvbandwidth.dir/testcase.cpp.o [ 28%] Building CXX object CMakeFiles/nvbandwidth.dir/testcases_ce.cpp.o [ 42%] Building CXX object CMakeFiles/nvbandwidth.dir/testcases_sm.cpp.o [ 57%] Building CUDA object CMakeFiles/nvbandwidth.dir/kernels.cu.o [ 71%] Building CXX object CMakeFiles/nvbandwidth.dir/memcpy.cpp.o [ 85%] Building CXX object CMakeFiles/nvbandwidth.dir/nvbandwidth.cpp.o [100%] Linking CXX executable nvbandwidth [100%] Built target nvbandwidth ```

## help ``` ./nvbandwidth -h ```
详细输出

``` nvbandwidth Version: v0.2 Built from Git version: 42e94d2 nvbandwidth CLI: -h [ --help ] Produce help message --bufferSize arg (=64) Memcpy buffer size in MiB --loopCount arg (=16) Iterations of memcpy to be performed -l [ --list ] List available testcases -t [ --testcase ] arg Testcase(s) to run (by name or index) -v [ --verbose ] Verbose output(详细输出) -d [ --disableAffinity ] Disable automatic CPU affinity control ```

--- ## 列出可用的测试用例 ``` > ./nvbandwidth -l nvbandwidth Version: v0.2 Built from Git version: 42e94d2 Index, Name: Description ======================= 0, host_to_device_memcpy_ce: Host to device CE memcpy using cuMemcpyAsync 1, device_to_host_memcpy_ce: Device to host CE memcpy using cuMemcpyAsync 2, host_to_device_bidirectional_memcpy_ce: A host to device copy is measured while a device to host copy is run simultaneously. Only the host to device copy bandwidth is reported. 3, device_to_host_bidirectional_memcpy_ce: A device to host copy is measured while a host to device copy is run simultaneously. Only the device to host copy bandwidth is reported. 4, device_to_device_memcpy_read_ce: Measures bandwidth of cuMemcpyAsync between each pair of accessible peers. Read tests launch a copy from the peer device to the target using the target's context. 5, device_to_device_memcpy_write_ce: Measures bandwidth of cuMemcpyAsync between each pair of accessible peers. Write tests launch a copy from the target device to the peer using the target's context. 6, device_to_device_bidirectional_memcpy_read_ce: Measures bandwidth of cuMemcpyAsync between each pair of accessible peers. A copy in the opposite direction of the measured copy is run simultaneously but not measured. Read tests launch a copy from the peer device to the target using the target's context. 7, device_to_device_bidirectional_memcpy_write_ce: Measures bandwidth of cuMemcpyAsync between each pair of accessible peers. A copy in the opposite direction of the measured copy is run simultaneously but not measured. Write tests launch a copy from the target device to the peer using the target's context. 8, all_to_host_memcpy_ce: Measures bandwidth of cuMemcpyAsync between a single device and the host while simultaneously running copies from all other devices to the host. 9, all_to_host_bidirectional_memcpy_ce: A device to host copy is measured while a host to device copy is run simultaneously. Only the device to host copy bandwidth is reported. All other devices generate simultaneous host to device and device to host interferring traffic. 10, host_to_all_memcpy_ce: Measures bandwidth of cuMemcpyAsync between the host to a single device while simultaneously running copies from the host to all other devices. 11, host_to_all_bidirectional_memcpy_ce: A host to device copy is measured while a device to host copy is run simultaneously. Only the host to device copy bandwidth is reported. All other devices generate simultaneous host to device and device to host interferring traffic. 12, all_to_one_write_ce: Measures the total bandwidth of copies from all accessible peers to a single device, for each device. Bandwidth is reported as the total inbound bandwidth for each device. Write tests launch a copy from the target device to the peer using the target's context. 13, all_to_one_read_ce: Measures the total bandwidth of copies from all accessible peers to a single device, for each device. Bandwidth is reported as the total outbound bandwidth for each device. Read tests launch a copy from the peer device to the target using the target's context. 14, one_to_all_write_ce: Measures the total bandwidth of copies from a single device to all accessible peers, for each device. Bandwidth is reported as the total outbound bandwidth for each device. Write tests launch a copy from the target device to the peer using the target's context. 15, one_to_all_read_ce: Measures the total bandwidth of copies from a single device to all accessible peers, for each device. Bandwidth is reported as the total inbound bandwidth for each device. Read tests launch a copy from the peer device to the target using the target's context. 16, host_to_device_memcpy_sm: Host to device SM memcpy using a copy kernel 17, device_to_host_memcpy_sm: Device to host SM memcpy using a copy kernel 18, device_to_device_memcpy_read_sm: Measures bandwidth of a copy kernel between each pair of accessible peers. Read tests launch a copy from the peer device to the target using the target's context. 19, device_to_device_memcpy_write_sm: Measures bandwidth of a copy kernel between each pair of accessible peers. Write tests launch a copy from the target device to the peer using the target's context. 20, device_to_device_bidirectional_memcpy_read_sm: Measures bandwidth of a copy kernel between each pair of accessible peers. Copies are run in both directions between each pair, and the sum is reported. Read tests launch a copy from the peer device to the target using the target's context. 21, device_to_device_bidirectional_memcpy_write_sm: Measures bandwidth of a copy kernel between each pair of accessible peers. Copies are run in both directions between each pair, and the sum is reported. Write tests launch a copy from the target device to the peer using the target's context. 22, all_to_host_memcpy_sm: Measures bandwidth of a copy kernel between a single device and the host while simultaneously running copies from all other devices to the host. 23, all_to_host_bidirectional_memcpy_sm: A device to host bandwidth of a copy kernel is measured while a host to device copy is run simultaneously. Only the device to host copy bandwidth is reported. All other devices generate simultaneous host to device and device to host interferring traffic using copy kernels. 24, host_to_all_memcpy_sm: Measures bandwidth of a copy kernel between the host to a single device while simultaneously running copies from the host to all other devices. 25, host_to_all_bidirectional_memcpy_sm: A host to device bandwidth of a copy kernel is measured while a device to host copy is run simultaneously. Only the host to device copy bandwidth is reported. All other devices generate simultaneous host to device and device to host interferring traffic using copy kernels. 26, all_to_one_write_sm: Measures the total bandwidth of copies from all accessible peers to a single device, for each device. Bandwidth is reported as the total inbound bandwidth for each device. Write tests launch a copy from the target device to the peer using the target's context. 27, all_to_one_read_sm: Measures the total bandwidth of copies from all accessible peers to a single device, for each device. Bandwidth is reported as the total outbound bandwidth for each device. Read tests launch a copy from the peer device to the target using the target's context. 28, one_to_all_write_sm: Measures the total bandwidth of copies from a single device to all accessible peers, for each device. Bandwidth is reported as the total outbound bandwidth for each device. Write tests launch a copy from the target device to the peer using the target's context. 29, one_to_all_read_sm: Measures the total bandwidth of copies from a single device to all accessible peers, for each device. Bandwidth is reported as the total inbound bandwidth for each device. Read tests launch a copy from the peer device to the target using the target's context. ``` ## 运行所有测试用例 ``` > ./nvbandwidth nvbandwidth Version: v0.2 Built from Git version: 42e94d2 NOTE: This tool reports current measured bandwidth on your system. Additional system-specific tuning may be required to achieve maximal peak bandwidth. CUDA Runtime Version: 11080 CUDA Driver Version: 12000 Driver Version: 525.105.17 Device 0: NVIDIA H800 Device 1: NVIDIA H800 Device 2: NVIDIA H800 Device 3: NVIDIA H800 Device 4: NVIDIA H800 Device 5: NVIDIA H800 Device 6: NVIDIA H800 Device 7: NVIDIA H800 Running host_to_device_memcpy_ce. memcpy CE CPU(row) -> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 55.28 55.30 55.32 55.30 55.31 55.34 55.32 55.34 SUM host_to_device_memcpy_ce 442.52 Running device_to_host_memcpy_ce. memcpy CE CPU(row) <- GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 55.15 55.15 55.15 55.15 55.09 55.13 55.10 55.13 SUM device_to_host_memcpy_ce 441.05 Running host_to_device_bidirectional_memcpy_ce. memcpy CE CPU(row) <-> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 52.75 52.33 52.96 52.86 52.70 52.90 52.96 52.85 SUM host_to_device_bidirectional_memcpy_ce 422.30 Running device_to_host_bidirectional_memcpy_ce. memcpy CE CPU(row) <-> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 34.47 50.50 34.41 34.72 34.29 34.38 34.41 34.68 SUM device_to_host_bidirectional_memcpy_ce 291.85 Running device_to_device_memcpy_read_ce. memcpy CE GPU(row) -> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 N/A 172.16 172.24 171.99 171.88 172.16 172.16 172.16 1 171.99 N/A 172.05 172.05 172.16 171.88 172.16 172.18 2 171.96 172.05 N/A 172.05 172.16 172.16 172.16 171.88 3 172.24 171.99 172.05 N/A 172.13 172.41 172.38 172.24 4 172.07 172.24 172.27 172.16 N/A 172.32 172.32 172.32 5 172.18 172.21 172.29 172.35 172.32 N/A 172.32 172.32 6 172.27 172.24 172.32 172.29 172.32 172.54 N/A 172.32 7 172.07 172.32 172.21 172.32 172.32 172.57 172.32 N/A SUM device_to_device_memcpy_read_ce 9643.22 Running device_to_device_memcpy_write_ce. memcpy CE GPU(row) <- GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 N/A 176.08 176.08 176.08 176.11 176.05 176.08 176.08 1 176.14 N/A 176.14 176.14 176.08 176.08 176.20 176.05 2 176.14 176.11 N/A 176.08 176.05 176.05 176.05 176.11 3 176.14 176.14 176.11 N/A 176.08 176.17 176.17 176.20 4 176.08 176.11 176.02 176.11 N/A 176.14 176.14 176.08 5 176.08 176.17 175.99 176.08 176.08 N/A 176.08 176.11 6 176.11 176.17 176.14 176.08 176.14 176.05 N/A 176.08 7 176.08 176.14 176.11 176.08 176.05 176.11 176.02 N/A SUM device_to_device_memcpy_write_ce 9861.63 Running device_to_device_bidirectional_memcpy_read_ce. memcpy CE GPU(row) <-> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 N/A 170.54 170.54 170.54 170.54 170.76 170.54 170.76 1 170.54 N/A 170.52 170.54 170.52 170.79 170.54 170.54 2 170.81 170.54 N/A 170.65 170.57 170.62 170.38 170.46 3 170.76 170.54 170.54 N/A 170.62 170.60 170.41 170.44 4 170.52 170.54 170.73 170.76 N/A 170.54 170.54 170.79 5 170.54 170.54 170.79 170.73 170.73 N/A 170.76 170.54 6 170.54 170.76 170.79 170.49 170.54 170.79 N/A 170.54 7 170.54 170.52 170.76 170.54 170.76 170.79 170.79 N/A SUM device_to_device_bidirectional_memcpy_read_ce 9554.42 Running device_to_device_bidirectional_memcpy_write_ce. memcpy CE GPU(row) <-> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 N/A 174.34 174.25 174.28 174.28 174.31 174.34 174.31 1 174.42 N/A 174.45 174.37 174.45 174.39 174.39 174.34 2 174.39 174.42 N/A 174.31 174.37 174.28 174.37 174.37 3 174.39 174.45 174.45 N/A 174.37 174.42 174.39 174.37 4 174.42 174.39 174.34 174.39 N/A 174.37 174.34 174.45 5 174.37 174.31 174.37 174.37 174.39 N/A 174.34 174.31 6 174.37 174.34 174.34 174.34 174.37 174.34 N/A 174.37 7 174.31 174.34 174.39 174.37 174.34 174.34 174.34 N/A SUM device_to_device_bidirectional_memcpy_write_ce 9764.26 Running all_to_host_memcpy_ce. memcpy CE CPU(row) <- GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 44.95 44.45 45.12 44.41 44.61 45.06 45.06 45.00 SUM all_to_host_memcpy_ce 358.66 Running all_to_host_bidirectional_memcpy_ce. memcpy CE CPU(row) <- GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 22.22 35.09 22.43 22.34 22.59 22.75 22.84 22.78 SUM all_to_host_bidirectional_memcpy_ce 193.04 Running host_to_all_memcpy_ce. memcpy CE CPU(row) -> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 55.21 55.26 55.15 55.12 55.12 55.19 55.13 55.11 SUM host_to_all_memcpy_ce 441.30 Running host_to_all_bidirectional_memcpy_ce. memcpy CE CPU(row) <- GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 33.49 24.64 33.51 33.56 34.15 34.34 34.36 34.42 SUM host_to_all_bidirectional_memcpy_ce 262.47 Running all_to_one_write_ce. memcpy CE All Gpus -> GPU(column) total bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 177.69 177.63 177.71 177.70 177.67 177.68 177.68 177.68 SUM all_to_one_write_ce 1421.43 Running all_to_one_read_ce. memcpy CE All Gpus <- GPU(column) total bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 142.09 142.13 142.14 142.13 142.15 142.08 142.09 142.12 SUM all_to_one_read_ce 1136.93 Running one_to_all_write_ce. memcpy CE GPU(column) -> All GPUs total bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 175.95 176.03 176.00 176.05 175.99 175.98 175.96 175.99 SUM one_to_all_write_ce 1407.95 Running one_to_all_read_ce. memcpy CE GPU(column) <- All GPUs total bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 177.62 177.70 177.68 177.67 177.70 177.70 177.69 177.70 SUM one_to_all_read_ce 1421.47 Running host_to_device_memcpy_sm. memcpy SM CPU(row) -> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 38.20 51.49 38.26 38.16 37.17 37.33 37.45 37.39 SUM host_to_device_memcpy_sm 315.45 Running device_to_host_memcpy_sm. memcpy SM CPU(row) <- GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 52.81 52.81 52.82 52.81 52.78 52.79 52.78 52.79 SUM device_to_host_memcpy_sm 422.39 Running device_to_device_memcpy_read_sm. memcpy CE GPU(row) -> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 N/A 167.56 167.58 167.53 167.58 167.63 167.63 167.58 1 167.58 N/A 167.61 167.63 167.66 167.63 167.63 167.56 2 167.58 167.58 N/A 167.56 167.50 167.58 167.61 167.61 3 167.61 167.63 167.61 N/A 167.63 167.58 167.58 167.61 4 167.61 167.58 167.58 167.61 N/A 167.58 167.61 167.56 5 167.56 167.56 167.61 167.50 167.53 N/A 167.61 167.66 6 167.61 167.56 167.61 167.56 167.53 167.66 N/A 167.63 7 167.61 167.56 167.61 167.53 167.56 167.61 167.63 N/A SUM device_to_device_memcpy_read_sm 9385.10 Running device_to_device_memcpy_write_sm. memcpy SM GPU(row) <- GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 N/A 165.44 165.39 165.54 165.31 165.44 165.72 165.49 1 165.82 N/A 165.69 165.54 165.67 165.74 165.62 165.77 2 165.72 165.51 N/A 165.36 165.23 165.33 165.49 165.28 3 165.95 165.82 165.77 N/A 165.62 165.77 165.74 165.87 4 165.90 165.82 165.74 165.51 N/A 165.62 165.72 165.79 5 165.67 165.41 165.26 165.44 165.13 N/A 165.21 165.44 6 165.64 165.49 165.49 165.41 165.49 165.39 N/A 165.51 7 165.74 165.51 165.46 165.41 165.44 165.23 165.54 N/A SUM device_to_device_memcpy_write_sm 9271.04 Running device_to_device_bidirectional_memcpy_read_sm. memcpy SM GPU(row) -> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 N/A 301.70 301.81 301.70 301.64 301.78 301.76 301.78 1 301.74 N/A 301.76 301.81 301.78 301.74 301.72 301.74 2 301.83 301.68 N/A 301.59 301.66 301.78 301.76 301.81 3 301.81 301.81 301.81 N/A 301.81 301.76 301.78 301.76 4 301.72 301.81 301.76 301.83 N/A 301.72 301.76 301.74 5 301.81 301.68 301.85 301.70 301.64 N/A 301.74 301.76 6 301.78 301.74 301.78 301.70 301.68 301.81 N/A 301.78 7 301.76 301.72 301.76 301.70 301.66 301.74 301.74 N/A SUM device_to_device_bidirectional_memcpy_read_sm 16898.01 Running device_to_device_bidirectional_memcpy_write_sm. memcpy SM GPU(row) <- GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 N/A 327.84 327.47 327.27 327.49 327.56 327.22 327.32 1 328.04 N/A 327.52 327.72 327.77 327.72 327.56 327.54 2 327.49 327.44 N/A 327.97 327.09 327.39 327.14 327.39 3 327.74 327.89 327.77 N/A 327.77 327.77 327.49 327.64 4 327.72 327.92 327.74 327.69 N/A 327.56 327.29 327.74 5 327.37 327.49 327.29 327.59 327.57 N/A 327.39 327.37 6 327.74 327.69 327.32 327.14 327.44 326.82 N/A 327.54 7 327.72 327.46 327.49 327.27 327.62 327.29 327.39 N/A SUM device_to_device_bidirectional_memcpy_write_sm 18341.61 Running all_to_host_memcpy_sm. memcpy SM CPU(row) <- GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 43.66 43.25 44.16 43.36 43.26 43.67 43.65 43.69 SUM all_to_host_memcpy_sm 348.69 Running all_to_host_bidirectional_memcpy_sm. memcpy SM CPU(row) <- GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 30.13 41.15 20.38 38.47 35.57 31.79 23.19 32.49 SUM all_to_host_bidirectional_memcpy_sm 253.18 Running host_to_all_memcpy_sm. memcpy SM CPU(row) -> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 34.98 51.55 35.16 34.98 35.21 35.28 35.33 35.33 SUM host_to_all_memcpy_sm 297.82 Running host_to_all_bidirectional_memcpy_sm. memcpy SM CPU(row) -> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 20.87 34.09 21.54 23.16 22.16 26.02 17.97 20.36 SUM host_to_all_bidirectional_memcpy_sm 186.16 Running all_to_one_write_sm. memcpy SM All Gpus -> GPU(column) total bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 167.68 167.74 167.81 167.82 167.81 167.82 167.81 167.83 SUM all_to_one_write_sm 1342.33 Running all_to_one_read_sm. memcpy SM All GPUs <- GPU(column) total bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 167.64 167.66 167.65 167.67 167.69 167.63 167.65 167.64 SUM all_to_one_read_sm 1341.22 Running one_to_all_write_sm. memcpy SM GPU(column) -> All GPUs total bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 146.35 137.24 151.35 146.34 165.73 163.10 151.48 146.06 SUM one_to_all_write_sm 1207.66 Running one_to_all_read_sm. memcpy SM GPU(column) <- All GPUs total bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 154.42 154.54 160.02 165.89 139.31 139.18 160.02 149.01 SUM one_to_all_read_sm 1222.39 ``` 运行特定的测试用例: ``` > ./nvbandwidth -t device_to_device_memcpy_read_ce nvbandwidth Version: v0.2 Built from Git version: 42e94d2 NOTE: This tool reports current measured bandwidth on your system. Additional system-specific tuning may be required to achieve maximal peak bandwidth. CUDA Runtime Version: 11080 CUDA Driver Version: 12000 Driver Version: 525.105.17 Device 0: NVIDIA H800 Device 1: NVIDIA H800 Device 2: NVIDIA H800 Device 3: NVIDIA H800 Device 4: NVIDIA H800 Device 5: NVIDIA H800 Device 6: NVIDIA H800 Device 7: NVIDIA H800 Running device_to_device_memcpy_read_ce. memcpy CE GPU(row) -> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 N/A 172.32 172.57 172.57 172.32 172.21 172.13 172.35 1 172.18 N/A 172.05 172.29 172.16 172.16 172.24 172.24 2 171.99 172.18 N/A 172.29 172.21 172.16 172.16 172.24 3 172.07 172.07 172.27 N/A 172.16 172.16 172.21 172.16 4 172.16 171.88 172.16 172.13 N/A 172.27 172.05 172.32 5 172.10 172.18 172.18 172.16 172.32 N/A 172.05 172.07 6 171.88 172.16 172.16 172.16 172.32 172.05 N/A 172.32 7 172.10 172.10 172.07 172.02 172.27 172.24 172.07 N/A SUM device_to_device_memcpy_read_ce 9642.08 ``` 打印详细结果: ``` ./nvbandwidth -v >> nvbandwitch.txt ``` ## 测试详情 实现了两种类型的 copies:Copy Engine (CE) 或 Steaming Multiprocessor (SM) CE copies 使用 memcpy API。 SM copies 使用 kernels。 SM copies将截断copy大小以均匀地适合目标设备,从而正确报告带宽。 copy的实际字节大小为: ``` (threadsPerBlock * deviceSMCount) * floor(copySize / (threadsPerBlock * deviceSMCount)) ``` threadsPerBlock 设置为 512。 ### 测量详情 ![image](https://github.com/liguodongiot/llm-action/assets/13220186/29fff486-6f54-4363-a817-4e38d23742b6) 阻塞 kernel 和 CUDA 事件用于测量通过 SM 或 CE 执行 copies 的时间,并根据一系列 copies 计算带宽。 首先,我们将一个spin kernel排入队列,该kernel在主机内存中的标志上旋转。 spin kernel在设备上旋转,直到所有用于测量的事件已完全排队到测量流中。 这确保了排队操作的开销被排除在互连上的实际传输的测量之外。 接下来,我们将一个开始事件、一次或多次 memcpy 迭代(具体取决于 LoopCount)以及最后一个停止事件排队。 最后,我们释放标志来开始测量。 该过程重复 3 次,并报告每次试验的中值带宽。 ### 单向带宽测试 ``` Running host_to_device_memcpy_ce. memcpy CE CPU(row) -> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 26.03 25.94 25.97 26.00 26.19 25.95 26.00 25.97 ``` 单向测试分别测量输出矩阵中每对之间的带宽。 流量不是同时发送的。 ### 双向主机 <-> 设备带宽测试 ``` Running host_to_device_bidirectional_memcpy_ce. memcpy CE CPU(row) <-> GPU(column) bandwidth (GB/s) 0 1 2 3 4 5 6 7 0 18.56 18.37 19.37 19.59 18.71 18.79 18.46 18.61 ``` 双向主机到设备带宽传输的设置如下所示: ![image](https://github.com/liguodongiot/llm-action/assets/13220186/edabb22a-6fb9-45bd-99f5-7c309fc7267f) Stream 0(测量流)对设备执行写入操作,而相反方向的interfering stream则产生读取操作。 这种模式相反,用于测量双向设备到主机的带宽,如下所示。 ![image](https://github.com/liguodongiot/llm-action/assets/13220186/c0c18882-1379-43bc-a854-4bb726180bd9) ### 双向设备 <-> 设备带宽测试 双向设备到设备传输的设置如下所示: ![image](https://github.com/liguodongiot/llm-action/assets/13220186/9b1302bd-2b31-4228-9542-3557b579389d) 该测试在两个流上启动流量:在设备 0 上启动的流 0 执行从设备 0 到设备 1 的写入操作,而interference stream 1 启动相反的流量,执行从设备 1 到设备 0 的写入操作。 CE 双向带宽测试计算measured stream上的带宽: ``` CE bidir. bandwidth = (size of data on measured stream) / (time on measured stream) ``` 然而,SM 双向测试在源 GPU 和对等 GPU 上作为独立流启动 memcpy kernels,并按如下方式计算带宽: ``` SM bidir. bandwidth = size/(time on stream1) + size/(time on stream2) ``` 官方文档:https://github.com/NVIDIA/nvbandwidth ================================================ FILE: ai-infra/网络/roce.md ================================================ AI场景下高性能网络技术RoCE v2介绍: https://mp.weixin.qq.com/s/XyMFst3w-d65u4fU7cgLPA RoCE是基于 Ethernet的RDMA,RoCEv1版本基于网络链路层,无法跨网段,基本无应用。 RoCEv2基于UDP,可以跨网段具有良好的扩展性,而且吞吐,时延性能相对较好,所以是被大规模采用的方案。 ## ofed驱动 使用RoCE v2之前需要安装相关驱动,也就是ofed软件栈。OFED (OpenFabrics Enterprise Distribution) 是一个开源的软件栈,用于在高性能计算 (HPC) 和数据中心环境中实现高性能网络通信。它是一组用于 InfiniBand 和以太网 RDMA (Remote Direct Memory Access) 技术的软件包和驱动程序的集合。 ## 性能测试-perftest perftest是ofed性能测试工具集。专门用于测试RDMA的性能 ``` 带宽测试 ib_send_bw -d mlx5_0 客户端 ib_send_bw -d mlx5_1 10.251.30.207 ``` ================================================ FILE: ai-infra/网络/网络硬件.md ================================================ LOC PIX PXB PHB SYS GPU间的通讯速度: NV# > PIX > PXB > PHB > NODE > SYS - SYS : 穿越 PCIe 的连接以及 NUMA 节点之间的 SMP 互连(例如 QPI/UPI) - NODE :穿越 PCIe 的连接以及 NUMA 节点内 PCIe 主机桥(PCIe Host Bridges)之间的互连 - PHB :穿越 PCIe 以及 PCIe 主机桥(通常是 CPU)的连接 - PXB :穿过多个 PCIe 交换机的连接(不穿过 PCIe 主机桥) - PIX :最多穿越单个 PCIe 交换机的连接 - NV# :穿越一组 # NVLinks ================================================ FILE: ai-infra/网络/通信软件.md ================================================ Open MPI / MPICH - https://github.com/pmodels/mpich - https://github.com/open-mpi/ompi MPI有多种实现方式,例如OpenMPI,MPICH。 MPI 全名叫 Message Passing Interface,即信息传递接口,作用是可以通过 MPI 可以在不同进程间传递消息,从而可以并行地处理任务,即进行并行计算。NCCL中利用MPI来处理多机通讯的部分。 OpenMPI OpenMPI是一个开源的 Message Passing Interface 实现,是一种高性能消息传递库,能够结合整个高性能计算社区的专业知识、技术和资源,建立现有的最佳MPI库。OpenMPI在系统和软件供应商、应用开发者和计算机科学研究人员中有广泛应用。 NCCL NCCL(Nvidia Collective multi-GPU Communication Library,读作 "Nickel")是一个提供GPU间通信基元的库,它具有拓扑感知能力,可以轻松集成到应用程序中。NCCL做了很多优化,以在PCIe、Nvlink、InfiniBand上实现较高的通信速度。NCCL支持安装在单个节点或多个节点上的大量GPU卡上,并可用于单进程或多进程(如MPI)应用。 NCCL Tests NCCL Tests是一个测试工具集,可以用来评估NCCL的运行性能和正确性。 ================================================ FILE: ai-infra/网络/集合通信原语.md ================================================ 集合通信总结和 mpi4py 实践 https://www.armcvai.cn/2025-06-28/mpi4py-summary.html ================================================ FILE: blog/TODO.md ================================================ llm推理优化技术: - https://github.com/liguodongiot/llm-action/blob/main/docs/llm-inference/llm%E6%8E%A8%E7%90%86%E4%BC%98%E5%8C%96%E6%8A%80%E6%9C%AF.md?plain=1 分布式训练加速技术: - https://github.com/liguodongiot/llm-action/blob/main/docs/llm-base/distribution-training/%E5%88%86%E5%B8%83%E5%BC%8F%E8%AE%AD%E7%BB%83%E5%8A%A0%E9%80%9F%E6%8A%80%E6%9C%AF.md?plain=1 大模型优化技术 - 大模型显存优化技术-KV Cache - 大模型推理优化技术-Flash-Decoding - 大模型显存优化技术-PagedAttention - 大模型显存I/O优化技术-FlashAttention V1 - 大模型显存优化技术-ZeRO系列 - 大模型解码优化-Speculative Decoding及其变体 - 大模型推理服务化调度优化技术-Dynamic batching/Continuous batching - 大模型显存优化技术-混合精度训练 - 大模型显存I/O优化技术-FlashAttention V2 ================================================ FILE: blog/ai-infra/AI 集群基础设施 InfiniBand 详解.md ================================================ GPU在高性能计算和深度学习加速中扮演着非常重要的角色, GPU的强大的并行计算能力,大大提升了运算性能。随着运算数据量的不断攀升,GPU间需要大量的交换数据,因此,GPU通信性能成为了非常重要的指标。 在 AI 集群中进行分布式训练时,通信是必要环节,同时也是相比于单机训练而言多出来的系统开销。通信与计算的时间比例往往决定了分布式机器学习系统加速比的上限。 因此,分布式机器学习的关键是设计通信机制,从而降低通信与计算的时间比例,更加高效地训练出高精度模型。 下面给大家介绍AI集群通信的软硬件、NCLL集合通信库、InfiniBand网络通信技术协议、AI集群和AI框架中对于InfiniBand的应用。 > 文章较长,建议先点赞收藏,后续再慢慢观看。另外,我撰写的**大模型相关的博客及配套代码**均整理放置在Github:[llm-action](https://github.com/liguodongiot/llm-action/tree/main),有需要的朋友自取。 ## 通信硬件 ### 通信硬件的实现方式 通信的实现方式分为两种类型:机器内通信与机器间通信。 机器内通信: - 共享内存(QPI/UPI),比如:CPU与CPU之间的通信可以通过共享内存。 - PCIe,通常是CPU与GPU之间的通信。 - NVLink,通常是GPU与GPU之间的通信,也可以用于CPU与GPU之间的通信。 机器间通信: - TCP/IP 网络协议。 - RDMA (Remote Direct Memory Access) 网络协议。 - InfiniBand - iWARP - RoCE ### PCIe PCI-Express(peripheral component interconnect express),简称PCIe,是一种高速串行计算机扩展总线标准,主要用于扩充计算机系统总线数据吞吐量以及提高设备通信速度。 PCIE本质上是一种全双工的的连接总线,传输数据量的大小由通道数(lane,信道)决定的。 通常,1个连接通道lane称为X1,**每个通道lane由两对数据线组成,一对发送,一对接收,每对数据线包含两根差分线。即X1只有1个lane,4根数据线**,每个时钟每个方向1bit数据传输。依此类推,X2就有2个lane,由8根数据线组成,每个时钟传输2bit。类似的还有X12、X16、X32。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d629223a46564875a2c1160e9521728d~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=720&h=1131&s=714141&e=png&b=4a5a66) 2003 年 PCIe 1.0 正式发布,可支持每通道传输速率为 250MB/s,总传输速率为 2.5 GT/s。 2007 年推出 PCIe 2.0 规范。在 PCIe 1.0 的基础上将总传输速率提高了一倍,达到 5 GT/s,每通道传输速率从 250 MB/s 上升至 500 MB/s。 2022 年 PCIe 6.0 规范正式发布,总传输速率提高至 64 GT/s。 2022年6月,PCI-SIG 联盟宣布 PCIe 7.0 版规范,单条通道(x1)单向可实现128 GT/s 传输速率,计划于2025年推出最终版本。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f6a4a3004b3c4ceaa9567b2e7ef90eb0~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1406&h=431&s=102106&e=png&b=eeeeee) **PCIe吞吐量(可用带宽)计算方法:** `吞吐量=传输速率*编码方案` 传输速率为每秒传输量(GT/s),而不是每秒位数(Gbps),是因为传输量包括**不提供额外吞吐量的开销位**,比如:PCIe 1x和PCIe 2x使用8b/10b编码方案,导致占用了20%(=2/10)的原始信道带宽。 - GT/s,Giga transtion per second (千兆传输/秒),即每一秒内传输的次数,重点在于描述物理层通信协议的速率属性,可以不和链路宽度等关联。 - Gbps,Giga Bits per second (千兆位/秒)。GT/s和Gbps之间不存在成比例的换算关系。 PCIe 2.0协议支持5.0GT/s,即每一条Lane上支持每秒钟传输5G个Bit,但这并不意味着PCIe 2.0协议的每一条Lane支持5Gbps的速率。为什么这么说呢,因为PCIe 2.0的物理层协议中使用的是8b/10b编码方案,即每传输8个Bit,需要发送10个Bit,这多出来的2Bit并不是对上层有意义的信息。那么,PCIe 2.0协议的每一条Lane支持`5*8/10=4Gbps=500MB/s`的速率。以一个PCIe 2.0 x8的通道为例,x8的可用带宽为`4*8=32Gbps=4GB/s`。 同理,PCIe 3.0协议支持8.0GT/s,即每一条Lane上支持每秒钟传输8G个Bit。而PCIe 3.0的物理层协议中使用的是128b/130b编码方案,即每传输128个Bit,需要发送130个Bit,那么,PCIe 3.0协议的每一条Lane支持`8*128/130=7.877GB/s=984.6MB/s`的速率。以一个PCIe 3.0 x16的通道为例,x16的可用带宽为`7.877*16=126.032 Gbps=15.754GB/s`。 **PCIE体系架构**: PCIE体系架构一般包含根组件RC(root-complex),交换器switch,终端设备EP(endpoint)等类型的PCIE设备组成。RC在总线架构中只有一个,用于处理器和内存子系统与I/O设备之间的连接,而switch的功能通常是以软件形式提供的,它包括两个或更多的逻辑PCI到PCI的连接桥(PCI-PCI Bridge),以保持与现有PCI兼容。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2da8b7c4b2b044dfab80bb3c673043ed~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=852&h=600&s=203332&e=png&b=fefdfd) ### NVLink **背景**: 算力的提升不仅依靠单张 GPU 卡的性能提升,往往还需要多 GPU 卡组合。在多 GPU 系统内部,GPU 间通信的带宽通常在数百GB/s以上,PCIe总线的数据传输速率容易成为瓶颈,且PCIe链路接口的串并转换会产生较大延时,影响GPU并行计算的效率和性能。 GPU发出的信号需要先传递到PCIe Switch, PCIe Switch中涉及到数据的处理,CPU会对数据进行分发调度,这些都会引入额外的网络延迟,限制了系统性能。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e5298c9a3382455cad518360bc16a74f~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=700&h=356&s=89728&e=png&b=f8efe8) 为此,NVIDIA推出了能够提升GPU通信性能的技术——GPUDirect P2P技术,使GPU可以通过 PCI Express 直接访问目标GPU的显存,避免了通过拷贝到CPU host memory作为中转,大大降低了数据交换的延迟,但受限于PCI Express总线协议以及拓扑结构的一些限制,无法做到更高的带宽。此后,NVIDIA 提出了 NVLink 总线协议。 **NVLink简介**: NVLink 是一种高速互连技术,旨在加快 CPU 与 GPU、GPU 与 GPU 之间的数据传输速度,提高系统性能。NVLink通过GPU之间的直接互联,可扩展服务器内的多GPU I/O,相较于传统PCIe总线可提供更高效、低延迟的互联解决方案。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b46bcbcc54384297ab173b306a6ae58c~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=625&h=352&s=179166&e=png&b=353535) NVLink的首个版本于2014年发布,首次引入了高速GPU互连。2016年发布的P100搭载了第一代NVLink,提供 160GB/s 的带宽,相当于当时 PCIe 3.0 x16 带宽(双向)的 5 倍。之后陆续发布了很多新版本,V100搭载的 NVLink2 将带宽提升到300GB/s ,A100搭载了NVLink3带宽为600GB/s。H100中包含18条第四代NVLink链路,总带宽(双向)达到 900 GB/s,是PCIe 5.0 x16带宽(双向)的7倍。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6ac72f40a0374e7aa305034166b618fa~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=747&h=489&s=24935&e=png&b=eeeeee) ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a24232222ccb49598a816bd923351aac~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1710&h=273&s=71583&e=png&b=ededed) NVLink高速互联主要有两种: - 第一种是以桥接器的形式实现。 - 另一种是在主板上集成 `NVLink` 接口。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d07e4b62d39848b0a7aa9e37593ce6c4~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1033&h=381&s=382215&e=png&b=f9f6f6) ### NVSwitch 为了解决GPU之间通讯不均衡问题,NVIDIA引入NVSwitch。NVSwitch芯片是一种类似交换机的物理芯片(ASIC),通过NVLink接口可以将多个GPU高速互联到一起,可创建无缝、高带宽的多节点GPU集群,实现所有GPU在一个具有全带宽连接的集群中协同工作,从而提升服务器内部多个GPU之间的通讯效率和带宽。NVLink和NVSwitch的结合使NVIDIA得以高效地将AI性能扩展到多个GPU。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/936a389603f84830a4092394c7418358~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=688&h=401&s=48837&e=png&b=edeaea) 第一代 NVSwitch于2018年发布,采用台积电 12nm FinFET 工艺制造,共有 18 个 NVLink 2.0 接口。目前 NVSwitch 已经迭代至第三代。第三代 NVSwitch 采用台积电 4N 工艺(台积电 4N 工艺专为NVIDIA定制设计,并进行了一系列优化,它与普通台积电5nm节点相比,可实现更好的电源效率与性能,并且密度有所提升)构建,每个 NVSwitch 芯片上拥有 64 个 NVLink 4.0 端口,GPU 间通信速率可达 900GB/s。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b31291309f6d40ae92b525e78a6fcd70~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1546&h=207&s=56495&e=png&b=f3f3f3) ### Nvidia GPU 服务器 PCIe 版 和 SXM 版的区别 英伟达GPU卡间互连的内存插槽有2种,一种是PCIe口,一种是SXM口。 PCIe口是一个相对通用的协议,PCIe口相对慢一些,SXM是专门用来做卡间互连的,SXM协议是铺在电路板上,SXM协议做卡间互连会更快,对NVLink原生支持更好,显存带宽比PCIe高一些。PCIe和SXM都可以用NVLink,但是SXM是更好使用NVLink的方法。 SXM 架构是一种高带宽插座式解决方案,用于将 GPU 连接到 NVIDIA 专有的 DGX 和 HGX 系统。SXM 版 GPU 通过主板上集成的 NVSwitch 实现 NVLink 的连接,不需要通过主板上的PCIe进行通信,它能支持8块GPU卡的互联互通,实现了GPU之间的高带宽。未阉割的A100是600GB/s、H100是900GB/s,阉割过的A800、H800为400GB/s。 把 PCIe 版 GPU 卡插到 PCIe 插槽上,就可以和CPU、同一个服务器上其他的GPU卡进行通信,也可以通过网卡与其他的服务器节点上的设备进行通信,这种就是PCIe的通信方式,但是这种传输速度不快。如果想要和SXM一样,有很快的传输速度,可以使用NVlink桥接器实现GPU和CPU之间的通信,但是和SXM不一样的地方就是它只能实现2块GPU卡之间的通信。即 PCIe 版只有成对的 GPU 通过 NVLink Bridge 连接,通过 PCIe 通道进行数据通信。同时,最新的PCIe网络带宽有128GB/s的限制。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3bc4f115338245a88091182bddaaa1d1~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1982&h=677&s=821728&e=png&b=09428d) ### TCP/IP TCP/TP (或传输控制协议/Internet 协议)用于通过 Internet 互连网络设备。它确定了数据应该如何被打包、寻址、传输、路由和接收。TCP/IP 非常重视两台计算机之间的准确数据传输。如果系统在一次发送消息时遇到问题,则必须重新发送整个消息。 此外,TCP/IP 的功能分为四个不同的层:**数据链路层、互联网层、传输层和应用层**。数据在被另一端接收之前必须经过这四层。然后,TCP/IP 将通过以相反顺序传递层来重组数据并将其呈现给接收器。这样,您可以通过升级某些层而不是整个系统来提高数据中心的性能或安全性。 ### RDMA RDMA(远程直接数据存取)就是为了解决网络传输中服务器端数据处理的延迟而产生的,**无需使用CPU,就可以从一个主机或服务器的内存直接访问另一主机或服务器的内存**。它释放了CPU去执行其应做的工作,比如:运行应用程序和处理大量数据。这既提高了带宽又降低了延迟、抖动和 CPU 消耗。 对比传统的网络传输机制,RDMA无需操作系统和TCP/IP协议栈的介入。**RDMA的内核旁路机制,允许应用与网卡之间的直接数据读写**,将服务器内的数据传输时延降低到1us以下。同时,RDMA的内存零拷贝机制,允许接收端直接从发送端的内存读取数据,极大的减少了CPU的负担,提升CPU的效率。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1e4c8404a9124f48ad6ee0e914489ca8~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1080&h=443&s=125224&e=png&b=ffffff) 大致有三类RDMA网络,分别是Infiniband、RoCE、iWARP。其中,Infiniband是一种专为RDMA设计的网络,从硬件级别保证可靠传输 ,而RoCE 和 iWARP都是基于以太网的RDMA技术,支持相应的verbs接口。 RDMA最早在Infiniband传输网络上实现,技术先进,但是价格高昂(**只有Mellanox(现已被英伟达收购)和Intel(2012年,英特尔公司出资收购了QLogic的InfiniBand技术)供应商提供全套网络解决方案**),后来业界厂家把RDMA移植到传统Ethernet以太网上,降低了RDMA的使用成本,推动了RDMA技术普及。在Ethernet以太网上,根据协议栈融合度的差异,分为iWARP和RoCE两种技术,而RoCE又包括**RoCEv1和RoCEv2两个**版本(RoCEv2的最大改进是支持IP路由)。各RDMA网络协议栈的对比,如下图所示: ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7d143d6d63a44f2caffe208201eec22d~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1024&h=532&s=463868&e=png&b=fdfbfb) **IB(InfiniBand):** 基于 InfiniBand 架构的 RDMA 技术,由 IBTA(InfiniBand Trade Association)提出。搭建基于 IB 技术的 RDMA 网络需要专用的 IB 网卡和 IB 交换机。 **iWARP(Internet Wide Area RDMA Protocal):** 基于 TCP/IP 协议的 RDMA 技术,由 IETF 标 准定义。iWARP 支持在标准以太网基础设施上使用 RDMA 技术,但服务器需要使用支持iWARP 的网卡。 **RoCE(RDMA over Converged Ethernet):** 基于以太网的 RDMA 技术,也是由 IBTA 提出。RoCE 支持在标准以太网基础设施上使用RDMA技术,但是需要交换机支持无损以太网传输,需要服务器使用 RoCE 网卡。 在三种主流的RDMA技术中,可以划分为两大阵营。一个是IB技术,另一个是支持RDMA的以太网技术(RoCE和iWARP)。其中, IBTA力挺的技术自然是IB和RoCE, Mellanox公司是这方面的急先锋。而iWARP则是IEEE/IETF力挺的技术,主要是Chelsio公司在推进。 在存储领域,支持RDMA的技术早就存在,比如:SRP(SCSI RDMA Protocol)和iSER(iSCSI Extensions for RDMA)。如今兴起的NVMe over Fabrics如果使用的不是FC网络的话,本质上就是 NVMe over RDMA。 换句话说,NVMe over InfiniBand, NVMe over RoCE 和 NVMe over iWARP 都是 NVMe over RDMA。 ## InfiniBand InfiniBand(直译为 “无限带宽” 技术,缩写为IB)是一个为大规模、易扩展机群而设计的**网络通信技术协议**。可用于计算机内部或外部的数据互连,服务器与存储系统之间直接或交换互连,以及存储系统之间的互连。 InfiniBand 最重要的一个特点就是**高带宽**、**低延迟**,因此在高性能计算项目中广泛的应用。 主要用于高性能计算(HPC)、高性能集群应用服务器和高性能存储。 ### InfiniBand 链路速率 InfiniBand在物理层定义了多种链路速度,例如:1X,4X,12X。每个单独的链路是四线串行差分连接(每个方向两根线)。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4470dc47a85b40d886470cdbf1212bd9~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=318&h=286&s=62025&e=png&b=cbd6fc) 以早期的SDR(单数据速率)规范为例,1X链路的原始信号带宽为2.5Gbps,4X链路是10Gbps,12X链路是30Gbps。 1X链路的实际数据带宽为2.0Gbps(因为采用8b/10b编码)。由于链路是双向的,因此相对于总线的总带宽是4Gbps。 随着时间的推移,InfiniBand的网络带宽不断升级,下图展示了 InfiniBand 从SDR、DDR、QDR、FDR、EDR发展到HDR、NDR的网络带宽,其速度是基于 4x 链路速度。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/52c2a6d6c45f4ac4be1b19c2032bd380~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1080&h=248&s=81845&e=png&b=fefefe) - SDR(Single Data Rate):2.5Gb/s (10Gb/s for 4x)。 - DDR(Double Data Rate):5 Gb/s (20Gb/s for 4x)。 - QDR(Quad Data Rate):10 Gb/s (40Gb/s for 4x)。 - FDR(Fourteen Data Rate):14Gb/s (56Gb/s for 4x)。 - EDR(Enhanced Data Rate):25 Gb/s (100Gb/s for 4x)。 - HDR(High Data Rate):50 Gb/s (200Gb/s for 4x)。 - NDR(Next Data Rate):100 Gb/s (400Gb/s for 4x)。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/23c8aee1729541f0bf0b02c0fab555cb~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1080&h=632&s=139743&e=png&b=f7f7f7) ### InfiniBand 网络互连产品 InfiniBand 网络中,使用的线缆区别于传统的以太网线缆和光纤线缆。针对不同的连接场景,需使用专用的InfiniBand线缆。 InfiniBand网络互连产品包括:**DAC高速铜缆**、**AOC有源线缆**以及**光模块**。 DAC高速线缆和AOC有源光缆都是用于数据中心、高性能计算机等大容量储存器设备间的传输设备。 **DAC高速线缆**,也叫直连铜缆(Direct Attach Copper cable), 它的线材是铜缆,是低压脉冲传输信号;因为材料的不同导致功耗、传输距离和价格的不同,DAC高速线缆的功耗比较低,但传输距离相对比较短,低于10米。价格方面相对便宜一些。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b017a8bae70644d8bc387856ea456539~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=800&h=800&s=137041&e=png&b=f8f6f9) **AOC有源光缆**(Active Optial Cable),它的线材是光缆,为光信号传输,通过电-光-电的转换;功耗相对比较大些但传输的距离可达到100米,价格方面相对高些。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c9ad44b030d74bea94f59466dbe08850~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=710&h=533&s=241635&e=png&b=f8f7f7) **光模块**的作用也是光电信号之间的转换,主要用于交换机与设备之间传输的载体,和光纤收发器的原理相同,只是光模块相比收发器更具效率性、安全性。光模块按照封装形式分类,常见的有 SFP,SFP+,XFP,SFP28,QSFP+,QSFP28 等。 **光纤收发器**是将短距离的电信号和长距离的光信号进行转换的设备,一般应用在远距离传输中,通过光纤进行传输,将电信号转换成光信号发送出去,同时,在接收端将接收到的光信号转换成电信号。在很多地方也被称之为光电转换器(Fiber Converter)。光纤收发器为需要将系统从铜线升级到光纤,为缺少资金、人力或时间的用户提供了一种廉价的方案。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/536b4be32d9449babb8907b900b0adac~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=771&h=470&s=217027&e=png&b=f0eeee) **光模块与光纤收发器如何配对使用?** 1. 波长和传输距离必须一致,比如:采用1310nm波长,传输距离应该是10KM/20KM。 2. 光纤跳线尾纤接口选择需注意,一般光纤收发器采用的SC口,光模块采用的是LC口。 3. 速率必须一样,比如:千兆收发器对应 1.25G 光模块,百兆连百兆,千兆连千兆。 4、光模块类型需要采用相同类型,单纤对单纤,双纤对双纤。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5c6e868c217341cf93d59cb373a94d3c~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1294&h=482&s=422163&e=png&b=bdd3e0) ### InfiniBand 的网络架构 InfiniBand 是一种基于通道的结构,组成单元主要分为四类: - HCA(Host Channel Adapter,主机通道适配器) - TCA(Target Channel Adapter,目标通道适配器) - InfiniBand link(连接通道,可以是电缆或光纤,也可以是板上链路) - InfiniBand交换机和路由器(组网用的) ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/da3bbe48cb1947d7afe16ad22294e945~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1080&h=793&s=80831&e=png&b=ffffff) 通道适配器就是搭建InfiniBand通道用的。所有传输均以通道适配器开始或结束,以确保安全或在给定的QoS(服务质量)级别下工作。 使用 InfiniBand 的系统可以由多个子网(Subnet)组成,每个子网最大可由 6 万多个节点组成。 - 子网内部,InfiniBand 交换机进行二级处理。 - 子网之间,使用路由器或网桥进行连接。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9b241ef3b4294bf4ad4cf1d5203e9e53~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1049&h=519&s=63954&e=png&b=ffffff) InfiniBand 的二级处理过程非常简单,每个 InfiniBand 子网都会设一个子网管理器,生成16位的 LID(本地标识符)。InfiniBand 交换机包含多个 InfiniBand 端口,并根据第二级本地路由标头中包含的LID,将数据包从其中一个端口转发到另一个端口。**除管理数据包外,交换机不会消耗或生成数据包**。 简单的处理过程,加上自有的Cut-Through技术,InfiniBand 将转发时延大幅降低至 100ns 以下,明显快于传统以太网交换机。 在 InfiniBand 网络中,数据同样以数据包(最大4KB)的形式传输,采用的是串行方式。 ### InfiniBand 的协议栈 InfiniBand 协议同样采用了分层结构,各层相互独立,下层为上层提供服务,如下图所示: ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bff99416b2a843ebb08b36424e03383b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1080&h=622&s=87147&e=png&b=fefefe) - **物理层**定义了在线路上如何将比特信号组成符号,然后再组成帧、数据符号以及包之间的数据填充等,详细说明了**构建有效包的信令协议**等。 - **链路层**定义了数据包的格式以及数据包操作的协议,如:流控、 路由选择、编码、解码等。 - **网络层**通过在数据包上添加一个40字节的全局的路由报头(Global Route Header, GRH)来进行路由的选择,对数据进行转发。**在转发的过程中,路由器仅仅进行可变的CRC校验,这样就保证了端到端的数据传输的完整性**。Infiniband报文封装格式如下图所示: ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/16014600fd2c4c1a8f52a3e2555a3efd~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1080&h=533&s=242259&e=png&b=fcfafa) - **传输层**再将数据包传送到某个指定的队列偶(Queue Pair, QP)中,并指示 QP 如何处理该数据包。 可以看出,InfiniBand 拥有自己定义的 1-4 层格式,是一个完整的网络协议。端到端流量控制,是 InfiniBand 网络数据包发送和接收的基础,可以实现无损网络。 > QP(队列偶)说明: > > QP是RDMA技术中通信的基本单元。队列偶就是一对队列,SQ(Send Queue,发送工作队列)和 RQ(Receive Queue,接收工作队列)。用户调用API发送接收数据的时候,实际上是将数据放入QP当中,然后以轮询的方式,将QP中的请求一条条的处理。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/51bb447ee5664c22b24cbebfe9af1a08~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1080&h=628&s=83343&e=png&b=ebebeb) ### Mellanox OFED 软件栈 Mellanox OFED 是一个单一的软件堆栈,包括驱动、中间件、用户接口,以及一系列的标准协议 IPoIB、SDP、SRP、iSER、RDS、DAPL(Direct Access Programming Library),支持 MPI、Lustre/NFS over RDMA 等协议,并提供 Verbs 编程接口;Mellanox OFED 由开源 OpenFabrics 组织维护。 Mellanox OFED 软件堆栈是承载在 InfiniBand 硬件和协议之上的,软件通过协议和硬件进行有效的数据传输。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5b954db7a5c44dc5870e82d2d2c0845e~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1136&h=720&s=2458522&e=png&b=e6e3e3) ### OpenSM 子网管理器 OpenSM 软件是符合InfiniBand的子网管理器(SM),运行在Mellanox OFED软件堆栈进行 IB 网络管理,管理控制流走业务通道,属于带内管理方式。 OpenSM 包括**子网管理器、背板管理器和性能管理器**三个组件,绑定在交换机内部的必备部件。提供非常完备的管理和监控能力,如:**设备自动发现、设备管理、Fabric可视化、智能分析、健康监测**等等。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/63608c4c208f4ce5890da2e6ce52ae66~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1280&h=628&s=2416125&e=png&b=f1f0ef) ### InfiniBand 组网 InfiniBand 组网跟普通的交换机不太一样,InfiniBand 的组网成本很高。如果希望这个网络中任何两个计算节点的网卡之间互相无损地通信,需要使用一种叫做胖树(Fat Tree)的网络拓扑,大概是如下一种拓扑结构,方块是交换机,椭圆是计算节点。 胖树主要有两层,上面一层是核心层,不连任何计算节点,它的功能就是转发流量;下面一层是接入层,接入各类计算节点。 胖树拓扑成本高的主要原因是:某一个汇聚交换机上,假如有36个口,那如果为了达到无损速率,一半的口,也就是18个口可以给计算节点连,剩下一半要连到上层的核心交换机上。要知道,任何一根线,就是1万多块钱呢,如果达到无损,就要冗余地做这些连接。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/77ea150e49e146d2a25a4e7dbbf4520e~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=591&h=331&s=47543&e=png&b=ffffff) ### NVIDIA InfiniBand 商用产品 Mellanox 在全球 InfiniBand 市场的占有率基本上无敌的存在,在英伟达收购 Mellanox 之后,也于2021年推出了自己的第七代 NVIDIA InfiniBand 架构:NVIDIA Quantum-2。 NVIDIA Quantum-2 平台包括:NVIDIA Quantum-2 系列交换机、NVIDIA ConnectX-7 InfiniBand 适配器、BlueField-3 InfiniBand DPU以及电缆。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a93953336c7a426880e2f97a42898a29~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1499&h=696&s=662947&e=png&b=faf9f9) **NVIDIA Quantum-2 系列交换机**采用紧凑型1U设计,包括风冷和液冷版本。交换机的芯片制程工艺为7nm,单芯片拥有570亿个晶体管(比A100 GPU还多)。单个交换机采用64个400Gb/s端口或128个200Gb/s端口的灵活搭配,提供总计 51.2Tb/s的双向吞吐量。NVIDIA NDR 400Gb/s InfiniBand 交换机如下图所示: ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6cbb986d98c04b42a5f1d8789b53a9ef~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=630&h=354&s=113706&e=png&b=1b1b1b) **NVIDIA ConnectX-7 InfiniBand 适配器**支持PCIe Gen4和Gen5,具有多种外形规格,可提供 400Gb/s 吞吐量。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7e2025e0d5244d199fd554174dfe12f6~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=391&h=265&s=58835&e=png&b=fefefe) ### InfiniBand 常用命令 - `ibv_asyncwatch`:监视 InfiniBand 异步事件 - `ibv_devices` 或 `ibv_devinfo`: 列举 InfiniBand 设备或设备信息 - `ibstatus`:查询 IB 设备的基本状态 - `ibping`: 验证 IB 节点之间的连通性 - `ibtracert`:跟踪 IB 路径 - `iblinkinfo`:查看IB交换模块的所有端口的连接状态。此命令会将集群内所有的IB交换模块都进行列举。 ## 通信软件 通信软件指用于分布式训练时,多个计算设备之间的集合通信。在分布式系统中,各个节点间往往存在大量的集合通信需求,而我们可以用消息传递接口 (Message Passing Interface,MPI,一套集合通信相关的接口标准) 来定义一些比较底层的消息通信行为。譬如 Reduce、AllReduce、Scatter、Gather、AllGather 等。 常见的集合通信库(如:Open MPI、Gloo、NCCL等)都在 MPI 的基础上,对各种集合通信的模式和算法作了各自的实现。 **Open MPI**: Open MPI 是一个开源 MPI(消息传递接口 )的实现,由学术,研究和行业合作伙伴联盟开发和维护。因此,Open MPI 可以整合高性能计算社区中所有专家,技术和资源,以构建可用的最佳 MPI 库。 **Gloo**: Gloo 是 Facebook 开源的一套集体通信库,提供了对机器学习中有用的一些集合通信算法。如:Barrier,Broadcast,AllReduce。 **NCCL**: NCCL(Nvidia Collective multi-GPU Communication Library)是英伟达基于 NVIDIA GPU 的一套开源的集合通信库,如其官网描述:NVIDIA 集合通信库(NCCL)实现了针对 NVIDIA GPU 性能优化的多 GPU 和多节点集合通信原语。NCCL 提供了诸如 All Gather,All Reduce,Broadcast,Reduce,Reduce-Scatter 等实现,这些实现优化后可以通过 PCIe、 NVLink、InfiniBand 等高速互联,从而实现高带宽和低延迟。 因为 NCCL 是 NVIDIA 基于自身硬件定制的,能做到更有针对性且更方便优化,故在英伟达硬件上,NCCL 的效果往往比其它的通信库更好。 NCCL主要做几件事:**探测计算节点的网络设备和拓扑结构**,使用算法自动调优选择一个最优的通信方式。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eb1018950a05412b93e30ab79b808039~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=537&h=276&s=72386&e=png&b=fdfafa) ## NCCL 集合通信库 ### 通信原语 并行任务的通信一般可以分为 Point-to-point communication 和 Collective communication 。 P2P 通信这种模式只有一个sender和一个receiver,实现起来比较简单。 集合通信包含多个sender多个receiver,一般的通信原语包括broadcast,gather,all-gather,scatter,reduce,all-reduce,reduce-scatter,all-to-all等。 简单介绍几个常用的操作: **Reduce**:从多个sender那里接收数据,最终combine到一个节点上。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a6a99b0337024a50ae84d1aecd9ea61a~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=662&h=216&s=53187&e=png&b=f3f2f2) **All-reduce**:从多个sender那里接收数据,最终combine到每一个节点上。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/45af7fe062af410f8efb9fc3bca546b2~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=671&h=214&s=75137&e=png&b=fefcfc) ### NCCL 实现 NCCL 实现成 CUDA C++ kernels,包含3种 primitive operations: Copy,Reduce,ReduceAndCopy。 - NCCL 1.0 版本只支持单机多卡,卡之间通过 PCIe、NVlink、GPUDirect P2P 来通信。 - NCCL 2.0 支持多机多卡,多机间通过 Sockets (Ethernet) 或者 InfiniBand with GPUDirect RDMA 通信。 单机内多卡通过PCIe以及CPU socket通信。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d6a6b3be0c3c4a509bd9d5560fd926e0~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=553&h=183&s=42945&e=png&b=fefcfc) 多机通过InfiniBand通信,在多机多卡内部,也要构成一个通信环。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4fef434d39714c13bf66dfa2dce11d49~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=616&h=176&s=56241&e=png&b=fefcfc) ### 对比 NCCL 在不同硬件架构下网络带宽 下图是 Allreduce 在单机不同架构下的速度比较: ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bf622a93a1fb4d5a91974c6916856df9~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=659&h=335&s=77763&e=png&b=fcfbfb) 前面三个是单机多卡典型的三种连接方式: - 第一种是两个GPU通过CPU然后通过QPI和另一个CPU上的两块卡相连,因此速度最慢,但也能达到>5GB/s。 - 第二种是两个GPU通过PCIe switch相连后再经过CPU连接,速度会稍微低一点。 - 第三种是四张卡都在一个PCIe switch上,所以带宽较高,能达到>10GB/s PCIe的带宽大小。 第四种是DGX-1架构,这是Nvidia推出的深度学习平台,带宽能达到60GB/s。 下图是 Allreduce 多机下的速度表现。其中,左图2机8卡,机内PCIe,机间InfiniBand能达到>10GB/s的速度,InfiniBand基本上能达到机内的通信速度;右图4机32卡,机内NVLink,机间InfiniBand,带宽能达到>40GB/s。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e8abc881b9a749e094c5ed08454fe12e~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=661&h=380&s=102021&e=png&b=fefdfd) 下图是 NCCL 在 CNTK ResNet50 上的可扩展性(scalability),32 卡基本能达到线性加速比。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1cd8d50a4f3b4a79aa3f8a11f7bec3b1~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=665&h=402&s=102462&e=png&b=fefdfd) ### NCCL 常见的环境变量设置 **NCCL_P2P_DISABLE** 该变量禁用 P2P 传输,该传输使用 NVLink 或 PCI 在GPU之间使用CUDA直接访问。 设定为 1 相当于设置 `NCCL_P2P_LEVEL=0`,并且会被 NCCL_P2P_LEVEL 的值所覆盖。 **NCCL_P2P_LEVEL**: 该变量允许用户精细地控制何时在GPU之间使用 P2P 传输。该级别定义了NCCL将使用P2P传输的GPU之间的最大距离。 如果未指定,NCCL 将尝试根据其运行的体系结构和环境来最佳选择一个值。 可选值: - LOC:从不使用P2P(始终禁用) - NVL :当 GPU 通过 NVLink 连接时使用 P2P - PIX :当 GPU 位于同一 PCI 交换机上时使用 P2P。 - PXB:当 GPU 通过 PCI 交换机(可能是多跳)连接时使用 P2P。 - PHB :当 GPU 位于同一 NUMA 节点上时使用 P2P。 流量将通过 CPU。 - SYS :在 NUMA 节点之间使用 P2P,可能跨越 SMP 互连(例如:QPI/UPI)。 **NCCL_NET_GDR_LEVEL**: 该变量允许用户精细控制何时在NIC和GPU之间使用GPUDirect RDMA。该级别定义NIC和GPU之间的最大距离。 如果未指定,NCCL 将尝试根据其运行的体系结构和环境来最佳选择一个值。 可选值: - LOC:从不使用 GPU Direct RDMA。(始终禁用) - PIX:当 GPU 和 NIC 位于同一 PCI 交换机上时,使用 GPU Direct RDMA。 - PXB:当 GPU 和 NIC 通过 PCI 交换机(可能是多跳)连接时,使用 GPU Direct RDMA。 - PHB :当 GPU 和 NIC 位于同一 NUMA 节点上时,使用 GPU Direct RDMA。 流量将通过 CPU。 - SYS :即使跨 NUMA 节点之间的 SMP 互连(例如 QPI/UPI)也使用 GPU Direct RDMA。 (始终启用) **NCCL_NET_GDR_READ**: 只要 GPU-NIC 距离在 NCCL_NET_GDR_LEVEL 指定的距离内,NCCL_NET_GDR_READ 变量就会在发送数据时启用 GPU Direct RDMA。 - 2.4.2之前,默认情况下禁用GDR读取,即发送数据时,数据先存储在 CPU 内存中,然后再发送到 InfiniBand 卡。 - 自 2.4.2 起,基于 NVLink 的平台默认启用 GDR 读取。 注意:已知在某些平台(例如:PCI-E)上,发送数据时直接从 GPU 内存读取比从 CPU 内存读取稍慢。 可选值为0或1。定义并设置为1以使用GPU Direct RDMA直接将数据发送到NIC(绕过CPU)。 在 2.4.2 之前,所有平台的默认值都是 0。 自 2.4.2 起,基于 NVLink 的平台的默认值为 1,否则为 0。 **NCCL_IB_DISABLE**: 该变量将禁用 NCCL 要使用的IB传输。NCCL 将使用IP sockets 。 定义并设置为1以强制使用IP sockets 。 **NCCL_SOCKET_IFNAME**: 指定NCCL使用的SOCKET网卡。如:`NCCL_SOCKET_IFNAME=bond0,eth0`。 **NCCL_IB_HCA**: 该变量指定要用于通信的 RDMA 接口。使用IB通信必须要设置的(指定NCCL使用的IB网卡)。 可以通过 ibstat 查看IB网卡名。 用法: 定义一个前缀列表来过滤要由 NCCL 使用的接口。使用 ^ 符号,NCCL 将排除以列表中任何前缀开头的接口。还可以使用 : 符号来指定特定的端口。要匹配(或不匹配)确切的接口名称而不是前缀,在字符串前面加上 = 字符。 示例: - `mlx5`:使用以 mlx5 开头的所有卡的所有端口。 - `=mlx5_0:1,mlx5_1:1`:使用卡 mlx5_0 和 mlx5_1 的端口 1。 - `^=mlx5_1`:不使用卡 mlx5_1。 比如: NCCL_IB_HCA=mlx5_2,mlx5_3,mlx5_4,mlx5_5 >注意: > > 如果不加前缀 =,使用 mlx5_1 将同时选择 mlx5_1 和 mlx5_10 到 mlx5_19(如果存在)。因此,始终建议添加前缀 = 以确保精确匹配。 使用建议: 通过这个环境变量可以调整NIC(Network Interface Controller)数量,NIC 通常是一块插入计算机主板上的扩展卡,更多NIC,节点带宽更大。通过控制NIC数量可以控制节点间通信带宽。 **NCCL_IB_TIMEOUT**: 该变量用于控制InfiniBand Verbs超时。取值范围1-22。 超时时间的计算公式为4.096微秒 * 2 ^ timeout,正确的值取决于网络的大小。增加该值可以在非常大的网络上提供帮助,例如,如果NCCL在调用ibv_poll_cq时出现错误12。 使用建议: 在大模型训练任务中设置成最大值22,可以减少不少nccl timeout异常。 **NCCL_IB_RETRY_CNT** 该变量控制 InfiniBand 的重试次数。 使用建议: 在大模型训练任务中设置成13,尽可能多重试。 **NCCL_PXN_DISABLE**: 禁止使用非本地 NIC 的进行节点间通信,使用 NVLink 和一个中间 GPU。 使用建议: 设置成1。在PyTorch中进行跨节点all-to-all通信时,如果该环境变量是0会出现异常。 **NCCL_DEBUG_FILE**: 设置一个文件地址,变量用于将NCCL的调试日志输出到文件中,有助于调试NCCL。 **NCCL_IB_PCI_RELAXED_ORDERING**: 启用 IB Verbs 传输的 Relaxed Ordering。Relaxed Ordering可以极大地提高虚拟化环境下 InfiniBand 网络的性能。 传统的顺序执行(Strict Ordering)要求数据在发送和接收之间按照严格的顺序进行传输和处理。这种机制可以确保数据的顺序性,但可能会导致性能瓶颈,特别是在高负载和复杂通信模式下。 而Relaxed Ordering允许数据在发送和接收之间进行乱序传输和处理。这意味着系统可以更灵活地调度和处理数据,提高并行性和吞吐量。Relaxed Ordering 机制在虚拟化环境中尤其有益,因为它可以减少虚拟机之间的争用和延迟,提高整体性能。 接受的取值: - 设置为 2,如果可用,自动使用Relaxed Ordering。 - 设置为 1,强制使用Relaxed Ordering,如果不可用,则失败。 - 设置为 0,禁用使用Relaxed Ordering。 默认值为 2。建议设置成 1。 **NCCL_SHM_DISABLE**: 该变量禁用共享内存(SHM)传输。 在P2P不能生效的情况下,是否使用CPU的共享内存来传输数据。 当 SHM 禁用时,NCCL 使用网络( InfiniBand 或 IP sockets)在 CPU sockets 之间进行通信。 ## InfiniBand 在 AI 集群中的应用 ### GPUDirect 简介 GPUDirect 是 NVIDIA 开发的一项技术,可实现 GPU 与其他设备(例如网络接口卡 (NIC) 和存储设备)之间的直接通信和数据传输,而不涉及 CPU。 传统上,当数据需要在 GPU 和另一个设备之间传输时,数据必须通过 CPU,从而导致潜在的瓶颈并增加延迟。使用 GPUDirect,网络适配器和存储驱动器可以直接读写 GPU 内存,减少不必要的内存消耗,减少 CPU 开销并降低延迟,从而显著提高性能。GPU Direct 技术包括 GPUDirect Storage、GPUDirect RDMA、GPUDirect P2P 和 GPUDirect Video。 ### GPUDirect 发展简史 - GPUDirect Shared Memory (2012) : Nvidia在PCIe上实现了单机上的GPUDirect Shared Memory 技术; - GPUDirect P2P (2014): Nvidia在PCIe上实现了单机上的GPUDirect P2P技术; - NVLink(2014) :解决了单机多卡通信时PCIe瓶颈问题; - GPUDirect RDMA(2014):提升多机多卡通信性能; ### GPUDirect Peer to Peer(P2P)简介 GPUDirect Peer-to-Peer(P2P) 技术主要用于单机GPU间的高速通信,它使得**GPU可以通过PCI Express直接访问目标GPU的显存**,避免了通过拷贝到CPU host memory作为中转,大大降低了数据交换的延迟。 以深度学习应用为例,主流的开源深度学习框架(如:TensorFlow、MXNet)都提供了对GPUDirect P2P的支持,NVIDIA开发的NCCL(NVIDIA Collective Communications Library)也提供了针对GPUDirect P2P的特别优化。 通过使用GPUDirect P2P技术可以大大提升深度学习应用单机多卡的扩展性,使得深度学习框架可以获得接近线性的训练性能加速比。 ### GPUDirect RDMA 简介 所谓 GPUDirect RDMA,就是计算机1的GPU可以直接访问计算机2的GPU内存。而在没有这项技术之前,GPU需要先将数据从GPU内存搬移到系统内存,然后再利用RDMA传输到计算机2,计算机2的GPU还要做一次数据从系统内存到GPU内存的搬移动作。GPUDirect RDMA技术使得进一步减少了GPU通信的数据复制次数,通信延迟进一步降低。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/02ea5dd1ecf746cbaa6628ae78bf8db6~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=3840&h=2160&s=192623&e=png&a=1&b=2083bd) 使用 GPUDirect RDMA 两个 GPU 设备必须共享相同的上游 PCI Express root complex。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f4c74697fc854927bc45a2dbc23aae6c~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=747&h=506&s=15351&e=png&b=ffffff) ## InfiniBand 在 NVIDIA DGX 集群中应用 **DGX-1 集群中应用 InfiniBand**: 下图展示了 DGX-1 配有四个 EDR InfiniBand 卡(每个 100 Gb/s)和两个 10Gb/s 以太网卡(铜质)。 这些网络接口可用于将 DGX-1 连接到网络以进行通信和存储。 每两个 GPU 都连接到系统板上的一个 PCIe 交换机。 该交换机还连接到 InfiniBand (IB) 网卡。 为了减少延迟并提高吞吐量,来自这两个 GPU 的网络流量应流向关联的 IB 卡。 这就是 DGX-1 设备中有四张 IB 卡的原因。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e2af36e854ea4ce8ac99993d861ae893~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1280&h=482&s=1854438&e=png&b=fefefe) 如果您想使用InfiniBand(IB)网络连接DGX设备,理论上,您只需使用其中一张IB卡即可。 然而,这些数据流量将强行通过 CPU 之间的 QPI 链路,这对于 GPU 流量来说是一个非常慢的链路(即,它成为瓶颈)。更好的解决方案是使用两张 IB 卡,一张连接到每个 CPU。这可以是 IB0 和 IB2,或者 IB1 和 IB3,或者 IB0 和 IB3,或者 IB1 和 IB2。 这将大大减少必须穿越 QPI 链路的流量。 最佳性能始终是使用 IB 交换机的所有四个 IB 链路。 使用 IB 链路是将所有四个 IB 卡连接到 IB 结构的最佳方法。 如果您使用多个 DGX 设备进行训练,这将带来最佳性能(完全的平分带宽和最低延迟)。 通常,最小的 IB 交换机配有 36 个端口。 这意味着单个 IB 交换机可容纳使用全部四张 IB 卡的九个 DGX-1 设备。 这允许从 DGX-1 到交换机的带宽为 400 Gb/s。 如果您的应用程序不需要 DGX-1 设备之间的带宽,则可以如前所述为每个 DGX-1 使用两个 IB 连接。 这允许您将最多 18 个 DGX-1 设备连接到单个 36 端口 IB 交换机。 注意:**不建议仅使用单个 IB 卡**,但如果由于某种原因采用这种配置,则您最多可以将 36 个 DGX-1 设备连接到单个交换机。 对于大量 DGX-1 设备,您可能必须使用两级交换网络。 经典的 HPC 配置是在第一级使用 36 端口 IB 交换机(有时称为叶子(Leaf)交换机),并将它们连接到单个大型核心交换机,有时称为导向器级(director class)交换机。 最大的导向器级InfiniBand交换机有648个端口。当然您也可以使用多个核心交换机,但配置会变得相当复杂。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d0a6402a97d14a18ba3ea1f39c4c1337~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=763&h=720&s=1651546&e=png&b=fefefe) 对于两级交换网络,如果每个 DGX-1 设备的全部 4 个 IB 卡都用于连接到 36 端口交换机,并且没有过度订阅,则每个交换机的 DGX-1 设备的最大数量为 4。这时每个 DGX-1 有 4 个端口进入交换机,总共 16 个端口。然后,从叶子交换机到核心交换机(导向器级交换机)有 16 个上行链路。总共 40 台 36 端口叶子交换机可连接到 648 端口核心交换机 (648/16)。 这导致 160(40 * 4) 个 DGX-1 设备(共640卡)以全对分带宽连接。 当然您还可以在设计 IB 网络时使用所谓的过度订阅。过度订阅意味着来自**上行链路的带宽小于进入设备的带宽**(换句话说,带宽性能较差)。如果我们使用从 DGX-1 设备到第一级交换机(36 端口叶交换机)的 2:1 超额订阅,则每个 DGX-1 设备仅使用两个 IB 卡连接到交换机。与使用所有四张卡相比,这会导致带宽更少,并且延迟也会更高。 如果我们保持从叶子交换机到核心交换机的网络带宽为 1:1(换句话说,没有过度订阅,全对分带宽),那么我们可以将九个 DGX-1 设备放入一个单叶子交换机(从 DGX 设备到叶子交换机的总共 18 个端口以及到核心交换机的 18 个上行链路端口)。结果是总共36(648/18)台叶子交换机可以连接到核心交换机。 这使得总共 324(36 * 9) 个 DGX-1 设备可以连接在一起。 您还可以通过使用从叶子交换机到核心交换机的超额订阅来进一步定制 IB 网络。 这可以通过**使用每个 DGX 设备到叶子交换机的四个 IB 连接**,然后对核心交换机进行 2:1 超额订阅,甚至使用到叶子交换机的两个 IB 连接,然后对核心交换机进行 2:1 超额订阅来完成。 InfiniBand 网络的另一个重要方面是子网管理器 (SM)。 SM仅管理IB网络。 任何时候都有一个 SM 管理 IB 结构,但您可以让其他 SM 运行并准备好在第一个 SM 崩溃时接管。 选择运行多少个 SM 以及在何处运行它们会对集群的设计产生重大影响。 首先要做的决定是**在哪里运行 SM**。 如果您愿意,它们可以在 IB 交换机上运行。 这称为硬件 SM,因为它在交换机硬件上运行。 这样做的优点是您不需要任何其他也可以运行 SM 的服务器。 在节点上运行 SM 称为软件 SM。 运行硬件 SM 的一个缺点是,如果 IB 流量很大,SM 可能会遇到困难。 对于大量 IB 流量和较大的网络,最佳实践是在专用服务器上使用软件 SM。 要做的第二个决定是您**想要运行多少个 SM**。 您至少必须运行一个 SM。 最便宜的解决方案是运行单个硬件 SM。 这对于 DGX-1 设备的小集群(可能是 2-4 个)来说效果很好。 随着单元数量的增加,您将需要考虑同时运行两个 SM 以获得 HA(高可用性)功能。 您需要 HA 的原因是集群上有更多用户,并且集群故障比少量设备故障产生的影响更大。 随着设备数量的增长,请考虑在专用服务器(软件 SM)上运行 SM。 您还需要为集群运行至少两个 SM。 理想情况下,这意味着 SM 有两台专用服务器。 **DGX SuperPOD 中广泛应用InfiniBand**: 下图为 DGX A100/H100 256 SuperPOD 网络拓扑图: ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fe23e909b133481a9255d546cbd8992d~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1570&h=552&s=627571&e=png&b=fdfbfb) 下图为 DGX A100/H100 1K POD 网络拓扑图: ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/375e5847ec8040f0a426078c216c352d~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1640&h=488&s=388989&e=png&b=fdfcfc) ## InfiniBand 在 AI 框架中的应用 在之前文章([AI 集群基础设施 NVMe SSD 详解](https://juejin.cn/post/7311604023184162835))中谈到了 NVMe 在 DeepSpeed 中的应用。DeepSpeed 通过 ZeRO-Infinity 技术尝试**利用 NVMe 的空间进一步打破内存墙的限制训练超大模型**。除此之外,该方法也充分利用了InfiniBand网络进行多机通信,具体如下图所示。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cc71d99bd8a44f8b8f86e60909ee38a7~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1280&h=716&s=3672639&e=png&b=fbfbfb) 另外,像NCCL、Gloo等集合通信库都继承了InfiniBand,Pytorch框架也能够通过通信库轻松应用InfiniBand进行分布式训练。 ## 总结 本文讲述了AI集群通信的软硬件;同时,针对NCLL集合通信库以及InfiniBand网络通信技术协议进行了更为详细的介绍;另外,也讲述了AI集群以及AI框架中对于InfiniBand的应用。 码字不易,如果觉得有帮助,欢迎点赞收藏加关注。 ## 参考文档 - [带你了解PCIE通信原理](https://zhuanlan.zhihu.com/p/454282470) - [电脑硬件冷知识:主板北桥芯片为何消失了,南桥也有同样的命运?](https://zhuanlan.zhihu.com/p/662904805) - [必看: 原来PCIe技术原理这么简单](https://mp.weixin.qq.com/s/FlRc2q8r0fUOzxJFWulGfw) - [AI网络互联,PCIe还是NVLink?](https://www.sdnlab.com/26316.html) - [RDMA技术原理分析、主流实现对比和解析](https://www.sohu.com/a/229080366_632967) - [详谈RDMA技术原理和三种实现方式](https://mp.weixin.qq.com/s/FgKjDjZsPlweVJ03OVr3SA) - [RDMA技术详解——RDMA的三种实现方式](https://blog.csdn.net/u013253075/article/details/119843611) - [【英伟达官网】线缆和收发器](https://www.nvidia.cn/networking/interconnect/) - [DAC高速线缆和AOC有源光缆有什么区别呢?](http://www.rhopto.com/articles/dacgsx.html) - [你会区分光模块和光纤收发器吗?](https://www.etulink.com/blog/-_b268) - [都是光电转换作用,光模块和光纤收发器有什么区别?](https://zhuanlan.zhihu.com/p/139294038) - [态路小课堂丨关于InfiniBand网络相关内容简介!](https://baijiahao.baidu.com/s?id=1760941961023057651&wfr=spider&for=pc) - [态路小课堂丨InfiniBand AOC有源光缆简介](https://blog.51cto.com/u_14408894/8031135) - [InfiniBand,到底是个啥?](https://mp.weixin.qq.com/s?__biz=MzI1NTA0MDUyMA==&mid=2456692454&idx=1&sn=031a11b931edee5504b15045cd863d37&chksm=fda68b81cad10297e4dd53bc97f63e0c47c26a27cdbb3c584cce6fc49fc6b4367b1531cbfcb6&scene=0&xtrack=1#rd) - [NVIDIA MLNX_OFED Documentation v5.8-3.0.7.0.101 for DGX H100 Systems](https://docs.nvidia.com/networking/display/mlnxofedv583070101/introduction) - [NCCL 环境变量](https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/env.html) - [大模型训练场景下NCCL环境变量设置](https://zhuanlan.zhihu.com/p/653001915) - [【GitHub】CUDA_GPU详细介绍](https://github.com/FelixFu520/README/blob/main/envs/pytorch/cuda_gpu.md) - [GPU卡的底层通信原理](https://www.jianshu.com/p/e40059d5c832) - [NVIDIA ConnectX InfiniBand 网卡](https://www.nvidia.cn/networking/infiniband-adapters/) - [H3C IB网卡常用命令](https://www.h3c.com/cn/d_202007/1317229_30005_0.htm#_Toc46935211) - [IB常用命令](https://blog.csdn.net/weixin_42319496/article/details/125942763) - [浅析GPU通信技术(上)-GPUDirect P2P](https://developer.aliyun.com/article/591403) - [浅析GPU通信技术(下)-GPUDirect RDMA](https://developer.aliyun.com/article/603617) - [GPUDirect RDMA 12.3 文档](https://docs.nvidia.com/cuda/gpudirect-rdma/index.html) - [【大模型训练】RDMA高速网络与集合通讯](https://zhuanlan.zhihu.com/p/622853211) - [百度智能云-NCCL环境搭建](https://cloud.baidu.com/doc/GPU/s/Yl3mr0ren) ================================================ FILE: blog/ai-infra/AI 集群基础设施 NVMe SSD 详解.md ================================================ 随着 AI 和 HPC 数据集的大小不断增加,为给定应用程序加载数据所花费的时间开始对整个应用程序的性能造成压力。 在考虑端到端应用程序性能时,快速的 GPU 通过缓慢的 I/O 将显著降低GPU的利用率。 I/O 是将数据从存储加载到 GPU 进行处理的过程,历来由 CPU 控制。 随着计算从较慢的 CPU 转移到更快的 GPU,I/O 越来越成为整体应用程序性能的瓶颈。 正如 GPUDirect RDMA(远程直接内存地址)在网络接口卡 (NIC) 和 GPU 内存之间直接移动数据时改善了带宽和延迟一样,一种名为 GPUDirect Storage 的新技术支持本地或远程存储(例如:NVMe 或 NVMe over Fabric (NVMe-oF))与GPU 内存之间的直接移动数据。 本文将针对硬盘的发展、NVMe的技术原理以及NVMe在AI服务器及DeepSpeed框架中的应用进行详细的介绍。 > 文章较长,建议先点赞收藏,后续再慢慢观看。另外,我撰写的**大模型相关的博客及配套代码**均整理放置在Github:[llm-action](https://github.com/liguodongiot/llm-action/tree/main),有需要的朋友自取。 ## 衡量硬盘传输速度的三大要素 要知道一块硬盘真正的性能,就要知道如何衡量一块硬盘速度?通常情况下,我们从以下三个方面进行评估:通讯协议(总线)、物理接口标准、传输通道。 ### 传输通道/总线 总线是计算机系统内部各个组件之间传输数据的通道。硬盘通过总线与其他系统组件(如主板、内存等)进行通信。总线的速度直接影响着硬盘的数据传输速度。 常见的总线/通道类型包括SATA(Serial ATA)和PCI Express。SATA是较为常见的硬盘连接总线,而PCI Express则通常用于更高性能的存储解决方案。其他的通道有SAS通道(企业级别硬盘用的通道)、FC通道(光纤通道)等。 ### 通讯协议 协议定义了数据在总线上的传输方式和规则。其内容主要包括设备间如何相互识别、如何建立链接、使用的讯号类型、数据的编码解码方式、数据传输的类型、数据传 输的方式以及物理层面上的电压、电流、保持时间和截止时间等。 只有当两个设备之间的协议相同或者相容时,才可以正常进行通讯。不同协议能够支持的最大传输速率也不同。 常见的通信协议如下: | 协议名称 | 应用场合 | 说明 | | :--: | :--: | :-----------------------------------------------------------------------------------------------------------------------------------------------------: | | IDE | 民用 | 机械硬盘时代,用于数据操作,传输的协议。目前已被淘汰。 | | AHCI | 民用 | 仍然是机械硬盘时代的主流数据传输协议。但SATA固态硬盘和极少数PCIe固态硬盘可以使用此协议,用SATA通道优化后的效率相比IDE提升10-30%。 | | NVMe | 民用 | 由于机械硬盘和固态硬盘的工作模式发生巨大变化,需要一种全新的针对固态的传输层协议,NVMe 应运而生。NVMe协议相比传统的AHCI协议具有更低的延迟和更高的数据传输速度,适用于高性能要求的应用。 | | SCSI | 服务器 | SCSI(Small Computer System Interface)协议是一种通用的存储协议,最初是一种并行接口,后来也演变为串行接口(SAS,Serial Attached SCSI)。 常见于企业级固态硬盘,消费级市场不常见。但其设计并非专门针对固态硬盘,可能在利用硬件特性方面不如NVMe。 | 不同的硬盘可以采用不同的数据传输协议。例如,SATA 上的硬盘通常使用AHCI(Advanced Host Controller Interface)协议,而PCIe(PCI Express)上的硬盘可能使用NVMe(Non-Volatile Memory Express)协议。 ### 物理接口 接口是硬盘与计算机或其他设备之间物理连接的方式。硬盘接口通常是指连接到主板的插槽或端口。常见的硬盘接口包括 M.2、SATA、PCI Express等。 不同的接口也会影响硬盘的数据传输速度,因为不同接口支持的总线和协议可能有所不同。 常见的硬盘接口类型: * **PCI Express(PCIe):** PCI Express接口用于连接高性能固态硬盘(NVMe SSD)和一些扩展卡。NVMe(Non-Volatile Memory Express)是一种用于固态存储的高效协议,通常与PCI Express接口结合使用,提供更高的传输速度和更低的延迟。 * **M.2(NGFF):** M.2是一种小型、高密度的接口,用于连接固态硬盘和一些无线通信设备。M.2接口通常支持**AHCI协议**(走SATA通道)和**NVMe协议**(走PCI Express通道),适用于轻薄型笔记本电脑和台式机。 * **SATA(Serial ATA):** SATA是目前最为普遍的硬盘接口之一,用于连接传统的机械硬盘(HDD)和固态硬盘(SSD)。它是一种串行数据传输接口,提供了不同版本,如:SATA I(1.5 Gbit/s)、SATA II(3 Gbit/s)、SATA III(6 Gbit/s)等。 * **SAS(Serial Attached SCSI):** SAS是一种用于连接企业级硬盘的接口,提供了更高的性能和可靠性。SAS接口通常用于服务器和存储系统,支持更高的数据传输速度和更多的同时连接。 * **mSATA:** mSATA是一种用于连接小型存储设备的接口,通常用于一些较老的笔记本电脑和嵌入式系统。它支持SATA。 * **IDE(PATA):** IDE(Integrated Drive Electronics)是一种较老的硬盘接口,也称为PATA(Parallel ATA)。这种接口用于连接传统的机械硬盘和光盘驱动器,已经逐渐被SATA接口所取代。 * **SCSI**:SCSI是一种用于连接计算机和外部设备的通用接口标准,也用于连接一些服务器和存储设备上的硬盘。SCSI有多个版本,包括并行SCSI和串行SCSI。 总之,硬盘接口技术在不断进化革新,从早期的IDE、SCSI接口到主流的SATA、SAS接口,再到M.2、PCIe接口。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d4f1e6d05a0c49b58a20a7593e74f8a5~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1144\&h=720\&s=2475831\&e=png\&b=fdfdfd) 可以看到,SATA、PCIe 即是一种**物理接口标准**,也是**总线(通道)标准**,其中,SATA接口使用AHCI通讯协议;PCIe接口通常使用NVMe通讯协议,也可以使用AHCI通讯协议。 ## 硬盘 ### 机械硬盘 机械硬盘(HDD)是一种带有机械马达结构的存储装置,主要带有马达、盘片、磁头、缓存。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0b870c11c5dd4bd3a5d2495e12958eed~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=920\&h=720\&s=1991213\&e=png\&b=eeeceb) ### 固态硬盘 固态硬盘(SSD)是一种不带有机械马达结构的存储装置,主要带有闪存、主控芯片、缓存。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b2098c24372f471c9caf6b9dc8540163~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=986\&h=577\&s=565723\&e=png\&b=fcfbfc) ### 固态硬盘外形尺寸 固态硬盘存在多种外形和尺寸,如:2.5 英寸、M.2、mSATA 和 U.2。 **2.5"(2.5 英寸)**:最常见的固态硬盘类型,适用于多数笔记本电脑或台式机。其外形类似传统机械硬盘 (HDD) 并通过 SATA 线缆连接,因此使用起来与众多现有产品非常类似。 **M.2**:另一种外形尺寸, M.2 已变成纤薄便携式计算机和笔记本电脑的标配存储类型。这种小巧的外形尺寸常常类似于一片口香糖,在多数情况下可轻松安装到主板上。它具备各种不同长度,可实现不同的固态硬盘存储容量;硬盘越长,可搭载的 NAND 闪存芯片越多,从而实现更高存储容量。 **mSATA**:mSATA 或 mini-SATA 是全尺寸 SATA 固态硬盘的缩小版。它像 M.2 一样使用紧凑的外形尺寸,但两者不可互换。M.2 硬盘支持 SATA 和 PCIe 两种接口选项,而 mSATA 仅支持 SATA。这种外形尺寸专为空间受限的小型系统设计。 **U.2** :它看起来像 2.5 英寸硬盘,但略微厚一点。它使用不同的连接方式,并通过 PCIe 接口发送数据。U.2 固态硬盘技术通常用于需要更大存储容量的高端工作站、服务器和企业应用。它支持更高工作温度,比 M.2 外形尺寸更利于散热。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0b07f53e501e46ec9a9ae22bbddc2214~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=450\&h=800\&s=163542\&e=png\&b=ffffff) ### 固态硬盘接口类型 常见的固态硬盘接口类型: * **SATA(Serial ATA):** SATA接口是一种常见的硬盘接口,广泛用于连接传统的机械硬盘和固态硬盘。SATA接口有不同的版本,包括:SATA I(1.5 Gbit/s)、SATA II(3 Gbit/s)、SATA III(6 Gbit/s)等。 * **PCI Express(PCIe):** PCI Express接口是一种高速串行总线,用于连接固态硬盘和其他高性能设备。通过PCIe接口连接的固态硬盘通常使用NVMe(Non-Volatile Memory Express)协议,提供更高的数据传输速度和更低的延迟。 * **M.2(NGFF):** M.2是一种小型、高密度的接口,广泛用于连接固态硬盘和无线通信设备。M.2接口支持SATA和PCI Express协议,适用于轻薄型笔记本电脑和台式机。 * **mSATA:** mSATA是一种较老的小型接口,用于连接固态硬盘。它采用SATA协议,通常用于一些较老的笔记本电脑和嵌入式系统。 * **U.2:** U.2是一种适用于企业级硬盘的接口,支持SATA和PCI Express协议。U.2接口通常用于连接高性能企业级固态硬盘,提供更大的功率和散热能力。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/58606ac104bc4a09b9db26560d488277~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=500\&h=300\&s=121643\&e=png\&b=fcfbfb) ### M.2 固态硬盘类型 M.2 固态硬盘包含 SATA 和 NVMe(使用PCIe) 两种类型。 注意:M.2 固态硬盘仅兼容支持 M.2 插槽的主板。检查计算机的主板,确保包含 M.2 插槽。 M.2接口类型分为Socket 2和Socket 3: * Socket 2:也可以叫做B key,支持sata,pcie x2 通道。 * Socket 3:也可以叫做M key,支持sata,pcie x4 通道。 一开始,B key的只能插在B key(Socket 2)的接口中,M key的只能插在 M key(Socket 3)的接口中,但是**随着M key接口的普及,越来越多电脑主板只有M key 接口,B key的固态硬盘根本插不上去,于是厂商们又设计了一个B\&M key接口的固态硬盘(SSD)**。 B\&M key接口即可以插上B key也可以插上M key。**B\&M key支持的通道和B key支持的通道一样,都是sata和pcie x2 通道**,但是 **B\&M key可以兼容 M key 和 B key两种,而B key只能兼容B key一种,这就导致了B key毫无优势,B key被B\&M key取代**,现在市面上只有B\&M key和M key两种M.2 ssd卖, B key的 M.2 SSD 已经绝迹。 注意:固态硬盘(SSD)的金手指有B key,B key ,B\&M key三种,但是主板上的M.2接口只有B key和M key两种。 **SATA M.2 固态硬盘**: **SATA 固态硬盘是性能最低的固态硬盘,采用的接口与机械硬盘相同**。尽管如此,SATA 固态硬盘的带宽是旋转式机械硬盘的三到四倍。SATA M.2 固态硬盘使用的 SATA 接口最大数据传输速率为 6Gbps。SATA 固态硬盘比 NVMe 固态硬盘更加普及、更加便宜。如果计算机没有空间安装 2.5 英寸固态硬盘,SATA M.2 固态硬盘可能是 2.5 英寸固态硬盘的出色替代选项。  如图所示,同时具有 M 键和 B 键的 M.2 固态硬盘将是 SATA 固态硬盘。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2e453a69c4e34355bd553d859b5ef721~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=450\&h=250\&s=169390\&e=png\&b=e1e5e9) SATA 一直是用于存储技术的主要接口。使用 SATA 线缆的 SATA 硬盘需要两根线缆才能工作。一根用于将数据传输到主板,另一根用于连接 PSU(电源)。当使用多个 SATA 存储硬盘时,杂乱无章的线缆是可能影响 PC 机箱性能的问题之一。包括超级本在内的纤薄笔记本电脑和便携式计算机甚至没有空间来安放 SATA 线缆,所以需要采用 M.2 的外形尺寸。SATA M.2 外形尺寸的固态硬盘解决了这个问题,它没有其他 SATA 存储硬盘所使用的两个线缆连接。 **NVMe M.2 固态硬盘**: 如图所示,只有 M 键的 M.2 固态硬盘将是 NVMe 固态硬盘。  **NVMe M.2 固态硬盘采用了专为固态硬盘设计的 NVMe 协议**。与 PCIe 总线配合,NVMe 固态硬盘可以提供市面上最新水平的性能和速度。NVMe 固态硬盘利用 PCIe 插槽直接与系统 CPU 进行通信。基本上,它让闪存可以作为固态硬盘通过 PCIe 插槽进行运行,而不必使用速度比 NVMe 慢得多的 SATA 通信驱动程序。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/090ec4516e6e474491c5fd07969ac893~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=450\&h=550\&s=355389\&e=png\&b=f1f3f7) NVMe M.2 固态硬盘的性能比 SATA M.2 固态硬盘高得多。通过利用 PCIe 总线,NVMe M.2 固态硬盘拥有高达 20Gbps 的理论传输速度,比 SATA M.2 固态硬盘的 6Gbps 快。**PCIe 总线支持 1x、4x、8x 和 16x 通道**。PCIe 3.0 的有效传输速度高达每通道 985 MB/秒,这意味着潜在传输速度高达 16GB/秒。不过,**当使用 M.2 外形尺寸与 PCIe 总线时,只能访问 x2 和 x4 通道**,这使得最大传输速度为 4GB/秒。 **SATA 固态硬盘与 NVMe M.2 固态硬盘的区别**: SATA 固态硬盘与 NVMe M.2 固态硬盘之间的主要区别在于接口技术和性能水平。SATA M.2 固态硬盘仍然采用 SATA 接口设计,这无法改进速度与性能,毕竟这不是 NVMe M.2 固态硬盘。 NVMe允许SSD通过PCIe总线直接连接到CPU以通过高速通道传输数据。单个第四代PCIe通道可以传输高达**2,000 MB/s**的数据,NVMe SSD最多使用其中四个。相比之下,SATA只有一个lane,最高可以传输**600MB/s**。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8daa735866ed40eb8be6a293ff2dda77~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1508\&h=596\&s=336666\&e=png\&b=d9e2fb) SATA SSD AHCI驱动程序只有一个可用队列,每个队列有32个命令。而 NVMe 允许多达65,535个队列,每个队列的最大深度为65,536个命令。 使用NVMe技术,由于I/O处理门铃信号的高性能,CPU可以更有效地管理队列,从而降低CPU开销。低CPU开销会导致CPU周期减少。相比之下,SATA SSD在I/O处理中产生较高的CPU周期。 与SATA SSD相比,NVMe技术缩短和优化了数据路径,从而降低了延迟。它产生大约2.8微秒的延迟,而SATA SSD有大约6微秒的延迟——比NVMe SSD长了近3微秒。 NVMe SSD最适合企业工作负载处理和人工智能、机器学习项目、实时分析、大数据传输和DevOps。它们通常用于数据中心、高端笔记本电脑和预制台式电脑。而 SATA SSD 最适合小数据分析和各种轻量级存储应用程序。它们主要用于预算笔记本电脑和服务器。 在价格方面,与SATA SSD相比,NVMe SSD更贵。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c4d9099fe41641d28489fa59350d9179~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1510\&h=568\&s=401661\&e=png\&b=d8e0fb) 总之,由于 NVMe 利用 PCIe 插槽,它传输的数据量是同等 SATA 产品的 25 倍。除了更多数据,NVMe 命令的速度是 AHCI 驱动程序命令的 2 倍。此外,NVMe 的每秒输入/输出操作 (IOPS) 超过 100 万,是 AHCI 硬盘的 900%。得益于自身的兼容性,NVMe 还直接与系统 CPU 通信,具有惊人的速度。同时,NVMe 硬盘兼容所有主要的操作系统。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f8d2effd638e41988430717dd9436606~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=992\&h=620\&s=86030\&e=png\&b=ffffff) **通信驱动器程序:AHCI 与 NVMe 对比**: 通信驱动程序被操作系统用来与存储设备交换数据。NVMe 驱动程序比常见于 SATA 接口的 AHCI 驱动程序速度快。 * NVMe专为采用闪存技术的 SSD 设计,速度远超专为采用旋转磁盘技术的普通机械硬盘设计的 AHCI 驱动程序。 * NVMe 拥有 64000 个命令队列,可以每个队列发送 64000 条命令,而 AHCI 只有一个命令队列,每个队列只能发送 32 条命令。 * 利用 AHCI 驱动程序,命令利用高 CPU 周期,延迟为 6 微秒,而 NVMe 驱动程序命令利用低 CPU 周期,延迟为 2.8 微秒。 NVMe驱动程序直接与系统 CPU 通信,而 AHCI 必须与 SATA 控制器通信。AHCI 的 IOPS(每秒输入/输出操作)最高 10 万,而 NVMe 的 IOPS 超过 100 万。IOPS(每秒输入/输出操作,发音是 i-ops)是用来对计算机存储设备进行基准测试的常见性能衡量指标。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5eb17b23064f4b9ea40d8331a5f5056b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=932\&h=874\&s=368173\&e=png\&b=fbfbfb) ### 常见硬盘规格 | 名称 | 接口 | 总线 | 协议 | 接口理论速率上限 | | -------------- | ------------ | --------- | ---- | -------- | | 西部数据蓝盘1TB | SATA | SATA3.0 | AHCI | 600MB/s | | 固态铠侠TC10(SATA) | SATA | SATA3.0 | AHCI | 600MB/s | | 三星860EVO(M.2) | M.2 B\&M-Key | SATA3.0 | AHCI | 600MB/s | | 三星SM951(AHCI) | M.2 M-Key | PCIe3.0×4 | AHCI | 4GB/s | | 三星XP941 | M.2 M-Key | PCIe2.0×4 | NVMe | 2GB/s | | 西部数据SN500 | M.2 B\&M-Key | PCIe3.0×2 | NVMe | 2GB/s | | 西部数据SN750 | M.2 M-Key | PCIe3.0×4 | NVMe | 4GB/s | | 三星980PRO | M.2 M-Key | PCIe4.0×4 | NVMe | 8GB/s | | 三星983ZET | PCIe | PCIe3.0×4 | NVMe | 4GB/s | | Intel SSD I910 | PCIe | PCIe2.0×8 | SCSI | 4GB/s | | 希捷银河4T | SAS | SAS3.0 | SCSI | 1.2GB/s | | Intel P4510 | U.2 | PCIe3.0×4 | NVMe | 4GB/s | ## NVMe ### NVMe 简介 NVMe (non-volatile memory express)是一种高性能、NUMA(非统一内存访问)优化的、高度可扩展的**存储协议**,用于连接主机和内存子系统。NVMe是专门为NAND、闪存等非易失性存储设计的,NVMe协议建立在高速PCIe通道上。它可以使我们能够充分利用SSD和存储类内存(SCM)的速度。 ### NVMe 的主要特征 1. 为PCIe制定的标准接口协议。解除了旧标准施放在SSD上的各种限制。 2. 支持所有常见的操作系统。 3. 良好的可拓展性。 4. 采用多队列设计,支持64K命令队列:提高数据传输速度,因为数据是利用芯片和块以分散形式写入 SSD 的,而不是像机械硬盘一样在旋转的磁盘上写入数据。 5. 可以使用低CPU周期为每个队列发送64K命令; 6. 延迟约为2.8微秒; 7. 可以直接与系统CPU通信; 8. 可以实现超过一百万的IOPS。 ### NVMe 的发展史 在过去的十年中,存储技术发生了翻天覆地的变化。随着固态硬盘开始取代机械硬盘成为主要的存储设备,我们急需一个新的接口标准来利用更快的速度和功能。 传统的SATA接口与AHCI标准其实是为了机械硬盘而设计的,早期的SSD性能不高,即使使用这些传统的接口和协议,也不觉得有什么问题,但是随着SSD的性能逐渐增强,传统的标准已经不再适用,进而成为了限制SSD的一大瓶颈。NVMe是第一个真正满足高速存储介质需求的协议。 2009年下半年,NVM Express工作组(NVMHCI)开始制定NVMe规范,NVM Express工作组包含90多家公司成员,Intel是主要领头人,小组成员包括美光、戴尔、三星、Marvell、NetAPP、EMC、IDT等公司,目的就是为SSD建立新的存储规范标准,让它在老旧的SATA与AHCI中解放出来。 2011年,NVMe 1.0标准正式出炉,该标准是根据闪存存储的特点量身定制的,新的标准解除了旧标准施放在SSD上的各种限制。2012、2014、2017和2019年相继推出了1.1、1.2、1.3、1.4版本。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/81425d6ef93342c898e74859f98201ae~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2130\&h=880\&s=631178\&e=png\&b=fefefe) NVMe从1.0发展到1.4,逐渐形成 **NVMe Base Specification(NVMe)、NVMe Management Interface Specification(NVMe-MI)和NVMe Over Fabrics Specification(NVMe-oF)** 三大Spec合集,它们看似独立,但又彼此关联,相互依赖。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ab898d2fa3ce4d51a122fee21eb0e645~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1023\&h=590\&s=95570\&e=png\&b=fefefe) 随着Spec的增多,如何组织这些Spec就成了新的问题。在NVMe 1.4架构下,如果想要添加新的命令集,或区分不同的Transports协议,使用当前Spec架构就会带来诸多不便,牵一发而动全身。因此,NVMe 2.0最重要的使命,就是通过对Spec结构进行调整以方便在最小化已有方案影响的前提下进行新的开发。 新的Spec架构更加趋于模块化,将Commend Set和Transport Spec从原有三大合集中独立出来,与Base Spec、NVMe-MI一同,构成了新的NVMe 2.0协议族,也方便未来有更多新的功能添加进来。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/21e1e6838355412f8d3d8b2e9acfbeae~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1080\&h=304\&s=79723\&e=png\&b=f9f1f0) 此外,NVM Express还对NVMe设备的启动做了规范(NVM Express Boot Specification)。因此,最新的NVMe协议族如下: ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/31e56e5c1c474334a13de29b59c56757~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1025\&h=426\&s=84180\&e=png\&b=efe8e2) | 名词 | 说明 | | ------------------------------------------------------------ | -------------------------------------------- | | I/O Command Set Specifications | 定义扩展NVM Express基本规范的数据结构、功能、日志页、命令和状态值。 | | NVM Express Base Specification | 定义了主机软件通过各种基于存储器的传输和基于消息的传输与非易失性存储器子系统通信的协议。 | | Transport Specifications | 定义包括控制器属性的NVMe协议到特定传输的绑定。 | | The NVM Express Management Interface (NVMe-MI) Specification | 定义了所有NVM Express子系统的可选管理接口。 | | NVM Express Boot Specification (NVMe Boot) | 定义了从NVM Express接口启动的结构和指南。 | 2021年,NVMe 2.0 协议族证书发布,它由8个具体的协议规范组成,其中,**NVM Command Set、Zoned Namespace Command Set、Key Value Command Set**共同组成了新的Command Set 协议族,Transport Spec 也被细分为PCIe、RDMA和TCP三种。 **NVM Commend Set Spec、PCIe Transport Spec** 是NVMe最开始想要实现的目标,在此基础上又有6个Spec被开发出来,可见NVMe的技术发展确实是非常快的。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d170dac1e7314181a8a83aa7f81d4b0f~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1040\&h=401\&s=81203\&e=png\&b=fdfdfd) NVMe 2.0定义了3种命令类型:**Admin命令、I/O命令和Fabrics命令**。作用跟之前版本一样。 * Admin命令用于控制器的管理,有专用的Admin SQ/CQ来实现命令传递。 * I/O命令使用I/O SQ/CQ,如我们熟悉的读和写,都由I/O命令完成,在NVMe 2.0协议族中,I/O命令集又分为**NVM命令集、Zoned Namespace命令集和Key Value命令集**三种。 * Fabrics命令则专用于NVMe over Fabrics。 NVMe Transport是基于物理连接属性抽象的协议层,分为Memory-Based、Message-Based、Message/Memory混合型。 * **Memory-Based Transport**:指Host和NVM Subsystem之间的命令、应答和数据是由显性的内存读写命令来完成的,代表协议:NVMe over PCIe Transport Spec。 * **Message-Based Transport**:指Host和NVM Subsystem之间通过发送Message封装命令和响应数据,代表协议:Fiber Channel、TCP Transport Spec。 * **Message/Memory 混合型 Transport**:组合使用Message和显性的内存读写命令,代表协议:RDMA Transport Spec。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a094e5b008ac4ac9aa499115b34d185f~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=906\&h=365\&s=104141\&e=png\&b=fffefe) ### NVMe SSD 外形尺寸 NVMe SSD 存在多种不同的外形尺寸,但具体取决于用例或应用。 * 个人/客户端产品使用 BGA 和 M.2 外形尺寸。 * 数据中心/服务器应用使用 M.2、U.2、U.3 和 EDSFF 外形尺寸。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/889afa23013847d8b1d58db88e041d17~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=900\&h=430\&s=124121\&e=png\&b=eeeeee) ### NVMe 协议在协议栈中的位置 NVMe是一种Host与SSD之间通讯的协议,它在协议栈中隶属高层。NVMe在协议栈中处于应用层,底层通常是PCIe协议栈,NVMe协议能够正常运行,是依赖于底层PCIe协议提供的一些功能,而PCIe协议是目前计算机硬件与CPU之间互联互通的关键,诸如网卡、显卡等等都在利用这套协议,可以说底层利用PCIe协议栈是最简单快速的方法。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0226f894935a4b1d95a774f502d36cdf~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1320\&h=696\&s=448777\&e=png\&b=faf9f9) 理论上,NVMe协议不一定跑在PCIe协议栈之上,只要底层能够完成同样的任务,替换成别的协议框架也是可以的,就比如把NVMe移植到手机上,就可能发生一些变化。 **NVMe over Fabrics**就换掉了NVMe下层部分协议,具体如下图所示。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4d6b132435764979bab986f5885b5127~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=720\&h=565\&s=71985\&e=png\&b=8d8d8d) ### NVMe 命令 NVMe制定了Host与SSD之间通讯的命令,NVMe有两种命令: * 一种叫Admin Command,用于Host管理和控制SSD; * 另外一种就是I/O Command,用于Host和SSD之间数据的传输。 ### NVMe 队列 NVMe 的队列分为2种,其中一种是用于管理的队列,称为Admin Queue(管理队列),仅有一个,另外一种是命令队列(Command Queue),最多可以有65535个。 其中,命令队列的数量和模式都是通过管理队列来设置的。每一个队列实际上是一个队列对,也就是包括两个队列,分别是提交队列(Submission Queue)和完成队列(Completion Queue)。**提交队列**用于主机端向NVMe设备发送NVMe命令,而**完成队列**则用于NVMe设备向主机反馈命令执行情况。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7028fa5e992d468baff80a2287ae9a0e~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=552\&h=202\&s=122591\&e=png\&b=e3e2e2) * Admin Submission Queue和对应的Admin Completion Queue用来管理和控制主控器(如:创建和删除IO队列,终止命令等),只有属于Admin Command Set的命令才会被提交到Admin Submission Queue。Admin Queue的ID都是0。 * IO Submission Queues和对应的IO Completion Queues用来处理IO命令,规范定义了一种IO Command Set,叫做NVM Command Set,与IO队列一起使用。系统在创建Submission Queue前必须先创建相关的Completion Queue,同时,删除Submission Queue操作也要先于相关的Completion Queue。 实际上NVMe还有另外一种模式,就是多个提交队列共享同一个完成队列的情况。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f433a128f7534631a63b3db4eb7bd837~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=552\&h=202\&s=116964\&e=png\&b=e3e2e2) NVMe是通过队列传递控制命令和命令等内容。而提交队列和完成队列就是内存的一个区域,在数据结构原理上这里的队列其实是一个环形缓冲区。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bc455f929dbb4084b56fc0bd4029cae6~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=619\&h=440\&s=124578\&e=png\&b=fcfcfc) **NVMe通过一种门铃机制(Doorbell)来告知控制器命令队列是否有新数请求/命令**。也就是说每个队列都有一个门铃指针。对于发送队列来说,这个指针表示的是发送队列的尾指针。主机端将数据写入到发送队列后,**更新映射到位于设备寄存器空间中的门铃的尾指针**。此时,在控制器端就知道有新的请求/命令到来,接下来就可以进行对其进行处理。 当控制器完成一个NVMe请求时,通过完成队列来把完成的结果告知主机端。与发送队列不同,完成队列是通过\*\*中断机制(可以是INTx,MSI或MSIx)\*\*告诉主机端。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9313c23aa41d483d9431ea26f5514565~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1280\&h=475\&s=2436481\&e=png\&b=ede2d5) ### 带 NVMe SSD 的 PCIe 拓扑 SSD 作为一个 PCIe Endpoint 通过 PCIe 连着 Root Complex (RC);然后,RC连接着CPU和内存。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6294983025214f4a9051d68a63e5efcf~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=683\&h=457\&s=187824\&e=png\&b=f4ebe5) 核心部分说明: * **Submission Queue(SQ)**:位于Host内存中,由系统放置命令,**Host要发送命令时,先把准备好的命令放在SQ中**,然后通知SSD来取; * **Completion Queue(CQ)**:也是位于Host内存中,**由控制器(NVMe)放置完成信息**。一个命令执行完成,成功或失败,SSD总会往CQ中写入命令完成状态。 * **Doorbell Register(DB)**: 位于SSD的控制器内部,在Host发送命令时,不是直接往SSD中发送命令的,而是把命令准备好放在自己的内存中,Host就是通过写SSD端的DB寄存器来告知SSD命令已经处理完毕。 * **Root Complex(RC)**:CPU和PCle总线之间的接口,可能包含几个组件(处理器接口、DRAM接口等),甚至可能包含几个芯片。主要负责PCIe报文的解析和生成。RC接受来自CPU的IO指令,生成对应的PCIe报文,或者接受来自设备的PCIe TLP报文,解析数据传输给CPU或者内存。 * **Switch**:提供扩展或聚合能力,并允许更多的设备连接到一个PCle端口。 * NVM 子系统(Subsystem): * **PCIe Endpoint** : PCIe设备;处于PCIe总线系统拓扑结构中的最末端,一般作为总线操作的发起者或者终结者。显然,Endpoint只能接受来自上级拓扑的数据包或者向上级拓扑发送数据包。细分Endpoint类型的话,分为 Lagacy PCIe Endpoint 和 Native PCIe Endpoint。 * **Lagacy PCIe Endpoint**:指那些原本准备设计为PCI-X总线接口的设备,但是却被改为PCIe接口的设备。 * **Native PCIe Endpoint**:标准的PCIe设备。 **Lagacy PCIe Endpoint 和 Native PCIe Endpoint的区别**: * Lagacy PCIe Endpoint可以使用一些在 Native PCIe Endpoint 禁止使用的操作,如IO Space和Locked Request等。 * Native PCIe Endpoint 则全部通过Memory Map来进行操作,因此,Native PCIe Endpoint 也被称为 Memory Mapped Devices(MMIO Devices)。 ### NVMe 子系统 NVMe子系统直接通过PCIe总线和主机连接,路径中不再需要HBA(主机总线适配器)卡,降低了系统开销。 NVMe 子系统内部组成: * 至少一个PCIe port,用于外部连接。 * 至少一个NVMe controller,该controller是实现了NVMe逻辑的PCI   function * 名字空间标识(NSID) * 名字空间(NS):指一定量的NVM(Non-Volatile Memory)集合,这些NVM可被格式化为许多个逻辑块。一个NVMe控制器能支持多个不同命名空间ID(简称:NSID)标识的NS。 * NAND Flash介质 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5e222796e0ca492bbc32e1376db19408~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=702\&h=555\&s=52114\&e=png\&b=f1f1d6) 注意:在系统向某个NS提交IO命令之前,**这个NS必须与某个控制器关联**。若NVM子系统支持NS管理,则NVM子系统内的NSID必须是唯一的(不管NS连接的是哪个控制器);若不支持,则不要求私有NS的ID唯一。 ### NVMe SSD 架构 NVMe SSD可以分为三部分,host端的驱动(NVMe官网以及linux、Windows已经集成了相应的驱动)、PCIe+NVMe实现的控制器以及FTL+NAND Flash的存储介质。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6078fba77dfb4ebdbc7344a83aa00d13~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1080\&h=691\&s=482608\&e=png\&b=fefbfa) ### NVMe 工作流程 NVMe 工作流程大体为主机端(Host)通过创建 Admin 命令和 I/O 命令提交到队列和更新门铃寄存器(Doorbell Register),以建立与SSD之间的通信,实现指令的发送和完成信息处理过程。 NVMe协议所规范的标准工作流程如图所示。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/95910b9d4a774b7d9f592bf6784ba92d~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=978\&h=532\&s=186877\&e=png\&b=fcfbfb) 具体工作流程按以下过程进行: 1. 主机控制器将指令写入相应的提交队列(SQ); 2. 主机更新SSD端门铃寄存器(DB)以通知SSD有新的待执行指令; 3. SSD通过检查门铃寄存器获取指令数量,并将指令从对应的提交队列中读出; 4. SSD控制器依次解析并执行指令; 5. 指令执行完成后,SSD控制器将提交指令对应的完成信息依次写入主机端完成队列(CQ)队尾; 6. SSD发送中断信号,通知主机指令执行完成; 7. 主机控制器从队列队首开始依次检查完成队列中新的完成信息,并分析指令的执行情况; 8. 检查完成后,主机发送门铃信息至完成队列的门铃寄存器(DB),以通知SSD其返回的完成信息已检查完成。 ### NVMe over Fabric NVMe over Fabrics,简称 NVMe-oF,它是 NVM Express工作组在2016年发布的规范,通过网络将主机(如服务器)连接到存储。 早期的 NVMe over PCIe 局限在主机的本地盘使用。而通过 Fabrics(如RDMA或光纤通道)代替PCIe,可帮助主机访问节点外的NVMe SSD资源,NVMe-oF极大地增强了灵活性和扩展性,**将NVMe低延时、高并发等特性,从服务器级别,扩展到整个数据中心级别**。 具体如下图(NVMe Transports)所示,左边表示在PCIe上进行传输,右边为在Fabrics上的几种类型传输方式。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/95645cba06c740e1a71e89398ea58742~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1280\&h=581\&s=2235309\&e=png\&b=e8e8e8) 构建NVMe-oF的Fabrics网络,也即主机和外地盘的连接通道,有多种方式,如:**RDMA (NVMe /RDMA),Fibre Channel (NVMe/FC) 、TCP (NVMe/TCP)** ,各自适用不同领域。 * NVMe/RDMA:性能高、成本也较高,用于HPC、分布式数据库、AI机器学习等场景。 * NVMe/FC:非常适合运行关键型任务工作负载的现有大型 FC 基础设施。 * NVMe/TCP:在性能和成本之间取得了平衡,被定位为通用 NVMe-oF 的主力。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/19a3962bac40477cb59f609dd42db961~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1066\&h=478\&s=212045\&e=png\&b=fafafa) **为什么出现NVMe Over Fabrics?** 1)更快的存储,需要更快的网络 从HDD到SSD,再发展到PM (Persistent Memory),性能的改善(延时缩短)比最初提升到数千倍! 2)更快更大容量的存储,需要给多个主机共享 不过考虑到效率、弹性、可靠性、可用性、可运维性等需求,开始出现了JBOF、EBOF等新型架构。 通常一个闪存盘箱(JBOF或EBOF)的SSD个数在20以上,也即能提供的总IOPS高达1600万! 常规的主机(服务器)很难吸收或全部利用这么高的磁盘性能。合理的架构应该是一些主机构成的集群,通过Fabrics共享使用一个或多个全闪存盘箱。 当网络或说是传输通道延时超低,带宽也高时,主机可不配置本地盘。只留少数启动盘,甚至通过使用NVMe Server Boot Cards,连启动盘都不需要。例如,Marvell推出了RAID 1 Accelerator来提高NVMe启动盘的冗余保护。 这其实就是 Disaggregation of Compute and Storage(计算和存储的解耦),即大家近年来经常听到的存算分离。NVMe-oF的优势只有在计算和存储完全分开时才能完全发挥出来。也就是说,通过网络将一个NVMe SSD池提供给一个服务器池,这种方式允许按需提供计算和存储。计算和存储的分解提升了存储的可伸缩性和可共享性,并支持可组合性,如下图所示。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d4c4aec528bc48bf87a02991d6a62f3b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=900\&h=376\&s=246631\&e=png\&b=faf6f5) 存储分离的另一个部分是存储服务(即数据保护、复制、压缩等)。存储服务可以由服务器管理(如:加载模型),也可以卸载到靠近实际存储的数据处理单元(DPU)。 加载模型会消耗额外的 CPU 周期和网络带宽,但可以最大限度地降低成本,而卸载模型会增加成本,并且根据配置的不同,可能会产生瓶颈,因此必须做出权衡。 由于 TCO(总成本)优势,对大规模低成本存储的追求引领了加载附加存储的策略。 **为什么需要网络呢? 主机直接在本地盘使用不行吗?** 当然可以,确实有些要求延时低且冗余要求不高的场景,如:AI训练、NoSQL(数据冗余在应用软件层实现)等。 ### EBOF、JBOF 与 JBOD 的区别? JBOD(Just a Bunch of Disks)通常用于在PCIe上使用NVMe扩展机架中的存储。而EBOF或JBOF可以使用NVMe-oF在数据中心之间扩展存储。 全闪存阵列(bunch of flash)有两种方式接入到 NVMe-oF:通过网络接入(EBOF(Ethernet Bunch of Flash))和直接连接 (JBOF(just a bunch of flash))。JBOF使用PCIe交换机向SSD扩展,而EBOF使用以太网交换机向SSD扩展。JBOF和EBOF都使用NVMe-oF连接到服务器。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d0966f32b4e94ba2adca3c443ddde8d8~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=900\&h=454\&s=107210\&e=png\&b=fefefe) 除了以太网和PCIe交换之外,这两种方法的主要区别在于从NVMe到NVMe-oF的转换发生在哪里。 * 在JBOF上,转换或桥接是在外围使用一个或多个DPU (x DPU到y SSD, x:y比率)。 * 在EBOF上,桥接在SSD载体完成(x桥接到x SSD, 1:1的比例)。 虽然JBOF有使用DPU的处理能力来运行存储服务的优势,但它确实存在一个潜在的瓶颈,并且和EBOF模型相比,带来了额外的成本,具有一些新功能。当桥接器与固态硬盘的比例不是1:1时,成本权衡和瓶颈问题就开始显现出来了。 ### 如何选择 NVMe-over-Fabrics 方案? NVMe 可以通过 FC、启用了 RDMA 的以太网或使用 TCP/IP 的标准以太网进行传输,下图展示了目前可用的主流 NVMe 光纤连接方案。那么不同方案间的主要差异是什么呢? ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f4d24028e25d4745b5a755b38790eccc~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=720\&h=745\&s=1612626\&e=png\&b=fbfafa) **NVMe-over-FC (FC-NVMe)**: 对于已经部署了光纤通道存储网络(SAN)基础设施的用户而言,FC-NVMe 当属最优方案。使用 16Gb FC 或 32Gb FC 主机总线适配器(HBA)和SAN交换机,即可将 NVMe 协议封入 FC 框架内部。通过升级至最新的HBA固件和驱动程序则能获取 Linux 服务器上的 FC-NVMe 支持。因此,投资新型 16Gb 或 32Gb FC HBA和 SAN 基础设施,能够为应用今后推出的 FC-NVMe 存储阵列做好提前准备。另外值得注意的是,SCSI (FCP) 和 NVMe (FC-NVMe) 可以共存于相同的FC光纤网络中,因此,基于 FC-SCSI 的老存储可以与全新的 NVMe 存储同时运行。 **使用RDMA的NVMe-over-Ethernet光纤**: RDMA 有两种不同的部署方式,名称分别为RoCE(v1/v2)和iWARP。 然而非常遗憾,以上两种协议无法实现交互操作。下面我将简要说明两种协议各自的优劣势: **a. NVMe-over-RoCE (NVMe/RoCE)** : 如果您使用的是只有以太网的网络,NVMe-over-RoCE 是共享存储或超融合基础设施 (HCI) 连接的最佳方案。正因如此,目前已有多家存储阵列供应商公布了他们的计划,及表示支持 NVMe-over-RoCE 连接。 RoCE 能够提供最低的以太网络延迟,并且对于跳数不超过 2 个的小规模存储网络,能达到非常优异的运行效果。顾名思义,RoCE 需要聚合或无损的以太网络才能正常运行。此外,该方案还需启用实现额外的网络功能,包括数据中心桥接(DCB)、优先流控制(PFC),以及其他一些更复杂的组织架构和网络拥塞管理机制。如果低延迟是您的首要目标,那么 NVMe-over-RoCE 很可能是您的最优选择,尽管其网络复杂性也相对较高。 **b. NVMe-over-iWARP (NVMe/iWARP)** : iWARP RDMA 协议运行于标准 TCP/IP 网络之中,因此其部署操作也更加简单。 尽管该协议的延迟性能不及 RoCE,但更加易用的特性以及更低的管理难度依然具有巨大的吸引力。在现阶段,存储阵列供应商尚未设计出支持 iWARP 的阵列,因此目前的 iWARP 最适合软件定义或者基于 Microsoft Azure Stack HCI / Storage Spaces Direct (S2D) 等 HCI 解决方案。 **NVMe-over-TCP(NVMe/TCP)** NVMe-over-TCP 还处于研发萌芽阶段。该方案于 2018 年 11 月获批,在不进行任何必要调整工作的情况下即可在现有的以太网基础设施中运行(这一点利用了 TCP/IP 广泛的普遍性)。 NVMe-over-TCP 发挥的性能表现可能在速度上不及 NVMe-over-RDMA 或 FC-NVMe,但在标准以太网卡和以太网网络交换机上就可以轻松实现部署。无需大量的硬件投资,即可享受 NVMe SSD 存储的主要优势。 Marvell FastLinQ 10/25/50/100GbE 等部分网卡还能利用网卡内置的TCP/IP协议栈的硬件卸载(offload)功能,发挥为 NVMe/TCP报文卸载并加速的潜力。 ### NVMe 常用命令 以下是一些比较常用的命令,大部分命令需要在root用户下运行。 * **nvme list**:查看所有连接到当前系统的nvme设备:名称,序列号,大小,LBA 和 serial * **nvme id-ctrl**:展示nvme控制器和它所支持的一些特性 * **nvme id-ns**:展示 nvme 的命名空间,优化特性和支持特性 * **nvme format**:安全擦除SSD上的数据,格式化LBA大小或保护信息以实现端到端数据保护 * **nvme sanitize**:安全的擦除SSD上的所有数据 * **nvme smart-log**:查看NVME的smart log信息:page的健康状态,温度,稳定性情况等 * **nvme fw-log**:查看NVME的固件日志,会打印每个entry的健康情况 * **nvme error-log**:NVME的异常日志 * **nvme reset**:重置NVME的控制器 * **nvme help**:查看帮助信息 * **nvme delete-ns**:指定设备删除一个命名空间 * **nvme create-ns**:指定设备创建命名空间。比如可以为一个设备创建一个较小大小的命名空间,从而提升SSD的稳定性,性能和延时 * **nvme fw-download**:为一个设备下载一个新的固件系统 * **nvme fw-commit**:让固件立即运行 ## NVMe 在 AI 服务器中的应用 ### GPUDirect 简介 GPUDirect 是 NVIDIA 开发的一项技术,可实现 GPU 与其他设备(例如网络接口卡 (NIC) 和存储设备)之间的直接通信和数据传输,而不涉及 CPU。 传统上,当数据需要在 GPU 和另一个设备之间传输时,数据必须通过 CPU,从而导致潜在的瓶颈并增加延迟。使用 GPUDirect,网络适配器和存储驱动器可以直接读写 GPU 内存,减少不必要的内存消耗,减少 CPU 开销并降低延迟,从而显著提高性能。GPU Direct 技术包括 GPUDirect Storage、GPUDirect RDMA、GPUDirect P2P 和 GPUDirect Video。 ### GPUDirect Storage 简介 GPUDirect Storage (GDS)允许本地或远程存储(例如:NVMe 或 NVMe over Fabric (NVMe-oF))和 GPU 之间进行直接数据传输,绕过 CPU,**使 NIC 或存储附近的直接内存访问 (DMA) 引擎能够将数据通过直接路径移入或移出 GPU 内存**,从而减少数据传输的延迟和 CPU 开销。 通过 GPUDirect Storage,GPU 可以直接从存储设备(如:固态硬盘(SSD)或非易失性内存扩展(NVMe)驱动器)访问数据,而无需将数据先复制到 CPU 的内存中。这种直接访问能够实现更快的数据传输速度,并更高效地利用 GPU 资源。 GPUDirect Storage方案用到了两项高端技术,一个是RDMA,一个是NVMe(NVMe-oF),其中,RDMA被封装在GPUDirect的协议中,依靠各种网络适配器工作(比如Mellanox的NIC),既可以访问远程的存储也可以访问本地的存储设备。 下图展示了 GPU 内存和 NVMe 驱动器之间是否使用 GPUDirect Storage 的对比。从存储器到 GPU 的直接内存访问缓解了 CPU I/O 瓶颈,并提高了 I/O 带宽和容量。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/02e2b74589394624b353e6bcf42e7511~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2397\&h=1202\&s=80887\&e=png\&b=ffffff) GPUDirect Storage 的主要特点和优势包括: * **减少 CPU 参与**:通过绕过 CPU,实现 GPU 和存储设备之间的直接通信,GPUDirect Storage 减少了 CPU 开销,并释放 CPU 资源用于其他任务,从而改善系统的整体性能。 * **低延迟数据访问**:GPUDirect Storage 消除了数据通过 CPU 的传输路径,从而最小化了数据传输的延迟。这对于实时分析、机器学习和高性能计算等对延迟敏感的应用非常有益。 * **提高存储性能**:通过允许 GPU 直接访问存储设备,GPUDirect Storage 实现了高速数据传输,可以显著提高存储性能,加速数据密集型工作负载的处理速度。 * **增强的可扩展性**:GPUDirect Storage 支持多 GPU 配置,允许多个 GPU 同时访问存储设备。这种可扩展性对于需要大规模并行处理和数据分析的应用至关重要。 * **兼容性和生态系统支持**:GPUDirect Storage 设计用于与各种存储协议兼容,包括:NVMe、NVMe over Fabrics和网络附加存储(NAS)。它得到了主要存储供应商的支持,并集成到流行的软件框架(如:NVIDIA CUDA)中,以简化与现有的 GPU 加速应用程序的集成。 ### GPUDirect Storage 工作原理 NVIDIA 力求尽可能采用现有标准,并在必要时扩展这些标准。 POSIX 标准的 pread 和 pwrite 提供存储和 CPU 缓冲区之间的复制,但尚未启用到 GPU 缓冲区的复制。 Linux 内核中不支持 GPU 缓冲区的缺点将随着时间的推移得到解决。一种名为 **dma\_buf** 的解决方案正在开发中,该解决方案可以在 NIC 或 NVMe 和 GPU 等 PCIe 总线上的对等设备之间进行复制,以解决这一问题。 与此同时,GDS 的性能提升空间太大,无法等待上游解决方案传递给所有用户。 许多供应商都提供了支持 GDS 的替代解决方案,如:MLNX\_OFED。 GDS 解决方案涉及新的 API:cuFileRead 或 cuFileWrite,它们与 POSIX pread 和 pwrite 类似。 像**动态路由、NVLink 的使用以及只能从 GDS 获得的用于 CUDA 流的异步 API** 等优化使得 cuFile API 成为 CUDA 编程模型的持久特性,即使在解决了 Linux 文件系统中的缺陷之后也是如此。 以下是 GDS 的实现: 首先,当前 Linux 实现的根本问题是将 GPU 缓冲区地址作为 DMA 目标向下通过虚拟文件系统 (VFS) 传递,以便本地 NVMe 或网络适配器中的 DMA 引擎可以执行与 GPU 内存之间的传输,这会导致错误情况。我们现在有一个解决这个问题的方法:传递 CPU 内存中缓冲区的地址。 当使用 cuFileRead 或 cuFileWrite 等 cuFile API 时,libcufile.so 用户级库**捕获 GPU 缓冲区地址**并**替换**传递给 VFS 的**代理 CPU 缓冲区地址**。 就在缓冲区地址用于 DMA 之前,启用 GDS 的驱动程序对 nvidia-fs.ko 的调用会**识别 CPU 缓冲区地址**并**再次提供替代** GPU 缓冲区地址,以便 DMA 可以正确进行。 libcufile.so 中的逻辑将执行前面描述的各种优化,例如:动态路由、prepinned缓冲区的使用、对齐等。 下图为 GDS 软件堆栈,其中:应用程序使用 cuFile API,并且支持 GDS 的存储驱动程序调用 nvidia-fs.ko 内核驱动程序来获取正确的 DMA 地址。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c0671b6cf14243ccaee026619fbd24b3~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1227\&h=1064\&s=104304\&e=png\&b=fefefe) ### NVIDIA DGX 中集成 NVME SSD NVIDIA DGX 系列是一系列专为深度学习工作负载而设计的高性能计算系统。下面为DGX 系列中搭载的 NVME SSD 详情。 | DGX 系列 | 存储 (OS) | 存储 (Data Cache) | | -------- | -------------------------------- | --------------------------------- | | DGX-1 | 1 x 480 GB, 6 Gb/s, SATA 3.0 SSD | 4 x 1.92 TB, 6 Gb/s, SATA 3.0 SSD | | DGX-2 | 2 x 960GB NVMe SSDs | 8 x 3.84 TB NVMe SSD | | DGX A100 | 2 x 1.92 TB NVMe M.2 SSD | 4 x 3.84 TB NVMe U.2 SED | | DGX H100 | 2 x 1.92 TB NVMe M.2 SSD (ea) | 8 x 3.84 TB NVMe U.2 SED | **DGX-2 中包含 NVMe SSD:** DGX-2 机柜包含两个 CPU ,每个 CPU 都有两个 PCIe 子树实例,如图所示。从存储或系统内存到 GPUs 的多条 PCIe 路径由两级的 PCIe 交换机支持。 NVIDIA DGX-2 由 16 个 Tesla V100 组成,包含 30TB NVMe SSD 数据缓存存储( 8x 3.84TB )和 1.5TB 系统内存。启用驱动器的 DMA 操作允许快速访问内存,同时增加带宽、降低延迟。 跟原来不支持 GPUDirect Storage 的 DGX-2 系统相比,GPUDirect Storage 的吞吐带宽能提升8倍。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f0f78b0c75134fbe9313bb612341686c~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2397\&h=1202\&s=86869\&e=png\&b=fffefe) **DGX-A100 中包含 NVMe SSD:** DGX A100 有 8个 A100 GPU,每个A100 GPU拥有12个NVLink端口,每个GPU拿出2个Link端口与一个NVSwitch连接,一共连接了6个NVSwitch。 同时,每个A100 GPU通过PCIE Switch连接了 200Gb/s 网卡(NIC)和 NVMe。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/47e765e2ee68482abbd3622287aa91f3~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1083\&h=720\&s=2343859\&e=png\&b=fefdfd) **DGX-H100 中包含 NVMe SSD:** HGX H100 拥有八个 H100 Tensor Core GPU 和 四个第三代 NV 交换机。每个 H100 GPU 都有多个第四代 NVLink 端口,并连接到所有四个 NVLink 交换机。每个 NVSwitch 都是一个完全无阻塞的交换机,完全连接所有八个 H100 Tensor Core GPU 。 NVSwitch 的这种完全连接的拓扑结构使任何 H100 都可以同时与任何其他 H100 通信。值得注意的是,这种通信以每秒 900 千兆字节( GB/s )的 NVLink 双向速度运行,这是当前 PCIe Gen4 x16 总线带宽的 14 倍多。 同时,每个 H100 GPU 通过 ConnectX-7 智能网卡连接 InfiniBand 及Ethernet(400Gb/s)。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/24412bf7ca844e029a9ff7007af6eb95~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1235\&h=720\&s=2672709\&e=png\&b=fcfafa) ## NVMe 在 DeepSpeed 中的应用 GPU 集群在存储器方面具有高度异构性。除了GPU内存外,还有 CPU 内存以及无限大(Infinity)的 NVMe 磁盘空间。ZeRO-Infinity 通过利用这些异构存储器,突破 GPU 内存壁垒。 讲述 ZeRO-Infinity 之前,先来看看 ZeRO 和 ZeRO-Offload 技术原理。 ### ZeRO 技术原理 在 ZeRO 中,通过三个阶段依次对优化器状态(一阶动量、二阶动量)、梯度、参数的切割,解决了传统数据并行中冗余存储的问题,提高了 GPU 的内存使用效率。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/941d242f6b2546fb80e3017efc6cbb66~tplv-k3u1fbpfcp-watermark.image#?w=1280\&h=617\&s=3164841\&e=png\&b=fefefe) **ZeRO-1**: ZeRO-1没有将模型本身进行分片,也没有将Gradient进行分片,而是只将优化器进行分片。训练过程与DDP类似。 1. forward过程由每个rank的GPU独自完整的完成,然后进行backward过程。在backward过程中,梯度通过allReduce进行同步。 2. Optimizer state 使用贪心策略基于参数量进行分片,以此确保每个rank几乎拥有相同大小的优化器内存。 3. 每个rank只负责更新当前优化器分片的部分,由于每个rank只有分片的优化器state,所以当前rank忽略其余的state。 4. 在更新过后,通过广播或者allGather的方式确保所有的rank都收到最新更新过后的模型参数。 ZeRO-1 非常适合使用类似Adam进行优化的模型训练,因为Adam拥有额外的参数m(momentum)与v(variance),特别是FP16混合精度训练。ZeRO-1 不适合使用SGD类似的优化器进行模型训练,因为SGD只有较少的参数内存,并且由于需要更新模型参数,导致额外的通讯成本。ZeRO-1只是解决了Optimizer state的冗余。 **ZeRO-2**: 相比于ZeRO-1,ZeRO-2除了对optimizer state进行切分,还对Gradient进行了切分。 像ZeRO-1一样将optimizer的参数进行分片,并安排在不同的rank上。在backward过程中,**gradients被reduce操作到对应的rank上,取代了all-reduce**,以此减少了通讯开销。 每个rank独自更新各自负责的参数。在更新操作之后,广播或allGather保证所有的ranks接收到更新后的参数。 **ZeRO-3**: 为了进一步节省更多的内存,ZeRO-3提出进行模型参数的分片。类似以上两种分片方式,ranks负责模型参数的切片。可以进行参数切片的原因主要有以下两点: 1. All-Reduce操作可以被拆分为Reduce与allgather操作的结合。 2. 模型的每一层拥有该层的完整参数,并且整个层能够直接被一个GPU装下。所以计算前向的时候,除了当前rank需要的层之外,其余的层的参数可以抛弃。从这个层面上来说,Zero相当于数据并行+模型并行。 更具体说明查看之前的文章:[大模型分布式训练并行技术(二)-数据并行](https://zhuanlan.zhihu.com/p/650002268) ### ZeRO-Offload 技术原理 ZeRO-Offload 的动机是解决 GPU 内存墙的问题。具体而言,传统分布式训练中的 3D 并行(数据、张量、流水线)解决了模型无法存放在单张 GPU 内存中的问题,但是因为模型的参数、梯度、优化器状态总要存放在 GPU 内存中,需要要求所有的 GPU 的内存总和大于上述模型状态所需内存。但是模型规模的增长速度要远远大于 GPU 内存大小的增长速度,二者之间越来越大的差距使得上述要求已经很难得到满足。为此,ZeRO-Offload 利用异构设备训练(Heterogeneous DL training )的思想,即利用 CPU 内存来减少 GPU 内存的压力,并集成到了 ZeRO-2 中。 ZeRO-Offload 分为 Offload Strategy 和 Offload Schedule 两部分,前者解决如何在 GPU 和 CPU 间划分模型的问题,后者解决如何调度计算和通信的问题。 在 Offload Strategy 方面,方法首先将训练过程抽象为数据流图,图中点分为两类,一类表示需要存储的模型状态,一类表示运算操作(前向传播、反向传播、参数更新等);图中边表示节点之间传递的数据量。在数据流图的基础上,该方法提出了关于最优策略的 3 点见解: 1. 保证 CPU 的计算负担远远小于 GPU,从而防止 CPU 成为计算瓶颈; 2. 保证 CPU 和 GPU 之间的通信量最小; 3. 保证 GPU 的内存节省最大; ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a59e37656f3e4ae29345c46d3ba73cb2~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1494\&h=938\&s=278217\&e=png\&b=f2f2f2) CPU 负责存储 FP32 的优化器状态和 FP16 的梯度,同时更新参数;GPU 负责存储 FP16 的梯度和参数,同时完成前向传播和反向传播。该方法声称这种策略在不增加 CPU 计算量和不增加 CPU 和 GPU 之间通信开销的前提下是最优的。 在 Offload Schedule 方面,分为单张 GPU 和多张 GPU 两部分。 单张 GPU 的调度如下图所示,核心是将 GPU 到 CPU 的梯度 offload 和 GPU 上反向传播时的梯度计算重叠,以及将 CPU 到 GPU 的参数 swap和 CPU 上的参数更新重叠。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a859b37ad6bd468b80a9f0992d508d96~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1066\&h=362\&s=88128\&e=png\&b=fefbfb) 多张 GPU 的调度如下图所示,GPU 和 CPU 之间的通信量和 CPU 上的计算量没有改变,单纯和 ZeRO-2 的并行方式相结合。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c842f89e854148f6b8666c7caf2a3127~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=946\&h=436\&s=85398\&e=png\&b=fefdfd) ### ZeRO-Infinity 技术原理 ZeRO-Infinity 则在 ZeRO-Offload 的基础上进一步优化,主要包括三个方面。 * 一是将和 ZeRO 的结合从 ZeRO-2 延伸到了 ZeRO-3,**解决了模型参数受限于单张 GPU 内存的问题**; * 二是解决了 ZeRO-Offload 在训练 batch size 较小的时候效率较低的问题; * 三是除 CPU 内存外,尝试**利用 NVMe 的空间进一步打破内存墙的限制训练超大模型**。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/034a508f0ec2470b93cd2896aa3ee864~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1120\&h=1064\&s=353789\&e=png\&b=faf4f3) ### ZeRO-Infinity 应用示例 在 DeepSpeed AI框架中,进行模型训练时,可通过配置 deepspeed\_config文件通过 ZeRO-Infinity 技术来使用 NVMe。 比如:将模型参数卸载到 CPU/NVMe。仅适用于 ZeRO Stage 3。 ```json { "offload_param": { "device": "[cpu|nvme]", "nvme_path": "/local_nvme", "pin_memory": [true|false], "buffer_count": 5, "buffer_size": 1e8, "max_in_cpu": 1e9 } } ``` 参数说明: * **device**:用于卸载模型参数的设备内存。 支持的选项有 cpu 和 nvme。 * **pin\_memory**:转移到CPU锁页(page-locked)内存。这可能会提升吞吐量,但代价是增加了额外的内存开销。(默认值:false) * **nvme\_path**:用于参数卸载的 NVMe 设备的文件系统路径。 * **buffer\_count**:用于参数卸载到 NVMe 的缓冲池中的缓冲区数量。 * **buffer\_size**:用于参数卸载到 NVMe 的缓冲池中的缓冲区大小。 * **max\_in\_cpu**:启用卸载到 NVMe 时要在 CPU 内存中维护的参数元素数量。 同时,还支持将优化器计算卸载到 CPU 并将优化器状态卸载到 CPU/NVMe。 卸载到 CPU 适用于 ZeRO Stage 1、2、3。卸载到 NVMe 仅适用于 ZeRO Stage 3 ```json { "offload_optimizer": { "device": "[cpu|nvme]", "nvme_path": "/local_nvme", "pin_memory": [true|false], "ratio": 0.3, "buffer_count": 4, "fast_init": false } } ``` 参数说明: * **device**:用于卸载优化器状态的设备内存。 支持的选项有 cpu 和 nvme。 无论设备选项如何,优化器计算都会卸载到 CPU。 * **nvme\_path**:用于优化器状态卸载的 NVMe 设备的文件系统路径。 * **pin\_memory**:卸载到 CPU 锁页内存。这可以提高吞吐量,但代价是额外的内存开销。 * **ratio**:CPU 侧参数更新(即优化器步骤)的比率。 * **buffer\_count**:用于优化器状态卸载到 NVMe 的缓冲池中的缓冲区数量。 这至少应该是优化器为每个参数维护的状态数。 例如,Adam 优化器有 4 个状态(参数、梯度、动量和方差)。 * **fast\_init**:卸载到 NVMe 时启用快速优化器初始化。 总的来说就是在使用 ZeRO Stage 1、2 时,可以使用 offload\_optimizer,优化器状态卸载到CPU。在使用 ZeRO Stage 3 时,可以同时使用offload\_optimizer 和 offload\_param 将优化器状态和模型参数卸载到CPU或NVMe。 ## 总结 本文讲述了首先提到了衡量传输速度的三大要素(传输通道、通信协议、硬件接口),然后硬盘的发展进行了基本的介绍、之后对NVMe的技术原理以及NVMe在AI服务器及DeepSpeed框架中的应用进行了详细的讲述。 码字不易,如果觉得有帮助,欢迎点赞收藏加关注。 ## 参考文档 * [计算机固态硬盘(SSD)和机械硬盘(HDD)的区别](https://consumer.huawei.com/cn/support/content/zh-cn15819906/) * [了解 SSD 技术:NVMe、SATA、M.2](https://www.kingston.com/cn/ssd/what-is-nvme-ssd-technology) * [固态硬盘接口类型及区别](https://www.i-tc.com.cn/product-service/736.html) * [总线、协议、接口](https://zhuanlan.zhihu.com/p/561858380) * [M.2 固态硬盘的两种类型:SATA 和 NVMe](https://www.kingston.com/cn/blog/pc-performance/two-types-m2-vs-ssd) * [硬盘科普,M.2,PCI-E,NVMe 傻傻分不清](https://zhuanlan.zhihu.com/p/396745362) * [NVMe、AHCI、PCIe、SATA、NGFF接口、协议小结](https://blog.csdn.net/wujinglin7/article/details/122826608) * [M.2 固态硬盘的两种类型:SATA 和 NVMe](https://www.kingston.com/cn/blog/pc-performance/two-types-m2-vs-ssd) * [M.2 接口详解](https://zhuanlan.zhihu.com/p/491944861) * [「科普」NVMe2.0:闪存存储新篇章](https://baijiahao.baidu.com/s?id=1782475465795992948\&wfr=spider\&for=pc) * [什么是NVMe存储?了解新的行业标准](https://www.wbolt.com/what-is-nvme.html) * [NVMe技术分析之工作原理](https://blog.csdn.net/tiantianuser/article/details/117802938) * [固态硬盘常提到的NVMe协议是个啥?](https://www.zhihu.com/tardis/zm/art/137903162?source_id=1003) * [NVME协议解读(一)](https://blog.csdn.net/jingjiankai5228/article/details/121865937) * [理解NVMe的内部实现原理,这一篇就够了](https://zhuanlan.zhihu.com/p/71932654) * [收藏:NVMe协议基础原理介绍](https://blog.csdn.net/weixin_38889300/article/details/128349761) * [NVMe技术架构深度分析](https://blog.csdn.net/BtB5e6Nsu1g511Eg5XEg/article/details/84332456) * [深入剖析NVMe Over Fabrics](https://www.qinglite.cn/doc/300664763aa0aa7f1) * [如何选择最优的NVMe-over-Fabrics方案?](https://mp.weixin.qq.com/s/yNFcUoqcNVBGekxrrkoMOg) * [再见,Intel!GPU直连NVMe SSD!](https://www.sohu.com/a/442463342_505795) * [Ethernet Bunch of Flash in an NVMe-oF™ Network for Low-Cost Storage at Scale ](https://www.micron.com/about/blog/2020/november/ethernet-bunch-of-flash-in-an-nvme-of-network-for-low-cost-storage-at-scale) * [聊透 GPU 通信技术——GPU Direct、NVLink、RDMA](https://zhuanlan.zhihu.com/p/654417967) * [NVIDIA GPUDirect](https://developer.nvidia.com/gpudirect) * [GPUDirect Storage: A Direct Path Between Storage and GPU Memory](https://developer.nvidia.com/blog/gpudirect-storage/) * [Accelerating IO in the Modern Data Center: Magnum IO Storage](https://developer.nvidia.com/blog/accelerating-io-in-the-modern-data-center-magnum-io-storage/) * [NVIDIA Hopper 深入研究架构](https://developer.nvidia.com/zh-cn/blog/nvidia-hopper-architecture-in-depth/) * [介绍 NVIDIA HGX H100 :用于人工智能和高性能计算的加速服务器平台](https://developer.nvidia.com/zh-cn/blog/introducing-nvidia-hgx-h100-an-accelerated-server-platform-for-ai-and-high-performance-computing/) * [DeepSpeed config-json](https://www.deepspeed.ai/docs/config-json/) * [关于Deepspeed的一些总结与心得](https://zhuanlan.zhihu.com/p/650824387) * [ZeRO-Offload 和 ZeRO-Infinity 流程解读](https://zhuanlan.zhihu.com/p/657946200) ================================================ FILE: blog/distribution-parallelism/大模型分布式训练并行技术(一)-概述.md ================================================ 近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,传统的单机单卡模式已经无法满足超大模型进行训练的要求。因此,我们需要基于单机多卡、甚至是多机多卡进行分布式大模型的训练。 而利用AI集群,使深度学习算法更好地从大量数据中高效地训练出性能优良的大模型是分布式机器学习的首要目标。为了实现该目标,一般需要根据硬件资源与数据/模型规模的匹配情况,考虑对计算任务、训练数据和模型进行划分,从而进行分布式存储和分布式训练。因此,分布式训练相关技术值得我们进行深入分析其背后的机理。 下面主要对大模型进行分布式训练的并行技术进行讲解,本系列大体分九篇文章进行讲解。 - [大模型分布式训练并行技术(一)-概述](https://juejin.cn/post/7195845066887053368) - [大模型分布式训练并行技术(二)-数据并行](https://juejin.cn/post/7254001262646738981) - [大模型分布式训练并行技术(三)-流水线并行](https://juejin.cn/post/7262274383287484476) - 大模型分布式训练并行技术(四)-张量并行 - 大模型分布式训练并行技术(五)-序列并行 - 大模型分布式训练并行技术(六)-多维混合并行 - 大模型分布式训练并行技术(七)-自动并行 - 大模型分布式训练并行技术(八)-MOE并行 - 大模型分布式训练并行技术(九)-总结 本文为分布式训练并行技术的第一篇,对大模型进行分布式训练常见的并行技术进行简要介绍。 ## 数据并行 数据并行是最常见的并行形式,因为它很简单。在数据并行训练中,数据集被分割成几个碎片,每个碎片被分配到一个设备上。这相当于沿批次(Batch)维度对训练过程进行并行化。每个设备将持有一个完整的模型副本,并在分配的数据集碎片上进行训练。在反向传播之后,模型的梯度将被全部减少,以便在不同设备上的模型参数能够保持同步。典型的数据并行实现:PyTorch DDP。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f2db22e52a3d45b2804d09d06dd2eca6~tplv-k3u1fbpfcp-watermark.image?) ## 模型并行 在数据并行训练中,一个明显的特点是每个 GPU 持有整个模型权重的副本。这就带来了冗余问题。另一种并行模式是模型并行,即模型被分割并分布在一个设备阵列上。 通常有两种类型的模型并行:张量并行和流水线并行。 - 张量并行是在一个操作中进行并行计算,如:矩阵-矩阵乘法。 - 流水线并行是在各层之间进行并行计算。 因此,从另一个角度来看,张量并行可以被看作是层内并行,流水线并行可以被看作是层间并行。 ### 张量并行 张量并行训练是将一个张量沿特定维度分成 N 块,每个设备只持有整个张量的 1/N,同时不影响计算图的正确性。这需要额外的通信来确保结果的正确性。 以一般的矩阵乘法为例,假设我们有 C = AB。我们可以将B沿着列分割成 [B0 B1 B2 ... Bn],每个设备持有一列。然后我们将 A 与每个设备上 B 中的每一列相乘,我们将得到 [AB0 AB1 AB2 ... ABn] 。此刻,每个设备仍然持有一部分的结果,例如,设备(rank=0)持有 AB0。为了确保结果的正确性,我们需要收集全部的结果,并沿列维串联张量。通过这种方式,我们能够将张量分布在设备上,同时确保计算流程保持正确。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/68b63612448b4d3198000de9c14aa507~tplv-k3u1fbpfcp-watermark.image?) 典型的张量并行实现:Megatron-LM(1D)、Colossal-AI(2D、2.5D、3D)。 ### 流水线并行 流水线并行的核心思想是,模型按层分割成若干块,每块都交给一个设备。 - 在前向传播过程中,每个设备将中间的激活传递给下一个阶段。 - 在后向传播过程中,每个设备将输入张量的梯度传回给前一个流水线阶段。 这允许设备同时进行计算,从而增加训练的吞吐量。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a6f22c0c781b4b0bbe0824ee675b4f8c~tplv-k3u1fbpfcp-watermark.image?) 流水线并行训练的一个明显缺点是训练设备容易出现空闲状态(因为后一个阶段需要等待前一个阶段执行完毕),导致计算资源的浪费,加速效率没有数据并行高。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/40b30ba8a4ef4c688d76b7a6985d9e26~tplv-k3u1fbpfcp-watermark.image?) 典型的流水线并行实现:GPipe、PipeDream、PipeDream-2BW、PipeDream Flush(1F1B)。 ## 优化器相关的并行 目前随着模型越来越大,单个GPU的显存目前通常无法装下那么大的模型了。那么就要想办法对占显存的地方进行优化。 通常来说,模型训练的过程中,GPU上需要进行存储的参数包括了模型本身的参数、优化器状态、激活函数的输出值、梯度以及一些零时的Buffer。各种数据的占比如下图所示: ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4b78aaafb07c433593b7aac716e17abc~tplv-k3u1fbpfcp-watermark.image?) 可以看到模型参数仅占模型训练过程中所有数据的一部分,当进行混合精度运算时,其中模型状态参数(优化器状态 + 梯度+ 模型参数)占到了一大半以上。因此,我们需要想办法去除模型训练过程中的冗余数据。 而优化器相关的并行就是一种去除冗余数据的并行方案,目前这种并行最流行的方法是 ZeRO(即零冗余优化器)。针对模型状态的存储优化(去除冗余),ZeRO使用的方法是分片,即每张卡只存 1/N 的模型状态量,这样系统内只维护一份模型状态。ZeRO有三个不同级别,对模型状态进行不同程度的分片: - ZeRO-1 : 对优化器状态分片(Optimizer States Sharding) - ZeRO-2 : 对优化器状态和梯度分片(Optimizer States & Gradients Sharding) - ZeRO-3 : 对优化器状态、梯度分片以及模型权重参数分片(Optimizer States & Gradients & Parameters Sharding) ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/941d242f6b2546fb80e3017efc6cbb66~tplv-k3u1fbpfcp-watermark.image?) ## 异构系统并行 上述的方法中,通常需要大量的 GPU 来训练一个大型模型。然而,人们常常忽略一点,与 GPU 相比,CPU 的内存要大得多。在一个典型的服务器上,CPU 可以轻松拥有几百GB甚至上TB的内存,而每张 GPU 卡通常只有 48 或 80 GB的内存。这促使人们思考为什么 CPU 内存没有被用于分布式训练。 而最近的进展是依靠 CPU 甚至是 NVMe 磁盘来训练大型模型。主要的想法是,在不使用张量时,将其卸载回 CPU 内存或 NVMe 磁盘。 通过使用异构系统架构,有可能在一台机器上容纳一个巨大的模型。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fa79b1a0e8d0480e909f0e723173757c~tplv-k3u1fbpfcp-watermark.image?) ## 多维混合并行 多维混合并行指将数据并行、模型并行和流水线并行等多种并行技术结合起来进行分布式训练。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ba458ff0694d4f249fd7244ed0df6543~tplv-k3u1fbpfcp-watermark.image?) 通常,在进行超大规模模型的预训练和全参数微调时,都需要用到多维混合并行。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/136fffe75989425c87a02580eb44cdae~tplv-k3u1fbpfcp-watermark.image?) 为了充分利用带宽,通常情况下,张量并行所需的通信量最大,而数据并行与流水线并行所需的通信量相对来说较小。因此,同一个服务器内使用张量并行,而服务器之间使用数据并行与流水线并行。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a8849d41835a4fe5b14c8a877ba3f991~tplv-k3u1fbpfcp-watermark.image?) ## 自动并行 上面提到的数据并行、张量并行、流水线并行等多维混合并行需要把模型切分到多张AI加速卡上面,如果让用户手动实现,对开发者来说难度非常大,需要考虑性能、内存、通信、训练效果等问题,要是能够将模型按算子或者按层自动切分到不同的加速卡上,可以大大的降低开发者的使用难度。因此,自动并行应运而生。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/03d78267b613453687c655f95b84eb03~tplv-k3u1fbpfcp-watermark.image?) ## MOE并行 / 专家并行 通常来讲,模型规模的扩展会导致训练成本显著增加,计算资源的限制成为了大规模密集模型训练的瓶颈。为了解决这个问题,一种基于稀疏 MoE 层的深度学习模型架构被提出,即将大模型拆分成多个小模型(专家,`expert`), 每轮迭代根据样本决定激活一部分专家用于计算,达到了节省计算资源的效果; 并引入可训练并确保稀疏性的门( `gate` )机制,以保证计算能力的优化。 使用 MoE 结构,可以在计算成本次线性增加的同时实现超大规模模型训练,为恒定的计算资源预算带来巨大增益。而 MOE 并行,本质上也是一种模型并行方法。下图展示了一个有六个专家网络的模型被两路专家并行地训练。其中,专家1-3被放置在第一个计算单元上,而专家4-6被放置在第二个计算单元上。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ab7a0047b4444dafa6a0cbd510ae551d~tplv-k3u1fbpfcp-watermark.image?) ## 结语 本文针对大模型进行分布式训练常见的并行技术进行了简要的介绍。后续章节将针对常见并行技术的不同方案进行详细的讲解。 如果觉得我的文章能够能够给您带来帮助,期待您的点赞收藏加关注~~ ================================================ FILE: blog/distribution-parallelism/大模型分布式训练并行技术(九)-总结.md ================================================ 近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,传统的单机单卡模式已经无法满足超大模型进行训练的要求。因此,我们需要基于单机多卡、甚至是多机多卡进行分布式大模型的训练。 而利用AI集群,使深度学习算法更好地从大量数据中高效地训练出性能优良的大模型是分布式机器学习的首要目标。为了实现该目标,一般需要根据硬件资源与数据/模型规模的匹配情况,考虑对计算任务、训练数据和模型进行划分,从而进行分布式存储和分布式训练。因此,分布式训练相关技术值得我们进行深入分析其背后的机理。 下面主要对大模型进行分布式训练的并行技术进行讲解,本系列大体分九篇文章进行讲解。 - [大模型分布式训练并行技术(一)-概述](https://zhuanlan.zhihu.com/p/598714869) - [大模型分布式训练并行技术(二)-数据并行](https://zhuanlan.zhihu.com/p/650002268) - [大模型分布式训练并行技术(三)-流水线并行](https://juejin.cn/post/7262274383287484476) - [大模型分布式训练并行技术(四)-张量并行](https://juejin.cn/post/7269698032655728640) - [大模型分布式训练并行技术(五)-序列并行](https://juejin.cn/post/7273680143658287156) - [大模型分布式训练并行技术(六)-多维混合并行](https://juejin.cn/post/7277799192966578176) - [大模型分布式训练并行技术(七)-自动并行](https://juejin.cn/post/7289661052806594618) - [大模型分布式训练并行技术(八)-MOE并行]() - 大模型分布式训练并行技术(九)-总结 前面讲述了一系列大模型训练的分布式并行方案,本文简要对其进行相应的总结。 ## 数据并行 数据并行,由于其原理相对比较简单,是目前使用最广泛的分布式并行技术。数据并行不仅仅指对训练的数据并行操作,还可以对网络模型梯度、权重参数、优化器状态等数据进行并行。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/40aa4300bcb14346923f5ce339fa6858~tplv-k3u1fbpfcp-watermark.image?) 我们首先以PyTorch 数据并行的发展(DataParallel、DistributedDataParallel、FullyShardedDataParallel)为主线进行讲述了数据并行的技术原理。同时,也简述了 DeepSpeed 中的增强版数据并行ZeRO。 ## 流水线并行 所谓流水线并行,就是由于模型太大,无法将整个模型放置到单张GPU卡中;因此,将模型的不同层放置到不同的计算设备,降低单个计算设备的显存消耗,从而实现超大规模模型训练,也被称为层间模型并行。 我们首先讲述了朴素流水线并行,但是,朴素流水线并行存在的Bubble太大,导致GPU的利用率很低。为了减少Bubble率,后面又讲述了微批次流水线并行方案GPipe,虽然,GPipe可以显著提高GPU的利用率,但是GPipe采用的是F-then-B 模式(先进行前向计算,再进行反向计算),由于缓存了多个 micro-batch 的中间变量和梯度,因此,显存的实际利用率并不高。后来,我们又讲述了采用1F1B模式(前向计算和反向计算交叉进行,可以及时释放不必要的中间变量)的PipeDream及其变体(PipeDream-2BW、PipeDream-Flush等)来进一步节省显存,训练更大的模型。同时,还提到了常见的AI训练框架中采用的流水线并行方案。 ## 张量并行 将计算图中的层内的参数(张量)切分到不同设备(即层内并行),每个设备只拥有模型的一部分,以减少内存负荷,我们称之为张量模型并行。按照行或者列的切分方式,可将张量并行切分为对应的行并行或者列并行。我们首先介绍了由Megatron-LM提出的仅对权重进行划分的1D张量并行。为了应对超大规模的AI模型,后来又介绍了由 Colossal-AI 提出的多维(2/2.5/3 维)张量并行。2D张量并行提出了针对激活进行切分。该并行方式降低了内存成本,但是却引入更多的通信成本。而2.5D张量通过增加更多的设备来减少通信的开销。而为了进一步减少内存冗余和通信开销,后续有提出了3D张量并行。除此之外,我们还谈到了PyTorch2.0中,开始对张量并行进行支持。 ## 序列并行 序列并行,目前并没有一个统一的定义。我们主要介绍了两篇关于序列并行的工作。 - 第一篇是 Colossal-AI 发表的论文:Sequence Parallelism: Long Sequence Training from System Perspective - 第二篇是 Megatron-LM 发表的论文:Reducing Activation Recomputation in Large Transformer Models 虽然两者都叫序列并行(Sequence Parallelism),但是实际上解决的问题、方法都不一样。前者主要是解决模型的输入长度(sequence length)限制,而后者是主要是减少模型显存的。 同时,还谈到了在PyTorch2.0的版本中提供了对序列并行的支持,不过目前还没有realease。 ## 多维混合并行 前面讲述了数据并行、张量并行、流水线并行等多种并行技术,但在进行上百亿/千亿级以上参数规模的超大模型预训练时,我们通常会组合多种并行技术一起使用。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/538d44466adf463ca3f965455f4d4281~tplv-k3u1fbpfcp-watermark.image?) 我们对目前常见的分布式并行技术组合策略进行了探讨,同时,还讲述了目前业界知名大模型中所采用的多维混合并行方案。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e6969a553890461ab00ed520006c02ac~tplv-k3u1fbpfcp-watermark.image?) ## 自动并行 大模型的分布式训练是一个非常复杂的问题,目前的绝大多数的分布式训练系统,都依赖用户人工反复尝试以及系统专家经验来进行部署,造成严重的资源利用效率低下的问题。因此,我们讲述了自动并行技术。主要针对目前一些经典的半自动(Mesh-tensorflow、GSPMD)或全自动(FlexFlow、Alpa)并行方案进行了相应的探讨。但目前自动并行方案在工业界落地的应用比较少。 ## MOE 并行 现在的模型越来越大,训练样本越来越多,每个样本都需要经过模型的全部计算,这就导致了训练成本的平方级增长。而当我们希望在牺牲极少的计算效率的情况下,把模型规模提升上百倍、千倍,通常就需要使用 MOE并行。我们对带MOE结构的分布式并行策略进行了讲解,同时,也讲述了业界的一些超大模型(Switch-Transformer、GLaM)的MOE并行方案。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/29595855e2da48c590bb690c4be118fd~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=991&h=297&s=59206&e=png&b=fffdfd) ## 分布式训练并行策略选择 上面讲述了各种分布式并行策略,以下是进行分布式训练时针对不同的服务器资源类型(单机多卡、多机多卡),如何选择并行策略非常粗略的概述。 ### 单机单卡场景 当你的模型可以在单张 GPU 卡进行训练时,正常使用。 当你的模型不能在单张 GPU 卡进行训练时, - ZeRO + Offload CPU 和 NVMe(可选的)。 - 启用以**内存为中心的平铺** 。 如果最大层无法放置在单张GPU,则使用 ZeRO - 启用以**内存为中心的平铺** (MCT)。 它允许您通过自动分割层并按顺序执行来运行任意大的层。 MCT 减少了 GPU 上实时参数的数量,但不影响激活内存。 ### 单机多卡场景 当你的模型可以在单张 GPU 卡进行训练时,可以选择 DDP 或 ZeRO: - DDP:分布式 DP。 - ZeRO:可能会更快,也可能不会更快,具体取决于所使用的情况和配置。 当你的模型不能在单张 GPU 卡进行训练时,可以选择 PP、ZeRO、TP: - PP - ZeRO - TP 如果使用 NVLINK 或 NVSwitch 进行节点内通信,这三者应该基本处于同等水平。 如果没有这些, PP 将比 TP 或 ZeRO 更快。 TP 的大小也可能产生影响,最好在您特定设置上进行试验以找到最优的方式。 注意: TP 几乎总是在单个节点内进行使用。 即:TP 大小 <= 每个节点的 GPU 数。 ### 多机多卡场景 当您服务器节点间网络通信速度较快时,可以选择 ZeRO、PP+TP+DP: - ZeRO - 因为它几乎不需要对模型进行任何修改。 - PP+TP+DP - 通信较少,但需要对模型进行大量更改。 当您服务器节点间网络通信速度较慢,并且 GPU 内存仍然不足时,可以选择 DP+PP+TP+ZeRO-1。 这里采用 PP 与 ZeRO-1 进行混合并行,**那么 PP 能与 DeepSpeed ZeRO 2/3一起训练吗**? 答:PP + ZeRO 2/3 不推荐一起训练。 PP 需要累积梯度(accumulate gradients),但 ZeRO2 需要对梯度进行分块(chunk)。 即使能够实现,也没有真正的性能提升。 将两者结合使用来提高效率并不容易,PP + ZeRO 2 实际上比 ZeRO2(无 PP)更慢且内存效率低。如果用户内存不足,用户可以使用 ZeRO3 代替 ZeRO2 + PP。而正因为如此,在 DeepSpeed 中, PP + ZeRO 2/3 之间不兼容。但可以将 PP 与 ZeRO 1 进行组合使用。 这里多说一点:即使该方法效率不高,但是 ColossalAI 为了支持更多的并行训练方法。ColossalAI 还是提供了 ZeRO 3 + PP + TP 一起组合的方案。 参考: - https://github.com/microsoft/DeepSpeed/issues/1110 - https://github.com/microsoft/DeepSpeed/blob/master/deepspeed/runtime/pipe/engine.py#L71 - https://github.com/hpcaitech/ColossalAI/issues/682 - https://github.com/hpcaitech/ColossalAI/pull/477 ## 大模型混合精度训练 FP16 与 BF16 的对比 目前,进行大模型训练的时候,为了节约显存,混合精度训练基本上已经成为了标配。而FP16混合精度已经成为主流大规模模型训练框架的默认选项,用于训练十亿到百亿规模的模型。但是用 FP16 训练巨型 LLM 模型却是一个禁忌,它将面临更多的稳定性挑战。 FP16 会经常溢出,导致数值不稳定、模型不收敛的情况! ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0d9b3ad2162241acaffeb921b4bdb4a4~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=361&h=265&s=79411&e=png&b=fcfbfb) 为了避免溢出,这意味着你的权重必须保持很小。一种称为损失缩放 (loss scaling) 的技术有助于缓解这个问题,但是当模型变得非常大时,FP16 较小的数值范围仍然是一个问题。因此,你需要采用一些训练策略来稳定巨型模型的训练。 作为补救措施,NVIDIA Ampere GPU 提供了BF16浮点格式来缓解FP16的问题。但目前,但目前,**BF16在一些平台上不被支持(因此,它的使用的可能广泛性会被限制)**。当使用 BF16 时,BF16 为指数保留了 8 位 (与 FP32 相同),为小数保留了 7 位。这意味着使用 BF16 我们可以保留与 FP32 相同的动态范围。但代价就是它的精度非常差(相对于 FP16,损失了 3 位精度)。但是在训练时,采用的随机梯度下降法及其变体,该方法有点像蹒跚而行,如果你这步没有找到完美的方向其实没关系,你会在接下来的步骤中纠正自己。无论使用 BF16 还是 FP16,都有一个权重副本始终在 FP32 中 —— 这是由优化器更新的内容。 16 位格式仅用于计算,**优化器以全精度更新 FP32 权重**,然后将它们转换为 16 位格式以用于下一次迭代。因此,不会发生精度损失。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4c40e8a7b4304a63927e999d96c8bba0~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2140&h=808&s=285179&e=png&b=fef9f9) 虽然,之前有一些巨型大模型使用了 FP16 进行混合进行训练,但是从OPT-175、Bloom-176B、GLM130B的训练报告来看,BF16 是更佳的一个解决方案,可以规避很多不必要的烦恼。 ## 结语 本文对本系列文中谈到的一些分布式并行技术进行了简要的总结,以加深对其的理解。 本系列文章更新到此为止,完结,撒花~~ 码字不易,如果觉得我的文章能够能够给您带来帮助,期待您的点赞收藏加关注~~ ================================================ FILE: blog/distribution-parallelism/大模型分布式训练并行技术(六)-多维混合并行.md ================================================ 近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,传统的单机单卡模式已经无法满足超大模型进行训练的要求。因此,我们需要基于单机多卡、甚至是多机多卡进行分布式大模型的训练。 而利用AI集群,使深度学习算法更好地从大量数据中高效地训练出性能优良的大模型是分布式机器学习的首要目标。为了实现该目标,一般需要根据硬件资源与数据/模型规模的匹配情况,考虑对计算任务、训练数据和模型进行划分,从而进行分布式存储和分布式训练。因此,分布式训练相关技术值得我们进行深入分析其背后的机理。 下面主要对大模型进行分布式训练的并行技术进行讲解,本系列大体分八篇文章进行讲解。 - [大模型分布式训练并行技术(一)-概述](https://zhuanlan.zhihu.com/p/598714869) - [大模型分布式训练并行技术(二)-数据并行](https://zhuanlan.zhihu.com/p/650002268) - [大模型分布式训练并行技术(三)-流水线并行](https://juejin.cn/post/7262274383287484476) - [大模型分布式训练并行技术(四)-张量并行](https://juejin.cn/post/7269698032655728640) - [大模型分布式训练并行技术(五)-序列并行](https://juejin.cn/post/7273680143658287156) - 大模型分布式训练并行技术(六)-多维混合并行 - 大模型分布式训练并行技术(七)-自动并行 - 大模型分布式训练并行技术(八)-MOE并行 前面的文章中讲述了数据并行、流水线并行、张量并行等多种并行技术。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/538d44466adf463ca3f965455f4d4281~tplv-k3u1fbpfcp-watermark.image?) 但是在进行上百亿/千亿级以上参数规模的超大模型预训练时,通常会组合多种并行技术一起使用。比如,下图使用了8路模型并行组,64路数据并行组。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d36f0b6a2000412fbf1b67719d759966~tplv-k3u1fbpfcp-watermark.image?) 下面我们一起来看看常见的分布式并行技术组合方案。 ## 常见的分布式并行技术组合 ### DP + PP 下图演示了如何将 DP 与 PP 结合起来使用。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f5d578f014d94d10a623c0775fab3d51~tplv-k3u1fbpfcp-watermark.image?) 这里重要的是要了解 DP rank 0 是看不见 GPU2 的, 同理,DP rank 1 是看不到 GPU3 的。对于 DP 而言,只有 GPU 0 和 1,并向它们供给数据。GPU0 使用 PP 将它的一些负载转移到 GPU2。同样地, GPU1 也会将它的一些负载转移到 GPU3 。 由于每个维度至少需要 2 个 GPU;因此,这儿至少需要 4 个 GPU。 ![并行技术.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e5920b6e0ba74e2d99d2fe94df94e01c~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=457&h=281&s=13883&e=png&b=fef9f9) ### 3D 并行(DP + PP + TP) 而为了更高效地训练,可以将 PP、TP 和 DP 相结合,被业界称为 3D 并行,如下图所示。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e6969a553890461ab00ed520006c02ac~tplv-k3u1fbpfcp-watermark.image?) 由于每个维度至少需要 2 个 GPU,因此在这里你至少需要 8 个 GPU 才能实现完整的 3D 并行。 ### ZeRO-DP + PP + TP 在[大模型分布式训练并行技术(二)-数据并行](https://juejin.cn/post/7254001262646738981) 一文中介绍过 ZeRO,作为 DeepSpeed 的主要功能之一,它是 DP 的超级可伸缩增强版,并启发了 PyTorch FSDP 的诞生。通常它是一个独立的功能,不需要 PP 或 TP。但它也可以与 PP、TP 结合使用。 当 ZeRO-DP 与 PP 和 TP 结合使用时,通常只启用 ZeRO 阶段 1(只对优化器状态进行分片)。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2c13579db2a14e73a0082626d2a30845~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2048&h=1230&s=650273&e=png&a=1&b=ead272) 而 ZeRO 阶段 2 还会对梯度进行分片,ZeRO 阶段 3 还会对模型权重进行分片。虽然理论上可以将 ZeRO 阶段 2 与 流水线并行一起使用,但它会对性能产生不良影响。**每个 micro batch 都需要一个额外的 reduce-scatter 通信来在分片之前聚合梯度**,这会增加潜在的显著通信开销。根据流水线并行的性质,我们会使用小的 micro batch ,并把重点放在算术强度 (micro batch size) 与最小化流水线气泡 (micro batch 的数量) 两者间折衷。因此,增加的通信开销会损害流水线并行。 此外,由于 PP,层数已经比正常情况下少,因此并不会节省很多内存。PP 已经将梯度大小减少了 `1/PP`,因此在此基础之上的梯度分片和纯 DP 相比节省不了多少内存。 除此之外,我们也可以采用 DP + TP 进行组合、也可以使用 PP + TP 进行组合,还可以使用 ZeRO3 代替 DP + PP + TP,ZeRO3 本质上是DP+MP的组合,并且无需对模型进行过多改造,使用更方便。 ## 业界大模型混合并行策略 上面讲述了使用分布式并行技术组合策略,下面我们一起来看看一些业界大模型的混合并行策略。 ### CodeGeeX(13B) CodeGeeX 是一个具有 130 亿参数的多编程语言代码生成预训练模型。CodeGeeX 采用华为 MindSpore 框架实现,在鹏城实验室"鹏城云脑II"中的192个节点(共1536个国产昇腾910 AI处理器)上训练而成。CodeGeeX 历时两个月在20多种编程语言的代码语料库(> 8500 亿 Token)上预训练得到。 CodeGeeX 使用纯解码器的GPT架构,并使用自回归语言建模。CodeGeeX 的核心架构是39层的Transformer解码器。在每个Transformer层包含:多头自注意力模块、MLP模块、LayerNorm和残差连接。使用类GELU的FaastGELU激活,其在Ascend 910 AI处理器上更加高效,整个模型架构如下图所示: ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5f7ac9c345bd42c08b24fe0c92b1c831~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1436&h=1348&s=366741&e=png&b=fefdfd) 为了提高训练效率,CodeGeeX采用8路模型并行组和192路数据并行组进行混合并行训练;同时,启用 ZeRO-2 来进一步减少优化器状态的内存消耗。 ### GPT-NeoX(20B) GPT-NeoX-20B 是一个具有 200 亿参数通用的自回归密集型预训练语言模型。在12 台 Supermicro AS-4124GO-NART 服务器上进行训练;其中,每台服务器配备 8 个 NVIDIA A100-SXM4-40GB GPU,并配置了两个 AMD EPYC 7532 CPU。 所有 GPU 都可以通过用于 GPUDirect RDMA 的四个 ConnectX-6 HCA 之一直接访问 InfiniBand 交换结构(switched fabric)。两台 NVIDIA MQM8700-HS2R 交换机(通过 16 个链路连接)构成了该 InfiniBand 网络的主干,每个节点的 CPU 插槽有一个链路连接到每个交换机。每个训练节点的架构图如下所示: ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0823ccfe916e4d3b8f60ecfa8cba07a9~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1606&h=894&s=289541&e=png&b=fefcfc) GPT-NeoX-20B 采用了数据并行、流水线并行和张量并行相结合的方式进行训练。 同时,作者发现,在给定硬件设置的情况下,最有效方法是将张量并行大小设置为 2,将流水线并行大小设置为 4。这允许最通信密集的进程,张量和流水线并行发生在节点内,数据并行通信发生在节点边界之间。 ### GLM(130B) GLM-130B 是一个由清华开源的双语(中文和英文)双向稠密模型,拥有 1300 亿参数,模型架构采用通用语言模型(GLM)。在超过 4000 亿个文本标识符上预训练完成。GLM-130B 利用自回归空白填充作为其主要的预训练目标,以下图中的句子为例,它掩盖了随机的连续文本区间(例如,“complete unkown”),并对其进行自回归预测。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7203bda62d6447de9a3e95714ff5f581~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1496&h=608&s=345552&e=png&b=fefdfd) 在实际训练中,GLM-130B 使用两种不同的掩码标识符(`[MASK]` 和 `[gMASK]`),分别用于短文和长文的生成。此外,它还采用了最近提出的旋转位置编码(RoPE)、DeepNorm 层规范化和高斯误差 GLU(GeGLU)技术。所有这些设计和技术都对 GLM-130B 大规模语言模型的稳定训练和高精度性能有所帮助。具体来说,GLM-130B 模型含有 70 层 Transformer,隐层维度 12,288,最大序列长度 2,048,以及一个基于 [icetk](https://github.com/THUDM/icetk) 的 150,000 个标识符的双语分词器。 它的预训练目标由两部分组成:第一部分(95%)是自监督的预训练,即在公开的大规模语料库以及其他一些较小的中文语料库上的自回归空白填充。第二部分(5%)是在 T0++ 和 DeepStruct 中 70 个不同数据集的抽样子集上进行多任务指令预训练,格式为基于指令的多任务多提示序列到序列的生成。这种设计使 GLM-130B 可以在其他数据集上进行了零样本学习,以及从英文到中文的零样本迁移。 GLM-130B 的预训练持续了 60 天,使用 96 个 DGX-A100(40G)节点,共 768 张 GPU 卡。采用了流水线模型并行与张量并行、数据并行策略相结合的方式,形成 3D并行策略。 为了进一步减少流水线引入的气泡,利用 DeepSpeed 的 PipeDream-Flush 实现来训练具有相对较大的全局批量大小 (4,224) 的 GLM-130B,以减少时间和 GPU 内存浪费。 通过数值和实证检验,采用4路张量并行组和8路流水线并行组,达到每张 GPU(40G)135 TFLOP/s。 ### OPT(175B) OPT-175B 是 Meta AI 开源的一个拥有 1750 亿参数的语言模型,利用完全分片数据并行(FSDP)与 Megatron-LM 张量并行(8路组)在 992 个 80GB A100 GPU 上训练了 OPT-175B。训练数据包含180B个token,对应800GB的数据,持续训练了约33天。 每个 GPU 的利用率高达 147 TFLOP/s。 OPT-175B 将 Adam 状态使用 FP32,并将其分片到所有主机上;而模型权重则使用 FP16。为了避免下溢,使用了动态损失缩放。 ### Bloom(176B) Bloom-176B 是一个拥有 1760 亿参数自回归大语言模型 (LLM),它是迄今为止开源的最大的多语言(含46种自然语言和13种编程语言)大模型,整个模型架构如下图所示: ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a84f2846898b48a7b1419645990c31ec~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1702&h=928&s=209098&e=png&b=fef7f7) Bloom-176B 进行预训练时,在 384 张 NVIDIA A100 80GB GPU (48 个节点) 上使用了 3D 并行(数据并行、流水线并行、张量并行 )策略,针对 350B 个Token 训练了大约 3.5 个月。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ef862f747a0f45cea7a24b2500ea166c~tplv-k3u1fbpfcp-watermark.image?) ### Megatron-Turing NLG(530B) Megatron-Turing NLG-530B 是微软和英伟达联合推出的一个包含 5300 亿参数的自回归大语言模型。使用了 Transformer 解码器的架构,其中:Transformer层数、隐藏层维度、注意力头分别为 105、20480 和 128。 序列长度为2048,全局批量大小为1920。 在训练时,每个模型副本跨越 280 个 NVIDIA A100 GPU,节点内采用Megatron-LM 的 8 路张量并行组,节点间采用 35 路流水线并行组。整个训练过程一共使用了 4480 块英伟达 A100 GPU, 在 2700 亿个 Token 上面训练。 ## 结语 本文主要讲解了常见的大模型分布式并行技术的组合策略,同时,也讲述了目前业界的一些大模型所使用的并行策略,具体如下表所示。 | 模型 | DP | TP | PP | ZeRO Stage | FSDP(ZeRO Stage 3) | GPUs | FP16/BF16 | | ------------ | --- | --- | --- | ---------- | ------------------ | ----------------------- | ------ | | Bloom-176B | 8 | 4 | 12 | ZeRO-1 | - | 384 张 A100 80GB | BF16 | | CodeGeeX-13B | 192 | 8 | - | ZeRO-2 | - | 1,536 张 Ascend 910 32GB | FP16 | | GLM-130B | 24 | 4 | 8 | ZeRO-1 | - | 768 张 A100 40G | FP16 | | OPT-175B | 124 | 8 | - | - | ✅ | 992 张 80GB A100 | FP16 | | Megatron-Turing NLG-530B | 16 | 8 | 35 | N/A | - | 4480 张 A100 80G | BF16 | | GPT-NeoX-20B | 12 | 2 | 4 |ZeRO-1 | - | 96 张 A100 40G | FP16 | 码字不易,如果觉得我的文章能够能够给您带来帮助,期待您的点赞收藏加关注~~ ================================================ FILE: blog/llm-algo/moe.md ================================================ 将输入路由到不止一个专家,以便门控学会如何进行有效的路由选择,因此至少需要选择两个专家。Switch Transformers 就这点进行了更多的研究。 ================================================ FILE: blog/llm-algo/大白话Transformer架构.md ================================================ Attention(注意力机制): Attention机制允许模型为输入序列中的每个位置分配不同的权重,用以关注输入序列中不同位置的信息。它通过计算每个位置与其他所有位置之间的相似度(通过点积、缩放点积等方法),然后将这些相似度转换成权重,最后将输入序列中的所有位置按照这些权重进行加权求和。这种机制使得模型能够处理长距离的依赖关系,同时能够并行计算,提高了模型的效率。 Feed-Forward Neural Network (FFN)(前馈神经网络): 每个Transformer层都包含两个线性变换,之间由非线性激活函数(通常是ReLU)连接。FFN对每个位置的表示进行独立的变换,从而捕捉到位置特定的模式和特征。这个步骤有助于提高模型的非线性建模能力。 Layer Normalization(层归一化): 在每个Transformer层的子层(Attention和FFN)之后都会应用LayerNorm。LayerNorm的作用是对每个位置的特征进行归一化处理,使得每个特征的均值接近0,标准差接近1。这样做有助于缓解训练时的梯度消失问题,并且可以加速训练过程。 Add & Normalize(加和与归一化): 在每个子层(Attention和FFN)的输入和输出之间应用残差连接(或者称为skip connection),然后对输出进行LayerNorm操作。这个步骤的目的是引入残差连接,使得模型可以学习到输入和输出之间的差异,有助于减缓梯度消失问题,同时也使得模型更容易学习到恒等映射。在LayerNorm之后应用残差连接有助于稳定训练。 Attention机制用于捕捉输入序列中的关联关系, FFN用于捕捉每个位置的非线性特征,从而增加模型的表示能力和拟合复杂模式的能力, LayerNorm用于归一化特征并缓解梯度消失问题,而Add & Normalize结构引入残差连接,使得模型更容易训练。 ================================================ FILE: blog/llm-compression/大模型量化技术原理-ZeroQuant系列.md ================================================ 近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,从而导致模型变得越来越大,因此,我们需要一些大模型压缩技术来降低模型部署的成本,并提升模型的推理性能。 模型压缩主要分为如下几类: - 剪枝(Pruning) - 知识蒸馏(Knowledge Distillation) - 量化 本系列将针对大模型的一些常见训练后量化方案(GPTQ、LLM.int8()、SmoothQuant、AWQ等)进行讲述。 - [大模型量化概述](https://www.zhihu.com/question/627484732/answer/3261671478) - [大模型量化技术原理-GPTQ、LLM.int8()]() - [大模型量化技术原理-SmoothQuant]() - [大模型量化技术原理-AWQ、AutoAWQ]() - [大模型量化技术原理-SpQR]() - [大模型量化技术原理-ZeroQuant系列]() 而本文主要针对大模型量化技术 ZeroQuant 系列进行讲述。 - **ZeroQuant**: Efficient and Affordable Post-Training Quantization for Large-Scale Transformers - **ZeroQuant-V2**: Exploring Post-training Quantization in LLMs from Comprehensive Study to Low Rank Compensation - **ZeroQuant-FP**: A Leap Forward in LLMs Post-Training W4A8 Quantization Using Floating-Point Formats - **ZeroQuant-HERO**: Hardware-Enhanced Robust Optimized Post-Training Quantization Framework for W8A8 Transformers ## ZeroQuant ## ZeroQuant-V2 ## ZeroQuant-FP ## ZeroQuant-HERO 参考文档: - https://github.com/microsoft/DeepSpeed - ZeroQuant: https://arxiv.org/pdf/2206.01861.pdf - ZeroQuant-V2: https://arxiv.org/abs/2303.08302 - ZeroQuant-FP: https://arxiv.org/pdf/2307.09782.pdf - ZeroQuant-HERO: https://arxiv.org/pdf/2310.17723.pdf ================================================ FILE: blog/llm-compression/大模型量化技术原理:QoQ量化及QServe推理服务系统.md ================================================ 近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,从而导致模型变得越来越大,因此,我们需要一些大模型压缩技术来降低模型部署的成本,并提升模型的推理性能。 模型压缩主要分为如下几类: - 剪枝(Pruning) - 知识蒸馏(Knowledge Distillation) - 量化(Quantization) 本系列将针对一些常见大模型量化方案(GPTQ、LLM.int8()、SmoothQuant、AWQ等)进行讲述。 - [大模型量化概述](https://www.zhihu.com/question/627484732/answer/3261671478) - 量化感知训练: - [大模型量化感知训练技术原理:LLM-QAT](https://zhuanlan.zhihu.com/p/647589650) - [大模型量化感知微调技术原理:QLoRA]() - 训练后量化: - [大模型量化技术原理:GPTQ、LLM.int8()](https://zhuanlan.zhihu.com/p/680212402) - [大模型量化技术原理:SmoothQuant](https://www.zhihu.com/question/576376372/answer/3388402085) - [大模型量化技术原理:AWQ、AutoAWQ](https://zhuanlan.zhihu.com/p/681578090) - [大模型量化技术原理:SpQR](https://zhuanlan.zhihu.com/p/682871823) - [大模型量化技术原理:ZeroQuant系列](https://juejin.cn/post/7338284106797432873) - [大模型量化技术原理:FP8](https://www.zhihu.com/question/658712811/answer/3596678896) - [大模型量化技术原理:FP6](https://juejin.cn/post/7412893752090853386) - [大模型量化技术原理:KIVI、IntactKV、KVQuant](https://zhuanlan.zhihu.com/p/5932153295) - [大模型量化技术原理:Atom、QuaRot](https://zhuanlan.zhihu.com/p/6281447174) - [大模型量化技术原理:QoQ量化及QServe推理服务系统](https://zhuanlan.zhihu.com/p/8047106486) - [大模型量化技术原理:FP4]() - [大模型量化技术原理:总结]() 之前讲述了W4A4KV4量化方案Atom和QuaRot,本文将讲述来自 MIT HAN Lab 的W4A8KV4量化方案 QoQ 及 QServe 推理服务系统。 > 文章较长,建议先点赞收藏,后续再慢慢观看。另外,我撰写的**大模型相关的博客及配套代码**均整理放置在Github:[llm-action](https://github.com/liguodongiot/llm-action/tree/main),有需要的朋友自取。 ## 背景 目前,业界主要的整数量化算法可以分为三类:8位权重和8位激活(W8A8)、4位权重和16位激活(W4A16)、4位权重和4位激活(W4A4)量化。前两种方法在准确性方面几乎无损。相比之下,W4A4量化导致显著的准确性降低,尽管通过将其计算映射到高吞吐量的 INT4 Tensor Cores 上有望提供更高的吞吐量。 不幸的是,这种预期的性能提升并没有在当前的GPU上得到一致的观察。例如,最先进的W4A4服务系统 Atom 在 A100 GPU上运行Llama2-7B模型时,比TensorRT-LLM中的 W4A16 和 W8A8 性能还要低20-25%。 也就是说,社区尚未找到一种比W4A16和W8A8更优越的精度组合,用于高效的进行LLM推理服务。例如,W4A16 量化在 FP16 Tensor Cores 上执行计算,由于权重在INT4中,因此需要在 GEMM Kernel 中进行权重反量化。 另一方面,对于W4A4量化,为了保持准确性,**必须对权重和激活应用逐组(per-group)量化,在子通道基础上共享 FP16 缩放因子**。例如,最先进的W4A4量化方法 QuaRot 报告中说从逐组(per-group)量化切换到逐通道(per-channel)量化后,导致困惑度退化0.2。这种逐组(per-group)量化设计需要对局部和进行整数到浮点的反量化(因为INT4 Tensor Core 产生 INT32 局部和),它在W4A4 GEMM的顺序主循环中运行在较慢的 CUDA Core 内。在数据中心GPU上,如A100,**一个CUDA Core 操作与 50 个INT4 Tensor core 操作一样昂贵**。因此,减少CUDA Core 上的开销对于实现LLM服务的最佳吞吐量至关重要。 为了应对这一挑战,作者引入了QoQ,一种W4A8KV4量化算法。QoQ由QServe推理库实现。在QoQ算法中,引入了渐进式量化,在 W4A8 GEMM 中具有较低的反量化开销。此外,还开发了SmoothAttention 来有效减轻4位KV量化引起的准确性下降。在QServe系统中,执行计算感知的权重重排序,并利用寄存器级并行来减少反量化延迟,还使融合注意力算子保持在内存受限区域,利用KV4量化带来性能提升。 ## 动机 权重和KV缓存量化(例如:W4、KV4)可以减少LLM服务中的内存占用。同时量化权重和激活(例如:W8A8)也可以提高峰值计算吞吐量。为LLM部署选择合适的精度是一项困难的任务。现有的解决方案如上所述可以大概分为三类:W4A16(per-group)、W8A8(per-channel权重量化+per-token激活量化)、W4A4(per-group)。 **QoQ 为什么选择 W4A8KV4 精度进行量化**? 在LLM中Attention和GEMM运算占大头,所以集中分析这2个部分。在LLM中,计算强度主要被batch_size影响,batch_size越大计算强度越大,如下图所示。 ![](https://files.mdnice.com/user/18421/c0d2dfb3-1dec-4cde-9f04-c537ff19c3e0.png) 对于一个 m × n × k GEMM 问题,当n、k比m大得多时,计算强度(定义为 MACs/element)大约是m。这种情况适用于LLM解码阶段,因为m是序列数,而n、k是通道大小。 对图 3中 A100 GPU 的 Roofline 进行性能分析,当 m < 78 时,W4A16的理论吞吐量更高,而当 m > 78 时,W8A8表现更好。当输入批处理大小很小时,LLM中的GEMMs是内存受限的,内存带宽由权重流量主导。因此,W4A16的较小内存占用带来了更好的性能。然而,当m很大时,问题就变成了计算受限的。因此,W8A8由于INT8 Tensor Core具有更高吞吐量而速度更快。而作者期望 W4A8 在所有批处理大小上能结合以上两者的优势。 ![](https://files.mdnice.com/user/18421/cf5ec5d5-a9b5-40c2-b276-d4197d801c92.png) 综上所述,在计算强度较小时,主要是memory-bound,memory带宽主要被模型权重占据;因此,占用内存更低的W4A16的吞吐量会比W8A8要高。在计算强度较大时,主要是compute-bound,这时因为能够充分利用INT8 Tensor Core,W8A8的吞吐量会更高。而W4A8可以认为兼具两者的优势,不论计算密度是高是低,它都能保持最优的计算吞吐量。 而 LLM 解码阶段Attention的计算密度很低(每个token逐步回归迭代),这个阶段还是memory-bound,所以 KV Cache 加载越快计算吞吐就越高,因此,采用KV4可以得到KV8的两倍峰值性能。 **那么为什么不选择更激进的W4A4呢**? 当输入序列数 m 超过78时,由memory-bound变为了compute-bound,W4A4开始获得更好的理论GEMM性能,因为4位 Tensor Core 的性能是8位 Tensor Core 的两倍。然而,除了显著的准确性降低,这种理论性能提升在现有的GPU架构(Ampere和Hopper)上无法实现。如图2b所示,现有的W4A4服务系统Atom和QuaRot甚至比TensorRT-LLM中的W16A16解决方案慢得多。 虽然这种性能差距部分可以用这两个系统中的低效运行时来解释,但以前文献中忽略了将逐组(per-group)量化的 W4A4 GEMM 映射到GPU的固有困难。 最先进的系统实现 Tensor Core GEMM 如图4所示的输出固定数据流。 ![](https://files.mdnice.com/user/18421/57314dce-7829-404e-8ab2-3598431262c9.png) 对于一个m × n × k GEMM 问题,每个线程块通过顺序遍历reduction维度k来计算一个 $t_m × t_n$ 输出分片(tile)。这个顺序循环被称为主循环。主循环包含100多个迭代,并且占据了GEMM Kernel 的大部分运行时间。 在 FP16 和 W8A8 GEMM(图5a)中,**主循环完全在 Tensor cores 上执行**。 TensorRT-LLM-W4A16(图5b)和 Atom-W4A4(图5c)都**需要在主循环中进行反量化操作,这些操作在 CUDA Core 上运行**。W4A16 需要 INT4到FP16的权重转换,而 Atom-W4A4 需要INT32到FP32的局部和转换和累加。 ![](https://files.mdnice.com/user/18421/3b516e57-7376-4864-88ae-206c2e8fc080.png) Atom主循环中的反量化过程导致了两个显著的效率瓶颈。 - 首先,在像A100和H100这样的GPU上,FP32 CUDA Core 的峰值性能仅为 INT4 Tensor Core 的2%。也就是说,在Atom中反量化一个单独的局部和相当于 50 个 Tensor Core MACs。而主循环由慢速 CUDA Core 操作而不是快速Tensor Core 操作主导。 - 其次,Atom 创建了两组寄存器(一组用于FP32,一组用于INT32)来保存局部和。由于输出固定数据流的特性,较大的GEMM问题(例如:预填充阶段)通常在GPU上而受到寄存器限制,这导致存储局部和的寄存器消耗很高。每个warp消耗大量寄存器限制了可以在流式多处理器(SM)上同时执行的warp数量。值得注意的是,GPU 依赖于大量 in-flight warp 之间进行低成本上下文切换来隐藏延迟。因此,同时执行的warp数量减少限制了延迟隐藏的机会,进一步加剧了主循环开销。 QServe 中的 W4A8 逐组(per-group)量化 GEMM Kernel 设计如图5d。通过采用了两级渐进式分组量化方法,以确保所有计算都在INT8 Tensor Cores上执行。**选择权重反量化而不是局部和反量化,因为它的寄存器压力较低**。此外,应用4路寄存器级并行来同时解码四个INT4权重,进一步减少了主循环开销。 ## QoQ 为了实现 W4A8KV4 量化精度的理论吞吐量优势,同时不牺牲大语言模型的有效性。QoQ算法采用渐进式分组量化、SmoothAttention和各种通用量化优化功能。 ### 渐进式分组量化 为了提高低比特量化的准确性,通常使用分组量化。然而,它在系统实现中的反量化开销可能会抵消这些准确性的提高。为了解决这个问题,引入了渐进式分组量化,如图6所示。 ![](https://files.mdnice.com/user/18421/b8114690-40be-4d14-b663-b6133e3431a3.png) 给定权重张量 $\mathbf{W} \in \mathbb{R}^{k \times n}$,首先,应用逐通道(per-channel)对称INT8量化: $$\small \hat{\mathbf{W}} = {\mathbf{Q}_{\mathbf{W}}}^{(0)}_{\mathrm{s8}} \cdot \mathbf{s}^{(0)}_{\mathrm{fp16}}$$ 其中,${\mathbf{Q}_{\mathbf{W}}}_{\mathrm{s8}}^{(0)} \in \mathbb{N}^{n \times k}$ 是中间8位量化的权重张量,$\mathbf{s}^{(0)}_{\mathrm{fp16}} \in \mathbb{R}^{n \times 1}$ 是逐通道(channel-wise)量化缩放因子。 然后,进一步在中间权重张量上应用逐组(per-group)非对称INT4量化: $$ \small {{\mathbf{Q}}_{\mathbf{W}}}_\mathrm{s8}^{(0)} = \left({\mathbf{Q}_{\mathbf{W}}}_{\mathrm{u4}} - \mathbf{z}_{\mathrm{u4}} \right)\cdot \mathbf{s}^{(1)}_{\mathrm{u8}}$$ 其中, ${\mathbf{Q}_{\mathbf{W}}}_{\mathrm{u4}} \in \mathbb{N}^{n \times k}$ 是无符号4位量化权重张量,$\mathbf{z}_{\mathrm{u4}} \in \mathbb{N}^{n \times k / g}$ 是无符号4位逐组(group-wise)量化零点, $\mathbf{s}^{(1)}_{\mathrm{u8}} \in \mathbb{N}^{n \times k/g}$ 是无符号8位逐组(group-wise)量化缩放因子。 对于W4A8 GEMM计算,4位量化权重张量 ${\mathbf{Q}_{\mathbf{W}}}_{\mathrm{u4}}$ 将首先根据上述方程反量化为中间8位量化权重张量 ${\mathbf{Q}_{\mathbf{W}}}_{\mathrm{s8}}^{(0)}$,然后执行INT8矩阵乘法,就好像是 W8A8 逐通道(per-channel)量化一样。 a) 保护量化范围 简单地应用上述方程并不能保证中间反量化权重完全位于8位整数表示范围内。例如,经过INT8量化后,一组8位权重位于[-113, 120]。4位非对称量化将得到缩放因子 ⌈(120−(−113))/(15−0)⌉=16 和零点 ⌈0−(−113)/16⌉=7 。因此,值120被量化为 ⌈120/16+7⌉=15。它将被反量化为 (15−7)×16=128,这超出了最大8位整数127。 一个直接的解决方案是在反量化过程中的算术指令启用饱和选项。然而,简单地应用饱和将严重损害计算吞吐量,速度降低高达67%。 作者重新考虑反量化过程。 将 $\mathbf{Q}_{\mathbf{X}} = \left\lceil \frac{\mathbf{X}}{s}+z\right\rfloor, s=\frac{\mathbf{X}_{\max}-\mathbf{X}_{\min}}{q_{\max}-q_{\min}}, z= \left\lceil q_{\min}-\frac{\mathbf{X}_{\min}}{s}\right\rfloor$ 代入 $\small {{\mathbf{Q}}_{\mathbf{W}}}_\mathrm{s8}^{(0)} = \left({\mathbf{Q}_{\mathbf{W}}}_{\mathrm{u4}} - \mathbf{z}_{\mathrm{u4}} \right)\cdot \mathbf{s}^{(1)}_{\mathrm{u8}}$ 得到: $$ \small \hat{q}_{s8} = \lfloor \frac{{q}_{s8}}{{s}_{u8}} \rceil \cdot {{s}_{u8}} \le {q}_{s8} + \frac{1}{2} {{s}_{u8}}. $$ 由于${s}_{u8} = \frac{{{q}_{s8}}_{\max} - {{q}_{s8}}_{\min}}{{{q}_{u4}}_{\max} - {{q}_{u4}}_{\min}} \le \frac{127-(-128)}{15-0} = 17$ ,得到:$\small \hat{q}_{s8} \le 127 \rightarrow {q}_{s8} \le 127 - \frac{1}{2} {{s}_{u8}} \rightarrow {q}_{s8} \le 119.5$ 因此,**将INT8对称量化范围从[-127, 127]缩小到保护范围[-119, 119],以避免去量化溢出**,如图6顶部所示。 b) 与以前的两级量化方法比较,渐进式分组量化引入了两个层级的缩放因子: $\mathbf{s}^{(0)}_{\mathrm{fp16}}$ 和 $\mathbf{s}^{(1)}_{\mathrm{u8}}$。 以前的研究,如QLoRA中的VSQuant和DoubleQuant,也引入了两级缩放因子来减少组内缩放因子的内存占用。它与这里的量化流程不同,以前的方法直接使用目标精度进行组量化,然后使用组内浮点缩放因子执行逐通道(per-channel)量化,如图6底部所示: $$\small \hat{\mathbf{W}} = {\mathbf{Q}_{\mathbf{W}}}_{\mathrm{s4}} \cdot \mathbf{s}_{\mathrm{fp16}}, \;\;\;\hat{\mathbf{s}}_{\mathrm{fp16}} = {\mathbf{s}}^{(1)}_{\mathrm{u8}} \cdot \mathbf{s}^{(0)}_{\mathrm{fp16}}$$ 因此,使用组内缩放因子 ${\mathbf{s}}^{(1)}_{\mathrm{u8}}$ 反量化 $\mathbf{Q}_{\mathbf{W}_{\mathrm{s4}}}$ 不能产生8位权重张量。在GPU上进行计算时,这些方法首先反量化缩放因子(scales),然后反量化权重为浮点值,这最终限制了峰值吞吐量。 DGQ也遵循VSQuant和DoubleQuant的量化方案,但对缩放因子施加限制,以确保所有计算都可以映射到INT8 Tensor Core上。然而,DGQ服务系统**将反量化Kernel与GEMM Kernel 分开**。因此,DGQ中W4A8 GEMM的端到端延迟甚至比cuBLAS中的W8A8 GEMM还要慢,未能展示4位权重量化的内存带宽优势。 相反,QoQ引入了一个保护范围,允许**将反量化操作融合到 W4A8 GEMM Kernel 中,实现全寄存器级并行**,最小化CUDA Core开销。因此,QServe的 W4A8 逐组(per-group)GEMM 比 cuBLAS GEMM 快 1.5 倍。 ### SmoothAttention 如图16所示,直接将KV缓存减少到4位会显著降低LLM的准确性。图7中可视化了采样的Key和Value缓存激活的幅度分布。可以观察到:Value矩阵没有明显的异常值,**而Key矩阵在每个Attention头中都有固定的异常值通道**。 ![](https://files.mdnice.com/user/18421/ed4fef05-ec68-47df-8ff2-6a2defc5337f.png) ![](https://files.mdnice.com/user/18421/260df91c-42b9-46ee-bcaf-e1308908d533.png) 这些异常值比大多数激活值大10倍左右。虽然在以前的工作中很容易处理KV8量化,但对KV4量化来说是一个挑战,因为较低的量化层级。 受SmoothQuant的启发,作者提出了SmoothAttention,通过逐通道(per-channel)因子 $\lambda$ 缩小 Key 缓存中的异常通道: $$ \small \mathbf{Z} = \left(\mathbf{Q}\mathbf{\Lambda}\right)\cdot \left(\mathbf{K}\mathbf{\Lambda}^{-1}\right)^T,\;\;\;\mathbf{\Lambda}=\mathrm{diag}\left(\mathbf{\lambda}\right)$$ SmoothQuant将**量化难度从激活迁移到权重**,因此需要**通过搜索迁移强度来平衡激活和权重量化**。相反,由于**QoQ不量化Query,只需要专注于Key**,并且简单地选择 SmoothAttention 缩放因子为: $$ \small \mathbf{\lambda}_{i} = \max\left(|\mathbf{K}_i|\right)^{\alpha}.$$ 在实践中,$\alpha = 0.5$ 就足够了。 如图7所示,经过SmoothAttention处理后,Key缓存中的异常值已经大大平滑。**为了消除SmoothAttention缩放的额外Kernel调用开销,最好将缩放因子融合到前一层的权重中**。然而,现代LLM使用旋转位置嵌入(RoPE)处理Key和Query,这需要额外处理。在实践中,旋转位置嵌入将通道i与每个Attention头中的通道i + D/2配对。 因此,为了使SmoothAttention缩放在RoPE方面可交换,增加了一个硬约束,即$\lambda_{i} = \lambda_{i + \frac{D}{2}}$, $$\small \mathbf{\lambda}_{i} = \lambda_{i + \frac{D}{2}} = \max\left(\max\left(|\mathbf{K}_i|\right), \max\left(|\mathbf{K}_{i+\frac{D}{2}}|\right)\right)^{\alpha}$$ 之后,可以轻松地将SmoothAttention缩放 $\mathbf{\Lambda}$ 融合到前一层的权重中,按照 $\mathbf{W}_{Q} = \mathbf{\Lambda}\mathbf{W}_{Q}$和 $\mathbf{W}_{K} = \mathbf{\Lambda}^{-1}\mathbf{W}_{K}$。 ### LLM量化通用优化 低比特LLM量化的一个关键挑战是每个线性层的激活异常值。作者对不同类型的线性层应用不同的优化,如下所述。 1. **块输入模块旋转** 在 Transformer 块中,定义**接收块输入的组件**作为输入模块,例如:QKV投影层和第一个FFN层。如图8所示,受Quarot、Quip的启发,通过**乘以旋转矩阵来旋转块输入激活**。 为了保持线性层的数学等价性,相应地**以相反的方向旋转对应权重**。**旋转后,每个通道的激活是所有其他通道的线性组合,因此有效地抑制了异常值通道**。 此外,由于旋转是酉变换(酉变换,即酉空间V的等度量变换,复数向量空间中保持向量内积不变的线性变换。这种变换保留了向量的长度和向量之间的夹角,使其在许多数学和物理问题中变得非常有用,如在量子力学中,酉变换用来描述系统的演化,保持概率守恒;在信号处理中,酉变换用于保持信号的能量不变),可以将旋转矩阵与前一层的权重融合。这里简单地选择**缩放后的哈达玛矩阵**(哈达玛矩阵是一种方块矩阵。它的矩阵元素为1或-1。其矩阵中不同的行具备正交性质)作为旋转矩阵。 ![](https://files.mdnice.com/user/18421/156c1f61-ff27-4a28-af81-8765d2b7ab35.png) 2. **块输出模块平滑** 输出模块指的是**生成块输出的层**,例如:输出投影层和第二个FFN层。如图9所示,受SmoothQuant的启发,**通过除以每个通道的平滑因子来平滑块中间激活**,原始的SmoothQuant没有平滑块中间激活; 此外,如果这里直接用与输入模块相同的迁移强度平滑这些模块(例如:q_proj、up_proj),在Wikitext-2上Llama2-7B模型的困惑度将退化高达0.05。 **在实践中,发现迁移强度$\alpha$应该接近0。也就是说,平滑因子$\lambda$主要由权重而不是激活决定**,这与SmoothQuant中的观察结果非常不同。 ![](https://files.mdnice.com/user/18421/f62a6b2e-3a6b-4877-9596-9839d0852de0.png) 3. **激活感知的通道重排序** AWQ和Atom都观察到,保持显著权重为FP16可以显著提高模型准确性。这些显著的权重可以通过激活分布来识别。与Atom使用的混合精度量化不同,这里提出了激活感知通道重排序,如图10所示。**使用最大(|X|)来确定通道显著性,然后重新排序通道,使得具有相似显著性的通道在同一个量化组中**。 ![](https://files.mdnice.com/user/18421/2f670af9-7655-4184-90e1-a6d8ebdbb669.png) 4. **权重裁剪** 权重裁剪是另一种流行的量化优化技术。它通过$\mathbf{W}_{\max}=\alpha \max\left(\mathbf{W}\right)$ 和 $\mathbf{W}_{\min}=\alpha \min\left(\mathbf{W}\right)$ 对方程中 $\mathbf{Q}_{\mathbf{X}} = \left\lceil \frac{\mathbf{X}}{s}+z\right\rfloor, s=\frac{\mathbf{X}_{\max}-\mathbf{X}_{\min}}{q_{\max}-q_{\min}}, z= \left\lceil q_{\min}-\frac{\mathbf{X}_{\min}}{s}\right\rfloor$中的动态范围应用裁剪比率 $\alpha$ 进行裁剪。 以前的方法Quarot、GPTQ、Awq、Atom通过网格搜索裁剪比率 $\alpha$ 来最小化张量本身的量化误差(即:$\|\mathbf{W} - Q\left(\mathbf{W};\alpha\right)\|$ )或输出均方误差(即:$\|\mathbf{X}\mathbf{W}^T - \mathbf{X}Q\left(\mathbf{W}^T;\alpha\right)\|$ )。在QServe中,最小化所有线性层(除了 q_proj 和 k_proj)的**层输出误差**,对于 q_proj 和 k_proj,通过优化**块输出均方误差**: $$\small \arg\min_{\alpha} \|\mathrm{Block}\left(\mathbf{X}; \mathbf{W}\right) - \mathrm{Block}\left(\mathbf{X}; Q\left(\mathbf{W}; \alpha\right)\right)\|$$ ## QServe 在介绍了QoQ量化算法之后,实现图3中预测的理论吞吐量优势仍然是一个挑战。因此,下面将深入探讨QServe系统设计,该设计遵循两个重要原则: 1. 减少 GEMM Kernel 中主循环的开销; 2. 使融合注意力 Kernel 保持在内存受限的范围。 ### QServe 系统运行时 首先介绍图11中的QServe运行时。 ![](https://files.mdnice.com/user/18421/95f2e32e-f8e2-4230-bcbc-55058fbb1311.png) QServe中的**所有GEMM层都使用W4A8输入**,在 INT8 Tensor Core 上执行计算,并生成FP16输出。所有注意力层都在CUDA Core上以FP16执行计算。因此,**QServe中的每个LLM块都有FP16输入和FP16输出**。 **激活量化**。为确保每个GEMM输入为INT8激活,对于QKV投影和第一个FFN层,将激活量化融合到前面的 layernorm 中;对于第二个FFN层,则融合到前面的激活 Kernel 中。此外,在注意力块的输出投影之前插入了一个单独的量化节点。 **KV缓存管理**。为了避免内存碎片化,遵循vLLM和TensorRT-LLM的方法,采用分页KV缓存。与这些框架不同,它们对KV缓存执行逐层(per-tensor)静态量化(即,缩放因子离线计算),QServe由于较低的比特精度需要逐头(per-head)动态KV量化以保持准确性。因此,在每个 KV 缓存页面中量化 KV 特征之后,紧跟存储每个头的 FP16 缩放因子和零点,从而允许动态更新这些值。 此外,QServe还支持与vLLM和TensorRT-LLM相似的连续批处理。 ### QServe 中的 W4A8 GEMM 如前文所讨论的,主循环的开销在**量化GEMM以实现roofline模型(图3)预测的理论性能增益**方面构成了重大障碍。因此,QServe W4A8 GEMM的重点在于减少主循环开销。 具体来说,通过计算感知的权重重排序来解决指针算术操作的成本,并采用乘法后减法(subtraction after multiplicatio)计算顺序和寄存器级并行来减少反量化开销。 1. 计算感知的权重重排序: 在反量化和Tensor Core计算之前,运算对象必须从全局内存加载到L1共享内存中,每个主循环迭代期间都是如此。 如图所示,Tensor Core GEMM 本质要求在计算中为每个线程进行跨步(strided)布局。由于Tensor Core GEMM kernel要求每个线程在计算时都采用跨步布局,因此这一加载过程并不简单。 ![](https://files.mdnice.com/user/18421/8539a6e0-db54-4e27-bd32-c352468c9016.png) 例如,线程0不是连续加载八个INT8权重,而是首先加载输入通道0-3,然后跳到输入通道16-19。也就是说,一个简单的权重加载实现将需要每个四个通道执行一次地址计算,这将导致两个效率问题。 - 首先,指针算术操作在CUDA Core上执行,其吞吐量比A100上的INT8 Tensor Core 低32倍。因此,地址计算开销变得不可忽视。 - 其次,跨步内存访问阻止了通过**打包128位加载**实现最高的HBM带宽,进一步减慢了内存流水线。 当存储和计算数据类型相同时,ldmatrix指令解决了这个问题。如图12a所示,线程i连续加载输出通道i%8的128位,ldmatrix指令自动以跨步方式分布数据,确保每个线程最终获得INT8 Tensor Core 计算所需的数据。 不幸的是,当用于存储和计算的数据类型不同时(如W4A8),ldmatrix指令将无法工作。 具体来说,在图12b中,ldmatrix确保每个线程在寄存器文件中的数据置换后获得相同数量的字节,而不是相同数量的元素。 因此,线程0获得了T0自身和线程1所需的分片(tiles),而线程1获得了线程2和线程3在随后的INT8 Tensor Core计算中所需的分片(tiles)。这在每个线程获得的数据和计算中使用的数据之间造成了不匹配。 也就是说,ldmatrix无法用于W4A8 GEMM,并且前述的指针算术开销持续存在。更糟糕的是,当我们连续加载4位权重时,内存带宽利用率进一步恶化。 因此,通过计算感知的权重重排序(图12c)解决了这个挑战。关键是以它们在计算中使用的顺序存储权重。通过将整个GEMM问题分成多个32×32分片(tiles) 。在每个分片中,线程0使用输入通道0-3和16-19用于输出通道0、8、16和24(在图12c中省略了输出通道16-31)。因此,将这32个通道连接成一个单独的128位字(word)。 线程1使用的32个通道紧跟在线程0的32个通道之后存储。**由于权重是静态的,这种重排序不会引入任何运行时开销**。 此外,它不仅将指针算术开销降低到与ldmatrix相同的水平,而且还保证了高带宽的**128位/线程**内存事务。将这种重排序应用于零点和缩放因子,以减轻反量化开销。 2. W4A8 GEMM中逐通道(per-channel)快速反量化 如图5d所示,当权重和激活使用的比特精度不同时,在主循环中反量化权重变得必要。在逐通道(per-channel)量化 W4A8 的情况下,省略了第二层级缩放因子 ,第一层级 FP16 缩放因子被有效地融合到GEMM尾部(epilogue)。因此,这里讨论的重点在于,在主循环中,将 ZINT4(即:有零点的无符号4位整数)有效地转换为SINT8。将这种转换进一步分解为两个步骤:UINT4到UINT8(权重解包)和UINT8到SINT8(零点减法)。 如图13所示,重新排列每32个UINT4权重w0、w1、...、w31为w0、w16、w1、w17、...,这使得可以利用寄存器级并行,并以仅三个逻辑运算高效地将它们解包为UINT8数字。 ![](https://files.mdnice.com/user/18421/28e6765a-15bd-4c8e-b484-6822e8960de4.png) 对于从UINT8到SINT8的转换,最直接的方法是在主循环中引入整数减法指令,将其称为**乘法前减法(subtraction before multiplication)**。虽然这种方法简单,但不可避免地给主循环带来了额外的成本,这是不可取的。相反,作者**采用乘法后减法(subtraction after multiplicatio)方法,以最小化主循环开销**。 那么,具有逐通道(per-channel)量化操作对象的GEMM层可以表示为: $$ \small \mathbf{O} = \hat{\mathbf{X}}\hat{\mathbf{W}} = (\mathbf{Q}_\mathbf{X}\odot\mathbf{S}_\mathbf{X})((\mathbf{Q}_\mathbf{W} - \mathbf{Z}_\mathbf{W})\odot\mathbf{S}_\mathbf{W}) $$ 其中,$\mathbf{Q}_\mathbf{W}$ ($\mathbf{Q}_\mathbf{X}$) 是量化权重(激活),$\mathbf{Z}_\mathbf{W}$ 将大小为n(输出通道)的零点向量 $\mathbf{z}_\mathbf{W}$ 扩展到k×n(k是输入通道),$\mathbf{S}_\mathbf{W}$, $\mathbf{S}_\mathbf{X}$ 也是从缩放向量 $\mathbf{s}_\mathbf{W},\mathbf{s}_\mathbf{X}$ 获得的。 将 $\mathbf{Z}_\mathbf{W}\odot\mathbf{S}_\mathbf{W}$ 表示为 $\mathbf{ZS}_\mathbf{W}$ ,然后我们重写上面的方程为: $$ \mathbf{O} = (\mathbf{Q}_\mathbf{X}\odot\mathbf{S}_\mathbf{X})(\mathbf{Q}_\mathbf{W}\odot\mathbf{S}_\mathbf{W}-\mathbf{ZS}_\mathbf{W}) = (\mathbf{Q}_\mathbf{X}\mathbf{Q}_\mathbf{W})\odot(\mathbf{s}_\mathbf{W}\times\mathbf{s}_\mathbf{X}) - (\mathbf{Q}_\mathbf{X}\odot\mathbf{S}_\mathbf{X})\mathbf{ZS}_\mathbf{W} $$ 对于第一项,$(\mathbf{Q}_\mathbf{X}\mathbf{Q}_\mathbf{W})\odot(\mathbf{s}_\mathbf{W}\times\mathbf{s}_\mathbf{X})$ ,类似于TensorRT-LLM中的W8A8 GEMM,其中, $\mathbf{s}_\mathbf{W}\times\mathbf{s}_\mathbf{X}$ 外积缩放在尾部(epilogue)执行。 对于第二项,首先用未量化的 $\mathbf{X}$ 替换 $\mathbf{Q}_\mathbf{X}\mathbf{S}_\mathbf{X}$ ($\hat{\mathbf{X}}$)。然后: $$\mathbf{X}(\mathbf{ZS}_\mathbf{W}) = \mathbf{t}_\mathbf{X}\times(\mathbf{z}_\mathbf{W}\odot\mathbf{s}_\mathbf{W})$$ 其中, $\mathbf{t}_\mathbf{X} = \mathbf{X}\mathbf{1}_k$ ,即对每个 token 的所有输入通道求和。 此时注意到方程$\mathbf{X}(\mathbf{ZS}_\mathbf{W}) = \mathbf{t}_\mathbf{X}\times(\mathbf{z}_\mathbf{W}\odot\mathbf{s}_\mathbf{W})$具有类似于缩放因子外积的形式。因此,它也可以融合到W4A8 GEMM的尾部中,类似于第一项$(\mathbf{Q}_\mathbf{X}\mathbf{Q}_\mathbf{W})\odot(\mathbf{s}_\mathbf{W}\times\mathbf{s}_\mathbf{X})$。 为此,将零点减法从主循环移动到尾部,从而在GEMM Kernel 中大大消除了其开销。这种乘法后减法形式的反量化需要预先计算 $\mathbf{t}_\mathbf{X}$。 通常,每个 W4A8 Kernel 之前总是有一个内存受限的 Kernel ,允许将预计算 Kernel 与它融合,因此,几乎没有延迟开销。 3. W4A8 GEMM中逐组(per-group)快速反量化 W4A8 GEMM 中的逐组与它的逐通道的主要区别在于图5d中的第二层级反量化过程。 首先,由于零点现在定义在组的基础上,因此不再可能如前一节所做的将零点减法合并到尾部。 其次,由于存在第二层级缩放,需要对每个权重执行额外的INT8乘法。类似于前一节,必须确定在第二层级反量化过程中是先应用乘法(缩放)还是减法(零点)。在这种情况下,作者认为在乘法后应用减法仍然是有利的方法,因为它启用了寄存器级并行(RLP)。 如图14所示,NVIDIA GPU 提供 vadd4 指令,可通过单个 INT32 ALU 运算执行四个 INT8 加法。然而,没有指令可以实现4路INT8乘法的类似效果。因此,为了实现RLP,必须通过向 8 位缩放因子的最高有效位 (MSB) 填充 24 个零来模拟这一点。 ![](https://files.mdnice.com/user/18421/d00fbda4-65fc-4628-afc4-c5db51f15d38.png) 然而,这种模拟只有在每个INT8乘法的结果保持在INT8范围内时才有效。这种条件对于乘法前减法计算顺序并未满足。如图14a所示,**缩放乘法的结果溢出,导致输出不正确**。 在乘法前减法方法中,只能一个接一个地执行乘法,这是极其低效的。而**有了乘法后的减法计算顺序,渐进式分组量化算法确保了初始乘法步骤的结果永远不会超出INT8范围**。这允许在乘法和减法中充分利用RLP的性能优势。 4. 通用优化:在W4A8 Kernel 中,还采用了GEMM优化的通用技术。 在内存方面,应用了多阶段软件流水线和异步内存复制,以更好地重叠内存访问和计算。 此外,交换了L1共享内存的布局,以消除bank冲突。 为了提高L2缓存利用率,跨不同线程块重新排列计算分区,允许相邻块重用相同的权重。 在计算方面,当输入Token(m)的数量很小时,将reduction维度k分割成多个切片并在L1共享内存中跨不同的 warp 来 reduce 局部和是有益的。 ### QServe 中的KV4注意力 注意力占据了LLM总运行时间的30-50%,如图2a所示。尽管图5中的roofline模型表明,将KV缓存量化为4比特应该比8比特基线快2倍,但实际情况并非如此。 使用 TensorRT-LLM 的 KV8-attention 解码阶段 Kernel 作为基线,将所有**静态逐层(per-tensor)8位KV缓存量化**的访问和转换替换为它们的**动态逐头(per-head)4位KV缓存量化**。 这种直接替换,在L40S上带来了的1.7倍加速;但在A100上比KV8基线慢1.2倍。作者通过再次分析揭示了问题的症结所在:慢速的 CUDA Core 负责在解码阶段执行注意力 Kernel 。虽然每个单独的批处理GEMV的计算强度为 1 MAC/element,但融合注意力 Kernel 的计算强度显著增加,该 Kernel 结合了所有算术运算和KV缓存更新。例如,简单地从KV缓存中反量化一个INT4需要5个ALU操作。这包括掩码和移位操作以隔离操作数,从整数到浮点表示的类型转换,以及获取最终结果所需的浮点乘法和减法。 更重要的是,A100 FP32 CUDA Core 的 roofline 转折点仅为 9.8 Ops/Byte。也就是说,KV反量化操作本身就已经达到饱和界限,这可能导致融合的KV4注意力Kernel在数据中心GPU(如:A100)上变成计算受限的。 实际上,其他系统(如QuaRot和Atom)也有类似的观察。比如,QuaRot在注意力操作中引入了计算密集的Hadamard变换,使得4位KV缓存量化难以实现比TRT-LLM-KV8更快的速度。 为了缓解计算受限的瓶颈,重要的是要将解码阶段KV4注意力Kernel从计算受限区域转移出去。作者通过2个方法实现了这个目标:首先,延迟roofline转折点的到来,其次,同时减少融合Kernel内的计算强度。 对于第一部分,将原始TensorRT-LLM Kernel 中的所有FP32操作替换为它们的FP16对应物,有效地将计算 roof 翻倍。 对于第二部分,通过应用位技巧,反量化的算术强度可以显著减少到每个元素2个操作。 此外,通过简化控制逻辑和预取缩放因子和零值,从而简化地址计算,也有助于提高性能。在融合了这些增强功能之后,在A100上比TensorRT-LLM的 KV8 Kernel 加速了1.5倍。 ## 实验细节 将QoQ与常用的后训练LLM量化技术(如:SmoothQuant、GPTQ、AWQ)以及4位权重-激活量化框架Atom和QuaRot进行了比较,在WikiText2上,对于Llama2-7B模型,与W8A8 SmoothQuant和W4A16 AWQ相比,QoQ的困惑度最多增加了0.16。无论Atom使用W4A4还是W4A8KV4量化精度,QoQ始终优于Atom。与Quarot相比,QoQ在困惑度上也显示出高达0.49的改进。 > 注意: > > 对于SmoothQuant,遵循TensorRT-LLM中的设置,对KV Cache使用静态逐层(per-tensor)对称8位量化。 > > 对于GPTQ,使用官方最新的版本,带有“重排序”技巧,记为“GPTQ-R”。 > > 对于QuaRot和Atom,主要使用Pile验证数据集作为校准数据集。同时,还使用了WikiText2作为校准数据集(灰色显示)。 > > 对于“W4A8KV4 g128”设置,QuaRot和Atom不支持渐进式组量化,因此使用普通分组权重量化(即每个组有一个FP16 缩放因子)来评估他们。不支持的模型和量化为NaN。 ![](https://files.mdnice.com/user/18421/375cfb4e-1a18-48df-ba5e-90a0b40fa26a.png) 对于五个常识任务的 Zero-shot 准确性,QoQ显著优于其他4位量化方法。特别是在WinoGrande任务中,与Quarot相比,QoQ的准确性提高了4.82%。与FP16相比,针对7B、13B和70B大小的Llama-2,QoQ量化仅引入了1.03%、0.89%和0.40%的准确性损失。 ![](https://files.mdnice.com/user/18421/98ecf269-add8-4de0-97fd-2ff9650de387.png) 通过与TensorRT-LLM(使用FP16、W8A8和W4A16精度)、Atom(W4A4)和QuaRot(W4A4)进行比较,评估了QServe在A100-80G-SXM4和L40S-48G GPU上的效率。与 TensorRT-LLM 的最佳配置相比,QServe在A100上表现出显著的改进,为Llama1-30B实现了2倍的吞吐量提升,为Llama2模型实现了1.2-1.4×的吞吐量提升,为Mistral和Yi模型实现了1.2×的吞吐量提升,为Qwen-1.5模型实现了2.4×的吞吐量提升。在 L40S GPU 上,所有评估模型的吞吐量提高了1.47×至3.47×。 > 注意: > > 系统评估指标:在相同的内存限制下可实现的最大吞吐量。 > > 使用1024的输入序列长度和512的输出序列长度。 > > Atom仅支持Llama-2-7B,QuaRot不支持GQA。因此,在测量基线系统的性能时,跳过了这些不支持的模型。 > > 在A100上使用逐通道量化,在L40S上使用逐组量化。因为L40S拥有更强大的CUDA Core进行反量化。 ![](https://files.mdnice.com/user/18421/fc776f78-62c6-47e5-a82c-597e3d388be6.png) 尽管 L40S 的内存容量明显小于A100,QServe在L40S上以与TensorRT-LLM在A100上,相同的批处理大小下有效地保持了性能。这一成就归因于对权重和KV缓存都应用了激进的4位量化。 在L40S上,以QServe服务的34B以下的七个模型,有五个模型实现了比在A100上使用TensorRT-LLM更高的吞吐量。 在A100上,与Atom和QuaRot相比,性能提升更为显著,因为这些系统性能没有超过TensorRT-LLM。 在L40S上,对于Atom系统支持的模型Llama-2-7B,尽管QServe使用了更高的量化精度,QServe仍然比Atom高出10%的吞吐量;此外,QServe实现的准确性也比Atom更好。 通过探讨QoQ量化方法中不同量化技术对模型性能的影响。以Llama-2-7B模型为例,首先应用了W8A8的量化配置,然后逐步降低量化精度,并逐步应用不同的量化技术。对于每一步,都评估了在WikiText2数据集上的困惑度(perplexity)以及在L40S GPU上使用64个请求、每个请求包含1024个输入Token和512个输出Token时的端到端推理性能。结果显示,**将权重精度降低到4位会显著损害模型性能**,尽管它将端到端处理速度提高了1.12倍,并节省了3.5GB的GPU内存。**旋转块输入模块有助于抑制激活异常值**,使困惑度提高了0.18。此外,**通过权重剪裁最小化块输出均方误差**(MSE)进一步降低了0.16的困惑度。因此,QoQ的W4A8配置实现了与W4A16相当的困惑度。然而,将**KV缓存量化到4位再次使模型性能退化了0.14**,尽管它显著提高了端到端推理吞吐量1.47倍,并减半了GPU内存使用量。为了解决这个问题,**SmoothAttention技术将困惑度降低了0.05,而没有增加系统开销**。渐进式分组量化进一步将困惑度降低0.02,同时仅增加了微不足道的量化开销。最后,激活感知通道重排序将困惑度降低0.03。 ![](https://files.mdnice.com/user/18421/e1fca3ba-1e0e-495c-a7dc-1a69696b8001.png) ## 结语 本文介绍了一种W4A8KV4量化算法QoQ,具有4位权重、8位激活和4位KV缓存。QoQ由QServe推理库实现。在QoQ算法中,引入了渐进式量化,在W4A8 GEMM中具有较低的反量化开销。此外,开发了SmoothAttention来有效减轻4位KV量化引起的准确性下降。在QServe系统中,通过执行计算感知的权重重排序,并利用寄存器级并行来减少反量化延迟。此外利用KV4量化提升吞吐性能,并使融合注意力保持在内存受限(memory-bound)区域。 与TensorRT-LLM相比,QServe显著提高了服务吞吐量,比如:Llama-3-8B在A100上1.2×、在L40S上1.4×;以及Qwen1.5-72B在A100上2.4×、在L40S上3.5×,。值得注意的是,QServe在L40S GPU上可以实现比A100上的TensorRT-LLM更高的吞吐量。因此,QServe有效地将LLM服务的成本降低了3倍。 码字不易,如果觉得我的文章能够能够给您带来帮助,期待您的点赞收藏加关注~~ ================================================ FILE: blog/llm-inference/大模型推理框架概述.md ================================================ 从 ChatGPT 面世以来,引领了大模型时代的变革,除了大模型遍地开花以外,承载大模型进行推理的框架也是层出不穷,大有百家争鸣的态势。本文主要针对业界知名度较高的一些大模型推理框架进行相应的概述。 ## vLLM - GitHub: https://github.com/vllm-project/vllm ### 简介 vLLM是一个开源的大模型推理加速框架,通过PagedAttention高效地管理attention中缓存的张量,实现了比HuggingFace Transformers高14-24倍的吞吐量。 PagedAttention 是 vLLM 的核心技术,它解决了LLM服务中内存的瓶颈问题。传统的注意力算法在自回归解码过程中,需要将所有输入Token的注意力键和值张量存储在GPU内存中,以生成下一个Token。这些缓存的键和值张量通常被称为KV缓存。 ### 主要特性 - 通过PagedAttention对 KV Cache 的有效管理 - 传入请求的continus batching,而不是static batching - 支持张量并行推理 - 支持流式输出 - 兼容 OpenAI 的接口服务 - 与 HuggingFace 模型无缝集成 ### 与其他框架(HF、TGI)的性能对比 vLLM 的吞吐量比 HF 高 14 - 24 倍,比 TGI 高 2.2 - 2.5 倍。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bba59bd5541b4ffcaeb5e786ac823212~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1530&h=616&s=126561&e=png&b=fefefe) ### 存在的问题 - 同样的模型、参数和prompt条件下,vLLM推理和Huggingface推理结果不一致。具体请参考:https://zhuanlan.zhihu.com/p/658780653 ### 业界案例 vLLM 已经被用于 Chatbot Arena 和 Vicuna 大模型的服务后端。 ## HuggingFace TGI - GitHub: https://github.com/huggingface/text-generation-inference ### 简介 Text Generation Inference(TGI)是 HuggingFace 推出的一个项目,作为支持 HuggingFace Inference API 和 Hugging Chat 上的LLM 推理的工具,旨在支持大型语言模型的优化推理。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2a9691f2e10a4f00a6f6b685096753a6~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1177&h=720&s=2547229&e=png&b=fcfafa) ### 主要特性 - 支持张量并行推理 - 支持传入请求 Continuous batching 以提高总吞吐量 - 使用 flash-attention 和 Paged Attention 在主流的模型架构上优化用于推理的 transformers 代码。**注意:并非所有模型都内置了对这些优化的支持**。 - 使用bitsandbytes(`LLM.int8()`)和GPT-Q进行量化 - 内置服务评估,可以监控服务器负载并深入了解其性能 - 轻松运行自己的模型或使用任何 HuggingFace 仓库的模型 - 自定义提示生成:通过提供自定义提示来指导模型的输出,轻松生成文本 - 使用 Open Telemetry,Prometheus 指标进行分布式跟踪 ### 支持的模型 - [BLOOM](https://huggingface.co/bigscience/bloom) - [FLAN-T5](https://huggingface.co/google/flan-t5-xxl) - [Galactica](https://huggingface.co/facebook/galactica-120b) - [GPT-Neox](https://huggingface.co/EleutherAI/gpt-neox-20b) - [Llama](https://github.com/facebookresearch/llama) - [OPT](https://huggingface.co/facebook/opt-66b) - [SantaCoder](https://huggingface.co/bigcode/santacoder) - [Starcoder](https://huggingface.co/bigcode/starcoder) - [Falcon 7B](https://huggingface.co/tiiuae/falcon-7b) - [Falcon 40B](https://huggingface.co/tiiuae/falcon-40b) - [MPT](https://huggingface.co/mosaicml/mpt-30b) - [Llama V2](https://huggingface.co/meta-llama) - [Code Llama](https://huggingface.co/codellama) ### 适用场景 依赖 HuggingFace 模型,并且不需要为核心模型增加多个adapter的场景。 ## FasterTransformer - GitHub: https://github.com/NVIDIA/FasterTransformer ### 简介 [NVIDIA FasterTransformer (FT)](https://github.com/NVIDIA/FasterTransformer/) 是一个用于实现基于Transformer的神经网络推理的加速引擎。它包含Transformer块的高度优化版本的实现,其中包含编码器和解码器部分。使用此模块,您可以运行编码器-解码器架构模型(如:T5)、仅编码器架构模型(如:BERT)和仅解码器架构模型(如: GPT)的推理。 FT框架是用C++/CUDA编写的,依赖于高度优化的 cuBLAS、cuBLASLt 和 cuSPARSELt 库,这使您可以在 GPU 上进行快速的 Transformer 推理。 与 NVIDIA TensorRT 等其他编译器相比,FT 的最大特点是它支持以分布式方式进行 Transformer 大模型推理。 下图显示了如何使用张量并行 (TP) 和流水线并行 (PP) 技术将基于Transformer架构的神经网络拆分到多个 GPU 和节点上。 - 当每个张量被分成多个块时,就会发生张量并行,并且张量的每个块都可以放置在单独的 GPU 上。在计算过程中,每个块在不同的 GPU 上单独并行处理;最后,可以通过组合来自多个 GPU 的结果来计算最终张量。 - 当模型被深度拆分,并将不同的完整层放置到不同的 GPU/节点上时,就会发生流水线并行。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/748aaae6515441f79a0a944518dce9d6~tplv-k3u1fbpfcp-watermark.image?) 在底层,节点间或节点内通信依赖于 MPI 、 NVIDIA NCCL、Gloo等。因此,使用FasterTransformer,您可以在多个 GPU 上以张量并行运行大型Transformer,以减少计算延迟。同时,TP 和 PP 可以结合在一起,在多 GPU 节点环境中运行具有数十亿、数万亿个参数的大型 Transformer 模型。 除了使用 C ++ 作为后端部署,FasterTransformer 还集成了 TensorFlow(使用 TensorFlow op)、PyTorch (使用 Pytorch op)和 Triton 作为后端框架进行部署。当前,TensorFlow op 仅支持单 GPU,而 PyTorch op 和 Triton 后端都支持多 GPU 和多节点。 ### FasterTransformer 中的优化技术 与深度学习训练的通用框架相比,FT 使您能够获得更快的推理流水线以及基于 Transformer 的神经网络具有更低的延迟和更高的吞吐量。 FT 对 GPT-3 和其他大型 Transformer 模型进行的一些优化技术包括: 1. 层融合(Layer fusion) 这是预处理阶段的一组技术,将多层神经网络组合成一个单一的神经网络,将使用一个单一的核(kernel)进行计算。 这种技术减少了数据传输并增加了数学密度,从而加速了推理阶段的计算。 例如, multi-head attention 块中的所有操作都可以合并到一个核(kernel)中。 2. 自回归模型的推理优化(激活缓存) 为了防止通过Transformer重新计算每个新 token 生成器的先前的key和value,FT 分配了一个缓冲区来在每一步存储它们。 虽然需要一些额外的内存使用,但 FT 可以节省重新计算的成本。该过程如下图所示,相同的缓存机制用于 NN 的多个部分。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e1e46625612b413996b500b78a991933~tplv-k3u1fbpfcp-watermark.image?) 3. 内存优化 与 BERT 等传统模型不同,大型 Transformer 模型具有多达数万亿个参数,占用数百 GB 存储空间。即使我们以半精度存储模型,GPT-3 175b 也需要 350 GB。因此有必要减少其他部分的内存使用。 例如,在 FasterTransformer 中,我们在不同的解码器层重用了激活/输出的内存缓冲(buffer)。由于 GPT-3 中的层数为 96,因此我们只需要 1/96 的内存量用于激活。 4. 使用 MPI 和 NCCL 实现节点间/节点内通信并支持模型并行 FasterTransormer 同时提供张量并行和流水线并行。 对于张量并行,FasterTransformer 遵循了 [Megatron](https://arxiv.org/pdf/1909.08053.pdf) 的思想。 对于自注意力块和前馈网络块,FT 按行拆分第一个矩阵的权重,并按列拆分第二个矩阵的权重。 通过优化,FT 可以将每个 Transformer 块的归约(reduction)操作减少到两次。 对于流水线并行,FasterTransformer 将整批请求拆分为多个微批,隐藏了通信的空泡(bubble)。 FasterTransformer 会针对不同情况自动调整微批量大小。 5. MatMul 核自动调整(GEMM 自动调整) 矩阵乘法是基于 Transformer 的神经网络中最主要和繁重的操作。 FT 使用来自 CuBLAS 和 CuTLASS 库的功能来执行这些类型的操作。 重要的是要知道 MatMul 操作可以在“硬件”级别使用不同的底层(low-level)算法以数十种不同的方式执行。 [`GemmBatchedEx`](https://docs.nvidia.com/cuda/cublas/index.html#cublas-GemmBatchedEx) 函数实现了 MatMul 操作,并以`cublasGemmAlgo_t`作为输入参数。 使用此参数,您可以选择不同的底层算法进行操作。 FasterTransformer 库使用此参数对所有底层算法进行实时基准测试,并为模型的参数和您的输入数据(注意层的大小、注意头的数量、隐藏层的大小)选择最佳的一个。 此外,FT 对网络的某些部分使用硬件加速的底层函数,例如: `__expf`、`__shfl_xor_sync`。 6. 低精度推理 FT 的核(kernels)支持使用 fp16 和 int8 等低精度输入数据进行推理。 由于较少的数据传输量和所需的内存,这两种机制都会加速。 同时,int8 和 fp16 计算可以在特殊硬件上执行,例如:Tensor Core(适用于从 Volta 开始的所有 GPU 架构)。 除此之外还有**快速的 C++ BeamSearch 实现**、当模型的权重部分分配到八个 GPU 之间时,**针对 TensorParallelism 8 模式优化的 all-reduce**。 ### 支持的模型 目前,FT 支持了 Megatron-LM GPT-3、GPT-J、BERT、ViT、Swin Transformer、Longformer、T5 和 XLNet 等模型。您可以在 GitHub 上的 [FasterTransformer](https://github.com/NVIDIA/FasterTransformer#support-matrix)库中查看最新的支持矩阵。 ### 与其他框架(PyTorch)的性能对比 FT 适用于计算能力 >= 7.0 的 GPU,例如: V100、A10、A100 等。 下图展示了 GPT-J 6B 参数的模型推断加速比较: ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d22815ddfcbe4860b2887a4e47c59651~tplv-k3u1fbpfcp-watermark.image?) ### 存在的问题 - 英伟达新推出了TensorRT-LLM,相对来说更加易用,后续FasterTransformer将不再为维护了。 ## DeepSpeed-MII - GitHub: https://github.com/microsoft/DeepSpeed-MII ### 简介 DeepSpeed-MII 是 DeepSpeed 的一个新的开源 Python 库,旨在使模型不仅低延迟和低成本推理,而且还易于访问。 - MII 提供了对数千种广泛使用的深度学习模型的高度优化实现。 - 与原始PyTorch实现相比,MII 支持的模型可显著降低延迟和成本。 - 为了实现低延迟/低成本推理,MII 利用 DeepSpeed-Inference 的一系列广泛优化,例如:transformers 的深度融合、用于多 GPU 推理的自动张量切片、使用 ZeroQuant 进行动态量化等。 - MII 只需几行代码即可通过 AML 在本地和 Azure 上低成本部署这些模型。 ### MII 工作流程 下图显示了 MII 如何使用 DS-Inference 自动优化 OSS 模型;然后,使用 GRPC 在本地部署,或使用 AML Inference 在 Microsoft Azure 上部署。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/56b59d67c9284c92a867bf2720b50978~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=3394&h=1735&s=286885&e=png&a=1&b=4c83ca) MII 的底层由 DeepSpeed-Inference 提供支持。 根据模型类型、模型大小、批量大小和可用硬件资源,MII 自动应用 DeepSpeed-Inference 中的一组适当的系统优化,以最大限度地减少延迟并最大限度地提高吞吐量。它通过使用许多预先指定的模型注入策略之一来实现这一点,该策略允许 MII 和 DeepSpeed-Inference 识别底层 PyTorch 模型架构并用优化的实现替换它。在此过程中,MII 使 DeepSpeed-Inference 中一系列的优化自动可用于其支持的数千种流行模型。 ### 支持的模型和任务 MII 目前支持超过 50,000 个模型,涵盖文本生成、问答、文本分类等一系列任务。 MII 加速的模型可通过 Hugging Face、FairSeq、EluetherAI 等多个开源模型存储库获取。我们支持基于 Bert、Roberta 或 GPT 架构的稠密模型,参数范围从几亿参数到数百亿参数。除此之外,MII将继续扩展该列表,支持即将推出的大规模千亿级以上参数稠密和稀疏模型。 目前 MII 支持以下 HuggingFace Transformers 模型系列: model family | size range | ~model count ------ | ------ | ------ [llama](https://huggingface.co/models?other=llama) | 7B - 65B | 1,500 [bloom](https://huggingface.co/models?other=bloom) | 0.3B - 176B | 480 [stable-diffusion](https://huggingface.co/models?other=stable-diffusion) | 1.1B | 3,700 [opt](https://huggingface.co/models?other=opt) | 0.1B - 66B | 460 [gpt\_neox](https://huggingface.co/models?other=gpt_neox) | 1.3B - 20B | 850 [gptj](https://huggingface.co/models?other=gptj) | 1.4B - 6B | 420 [gpt\_neo](https://huggingface.co/models?other=gpt_neo) | 0.1B - 2.7B | 700 [gpt2](https://huggingface.co/models?other=gpt2) | 0.3B - 1.5B | 11,900 [xlm-roberta](https://huggingface.co/models?other=xlm-roberta) | 0.1B - 0.3B | 4,100 [roberta](https://huggingface.co/models?other=roberta) | 0.1B - 0.3B | 8,700 [distilbert](https://huggingface.co/models?other=distilbert) | 0.1B - 0.3B | 4,700 [bert](https://huggingface.co/models?other=bert) | 0.1B - 0.3B | 23,600 ### 与其他框架(PyTorch)的性能对比 MII 将 Big-Science Bloom 176B 模型的延迟降低了 5.7 倍,同时将成本降低了 40 倍以上。同样,它将部署 Stable Diffusion 的延迟和成本降低了 1.9 倍。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/165a34083e6f4a50b8080ab2474a48b9~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=3141&h=2488&s=362214&e=png&a=1&b=595959) ## FlexFlow Server - GitHub: https://github.com/flexflow/FlexFlow/tree/inference - 论文:**SpecInfer: Accelerating Generative Large Language Model Serving with Speculative Inference and Token Tree Verification** ### 简介 FlexFlow Serve 是一个开源编译器和分布式系统,用于低延迟、高性能 LLM 服务。 ### 主要特征 #### 投机(Speculative) 推理 使 FlexFlow Serve 能够加速 LLM 服务的一项关键技术是Speculative推理,它结合了各种集体boost-tuned的小型投机模型 (SSM) 来共同预测 LLM 的输出; 预测被组织为token树,每个节点代表一个候选 token 序列。 使用一种新颖的基于树的并行解码机制,根据 LLM 的输出并行验证由 token 树表示的所有候选 token 序列的正确性。 FlexFlow Serve 使用 LLM 作为 token 树验证器而不是增量解码器,这大大减少了服务生成 LLM 的端到端推理延迟和计算要求,同时,可证明保持模型质量。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8470b30bcf844e769420d8eb5b7f5c8b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=990&h=511&s=82119&e=png&b=fefbfb) #### CPU Offloading FlexFlow Serve 还提供基于Offloading的推理,用于在单个 GPU 上运行大型模型(例如:llama-7B)。 CPU Offloading是将张量保存在CPU内存中,并且在计算时仅将张量复制到GPU。 > 注意: > > 现在我们有选择地offload最大的权重张量(线性、注意力中的权重张量)。 此外,由于小模型占用的空间要少得多,如果不构成GPU内存瓶颈,offload会带来更多的运行空间和计算成本,因此,我们只对大模型进行offload。 可以通过启用 -offload 和 -offload-reserve-space-size 标志来运行offloading。 #### 支持量化 FlexFlow Serve 支持 int4 和 int8 量化。 压缩后的张量存储在CPU端, 一旦复制到 GPU,这些张量就会进行解压缩并转换回其原始精度。 ### 支持的 LLMs 和 SSMs FlexFlow Serve 当前支持以下模型架构的所有Hugingface模型: * `LlamaForCausalLM` / `LLaMAForCausalLM` (例如:LLaMA/LLaMA-2, Guanaco, Vicuna, Alpaca, ...) * `OPTForCausalLM` (OPT家族模型) * `RWForCausalLM` (Falcon家族模型) * `GPTBigCodeForCausalLM` (Starcoder家族模型) 以下是我们已经测试过并且可以使用 SSM 的模型列表: | 模型 | 在 HuggingFace 中的模型 id | Boost-tuned SSMs | | :---- | :---- | :---- | | LLaMA-7B | decapoda-research/llama-7b-hf | [LLaMA-68M](https://huggingface.co/JackFram/llama-68m) , [LLaMA-160M](https://huggingface.co/JackFram/llama-160m) | | LLaMA-13B | decapoda-research/llama-13b-hf | [LLaMA-68M](https://huggingface.co/JackFram/llama-68m) , [LLaMA-160M](https://huggingface.co/JackFram/llama-160m) | | LLaMA-30B | decapoda-research/llama-30b-hf | [LLaMA-68M](https://huggingface.co/JackFram/llama-68m) , [LLaMA-160M](https://huggingface.co/JackFram/llama-160m) | | LLaMA-65B | decapoda-research/llama-65b-hf | [LLaMA-68M](https://huggingface.co/JackFram/llama-68m) , [LLaMA-160M](https://huggingface.co/JackFram/llama-160m) | | LLaMA-2-7B | meta-llama/Llama-2-7b-hf | [LLaMA-68M](https://huggingface.co/JackFram/llama-68m) , [LLaMA-160M](https://huggingface.co/JackFram/llama-160m) | | LLaMA-2-13B | meta-llama/Llama-2-13b-hf | [LLaMA-68M](https://huggingface.co/JackFram/llama-68m) , [LLaMA-160M](https://huggingface.co/JackFram/llama-160m) | | LLaMA-2-70B | meta-llama/Llama-2-70b-hf | [LLaMA-68M](https://huggingface.co/JackFram/llama-68m) , [LLaMA-160M](https://huggingface.co/JackFram/llama-160m) | | OPT-6.7B | facebook/opt-6.7b | [OPT-125M](https://huggingface.co/facebook/opt-125m) | | OPT-13B | facebook/opt-13b | [OPT-125M](https://huggingface.co/facebook/opt-125m) | | OPT-30B | facebook/opt-30b | [OPT-125M](https://huggingface.co/facebook/opt-125m) | | OPT-66B | facebook/opt-66b | [OPT-125M](https://huggingface.co/facebook/opt-125m) | | Falcon-7B | tiiuae/falcon-7b | | | Falcon-40B | tiiuae/falcon-40b | | | StarCoder-15.5B | bigcode/starcoder | | ### 与其他框架(vLLM、TGI、FasterTransformer)的性能对比 FlexFlow Serve 在单节点多 GPU 推理方面比现有系统高 1.3-2.0 倍,在多节点多 GPU 推理方面比现有系统高 1.4-2.4 倍。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d5abe24e29f0495f995fbed37c8dc765~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1241&h=480&s=60989&e=png&b=fefefe) ### 提示数据集 FlexFlow 提供了五个用于评估 FlexFlow Serve 的提示数据集: - Chatbot 指令提示:https://specinfer.s3.us-east-2.amazonaws.com/prompts/chatbot.json - ChatGPT 提示:https://specinfer.s3.us-east-2.amazonaws.com/prompts/chatgpt.json - WebQA:https://specinfer.s3.us-east-2.amazonaws.com/prompts/webqa.json - Alpaca:https://specinfer.s3.us-east-2.amazonaws.com/prompts/alpaca.json - PIQA:https://specinfer.s3.us-east-2.amazonaws.com/prompts/piqa.json ### 未来的规划 FlexFlow Serve 正在积极开发中,主要专注于以下任务: - AMD 基准测试。目前正在积极致力于在 AMD GPU 上对 FlexFlow Serve 进行基准测试,并将其与 NVIDIA GPU 上的性能进行比较。 - Chatbot prompt 模板和多轮对话 - 支持 FastAPI - 与LangChain集成进行文档问答 ## LMDeploy - GitHub: https://github.com/InternLM/lmdeploy ### 简介 LMDeploy 由 [MMDeploy](https://github.com/open-mmlab/mmdeploy) 和 [MMRazor](https://github.com/open-mmlab/mmrazor) 团队联合开发,是涵盖了 LLM 任务的全套轻量化、部署和服务解决方案。 这个强大的工具箱提供以下核心功能: - **高效推理引擎 TurboMind**:基于 [FasterTransformer](https://github.com/NVIDIA/FasterTransformer)推理引擎,实现了高效推理引擎 TurboMind,支持 InternLM、LLaMA、vicuna等模型在 NVIDIA GPU 上的推理。 - **交互推理方式**:通过缓存多轮对话过程中 attention 的 k/v,记住对话历史,从而避免重复处理历史会话。 - **多 GPU 部署和量化**:提供了全面的模型部署和量化(支持使用AWQ算法对模型权重进行 INT4 量化,支持 KV Cache INT8 量化)支持,已在不同规模上完成验证。 - **persistent batch 推理**:进一步优化模型执行效率。 - 支持张量并行推理(注意:量化部署时不支持进行张量并行) ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/757afd57a68f4d698559033e3af35f83~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=990&h=460&s=42660&e=png&b=fcf8f7) ### 支持的模型 `LMDeploy` 支持 `TurboMind` 和 `Pytorch` 两种推理后端。 **TurboMind** > **注意:**
> W4A16 推理需要 Ampere 及以上架构的 Nvidia GPU | 模型 | 模型并行 | FP16 | KV INT8 | W4A16 | W8A8 | | :----------: | :------: | :--: | :-----: | :---: | :--: | | Llama | Yes | Yes | Yes | Yes | No | | Llama2 | Yes | Yes | Yes | Yes | No | | InternLM-7B | Yes | Yes | Yes | Yes | No | | InternLM-20B | Yes | Yes | Yes | Yes | No | | QWen-7B | Yes | Yes | Yes | No | No | | Baichuan-7B | Yes | Yes | Yes | Yes | No | | Baichuan2-7B | Yes | Yes | No | No | No | | Code Llama | Yes | Yes | No | No | No | **Pytorch** | 模型 | 模型并行 | FP16 | KV INT8 | W4A16 | W8A8 | | :---------: | :------: | :--: | :-----: | :---: | :--: | | Llama | Yes | Yes | No | No | No | | Llama2 | Yes | Yes | No | No | No | | InternLM-7B | Yes | Yes | No | No | No | ### 与其他框架(HF、DeepSpeed、vLLM)的性能对比 **场景一**: 固定的输入、输出token数(1,2048),测试 output token throughput **场景二**: 使用真实数据,测试 request throughput 测试配置:LLaMA-7B, NVIDIA A100(80G) TurboMind 的 output token throughput 超过 2000 token/s, 整体比 DeepSpeed 提升约 5% - 15%,比 huggingface transformers 提升 2.3 倍 在 request throughput 指标上,TurboMind 的效率比 vLLM 高 30%。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fceaa4f6da59436f83a13a30428f8ecf~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=4494&h=1320&s=201272&e=png&b=fefefe) ## 结语 总而言之,大模型推理框架的核心目标都是为了降低延迟;同时,尽可能地提升吞吐量;从上面的框架中可以看到,每个框架各有优缺点,但是目前来看,还没有一个LLM推理框架有一统天下的态势,大家都在加速迭代。 ================================================ FILE: blog/llm-localization/大模型国产化适配1-华为昇腾AI全栈软硬件平台总结.md ================================================ 随着 ChatGPT 的现象级走红,引领了AI大模型时代的变革,从而导致 AI 算力日益紧缺。与此同时,中美贸易战,导致AI算力国产化适配势在必行。本文主要对最近使用昇腾芯片做一个简单总结。 ## 昇腾AI全栈软硬件平台简述 昇腾芯片是华为公司发布的两款 AI 处理器(NPU),昇腾910(用于训练)和昇腾310(用于推理)处理器,采用自家的达芬奇架构。昇腾在国际上对标的主要是英伟达的GPU,国内对标的包括寒武纪、海光等厂商生产的系列AI芯片产品(如:思元590、深算一号等)。 整个昇腾软硬件全栈包括5层,自底向上为**Atlas系列硬件、异构计算架构、AI框架、应用使能、行业应用**。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d018ad688e6a47a2a8e13a88a8d32bb8~tplv-k3u1fbpfcp-watermark.image?) ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2a47859dd75a4c2d87af963c5eae49d5~tplv-k3u1fbpfcp-watermark.image?) ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/189c11c826d042a89ee1dfd88c7e3c23~tplv-k3u1fbpfcp-watermark.image?) ### Atlas系列硬件 Atlas系列产品是基于昇腾910和昇腾310打造出来的、面向不同应用场景(端、边、云)的系列AI硬件产品。比如: - **Atlas 800(型号:9000)** 是训练服务器,包含8个训练卡(**Atlas 300 T**:采用昇腾910,300T有三种规格,分别为910A、910B、910 ProB;算力对应关系为910A--256、910B--256、910 ProB--280)。 - **Atlas 900** 是训练集群(由128台**Atlas 800(型号:9000)**构成),相当于是由一批训练服务器组合而成。 - **Atlas 800(型号:3000)** 是推理服务器,包含8个推理卡(**Atlas 300 I**:采用昇腾310)。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/32888c111cac4c17a9da541d2d75b3ec~tplv-k3u1fbpfcp-watermark.image?) **散热方式**: Atlas 800 训练服务器支持风冷和液冷(其实是风液混合散热,即通过冷板式液冷将昇腾910处理器发出的热量带走)两种散热方式,这可以根据数据中心条件进行选择。其中,风冷系统不需要安装冷却塔、冷却塔及泵房,初期成本投入较低、 运行方便,但能够支持的数据中心功率较低,机柜功率一般在 12kW 以内。 而液冷技术用换热系数更好的液体代替空气,可以支持更高的功率。因此,目前一些高端AI芯片通常都采用液冷方式进行散热。 ### 异构计算架构 异构计算架构(CANN)是对标英伟达的CUDA + CuDNN的核心软件层,对上支持多种AI框架,对下服务AI处理器,发挥承上启下的关键作用,是提升昇腾AI处理器计算效率的关键平台,主要包括有各种引擎、编译器、执行器、算子库等。之所以叫异构软件,是因为承载计算的底层硬件包括AI芯片和通用芯片,自然就需要有一层软件来负责算子的调度、加速和执行,最后自动分配到对应的硬件上(CPU或NPU)。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6788095c7819431aba6dea4eb85b6233~tplv-k3u1fbpfcp-watermark.image?) - **昇腾计算语言**(Ascend Computing Language,AscendCL)接口是昇腾计算开放编程框架,对开发者屏蔽底层多种处理器差异,提供算子开发接口TBE、标准图开发接口AIR、应用开发接口,支持用户快速构建基于Ascend平台的AI应用和业务。 - **昇腾计算服务层**主要提供**昇腾算子库AOL**,通过神经网络(Neural Network,NN)库、线性代数计算库(Basic Linear Algebra Subprograms,BLAS)等高性能算子加速计算;**昇腾调优引擎AOE**,通过算子调优OPAT、子图调优SGAT、梯度调优GDAT、模型压缩AMCT提升模型端到端运行速度。同时提供**AI框架适配器Framework Adaptor**用于兼容Tensorflow、Pytorch等主流AI框架。 - **昇腾计算编译层**通过图编译器(Graph Compiler)将用户输入中间表达(Intermediate Representation,IR)的计算图编译成昇腾硬件可执行模型;同时借助张量加速引擎TBE(Tensor Boost Engine)的自动调度机制,高效编译算子。 - **昇腾计算执行层**负责模型和算子的执行,提供运行时库(Runtime)、图执行器(Graph Executor)、数字视觉预处理(Digital Vision Pre-Processing,DVPP)、人工智能预处理(Artificial Intelligence Pre-Processing,AIPP)、华为集合通信库(Huawei Collective Communication Library,HCCL)等功能单元。 - **昇腾计算基础层**主要为其上各层提供基础服务,如共享虚拟内存(Shared Virtual Memory,SVM)、设备虚拟化(Virtual Machine,VM)、主机-设备通信(Host Device Communication,HDC)等。 ### AI框架 AI框架层主要包括**自研框架MindSpore(昇思)** 和**第三方框架(PyTorch、TensorFlow等)** ,其中MindSpore完全由华为自主研发,第三方框架华为只是做了适配和优化,让PyTorch和TensorFlow等框架编写的模型可以高效的跑在昇腾芯片上。 以PyTorch为例,华为的框架研发人员会将其做好适配,然后把适配后的PyTorch源码发布出来,想要在昇腾上用PyTorch的开发者,下载该源码自行编译安装即可。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c6195f81e22940fe9597a0b4d5586240~tplv-k3u1fbpfcp-watermark.image?) ### 应用使能 应用使能层主要包括**ModelZoo、MindX SDK、MindX DL、MindX Edge**等。 - **ModelZoo:** 存放模型的仓库 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c50fe98850274524b21a0bbcff1fef9b~tplv-k3u1fbpfcp-watermark.image?) - **MindX SDK:** 帮助特定领域的用户快速开发并部署人工智能应用,比如工业质检、检索聚类等,致力于简化昇腾 AI 处理器推理业务开发过程,降低使用昇腾AI处理器开发的门槛。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7444199e44b84cfea66ba4e9324f1d33~tplv-k3u1fbpfcp-watermark.image?) - **MindX DL(昇腾深度学习组件):** 是支持 Atlas训练卡、推理卡的深度学习组件,提供昇腾 AI 处理器集群调度、昇腾 AI 处理器性能测试、模型保护等基础功能,快速使能合作伙伴进行深度学习平台开发。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/245bf318c3b343d58996c378efa82d81~tplv-k3u1fbpfcp-watermark.image?) ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/988982604f244ff6b748b8a1bbc56b42~tplv-k3u1fbpfcp-watermark.image?) ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ea5f8eedab3d409b9df22fddb1ba4b5d~tplv-k3u1fbpfcp-watermark.image?) ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/236bc27c3f8e4c55818cd0a0616facc0~tplv-k3u1fbpfcp-watermark.image?) - **MindX Edge(昇腾智能边缘组件):**  提供边缘 AI 业务容器的全生命周期管理能力,同时提供严格的安全可信保障,为客户提供边云协同的边缘计算解决方案,使能客户快速构建边缘 AI 业务。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0ba533c6c3ed4a62a2eaf3dd38f5614a~tplv-k3u1fbpfcp-watermark.image?) - **Modelarts:** ModelArts 是面向开发者的一站式 AI 平台,为机器学习与深度学习提供海量数据预处理及交互式智能标注、大规模分布式训练、自动化模型生成,及端-边-云模型按需部署能力,帮助用户快速创建和部署模型,管理全周期 AI 工作流。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/09e8210b12244705b076b6967a75d75d~tplv-k3u1fbpfcp-watermark.image?) - **HiAI Service**:HUAWEI HiAI是面向智能终端的AI能力开放平台,基于 “芯、端、云”三层开放架构,即**芯片能力开放、应用能力开放、服务能力开放**,构筑全面开放的智慧生态,让开发者能够快速地利用华为强大的AI处理能力,为用户提供更好的智慧应用体验。 ### 行业应用 主要应用于能源、金融、交通、电信、制造、医疗等行业,这里就不过多介绍了。 ## 安装 MindSpore 和 MindFormers 简单流程 > 建议:确定要安装的MindSpore具体版本,再确定需要安装的驱动和固件版本。 主要有物理机、容器和虚拟机安装。其中,容器和虚拟机不支持固件包安装。 **安装流程**: 这里针对昇腾910处理器进行安装。 - 安装驱动和固件 ``` chmod +x Ascend-hdk-910-npu-driver_23.0.rc1_linux-aarch64.run ./Ascend-hdk-910-npu-driver_23.0.rc1_linux-aarch64.run --full --install-path=/usr/local/Ascend chmod +x Ascend-hdk-910-npu-firmware_6.3.0.1.241.run ./Ascend-hdk-910-npu-firmware_6.3.0.1.241.run --check ./Ascend-hdk-910-npu-firmware_6.3.0.1.241.run --full ``` - 安装开发工具集(CANN) ``` chmod +x Ascend-cann-nnae_6.0.1_linux-aarch64.run ./Ascend-cann-nnae_6.0.1_linux-aarch64.run --install --install-for-all # 建议配置在~/.bashrc中 source /usr/local/Ascend/nnae/set_env.sh ``` - 创建虚拟环境 ``` cd /tmp curl -O https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py37_4.10.3-Linux-$(arch).sh bash Miniconda3-py37_4.10.3-Linux-$(arch).sh -b cd - . ~/miniconda3/etc/profile.d/conda.sh conda init bash conda create -n mindspore_py37 python=3.7 -y conda activate mindspore_py37 # python -m pip install -U pip ``` - 升级GCC以及安装Cmake ``` # 安装GCC sudo yum install gcc -y # 安装Cmake, aarch64使用 curl -O https://cmake.org/files/v3.19/cmake-3.19.8-Linux-aarch64.sh sudo mkdir /usr/local/cmake-3.19.8 sudo bash cmake-3.19.8-Linux-*.sh --prefix=/usr/local/cmake-3.19.8 --exclude-subdir echo -e "export PATH=/usr/local/cmake-3.19.8/bin:\$PATH" >> ~/.bashrc source ~/.bashrc ``` - 安装通信库 ``` # pip uninstall te topi hccl -y pip install sympy pip install /usr/local/Ascend/nnae/latest/lib64/topi-*-py3-none-any.whl pip install /usr/local/Ascend/nnae/latest/lib64/te-*-py3-none-any.whl pip install /usr/local/Ascend/nnae/latest/lib64/hccl-*-py3-none-any.whl ``` - 安装 MindSpore ``` conda install mindspore-ascend=1.10.1 -c mindspore -c conda-forge ``` - 安装 MindFormers ``` git clone https://gitee.com/mindspore/mindformers.git cd mindformers/ pip install . ``` - 安装其他库 ``` pip install requests ``` ## GPT2 模型推理 下面针对 GPT2 进行模型推理测试: ``` from mindformers.pipeline import pipeline pipeline_task = pipeline("text_generation", model='gpt2', max_length=20) pipeline_result = pipeline_task("I love Beijing, because", top_k=3) print(pipeline_result) ``` 运行过程: ``` >>> from mindformers.pipeline import pipeline >>> pipeline_task = pipeline("text_generation", model='gpt2', max_length=20) [WARNING] ME(55115:281472858920832,MainProcess):2023-06-16-16:26:33.147.258 [mindspore/ops/primitive.py:207] The in_strategy of the operator in your network will not take effect in stand_alone mode. This means the the shard function called in the network is ignored. If you want to enable it, please use semi auto or auto parallel mode by context.set_auto_parallel_context(parallel_mode=ParallelMode.SEMI_AUTO_PARALLEL or context.set_auto_parallel_context(parallel_mode=ParallelMode.AUTO_PARALLEL) [WARNING] ME(55115:281472858920832,MainProcess):2023-06-16-16:26:33.311.599 [mindspore/common/_decorator.py:38] 'DropoutGenMask' is deprecated from version 1.5 and will be removed in a future version, use 'ops.Dropout' instead. [WARNING] ME(55115:281472858920832,MainProcess):2023-06-16-16:26:33.312.329 [mindspore/common/_decorator.py:38] 'DropoutDoMask' is deprecated from version 1.5 and will be removed in a future version, use 'ops.Dropout' instead. [WARNING] ME(55115:281472858920832,MainProcess):2023-06-16-16:26:33.313.109 [mindspore/common/parameter.py:599] This interface may be deleted in the future. 2023-06-16 16:26:34,473 - mindformers - INFO - Start download ./checkpoint_download/gpt2/gpt2.ckpt Downloading: 498MB [00:13, 35.7MB/s] 2023-06-16 16:26:48,825 - mindformers - INFO - Download completed!,times: 14.68s 2023-06-16 16:26:48,829 - mindformers - INFO - start to read the ckpt file: 497772028 [WARNING] ME(55115:281472858920832,MainProcess):2023-06-16-16:26:50.316.896 [mindspore/train/serialization.py:736] For 'load_param_into_net', remove parameter prefix name: backbone., continue to load. [WARNING] ME(55115:281472858920832,MainProcess):2023-06-16-16:26:50.325.714 [mindspore/train/serialization.py:736] For 'load_param_into_net', remove parameter prefix name: backbone.blocks., continue to load. 2023-06-16 16:26:50,391 - mindformers - INFO - weights in ./checkpoint_download/gpt2/gpt2.ckpt are loaded 2023-06-16 16:26:50,392 - mindformers - INFO - Download the yaml from the url https://ascend-repo-modelzoo.obs.cn-east-2.myhuaweicloud.com/XFormer_for_mindspore/gpt2/vocab.json to ./checkpoint_download/gpt2/vocab.json. 2023-06-16 16:26:50,564 - mindformers - INFO - Start download ./checkpoint_download/gpt2/vocab.json Downloading: 1.04MB [00:00, 5.61MB/s] 2023-06-16 16:26:50,751 - mindformers - INFO - Download completed!,times: 0.36s 2023-06-16 16:26:50,752 - mindformers - INFO - Download the yaml from the url https://ascend-repo-modelzoo.obs.cn-east-2.myhuaweicloud.com/XFormer_for_mindspore/gpt2/merges.txt to ./checkpoint_download/gpt2/merges.txt. 2023-06-16 16:26:50,914 - mindformers - INFO - Start download ./checkpoint_download/gpt2/merges.txt Downloading: 457kB [00:00, 3.59MB/s] 2023-06-16 16:26:51,042 - mindformers - INFO - Download completed!,times: 0.29s >>> pipeline_result = pipeline_task("I love Beijing, because", top_k=3) >>> print(pipeline_result) [{'text_generation_text': ['I love Beijing, because it\'s so beautiful," he told the crowd, adding, "We\'re']}] ``` 模型权重文件: ``` > tree -h gpt2 gpt2 ├── [ 475M] gpt2.ckpt ├── [ 446K] merges.txt └── [1018K] vocab.json ``` NPU显存使用情况: ``` > npu-smi info +-------------------------------------------------------------------------------------------+ | npu-smi 23.0.rc1 Version: 23.0.rc1 | +----------------------+---------------+----------------------------------------------------+ | NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page)| | Chip | Bus-Id | AICore(%) Memory-Usage(MB) HBM-Usage(MB) | +======================+===============+====================================================+ | 0 910ProB | OK | 78.4 33 0 / 0 | | 0 | 0000:C1:00.0 | 0 1198 / 15137 30711/ 32768 | +======================+===============+====================================================+ +----------------------+---------------+----------------------------------------------------+ | NPU Chip | Process id | Process name | Process memory(MB) | +======================+===============+====================================================+ | 0 0 | 55115 | python | 30784 | +======================+===============+====================================================+ ``` MindFormers 目前适配的一些模型: ``` { 'swin_base_p4w7', 'clip_vit_b_32', 'clip_vit_b_16', 'clip_vit_l_14', 'gpt2', 'llama_13b', 'bloom_560m', 't5_small', 'glm_6b_lora', 'bert_tiny_uncased', 'llama_7b', 'bloom_65b', 't5_tiny', 'gpt2_13b', 'mindspore/txtcls_bert_base_uncased_mnli', 'glm_6b_chat', 'common', 'gpt2_52b', 'tokcls_bert_base_chinese', 'mindspore/vit_base_p16', 'qa_bert_base_uncased_squad', 'pangualpha_13b', 'pangualpha_2_6b', 'mae_vit_base_p16', 'clip_vit_l_14@336', 'bloom_7.1b', 'llama_65b', 'glm_6b_lora_chat', 'bloom_176b', 'glm_6b', 'mindspore/clip_vit_b_32', 'qa_bert_base_uncased', 'tokcls_bert_base_chinese_cluener', 'vit_base_p16', 'txtcls_bert_base_uncased_mnli', 'llama_7b_lora', 'mindspore/swin_base_p4w7', 'bert_base_uncased', 'mindspore/qa_bert_base_uncased', 'txtcls_bert_base_uncased' } ``` 可以看到,昇腾针对ChatGLM、OpenLLaMA等开源大模型进行了一些适配,不过不太稳定,运行还有一些问题,还在摸索中。而且,像LLaMA之类的大模型,目前多卡模型并行推理是不支持的。 ## 注意事项 - 昇腾推理服务器不支持训练,模型训练需要使用训练类型服务器。 - Ascend 310只能用作推理,MindSpore支持在Ascend 910训练,训练出的模型要转化为OM模型用于Ascend 310上进行推理。 - 目前华为昇腾主要还是运行华为自家闭环的大模型产品。 - 任何公开模型都必须经过华为的深度优化才能在华为的平台上运行。而这部分优化工作严重依赖于华为,进度较慢。 - 目前(2023.06.19)昇腾芯片对于Pytorch/TensorFlow等第三方框架的支持很差,如果需要适配最新出来的大模型,使用起来困难重重。 - 目前(2023.06.19)MindFormers 里面适配的大模型(如:ChatGLM、LLaMA、Bloom)仅支持Ascend 910进行模型训练和推理,不支持Ascend 310进行推理。 - 目前(2023.06.19)针对 ChatGLM、LLaMA、Bloom 等大模型不支持int8量化。 - 使用昇腾 NPU 芯片进行大模型推理时是独占的,即使NPU显存充裕的情况下,也不支持同一张 NPU 卡运行多个大模型。 ## 结语 说实话,刚开始看昇腾的时候,还是有点懵逼的。虽然相关的文档很多,但感觉稍显凌乱。遇到问题的时候,社区使用的人少,很可能得不到相应的解决,所以,经常有一种原地爆炸的心情。目前来看,昇腾的生态相比Nvidia的生态还是差很远。但是,在国内来说,也是做的比较全的了,希望昇腾越来越好吧,保持耐心。 参考文档: - [npu-smi 命令参考文档](https://support.huawei.com/enterprise/zh/doc/EDOC1100273886/d8e258d6) - [mindspore 安装(Gitee)](https://gitee.com/mindspore/docs/blob/r1.10/install/mindspore_ascend310_install_pip.md) - [mindspore 安装(官网)](https://www.mindspore.cn/install) - [CANN 安装](https://www.hiascend.com/document/detail/zh/canncommercial/601/overview/index.html) - [mindspore 官方教程](https://www.mindspore.cn/tutorials/zh-CN/r1.10/index.html) ================================================ FILE: blog/llm-localization/大模型国产化适配4-基于昇腾910使用LLaMA-13B进行多机多卡训练.md ================================================ 随着 ChatGPT 的现象级走红,引领了 AI 大模型时代的变革,从而导致 AI 算力日益紧缺。与此同时,中美贸易战以及美国对华进行AI芯片相关的制裁导致 AI 算力的国产化适配势在必行。之前讲述了**基于昇腾910使用ChatGLM-6B进行模型训练和推理**,主要是针对 MindSpore 框架进行大模型训练,这也是华为自家研发的 AI 框架。 在昇腾上面除了使用 MindSpore 进行大模型训练,我们也可以使用 PyTorch 进行大模型训练。这两个框架也是在昇腾 NPU 上华为花主要精力维护的两款AI框架。 本文主要针对 MindSpore 和 Pytorch 分布式 AI 框架在进行多机多卡训练(双机16卡),为了文章具有更好的阅读体验,具体代码放置在GitHub:[llm-action](https://github.com/liguodongiot/llm-action/tree/main/train/ascend)。 ## 数据准备及数据格式转换 本文多机多卡训练采用斯坦福羊驼提供的数据集:[下载地址](https://github.com/tatsu-lab/stanford_alpaca/blob/main/alpaca_data.json)。该数据集是利用OpenAI提供的GPT模型API生成质量较高的指令数据。然而,Alpaca 格式不适合用于多轮对话。参考 Vicuna 进行多轮对话训练的数据集格式,下面使用 [`alpaca_converter.py`](https://gitee.com/mindspore/mindformers/tree/8eec953/mindformers/tools/dataset_preprocess/llama) 脚本添加 prompts 模板,同时,转换为多轮对话格式。 ``` > python alpaca_converter.py \ --data_path /home/workspace/data/alpaca_data.json \ --output_path /home/workspace/data/alpaca-data-conversation.json > tree -h /home/workspace/data /home/workspace/data ├── [ 35M] alpaca-data-conversation.json └── [ 22M] alpaca_data.json ``` 转换前格式: ```json [ { "instruction": "Give three tips for staying healthy.", "input": "", "output": "1.Eat a balanced diet and make sure to include plenty of fruits and vegetables. \n2. Exercise regularly to keep your body active and strong. \n3. Get enough sleep and maintain a consistent sleep schedule." }, { "instruction": "What are the three primary colors?", "input": "", "output": "The three primary colors are red, blue, and yellow." }, ] ``` 转换后格式: ```json [ { "id": "1", "conversations": [ { "from": "human", "value": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instruction:\nGive three tips for staying healthy.\n\n### Response:" }, { "from": "gpt", "value": "1.Eat a balanced diet and make sure to include plenty of fruits and vegetables. \n2. Exercise regularly to keep your body active and strong. \n3. Get enough sleep and maintain a consistent sleep schedule." } ] }, { "id": "2", "conversations": [ { "from": "human", "value": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instruction:\nWhat are the three primary colors?\n\n### Response:" }, { "from": "gpt", "value": "The three primary colors are red, blue, and yellow." } ] }, ] ``` ## 模型准备及模型格式转换 下面准备好LLaMA-13B模型权重文件,有以下两种方案。 - 方案一:基于原始的LLaMA模型权重文件使用 HuggingFace Transformers 中提供的模型转换[工具](https://github.com/huggingface/transformers/blob/main/src/transformers/models/llama/convert_llama_weights_to_hf.py)进行模型格式转换。 - 方案二:直接从 HuggingFace 下载转换好的模型:[decapoda-research / llama-13b-hf](https://huggingface.co/decapoda-research/llama-13b-hf)。 模型和数据集准备好之后,我们我们先来看一下使用 MindSpore 进行多机多卡训练。 ## 网络通信 昇腾 910 通过自研的集合通信库(HCCL)整合了三种高速互联接口:PCIe、RoCE v2 以及 HCCS。 通常情况下,NPU 与 CPU 之间采用 PCIe 进行通信,服务器内的 NPU 之间则采用 HCCS(组间) 或 PCIe(组间) 进行通信,而服务器之间使用 RoCE 进行通信。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d1b50aac8824407cb5cdb7a9ab1ef6dc~tplv-k3u1fbpfcp-watermark.image?) ## 使用 MindSpore 进行多机多卡训练 ### 基础环境安装 - **操作系统版本/架构**:EulerOS release 2.0 (SP8)/aarch64 - **NPU**:8卡 910B1 64G - **Python**:3.7.5 - **NPU 驱动**:23.0.rc1,[下载](https://www.hiascend.com/zh/hardware/firmware-drivers/community?product=2&model=19&cann=6.3.RC1.alpha003&driver=1.0.19.alpha) - **NPU 固件**:6.3.0.1.241,[下载](https://www.hiascend.com/zh/hardware/firmware-drivers/community?product=2&model=19&cann=6.3.RC1.alpha003&driver=1.0.19.alpha) - **CANN 工具包**:6.3.RC1.alpha003,[下载](https://www.hiascend.com/software/cann/community-history) - **MindSpore**:2.0.0 - **MindFormers**:dev 对于驱动、固件以及 CANN 工具集的安装和之前在昇腾910上面安装方式基本一致,找到对应版本的驱动、固件以及CANN工具集进行安装即可。 创建新的虚拟环境: ``` conda create -n llama_cluster python=3.7.5 conda activate llama_cluster ``` 安装 MindSpore 和 MindFormers(MindSpore Transformers 的简称)。 ``` pip install ./mindspore-2.0.0-cp37-cp37m-linux_aarch64.whl cd /home/workspace/code git clone https://gitee.com/mindspore/mindformers.git cd mindformers bash build.sh ``` 如果模型权重为 Huggingface Transformers 模型权重格式,还需要下载Pytorch 和 Huggingface Transformers 库用于将权重转换为 MindSpore 格式。 ``` pip install torch transformers ``` ### 模型权重格式转换 将 Huggingface Transformers 模型权重格式转换成 MindFormers 权重格式。 ``` cd /home/workspace/code/mindformers python mindformers/models/llama/convert_weight.py \ --torch_ckpt_dir /home/workspace/model/vicuna-13B \ --mindspore_ckpt_path /home/worspace/model/vicuna-13B-ms ``` ### 数据集格式转换 使用 MindFormers 进行模型训练时,需先将带有 Prompt 模板的数据集转换为 MindRecord 格式。 ``` cd /home/workspace/code/mindformers/mindformers/tools/dataset_preprocess/llama python llama_preprocess.py \ --input_glob '/home/workspace/data/alpaca-data-conversation.json' \ --dataset_type qa \ --model_file /home/workspace/model/tokenizer.model \ --seq_length 1024 \ --repeat 3 \ --shuffle 1 \ --output_file /home/workspace/data/alpaca-fastchat1024.mindrecord ``` 参数说明: - input_glob:输入数据集路径。 - dataset_type:数据集类型,qa(对话)/wiki(生成)。 - model_file:tokenizer模型权重。 - seq_length:最大序列长度。 - repeat: 数据重复次数。 - shuffle: 是否对数据集进行shuffle,值为0或1。 - output_file:输出数据集路径。 ### 模型训练 首先,在每台服务器上面生成用于Ascend芯片分布式通信的芯片资源信息配置文件(RANK_TABLE_FILE)。Ascend HCCL 的 RANK_TABLE_FILE 文件提供 Ascend 分布式训练作业的集群信息。 ``` python ./mindformers/tools/hccl_tools.py --device_num "[0,8)" --server_ip=90.90.3.xx python ./mindformers/tools/hccl_tools.py --device_num "[0,8)" --server_ip=90.90.3.yy ``` 然后,合并每个机器上的RANK_TABLE_FILE文件。可以使用官网提供的脚本`merge_hccl.py`进行合并,也可以手动进行合并。 ``` python ./mindformers/tools/merge_hccl.py hccl*.json ``` 合并后的文件如下所示。 ```json { "version": "1.0", "server_count": "2", "server_list": [ { "server_id": "90.90.3.xx", "device": [ { "device_id": "0", "device_ip": "10.0.0.36", "rank_id": "0" }, ... { "device_id": "7", "device_ip": "10.0.0.48", "rank_id": "7" } ], "host_nic_ip": "reserve" }, { "server_id": "90.90.3.yy", "device": [ { "device_id": "0", "device_ip": "10.0.0.37", "rank_id": "8" }, ... { "device_id": "7", "device_ip": "10.0.0.49", "rank_id": "15" } ], "host_nic_ip": "reserve" } ], "status": "completed" } ``` 之后,将合并后的RANK_TABLE_FILE文件分别复制到所有的机器上。 下面修改配置文件`configs/llama/run_llama_13B.yaml` 将 only_save_strategy 改为 True;同时,修改并行策略,目前支持纯数据并行(类似DeepSpeed的ZeRO3,会对模型进行切分)进行训练。 ```yaml only_save_strategy: True parallel_config: data_parallel: 16 model_parallel: 1 pipeline_stage: 1 ``` 然后,启动训练任务**生成模型切分策略文件**。 ``` # 服务器1: cd scripts bash run_distribute.sh ../hccl_2s_16p.json ../configs/llama/run_llama_13b.yaml [0,8] train 16 # 服务器2: cd scripts bash run_distribute.sh ../hccl_2s_16p.json ../configs/llama/run_llama_13b.yaml [8,16] train 16 ``` 根据策略文件,切分模型。 ``` python ./mindformers/tools/transform_ckpt.py \ --src_ckpt_strategy '' \ --dst_ckpt_strategy output/strategy/ckpt_strategy_rank_0.ckpt \ --src_ckpt_dir /home/zk/workspace/model/ \ --dst_ckpt_dir /home/zk/workspace/model/ckpt-multi-node \ --prefix "checkpoint_" ``` 参数说明: - src_ckpt_strategy:原权重切分策略,空代表不切分 - dst_ckpt_strategy:目标切分策略路径 - src_ckpt_dir:原权重路径,需按照`checkpoint_root_dir/rank_{}/*.ckpt`格式 - dst_ckpt_dir:目标权重路径 prefix:生成权重的文件名前缀 接下来,修改配置文件 `configs/llama/run_llama_13B.yaml` 中,模型权重文件路径、数据集路径、模型超参数等配置信息。 ```yaml load_checkpoint: '/home/llama-sft/ckpt/13B-vicuna-dp' train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "/home/ms_llama/datasets/alpaca_1024" shuffle: True ... ``` 最后,在每一台服务器上面运行训练脚本。 ```bash # 配置环境变量,使能GE,MS_GE_ATOMIC_CLEAN_POLICY算子内存复用,并将HCCL通信超时增大到600s export MS_ENABLE_GE=1 export MS_GE_TRAIN=1 export MS_GE_ATOMIC_CLEAN_POLICY=1 export HCCL_CONNECT_TIMEOUT=600 # 服务器1: cd scripts bash run_distribute.sh ../hccl_2s_16p.json ../configs/llama/run_llama_13b.yaml [0,8] train 16 # 服务器2: cd scripts bash run_distribute.sh ../hccl_2s_16p.json ../configs/llama/run_llama_13b.yaml [8,16] train 16 ``` 运行日志: ``` ... 2023-08-07 17:27:21,717 - mindformers - INFO - .........Build context config.......... 2023-08-07 17:27:21,718 - mindformers - INFO - initial recompute_config from dict: {'recompute': True, 'parallel_optimizer_comm_recompute': False, 'mp_comm_recompute': True, 'recompute_slice_activation': True} 2023-08-07 17:27:21,718 - mindformers - INFO - initial parallel_config from dict: {'data_parallel': 16, 'model_parallel': 1, 'pipeline_stage': 1, 'optimizer_shard': True, 'micro_batch_num': 16, 'vocab_emb_dp': True, 'gradient_aggregation_group': 4} 2023-08-07 17:27:21,719 - mindformers - INFO - context config is: [ParallelConfig] ... 2023-08-07 19:12:16,935 - mindformers - INFO - Epoch:[ 1/ 1], step:[ 804/ 812], loss:[0.762/0.762], time:27421.790 ms, lr:[1.2624264e-09], overflow cond: False, loss_scale: 65536.0 2023-08-07 19:12:16,935 - mindformers - INFO - Per sink_size step time: 27443.713 ms, per step time: 6860.928 ms, avg loss: 0.762 2023-08-07 19:12:44,368 - mindformers - INFO - Epoch:[ 1/ 1], step:[ 808/ 812], loss:[0.702/0.702], time:27411.658 ms, lr:[3.08156e-10], overflow cond: False, loss_scale: 65536.0 2023-08-07 19:12:44,369 - mindformers - INFO - Per sink_size step time: 27433.661 ms, per step time: 6858.415 ms, avg loss: 0.702 2023-08-07 19:13:11,812 - mindformers - INFO - Epoch:[ 1/ 1], step:[ 812/ 812], loss:[0.739/0.739], time:27419.873 ms, lr:[0.], overflow cond: False, loss_scale: 65536.0 2023-08-07 19:13:11,813 - mindformers - INFO - Per sink_size step time: 27443.428 ms, per step time: 6860.857 ms, avg loss: 0.739 2023-08-07 19:14:21,468 - mindformers - INFO - .........Training Over!............. ``` 至此,基于 MindSpore 和 MindFormers 进行多机多卡训练结束。 下面我们继续来看下使用 Pytorch 进行多机多卡训练。 ## 使用 PyTorch 进行多机多卡训练 ### 基础环境安装 - **操作系统版本/架构**:EulerOS release 2.0 (SP8)/aarch64 - **NPU**:8卡 910B1 64G - **Python**:3.7.5 - **NPU 驱动**:23.0.rc2.b090,[下载](https://www.hiascend.com/zh/hardware/firmware-drivers/community?product=2&model=19&cann=6.3.RC1.alpha003&driver=1.0.19.alpha) - **NPU 固件**:6.3.0.1.241,[下载](https://www.hiascend.com/zh/hardware/firmware-drivers/community?product=2&model=19&cann=6.3.RC1.alpha003&driver=1.0.19.alpha) - **CANN 工具包**:6.3.RC1.alpha003,[下载](https://www.hiascend.com/software/cann/community-history) - **Pytorch**:1.11.0 - **Huggingface Transformers**:4.28.1 - **DeepSpeed**:0.6.0 目前,在昇腾上面针对 MindSpore 和 PyTorch 框架的支持是不同的团队支持。因此,驱动、固件以及 CANN 工具集目前还没有办法使用同一套。因此,需要根据官方的要求选择对应的版本进行重新安装,安装方式和之前在昇腾910上面安装方式基本一致。 为了避免之前的环境干扰,创建新的虚拟环境: ```bash conda create -n llama_pytorch_cluster python=3.7.5 conda activate llama_pytorch_cluster ``` 安装依赖。 ``` pip3 install --upgrade pip pip3 install einops sympy regex decorator scipy setuptools scm prompt toolkit ``` 安装 PyTorch 和 PyTorch 的适配插件 torch_npu。 ```bash # 安装 1.11.0 版本 wget https://repo.huaweicloud.com/kunpeng/archive/Ascend/PyTorch/torch-1.11.0-cp37-cp37m-linux_aarch64.whl pip3 install torch-1.11.0-cp37-cp37m-linux_aarch64.whl # 安装 1.11.0 版本 wget https://gitee.com/ascend/pytorch/releases/download/v3.0.0-pytorch1.11.0/torch_npu-1.11.0-cp37-cp37m-linux_aarch64.whl pip3 install torch_npu-1.11.0-cp37-cp37m-linux_aarch64.whl ``` 安装Apex。 ```bash yum install -y patch libjpeg-turbo-devel dos2unix openblas git # gcc 7.3.0版本及以上,cmake 3.12.0版本及以上。若用户要安装1.11.0版本PyTorch,则gcc需为7.5.0版本以上。 yum install -y gcc==7.3.0 cmake==3.12.0 # 获取昇腾适配的APEX源码。 git clone -b master https://gitee.com/ascend/apex.git # 进入昇腾适配的APEX源码目录,获取原生APEX代码。 cd apex git clone https://github.com/NVIDIA/apex.git # 进入原生APEX代码目录,切换对应分支。 cd apex git checkout 4ef930c1c884fdca5f472ab2ce7cb9b505d26c1a cd .. # 在昇腾适配的APEX源码目录下的scripts中执行命令生成NPU适配的全量代码。 cd scripts bash gen.sh 进入原生APEX执行命令编译生成二进制安装包。 cd ../apex python3 setup.py --cpp_ext --npu_float_status bdist_wheel # 执行如下命令安装。如果使用非root用户安装,需要在命令后加--user。 cd dist pip3 install apex-0.1_ascend-cp37-cp37m-linux_aarch64.whl ``` 在昇腾上面使用 Pytorch 训练 LLaMA-13B 是基于 FastChat 项目进行的适配。下面安装相关的依赖包及Huggingface Transformers库。 ``` git clone https://gitee.com/ascend/ModelZoo-PyTorch.git cd ModelZoo-PyTorch/PyTorch/built-in/foundation/LLaMA-13B pip3 install -e . ``` 安装 DeepSpeed 以及 Ascend NPU 适配 DeepSpeed 的插件。 ``` pip3 install deepspeed==0.6.0 git clone https://gitee.com/ascend/DeepSpeed.git cd DeepSpeed git checkout ad2347e python setup.py develop ``` 安装完成之后,修改将`deepspeed_npu`适配包导入到deepspeed中。首先,使用 whereis 命令查看 deepspeed 安装路径,找到路径后,在`.../deepspeed/bin/deepspeed`文件中增加以下内容。 ``` import deepspeed_npu ``` 下面,替换transformers库中相关文件。将源码包根目录下`transformers_modify`文件夹中的各个文件分别替换到transformers 安装目录下的对应位置(基于transformers 4.28.1版本): ``` training_args.py -> transformers/training_args.pu trainer.py -> transformers/trainer.py versions.py -> utils/versions.py modeling_llama.py -> transformers/models/llama/modeling_llama.py ``` ### 模型训练 下面进行模型训练,本文使用 Pytorch 原生方式启动训练任务(除此之外,还可以采用DeepSpeed命令进行启动,需先安装pdsh,同时配置hostfile。) ```bash # 服务器1 export HCCL_CONNECT_TIMEOUT=1200 cd /home/workspace/code/ModelZoo-PyTorch/PyTorch/built-in/foundation/LLaMA-13B nohup python -m torch.distributed.launch --nproc_per_node 8 --nnodes 2 --node_rank 0 --master_addr='90.90.3.xx' --master_port='29500' \ fastchat/train/train_mem.py \ --model_name_or_path /home/workspace/model/vicuna-13B \ --data_path /home/workspace/data/alpaca-data-conversation.json \ --fp16 True \ --output_dir /home/workspace/model/output \ --num_train_epochs 30 \ --per_device_train_batch_size 8 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 16 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 500 \ --save_total_limit 2 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --tf32 False \ --model_max_length 1024 \ --gradient_checkpointing True \ --lazy_preprocess True \ --deepspeed ./deepspeed_config_13B.json > train_13B.log & # 服务器2 export HCCL_CONNECT_TIMEOUT=1200 cd /home/workspace/code/ModelZoo-PyTorch/PyTorch/built-in/foundation/LLaMA-13B nohup python -m torch.distributed.launch --nproc_per_node 8 --nnodes 2 --node_rank 1 --master_addr='90.90.3.xx' --master_port='29500' \ fastchat/train/train_mem.py \ --model_name_or_path /home/workspace/model/vicuna-13B \ --data_path /home/workspace/data/alpaca-data-conversation.json \ --fp16 True \ --output_dir /home/workspace/model/output \ --num_train_epochs 30 \ --per_device_train_batch_size 8 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 16 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 500 \ --save_total_limit 2 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --tf32 False \ --model_max_length 1024 \ --gradient_checkpointing True \ --lazy_preprocess True \ --deepspeed ./deepspeed_config_13B.json > train_13B.log & ``` 显存占用: ``` +------------------------------------------------------------------------------------------------+ | npu-smi 23.0.rc2.b090 Version: 23.0.rc2.b090 | +---------------------------+---------------+----------------------------------------------------+ | NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page)| | Chip | Bus-Id | AICore(%) Memory-Usage(MB) HBM-Usage(MB) | +===========================+===============+====================================================+ | 0 910B1 | OK | 327.1 54 0 / 0 | | 0 | 0000:C1:00.0 | 57 0 / 0 64293/ 65536 | +===========================+===============+====================================================+ ... +===========================+===============+====================================================+ | 7 910B1 | OK | 451.6 76 0 / 0 | | 0 | 0000:42:00.0 | 68 0 / 0 64114/ 65536 | +===========================+===============+====================================================+ +---------------------------+---------------+----------------------------------------------------+ | NPU Chip | Process id | Process name | Process memory(MB) | +===========================+===============+====================================================+ | 0 0 | 2441447 | python | 59618 | +===========================+===============+====================================================+ | 1 0 | 2441448 | python | 59834 | +===========================+===============+====================================================+ ... +===========================+===============+====================================================+ | 7 0 | 2441454 | python | 59802 | +===========================+===============+====================================================+ ``` 至此,基于昇腾910采用 Pytorch 进行多机多卡训练结束。 ## 结语 本文讲述了在昇腾910上面使用 LLaMA-13B 进行多机多卡模型训练;但目前在昇腾910上面,无论是基于MindSpore还是基于Pytorch进行大模型训练,总体都还不是很完善,就当前时间节点而言,经常会有一些奇奇怪怪的坑;虽然,从硬件层面上来说昇腾910具备训练大模型的能力,但是软件层面(无论是生态还是AI框架的易用性,对于业界最新大模型的支持和适配等)上还有很长的路要走。 当然,目前来看,AI框架趋于收敛,大模型算法架构也趋于收敛,对于像华为昇腾这样的AI软硬件平台发展其生态来说是好事,不需要疲于拼命做太多AI框架和模型的适配工作。 参考文档: - [基于昇腾910采用 Pytorch 训练 LLaMA 大模型](https://gitee.com/ascend/ModelZoo-PyTorch/tree/master/PyTorch/built-in/foundation/LLaMA-13B) - [基于昇腾910采用 MindSpore 训练 LLaMA 大模型](https://gitee.com/mindspore/mindformers/blob/dev/docs/model_cards/llama.md) ================================================ FILE: blog/llm-peft/大模型参数高效微调技术原理综述(一)-背景、参数高效微调简介.md ================================================ 随着,ChatGPT 迅速爆火,引发了大模型的时代变革。然而对于普通大众来说,进行大模型的预训练或者全量微调遥不可及。由此,催生了各种参数高效微调技术,让科研人员或者普通开发者有机会尝试微调大模型。 因此,该技术值得我们进行深入分析其背后的机理,本系列大体分七篇文章进行讲解。 * 大模型参数高效微调技术原理综述(一)-背景、参数高效微调简介 * 大模型参数高效微调技术原理综述(二)-BitFit、Prefix Tuning、Prompt Tuning * 大模型参数高效微调技术原理综述(三)-P-Tuning、P-Tuning v2 * 大模型参数高效微调技术原理综述(四)-Adapter Tuning及其变体 * 大模型参数高效微调技术原理综述(五)-LoRA、AdaLoRA、QLoRA * 大模型参数高效微调技术原理综述(六)-MAM Adapter、UniPELT * 大模型参数高效微调技术原理综述(七)-最佳实践、总结 本文为大模型参数高效微调技术综述的第一篇。 # 背景 目前,基于 Transformers 架构的大型语言模型 (LLM),如 GPT、T5 和 BERT,已经在各种自然语言处理 (NLP) 任务中取得了 SOTA 结果。此外,还开始涉足其他领域,例如:计算机视觉 (VIT、Stable Diffusion、LayoutLM) 和音频 (Whisper、XLS-R)。 将预训练好的语言模型(LM)在下游任务上进行微调已成为处理 NLP 任务的一种范式。与使用开箱即用的预训练 LLM (例如:零样本推理) 相比,在下游数据集上微调这些预训练 LLM 会带来巨大的性能提升。 但是,随着模型变得越来越大,在消费级硬件上对模型进行全部参数的微调(full fine-tuning)变得不可行。 此外,为每个下游任务独立存储和部署微调模型变得非常昂贵,因为微调模型(调整模型的所有参数)与原始预训练模型的大小相同。 因此,近年来研究者们提出了各种各样的参数高效迁移学习方法(Parameter-efficient Transfer Learning),即固定住Pretrain Language model(PLM)的大部分参数,仅调整模型的一小部分参数来达到与全部参数的微调接近的效果(调整的可以是模型自有的参数,也可以是额外加入的一些参数)。 # Tansformer 上面谈到当前主流大语言模型都是基于 Transformers 架构,下面我们来详细看看 Transformers 架构内部构造。 Transformer(论文:**Attention is All You Need**)是谷歌在 2017年的提出的,它针对RNN的弱点进行重新设计,解决了RNN效率问题和传递中的缺陷等,在很多问题上都超过了RNN的表现。 Transformer 的整体结构如下图所示,图中 Transformer 用于中英文翻译。可以看到,Transformer 由 Encoder 和 Decoder 两个部分组成,Encoder 和 Decoder 都包含 6 个 block。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8eaba790ddb04a8d83a98ba889cc919f~tplv-k3u1fbpfcp-watermark.image?) 而 Transformer 的内部结构如下图,左侧为 Encoder block,右侧为 Decoder block。 可以看到 Encoder block 包含一个 Multi-Head Attention(Multi-Head Attention是由多个 Self-Attention组成的),而 Decoder block 包含两个 Multi-Head Attention (其中,有一个用到 Masked)。Multi-Head Attention 上方还包括一个 Add & Norm 层,Add 表示残差连接 (Residual Connection) 用于防止网络退化,Norm 表示 Layer Normalization,用于对每一层的激活值进行归一化。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c30d60548a4d4a1eb85547ea11e84171~tplv-k3u1fbpfcp-watermark.image?) 而 Transformer 的核心就是自注意力(Self-Attention)。引入Self Attention后会更容易捕获句子中长距离的相互依赖的特征,因为如果是RNN或者LSTM,需要依次序序列计算,对于远距离的相互依赖的特征,要经过若干时间步步骤的信息累积才能将两者联系起来,而距离越远,有效捕获的可能性越小。但是Self Attention在计算过程中会直接将句子中任意两个单词的联系通过一个计算步骤直接联系起来,所以,远距离依赖特征之间的距离被极大缩短,有利于有效地利用这些特征。除此之外,Self Attention 对于增加计算的并行性也有直接帮助作用。 而**多头注意力的机制**则进一步细化了注意力层,多头注意力是由多个自注意力组成。它通过以下两种方式提高了注意力层的性能: * 扩展了模型专注于不同位置的能力。当多头注意力模型和自注意力机制集合的时候,比如:我们翻译“动物没有过马路,因为它太累了”这样的句子的时候,我们想知道“它”指的是哪个词,如果能分析出来代表动物,就很有用。 * 为注意力层提供了多个“表示子空间”。对于多头注意力,我们有多组Query/Key/Value权重矩阵,这些权重矩阵集合中的每一个都是随机初始化的。然后,在训练之后,每组用于将输入Embedding投影到不同的表示子空间中。多个head学习到的Attention侧重点可能略有不同,这样给了模型更大的容量。 Self-Attention和 Multi-Head Attention 的内部结构如下所示:  ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4cd6465ea4ef47cc93ea2b12f4d05704~tplv-k3u1fbpfcp-watermark.image?) 而在Transformer模型架构中,FFN(Feed-Forward Network)由两个全连接层组成,其目的是引入非线性变换。它的作用是对每个位置的隐藏表示进行非线性变换,从而增加模型的表示能力和拟合复杂模式的能力。 总之,Transformer 架构的提出,奠定了其作为当前大模型领域主流的算法架构的基础。它不仅让模型能够支持更大的容量,使得模型参数能够轻松突破达到上亿规模。同时,还能够使模型较好地并行训练(Token并行、张量并行、流水线并行)。 # Bert 随着Transformer在2017年发布后,2018年谷歌又发布了BERT(论文:**BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding**),一经面世便一举击败 11 个 NLP 任务的 State-of-the-art (Sota)结果,成为了 NLP 界新的里程碑; Bert的结构如下图所示,左边是Bert模型预训练过程,右边是对于具体任务的微调过程。 其中,微调阶段是后续用于一些下游任务的时候进行微调,例如:文本分类,词性标注,问答系统等,BERT 无需调整结构就可以在不同的任务上进行微调。通过”预训练语言模型 + 下游任务微调”的任务设计,带来了强大的模型效果。从此,“预训练语言模型 + 下游任务微调”便成为了 NLP 领域主流训练范式。   ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/48f156ed6f1d4b8aa74e8944f5990275~tplv-k3u1fbpfcp-watermark.image?)   # 全量参数微调与参数高效微调对比 上面提到以BERT模型为代表的“预训练语言模型 + 下游任务微调”训练模式成为了自然语言处理研究和应用的新范式。此处的下游任务微调是基于模型全量参数进行微调。 但是,以 GPT3 为代表的预训练语言模型(PLM)参数规模变得越来越大,这使得在消费级硬件上进行全量微调变得不可行。 下表展示了在一张A100 GPU(80G 显存)以及 CPU 内存 64GB以上的硬件上进行模型全量微调以及参数高效微调对于 CPU/GPU 内存的消耗情况。 | **模型名** | **全量参数微调** | **PEFT-LoRA (PyTorch)** | **PEFT-LoRA(DeepSpeed+CPU Offloading技术)** | | ----------------------------- | ------------------------ | ----------------------- | ----------------------------------------- | | bigscience/T0\_3B (3B 参数) | 47.14GB GPU / 2.96GB CPU | 14.4GB GPU / 2.96GB CPU | 9.8GB GPU / 17.8GB CPU | | bigscience/bloomz-7b1 (7B 参数) | OOM GPU | 32GB GPU / 3.8GB CPU | 18.1GB GPU / 35GB CPU | | bigscience/mt0-xxl (12B 参数) | OOM GPU | 56GB GPU / 3GB CPU | 22GB GPU / 52GB CPU | 除此之外,模型全量微调还会损失多样性,存在灾难性遗忘的问题。 因此,如何高效的进行模型微调就成了业界研究的重点,这也为参数高效微调技术的快速发展带来了研究空间。 # 高效参数微调 参数高效微调是指微调少量或额外的模型参数,固定大部分预训练模型(LLM)参数,从而大大降低了计算和存储成本,同时,也能实现与全量参数微调相当的性能。参数高效微调方法甚至在某些情况下比全量微调效果更好,可以更好地泛化到域外场景。 高效微调技术可以粗略分为以下三大类:增加额外参数(A)、选取一部分参数更新(S)、引入重参数化(R)。而在增加额外参数这类方法中,又主要分为类适配器(Adapter-like)方法和软提示(Soft prompts)两个小类。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/52fa2811232f4b8bb5a1687124157b21~tplv-k3u1fbpfcp-watermark.image?) 常见的参数高效微调技术有BitFit、Prefix Tuning、Prompt Tuning、P-Tuning、Adapter Tuning、LoRA等,后续文章将对一些主流的参数高效微调方法进行讲解。 ================================================ FILE: blog/llm-peft/大模型参数高效微调技术原理综述(五)-LoRA、AdaLoRA、QLoRA.md ================================================ 随着,ChatGPT 迅速爆火,引发了大模型的时代变革。然而对于普通大众来说,进行大模型的预训练或者全量微调遥不可及。由此,催生了各种参数高效微调技术,让科研人员或者普通开发者有机会尝试微调大模型。 因此,该技术值得我们进行深入分析其背后的机理,本系列大体分七篇文章进行讲解。 * [大模型参数高效微调技术原理综述(一)-背景、参数高效微调简介](https://zhuanlan.zhihu.com/p/635152813) * [大模型参数高效微调技术原理综述(二)-BitFit、Prefix Tuning、Prompt Tuning](https://zhuanlan.zhihu.com/p/635686756) * [大模型参数高效微调技术原理综述(三)-P-Tuning、P-Tuning v2](https://zhuanlan.zhihu.com/p/635848732) * [大模型参数高效微调技术原理综述(四)-Adapter Tuning及其变体](https://zhuanlan.zhihu.com/p/636038478) * [大模型参数高效微调技术原理综述(五)-LoRA、AdaLoRA、QLoRA](https://zhuanlan.zhihu.com/p/636215898) * 大模型参数高效微调技术原理综述(六)-MAM Adapter、UniPELT * 大模型参数高效微调技术原理综述(七)-最佳实践、总结 本文为大模型参数高效微调技术原理综述的第五篇。 ## LoRA ### 背景 神经网络包含很多全连接层(线性层),其借助于矩阵乘法得以实现,然而,很多全连接层的权重矩阵都是满秩的。作者通过前人的一些工作发现当针对特定任务进行微调后,模型中权重矩阵其实具有很低的本征秩(intrinsic rank),因此,论文的作者认为权重更新的那部分参数矩阵尽管随机投影到较小的子空间,仍然可以有效的学习,可以理解为针对特定的下游任务这些权重矩阵就不要求满秩。 ### 技术原理 LoRA(论文:**LoRA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS**),该方法的核心思想就是通过低秩分解来模拟参数的改变量,从而以极小的参数量来实现大模型的间接训练。 在涉及到矩阵相乘的模块,在原始的PLM旁边增加一个新的通路,通过前后两个矩阵A,B相乘,第一个矩阵A负责降维,第二个矩阵B负责升维,中间层维度为r,从而来模拟所谓的本征秩(intrinsic rank)。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8cffc7d0555b486081086cfec94af839~tplv-k3u1fbpfcp-watermark.image?) 可训练层维度和预训练模型层维度一致为d,先将维度d通过全连接层降维至r,再从r通过全连接层映射回d维度,其中,r<\这里为什么是mask而不是删除奇异值? > >模型的学习是一个探索的过程,**在一开始模型认为不重要的奇异值,在后续过程中模型可能会慢慢学到它的重要性。因此,mask是比删掉更合理的方法。** 通过实验证明,AdaLoRA 实现了在所有预算、所有数据集上与现有方法相比,性能更好或相当的水平。 例如,当参数预算为 0.3M 时,AdaLoRA 在RTE数据集上,比表现最佳的基线(Baseline)高 1.8%。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b8191bf6859448069dfc59f06fdedbb3~tplv-k3u1fbpfcp-watermark.image?) ## QLoRA ### 背景 微调大型语言模型 (LLM) 是提高其性能以及添加所需或删除不需要的行为的一种非常有效的方法。然而,微调非常大的模型非常昂贵;以 LLaMA 65B 参数模型为例,常规的 16 bit微调需要超过 780 GB 的 GPU 内存。 虽然最近的量化方法可以减少 LLM 的内存占用,但此类技术仅适用于推理场景。 基于此,作者提出了QLoRA,并首次证明了可以在不降低任何性能的情况下微调量化为 4 bit的模型。 ### 技术原理 QLoRA(论文: **QLORA: Efficient Finetuning of Quantized LLMs**),使用一种新颖的高精度技术将预训练模型量化为 4 bit,然后添加一小组可学习的低秩适配器权重,这些权重通过量化权重的反向传播梯度进行微调。QLORA 有一种低精度存储数据类型(4 bit),还有一种计算数据类型(BFloat16)。实际上,这意味着无论何时使用 QLoRA 权重张量,我们都会将张量反量化为 BFloat16,然后执行 16 位矩阵乘法。QLoRA提出了两种技术实现高保真 4 bit微调——4 bit NormalFloat(NF4) 量化和双量化。此外,还引入了分页优化器,以防止梯度检查点期间的内存峰值,从而导致内存不足的错误,这些错误在过去使得大型模型难以在单台机器上进行微调。具体说明如下: * **4bit NormalFloat**(NF4):对于正态分布权重而言,一种信息理论上最优的新数据类型,该数据类型对正态分布数据产生比 4 bit整数和 4bit 浮点数更好的实证结果。 * **双量化**:对第一次量化后的那些常量再进行一次量化,减少存储空间。 * **分页优化器**:使用NVIDIA统一内存特性,该特性可以在在GPU偶尔OOM的情况下,进行CPU和GPU之间自动分页到分页的传输,以实现无错误的 GPU 处理。该功能的工作方式类似于 CPU 内存和磁盘之间的常规内存分页。使用此功能为优化器状态(Optimizer)分配分页内存,然后在 GPU 内存不足时将其自动卸载到 CPU 内存,并在优化器更新步骤需要时将其加载回 GPU 内存。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b818d83f6d9b4abca82359274309c0b4~tplv-k3u1fbpfcp-watermark.image?) 实验证明,无论是使用16bit、8bit还是4bit的适配器方法,都能够复制16bit全参数微调的基准性能。这说明,尽管量化过程中会存在性能损失,但通过适配器微调,完全可以恢复这些性能。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7dd93e49e61b4f54962bda75889857b8~tplv-k3u1fbpfcp-watermark.image?)   实验还比较了不同的4bit数据类型对效果(zero-shot均值)的影响,其中,NFloat 显著优于Float,而NFloat + DQ略微优于NFloat,虽然DQ对精度提升不大,但是对于内存控制效果更好。   ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a08a94ee6f2541828b50f7396bf53117~tplv-k3u1fbpfcp-watermark.image?) 除此之外,论文中还对不同大小模型、不同数据类型、在 MMLU数据集上的微调效果进行了对比。使用QLoRA(NFloat4 + DQ)可以和Lora(BFloat16)持平,同时, 使用QLORA( FP4)的模型效果落后于前两者一个百分点。   ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/143ad6b65e904cc8adaa6ebb6164302d~tplv-k3u1fbpfcp-watermark.image?) 作者在实验中也发现了一些有趣的点,比如:指令调优虽然效果比较好,但只适用于指令相关的任务,在聊天机器人上效果并不佳,而聊天机器人更适合用Open Assistant数据集去进行微调。通过指令类数据集的调优更像是提升大模型的推理能力,并不是为聊天而生的。 总之,QLoRA的出现给大家带来一些新的思考,不管是微调还是部署大模型,之后都会变得更加容易。每个人都可以快速利用自己的私有数据进行微调;同时,又能轻松的部署大模型进行推理。 ## 结语 本文针对讲述了参数高效微调方法LoRA、AdaLoRA、QLoRA,下文将对混合高效微调方法MAM Adapter、UniPELT进行讲解。 如果觉得我的文章能够能够给您带来帮助,期待您的点赞收藏加关注\~\~ ================================================ FILE: blog/reference/高性能 LLM 推理框架的设计与实现.md ================================================ - 高性能 LLM 推理框架的设计与实现:https://zhuanlan.zhihu.com/p/682872971 ================================================ FILE: docs/README.md ================================================ ## [LLM 基础](https://github.com/liguodongiot/llm-action/tree/main/docs/llm-base) ## [LLM 面试题](https://github.com/liguodongiot/llm-action/tree/main/docs/llm_interview) ## [LLM 国产化](https://github.com/liguodongiot/llm-action/tree/main/docs/llm_localization) ## [LLM 总结](https://github.com/liguodongiot/llm-action/tree/main/docs/llm_summarize) ================================================ FILE: docs/conda.md ================================================ 安装 - https://docs.anaconda.com/free/miniconda/ - https://repo.anaconda.com/miniconda/ ================================================ FILE: docs/flash-attention/FlashAttention.md ================================================ - https://github.com/Dao-AILab/flash-attention - FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness - FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning Flash Attention的主要目的是加速和节省内存,主要贡献包括: 计算softmax时候不需要全量input数据,可以分段计算; 反向传播的时候,不存储attention matrix (N^2的矩阵),而是只存储softmax归一化的系数。 Online Softmax+Tiling+Recompute Online Softmax Online normalizer calculation for softmax(https://arxiv.org/abs/1805.02867) FlashAttention-2 Flash Decoding https://crfm.stanford.edu/2023/10/12/flashdecoding.html Flash-Decoding 可以显著加快推理过程中的注意力,使长序列的生成速度提高 8 倍。 主要思想是尽可能快地并行加载Key和Value,然后分别重新缩放并组合结果以维持正确的注意力输出。 ================================================ FILE: docs/llm-base/FLOPS.md ================================================ ## FLOPS FLOPS(Floating-point operations per second),每秒浮点运算次数 ================================================ FILE: docs/llm-base/NVIDIA-Nsight-Systems性能分析.md ================================================ # NVIDIA Nsight Systems NVIDIA Nsight Systems是一款低开销性能分析工具,旨在为开发人员提供优化软件所需的洞察力。无偏差的活动数据可在工具中可视化,可帮助用户调查瓶颈,避免推断误报,并以更高的性能提升概率实现优化。用户将能够识别问题,例如 GPU 闲置、不必要的 GPU 同步、CPU 并行化不足,甚至其目标平台的 CPU 和 GPU 中意外昂贵的算法。它旨在跨各种 NVIDIA 平台进行扩展,例如:大型 Tesla 多 GPU x86 服务器、Quadro 工作站、支持 Optimus 的笔记本电脑、配备 Tegra+dGPU 多操作系统的 DRIVE 设备,以及 Jetson。NVIDIA Nsight Systems 甚至可以为 PyTorch 和 TensorFlow 等深度学习框架行为和负载提供宝贵见解;允许用户调整模型和参数,以提高单个或多个 GPU 的整体利用率。 ================================================ FILE: docs/llm-base/README.md ================================================ ## [AI 算法](https://github.com/liguodongiot/llm-action/blob/main/docs/llm-base/ai-algo.md) ## [AI 集群](https://github.com/liguodongiot/llm-action/tree/main/docs/llm-base/ai-cluster) ## [AI 集群通信](https://github.com/liguodongiot/llm-action/tree/main/docs/llm-base/network-communication) ## 其他 - [机器学习中常用的数据类型](https://github.com/liguodongiot/llm-action/blob/main/docs/llm-base/机器学习中常用的数据类型.md) ## 工具 ### nvidia-visual-profiler - nvprof - nvidia-visual-profiler - https://developer.nvidia.com/nvidia-visual-profiler ================================================ FILE: docs/llm-base/a800-env-install.md ================================================ ## GCC 升级 ``` yum update -y yum install -y centos-release-scl yum install -y devtoolset-9 source /opt/rh/devtoolset-9/enable gcc -v ``` ## GPU 驱动安装 ``` chmod +x NVIDIA-Linux-x86_64-525.105.17.run sh NVIDIA-Linux-x86_64-525.105.17.run -no-x-check nvidia-smi ``` GPUDirect 通信矩阵: ``` > nvidia-smi topo --matrix GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7 NIC0 NIC1 NIC2 NIC3 CPU Affinity NUMA Affinity GPU0 X NV8 NV8 NV8 NV8 NV8 NV8 NV8 NODE NODE SYS SYS 0-31,64-95 0 GPU1 NV8 X NV8 NV8 NV8 NV8 NV8 NV8 PIX NODE SYS SYS 0-31,64-95 0 GPU2 NV8 NV8 X NV8 NV8 NV8 NV8 NV8 NODE NODE SYS SYS 0-31,64-95 0 GPU3 NV8 NV8 NV8 X NV8 NV8 NV8 NV8 NODE PIX SYS SYS 0-31,64-95 0 GPU4 NV8 NV8 NV8 NV8 X NV8 NV8 NV8 SYS SYS NODE NODE 32-63,96-127 1 GPU5 NV8 NV8 NV8 NV8 NV8 X NV8 NV8 SYS SYS NODE NODE 32-63,96-127 1 GPU6 NV8 NV8 NV8 NV8 NV8 NV8 X NV8 SYS SYS NODE NODE 32-63,96-127 1 GPU7 NV8 NV8 NV8 NV8 NV8 NV8 NV8 X SYS SYS PIX PIX 32-63,96-127 1 NIC0 NODE PIX NODE NODE SYS SYS SYS SYS X NODE SYS SYS NIC1 NODE NODE NODE PIX SYS SYS SYS SYS NODE X SYS SYS NIC2 SYS SYS SYS SYS NODE NODE NODE PIX SYS SYS X PIX NIC3 SYS SYS SYS SYS NODE NODE NODE PIX SYS SYS PIX X Legend: X = Self SYS = Connection traversing PCIe as well as the SMP interconnect between NUMA nodes (e.g., QPI/UPI) NODE = Connection traversing PCIe as well as the interconnect between PCIe Host Bridges within a NUMA node PHB = Connection traversing PCIe as well as a PCIe Host Bridge (typically the CPU) PXB = Connection traversing multiple PCIe bridges (without traversing the PCIe Host Bridge) PIX = Connection traversing at most a single PCIe bridge NV# = Connection traversing a bonded set of # NVLinks NIC Legend: NIC0: mlx5_0 NIC1: mlx5_1 NIC2: mlx5_2 NIC3: mlx5_3 ``` 开启持久模式: 如果未开启持久模式(Persistence Mode),每次用nvidia-smi查询显卡资源的时候,会等到较长时间才有结果。 ``` nvidia-smi -pm ENABLED # 查询 Persistence Mode 是否开启 nvidia-smi -a nvidia-smi ``` ### 异常解决方案 - **问题**:Centos服务器重启后出现显卡驱动无法使用的情况:NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. - **解决方案**: ``` # 安装dkms修护驱动 > sudo yum install dkms # 查看显卡驱动版本 > ls /usr/src debug kernels nvidia-525.105.17 # 重新安装对应nvidia的驱动模块 > dkms install -m nvidia -v 525.105.17 ``` ## NVIDIA-Fabric Manager 安装 NVIDIA-Fabric Manager服务可以使多A100显卡间通过NVSwitch互联。 要通过NVSwitch互联必须安装与GPU驱动版本对应的NVIDIA-Fabric Manager软件包,否则将无法正常使用实例。 参考:https://www.volcengine.com/docs/6419/73634 ``` wget -c https://developer.download.nvidia.cn/compute/cuda/repos/rhel7/x86_64/nvidia-fabric-manager-525.105.17-1.x86_64.rpm rpm -ivh nvidia-fabric-manager-525.105.17-1.x86_64.rpm ``` ``` wget -c https://developer.download.nvidia.com/compute/cuda/repos/fedora37/x86_64/nvidia-fabric-manager-devel-525.105.17-1.x86_64.rpm rpm -ivh nvidia-fabric-manager-devel-525.105.17-1.x86_64.rpm ``` 启动NVIDIA-Fabric Manager: ``` # 启动Fabric Manager服务,实现NVSwitch互联 sudo systemctl restart nvidia-fabricmanager # 查看Fabric Manager服务是否正常启动,回显active(running)表示启动成功。 sudo systemctl status nvidia-fabricmanager # 配置Fabric Manager服务随实例开机自启动。 sudo systemctl enable nvidia-fabricmanager ``` ## CUDA 安装 ``` mkdir -p /home/local/cuda-11.7 sudo ln -s /home/local/cuda-11.7 /usr/local/cuda-11.7 wget https://developer.download.nvidia.com/compute/cuda/11.7.0/local_installers/cuda_11.7.0_515.43.04_linux.run sudo sh cuda_11.7.0_515.43.04_linux.run # 配置环境变量 export PATH="/usr/local/cuda-11.7/bin:$PATH" export LD_LIBRARY_PATH="/usr/local/cuda-11.7/lib64:$LD_LIBRARY_PATH" nvcc -V ``` ## openssl 升级 ``` yum install -y zlib-devel.x86_64 ``` ``` mkdir -p /home/local/openssl ln -s /home/local/openssl /usr/local/openssl tar -zxvf openssl-1.1.1t.tar.gz cd openssl-1.1.1t/ ./config --prefix=/usr/local/openssl shared zlib make depend sudo make sudo make install sudo ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl echo "/usr/local/openssl/lib" >> /etc/ld.so.conf ldconfig -v ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/lib/libssl.so.1.1 ln -s /usr/local/openssl/lib/libcrypto.so.1.1 /usr/lib/libcrypto.so.1.1 ``` ## Python3.10 安装 ``` yum install -y libffi-devel bzip2-devel yum install sqlite-devel -y ``` ``` mkdir -p /home/local/py310 ln -s /home/local/py310 /usr/local/py310 tar -xvf Python-3.10.10.tgz ./configure --prefix=/usr/local/py310 --with-openssl=/usr/local/openssl --with-openssl-rpath=no make sudo make install sudo ln -s /usr/local/py310/bin/python3.10 /usr/bin/python3.10 sudo ln -s /usr/local/py310/bin/pip3.10 /usr/bin/pip3.10 # sudo ln -s /usr/local/py310/bin/pip3.10 /usr/bin/pip pip3.10 install virtualenv -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn sudo ln -s /usr/local/py310/bin/virtualenv /usr/bin/virtualenv mkdir -p /home/guodong.li/virtual-venv cd /home/guodong.li/virtual-venv virtualenv -p /usr/bin/python3.10 llama-venv-py310-cu117 source /home/guodong.li/virtual-venv/llama-venv-py310-cu117/bin/activate ``` 配置pip源: ``` mkdir ~/.pip cd ~/.pip vim ~/.pip/pip.conf [global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple [install] trusted-host = https://pypi.tuna.tsinghua.edu.cn ``` ## miniconda安装 文档:https://docs.conda.io/en/latest/miniconda.html#linux-installers 安装: ``` wget -c https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Linux-x86_64.sh bash Miniconda3-py310_23.3.1-0-Linux-x86_64.sh ``` 配置清华源: ``` conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main ``` 安装包: ``` # 最常见的源是conda-forge,一个开源的代码库,许多软件通过这个源来安装。 conda install nodejs=16.6.1 -c conda-forge ``` ## NCCL 安装 ``` tar xvf nccl_2.14.3-1+cuda11.7_x86_64.txz cd nccl_2.14.3-1+cuda11.7_x86_64/ sudo cp -r include/* /usr/local/cuda-11.7/include/ sudo cp -r lib/* /usr/local/cuda-11.7/lib64/ export LD_LIBRARY_PATH="/usr/local/cuda-11.7/lib64:$LD_LIBRARY_PATH" ``` ## cuDNN 安装 ``` tar -xvf cudnn-linux-x86_64-8.8.1.3_cuda11-archive.tar.xz cd cudnn-linux-x86_64-8.8.1.3_cuda11-archive sudo cp include/cudnn*.h /usr/local/cuda-11.7/include sudo cp -P lib/libcudnn* /usr/local/cuda-11.7/lib64/ sudo chmod a+r /usr/local/cuda-11.7/include/cudnn*.h /usr/local/cuda-11.7/lib64/libcudnn* ``` ## Python 库安装 ### Pytorch ``` pip install torch-1.13.1+cu117-cp310-cp310-linux_x86_64.whl pip install torchvision-0.14.1+cu117-cp310-cp310-linux_x86_64.whl # pip install torch-scatter torch-sparse torch-cluster torch-geometric ``` ``` python -c "import torch; print(torch.cuda.is_available())" ``` ### Transformers ``` cd transformers-20230327 git checkout 0041be5 pip install . ``` ### Deepspeed... ``` pip install deepspeed==0.8.0 pip install accelerate pip install tensorboardX ``` ### 安装Apex ``` git clone https://github.com/NVIDIA/apex.git cd apex git checkout 22.04-dev pip install -v --disable-pip-version-check --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext" ./ ``` ### 安装mpi4py ``` yum -y install openmpi-devel export CC=/usr/lib64/openmpi/bin/mpicc pip install mpi4py ``` ## pdsh安装 ``` tar xf pdsh-2.31.tar.gz cd /data/nfs/llm/pkg/pdsh-pdsh-2.31 ./configure \ --prefix=/home/local/pdsh \ --with-ssh \ --with-machines=/home/local/pdsh/machines \ --with-dshgroups=/home/local/pdsh/group \ --with-rcmd-rank-list=ssh \ --with-exec && \ make && \ make install ln -s /home/local/pdsh /usr/local/pdsh ll /usr/local/pdsh/bin/ # 将pdsh的所有命令追加到环境变量中 echo "export PATH=/home/local/pdsh/bin:$PATH" >> /etc/profile source /etc/profile pdsh -V ``` ## nvidia-docker 安装 ``` wget https://download.docker.com/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo wget https://nvidia.github.io/nvidia-docker/centos7/x86_64/nvidia-docker.repo -O /etc/yum.repos.d/nvidia-docker.repo yum install -y epel-release # 安装docker yum install -y docker-ce nvidia-docker2 systemctl enable docker # 重启docker sudo systemctl restart docker docker info ``` --- 修改Docker配置(`/etc/docker/daemon.json`): ``` { "data-root": "/home/docker", "runtimes": { "nvidia": { "path": "nvidia-container-runtime", "runtimeArgs": [] } } } ``` 重启docker服务: ``` systemctl daemon-reload systemctl restart docker ``` --- 关闭 selinux 安全系统: ``` 1. 临时关闭(setenforce 0),系统重启后,恢复启动。 setenforce 0 查看: getenforce 2. 永久关闭,修改文件 /etc/selinux/config SELINUX=disabled 保存后,重启 reboot ``` ### 镜像导入及归档 ``` docker save -o tritonserver.tar runoob/ubuntu:v3 docker load --input tritonserver.tar ``` 常见docker命令参考该[文档](https://juejin.cn/post/7016238524286861325)。 ================================================ FILE: docs/llm-base/ai-algo.md ================================================ ## CodeGeeX - CodeGeeX: A Pre-Trained Model for Code Generation with Multilingual Evaluations on HumanEval-X - https://github.com/THUDM/CodeGeeX ## CodeX - Evaluating Large Language Models Trained on Code - https://github.com/openai/human-eval ## Transformer - 哈佛的NLP团队实现:https://github.com/harvardnlp/annotated-transformer ## Bert ## GPT2 - [GPT2](https://github.com/openai/gpt-2) - Language Models are Unsupervised Multitask Learners ## Bloom ## LLaMA / LLaMA2 ## ChatGLM ## ChatGLM2 ================================================ FILE: docs/llm-base/autoregressive-lm-decoding-methods.md ================================================ 近年来,以Transformers架构为基础的大模型正在席卷整个AI界。Transformer 开创了继 MLP 、CNN和 RNN之后的第四大类模型。而基于Transformer结构的模型又可以分为Encoder-only、Decoder-only、Encoder-Decoder这三类,具体如下图所示: ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/376fd2d6da6140288843ca5c528226d4~tplv-k3u1fbpfcp-watermark.image?) - 仅编码器架构(Encoder-only):自编码模型(破坏一个句子,然后让模型去预测或填补),更擅长理解类的任务,例如:文本分类、实体识别、关键信息抽取等。典型代表有:Bert、RoBERTa等。 - 仅解码器架构(Decoder-only):自回归模型(将解码器自己当前步的输出加入下一步的输入,解码器融合所有已经输入的向量来输出下一个向量,所以越往后的输出考虑了更多输入),更擅长生成类的任务,例如:文本生成。典型代表有:GPT系列、LLaMA、OPT、Bloom等。 - 编码器-解码器架构(Encoder-Decoder):序列到序列模型(编码器的输出作为解码器的输入),主要用于基于条件的生成任务,例如:翻译,概要等。典型代表有:T5、BART、GLM等。 ```python # generation_utils.py def generate( self, inputs: Optional[torch.Tensor] = None, max_length: Optional[int] = None, min_length: Optional[int] = None, do_sample: Optional[bool] = None, early_stopping: Optional[bool] = None, num_beams: Optional[int] = None, temperature: Optional[float] = None, top_k: Optional[int] = None, top_p: Optional[float] = None, typical_p: Optional[float] = None, repetition_penalty: Optional[float] = None, bad_words_ids: Optional[Iterable[int]] = None, force_words_ids: Optional[Union[Iterable[int], Iterable[Iterable[int]]]] = None, bos_token_id: Optional[int] = None, pad_token_id: Optional[int] = None, eos_token_id: Optional[int] = None, length_penalty: Optional[float] = None, no_repeat_ngram_size: Optional[int] = None, encoder_no_repeat_ngram_size: Optional[int] = None, num_return_sequences: Optional[int] = None, max_time: Optional[float] = None, max_new_tokens: Optional[int] = None, decoder_start_token_id: Optional[int] = None, use_cache: Optional[bool] = None, num_beam_groups: Optional[int] = None, diversity_penalty: Optional[float] = None, prefix_allowed_tokens_fn: Optional[Callable[[int, torch.Tensor], List[int]]] = None, logits_processor: Optional[LogitsProcessorList] = LogitsProcessorList(), renormalize_logits: Optional[bool] = None, stopping_criteria: Optional[StoppingCriteriaList] = StoppingCriteriaList(), constraints: Optional[List[Constraint]] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, output_scores: Optional[bool] = None, return_dict_in_generate: Optional[bool] = None, forced_bos_token_id: Optional[int] = None, forced_eos_token_id: Optional[int] = None, remove_invalid_values: Optional[bool] = None, synced_gpus: Optional[bool] = False, exponential_decay_length_penalty: Optional[Tuple[Union[int, float]]] = None, **model_kwargs, ) -> Union[GreedySearchOutput, SampleOutput, BeamSearchOutput, BeamSampleOutput, torch.LongTensor] ``` 目前最常用的解码方法,主要有贪心搜索 (Greedy search) 、波束搜索 (Beam search) 、Top-K 采样 (Top-K sampling) 以及 Top-p 采样 (Top-p sampling)。 ### 贪心搜索 贪心搜索在每个时间步 $t$ 都简单地选择概率最高的词作为当前输出词: $w_t = argmax_{w}P(w | w_{1:t-1})$ ,如下图所示。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/09c0593a9a89405a8945d37a27da735f~tplv-k3u1fbpfcp-watermark.image?) 从单词 $\text{“The”}$ 开始,算法在第一步贪心地选择条件概率最高的词 $\text{“nice”}$ 作为输出,依此往后。最终生成的单词序列为 $(\text{“The”}, \text{“nice”}, \text{“woman”})$,其联合概率为 $0.5 \times 0.4 = 0.2$。 下面,我们输入文本序列 $(\text{“I”}, \text{“enjoy”}, \text{“walking”}, \text{“with”}, \text{“my”}, \text{“cute”}, \text{“dog”})$ 给 GPT2 模型,让模型生成下文。 贪心搜索的主要缺点是它错过了隐藏在低概率词后面的高概率词,如上图所示: 条件概率为 $0.9$ 的单词 $\text{“has”}$ 隐藏在单词 $\text{“dog”}$ 后面,而 $\text{“dog”}$ 因为在 `t=1` 时条件概率值只排第二所以未被选择,因此贪心搜索会错过序列 $\text{“The”}, \text {“dog”}, \text{“has”}$ 。 ### 波束搜索 波束搜索通过在每个时间步保留最可能的 num_beams 个词,并从中最终选择出概率最高的序列来降低丢失潜在的高概率序列的风险。以 num_beams=2 为例: ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d10bf0ef53384c9fa7cf533132257504~tplv-k3u1fbpfcp-watermark.image?) 在时间步 1,除了最有可能的假设 $(\text{“The”}, \text{“nice”})$,波束搜索还跟踪第二可能的假设 $(\text{“The”}, \text{“dog”})$。在时间步 2,波束搜索发现序列 $(\text{“The”}, \text{“dog”}, \text{“has”})$ 概率为$0.36$,比 $(\text{“The”}, \text{“nice”}, \text{“woman”})$ 的 $0.2$ 更高。太棒了,在我们的例子中它已经找到了最有可能的序列! 波束搜索一般都会找到比贪心搜索概率更高的输出序列,但仍不保证找到全局最优解。 让我们看看如何在 `transformers` 中使用波束搜索。我们设置 `num_beams > 1` 和 `early_stopping=True` 以便在所有波束达到 EOS 时直接结束生成。 虽然结果比贪心搜索更流畅,但输出中仍然包含重复。一个简单的补救措施是引入 *n-grams* (即连续 n 个词的词序列) 惩罚。最常见的 *n-grams* 惩罚是确保每个 *n-gram* 都只出现一次,方法是如果看到当前候选词与其上文所组成的 *n-gram* 已经出现过了,就将该候选词的概率设置为 0。 我们可以通过设置 `no_repeat_ngram_size=2` 来试试,这样任意 *2-gram* 不会出现两次: 不错,看起来好多了!我们看到生成的文本已经没有重复了。但是,*n-gram* 惩罚使用时必须谨慎,如一篇关于 *纽约* 这个城市的文章就不应使用 *2-gram* 惩罚,否则,城市名称在整个文本中将只出现一次! 波束搜索的另一个重要特性是我们能够比较概率最高的几个波束,并选择最符合我们要求的波束作为最终生成文本。 在 `transformers` 中,我们只需将参数 `num_return_sequences` 设置为需返回的概率最高的波束的数量,记得确保 `num_return_sequences <= num_beams`! 如我们所见,五个波束彼此之间仅有少量差别 —— 这在仅使用 5 个波束时不足为奇。 **开放域文本生成**的研究人员最近提出了几个理由来说明对该领域而言**波束搜索可能不是最佳方案**: 在机器翻译或摘要等任务中,因为所需生成的长度或多或少都是可预测的,所以波束搜索效果比较好。但开放域文本生成情况有所不同,其输出文本长度可能会有很大差异,如对话和故事生成的输出文本长度就有很大不同。 我们已经看到**波束搜索已被证明存在重复生成的问题**。在故事生成这样的场景中,很难用 n-gram 或其他惩罚来控制,因为在“不重复”和最大可重复 n-grams 之间找到一个好的折衷需要大量的微调。 高质量的人类语言并不遵循最大概率法则。换句话说,作为人类,我们希望生成的文本能让我们感到惊喜,而可预测的文本使人感觉无聊。下面这个概率图,很好地展示了这一点,从图中可以看出人类文本带来的惊喜度比波束搜索好不少。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/49c735f7e4e341f486b1a6e3dfc54015~tplv-k3u1fbpfcp-watermark.image?) ### 采样 在其最基本的形式中,采样意味着根据当前条件概率分布随机选择输出词 $w_t$: $w_t∼P(w∣w_{1:t−1})$ 继续使用上文中的例子,下图可视化了使用采样生成文本的过程。 ![sampling search](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/89462fc4f9d048eabdff0565ec79b018~tplv-k3u1fbpfcp-zoom-1.image) 很明显,使用采样方法时文本生成本身不再是确定性的。单词 $\text{“car”}$ 从条件概率分布 $P(w | \text{“The”})$ 中采样而得,而 $\text{“drives”}$ 则采样自 $P(w | \text{“The”}, \text{“car”})$。 在 `transformers` 中,我们设置 `do_sample=True` 并通过设置 `top_k=0` 停用 *Top-K* 采样 (稍后详细介绍)。在下文中,为便于复现,我们会固定 `random_seed=0`,但你可以在自己的模型中随意更改 `random_seed`。 ``` # set seed to reproduce results. Feel free to change the seed though to get different results tf.random.set_seed(0) # activate sampling and deactivate top_k by setting top_k sampling to 0 sample_output = model.generate( input_ids, do_sample=True, max_length=50, top_k=0 ) print("Output:\n" + 100 * '-') print(tokenizer.decode(sample_output[0], skip_special_tokens=True)) ``` 有意思!生成的文本看起来不错 - 但仔细观察会发现它不是很连贯。*3-grams* *new hand sense* 和 *local batte harness* 非常奇怪,看起来不像是人写的。这就是对单词序列进行采样时的大问题: 模型通常会产生不连贯的乱码,*参见* [Ari Holtzman 等人 (2019)](https://arxiv.org/abs/1904.09751) 的论文。 缓解这一问题的一个技巧是通过降低所谓的 [softmax](https://en.wikipedia.org/wiki/Softmax_function#Smooth_arg_max) 的“温度”使分布 $P(w|w_{1:t-1})$ 更陡峭。而降低“温度”,本质上是增加高概率单词的似然并降低低概率单词的似然。 将温度应用到于我们的例子中后,结果如下图所示。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/841b6166b2d5432c8bdb92e94e181e5a~tplv-k3u1fbpfcp-watermark.image?) $t=1$ 时刻单词的条件分布变得更加陡峭,几乎没有机会选择单词 $\text{“car”}$ 了。 让我们看看如何通过设置 `temperature=0.7` 来冷却生成过程: 好,奇怪的 n-gram 变少了,现在输出更连贯了!虽然温度可以使分布的随机性降低,但极限条件下,当“温度”设置为 $0$ 时,温度缩放采样就退化成贪心解码了,因此会遇到与贪心解码相同的问题。 ### Top-K 采样 [Fan 等人 (2018)](https://arxiv.org/pdf/1805.04833.pdf) 的论文介绍了一种简单但非常强大的采样方案,称为 ***Top-K*** 采样。在 *Top-K* 采样中,概率最大的 *K* 个词会被选出,然后这 *K* 个词的概率会被重新归一化,最后就在这重新被归一化概率后的 *K* 个词中采样。 GPT2 采用了这种采样方案,这也是它在故事生成这样的任务上取得成功的原因之一。 我们将上文例子中的候选单词数从 3 个单词扩展到 10 个单词,以更好地说明 *Top-K* 采样。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c944881091f1485b8dfeb0ef0939d4b2~tplv-k3u1fbpfcp-watermark.image?) 设 $K = 6$,即我们将在两个采样步的采样池大小限制为 6 个单词。我们定义 6 个最有可能的词的集合为 $V_{\text{top-K}}$。在第一步中,$V_{\text{top-K}}$ 仅占总概率的大约三分之二,但在第二步,它几乎占了全部的概率。同时,我们可以看到在第二步该方法成功地消除了那些奇怪的候选词 $(\text{“not”}, \text{“the”}, \text{“small”}, \text{“told”})$。 我们以设置 `top_k=50` 为例看下如何在 `transformers` 库中使用 *Top-K*: 相当不错!该文本可以说是迄今为止生成的最 "*像人*" 的文本。现在还有一个问题,*Top-K* 采样不会动态调整从需要概率分布 $P(w|w_{1:t-1})$ 中选出的单词数。这可能会有问题,因为某些分布可能是非常尖锐 (上图中右侧的分布),而另一些可能更平坦 (上图中左侧的分布),所以**对不同的分布使用同一个绝对数 *K* 可能并不普适**。 在 $t=1$ 时,*Top-K* 将 $(\text{“people”}, \text{“big”}, \text{“house”}, \text{“cat”})$ 排出了采样池,而这些词似乎是合理的候选词。另一方面,在$t=2$ 时,该方法却又把不太合适的 $(\text{“down”}, \text{“a”})$ 纳入了采样池。因此,将采样池限制为固定大小 *K* 可能会在分布比较尖锐的时候产生胡言乱语,而在分布比较平坦的时候限制模型的创造力。这一发现促使 [Ari Holtzman 等人 (2019)](https://arxiv.org/abs/1904.09751) 发明了 **Top-p**- 或 **核**- 采样。 ### Top-p (核) 采样 在 *Top-p* 中,采样不只是在最有可能的 *K* 个单词中进行,而是在累积概率超过概率 *p* 的最小单词集中进行。然后在这组词中重新分配概率质量。这样,词集的大小 (*又名* 集合中的词数) 可以根据下一个词的概率分布动态增加和减少。好吧,说的很啰嗦,一图胜千言。 ![Top p sampling](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4b3365fcc0c044419a0a4d9f2c78adde~tplv-k3u1fbpfcp-zoom-1.image) 假设 $p=0.92$,*Top-p* 采样对单词概率进行降序排列并累加,然后选择概率和首次超过 $p=92%$ 的单词集作为采样池,定义为 $V_{\text{top-p}}$。在 $t=1$ 时 $V_{\text{top-p}}$ 有 9 个词,而在 $t=2$ 时它只需要选择前 3 个词就超过了 92%。其实很简单吧!可以看出,在单词比较不可预测时,它保留了更多的候选词,*如* $P(w | \text{“The”})$,而当单词似乎更容易预测时,只保留了几个候选词,*如* $P(w | \text{“The”}, \text{“car”})$。 好的,是时候看看它在 `transformers` 里怎么用了!我们可以通过设置 `0 < top_p < 1` 来激活 *Top-p* 采样: 太好了,这看起来跟人类写的差不多了,虽然还不算完全是。 虽然从理论上讲, *Top-p* 似乎比 *Top-K* 更优雅,但这两种方法在实践中都很有效。 *Top-p* 也可以与 *Top-K* 结合使用,这样可以避免排名非常低的词,同时允许进行一些动态选择。 最后,如果想要获得多个独立采样的输出,我们可以 *再次* 设置参数 `num_return_sequences > 1`: 很酷,现在你拥有了所有可以在 `transformers` 里用模型来帮你写故事的工具了! ### 总结 在开放域语言生成场景中,作为最新的解码方法, *top-p* 和 *top-K* 采样与传统的 *贪心* 和 *波束* 搜索相比,似乎能产生更流畅的文本。但,最近有更多的证据表明 *贪心* 和 *波束* 搜索的明显缺陷主要是生成重复的单词序列(是由模型 (特别是模型的训练方式) 引起的,而不是解码方法), 参见 [Welleck 等人 (2019)](https://arxiv.org/pdf/1908.04319.pdf) 的论文。此外,如 [Welleck 等人 (2020)](https://arxiv.org/abs/2002.02492) 的论文所述,看起来 *top-K* 和 *top-p* 采样也会产生重复的单词序列。 在 [Welleck 等人 (2019)](https://arxiv.org/pdf/1908.04319.pdf) 的论文中,作者表明,根据人类评估,在调整训练目标后,波束搜索相比 *Top-p* 采样能产生更流畅的文本。 开放域语言生成是一个快速发展的研究领域,而且通常情况下这里没有放之四海而皆准的方法,因此必须了解哪种方法最适合自己的特定场景。 好的方面是, *你* 可以在 `transfomers` 中尝试所有不同的解码方法 🤗。 以上是对如何在 `transformers` 中使用不同的解码方法以及开放域语言生成的最新趋势的简要介绍。 `generate` 方法还有几个正文未提及的参数,这里我们简要解释一下它们! - `min_length` 用于强制模型在达到 `min_length` 之前不生成 EOS。这在摘要场景中使用得比较多,但如果用户想要更长的文本输出,也会很有用。 - `repetition_penalty` 可用于对生成重复的单词这一行为进行惩罚。它首先由 [Keskar 等人 (2019)](https://arxiv.org/abs/1909.05858) 引入,在 [Welleck 等人 (2019)](https://arxiv.org/pdf/1908.04319.pdf) 的工作中,它是训练目标的一部分。它可以非常有效地防止重复,但似乎对模型和用户场景非常敏感,其中一个例子见 Github 上的 [讨论](https://github.com/huggingface/transformers/pull/2303)。 - `attention_mask` 可用于屏蔽填充符。 - `pad_token_id`、`bos_token_id`、`eos_token_id`: 如果模型默认没有这些 token,用户可以手动选择其他 token id 来表示它们。 参考文档: - [如何生成文本: 通过 Transformers 用不同的解码方法生成文本](https://huggingface.co/blog/zh/how-to-generate) - [How to generate text: using different decoding methods for language generation with Transformers](https://huggingface.co/blog/how-to-generate) Huggingface Transformers 库自回归模型文本生成类GenerationMixin的generate() 方法参数详解 ================================================ FILE: docs/llm-base/dcgmi.md ================================================ 下表列出了不同 GPU 产品上支持的功能。 | Feature Group | Tesla | Titan | Quadro | GeForce | | --- | --- | --- | --- | --- | | Field Value Watches (GPU metrics) | X | X | X | X | | Configuration Management | X | X | X | X | | Active Health Checks (GPU subsystems) | X | X | X | X | | Job Statistics | X | X | X | X | | Topology | X | X | X | X | | Introspection | X | X | X | X | | Policy Notification | X | | | | | GPU Diagnostics (Diagnostic Levels - 1, 2, 3) | All Levels | Level 1 | Level 1 | Level 1 | ## dcgmi ``` > dcgmi -h Usage: dcgmi dcgmi subsystem dcgmi -v Flags: -v vv Get DCGMI version information subsystem The desired subsystem to be accessed. Subsystems Available: topo GPU Topology [dcgmi topo -h for more info] (GPU拓扑) stats Process Statistics [dcgmi stats -h for more info] (过程统计) diag System Validation/Diagnostic [dcgmi diag –h for more info] (系统验证/诊断) policy Policy Management [dcgmi policy –h for more info] (策略管理) health Health Monitoring [dcgmi health –h for more info] (健康监测) config Configuration Management [dcgmi config –h for more info] (配置管理) group GPU Group Management [dcgmi group –h for more info] (GPU组管理) fieldgroup Field Group Management [dcgmi fieldgroup –h for more info] (Field组管理) discovery Discover GPUs on the system [dcgmi discovery –h for more info] (发现系统上的 GPU) introspect Gather info about DCGM itself [dcgmi introspect –h for more info] (收集有关 DCGM 本身的信息) nvlink Displays NvLink link statuses and error counts [dcgmi nvlink –h for more info] (显示 NvLink 链接状态和错误计数) dmon Stats Monitoring of GPUs [dcgmi dmon –h for more info] (GPU 统计监控) modules Control and list DCGM modules (控制和列出 DCGM 模块) profile Control and list DCGM profiling metrics (控制和列出 DCGM 分析指标) set Configure hostengine settings (配置hostengine设置) -- ignore_rest Ignores the rest of the labeled arguments following this flag. --version Displays version information and exits. -h --help Displays usage information and exits. Please email dcgm-support@nvidia.com with any questions, bug reports, etc. NVIDIA Datacenter GPU Management Interface ``` ``` > dcgmi -v Version : 3.1.8 Build ID : 8 Build Date : 2023-04-27 Build Type : Release Commit ID : c36ef145e4e71092fc106a80566758b1faf6115e Branch Name : rel_dcgm_3_1 CPU Arch : x86_64 Build Platform : Linux 4.15.0-180-generic #189-Ubuntu SMP Wed May 18 14:13:57 UTC 2022 x86_64 CRC : fd25da813d4871545eba7aaaf653fcba Hostengine build info: Version : 3.1.8 Build ID : 8 Build Date : 2023-04-27 Build Type : Release Commit ID : c36ef145e4e71092fc106a80566758b1faf6115e Branch Name : rel_dcgm_3_1 CPU Arch : x86_64 Build Platform : Linux 4.15.0-180-generic #189-Ubuntu SMP Wed May 18 14:13:57 UTC 2022 x86_64 CRC : fd25da813d4871545eba7aaaf653fcba ``` ## dcgmi topo ``` > dcgmi topo -h topo -- Used to find the topology of GPUs on the system. Usage: dcgmi topo dcgmi topo --host -g -j dcgmi topo --host --gpuid -j Flags: -g --group groupId The group ID to query. --host IP/FQDN Connects to specified IP or fully-qualified domain name. To connect to a host engine that was started with -d (unix socket), prefix the unix socket filename with 'unix://'. [default = localhost] -h --help Displays usage information and exits. --gpuid gpuId The GPU ID to query. -j --json Print the output in a json format -- --ignore_rest Ignores the rest of the labeled arguments following this flag. NVIDIA Datacenter GPU Management Interface ``` ``` > dcgmi topo -g 0 -j { "body" : { "CPU Core Affinity" : { "value" : "0 - 127" }, "NUMA Optimal" : { "value" : "False" }, "Worst Path" : { "value" : "Connected via a CPU-level link" } }, "header" : [ "Topology Information", "DCGM_ALL_SUPPORTED_GPUS" ] } ``` ``` > dcgmi topo --gpuid 1 -j { "body" : { "CPU Core Affinity" : { "value" : "0 - 31, 64 - 95" }, "To GPU 0" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 2" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 3" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 4" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 5" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 6" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 7" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" } }, "header" : [ "Topology Information", "GPU ID: 1" ] } ``` ``` dcgmi topo --gpuid 7 -j { "body" : { "CPU Core Affinity" : { "value" : "32 - 63, 96 - 127" }, "To GPU 0" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 1" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 2" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 3" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 4" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 5" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" }, "To GPU 6" : { "overflow" : [ "Connected via eight NVLINKs (Links: 0, 1, 2, 3, 4, 5, 6, 7)" ], "value" : "Connected via a CPU-level link" } }, "header" : [ "Topology Information", "GPU ID: 7" ] } ``` ## dcgmi stats ``` > dcgmi stats -h stats -- Used to view process statistics. Usage: dcgmi stats dcgmi stats --host -g -e -u <> -m <> dcgmi stats --host -g -d dcgmi stats --host -g -p -v dcgmi stats --host -g -s dcgmi stats --host -x dcgmi stats --host -j -v --host -r -v dcgmi stats --host -a -v Flags: -g --group groupId The GPU group to query on the specified host. --host IP/FQDN Connects to specified IP or fully-qualified domain name. To connect to a host engine that was started with -d (unix socket), prefix the unix socket filename with 'unix://'. [default = localhost] -p --pid pid View statistics for the specified pid. -e --enable Enable system watches and start recording information. -d --disable Disable system watches and stop recording information. -s --jstart job id Start recording job statistics. -x --jstop job id Stop recording job statistics. -j --job job id Display job statistics. -r --jremove job id Remove job statistics. -a --jremoveall Remove all job statistics. -h --help Displays usage information and exits. -v --verbose Show process information for each GPU. -u --update-interval How often to update the underlying job stats in ms. -m --max-keep-age How long to retain job stats data for in seconds. This should be longer than your job/process duration. -- --ignore_rest Ignores the rest of the labeled arguments following this flag. Process Statistics Information: -- Execution Stats -- Start Time (*) - Process start time End Time (*) - Process end time Total Execution Time (*) - Total execution time in seconds No. Conflicting Processes (*) - Number of other processes that ran Conflicting Compute PID - PID of conflicting compute process Conflicting Graphics PID - PID of conflicting graphics process -- Performance Stats -- Energy Consumed - Total energy consumed during process in joules Max GPU Memory Used (*) - Maximum amount of GPU memory used in bytes SM Clock - Statistics for SM clocks(s) in MHz Memory Clock - Statistics for memory clock(s) in MHz SM Utilization - Utilization of the GPU's SMs in percent Memory Utilization - Utilization of the GPU's memory in percent PCIe Rx Bandwidth - PCIe bytes read from the GPU PCIe Tx Bandwidth - PCIe bytes written to the GPU -- Event Stats -- Single Bit ECC Errors - Number of ECC single bit errors that occurred Double Bit ECC Errors - Number of ECC double bit errors that occurred PCIe Replay Warnings - Number of PCIe replay warnings Critical XID Errors - Number of critical XID Errors XID - Time of XID error in since start of process -- Slowdown Stats -- Power - Runtime % at reduced clocks due to power violation Thermal - Runtime % at reduced clocks due to thermal limit Reliability - Runtime % at reduced clocks due to reliability limit Board Limit - Runtime % at reduced clocks due to board's voltage limit Low Utilization - Runtime % at reduced clocks due to low utilization Sync Boost - Runtime % at reduced clocks due to sync boost (*) Represents a process statistic. Otherwise device statistic during process lifetime listed. NVIDIA Datacenter GPU Management Interface ``` ## dcgmi discovery 验证是否能够找到 GPU 设备 ``` > dcgmi discovery -l 8 GPUs found. +--------+----------------------------------------------------------------------+ | GPU ID | Device Information | +--------+----------------------------------------------------------------------+ | 0 | Name: NVIDIA H800 | | | PCI Bus ID: 00000000:18:00.0 | | | Device UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c | +--------+----------------------------------------------------------------------+ | 1 | Name: NVIDIA H800 | | | PCI Bus ID: 00000000:3E:00.0 | | | Device UUID: GPU-f5046fa5-3db4-45e8-870a-dc1376becaa5 | +--------+----------------------------------------------------------------------+ | 2 | Name: NVIDIA H800 | | | PCI Bus ID: 00000000:51:00.0 | | | Device UUID: GPU-9de407ad-ba9c-af12-ce09-65828829a67c | +--------+----------------------------------------------------------------------+ | 3 | Name: NVIDIA H800 | | | PCI Bus ID: 00000000:65:00.0 | | | Device UUID: GPU-b54d703a-dee5-a9da-aeb9-465003acdd4b | +--------+----------------------------------------------------------------------+ | 4 | Name: NVIDIA H800 | | | PCI Bus ID: 00000000:98:00.0 | | | Device UUID: GPU-09c6e33a-ffcf-b330-e68b-e1e9f745eae6 | +--------+----------------------------------------------------------------------+ | 5 | Name: NVIDIA H800 | | | PCI Bus ID: 00000000:BD:00.0 | | | Device UUID: GPU-9a8ef0b8-9816-459d-fa13-cda74cf19d37 | +--------+----------------------------------------------------------------------+ | 6 | Name: NVIDIA H800 | | | PCI Bus ID: 00000000:CF:00.0 | | | Device UUID: GPU-70c5b9a8-82a3-4199-d7f5-adb9186459eb | +--------+----------------------------------------------------------------------+ | 7 | Name: NVIDIA H800 | | | PCI Bus ID: 00000000:E2:00.0 | | | Device UUID: GPU-474d838c-171f-d249-4f45-bbc01a8eb74a | +--------+----------------------------------------------------------------------+ 0 NvSwitches found. +-----------+ | Switch ID | +-----------+ +-----------+ ``` ## dcgmi group ``` > dcgmi group -h group -- Used to create and maintain groups of GPUs. Groups of GPUs can then be uniformly controlled through other DCGMI subsystems. Usage: dcgmi group dcgmi group --host -l -j dcgmi group --host -c --default --defaultnvswitches dcgmi group --host -c -a dcgmi group --host -d dcgmi group --host -g -i -j dcgmi group --host -g -a dcgmi group --host -g -r Flags: --host IP/FQDN Connects to specified IP or fully-qualified domain name. To connect to a host engine that was started with -d (unix socket), prefix the unix socket filename with 'unix://'. [default = localhost] -l --list List the groups that currently exist for a host. -d --delete groupId Delete a group on the remote host. -c --create groupName Create a group on the remote host. -h --help Displays usage information and exits. -i --info Display the information for the specified group ID. -r --remove entityId Remove device(s) from group. (csv gpuIds, or entityIds like gpu:0,nvswitch:994) -a --add entityId Add device(s) to group. (csv gpuIds or entityIds simlar to gpu:0, instance:1, compute_instance:2, nvswitch:994) --default Adds all available GPUs to the group being created. --defaultnvswitches Adds all available NvSwitches to the group being created. -j --json Print the output in a json format -- --ignore_rest Ignores the rest of the labeled arguments following this flag. NVIDIA Datacenter GPU Management Interface ``` ``` dcgmi group -l +-------------------+----------------------------------------------------------+ | GROUPS | | 2 groups found. | +===================+==========================================================+ | Groups | | | -> 0 | | | -> Group ID | 0 | | -> Group Name | DCGM_ALL_SUPPORTED_GPUS | | -> Entities | GPU 0, GPU 1, GPU 2, GPU 3, GPU 4, GPU 5, GPU 6, GPU 7 | | -> 1 | | | -> Group ID | 1 | | -> Group Name | DCGM_ALL_SUPPORTED_NVSWITCHES | | -> Entities | None | +-------------------+----------------------------------------------------------+ ``` ``` > dcgmi group -c GPU_Group_Demo Successfully created group "GPU_Group_Demo" with a group ID of 18 > dcgmi group -g 18 -a 0,7 Add to group operation successful. > dcgmi group -g 0 -i +-------------------+----------------------------------------------------------+ | GROUP INFO | +===================+==========================================================+ | 0 | | | -> Group ID | 0 | | -> Group Name | DCGM_ALL_SUPPORTED_GPUS | | -> Entities | GPU 0, GPU 1, GPU 2, GPU 3, GPU 4, GPU 5, GPU 6, GPU 7 | +-------------------+----------------------------------------------------------+ > dcgmi group -g 18 -i +-------------------+----------------------------------------------------------+ | GROUP INFO | +===================+==========================================================+ | 18 | | | -> Group ID | 18 | | -> Group Name | GPU_Group_Demo | | -> Entities | GPU 0, GPU 7 | +-------------------+----------------------------------------------------------+ ``` ## dcgmi dmon 用于监控 GPU 及其统计数据 ``` > dcgmi dmon --help dmon -- Used to monitor GPUs and their stats. Usage: dcgmi dmon dcgmi dmon -i -g -f -e -d -c -l Flags: --host IP/FQDN Connects to specified IP or fully-qualified domain name. To connect to a host engine that was started with -d (unix socket), prefix the unix socket filename with 'unix://'. [default = localhost] -f --field-group-idfieldGroupId The field group to query on the specified host. -e --field-id fieldId Field identifier to view/inject.(要查看的字段ID) -l --list List to look up the long names, short names and field ids.(用于查找长名称、短名称和字段 ID 的列表。) -h --help Displays usage information and exits. -i --gpu-id gpuId The comma separated list of GPU/GPU-I/GPU-CI IDs to run the dmon on. Default is -1 which runs for all supported GPU. Run dcgmi discovery -c to check list of available GPU entities (用于运行守护程序的 GPU/GPU-I/GPU-CI ID 的逗号分隔列表。 默认值为 -1,适用于所有支持的 GPU。 运行 dcgmi discovery -c 以检查可用 GPU 实体列表) -g --group-id groupId The group to query on the specified host. -d --delay delay In milliseconds. Integer representing how often to query results from DCGM and print them for all of the entities. [default = 1000 msec, Minimum value = 1 msec.](以毫秒为单位。 表示从 DCGM 查询结果并为所有实体打印结果的频率。 [默认 = 1000 毫秒,最小值 = 1 毫秒) -c --count count Integer representing How many times to loop before exiting. [default- runs forever.](表示退出前循环次数。[默认值-永远运行]) -- --ignore_rest Ignores the rest of the labeled arguments following this flag. NVIDIA Datacenter GPU Management Interface ``` ``` > dcgmi dmon -l ___________________________________________________________________________________________________________ Long Name Short Name Field ID ___________________________________________________________________________________________________________ driver_version DRVER 1 nvml_version NVVER 2 process_name PRNAM 3 device_count DVCNT 4 cuda_driver_version CDVER 5 name DVNAM 50 brand DVBRN 51 nvml_index NVIDX 52 serial_number SRNUM 53 uuid UUID# 54 minor_number MNNUM 55 oem_inforom_version OEMVR 56 pci_busid PCBID 57 pci_combined_id PCCID 58 pci_subsys_id PCSID 59 system_topology_pci STVCI 60 system_topology_nvlink STNVL 61 system_affinity SYSAF 62 cuda_compute_capability DVCCC 63 compute_mode CMMOD 65 persistance_mode PMMOD 66 mig_mode MGMOD 67 cuda_visible_devices CUVID 68 mig_max_slices MIGMS 69 cpu_affinity_0 CAFF0 70 cpu_affinity_1 CAFF1 71 cpu_affinity_2 CAFF2 72 cpu_affinity_3 CAFF3 73 cc_mode CCMOD 74 mig_attributes MIGATT 75 mig_gi_info MIGGIINFO 76 mig_ci_info MIGCIINFO 77 ecc_inforom_version EIVER 80 power_inforom_version PIVER 81 inforom_image_version IIVER 82 inforom_config_checksum CCSUM 83 inforom_config_valid ICVLD 84 vbios_version VBVER 85 bar1_total B1TTL 90 sync_boost SYBST 91 bar1_used B1USE 92 bar1_free B1FRE 93 sm_clock SMCLK 100 memory_clock MMCLK 101 video_clock VICLK 102 sm_app_clock SACLK 110 mem_app_clock MACLK 111 current_clock_throttle_reasons DVCCTR 112 sm_max_clock SMMAX 113 memory_max_clock MMMAX 114 video_max_clock VIMAX 115 autoboost ATBST 120 supported_clocks SPCLK 130 memory_temp MMTMP 140 gpu_temp TMPTR 150 gpu_mem_max_op_temp GMMOT 151 gpu_max_op_temp GGMOT 152 power_usage POWER 155 total_energy_consumption TOTEC 156 slowdown_temp SDTMP 158 shutdown_temp SHTMP 159 power_management_limit PMLMT 160 power_management_limit_min PMMIN 161 power_management_limit_max PMMAX 162 power_management_limit_default PMDEF 163 enforced_power_limit EPLMT 164 pstate PSTAT 190 fan_speed FANSP 191 pcie_tx_throughput TXTPT 200 pcie_rx_throughput RXTPT 201 pcie_replay_counter RPCTR 202 gpu_utilization GPUTL 203 mem_copy_utilization MCUTL 204 accounting_data ACCDT 205 enc_utilization ECUTL 206 dec_utilization DCUTL 207 mem_util_samples MUSAM 210 gpu_util_samples GUSAM 211 graphics_pids GPIDS 220 compute_pids CMPID 221 xid_errors XIDER 230 pcie_max_link_gen PCIMG 235 pcie_max_link_width PCIMW 236 pcie_link_gen PCILG 237 pcie_link_width PCILW 238 power_violation PVIOL 240 thermal_violation TVIOL 241 sync_boost_violation SBVIO 242 board_limit_violation BLVIO 243 low_util_violation LUVIO 244 reliability_violation RVIOL 245 app_clock_violation TAPCV 246 base_clock_violation TAPBC 247 fb_total FBTTL 250 fb_free FBFRE 251 fb_used FBUSD 252 fb_resv FBRSV 253 fb_USDP FBUSP 254 ecc ECCUR 300 ecc_pending ECPEN 301 ecc_sbe_volatile_total ESVTL 310 ecc_dbe_volatile_total EDVTL 311 ecc_sbe_aggregate_total ESATL 312 ecc_dbe_aggregate_total EDATL 313 ecc_sbe_volatile_l1 ESVL1 314 ecc_dbe_volatile_l1 EDVL1 315 ecc_sbe_volatile_l2 ESVL2 316 ecc_dbe_volatile_l2 EDVL2 317 ecc_sbe_volatile_device ESVDV 318 ecc_dbe_volatile_device EDVDV 319 ecc_sbe_volatile_register ESVRG 320 ecc_dbe_volatile_register EDVRG 321 ecc_sbe_volatile_texture ESVTX 322 ecc_dbe_volatile_texture EDVTX 323 ecc_sbe_aggregate_l1 ESAL1 324 ecc_dbe_aggregate_l1 EDAL1 325 ecc_sbe_aggregate_l2 ESAL2 326 ecc_dbe_aggregate_l2 EDAL2 327 ecc_sbe_aggregate_device ESADV 328 ecc_dbe_aggregate_device EDADV 329 ecc_sbe_aggregate_register ESARG 330 ecc_dbe_aggregate_register EDARG 331 ecc_sbe_aggregate_texture ESATX 332 ecc_dbe_aggregate_texture EDATX 333 retired_pages_sbe RPSBE 390 retired_pages_dbe RPDBE 391 retired_pages_pending RPPEN 392 uncorrectable_remapped_rows URMPS 393 correctable_remapped_rows CRMPS 394 row_remap_failure RRF 395 row_remap_pending RRP 396 nvlink_flit_crc_error_count_l0 NFEL0 400 nvlink_flit_crc_error_count_l1 NFEL1 401 nvlink_flit_crc_error_count_l2 NFEL2 402 nvlink_flit_crc_error_count_l3 NFEL3 403 nvlink_flit_crc_error_count_l4 NFEL4 404 nvlink_flit_crc_error_count_l5 NFEL5 405 nvlink_flit_crc_error_count_l12 NFEL12 406 nvlink_flit_crc_error_count_l13 NFEL13 407 nvlink_flit_crc_error_count_l14 NFEL14 408 nvlink_flit_crc_error_count_total NFELT 409 nvlink_data_crc_error_count_l0 NDEL0 410 nvlink_data_crc_error_count_l1 NDEL1 411 nvlink_data_crc_error_count_l2 NDEL2 412 nvlink_data_crc_error_count_l3 NDEL3 413 nvlink_data_crc_error_count_l4 NDEL4 414 nvlink_data_crc_error_count_l5 NDEL5 415 nvlink_data_crc_error_count_l12 NDEL12 416 nvlink_data_crc_error_count_l13 NDEL13 417 nvlink_data_crc_error_count_l14 NDEL14 418 nvlink_data_crc_error_count_total NDELT 419 nvlink_replay_error_count_l0 NREL0 420 nvlink_replay_error_count_l1 NREL1 421 nvlink_replay_error_count_l2 NREL2 422 nvlink_replay_error_count_l3 NREL3 423 nvlink_replay_error_count_l4 NREL4 424 nvlink_replay_error_count_l5 NREL5 425 nvlink_replay_error_count_l12 NREL12 426 nvlink_replay_error_count_l13 NREL13 427 nvlink_replay_error_count_l14 NREL14 428 nvlink_replay_error_count_total NRELT 429 nvlink_recovery_error_count_l0 NRCL0 430 nvlink_recovery_error_count_l1 NRCL1 431 nvlink_recovery_error_count_l2 NRCL2 432 nvlink_recovery_error_count_l3 NRCL3 433 nvlink_recovery_error_count_l4 NRCL4 434 nvlink_recovery_error_count_l5 NRCL5 435 nvlink_recovery_error_count_l12 NRCL12 436 nvlink_recovery_error_count_l13 NRCL13 437 nvlink_recovery_error_count_l14 NRCL14 438 nvlink_recovery_error_count_total NRCLT 439 nvlink_bandwidth_l0 NBWL0 440 nvlink_bandwidth_l1 NBWL1 441 nvlink_bandwidth_l2 NBWL2 442 nvlink_bandwidth_l3 NBWL3 443 nvlink_bandwidth_l4 NBWL4 444 nvlink_bandwidth_l5 NBWL5 445 nvlink_bandwidth_l12 NBWL12 446 nvlink_bandwidth_l13 NBWL13 447 nvlink_bandwidth_l14 NBWL14 448 nvlink_bandwidth_total NBWLT 449 gpu_nvlink_errors GNVERR 450 nvlink_flit_crc_error_count_l6 NFEL6 451 nvlink_flit_crc_error_count_l7 NFEL7 452 nvlink_flit_crc_error_count_l8 NFEL8 453 nvlink_flit_crc_error_count_l9 NFEL9 454 nvlink_flit_crc_error_count_l10 NFEL10 455 nvlink_flit_crc_error_count_l11 NFEL11 456 nvlink_data_crc_error_count_l6 NDEL6 457 nvlink_data_crc_error_count_l7 NDEL7 458 nvlink_data_crc_error_count_l8 NDEL8 459 nvlink_data_crc_error_count_l9 NDEL9 460 nvlink_data_crc_error_count_l10 NDEL10 461 nvlink_data_crc_error_count_l11 NDEL11 462 nvlink_replay_error_count_l6 NREL6 463 nvlink_replay_error_count_l7 NREL7 464 nvlink_replay_error_count_l8 NREL8 465 nvlink_replay_error_count_l9 NREL9 466 nvlink_replay_error_count_l10 NREL10 467 nvlink_replay_error_count_l11 NREL11 468 nvlink_recovery_error_count_l6 NRCL6 469 nvlink_recovery_error_count_l7 NRCL7 470 nvlink_recovery_error_count_l8 NRCL8 471 nvlink_recovery_error_count_l9 NRCL9 472 nvlink_recovery_error_count_l10 NRCL10 473 nvlink_recovery_error_count_l11 NRCL11 474 nvlink_bandwidth_l6 NBWL6 475 nvlink_bandwidth_l7 NBWL7 476 nvlink_bandwidth_l8 NBWL8 477 nvlink_bandwidth_l9 NBWL9 478 nvlink_bandwidth_l10 NBWL10 479 nvlink_bandwidth_l11 NBWL11 480 nvlink_flit_crc_error_count_l15 NFEL15 481 nvlink_flit_crc_error_count_l16 NFEL16 482 nvlink_flit_crc_error_count_l17 NFEL17 483 nvlink_data_crc_error_count_l15 NDEL15 484 nvlink_data_crc_error_count_l16 NDEL16 485 nvlink_data_crc_error_count_l17 NDEL17 486 nvlink_replay_error_count_l15 NREL15 487 nvlink_replay_error_count_l16 NREL16 488 nvlink_replay_error_count_l17 NREL17 489 nvlink_recovery_error_count_l15 NRCL15 491 nvlink_recovery_error_count_l16 NRCL16 492 nvlink_recovery_error_count_l17 NRCL17 493 nvlink_bandwidth_l15 NBWL15 494 nvlink_bandwidth_l16 NBWL16 495 nvlink_bandwidth_l17 NBWL17 496 virtualization_mode VMODE 500 supported_type_info SPINF 501 creatable_vgpu_type_ids CGPID 502 active_vgpu_instance_ids VGIID 503 vgpu_instance_utilizations VIUTL 504 vgpu_instance_per_process_utilization VIPPU 505 enc_stats ENSTA 506 fbc_stats FBCSTA 507 fbc_sessions_info FBCINF 508 vgpu_type_ids VTID 509 vgpu_type_info VTPINF 510 vgpu_type_name VTPNM 511 vgpu_type_class VTPCLS 512 vgpu_type_license VTPLC 513 vgpu_instance_vm_id VVMID 520 vgpu_instance_vm_name VMNAM 521 vgpu_instance_type VITYP 522 vgpu_instance_uuid VUUID 523 vgpu_instance_driver_version VDVER 524 vgpu_instance_memory_usage VMUSG 525 vgpu_instance_license_status VLCST 526 vgpu_instance_frame_rate_limit VFLIM 527 vgpu_instance_enc_stats VSTAT 528 vgpu_instance_enc_sessions_info VSINF 529 vgpu_instance_fbc_stats VFSTAT 530 vgpu_instance_fbc_sessions_info VFINF 531 vgpu_instance_license_state VLCIST 532 vgpu_instance_pci_id VPCIID 533 vgpu_instance_gpu_instance_id VGII 534 nvswitch_link_bandwidth_tx SWLNKTX 780 nvswitch_link_bandwidth_rx SWLNKRX 781 nvswitch_link_fatal_errors SWLNKFE 782 nvswitch_link_non_fatal_errors SWLNKNF 783 nvswitch_link_replay_errors SWLNKRP 784 nvswitch_link_recovery_errors SWLNKRC 785 nvswitch_link_flit_errors SWLNKFL 786 nvswitch_link_crc_errors SWLNKCR 787 nvswitch_link_ecc_errors SWLNKEC 788 nvswitch_link_latency_low_vc0 SWVCLL0 789 nvswitch_link_latency_low_vc1 SWVCLL1 790 nvswitch_link_latency_low_vc2 SWVCLL2 791 nvswitch_link_latency_low_vc SWVCLL3 792 nvswitch_link_latency_medium_vc0 SWVCLM0 793 nvswitch_link_latency_medium_vc1 SWVCLM1 794 nvswitch_link_latency_medium_vc2 SWVCLM2 795 nvswitch_link_latency_medium_vc3 SWVCLM3 796 nvswitch_link_latency_high_vc0 SWVCLH0 797 nvswitch_link_latency_high_vc1 SWVCLH1 798 nvswitch_link_latency_high_vc2 SWVCLH2 799 nvswitch_link_latency_high_vc3 SWVCLH3 800 nvswitch_link_latency_panic_vc0 SWVCLP0 801 nvswitch_link_latency_panic_vc1 SWVCLP1 802 nvswitch_link_latency_panic_vc2 SWVCLP2 803 nvswitch_link_latency_panic_vc3 SWVCLP3 804 nvswitch_link_latency_count_vc0 SWVCLC0 805 nvswitch_link_latency_count_vc1 SWVCLC1 806 nvswitch_link_latency_count_vc2 SWVCLC2 807 nvswitch_link_latency_count_vc3 SWVCLC3 808 nvswitch_link_crc_errors_lane0 SWLACR0 809 nvswitch_link_crc_errors_lane1 SWLACR1 810 nvswitch_link_crc_errors_lane2 SWLACR2 811 nvswitch_link_crc_errors_lane3 SWLACR3 812 nvswitch_link_ecc_errors_lane0 SWLAEC0 813 nvswitch_link_ecc_errors_lane1 SWLAEC1 814 nvswitch_link_ecc_errors_lane2 SWLAEC2 815 nvswitch_link_ecc_errors_lane3 SWLAEC3 816 nvswitch_fatal_error SEN00 856 nvswitch_non_fatal_error SEN01 857 nvswitch_current_temperature TMP01 858 nvswitch_slowdown_temperature TMP02 859 nvswitch_shutdown_temperature TMP03 860 nvswitch_bandwidth_tx SWTX 861 nvswitch_bandwidth_rx SWRX 862 nvswitch_physical_id SWPHID 863 nvswitch_reset_required SWFRMVER 864 nvlink_id LNKID 865 nvswitch_pcie_dom SWPCIEDOM 866 nvswitch_pcie_bus SWPCIEBUS 867 nvswitch_pcie_dev SWPCIEDEV 868 nvswitch_pcie_fun SWPCIEFUN 869 nvswitch_nvlink_status SWNVLNKST 870 nvswitch_nvlink_dev_type SWNVLNKDT 871 link_pcie_remote_dom LNKDOM 872 link_pcie_remote_bus LNKBUS 873 link_pcie_remote_dev LNKDEV 874 link_pcie_remote_func LNKFNC 875 link_dev_link_id SWNVLNKID 876 link_dev_link_sid SWNVLNSID 877 link_dev_link_uuid SWNVLNUID 878 gr_engine_active GRACT 1001 sm_active SMACT 1002 sm_occupancy SMOCC 1003 tensor_active TENSO 1004 dram_active DRAMA 1005 fp64_active FP64A 1006 fp32_active FP32A 1007 fp16_active FP16A 1008 pcie_tx_bytes PCITX 1009 pcie_rx_bytes PCIRX 1010 nvlink_tx_bytes NVLTX 1011 nvlink_rx_bytes NVLRX 1012 tensor_imma_active TIMMA 1013 tensor_hmma_active THMMA 1014 tensor_dfma_active TDFMA 1015 integer_active INTAC 1016 nvdec0_active NVDEC0 1017 nvdec1_active NVDEC1 1018 nvdec2_active NVDEC2 1019 nvdec3_active NVDEC3 1020 nvdec4_active NVDEC4 1021 nvdec5_active NVDEC5 1022 nvdec6_active NVDEC6 1023 nvdec7_active NVDEC7 1024 nvjpg0_active NVJPG0 1025 nvjpg1_active NVJPG1 1026 nvjpg2_active NVJPG2 1027 nvjpg3_active NVJPG3 1028 nvjpg4_active NVJPG4 1029 nvjpg5_active NVJPG5 1030 nvjpg6_active NVJPG6 1031 nvjpg7_active NVJPG7 1032 nvofa0_active NVOFA0 1033 nvlink_l0_tx_bytes NVL0T 1040 nvlink_l0_rx_bytes NVL0R 1041 nvlink_l1_tx_bytes NVL1T 1042 nvlink_l1_rx_bytes NVL1R 1043 nvlink_l2_tx_bytes NVL2T 1044 nvlink_l2_rx_bytes NVL2R 1045 nvlink_l3_tx_bytes NVL3T 1046 nvlink_l3_rx_bytes NVL3R 1047 nvlink_l4_tx_bytes NVL4T 1048 nvlink_l4_rx_bytes NVL4R 1049 nvlink_l5_tx_bytes NVL5T 1050 nvlink_l5_rx_bytes NVL5R 1051 nvlink_l6_tx_bytes NVL6T 1052 nvlink_l6_rx_bytes NVL6R 1053 nvlink_l7_tx_bytes NVL7T 1054 nvlink_l7_rx_bytes NVL7R 1055 nvlink_l8_tx_bytes NVL8T 1056 nvlink_l8_rx_bytes NVL8R 1057 nvlink_l9_tx_bytes NVL9T 1058 nvlink_l9_rx_bytes NVL9R 1059 nvlink_l10_tx_bytes NVL10T 1060 nvlink_l10_rx_bytes NVL10R 1061 nvlink_l11_tx_bytes NVL11T 1062 nvlink_l11_rx_bytes NVL11R 1063 nvlink_l12_tx_bytes NVL12T 1064 nvlink_l12_rx_bytes NVL12R 1065 nvlink_l13_tx_bytes NVL13T 1066 nvlink_l13_rx_bytes NVL13R 1067 nvlink_l14_tx_bytes NVL14T 1068 nvlink_l14_rx_bytes NVL14R 1069 nvlink_l15_tx_bytes NVL15T 1070 nvlink_l15_rx_bytes NVL15R 1071 nvlink_l16_tx_bytes NVL16T 1072 nvlink_l16_rx_bytes NVL16R 1073 nvlink_l17_tx_bytes NVL17T 1074 nvlink_l17_rx_bytes NVL17R 1075 ``` ``` dcgmi dmon -i 0 -e 1011,1012,1009,1010 -c 5 #Entity NVLTX NVLRX PCITX PCIRX ID GPU 0 N/A N/A N/A N/A GPU 0 N/A N/A N/A N/A GPU 0 0 0 498948 1555 GPU 0 0 0 449138 2074 GPU 0 0 0 548740 1555 ``` ## dcgmi nvlink 用于获取系统中 GPU 和 NvSwitch 的 NvLink 链接状态或错误计数 ``` > dcgmi nvlink --help nvlink -- Used to get NvLink link status or error counts for GPUs and NvSwitches in the system NVLINK Error description ========================= CRC FLIT Error => Data link receive flow control digit CRC error. CRC Data Error => Data link receive data CRC error. Replay Error => Data link transmit replay error. Recovery Error => Data link transmit recovery error. Usage: dcgmi nvlink dcgmi nvlink --host -g -e -j dcgmi nvlink --host -s Flags: --host IP/FQDN Connects to specified IP or fully-qualified domain name. To connect to a host engine that was started with -d (unix socket), prefix the unix socket filename with 'unix://'. [default = localhost] -e --errors Print NvLink errors for a given gpuId (-g). -s --link-status Print NvLink link status for all GPUs and NvSwitches in the system. -h --help Displays usage information and exits. -g --gpuid gpuId The GPU ID to query. Required for -e -j --json Print the output in a json format(json格式输出) -- --ignore_rest Ignores the rest of the labeled arguments following this flag. NVIDIA Datacenter GPU Management Interface ``` json格式输出: ``` > dcgmi nvlink -g 0 -e -j { "body" : { "Link 0" : { "children" : { "CRC Data Error" : { "value" : "0" }, "CRC FLIT Error" : { "value" : "0" }, "Recovery Error" : { "value" : "0" }, "Replay Error" : { "value" : "0" } } }, "Link 1" : { "children" : { "CRC Data Error" : { "value" : "0" }, "CRC FLIT Error" : { "value" : "0" }, "Recovery Error" : { "value" : "0" }, "Replay Error" : { "value" : "0" } } }, "Link 2" : { "children" : { "CRC Data Error" : { "value" : "0" }, "CRC FLIT Error" : { "value" : "0" }, "Recovery Error" : { "value" : "0" }, "Replay Error" : { "value" : "0" } } }, "Link 3" : { "children" : { "CRC Data Error" : { "value" : "0" }, "CRC FLIT Error" : { "value" : "0" }, "Recovery Error" : { "value" : "0" }, "Replay Error" : { "value" : "0" } } }, "Link 4" : { "children" : { "CRC Data Error" : { "value" : "0" }, "CRC FLIT Error" : { "value" : "0" }, "Recovery Error" : { "value" : "0" }, "Replay Error" : { "value" : "0" } } }, "Link 5" : { "children" : { "CRC Data Error" : { "value" : "0" }, "CRC FLIT Error" : { "value" : "0" }, "Recovery Error" : { "value" : "0" }, "Replay Error" : { "value" : "0" } } }, "Link 6" : { "children" : { "CRC Data Error" : { "value" : "0" }, "CRC FLIT Error" : { "value" : "0" }, "Recovery Error" : { "value" : "0" }, "Replay Error" : { "value" : "0" } } }, "Link 7" : { "children" : { "CRC Data Error" : { "value" : "0" }, "CRC FLIT Error" : { "value" : "0" }, "Recovery Error" : { "value" : "0" }, "Replay Error" : { "value" : "0" } } } }, "header" : [ "NVLINK Error Counts", "GPU 0" ] } ``` ``` dcgmi nvlink -s +----------------------+ | NvLink Link Status | +----------------------+ GPUs: gpuId 0: U U U U U U U U _ _ _ _ _ _ _ _ _ _ gpuId 1: U U U U U U U U _ _ _ _ _ _ _ _ _ _ gpuId 2: U U U U U U U U _ _ _ _ _ _ _ _ _ _ gpuId 3: U U U U U U U U _ _ _ _ _ _ _ _ _ _ gpuId 4: U U U U U U U U _ _ _ _ _ _ _ _ _ _ gpuId 5: U U U U U U U U _ _ _ _ _ _ _ _ _ _ gpuId 6: U U U U U U U U _ _ _ _ _ _ _ _ _ _ gpuId 7: U U U U U U U U _ _ _ _ _ _ _ _ _ _ NvSwitches: No NvSwitches found. Key: Up=U, Down=D, Disabled=X, Not Supported=_ ``` ``` > dcgmi nvlink -g 1 -e +-----------------------------+------------------------------------------------+ | NVLINK Error Counts | | GPU 1 | +=============================+================================================+ | Link 0 | | | -> CRC FLIT Error | 0 | | -> CRC Data Error | 0 | | -> Replay Error | 0 | | -> Recovery Error | 0 | | Link 1 | | | -> CRC FLIT Error | 0 | | -> CRC Data Error | 0 | | -> Replay Error | 0 | | -> Recovery Error | 0 | | Link 2 | | | -> CRC FLIT Error | 0 | | -> CRC Data Error | 0 | | -> Replay Error | 0 | | -> Recovery Error | 0 | | Link 3 | | | -> CRC FLIT Error | 0 | | -> CRC Data Error | 0 | | -> Replay Error | 0 | | -> Recovery Error | 0 | | Link 4 | | | -> CRC FLIT Error | 0 | | -> CRC Data Error | 0 | | -> Replay Error | 0 | | -> Recovery Error | 0 | | Link 5 | | | -> CRC FLIT Error | 0 | | -> CRC Data Error | 0 | | -> Replay Error | 0 | | -> Recovery Error | 0 | | Link 6 | | | -> CRC FLIT Error | 0 | | -> CRC Data Error | 0 | | -> Replay Error | 0 | | -> Recovery Error | 0 | | Link 7 | | | -> CRC FLIT Error | 0 | | -> CRC Data Error | 0 | | -> Replay Error | 0 | | -> Recovery Error | 0 | +-----------------------------+------------------------------------------------+ ``` ## 指标 支持以下新的设备级分析指标。 列出了定义和相应的 DCGM 字段 ID。 默认情况下,DCGM 以 1Hz(每 1000毫秒(ms))的采样率提供指标。 用户可以以任何可配置的频率(最小为 100 毫秒(ms))从 DCGM 查询指标(例如:dcgmi dmon -d)。 以下是设备水平(level)的GPU指标 | Metric | Definition | DCGM Field Name (DCGM_FI_*) and ID | | --- | --- | --- | | Graphics Engine Activity | The fraction of time any portion of the graphics or compute engines were active. The graphics engine is active if a graphics/compute context is bound and the graphics/compute pipe is busy. The value represents an average over a time interval and is not an instantaneous value. | PROF_GR_ENGINE_ACTIVE (ID: 1001) | | SM Activity | The fraction of time at least one warp was active on a multiprocessor, averaged over all multiprocessors. Note that “active” does not necessarily mean a warp is actively computing. For instance, warps waiting on memory requests are considered active. The value represents an average over a time interval and is not an instantaneous value. A value of 0.8 or greater is necessary, but not sufficient, for effective use of the GPU. A value less than 0.5 likely indicates ineffective GPU usage.Given a simplified GPU architectural view, if a GPU has N SMs then a kernel using N blocks that runs over the entire time interval will correspond to an activity of 1 (100%). A kernel using N/5 blocks that runs over the entire time interval will correspond to an activity of 0.2 (20%). A kernel using N blocks that runs over one fifth of the time interval, with the SMs otherwise idle, will also have an activity of 0.2 (20%). The value is insensitive to the number of threads per block (see `DCGM_FI_PROF_SM_OCCUPANCY`). | PROF_SM_ACTIVE (ID: 1002) | | SM Occupancy | The fraction of resident warps on a multiprocessor, relative to the maximum number of concurrent warps supported on a multiprocessor. The value represents an average over a time interval and is not an instantaneous value. Higher occupancy does not necessarily indicate better GPU usage. For GPU memory bandwidth limited workloads (see `DCGM_FI_PROF_DRAM_ACTIVE`), higher occupancy is indicative of more effective GPU usage. However if the workload is compute limited (i.e. not GPU memory bandwidth or latency limited), then higher occupancy does not necessarily correlate with more effective GPU usage.Calculating occupancy is not simple and depends on factors such as the GPU properties, the number of threads per block, registers per thread, and shared memory per block. Use the [CUDA Occupancy Calculator](https://docs.nvidia.com/cuda/cuda-occupancy-calculator/index.html) to explore various occupancy scenarios. | PROF_SM_OCCUPANCY (ID: 1003) | | Tensor Activity | The fraction of cycles the tensor (HMMA / IMMA) pipe was active. The value represents an average over a time interval and is not an instantaneous value. Higher values indicate higher utilization of the Tensor Cores. An activity of 1 (100%) is equivalent to issuing a tensor instruction every other cycle for the entire time interval. An activity of 0.2 (20%) could indicate 20% of the SMs are at 100% utilization over the entire time period, 100% of the SMs are at 20% utilization over the entire time period, 100% of the SMs are at 100% utilization for 20% of the time period, or any combination in between (see `DCGM_FI_PROF_SM_ACTIVE` to help disambiguate these possibilities). | PROF_PIPE_TENSOR_ACTIVE (ID: 1004) | | FP64 Engine Activity | The fraction of cycles the FP64 (double precision) pipe was active. The value represents an average over a time interval and is not an instantaneous value. Higher values indicate higher utilization of the FP64 cores. An activity of 1 (100%) is equivalent to a FP64 instruction on [every SM every fourth cycle](https://docs.nvidia.com/cuda/volta-tuning-guide/index.html#sm-scheduling) on Volta over the entire time interval. An activity of 0.2 (20%) could indicate 20% of the SMs are at 100% utilization over the entire time period, 100% of the SMs are at 20% utilization over the entire time period, 100% of the SMs are at 100% utilization for 20% of the time period, or any combination in between (see DCGM_FI_PROF_SM_ACTIVE to help disambiguate these possibilities). | PROF_PIPE_FP64_ACTIVE (ID: 1006) | | FP32 Engine Activity | The fraction of cycles the FMA (FP32 (single precision), and integer) pipe was active. The value represents an average over a time interval and is not an instantaneous value. Higher values indicate higher utilization of the FP32 cores. An activity of 1 (100%) is equivalent to a FP32 instruction every other cycle over the entire time interval. An activity of 0.2 (20%) could indicate 20% of the SMs are at 100% utilization over the entire time period, 100% of the SMs are at 20% utilization over the entire time period, 100% of the SMs are at 100% utilization for 20% of the time period, or any combination in between (see `DCGM_FI_PROF_SM_ACTIVE` to help disambiguate these possibilities). | PROF_PIPE_FP32_ACTIVE (ID: 1007) | | FP16 Engine Activity | The fraction of cycles the FP16 (half precision) pipe was active. The value represents an average over a time interval and is not an instantaneous value. Higher values indicate higher utilization of the FP16 cores. An activity of 1 (100%) is equivalent to a FP16 instruction every other cycle over the entire time interval. An activity of 0.2 (20%) could indicate 20% of the SMs are at 100% utilization over the entire time period, 100% of the SMs are at 20% utilization over the entire time period, 100% of the SMs are at 100% utilization for 20% of the time period, or any combination in between (see `DCGM_FI_PROF_SM_ACTIVE` to help disambiguate these possibilities). | PROF_PIPE_FP16_ACTIVE (ID: 1008) | | Memory BW Utilization | The fraction of cycles where data was sent to or received from device memory. The value represents an average over a time interval and is not an instantaneous value. Higher values indicate higher utilization of device memory. An activity of 1 (100%) is equivalent to a DRAM instruction every cycle over the entire time interval (in practice a peak of ~0.8 (80%) is the maximum achievable). An activity of 0.2 (20%) indicates that 20% of the cycles are reading from or writing to device memory over the time interval. | PROF_DRAM_ACTIVE (ID: 1005) | | NVLink Bandwidth | 通过 NVLink 传输/接收的数据速率(不包括协议头(protocol headers)),以字节/秒为单位。 该值表示一段时间间隔内的平均值,而不是瞬时值。 该速率是时间间隔内的平均值。 例如,如果 1 秒内传输 1 GB 数据,则无论数据以恒定速率还是突发传输,速率均为 1 GB/s。 NVLink Gen2 的理论最大带宽为每个链路每个方向 25 GB/s。 | PROF_NVLINK_TX_BYTES (1011) and PROF_NVLINK_RX_BYTES (1012) | | PCIe Bandwidth | 通过 PCIe 总线传输/接收的数据速率,包括协议标头和数据有效负载,以字节/秒为单位。 该值表示一段时间间隔内的平均值,而不是瞬时值。 该速率是时间间隔内的平均值。 例如,如果 1 秒内传输 1 GB 数据,则无论数据以恒定速率还是突发传输,速率均为 1 GB/s。 理论最大 PCIe Gen3 带宽为每通道 985 MB/s。 | PROF_PCIE_[T\|R]X_BYTES (ID: 1009 (TX); 1010 (RX)) | ``` > dcgmi dmon -i 0,1,2,3 -e 1011,1012 #Entity NVLTX NVLRX ID GPU 3 19694075554 19687914629 GPU 2 19777203418 19819177524 GPU 1 19699841766 22070216956 GPU 0 20779220484 21900091841 GPU 3 12945588302 12953884356 GPU 2 12558214740 12560935679 GPU 1 13059621728 10651057317 GPU 0 11576689215 9600734242 GPU 3 11155319776 11155326544 GPU 2 11155466819 11155466298 GPU 1 11040517157 12515409691 GPU 0 11592513041 13925722805 GPU 3 1286216247 1217881887 GPU 2 928524939 860186978 GPU 1 1506174212 50051 GPU 0 31802 911367981 GPU 3 0 0 GPU 2 0 0 GPU 1 0 0 GPU 0 0 0 GPU 3 23309642310 23377912493 GPU 2 23176458503 23176459024 GPU 1 23447369511 23507663607 GPU 0 23508249062 23174848479 ... > dcgmi dmon -e 1011,1012 #Entity NVLTX NVLRX ID GPU 7 30570603980 30638829242 GPU 6 30567094640 30635348592 GPU 5 30628398352 33089365519 GPU 4 33098848601 36119516306 GPU 3 33750138990 33825970205 GPU 2 31743752465 31812022474 GPU 1 34030055050 34098309807 GPU 0 32873620375 29632298747 GPU 7 24371477520 24370431480 GPU 6 24443717565 24443653033 GPU 5 24450523113 23160485855 GPU 4 23167734167 23167708130 GPU 3 25744193567 25744198774 GPU 2 25027562441 25027562441 GPU 1 24099003605 24099024433 GPU 0 24669591596 24669655619 ... > dcgmi dmon -e 1011,1012,1009,1010 GPU 7 9012312241 9010146921 3658375705 1470950385 GPU 6 38735656050(36.07GB/s) 38739460219(36.08GB/s) 3715470394(3.46GB/s) 069653476(0.996GB/s) GPU 5 37117100494 37114692577 3684018382 1195478083 GPU 4 15832363949 30483540427 3617204053 1084584434 GPU 3 11415357717 11415357717 3762838708 3470626438 GPU 2 32126737331 32124608391 3860671178 1817597475 GPU 1 37055654032 37055676937 3666866771 1201785740 GPU 0 27827206810 27762665999 N/A 1146900782 GPU 7 37300245001 37302405771 3843250109 4599309358 GPU 6 14877616163 14939829270 3919059148 4513192032 GPU 5 17320548737 17382778744 3889129122 4641743864 GPU 4 30487341762 16373502117 3933037804 6115081312 GPU 3 34918736873 34918742079 3910245112 1761934955 GPU 2 16547291813 19112960872 2761505306 3060783203 GPU 1 18380875930 18390091637 148870522 2103742852 GPU 0 19407501485 15881929591 3711808007 1055934784 ``` 统计6000次,将结果保存到文件。 ``` dcgmi dmon -e 1011,1012,1009,1010 -c 6000 >> bandwitch.txt ``` ``` # -g 18 为 上面创建的组 dcgmi dmon -e 1011,1012,1009,1010 -g 18 #Entity NVLTX NVLRX PCITX PCIRX ID GPU 7 N/A N/A N/A N/A GPU 0 N/A N/A N/A N/A GPU 7 N/A N/A N/A N/A GPU 0 N/A N/A N/A N/A GPU 7 0 0 499346 3629 GPU 0 0 0 498931 2074 GPU 7 0 0 499343 3111 ``` ================================================ FILE: docs/llm-base/distribution-parallelism/README.md ================================================ - One weird trick for parallelizing convolutional neural networks - 不同的层适合用不同的并行方式,具体的,卷积层数据比参数大,适合数据并行,全连接层参数比数据大,适合模型并行。 - Exploring Hidden Dimensions in Parallelizing Convolutional Neural Networks - 这篇文章在抽象上更进一步,发现数据并行,模型并行都只是张量切分方式的不同罢了,有的是切数据,有的是切模型,而且对于多维张量,在不同的维度上切分,效果也不同,譬如在sample, channel, width, length等维度都可以切分。 - 其次,不同的切分方式,都是一种构型(configuration),不同的构型会导致不同的效果,所以寻找最优的并行方式,其实就是在构型空间里面搜索最优的构型而已,问题形式化成一个搜索问题。 - 最后,引入了代价模型来衡量每个构型的优劣,并提出了一系列对搜索空间剪枝的策略,并实现了原型系统。 - BEYOND DATA AND MODEL PARALLELISM FOR DEEP NEURAL NETWORKS(FlexFlow) - 主要是提出了execution simulator来完善cost model。 - Supporting Very Large Models using Automatic Dataflow Graph Partitioning(Tofu) - tofu 提出了一套DSL,方便开发者描述张量的划分策略,使用了类似poly的integer interval analysis来描述并行策略,同样,并行策略的搜索算法上也做了很多很有特色的工作。 - Tofu与所有其它工作的不同之处在于,它的关注点是operator的划分,其它工作的关注点是tensor的划分,二者当然是等价的。 - 不过,我认为关注点放在tensor的划分上更好一些,这不需要用户修改operator的实现,Tofu需要在DSL里描述operator的实现方式。 - - Mesh-TensorFlow: Deep Learning for Supercomputers - Mesh-TensorFlow的作者和GShard的作者几乎是重叠的,Mesh-TensorFlow甚至可以被看作GShard的前身。 - Mesh-TensorFlow的核心理念也是beyond batch splitting,数据并行是batch splitting,模型并行是张量其它维度的切分。这篇文章把集群的加速卡抽象成mesh结构,提出了一种把张量切分并映射到这个mesh结构的办法。 - Unity: Accelerating DNN Training Through Joint Opt of Algebraic Transform and Parallelization:https://zhuanlan.zhihu.com/p/560247608 - Unity 在 FlexFlow、TASO 和 MetaFlow 的基础上,提出在并行计算图(PCG)中代数变换和并行化的统一表示(OP,Operator)和共优化(图替代,Substitution)方法,可以同时考虑分布式训练中的计算、并行和通信过程。对于共优化,Unity 使用一个多级搜索算法来高效搜索性能最好的图替代组合以及相应的硬件放置策略。 - https://github.com/DicardoX/Individual_Paper_Notes - https://jeongseob.github.io/readings_mlsys.html - https://paperswithcode.com/methods/category/distributed-methods ================================================ FILE: docs/llm-base/distribution-parallelism/auto-parallel/Alpa.md ================================================ - https://www.usenix.org/conference/osdi22/presentation/zheng-lianmin - alpa: https://www.zhihu.com/question/414549247/answer/3044074132 Alpa 则是先通过动态规划来决定模型怎么切分成 stage,每个 stage 能分到哪些卡。然后在每个 stage 内部,再通过 整数线性规划 的方式来决定每个 op 是如何切分到这个 stage 的多个卡上的。这是一个自动优化的过程。 旧有的系统往往 focus 在 inter-op,intra-op 和自动并行策略搜索的一个或者两个点,而 alpa 兼顾了所有。比如 GShard 提出了 intra-op 的方式,GPipe 提出 inter-op 的方式,而 Megatron-LM v2 通过结合 inter 和 intra op 的方式,通过人工指定的并行策略来支持分布式训练 GPT 模型。微软提出的 ZeRO 模型(deepspeed)试图通过自动的策略,通过多个层级步骤,来优化数据并行中的显存使用。Alpa 我们前面介绍了,首先做 inter-op 的自动切分,然后做 intra-op 的层级调度方式,来达到兼顾所有的优化策略。 Alpa 高度依赖 JAX,它魔改了 XLA (JAX 底层通过 XLA 执行)中的 GSPMD,拿到 XLA 的计算图后,自动对 op 进行切分,生成对应的程序,在每个 worker 上执行。 Alpa 确实是大语言模型并行训练的 SOTA 工作,在理论上突破它还是有相当难度。 - 用ILP和DP自动探索DL分布式策略——Alpa:https://zhuanlan.zhihu.com/p/487588274 Alpa,可以在用户无任何干预的情况下,在可接受的时间内,自动对DL模型做分布式策略寻优。它需要两个输入:1. computation graph 2: device cluster Alpa将分布式策略归结为两类: Intra-Operator Parallelism:将Tensor按某些维度切裂,放到不同Device上计算的并行方式 Inter-Operator Parallelism:与Intra-Operator相对的并行方式 Data Parallelism和Operator Partitioning属于1,Pipeline Parallelism属于2。简单回顾一下这两类并行方式的特点:Intra-op Parallelism可充分利用带宽,切分带来的通信基本属于高效的集合通信。而Inter-op Parallelism若切点寻找的合适,则通信较小,但同步版本的策略无可避免的会引来Bubble。所以,可以利用cluster的非对称特性,将Intra-op Parallelism映射到高带宽互联的devices上;将Inter-op Parallelism映射到低带宽互联的devices上。如此组合,就能释放更大的算力。Alpa会自动探索这些策略及组合情况 之所以要做这两种区分,目的是为了在不同的level上做策略搜索,然后将二者组合起来,生成一统Data、Operator和Pipeline并行方式的执行计划。总结起来就是以下两个点: 将并行度视为两级:intra-operator和inter-operator,构建分级的解空间 在两级空间中分别探索最优解,然后提供高效的Runtime将二者编排起来 Alpa的Workflow Alpa工作在DL编译层(基于XLA,在HLO上进行策略探索),所以Paper中也称之为——自动生成分布式策略的DL编译器。因此,它使用优化Pass对HLO IR做策略探索,改图,以及其他优化。在Alpa的workflow中,有三个pass起了重要作用: Inter-op pass:不仅要将计算图切分成多个stage,还要对device cluster进行相应的切分,并组织成mesh分配给stage,所以产出stage-mesh pairs。这一过程使用动态规划(Dynamic Programming)完成,优化目标是追求端到端最小latency Intra-op pass:对单个stage-mesh pair做intra-op的切分探索,并把的结果将reports给上一级的inter-op pass。这一过程使用整数线性规划(Integer Linear Programming)完成,优化目标是最小化execution cost Runtime Orchestration pass:做Runtime缝合的事情。比如stage调度,通信优化等。显然这个pass和策略搜索没什么关系 所以在宏观上做DP,微观上ILP,Inter-op和Intra-op两个pass不断迭代最终获得最佳方案。 并行策略模块 Intra-Operator并行策略探索 Alpa使用ILP对单个stage-mesh pair求解。这里有两个假设:a. device mesh中所有的设备具有完全相同的计算能力;b. mesh一定是二维的 其他方面 还有两项值得注意,一个是关于Cost的获取,另一个是缩图剪枝。和很多文献中的cost model相同,Alpa也采用事先预估cost的方式,并假设所有的op的computation cost均为0(这和Tofu相同,即只考虑通信开销);在搜索空间方面,能剪枝则剪枝,例如将一些operator和它的operand融合,从而减少计算图的节点规模,是有必要的。 Inter-Operator并行策略搜索 上面已经提到,ILP针对单个stage-mesh pair做优化,那么如何将整个computation graph和device mesh cluster切成一个个stage-mesh pair呢?这就是Inter-Operator pass的工作了。该pass使用DP解决划分问题,目标是优化整体端到端latency。 不过,这里还是要做一个假设:假设computation graph的拓扑按照user define的顺序排列,这就是要把排序限定在固定的linear顺序。否则,动态规划算法不是很好建模。 - 【论文赏读】Alpa: Automating Inter- and Intra-Operator Parallelism for Distributed Deep Learning: https://zhuanlan.zhihu.com/p/571836701 Part 1. Introduction 已有并行工作的局限:要么被限制在单个并行方法 (PipeDream),要么依赖于对模型和集群规格的强假设 (DAPPLE, Tofu)。 自动混合并行的搜索空间较复杂,多并行策略的实现不够灵活。例如,若数据并行和 OP 并行结合,则添加一个 worker 需要额外分配多个设备;同时,最优的流水线策略依赖于每个 stage 数据和 OP 并行的决策,以及设备分配。因此,先前工作大部分局限于将数据并行和至多一类并行方法结合; Key observation:可以将不同并行策略组织为一个多级空间,并将这些并行策略映射到计算集群中的多级结构。不同并行策略对通信带宽要求不同,这与集群中不同位置设备间的带宽不同相一致; 多级并行策略的好处:1) intra-op 并行的硬件利用率更高,但会在每 iter 带来 OP 切片间的更多通信,以及划分 OP 后的合并;2) inter-op 并行仅在相邻 stages 间通信,若适当划分则轻量,但会导致设备的 idle 时间。Alpa 将 intra-op 映射到高带宽设备,将 inter-op 映射到距离较远的低带宽设备,并分级近似最优优化,全局非最优但性能较好; Part 2. Intra-op Parallelism Intra-op pass 中,模型图被表示为 XLA 的 HLO 格式,将常见的 DL OPs 总结为 80 个不到的原语 OPs,所以可以人工枚举每个原语 OPs 可能的并行策略。 整数线性规划 ILP Formulation: cost 模型:类似 Tofu,由于 Alpa 对大 OP 进行均匀切分,所有的并行方法有相同的算数复杂性;同时,小 OP 设备间存在的部分重复计算开销可忽略。因此,Alpa 仅关注通信开销和 reshard 开销,而非计算开销。在 intra-op pass 中,不对通信开销和 reshard 开销进行 profile,而是用通信量 / 带宽来评估; 目标函数:最小化图内所有节点的通信开销和所有边的 reshard 开销之和。 图简化:Alpa 将轻量 OP 合并,通过 BFS 确定并合并到深度最深的 OP。原因是推迟到最后的 depth 才计算,防止跨分支 merge 时出现依赖关系紊乱(例如分支 A 上已经执行到了,但分支 B 还没,此时执行 merged OP 显然不合理)。此外,和 ZeRO 类似,将 all-reduce 拆分为 reduce-scatter 和 all-gather,在 mesh 内共享优化器状态、梯度和参数,以节约内存。 Part 3. Inter-op Parallelism 不进行 OP 划分或 replicate,而是将不同 OPs 组织为 stages,分配到由 cluster mesh 切分的不同 device meshes 上执行,映射为 stage-mesh pair。Alpa 使用同步 1F1B 调度作为 pipeline 策略,该方法保留了同步一致性,且相较于 GPipe,保持 pipeline 延迟相同的同时,峰值内存开销更低。 Pipeline stages 间进行设备间的点对点通信,所需通信量远小于 intra-op parallelism;由于 stages 间的数据依赖,会导致部分设备在 fp/bp 过程中存在 idle time; 先前工作假设每个 stage 的设备是预先分配好的,且所有 stages 有固定的 intra-op plan; Inter-op pass 基于模型图的拓扑顺序(简单实现为 model IR 中 users 如何定义每个 OP 的顺序)进行模型图的线性化。 Part 4. Runtime Orchestration Workflow:Alpa 依次设计了 inter-op pass、intra-op pass 和 runtime orchestration 三类 pass。 给定 Jax IR 的模型描述和集群配置,inter-op pass 将 IR 切分为多个 stages,将设备集群切分为多个 device meshes,并通过动态规划 (DP) 将 stages 分配到 meshes,并对每个 stage-mesh pair 激活 intra-op pass。 被激活后,intra-op pass 通过整数线性规划 (ILP) 来最小化 stage 执行开销,优化 stage-mesh pair 的 intra-op plan,并将 plan 和开销反馈给 inter-op pass。 随后,inter-op pass 基于 intra-op plan 编译并执行 stage-mesh plan,获取精确的 stage latency,运行 stage 所需的内存,以及存储中间激励所需的内存,并基于 cost 和内存情况通过 DP 最小化 pipeline 的 end-to-end latency,以获取 stages 和 meshes 的最优划分方案。 在 stage level,Alpa 基于 XLA 和 GSPMD 进行编译,为每个 stage-mesh pair 生成并行可执行文件,并在需要的时候插入通信原语来处理 mesh 内通信;在 intra-op level,Alpa 实现了一个并行编排 pass,来解决 cross-mesh 的 stages 间通信,并为 inter-op 并行执行生成静态指令。 Cross-mesh Resharding:现有的人工 pipeline 系统要求 stages 有相同的 DP 和 MP 并行度,并将 stages 间通信简单实现为相同 meshes 间的 P2P send/recv。 Alpa 中,包含两个相邻 stages 的设备 meshes 可能有不同的 mesh shapes,且 stages 间通信的 tensor 可能有不同的 sharding specs,将这类通信模式定义为 cross-mesh resharding,一个多对多的多播问题。给定 sender 和 receiver mesh 上 tensors 的 sharding specs,Alpa 生成一个通信方案,从两步迭代来解决 cross-mesh sharding:1) Alpa 计算 src 和 dst mesh 间 tiles (tensor partitions) 的对应关系,生成 src 和 dst 设备间的 P2P send/recv 原语;2) 识别 dst tensor 的 sharding spec 中是否包含 replication,若包含则 tensor 仅需要向 dst mesh 传一次,并通过 all-gather 在 mesh 内的 devices 上以更高的带宽交换,该方法叫 local all-gather。由于 stages 间的通信量较小,Alpa 未考虑 cross-mesh resharding 的优化。 生成 pipeline 执行指令:最后一步,Alpa 生成静态执行指令来 launch 训练,使用一个 MPMD-style 的 runtime 来编排 inter-op 并行执行,为每个设备 mesh 单独生成静态执行指令集,包括 stage 内 tensors 的内存分配和去分配,stages 间按 cross-mesh resharding plan 的 tensors 通信,同步和计算等。根据 user 选择的 pipeline schedule,Alpa 使用一个 driver process 来在执行前提前生成指令并分发给各 worker,以避免 runtime 时 driver-worker 的协同开销。 - Alpa/Parax @OSDI 2022 : https://zhuanlan.zhihu.com/p/521211578 Alpa认为,不同的并行技术是有不同的带宽要求的,这也和分布式系统的结构相符合,因此,在不同的系统层次使用不同的并行技术,是Alpa的重要observation。基于这一observation,Alpa提出iter-operator和intra-operator并行。算子内并行主要考虑数据和模型划分,算子间并行主要考虑流水线并行。 算子间、算子内并行 Alpa提出的算子间、算子内并行划分方法,通过“是否切分了tensor的维度”来区分不同的并行。 算子内并行:切分了tensor维度的并行方式,包括数据并行和算子并行 算子间并行:不切分tensor,只是把子图进行不同的摆放分布,包括流水线并行。 Alpa设计 Alpa以计算图为输入,输出并行方案。为了决策这样的并行方案,Alpa需要解决两个层面的问题,一个是怎么分子图,子图间是流水线并行的;另一个是分好的子图怎么并行到不同的设备上。这两个层次是相互依赖的,而且每个子图分配多少设备也是需要决策的,这样整个决策问题非常复杂。Alpa的解决方案是在不同层次上用不同的优化算法(整数线性规划和动归)。 --- 2. 主要技术 2.1. 算子内并行 2.2 算子间并行 这一步需要解决两个问题: 子图怎么分 每个子图给多少设备 一个完整的计算图,可以看做一个算子列表(拓扑排序后),相邻的一些算子可构成一个stage,那么子图划分可以看成在这个算子列表里划分stage的问题(文章没提,这种划分总是合法的,因为总是保持stage的凸性)。划分子图后,可以给子图分配一个设备阵列,并根据前面介绍的算子内并行优化方法找到最好的并行方案。那么算子间并行的优化问题就是看做枚举不同的子图划分和设备划分,找到整体代价最小的组合划分方案: Alpa用动归方式解决这一问题 这个动归的复杂度很高,为了能在实际中应用,需要一些技巧: 提前剪枝 提前算子融合减少算子数目 2.3 并行处理 Alpa用XLA和GSPMD进行算子内并行方案的编译。对于算子间并行的编译,Alpa有一些自己的特殊处理。 cross-mesh resharding:相邻的stage可以用不同的设备阵列配置。 generating pipeline execution instruction:这一步需要MIMD的runtime 3. 实验 Alpa的代码是开源的( https://github.com/alpa-projects/alpa ),用JAX做前端,用XLA做后端。 用Ray actor实现设备阵列管理,用NCCL做通信。 ================================================ FILE: docs/llm-base/distribution-parallelism/auto-parallel/Flexflow.md ================================================ - 原paper ## Beyond Data and Model Parallelism for Deep Neural Networks ### 概要 训练深度神经网络 (DNN) 的计算要求已经增长到现在并行训练已成为标准做法。 现有的深度学习系统通常使用数据或模型并行性,但不幸的是,这些策略通常会导致并行化性能不佳。 在本文中,我们定义了一个更全面的 DNN 并行化策略搜索空间(称为 SOAP),其中包括在样本、操作、属性和参数维度中并行化 DNN 的策略。 我们还提出了 FlexFlow,这是一种深度学习框架,它使用 SOAP 空间的引导随机搜索来寻找特定并行机的快速并行化策略。 为了加速这种搜索,FlexFlow 引入了一种新颖的执行模拟器,它可以准确预测并行化策略的性能,并且比必须执行每个策略的先前方法快三个数量级。 我们在两个 GPU 集群上使用六个真实世界的 DNN 基准测试来评估 FlexFlow,结果表明,即使包括搜索时间,FlexFlow 也可以将训练吞吐量提高至最先进方法的 3.8 倍,并且还提高了可扩展性。 ### 6 Execution Optimizer 本节介绍执行优化器,它以运算符图和设备拓扑作为输入,并自动找到有效的并行化策略。 FlexFlow 使用模拟器作为预言机,将并行优化问题转化为成本最小化问题,即最小化预测执行时间。 这种方法的主要优点是,它避免了显式地编码相互依赖的优化之间的权衡(例如,减少数据传输与平衡工作负载分布),而只是专注于最小化应用程序的整体执行时间。 通过从最小完工时间轻松减少来找到最佳并行化策略是 NP 困难的[29]。 此外,如第 4 节所述,可能的策略数量与运算符图中的操作数量成指数关系,这使得穷举搜索空间变得困难。 为了找到低成本策略,FlexFlow 使用成本最小化搜索程序来启发式探索空间并返回发现的最佳策略。 - 更多维度的深度神经网络并行策略: https://diandiangu.github.io/2020/07/20/FlexFlow/ 这篇文章主要的点有如下几个: 相比于data-parallel和model-parallel,提出了更多维度的split方案。SOAP(sample,operator,atrribute,param)这四个维度的split方案。 在四个维度之上,提出了一种在候选空间搜索的方案 提出了一个更加轻量的simulator,可以更快速的对proposed split strategy做evaluate。相比直接执行的方案提升了3个数量级。 实现了总体的框架FlexFlow FlexFlow的总体框架如下: operator graph是计算图的描述。包括op作为node,tensor作为edge。 device topology描述实际设备的topo关系,device作为node,connection作为edge Execution Optimizer是FlexFlow的核心部件,用于搜索最优的split方案,下面是一个runtime,用于执行split方案。 SOAP 描述了与mindspore基本一致的模型切分config description。FlexFlow描述了SOAP维度的切分,是针对op的output tensor来切分的。选择了output tensor的多个维度: Sample表示input的batch维 Attribute表示tensor的属性维,例如height/width Parameter表示tensor的param维,例如in-channel/out-channel Operator表示op之间的切分维度。 从这里看,虽然把tensor分成了多个维度,实际上都是属于tensor本身的维度。这里跟mindspore是一样的。 Execution Simulator simulator是FlexFLow比较核心的部分,负责对proposed strategy做evaluate。得到candidate的性能数据。 这里为了提供evaluate的速度,没有使用直接执行的方式,而是用模拟执行。 还是正常去构建执行timelines,但是需要在device上执行时,直接从上一次执行相同input-size的数据中取得执行时间。这样降低了总体的执行时间。这里是假设op针对相同input-size的执行时间基本不变,而且跟input-data无关。在大多数模型中,这个假设都是成立的。 search algorithm 对所有解空间的遍历是一个NP-hard问题。FlexFlow采用了一个最小化cost的search算法来启发式探索解空间,并返回找到的最优策略。 采用了MCMC的随机方法search strategy space。MCMC是马尔可夫链蒙特卡洛算法。 蒙特卡洛方法是通过随机生成变量Xi的值,然后用Xi的值做模拟计算。从而得到目标问题的解。 如果随机变量Xi的概率分布比较复杂,不能用简单的均匀分布转换得到,就需要使用马尔可夫链蒙特卡洛方法来生成Xi的序列。 回到search space的问题,采用MCMC随机采样的方法生成随机的Xi,即可作为候选strategy。 - 读论文《FlexFlow-Beyond Data and Model Parallelism for Deep Neural Networks》: https://zhuanlan.zhihu.com/p/464355830 这篇文章提出了一个复杂的深度神经网络的并行策略:SOAP。Sample,Operation,Attribute,Parameter。提出了FlexFlow:一个在SOAP维度为特定的并行机器随机搜索快速并行策略的深度学习框架。为了加速这个搜索的过程,FlexFlow用了一个创新性的、可以准确预测一个并行策略的表现、比原有方法更快速的执行模拟器。实验结果表明FlexFlow可以很大程度上增大训练的吞吐率。本文由斯坦福大学团队发表于MLSys 2019。 这篇文章提出FlexFlow,一个可以自动在更大的范围内找出快速并行策略的深度学习框架。为了形式化这一问题,我们首先定义了SOAP。Operation维度描述了一个DNN中不同的operation是如何并行的。另外,对于一个单独的DNN operation来说,sample和parameter维度描述训练样例和模型参数如何在不同设备之间分布。最终,attribute维度定义一个sample中不同的attribute是如何划分的。已有的系统都是在SOAP的子集中划分的。 在SOAP这个更大的范围内搜索的一个主要的挑战是快速评估候选的并行方案已找到一个高效的方案。已有的工作依赖于在硬件上执行一轮训练来评估不同方案的执行时间。在SOAP的范围内,这样的方法代价太高。 为了解决这样的问题,FlexFlow提出了一个创新性的执行模拟器,可以准确预测并行策略的表现,比profile真实的运行快了三个数量级。设计模拟器的挑战在于如何准确估计不同DNN op的执行时间(非线性,取决于硬件)。模拟器依赖于两个事实:(1)很多DNN模型只用少数几个不同的op(2)op的执行时间通常差异不大,很大程度上取决于输入数据。FlexFlow的模拟器对于每种数据大小,用一个op的计算时间来衡量同种类op的计算时间。然后,这些估算被用于预测各种各样的并行策略。另外,模拟器使用了一种delta simulate算法,这种算法基于对之前的模拟的更新对新的策略作出模拟。何以有的方法比,这样的方法有两个优势:更快、所需资源更少。 模拟器的预测准确率很高。 FlexFlow的execution optimizer使用一种马尔可夫蒙特卡洛搜索算法探索SOAP的搜索空间,并给予对之前的候选策略的模拟表现选出候选策略。搜索过程结束后,optimizer返回最佳的策略。 --- 程序接口 与多数深度学习框架不同,FlexFlow用设备拓扑结构描述所有可用的应尽设备和他们之间的关联。拓扑结构中的“边”有带宽和延迟的标签。 FlexFlow可以自动为一个计算图和一个设备拓扑结构找到合适的并行策略。主要有两大优势:提供了易于编程的接口;可移植性(为不同的硬件自动选择搞笑的策略)。 FlexFlow架构 Execution optimizer为计算图和设备拓扑图选择高效的并行策略。 --- ================================================ FILE: docs/llm-base/distribution-parallelism/auto-parallel/Galvatron.md ================================================ 北大河图大模型自动并行训练工具Galvatron:https://zhuanlan.zhihu.com/p/591924340 系统特性 为了解决上述问题,研究者们提出了一些系列工作来探索混合并行的自动搜索:一类工作主要讨论了同时考虑数据并行和模型并行的搜索空间,代表性工作包括FlexFlow,Tofu,另一类工作则产生于流水并行场景,将其与数据并行相结合,代表性工作包括PipeDream,DAPPLE。在此基础上还有一些衍生工作,如Unity、Alpa,进一步扩展了自动并行的探索范围。我们提出的系统「惊破天」Galvatron同样属于自动并行搜索的研究领域,但相比于现有工作,我们主要拥有以下三方面优势: (1)在多样性方面,现有工作能够支持的并行维度仍然比较有限,我们不仅可以支持更多的并行维度,并且面对更加差异化的Transformer模型结构也能够精准建模,以及在不同的集群硬件条件下验证了其自适应调优的能力。 (2)在复杂性方面,由于我们在多样性上的优势,导致我们面临了前所未有的庞大的搜索空间,为此,我们探究了几条目前大规模分布式训练过程中的一些经过实验性或理论性验证的重要观察,作为我们的搜索空间剪枝准则,从而实现高效的分布式执行计划优化。 (3)在实用性方面,我们结合了理论建模和实验测量两者的优势,实现对内存、通信、计算开销的精确估计,甚至考虑到了计算与通信重叠所导致的GPU执行效率下降问题,从而保证我们能够得到足够准确的自动并行优化结果。 另外,Galvatron底层选择PyTorch作为执行引擎,兼容Huggingface等常见的主流Transformer模型实现,所以完全不会对PyTorch用户带来额外的使用负担;同时也不需要用户付出额外的系统安装或者调试代价,使用时只需要添加几行代码,就可以轻松完成自动并行的整个流程。 关键技术 1. 基于决策树的搜索空间分解 Galvatron的设计目标是高效地在复杂而庞大的并行策略空间内自动搜索,并为给定的Transformer模型和分布式环境生成最佳的并行执行计划。在搜索空间上,Galvatron是业界首个考虑4种主流并行方法的自动并行训练系统,包括包括数据并行(data parallelism, DP)、分片数据并行(sharded data parallelism, SDP)、张量并行(tensor parallelism, TP)和流水并行(pipeline parallelism, PP)。由于混合并行策略会包含以上四种并行算法的任意组合,在多GPU的场景下这种组合带来的搜索空间十分庞大。例如,对于双机四卡场景,一种可行的策略是在机内使用2-way TP,机间使用2-way PP,另一种可行的策略是在机内使用2-way PP,机间使用2-way DP。当节点内GPU数量扩展到8卡时,模型每一层的候选策略都多达上百种。随着模型层数的增加,其搜索空间规模指数增长,难以有效探索。 为了高效地搜索如此庞大的搜索空间,我们首先提出了以下观察作为指导: Takeway#1:PP倾向于被跨设备岛放置。此处“设备岛”指具有高内部带宽的一组设备,在绝大多数Transformer模型中,PP的通信量相比于其它并行方式,显著更少。因此,人们通常优先对模型进行PP切分并放置于设备岛之间。 Takeway#2:在同构设备的前提下,并行策略倾向于将设备均匀切分。例如,对于4卡GPU的2-way DP倾向于将设备切分两组2卡的设备,而不是一组1卡和一组3卡的设备。在这种情况下,一个设备组内的最优混合并行策略与其他组内的最优策略保持一致。 Takeway#3:一般来说,在能够混合使用DP和SDP的情况下,只使用SDP在理论上性能更优。根据分析结果, 基于以上重要观察,我们提出了一种基于决策树的搜索空间构建方法: - 给定一个Transformer模型,基于Takeway#1和Takeway#2,Galvatron首先用PP将模型切分成多个阶段,同时将设备均匀且连续地切分为多个设备组。例如8卡场景下,模型被切分为1/2/4/8-way PP,分别对应设备组大小为8/4/2/1。 - 每种PP切分对应着一棵决策树及一个子搜索空间,决策树叶结点总数为设备组大小,决策树高度为可用的并行方法数量,即决策树每一层可应用一种并行策略。 - 并行策略在决策树不同层间不可重复使用。 - 非叶结点的度数默认在2的指数次幂{2,4,8,…}中选择。 基于以上决策树构建规则,Galvatron构建的决策树能表示以上并行的任意组合。Takeway#1和Takeway#2帮助Galvatron规避了低效的并行组合,缩小了搜索空间。对于8卡GPU训练一层模型的场景,以上规则将产出34种候选的混合并行策略。进一步,使用Takeway#3将DP和SDP同时出现在一棵决策树的情形剪枝后,8卡候选策略数降至22种。 2. 基于动态规划的并行优化算法 3. 基于混合建模的执行代价估计方法 ================================================ FILE: docs/llm-base/distribution-parallelism/auto-parallel/Mesh-Tensorflow.md ================================================ - Mesh-Tensorflow: 广义分布式: https://zhuanlan.zhihu.com/p/342223356 在深度学习中,由于数据量和计算量的浩大,往往会使用到分布式计算。而最常用的分布式模式是SPMD(Single-Program-Multiple-Data),即数据并行,这种模式相当于在数据的batch维去做拆分;然后,进行并行。 Mesh-Tensorflow对这种模式做了泛化,即除了batch维外的其他维度也可做并行。 --- Mesh-Tensorflow的灵感来自于目前广泛使用的数据并行, 数据并行可以看做是把 tensors 和 operations 在 batch 这个维度上进行分割。 Mesh-Tensorflow则顺势把这个点子推广到所有维度。 Mesh-Tensorflow 看定义了一套DSL语法,用于描述模型的维度和布局,你用它重写你的整个Model后,它自动帮你把模型和数据分割到多个TPU上。 Mesh-Tensorflow看起来很复杂和精巧,比 recomputation, pipeline parallelism 等技巧要更复杂更自动化,那它是否就能解决问题呢? 我觉得它侵入性比普通的库(例如GPipe)更强,你需要用Mesh-Tensorflow的语法重写你的整个模型,仔细思考维度,说实话,这个精神负担挺重的(想起了C++)。况且,它目前还没有实现并行的卷积操作,因此对于CNN网络并没有卵用,暂时只适合 Language Model 这个领域. ================================================ FILE: docs/llm-base/distribution-parallelism/auto-parallel/README.md ================================================ - 分布式训练自动并行论文:https://zhuanlan.zhihu.com/p/642446009 - 北大河图大模型自动并行训练工具Galvatron:https://zhuanlan.zhihu.com/p/591924340 - 大规模模型训练:https://www.zhihu.com/question/508671222 - 如何评价Google的GShard论文?:https://www.zhihu.com/question/404721763/answer/2111040851 --- 大模型的自动并行之难主要体现在以下三个方面: (1)多样性:首先,在并行方式方面,目前大模型的并行方式呈现出百花齐放的态势, 即使是对于同一个算子,不考虑混合并行方式,不同的基础并行方式也会存在显著的差异,从而导致不同的内存开销、通信代价以及计算效率。 其次,在模型方面,各种各样的模型架构最近也是层出不穷,这往往也伴随着不同的模型配置(例如不同输入序列长度,模型层数,模型隐层宽度等),从而造成计算负载上的差异。 另外,在硬件方面,用户往往面临着非常差异化的集群环境,可能会面临不同的内存容量、通信带宽、计算能力等等。 总体上来看,由于上述多样性的存在,没有哪种并行技术总是能够获得最佳训练效率,“自动并行”也就成为了分布式训练的核心挑战。 (2)复杂性:上述分析还相对比较单一,实际上哪怕是对于同一个算子也可以同时应用多种不同的基础并行方式, 如果考虑到由这些基础并行方式复合所构成的混合并行方式,则会导致问题变得非常复杂。 更重要的是,大模型的计算图往往结构非常庞大,对应的也需要更大规模的集群,如果对每个算子都进行探索(包括选取集群中合适的计算资源以及设计相应的混合并行方式), 会带来组合空间爆炸的问题,寻找整个模型的最优分布式执行方案变得难以求解。 (3)实用性:除此之外,实用性也是非常重要的问题。 一方面,在进行自动并行搜索的过程中,对于各种分布式执行方案,必须提供比较精确的内存、通信、计算开销, 否则会导致结果与实际执行偏差过大,产生次优解或者根本无法使用。 为此,就需要非常精准的代价模型,对不同的模型结构和硬件条件进行建模。 另一方面,系统提供自动并行能力所带来的额外时间开销必须在一个可以接受的范围内,过于高昂的搜索代价同样也无法接受。 ## One weird trick for parallelizing convolutional neural network 发现不同的层适合用不同的并行方式,具体的,卷积层数据比参数大,适合数据并行,全连接层参数比数据大,适合模型并行。 ## Exploring Hidden Dimensions in Parallelizing Convolutional Neural Networks Alex前面那篇文章直观的提出来,有的层次适合数据并行,有的层次适合模型并行,那么给定一个神经网络,有没有自动的办法找到最优的并行办法呢? 这篇文章就是想解决这个问题。 首先,这篇文章在抽象上更进一步,发现数据并行,模型并行都只是张量切分方式的不同罢了,有的是切数据,有的是切模型,而且对于多维张量,在不同的维度上切分,效果也不同,譬如在sample, channel, width, length等维度都可以切分。 其次,不同的切分方式,都是一种构型(configuration),不同的构型会导致不同的效果,所以寻找最优的并行方式,其实就是在构型空间里面搜索最优的构型而已,问题形式化成一个搜索问题。 最后,引入了代价模型来衡量每个构型的优劣,并提出了一系列对搜索空间剪枝的策略,并实现了原型系统。 这篇文章勾勒了自动并行的基本框架,很多解决自动并行的工作都是这样一个流程。 ## FlexFlow Beyond Data and Model Parallelism for Deep Neural Networks 提出了execution simulator来完善cost model。 ## Tofu Tofu 提出了一套DSL,方便开发者描述张量的划分策略,使用了类似poly的integer interval analysis来描述并行策略,同样,并行策略的搜索算法上也做了很多很有特色的工作 Tofu与所有其它工作的不同之处在于,它的关注点是operator的划分,其它工作的关注点是tensor的划分,二者当然是等价的。不过,我认为关注点放在tensor的划分上更好一些,这不需要用户修改operator的实现,Tofu需要在DSL里描述operator的实现方式。 这种区别也会反应到API层面,譬如Mindspore和OneFlow 作为通用框架里少数实现了完整的数据并行、模型并行的系统,在Python API上也不同,在Mindspore训练盘古模型的示例代码里可以看到Mindspore 的划分接口是放在operator上的,相反,OneFlow的SBP体系是把划分接口放在张量上,在operator API上单卡和分布式完全一样。 ## Mesh-TensorFlow Mesh-TensorFlow的核心理念也是beyond batch splitting,数据并行是batch splitting,模型并行是张量其它维度的切分。这篇文章把集群的加速卡抽象成mesh结构,提出了一种把张量切分并映射到这个mesh结构的办法。 ## GShard ## GSPMD # 全自动并行 ## Alpa ## Unity ================================================ FILE: docs/llm-base/distribution-parallelism/auto-parallel/Unity.md ================================================ - Unity:通过代数变换和并行化的联合优化加速 DNN 训练:https://www.victorlamp.com/article/7387511088 - 【论文赏读】Unity: Accelerating DNN Training Through Joint Opt of Algebraic Transform and Parallelization: https://zhuanlan.zhihu.com/p/560247608 ================================================ FILE: docs/llm-base/distribution-parallelism/auto-parallel/auto-parallel.md ================================================ - Colossal-Auto - MindSpore - [Tofu ](https://arxiv.org/abs/1807.08887), - [Flexflow ](https://arxiv.org/abs/1807.05358), - [Alpa ](https://arxiv.org/abs/2201.12023) ## Alpa 模型量级很大的时候,搜索并行策略的时间非常长. ================================================ FILE: docs/llm-base/distribution-parallelism/auto-parallel/gspmd.md ================================================ - GSPMD - GSPMD:General and Scalable Parallelization for ML Computation Graphs: https://zhuanlan.zhihu.com/p/506026413 - GSPMD: ML计算图的通用可扩展并行化: https://zhuanlan.zhihu.com/p/504670919 ## 原paper GSPMD 是一个用于机器学习计算的高度自动化的并行化系统。 它提供了一个简单但功能强大的 API,该 API 足够通用,可以组合不同的典型并行模式。 GSPMD 提供直观的自动完成功能,使用户只需注解几个张量即可有效地划分整个模型。 我们已经证明,GSPMD 能够在多达数千个 Cloud TPUv3 核心上对多个图像、语音和语言模型进行分区,并具有良好且可预测的性能和内存扩展。 ================================================ FILE: docs/llm-base/distribution-parallelism/auto-parallel/分布式训练自动并行概述.md ================================================ A Survey on Auto-Parallelism of Neural Networks Training ## 2. 问题定义 ================================================ FILE: docs/llm-base/distribution-parallelism/auto-parallel/飞桨面向异构场景下的自动并行设计与实践.md ================================================ - 飞桨面向异构场景下的自动并行设计与实践: https://www.51cto.com/article/753512.html ## 一、背景介绍 第一个维度是自动并行的程度,分为全自动和半自动; 第二个维度是并行粒度,分别是针对每个 Layer 来提供并行策略,或者是针对每一个算子或者张量来提供并行策略; 第三个是表示能力,这里简化为 SPMD(Single Program Multiple Data)并行和 Pipeline 并行两大类; 第四个是特色,这里列出了个人觉得相关工作比较有特色的地方; 第五个是支持硬件,主要写出相关工作所支持最大规模的硬件类型和数量。其中,标红部分主要是对飞桨自动并行研发有启发性的点。 现状思考: 第一点,分布式策略在底层表示上逐渐统一。 第二点,半自动会逐渐成为框架的一种分布式编程范式,而全自动会结合特定的场景和经验规则去探索落地。 第三点,实现一个极致端到端性能,需要采用并行策略与优化策略联合调优来实现。 ## 二、架构设计 ``` 一般完整分布式训练包括 4 个具体的流程。 首先是模型切分,无论是手动并行还是自动并行都需要将模型切分为多个可以并行的任务; 其次是资源获取,可以通过自己搭建或者从平台申请来准备好我们训练所需要的设备资源; 然后是任务放置(或者任务映射),也就是将切分后的任务放置到对应资源上; 最后是分布式执行,就是各个设备上的任务并行执行,并通过消息通信来进行同步和交互。 ``` 现在一些主流的解决方案存在一些问题: 一方面可能只考虑分布式训练中的部分流程,或者只侧重部分流程; 第二个就是过于依赖专家的经验规则,比如模型切分和资源分配;最后是在整个训练的过程中,缺乏对任务和资源的感知能力。 飞桨所设计的端到端自适应分布式训练架构,在全面考虑 4 个流程基础上,又加入第五个流程,即弹性调度。我们核心设计理念主要包括这 3 点: ``` 第一,计算和资源统一表示,并且计算和资源同等重要。 往往大家比较关心怎么切分模型,但是对资源关注度比较少。 我们一方面用统一的分布式计算图来表示各种各样的并行策略;另一方面,我们用统一的分布式资源图来建模各种各样的机器资源,既能表示同构的,又能表示异构的资源连接关系,还包括资源本身的计算和存储能力。 第二,最大化解耦,除了模块之间解耦外,我们还将逻辑切分跟物理放置以及分布式执行等进行解耦,这样能够更好地实现不同模型在不同集群资源高效执行。 第三,端到端自适应,涵盖分布式训练所涉及的全面流程,并采用一个全局的代表模型来驱动并行策略或者资源放置的自适应决策,来尽可能代替人工定制化决策。上图浅蓝色框住的部分就是本次报告所介绍的自动并行相关工作。 ``` 1、统一分布式计算图 ``` 首先是统一的分布式计算图。 统一目的是便于我们采用统一方式来表示现有的各种各样的并行策略,这样利于做自动化处理。 众所周知,串行计算图能表示各种各样的模型,类似地,我们在串行计算图的基础上,对每个算子和张量加上分布式属性来作为分布式计算图,这种细粒度方式能表示现有并行策略,而且语义会更丰富和通用,还能表示新的并行策略。 分布式计算图中的分布式属性主要包括三个方面信息: 1)需要表示张量怎么切分或者算子怎么切分; 2)需要表示在哪些资源进行分布式计算; 3)如何将切分后的张量或算子映射到资源上。 对比串行计算图,分布式计算图有 3 个基础组成概念: 分布式张量,类似于串行的张量; 分布式算子,类似于串行的算子; 分布式重排,分布式计算图独有。 ``` (1)分布式张量 首先,介绍分布式张量所包括的三个方面信息: ① 串行张量信息:主要包含张量 shape、dtype 等一些元信息,一般实际计算不需要对串行张量进行实例化。 ② ProcessMesh:进程的 cartesion topology 表示,有别于 DeviceMesh,我们之所以采用 ProcessMesh,主要希望逻辑的进程跟物理设备进行一个解耦,这样便于做更高效任务映射。 ③ ShardSpec:用来表示串行张量每个维度用 ProcessMesh 哪个维度进行切分,具体可看下图示例。 ``` 假如有一个二维的 6*12 张量和一个 3*2 的 ProcessMesh(第一维是 x,第二维是 y,元素是进程 ID)。 如果 ShardSpec 是 [None,None],就表示张量第 0 维和第 2 维都不切分,每个进程上都有一个全量张量。 如果 ShardSpec是 ['x’, ‘y’],表示用 ProcessMesh 的 x 轴去切张量第 0 维,用 ProcessMesh 的 y 轴去切张量第 1 维,这样每个进程都有一个 2*6 大小的 Local 张量。 总之,通过 ProcessMesh 和 ShardSpec 以及张量未切分前的串行信息,就能够表示一个张量在相关进程上切分情况。 ``` (2)分布式算子 ``` 分布式算子表示是基于分布式张量的,包括串行算子信息,输入和输出张量的分布式属性。 类似一个分布式张量可能会对应多种切分方式,分布式算子里面的分布式属性不一样,对应着不同切分。 以矩形乘 Y=X*W 算子为例,如果输入和输出分布式属性不同,就对应不同的分布式算子实现(分布属性包括 ProcessMesh 和 ShardSpec)。 对于分布式算子来说,其输入和输出张量的 ProcessMesh 相同。 ``` (3)分布式重排 ``` 最后一个是分布式重排,这是分布式计算图所必须具有的概念,用来处理源张量和目的张量分布式属性不同的情况。 比如有 2 个算子的计算,上一个算子产生 y,跟下一个算子使用 y 分布式属性不同(图中用不同颜色表示),这时我们需要插入额外的一个 Reshard 操作来通过通信进行张量分布式重排,本质就是处理生产和消费不匹配问题。 导致不匹配的原因主要有三个方面: 1)支持数据和计算分离,所以对张量和使用它的算子有不同的分布式属性; 2)支持用户自定义标记分布式属性,用户可能对张量和使用它的算子标记不同的分布式属性; 3)分布式算子底层实现有限,如果出现了输入或者输出分布式属性不支持的情况,也需要通过分布式重排。 ``` 2、统一分布式资源图 ``` 介绍完统一的分布计算图三个基本概念后,再看统一的分布式资源图,主要设计的考量: 1)支持异构集群,异构集群就是集群中可能有 CPU、GPU、XPU 资源; 2)表示拓扑连接,这里面涵盖了集群的层次结构连接关系,包括对连接能力的量化,比如带宽或者延迟; 3)设备本身建模,包括一个设备的存储和计算能力。 为了满足上面设计需求,我们用Cluster来表示分布式资源,它包含多个同构 DeviceMesh。每个 DeviceMesh 内会隐含一个由 Device 链接组成的 Graph。 这里举个例子,上图可以看到有 4 台机器,包括 2 个 GPU 机器和 2 个 XPU 机器。 对于 2 台 GPU 机器,会用一个同构的 DeviceMesh 表示,而对于 2 台 XPU 机器,会用另一个同构的 DeviceMesh 表示。 对于一个固定集群来说,它的 DeviceMesh 是固定不变的,而用户操作的是 ProcessMesh,可以理解是 DeviceMesh 的抽象,用户可以随意 Reshape 和 Slice,最后会统一地将 ProcessMesh 进程映射到 DeviceMesh 设备上。 ``` 采用前面基于张量和算子细粒度的分布式计算图表示,能涵盖现有并行策略以及未来可能会出现新的并行策略。 ``` 数据并行就是对数据张量的 Batch 维度进行切分。 模型并行对权重相关维度进行切分。 流水线并行使用不同 ProcessMesh 来表示,它可以表示为更灵活 Pipeline 并行,比如一个 Pipeline Stage 可以连接多个 Pipeline Stage,而且不同 Stage 使用 ProcessMesh 的 shape 可以不同。其他有些框架的流水线并行是通过 Stage Number 或者 Placement 实现,不够灵活通用。 混合并行就是数据并行,张量模型并行和流水线并行三者混合。 ``` ## 三、关键实现 上图是飞桨整个自动并行的流程图。 ``` 首先我们会基于一个串行前向计算图,进行反向生成,获得包括前向、后向和更新子图的完整计算图。 然后,需要明确组网中每个张量和每个算子的分布式属性。既可以采用半自动的推导方式,也可以采用全自动搜索方式。 本报告主要讲解半自动推导方式,即基于用户少量标记来推导其他未标记张量和算子的分布式属性。通过分布式属性推导后,串行计算图中每个张量和每个算子都有自己的分布式属性。基于分布式属性,先通过自动切分模块,将串行计算图变成支持 SPMD 并行的逻辑分布式计算图,再通过分布式重排,实现支持 Pipeline 并行的逻辑分布式计算图。 生成的逻辑分布式计算图会通过物理映射,变成物理分布式计算图,目前只支持一个进程和一个设备的一一映射。 最后,将物理分布式计算图变成一个实际任务依赖图交给异步执行器进行实际执行。 ``` ### 1、分布式属性推导 分布式属性推导就是给定计算图中部分张量和算子的分布式属性,自动补全其他所有的张量和算子的分布式属性。 例子是两个 Matmul 计算,用户只标记了两个参数分布式属性,表示 W1 在 0,1 进程上进行列切,W2 是在 2,3 进程上进行行切,这里有两个不同 ProcessMesh,用不同的颜色表示。 分布式属性推导分为两个步骤: 1)先进行 ProcessMesh 传导,实现 Pipeline 切分; 2)再进行 ShardSpec 传导,实现一个 Stage 内的 SPMD 切分。ProcessMesh 推导利用了飞桨线性 Program lR, 按静态 Program Order 采用就近选择策略进行推导,支持包含计算,即如果两个 ProcessMesh,一个大一个小,就选较大作为最终 ProcessMesh。 而 ShardSpec 推导利用飞桨 SSA Graph IR 进行前向和后向数据流分析进行推导,之所以可以用数据流分析,是因为 ShardSpec 语义,满足数据流分析的 Semilattice 性质。数流分析理论上能保证收敛,通过结合前向和后向分析,能够将计算图任何一个位置标记信息传播到整张计算图,而不是只能单方向传播。 基于分布式属性推导,串行计算图中的每个张量和算子都拥有自己的分布式属性,这样就可以基于分布式属性进行计算图的自动切分。 按照例子来说,就是把单机串行计算图,变成 Rank0、Rank1,Rank2、Rank3 四个计算图。 简单来说,会遍历每个算子,先对算子输入和输出进行张量切分,然后再对每个算子进行计算切分。 张量切分会通过 Distributed Tensor 对象来构造 Local Tensor 对象, 而算子切分会通过 Distributed Operator 对象来基于实际输入和输出的分布属性来选择对应分布式实现,类似于单机框架的算子到 Kernel 的分发过程。 --- 通过前面自动切分,只能获得支持 SPMD 并行的分布式计算图。为了支持 Pipeline 并行,还需要通过分布式重排来处理,这样通过插入一个合适的 Reshard 操作,例子中每个 Rank 拥有自己真正独立计算图。虽然左图 Rank0 的 Y 跟 Rank2 的 Y,切分一样,但是由于他们在不同 ProcessMesh 上,导致了生产消费分布式属性不匹配,所以也需要插入 Reshard。 飞桨目前支持两类分布式重排。 第一类,是比较常见源张量分布跟目标张量分布都在同一个 ProcessMesh 上,但是源张量分布和目标张量分布所使用切分方式不一样(即 ShardSpec 不一样)。 第二类,是源张量分布和目标张量分布在不同的 ProcessMesh 上,而且 ProcessMesh 大小可以不一样,比如图中情形 2 中的 0-5 进程和 6-9 进程。为了尽可能减少通信,飞桨也对 Reshard 操作进行相关优化。 经过分布式重排后,得到一个逻辑上的分布式计算图,这个时候还没有决定进程和具体设备映射。 基于逻辑的分布式计算图和前面统一的资源表示图,会进行物理映射操作,也就是 Rank Mapping,就是从多种映射方案(一个进程具体跟哪个设备进行映射)中找到一个最优的映射方案。 这里介绍一个比较简单基于贪心规则的实现。先构建进程和进程间通信量的邻接表,边表示通信量,节点表示设备需求,再构建设备与设备之间的邻接表,边表示通信带宽,节点表示设备计算和内存。我们会任选一个进程 R 放置到满足需求的设备 D 上,放置后,选择与 R 通信量最大的进程放到 D 所在机器其他设备上,按照这种方式直到完成所有进程映射。在映射过程中,需要判断所选择的设备与进程图所需求的设备类型以及所需要计算量和内存是否匹配。 通过物理映射后,我们会根据所获得的物理分布式组网构建实际任务依赖图。 图中示例是基于计算图的前向、后向和更新角色来构建任务依赖图,相同角色的算子会组成一个任务。为了支持 Micro-batching 优化,一个任务依赖图会生成多个任务实例依赖图,每个示例虽然计算逻辑一样,但是使用不同内存。 目前飞桨会自动地根据计算图角色去构建任务图,但是用户可以根据合适粒度自定义任务构建。每个进程有了任务多实例依赖图后就会基于 Actor 模式进行异步执行,通过消息驱动方式就可以自动地实现 1F1B 执行调度。 基于上面整个流程,我们已经实现一个功能比较完备的自动并行。 但只有并行策略还无法获得一个比较好的端到端性能,所以我们还需要加入相应的优化策略。 对飞桨自动并行,我们会在一个自动切分之前和组网切分之后加一些优化策略, 这是因为一些优化在串行逻辑上实现比较自然,有一些优化在切分后比较容易实现,通过统一的优化 Pass 管理机制,我们能够保证飞桨自动并行中并行策略与优化策略自由结合。 ## 四、应用实践 首先是接口,不管如何实现,用户最终还是通过接口来使用我们所提供的自动并行能力。 如果对用户分布式需求进行拆解,包括模型组网切分,资源表示,数据分布式加载,分布式执行过程控制和分布式保存和恢复等。 为了满足这些需求,我们提供了一个 Engine 类,它同时兼顾易用性和灵活性。 易用性方面,它提供了高阶 API,能支持自定义 Callback,分布式过程对用户透明。 灵活性方面,它提供了低阶 API,包括分布式 dataloader 构建,自动并行切图和执行等接口,用户可以进行更细粒度控制。 两者会共享 shard_tensor、shard_op 以及 save 和 load 等接口。 这里有两个标记接口 shard_op 和 shard_tensor。 其中,shard_op 既可以标记单个算子,也可以对整个 Module 进行标记,是函数式。 上图是一个非常简单的使用示例。 首先,使用飞桨已有 API 进行一个串行组网,在其中,我们会使用 shard_tensor 或者 shard_op 进行非侵入式分布式属性标记。 然后,构建一个自动并行 Engine,传入模型相关信息和配置。这个时候用户有两个选择, 一个选择是直接使用 fit /evaluate/predict 高阶接口, 另一种选择是使用 dataloader+prepare+run 接口。 如果选择 fit 接口,用户只需要传 Dataset,框架会自动进行分布式数据集加载,自动并行过程编译和分布式训练执行。 如果选择 dataloader+prepare+run 接口,用户可以将分布式数据加载、自动并行编译和分布式执行进行解耦,能更好进行单步调试。 PaddleFleetX 是具备易用性和高性能的一个端到端的一站式大模型套件,支持自动并行功能。 用户要想调用飞桨自动并行端到端功能,只需要提供串行动态图模型组网即可。 在获得用户动态图串行组网后,内部实现会利用飞桨动转静模块,将动态图单卡组网变成静态图单卡组网, 然后通过自动并行编译,最后再进行分布式训练。 在推理生成时候,使用的机器资源可能与训练时使用的资源不太一样,内部实现还会进行参数和组网的自适应参数切分。 目前 PaddleFleetX 中的自动并行涵盖了大家常用的并行策略和优化策略,并支持两者任意组合,而且对生成任务来说,还支持 While 控制流的自动切分。 ## 五、总结展望 飞桨自动并行还有很多工作在开展中,目前的特色可以总结为以下几方面: 首先,统一的分布式计算图,能够支持完备的 SPMD 和 Pipeline 的分布式策略,能够支持存储和计算的分离式表示; 第二,统一的分布式资源图,能够支持异构资源的建模和表示; 第三,支持并行策略和优化策略的有机结合; 第四,提供了比较完备的接口体系; 最后,作为关键组成,支撑飞桨端到端的自适应分布式架构。 并行一般可以分为两个领域(没有明确分界),一个是传统的分布式计算,一个是传统高性能计算,两者各有优劣。 基于传统分布式计算的框架代表是 TensorFlow,它侧重 MPMD(Multiple Program-Multiple Data)并行模式,能够很好支持弹性和容错,分布式计算的用户体验会好一些,编程较简单,用户一般是以一个串行全局视角进行编程; 基于传统高性能的计算的框架代表是 PyTorch,更侧重 SPMD(Single Program-Multiple Data)模式,追求极致性能,用户需要直接面临物理集群进行编程,自己负责切分模型和插入合适通信,对用户要求较高。 而自动并行或者自适应分布式计算,可以看作两者结合。当然不同架构设计侧重点不一样,需要根据实际需求进行权衡,我们希望飞桨自适应架构能够兼顾两个领域的优势。 ================================================ FILE: docs/llm-base/distribution-parallelism/data-parallelism/README.md ================================================ ================================================ FILE: docs/llm-base/distribution-parallelism/moe-parallel/README.md ================================================ - https://github.com/laekov/fastmoe - SmartMoE: https://github.com/zms1999/SmartMoE - 飞浆-MOE:https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/06_distributed_training/moe_cn.html - - https://blog.csdn.net/qq_41185868/article/details/103219988 - [GShard-MoE](https://arxiv.org/abs/2006.16668) GShard,Switch-Transformer, GLaM - Mixture-of-Experts (MoE) 经典论文一览:https://zhuanlan.zhihu.com/p/542465517 ``` GShard,按照文章的说法,是第一个将MoE的思想拓展到Transformer上的工作。 具体的做法是,把Transformer的encoder和decoder中,每隔一个(every other)的FFN层,替换成position-wise 的 MoE层,使用的都是 Top-2 gating network。 跟其他MoE模型的一个显著不同就是,Switch Transformer 的 gating network 每次只 route 到 1 个 expert,而其他的模型都是至少2个。 这样就是最稀疏的MoE了,因此单单从MoE layer的计算效率上讲是最高的了。 ``` - Google的 Pathways(理想)与 PaLM(现实):https://zhuanlan.zhihu.com/p/541281939 ``` 当前模型的主要问题: 基本都是一个模型做一个任务; 在一个通用的模型上继续fine-tune,会遗忘很多其他知识; 基本都是单模态; 基本都是 dense 模型,在完成一个任务时(不管难易程度),网络的所有参数都被激活和使用; Pathways 的愿景 —— 一个跟接近人脑的框架: 一个模型,可以做多任务,多模态 sparse model,在做任务时,只是 sparsely activated,只使用一部分的参数 ``` - GShard论文笔记(1)-MoE结构:https://zhuanlan.zhihu.com/p/344344373 ``` Mixture-of-Experts结构的模型更像是一个智囊团,里面有多个专家,你的问题会分配给最相关的一个或多个专家,综合他们的意见得到最终结果。 为了实现这个结构,显而易见需要两部分: 1)分发器:根据你的问题决定应该问哪些专家 2)一群各有所长的专家:根据分发器分过来的问题做解答 3)(可选)综合器:很多专家如果同事给出了意见,决定如何整合这些意见,这个东西某种程度上和分发器是一样的,其实就是根据问题,给各个专家分配一个权重 左边部分展示了普通的Transformer模型,右边展示了引入MoE结构的Transformer模型:其实就是把原来的FFN(两层全连接)替换成了红框里的MoE结构。不过MoE里面的“专家”依旧是FFN,只是从单个FFN换成了一群FFN,又加了一个分发器(图中的Gating)。分发器的任务是把不同的token分发给不同的专家。 看完了专家和分发器的作用,我们再进一步看看GShard里面他们的具体实现: 对于分发器来说,在训练过程中,最好把token平均分配给各个专家:不然有些专家闲着,有些专家一堆事,会影响训练速度,而且那些整天无所事事的专家肯定最后训练的效果不好。。。因此分发器有一个很重要的任务,就是尽可能把token均分给各个专家。 为了完成这个目标,有一些繁琐的设定: 1)引入了一个loss,专门用来控制我分发器分发的怎么样:如果我把token都分给一个人,loss就很高,分的越均匀(最好是彻底均分),loss越小 2)每个token最多分配给两个专家。如果我每个token哐叽一下发给了所有人,那我多专家有什么意义?(专家之间的差别主要就是训练数据的不同引起的) 3)每个专家每次最多接手C个token。和2类似,如果一个专家成天:“教练,我想打篮球”,“教练,我想唱”,“教练,我想rapper”。。。那估计最后学出来也是四不像 ``` ================================================ FILE: docs/llm-base/distribution-parallelism/moe-parallel/moe-framework.md ================================================ ## colossalai - https://colossalai.org/zh-Hans/docs/advanced_tutorials/integrate_mixture_of_experts_into_your_model/ ## paddle - https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/06_distributed_training/moe_cn.html ``` python -m paddle.distributed.launch --gpus=0,1,2,3,4,5,6,7 --log_dir logs train_moe.py ``` ## deepspeed - https://www.deepspeed.ai/tutorials/mixture-of-experts/ - https://www.deepspeed.ai/tutorials/mixture-of-experts/ - https://github.com/microsoft/DeepSpeedExamples/blob/master/training/cifar/run_ds_moe.sh - https://colossalai.org/zh-Hans/docs/advanced_tutorials/integrate_mixture_of_experts_into_your_model/ ================================================ FILE: docs/llm-base/distribution-parallelism/moe-parallel/moe-parallel.md ================================================ ================================================ FILE: docs/llm-base/distribution-parallelism/moe-parallel/paddle_moe.py ================================================ # 导入需要的包 import paddle from paddle.nn import Layer, LayerList, Linear, Dropout from paddle.incubate.distributed.models.moe import MoELayer from paddle.distributed.collective import Group from paddle.distributed import fleet import numpy as np num_experts = 8 d_model = 512 d_hidden = 2048 # 封装专家层 class ExpertLayer(Layer): def __init__(self, d_model, d_hidden, name=None): super().__init__() self.htoh4 = Linear(d_model, d_hidden) self.h4toh = Linear(d_hidden, d_model) def forward(self, x): x = self.htoh4(x) x = self.h4toh(x) return x # 初始化分布式环境,并构建 expert 通信组 moe_group fleet.init(is_collective=True) moe_group = paddle.distributed.new_group(list(range(fleet.worker_num()))) gate_config = { "type": "gshard", "top_k": 2, } experts_list = LayerList() for expi in range(num_experts): exp_layer = ExpertLayer(d_model, d_hidden) experts_list.append(exp_layer) # 调用 MoELayer API 封装并创建出 MoE 模型 class Model(Layer): def __init__(self, d_model, d_hidden, name=None): super().__init__() self.linear1 = Linear(d_model, d_model) self.moe_layer = MoELayer(d_model = d_model, experts=experts_list, gate=gate_config, moe_group=moe_group, recompute_interval=0) self.linear2 = Linear(d_model, d_model) self.dropout = Dropout(p=0.1) def forward(self, x): x = self.linear1(x) x = self.moe_layer(x) x = self.linear2(x) x = self.dropout(x) return x model = Model(d_model, d_hidden) optim = paddle.optimizer.SGD(parameters=model.parameters()) # 创建数据集,开始训练 for step in range(1, 100): x = paddle.rand([4, 256, d_model]) y = model(x) loss = y.mean() loss.backward() optim.step() optim.clear_grad() print("=== step : {}, loss : {}".format(step, loss.numpy())) ================================================ FILE: docs/llm-base/distribution-parallelism/multidimensional-hybrid-parallel/README.md ================================================ - https://huggingface.co/docs/transformers/perf_train_gpu_many - https://huggingface.co/transformers/v4.12.5/parallelism.html ## 大模型多维混合并行汇总 | 模型 | DP | TP | PP | ZeRO Stage | FSDP(ZeRO Stage 3) | GPUs | FP16/BF16 | 训练框架 | | ------------ | --- | --- | --- | ---------- | ------------------ | ----------------------- | ------ | ------ | | Bloom-176B | 8 | 4 | 12 | ZeRO-1 | - | 384 张 A100 80GB | BF16 | Megatron-DeepSpeed | | CodeGeeX-13B | 192 | 8 | - | ZeRO-2 | - | 1,536 张 Ascend 910 32GB | FP16 | Megatron-LM | | GLM-130B | 24 | 4 | 8 | ZeRO-1 | - | 768 张 A100 40G | FP16 | Megatron-LM + DeepSpeed | | OPT-175B | 124 | 8 | - | - | ✅ | 992 张 80GB A100 | FP16 | PyTorch + Megatron | | Megatron-Turing NLG-530B | 16 | 8 | 35 | - | - | 4480 张 A100 80G | BF16 | Megatron-LM + DeepSpeed | | GPT-NeoX-20B | 12 | 2 | 4 |ZeRO-1 | - | 96 张 A100 40G | FP16 | PyTorch v1.10.0 + NCCL 2.10.3 + CUDA 11.1 + Megatron-LM + DeepSpeed | ### Bloom-176B - https://huggingface.co/bigscience/bloom - https://github.com/bigscience-workshop/bigscience/blob/master/train/tr11-176B-ml/tr11-176B-ml.slurm - https://github.com/bigscience-workshop/bigscience/ ``` Hardware: - 384 A100 80GB GPUs (48 nodes) - Additional 32 A100 80GB GPUs (4 nodes) in reserve - 8 GPUs per node Using NVLink 4 inter-gpu connects, 4 OmniPath links - CPU: AMD - CPU memory: 512GB per node - GPU memory: 640GB per node - Inter-node connect: Omni-Path Architecture (OPA) - NCCL-communications network: a fully dedicated subnet - Disc IO network: shared network with other types of nodes model: vocabulary size: 250,680 Total seen tokens: **366B** Bf16 weights: 329GB Full checkpoint with optimizer states: 2.3TB MICRO_BATCH_SIZE=2 # was MBS=1 till GBS=784 GLOBAL_BATCH_SIZE=2048 # 4.2M tokens. It is larger than the initial plan of 3.2M tokens to get higher throughput NHIDDEN=14336 NLAYERS=70 NHEADS=112 SEQ_LEN=2048 ZERO_STAGE=0 # important: bf16 must use z0! it implements its own zero stage 1 equivalent ``` ## CodeGeeX-13B 为了提高训练效率,我们采用8路模型并行训练和192路数据并行训练,启用 ZeRO-2 进一步减少优化器状态的内存消耗。 最后,微批量大小为每个节点 16 个,全局批量大小达到 3,072。 ``` Model parameters: 13B Vocabulary size: 52224 Position embedding: Learnable Maximum sequence length: 2048 Hidden size h: 5120 Feed-forward size 4h: 20480 Feed-forward activation: FastGELU Layernorm epsilon: 1e-5 Layernorm precision: FP32 Number of attention heads hn: 40 Attention softmax precision :FP32 Dropout rate: 0.1 Global batch size: 3072 ``` we use Adam optimizer (Kingma and Ba, 2014) to optimize the loss in Equation 2. The model weights are under FP16 format, except that we use FP32 for layer-norm and softmax for higher precision and stability. The model takes about 27GB of GPU memory. We start from an initial learning rate 1e-4, and apply a cosine learning rate decay ## GLM-130B ``` adopt 4-way tensor parallelism and 8-way pipeline parallelism 96 台 A100(40G*8) fp16 True glu_activation geglu hidden_size 12288 ffn_hidden_size 32768 num_layers 70 num_attention_heads 96 seq_length 2048 global_batch_size 4224 learning_rate 8e-05 ``` ## OPT-175B - https://github.com/facebookresearch/metaseq/tree/main/projects/OPT - [GitHub - facebookresearch/metaseq: Repo for external large-scale work](https://github.com/facebookresearch/metaseq/) - [Fully Sharded Data Parallel | FairScale documentation](https://fairscale.readthedocs.io/en/stable/api/nn/fsdp.html) - [Getting Started with Fully Sharded Data Parallel(FSDP) — PyTorch Tutorials 2.0.1+cu117 documentation](https://pytorch.org/tutorials/intermediate/FSDP_tutorial.html) ``` FP16 trained OPT-175B on 992 80GB A100 GPUs, by utilizing Fully Sharded Data Parallel with Megatron-LM Tensor Parallelism 通过利用完全分片数据并行与 Megatron-LM 张量并行 roughly ~33 days of continuous training 300B tokens ``` ### BloombergGPT We use the Amazon SageMaker service provided by AWS to train and evaluate BloombergGPT. We use the latest version available at the time of training and train on a total of 64 p4d.24xlarge instances. Each p4d.24xlarge instance has 8 NVIDIA 40GB A100 GPUs with NVIDIA NVSwitch intra-node connections (600 GB/s) and NVIDIA GPUDirect using AWS Elastic Fabric Adapter (EFA) inter-node connections (400 Gb/s). This yields a total of 512 40GB A100 GPUs. we rely on stage 3 of ZeRO optimization. We utilize the proprietary SageMaker Model Parallelism (SMP) library from AWS, which enables the automatic distribution of large models across multiple GPU devices and instances ZeRO shards the training state (model parameters, gradients, and optimizer state) across a group of GPUs. We shard a model across 128 GPUs, and we have 4 copies of the model during training ## Megatron-Turing NLG(530B) 我们使用了 Transformer 解码器的架构 [52],它是一个从左到右、自回归、基于生成 Transformer 的语言模型,并将其扩展到 5300 亿个参数。 层数、隐藏维度、注意力头分别为 105、20480 和 128。 序列长度为2048,全局批量大小为1920。 我们使用 8 路张量和 35 路管道并行。 学习率为5:0e−5。 我们使用 10 亿个代币进行线性学习率预热。 我们使用余弦衰减来使学习率目标达到超过 3400 亿代币价值的 10%。 在前 120 亿个代币中,我们从 32 的批量大小开始,并以 32 为增量逐渐增加批量大小,直到达到最终的批量大小 1920。 我们使用 Adam 优化器,β1 = 0:9、β2 = 0:95 和 = 10−8。 我们将梯度范数限制为 1.0,并使用 0.1 的权重衰减。 对于权重初始化,我们使用均值为零、标准差为 4:0e−3 的正态分布。 我们的训练数据集由 3390 亿个令牌组成,我们通过混合上述 15 个训练数据集在 2700 亿个令牌上训练 MT-NLG。 我们还留出 2% 的数据进行验证。 对于 MT-NLG 等模型的规模,训练稳定性是一个根本性的挑战。 在训练模型时,我们观察到学习率、权重初始化和 Adam 优化器参数直接影响模型的稳定性。 我们通过在 [9] 中绘制学习率与模型大小来预测 MT-NLG 的学习率。 较高的学习率会增加模型的稳定性。 我们使用大约 p1=(3 ∗ H) 作为权重初始化的标准差,其中 H 表示隐藏维度的大小。 与[45]类似,我们还观察到使用更高的方差进行权重初始化无法收敛。 我们还降低了 β2 的标准值 0:99,以减少训练损失的峰值。 训练过程一共使用了4480块英伟达A100 GPU 5300亿个参数的模型,每个模型副本跨越280个NVIDIA A100 GPU,节点内采用Megatron-LM的8路张量切片(tensor-slicing),节点间采用35路管道并行。 基于NVIDIA DGX SuperPOD的Selene超级计算机上完成混合精度训练。(该超级计算机由560个DGX A100服务器提供支持,每个DGX A100有8个 NVIDIA A100 80GB Tensor Core GPU,通过NVLink 和 NVSwitch相互完全连接)。 Model training is done with mixed precision using 16-bit bfloat on NVIDIA’s Selene supercomputer with 560 DGX A100 nodes. Each cluster node has 8 NVIDIA 80-GB A100 GPUs, connected to each other by NVLink and NVSwitch. Each node has eight NVIDIA Mellanox 200Gbps HDR Infiniband HCAs for application communication, with an additional two HCAs per node for dedicated storage. The nodes are connected in a three-level (leaf, spine, core) fat-tree topology with 850 switches. This topology allows efficient all-reduce communication (which is the dominant communication pattern in deep learning training). The cluster uses an all-NVME shared parallel filesystem for high-performance data access and storage. The peak device throughput of an A100 GPU with 16-bit precision is 312 teraFLOP/s, resulting in an aggregate of 1.4 exaFLOP/s of peak 16-bit precision performance mixed precision using 16-bit bfloat ## GPT-NeoX-20B We trained GPT-NeoX-20B on twelve Supermicro AS-4124GO-NART servers, each with eight NVIDIA A100-SXM4-40GB GPUs and configured with two AMD EPYC 7532 CPUs. All GPUs can directly access the InfiniBand switched fabric through one of four ConnectX-6 HCAs for GPUDirect RDMA. Two NVIDIA MQM8700-HS2R switches—connected by 16 links—compose the spine of this InfiniBand network, with one link per node CPU socket connected to each switch. Figure 2 shows a simplified overview of a node as configured for training。 ================================================ FILE: docs/llm-base/distribution-parallelism/pipeline-parallelism/README.md ================================================ DP 将批次(global batch size)拆分为小批次(mini-batch)。PP 将一个小批次切分为多个块 (chunks),因此,PP 引入了微批次(micro-batch,MBS) 的概念。 计算 DP + PP 设置的全局批量大小的公式为: `mbs*chunks*dp_degree` , 比如:DP并行度为4,微批次大小为8,块为32,则全局批次大小为:`8*32*4=1024`。 ================================================ FILE: docs/llm-base/distribution-parallelism/tensor-parallel/README.md ================================================ Megatron-LM 的张量并行,通信量很大,同时,计算和通信没办法同时进行。 需要特别考虑的是:由于前向和后向传播中每层都有两个 all reduce,因此 TP 需要设备间有非常快速的互联。因此,除非你有一个非常快的网络,否则不建议跨多个节点进行 TP。 ================================================ FILE: docs/llm-base/distribution-parallelism/tensor-parallel/tensor-parallel.md ================================================ 我们以一个线性层为例,它包括一个通用矩阵乘法(GEMM):$Y=XA$。 给定2个处理器,我们把列 A 划分为 $[A1 A2]$, 并在每个处理器上计算 $Y_i=XA_i$ , 然后,形成 $[Y_1 Y_2]=[XA_1 XA_2]$。 这被称为列并行方式。 当第二个线性层 $Z=YB$ 跟随上述列并行层的时候,我们把 B 划分为 $ \begin{bmatrix} B1 \\\ B2 \end{bmatrix} $,这就是所谓的行并行方式。 为了计算 $ Z = \begin{bmatrix} Y1 & Y2 \end{bmatrix} \begin{bmatrix} B1 \\\ B2 \end{bmatrix} $,我们首先在每个处理器上计算$Y_iB_i$,然后使用一个all-reduce操作将结果汇总为 $Z=Y_1B_1+Y_2B_2$。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/15955f8b9f7c4c139f6f82c98eeb357d~tplv-k3u1fbpfcp-watermark.image?) 需要注意,在后向计算中,列并行线性层需要聚合输入张量 X, 因为在每个处理器 i 上,我们只有 $\dot{X_i}=\dot{Y_i} A_i^T$,其中,$\dot{X_i}和\dot{Y_i}$为一阶导数,因此,我们在各处理器之间进行all-reduce,得到 $\dot{X}=\dot{Y}A^T=\dot{Y_1}A_1^T+\dot{Y_2}A_2^T$。 参考: - 图解大模型训练之:张量模型并行Megatron-LM :https://zhuanlan.zhihu.com/p/622212228 - Megatron论文和代码详细分析:https://zhuanlan.zhihu.com/p/366906920 - [源码解析]模型并行分布式训练Megatron : https://juejin.cn/post/7057837676430360584 - 张量模型并行详解 | 深度学习分布式训练专题 :https://www.paddlepaddle.org.cn/support/news?action=detail&id=2913 ================================================ FILE: docs/llm-base/distribution-parallelism/并行技术.drawio ================================================ 5ZjZbuIwFIafJpegJM56OaGUSqNKaFDVa+OYxMKJU2MGMk8/TuMsJqlaJJbRlAtk/8fr//mYBAPMsuOCwyJ9ZjGmhm3GRwM8GLYdOp78roSyFtwwrIWEk7iWrE5YkT9YiaZS9yTGO62hYIwKUugiYnmOkdA0yDk76M02jOqzFjDBA2GFIB2qryQWaa0Gtt/pT5gkaTOz5an9ZbBprHayS2HMDj0JzA0w44yJupQdZ5hW3jW+1P0eP4i2C+M4F1/qEKzXE/dn+foI357zlwVZRXyiRvkN6V5teLF8kUKzZlE2RnC2z2NcjWUaIDqkROBVAVEVPUjyUktFRmXNksUNoXTGKOPvfUEMcbBBUt8Jzra4F/FQgNcbGVHrwFzg44cbtFrb5HHDLMOCl7KJ6tCuumw2rOqHDpzV0Eh70DylQXVWknbozk5ZUI6e4a49cNewPSoqIwqYy3JSlWvH25CcqR+9DggmexBRGeW7Y1xM+QHgMlycf44LOIOLdQsumwBhNJog68B1XPM6CQLse4NwzgABbgringlyfy7uCJcTl+XPWVEV0Z7TMuIQbbH43O6OjXUZ7yzv88tlzLo2Fy7unXcb7zgTUBCWy2p4ofsBOOEUBJqdE8ucevaXHAW2NbXdK5nqD0x9WBpz34giI3AG/koLhO6dnr85y/FJ7isJUpJUliJpGZZ6VBlK5OPgDxXISBxX04zC0m+eS5zuk5vB9oen2xk93VfiEAw4LL8DB+C4+i0zckPflEM44PAL5tvRB/f/BkKgM2j32mPg35JB84o6hGB9GwjAuRoEWe1ejt9jvX8YwPwvldGxDoIwEADQr+loghRRRgOoi3FgUCdTaYGawpFSFPx6MQWxYdGlub5ce70rwn7ebCUpsz1QJpBt0QbhANm257jd+oZWw8LzNKSSU03zESL+ZD1avdacsspIVABC8dLEGIqCxcowIiU8zLQEhFm1JCmbQBQTMdUjpyrTurKXo+8YT7Oh8tzt+8vJkNx3UmWEwuOLcIiwLwGUjvLGZ+I9u2EuZ6feXu7t+pq0VdIEN344uTN92eafI58WJCvUr1d3wfi0bmP8Lw5f ================================================ FILE: docs/llm-base/distribution-training/Bloom-176B训练经验.md ================================================ - https://huggingface.co/blog/zh/bloom-megatron-deepspeed 用 FP16 训练巨型 LLM 模型是一个禁忌。FP16 经常溢出!FP16 的最大数值范围为 64k,您只能进行较小数的乘法。例如你可以做 250*250=62500,但如果你尝试 255*255=65025,你就会溢出,这是导致训练出现问题的主要原因。这意味着你的权重必须保持很小。一种称为损失缩放 (loss scaling) 的技术有助于缓解这个问题,但是当模型变得非常大时,FP16 较小的数值范围仍然是一个问题。 由于 BF16 和 FP16 的大小相同,均为 2 个字节,因此,没有免费的午餐,当使用 BF16 时,代价就是它的精度非常差。然而,你应该还记得我们在训练时采用的随机梯度下降法及其变体,该方法有点像蹒跚而行,如果你这步没有找到完美的方向其实没关系,你会在接下来的步骤中纠正自己。 无论使用 BF16 还是 FP16,都有一个权重副本始终在 FP32 中 —— 这是由优化器更新的内容。因此 16 位格式仅用于计算,优化器以全精度更新 FP32 权重,然后将它们转换为 16 位格式以用于下一次迭代。 所有 PyTorch 组件都已更新,以确保它们在 FP32 中执行任何累加,因此不会发生精度损失。 一个关键问题是梯度累积,它是流水线并行的主要特征之一,因为每个 micro batch 处理的梯度都会累积。在 FP32 中实现梯度累积以保证训练的精确性至关重要,这正是 BF16Optimizer 所做的。 除了其他改进之外,我们认为使用 BF16 混合精度训练将潜在的噩梦变成了一个相对平稳的过程。 --- ## slurm - https://github.com/bigscience-workshop/bigscience/blob/master/train/tr10-13B-ml/tr10-13B.slurm - https://github.com/bigscience-workshop/bigscience/blob/master/train/tr11-176B-ml/tr11-176B-ml.slurm ================================================ FILE: docs/llm-base/distribution-training/FP16-BF16.md ================================================ ## FP16 数值上溢和数值下溢的问题 数值上溢:大量级的数被近似为正无穷或负无穷时发生上溢,进一步运算导致无限值变为非数字。 数值下溢:接近零的数被四舍五入为0时发生下溢。被零除,取零的对数,进一步运算会变为非数字。 求梯度的时候可能下溢,求激活的时候可能上溢出。 ### 存在的问题 使用FP16同样会带来一些问题,其中最重要的是1)精度溢出和2)舍入误差。 数据溢出:可见FP16相比FP32的有效范围要窄很多,使用FP16替换FP32会出现上溢(Overflow)和下溢(Underflow)的情况。而在深度学习中,需要计算网络模型中权重的梯度(一阶导数),因此梯度会比权重值更加小,往往容易出现下溢情况。 舍入误差:Rounding Error指示是当网络模型的反向梯度很小,一般FP32能够表示,但是转换到FP16会小于当前区间内的最小间隔,会导致数据溢出。 如0.00006666666在FP32中能正常表示,转换到FP16后会表示成为0.000067,不满足FP16最小间隔的数会强制舍入。 ================================================ FILE: docs/llm-base/distribution-training/GLM-130B训练经验.md ================================================ - https://github.com/THUDM/GLM-130B/blob/main/README_zh.md 1. 浮点数格式:FP16 混合精度 FP16混合精度已经成为主流大规模模型训练框架的默认选项,用于训练十亿到百亿规模的模型。但其仍太容易遇到精度问题。作为补救措施,NVIDIA Ampere GPU提供了BF16浮点格式(被BLOOM采用)来缓解这个问题。然而,BF16在其他平台上不被支持,这大大缩小了它在更广泛的应用中的潜力。 为了让更多开发者使用,GLM-130B仍然选择FP16作为其训练浮点格式。同时,这意味着GLM-130B将面临着更多的稳定性挑战。幸运的是,经过多次尝试,我们发现以下的训练策略最终有助于稳定GLM-130B的训练。 2. 嵌入层:梯度缩减 我们观察到,在训练的早期阶段,嵌入层的梯度范数明显比其他层大。根据经验,我们发现大多数训练崩溃都发生在其梯度范数激增之后。为了解决这个问题,BLOOM汇报了使用嵌入归一化(我们也发现它能稳定训练),但同时,其牺牲了相对较大的下游性能。 由于根本问题是输入嵌入层的急剧梯度,我们建议缩小输入嵌入层的梯度。实现起来相当简单。 word_embedding = word_embedding * α + word_embedding.detach() * (1 - α) 这就把梯度缩小到α。在我们的实践中,我们发现α=0.1对GLM-130B是最好的。 在我们的初步实验中,我们观察到,对于早期阶段的训练来说,缩小嵌入梯度并没有减缓收敛速度;相反,没有缩小梯度的模型会出现意外的尖峰,并在5k步左右出现训练崩溃的情况。 3. 注意力计算:FP32 Softmax 梯度收缩是一种避免训练崩溃的事后技术。从本质上讲,崩溃是由异常的损失"梯度"形成的,要么是由于噪声数据,要么是正向计算中的精度上溢或者下溢。 我们观察到,在大型语言模型中,注意力的计算操作是最容易上溢或下溢的。 CogView显示,不同的注意力头对其注意力分数有非常不同的数值范围,有些注意力头计算出的平均分数可以达到+1e4或-1e-3。 这种不同的数值范围会导致在softmax计算中FP16下的频繁上溢或下溢。 CogView提出了精度瓶颈放松(PB-Relax)来缓解这个问题,它在做softmax之前扣除了每个头的注意力得分矩阵中的最大绝对值。 然而,事实证明,PB-Relax在GLM-130B的训练中很慢,可能是因为在96个大小为`2048*2048`的注意分数矩阵中寻找最大值和操作标量对CUDA内核不友好。 最后,经过几周的艰苦探索,我们发现避免这一问题的最快和最简单的方法是在softmax计算中使用FP32。与完全的FP16计算相比,它几乎没有任何速度上的损失,但明显提高了训练的稳定性。 ================================================ FILE: docs/llm-base/distribution-training/OPT-175B训练经验.md ================================================ ## OPT-175B是如何炼成的 - https://zhuanlan.zhihu.com/p/622061951 ### 训练大模型的痛点 我们都知道,训练大模型需要以月计的时间,比如这次OPT-175B就要在1000个80G A100上开足马力训练3000亿个词,需要至少33天时间。这个33天还只是指连续训练的时间,而实际上中间肯定有无数次回退和重启。只要手指按下按钮,烧钱就开始,最关键的是,烧完钱之后还不知道是否能成功,这种压力是在家折腾小模型无法相比的。 但听完Susan的介绍,感觉实际操作中还是试错、试错再试错这一套实验方法,没有特别高深的炫技。Susan之前没有训练大模型的经验,是在试错的过程中不断成长,积累经验,最终炼丹成功。 ### 崩溃的超参和崩溃的机器 训练模型就是找出合适的超参,然而这在大模型上是非常困难的事情,适用于小模型的超参未必适用于大模型,所以很难使用先从小模型着手做试验、再扩展到大模型的方法。 ### Bug是人之常情 Susan团队准备环境花了一个月,一切部署妥当后兴冲冲地跑训练,结果烧钱了几天,发现代码有Bug…… 修正代码后,有一次试验,模型效果很好,预测下一个词的准确率很高,正准备庆祝,却发现原来是当初清洗处理数据集时,有人加入了大量的反斜杠转义符却忘记删除,模型准确无误地精确预测了这些反斜杠…… ### 数值稳定性(Numerical Stability) 整个训练过程,团队最关注的就是数值稳定性。经过多次尝试,她们决定使用bloat16作为基础数值格式,一举奠定了成功的基础。中途遇到一个问题,卡了一段时间。Susan某天在BigScienece的Megatron fork上,看到有人提出一个类似的PR,使用一个小小的等价变换,就解决了这个数值稳定性问题。 n * (A dot B) === (sqrt(n) * A) dot (sqrt(n) * B) ### 崩溃的超参和崩溃的机器 训练模型就是找出合适的超参,然而这在大模型上是非常困难的事情,适用于小模型的超参未必适用于大模型,所以很难使用先从小模型着手做试验、再扩展到大模型的方法。 这方面OpenAI就很厉害,他们在训练GPT-4的时候研究了一个方法,通过在小模型上做试验,在开始训练大模型之前就准确预测训练完之后的最终Loss。Susan她们没有找到这个方法,只能参考前人的论文以及不停地试验。 另一个困扰她们的问题是机器不停地坏,今天坏个显卡,明天坏一块内存,后天硬盘校验错误,大后天NVLink又坏了,硬件问题层出不穷…… ### 无Benchmark可用 由于她们忙于训练自己的模型,没有闲暇再弄Benchmark。而这个领域又发展得很快,过往的Benchmark很快就被比下去,不适合再作为Benchmark。 以Prompt为例,改一下Prompt的标准格式,比如大小写,模型的效果都大不一样,你很难分辨究竟是因为Prompt的格式问题影响性能,还是模型本身的性能改善了。 ### 黎明前夕 2021年11月,Run 12 她们觉得问题解决得七七八八了,差不多是时候来最后一轮试验。然而她们不确定前面的试验定下来的超参能否适用于最后的正式训练。根据公开论文,她们发现GPT-3和Megatron的设置非常接近,很可能是训练这种大模型的通用真理,于是她们决定抄GPT-3和Megatron论文的设置。 最后一轮试验,一上来就失败了15次,其中2次是GPU烧了,6次是CUDA错误,还有一些不明错误。还有2次是因为她们自己写的checkpoint的恢复程序又有bug,导致无法从上一个checkpoint恢复。 此后她们不停地降低 Learning rate,在56天之后, 大概经过 50多次重启, 模型 survived 143K steps,终于成功了!下图中断掉的空白是她们的备份失败了…… ## 问答环节 Q:如果你现在重新回到训练开始之前,你再希望改善什么。 A:Much Much more data。超参什么的都是浮云,关键还是训练数据。另外,发现bfloat16是最适合的格式也是里程碑。 Q:为什么这个项目团队只有5个人?是因为老板认为5个人就足够,还是因为传说中的世界上只有约200人能够训练这些大型模型,而你们是其中之一。 A:途中有很多其他人员协助,但是核心团队确实只有5人。因为我们跑一段训练就要几个星期,而每次只跑一段训练,太多人就浪费了。 Q:一天中你有多少时间是焦虑地盯着Loss Curve? A:必须成功的压力很大,确实很多时间都盯着最新的Loss(我猜测比盯着K线图还紧张),试图在失败之前就介入,免得浪费更多时间,还有很多时间在解决硬件问题和debug代码。 Q:我个人训练过2.7B的模型,这个规模的模型很容易就搞定,参数数量到达哪个临界点之后,模型会变得非常不稳定? A:不确定,根据我浅薄的经验,以及Google等的论文,可能临界点是70B。 Q:怎么解决硬件问题? A:和云工程师一起解决。老黄的A100相比V100来说太不稳定了,希望未来能解决。 提问者补充:传闻最新的H100更多问题,祝你好运。 Q:这个项目怎么定义成功? A:当时没什么成功的概念,只是单纯地希望Loss低到一定程度,以及效果比benchmark好。在做项目的时候还没精力和当时的竞争模型做比较,只专注于loss loss loss。现在回过头来才有空跟竞品比较。 Q:你刚才强调数据质量,并说如果当初能有更好的数据,模型训练的效果也会更好。既然数据质量这么重要,如何定义数据的好与坏? A:书、论文和代码直觉上最好质量的数据。对于特定领域的模型,比如编程模型,一看就知道哪些是好的代码;但对于这些大型通用模型来说,我们不知道怎么定义数据的好坏,要等最终模型训练出来之后才知道喂的数据好不好。 Q:出现错误的时候,你怎么知道是什么原因导致的?有可能是bug,有可能是参数问题,有可能是硬件故障。 A:没有好的方法,只能不停地试错。我们还曾经遇到晶体管的问题,完全没有办法复现问题。完全没有通用的方法,只能通过失败积累经验,但到下一代机子H100时,积累的这些经验又没用了,要从头开始试错。 Q:为什么越新型号的机子越不稳定? A:你要问老黄。如果老黄的驱动是开源的,我们还能帮他debug,很可惜不是,所以爱莫能助。 ## 大模型调研之 OPT-175B是如何炼成的 - https://zhuanlan.zhihu.com/p/644780639 重要控制参数: - weight decay - global grad norm clipping - Adam优化器beta2 - Adam优化器epsilon - 增加warmup的步数(steps) 教训:要先在小规模数据上试跑,以便提早发现代码bug ``` Run 11: 一组认为可能还不错的参数设置: 2M batch size FP32 Adam Tensor parallel(8x MP) 新data,来自实验29(之前的数据集中存在问题,曾额外添加了转义字符,于是模型训练时通过找转义字符而降低了loss,而非真正学到东西) 训练中学习positional embedding。因为不太有信心学到positional embedding,所以通过正弦init(sinusoidal init)学习positional embedding,使之与原transformer论文相符合。 weight decay, 0.05 LR of 3+4, end LR of le-5。学习率开始时高,后期变低以避免训练变得不稳定 No dropout on embeddings Normformer (impact on grad norm is making earlier layers be more similar with later layers) Gradient pre-divide factor: 32(Naman has been running with this),目的是实现局部梯度积累(local gradient accumulation) Clip (12 norm): 2.5(后被证实是重要的,当时并不清楚这样的重要性) 将Gelu替换为Relu,因为Gelu的公式里有个x^3,可能造成不稳定 ``` ``` Run 12.00:Beginning of the "final" run Overall weight initialization updated: 总体的权重初始化 Removed extra layer norms from Normformer setup Removed embedding scaling Gaussian init for learned positional embeddings (instead of sinusoidal init),此处观点是,也许较小的标准差有助于提高稳定性 Weight decay = 0.1 Clipping = 1.0 Adam beta2 = 0.95 Max LR of 1.2e-4 Run 12.(01-15): Mainly "systems" issues 大量系统问题 Lost GPU(12.01, 12.10) CUDA errors (12.02, 12.03, 12.04, 12.09, 12.15, 12.17) Job hanging (12.05, 12.06) NCCL error (12.08) Job slowdown (12.11) For Run 12.16: Reduce clipping to 0.3 Backup plan:reset Adam state and do fresh warmup Runs 12.(17-34): Hardware issues (ECC errors, lost GPU, high#DRAM correctables, etc.) Mysterious job hanging issues Blob storage issues Gradient overflow issues Used loss scaling state "reset" with restarts to try and circumvent the same fate ``` ================================================ FILE: docs/llm-base/distribution-training/README.md ================================================ 用 FP16 训练巨型 LLM 模型是一个禁忌,它将面临更多的稳定性挑战。 ================================================ FILE: docs/llm-base/distribution-training/自动混合精度.md ================================================ Torch.cuda.amp vs Nvidia apex pytorch从1.6版本开始,已经内置了torch.cuda.amp,采用自动混合精度训练就不需要加载第三方NVIDIA的apex库了。 ================================================ FILE: docs/llm-base/gpu-env-var.md ================================================ CUDA_VISIBLE_DEVICES=1 ================================================ FILE: docs/llm-base/h800-env-install.md ================================================ | Fermi **†** | Kepler **†** | Maxwell **‡** | Pascal | Volta | Turing | Ampere | Ada (Lovelace) | [Hopper](https://www.nvidia.com/en-us/data-center/hopper-architecture/) | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | sm_20 | sm_30 | sm_50 | sm_60 | sm_70 | sm_75 | sm_80 | sm_89 | sm_90 | | | sm_35 | sm_52 | sm_61 | sm_72
(Xavier) | | sm_86 | | sm_90a (Thor) | | | sm_37 | sm_53 | sm_62 | | | sm_87 (Orin) | | | **†** Fermi and Kepler are deprecated from CUDA 9 and 11 onwards **‡** Maxwell is deprecated from CUDA 11.6 onwards 参考:https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/ 如果使用H800,CUDA版本要在11.8及以上,同时,PyTorch版本要在2.0.0以上。下面是我使用CUDA为11.7,同时PyTorch为1.13.1的报错信息。 ``` NVIDIA H800 with CUDA capability sm_90 is not compatible with the current PyTorch installation. The current PyTorch install supports CUDA capabilities sm_37 sm_50 sm_60 sm_70 sm_75 sm_80 sm_86. ``` ## CUDA ``` mkdir -p /home/local/cuda-11.8 sudo ln -s /home/local/cuda-11.7 /usr/local/cuda-11.8 wget https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda_11.8.0_520.61.05_linux.run chmod +x cuda_11.8.0_520.61.05_linux.run sudo sh cuda_11.8.0_520.61.05_linux.run ``` ## NCCL 安装 ``` tar xvf nccl_2.16.5-1+cuda11.8_x86_64.txz cd nccl_2.16.5-1+cuda11.8_x86_64/ sudo cp -r include/* /usr/local/cuda-11.8/include/ sudo cp -r lib/* /usr/local/cuda-11.8/lib64/ # export LD_LIBRARY_PATH="/usr/local/cuda-11.7/lib64:$LD_LIBRARY_PATH" ``` ## cuDNN 安装 ``` tar -xvf cudnn-linux-x86_64-8.9.2.26_cuda11-archive.tar.xz cd cudnn-linux-x86_64-8.9.2.26_cuda11-archive sudo cp include/cudnn*.h /usr/local/cuda-11.8/include sudo cp -P lib/libcudnn* /usr/local/cuda-11.8/lib64/ sudo chmod a+r /usr/local/cuda-11.8/include/cudnn*.h /usr/local/cuda-11.8/lib64/libcudnn* ``` ## OpenMPI ``` tar -xvzf openmpi-5.0.1.tar.gz cd openmpi-5.0.1 ./configure --prefix=/data/hpc/software/openmpi make -j 80 sudo make install -j 80 export LD_LIBRARY_PATH=/usr/local/cuda-11.0/lib64:/usr/local/nccl_2.11.4-1+cuda11.0_x86_64/lib:/usr/local/openmpi/lib:$LD_LIBRARY_PATH export PATH=/usr/local/openmpi/bin:/usr/local/cuda-11.0/bin:$PATH ``` ## 虚拟环境 ``` # mkdir -p /home/guodong.li/virtual-venv cd /home/guodong.li/virtual-venv virtualenv -p /usr/bin/python3.10 llama-venv-py310-cu118 source /home/guodong.li/virtual-venv/llama-venv-py310-cu118/bin/activate ``` ## Python 库安装 ### Pytorch 下载地址: https://download.pytorch.org/whl/torch_stable.html ``` wget -c https://download.pytorch.org/whl/cu118/torch-2.0.0%2Bcu118-cp310-cp310-linux_x86_64.whl wget -c https://download.pytorch.org/whl/cu118/torchvision-0.15.0%2Bcu118-cp310-cp310-linux_x86_64.whl pip install torch-2.0.0+cu118-cp310-cp310-linux_x86_64.whl pip install torchvision-0.15.0+cu118-cp310-cp310-linux_x86_64.whl ``` ### Deepspeed... ``` pip install deepspeed==0.9.5 pip install accelerate pip install tensorboardX ``` ### 安装Apex ``` git clone https://github.com/NVIDIA/apex.git cd apex git checkout 30a7ad3 pip install -v --disable-pip-version-check --no-cache-dir --no-build-isolation --config-settings "--build-option=--cpp_ext" --config-settings "--build-option=--cuda_ext" ./ ``` ## 配套 ``` wget https://developer.download.nvidia.com/compute/cuda/12.1.1/local_installers/cuda_12.1.1_530.30.02_linux.run sudo sh cuda_12.1.1_530.30.02_linux.run ``` ``` NCCL: https://developer.nvidia.com/downloads/compute/machine-learning/nccl/secure/2.18.3/agnostic/x64/nccl_2.18.3-1+cuda12.1_x86_64.txz/ CUDNN: pytorch: https://download.pytorch.org/whl/cu121/torch-2.1.2%2Bcu121-cp310-cp310-linux_x86_64.whl https://download.pytorch.org/whl/cu121/torchaudio-2.1.2%2Bcu121-cp310-cp310-linux_x86_64.whl https://download.pytorch.org/whl/cu121/torchvision-0.16.2%2Bcu121-cp310-cp310-linux_x86_64.whl ``` ================================================ FILE: docs/llm-base/monitor.md ================================================ # NVIDIA DCGM ## Remove Older Installations To remove the previous installation (if any), perform the following steps (e.g. on an RPM-based system). Make sure that the nv-hostengine is not running. You can stop it using the following command: ``` # 启动nv-hostengine # nv-hostengine # 停止 nv-hostengine sudo nv-hostengine -t ``` Remove the previous installation: ``` sudo yum remove datacenter-gpu-manager ``` ## 安装 ### Ubuntu ``` distribution=$(. /etc/os-release;echo $ID$VERSION_ID | sed -e 's/\.//g') wget https://developer.download.nvidia.com/compute/cuda/repos/$distribution/x86_64/cuda-keyring_1.0-1_all.deb dpkg -i cuda-keyring_1.0-1_all.deb apt-get update apt-get install -y datacenter-gpu-manager ``` ### CentOS centos8以上使用dnf,centos7建议还是使用yum. centos7: ``` wget https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo #或者使用wget https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/cuda-rhel7.repo yum install datacenter-gpu-manager systemctl restart nvidia-dcgm.service && systemctl enable nvidia-dcgm.service systemctl status nvidia-dcgm.service ``` centos8: ``` yum install epel-release yum install dnf ``` ``` # Determine the distribution name distribution=$(. /etc/os-release;echo $ID`rpm -E "%{?rhel}%{?fedora}"`) # Install the repository meta-data and the CUDA GPG key sudo dnf config-manager \ --add-repo http://developer.download.nvidia.com/compute/cuda/repos/$distribution/x86_64/cuda-rhel8.repo # Update the repository metadata sudo dnf clean expire-cache # install DCGM sudo dnf install -y datacenter-gpu-manager ``` ### docker(dcgm) url: https://hub.docker.com/r/nvidia/dcgm ``` docker pull nvidia/dcgm:3.1.7-1-ubuntu20.04 ``` ### docker(dcgm-exporter) url: https://hub.docker.com/r/nvidia/dcgm-exporter ``` docker pull nvidia/dcgm-exporter:3.1.8-3.1.5-ubuntu20.04 ``` ## docker(dcgm) 使用 ### 访问 GPU Telemetry 在此场景中,DCGM 独立容器已使用以下命令启动,其中端口 5555 映射到主机,以便其他客户端可以访问容器中运行的 nv-hostengine 服务。 请注意,要收集分析指标,需要向容器提供 SYS_ADMIN 功能: ``` docker run --gpus all \ --cap-add SYS_ADMIN \ -p 5555:5555 \ nvidia/dcgm:3.1.7-1-ubuntu20.04 ``` 现在,诸如 dcgmi dmon 之类的客户端可以在控制台上传输 GPU Telemetry/指标。 ### GPU 健康状况 在这种情况下,DCGM 不需要任何额外的caps,并且可以以非特权方式运行: ``` docker run --gpus all \ -p 5555:5555 \ nvidia/dcgm:3.1.7-1-ubuntu20.04 ``` 现在用于报告运行状况的 DCGM API 可以通过连接到 DCGM 容器的客户端访问。 ================================================ FILE: docs/llm-base/multimodal/sora.md ================================================ 方案:VAE Encoder(视频压缩) -> Transform Diffusion (从视频数据中学习分布,并根据条件生成新视频) -> VAE Decoder (视频解压缩) 从博客出发,经过学术Survey,可以推断出全貌。一句话结论: Sora是采用了Meta的 DiT (2022.12) 框架, 融合了Google的 MAGViT (2022.12) 的Video Tokenize方案, 借用Google DeepMind的NaViT (2023.07) 支持了原始比例和分辨率, 使用OpenAI DALL-E 3 (2023.09) 里的图像描述方案生成了高质量Video Caption(视频描述),即文本-视频对,实现了准确的条件生成。 ================================================ FILE: docs/llm-base/nvidia-smi-dmon.md ================================================ 设备监控命令,以滚动条形式显示GPU设备统计信息。 GPU统计信息以一行的滚动格式显示,要监控的指标可以基于终端窗口的宽度进行调整。如果没有指定任何GPU,则默认监控所有GPU。 ## 指定刷新时间(-d ) ``` > nvidia-smi dmon -d 5 # gpu pwr gtemp mtemp sm mem enc dec mclk pclk # Idx W C C % % % % MHz MHz 0 123 44 50 5 0 0 0 2619 1980 1 129 44 52 14 0 0 0 2619 1980 2 122 39 46 25 0 0 0 2619 1980 3 120 38 44 24 0 0 0 2619 1980 4 123 44 50 15 0 0 0 2619 1980 5 126 43 50 12 0 0 0 2619 1980 6 118 38 46 22 0 0 0 2619 1980 7 124 38 44 25 0 0 0 2619 1980 0 191 45 54 100 3 0 0 2619 1980 1 186 46 52 100 3 0 0 2619 1980 2 148 40 47 100 3 0 0 2619 1980 3 160 40 47 99 13 0 0 2619 1980 4 209 46 51 100 30 0 0 2619 1980 5 196 44 51 100 3 0 0 2619 1980 6 211 39 47 100 3 0 0 2619 1980 7 198 39 46 100 2 0 0 2619 1980 0 244 45 52 100 0 0 0 2619 1980 1 195 45 52 100 2 0 0 2619 1980 2 271 40 48 100 0 0 0 2619 1980 3 236 47 50 20 9 0 0 2619 1980 4 300 53 56 73 39 0 0 2619 1980 5 254 51 57 16 8 0 0 2619 1980 6 219 39 47 100 2 0 0 2619 1980 7 214 39 47 100 4 0 0 2619 1980 ``` ## 指定要监控的GPU索引(-i) ``` nvidia-smi dmon -i 3 -d 5 # gpu pwr gtemp mtemp sm mem enc dec mclk pclk # Idx W C C % % % % MHz MHz 3 234 40 45 100 5 0 0 2619 1980 3 120 38 44 16 0 0 0 2619 1980 3 182 39 45 100 3 0 0 2619 1980 3 246 39 45 100 0 0 0 2619 1980 # 多个GPU nvidia-smi dmon -i 3,6 -d 5 # gpu pwr gtemp mtemp sm mem enc dec mclk pclk # Idx W C C % % % % MHz MHz 3 141 39 45 100 7 0 0 2619 1980 6 143 38 46 100 5 0 0 2619 1980 3 139 40 47 51 5 0 0 2619 1980 6 143 39 48 24 23 0 0 2619 1980 ``` ## 指定显示哪些监控指标(-s) 指定显示哪些监控指标(默认为puc) - p:电源使用情况和温度(pwr:功耗,temp:温度) - u:GPU使用率(sm:流处理器,mem:显存,enc:编码资源,dec:解码资源) - c:GPU处理器和GPU内存时钟频率(mclk:显存频率,pclk:处理器频率) - v:电源和热力异常 - m:FB内存和Bar1内存 - e:ECC错误和PCIe重显错误个数 - t:PCIe读写带宽 ``` > nvidia-smi dmon -i 3 -d 1 -s put # gpu pwr gtemp mtemp sm mem enc dec rxpci txpci # Idx W C C % % % % MB/s MB/s 3 224 43 47 91 46 0 0 1968 1621 3 231 40 45 100 13 0 0 838 2025 3 169 41 46 11 6 0 0 4587 521 3 273 40 45 100 5 0 0 2016001 1765799 3 212 40 45 100 3 0 0 775 726 3 203 40 45 99 26 0 0 1572 601 3 128 39 45 0 0 0 0 110 111 3 120 39 44 0 0 0 0 101 116 3 179 45 48 100 20 0 0 321785 214053 3 289 47 49 88 7 0 0 1861316 199124 3 193 40 46 100 5 0 0 794 945 3 278 40 45 100 6 0 0 1910283 552 3 237 41 45 100 38 0 0 767 1548 3 214 41 46 99 20 0 0 107 122 3 132 39 45 0 0 0 0 102 112 3 120 39 44 0 0 0 0 105 117 3 136 44 47 95 14 0 0 40821 81122 3 323 42 47 90 28 0 0 1143 610 3 147 39 45 100 4 0 0 1138 855 3 224 40 45 100 8 0 0 501 580 ``` ================================================ FILE: docs/llm-base/nvidia-smi.md ================================================ # nvidia-smi ## 基本概念 - Tx是发送数据的意思,Rx是接收数据的意思。 ## 基本操作 ``` nvidia-smi ``` ### 查询GPU卡信息和统计GPU卡数 ``` nvidia-smi -L ``` ``` nvidia-smi -L | wc -l ``` ### 可以列出所有GPU设备的详细信息 使用 nvidia-smi -q 可以列出所有GPU设备的详细信息。 如果只想列出某一GPU的详细信息,可使用 -i 选项指定。 ``` > nvidia-smi -q -i 0 ==============NVSMI LOG============== Timestamp : Fri Jun 30 17:20:02 2023 Driver Version : 525.105.17 CUDA Version : 12.0 Attached GPUs : 8 GPU 00000000:18:00.0 Product Name : NVIDIA H800 Product Brand : NVIDIA Product Architecture : Hopper Display Mode : Disabled Display Active : Disabled Persistence Mode : Enabled MIG Mode Current : Disabled Pending : Disabled Accounting Mode : Disabled Accounting Mode Buffer Size : 4000 Driver Model Current : N/A Pending : N/A Serial Number : 1651323018291 GPU UUID : GPU-34bf77d1-c686-6821-79a8-32d326c5039c Minor Number : 0 VBIOS Version : 96.00.51.00.0E MultiGPU Board : No Board ID : 0x1800 Board Part Number : 692-2G520-0205-000 GPU Part Number : 2324-865-A1 Module ID : 5 Inforom Version Image Version : G520.0205.00.02 OEM Object : 2.1 ECC Object : 7.16 Power Management Object : N/A GPU Operation Mode Current : N/A Pending : N/A GSP Firmware Version : 525.105.17 GPU Virtualization Mode Virtualization Mode : None Host VGPU Mode : N/A IBMNPU Relaxed Ordering Mode : N/A PCI Bus : 0x18 Device : 0x00 Domain : 0x0000 Device Id : 0x232410DE Bus Id : 00000000:18:00.0 Sub System Id : 0x17A610DE GPU Link Info PCIe Generation Max : 5 Current : 5 Device Current : 5 Device Max : 5 Host Max : 5 Link Width Max : 16x Current : 16x Bridge Chip Type : N/A Firmware : N/A Replays Since Reset : 0 Replay Number Rollovers : 0 Tx Throughput : 123000 KB/s Rx Throughput : 111000 KB/s Atomic Caps Inbound : N/A Atomic Caps Outbound : N/A Fan Speed : N/A Performance State : P0 Clocks Throttle Reasons Idle : Active Applications Clocks Setting : Not Active SW Power Cap : Not Active HW Slowdown : Not Active HW Thermal Slowdown : Not Active HW Power Brake Slowdown : Not Active Sync Boost : Not Active SW Thermal Slowdown : Not Active Display Clock Setting : Not Active FB Memory Usage Total : 81559 MiB Reserved : 516 MiB Used : 0 MiB Free : 81042 MiB BAR1 Memory Usage Total : 131072 MiB Used : 1 MiB Free : 131071 MiB Compute Mode : Default Utilization Gpu : 0 % Memory : 0 % Encoder : 0 % Decoder : 0 % Encoder Stats Active Sessions : 0 Average FPS : 0 Average Latency : 0 FBC Stats Active Sessions : 0 Average FPS : 0 Average Latency : 0 Ecc Mode Current : Disabled Pending : Disabled ECC Errors Volatile SRAM Correctable : N/A SRAM Uncorrectable : N/A DRAM Correctable : N/A DRAM Uncorrectable : N/A Aggregate SRAM Correctable : N/A SRAM Uncorrectable : N/A DRAM Correctable : N/A DRAM Uncorrectable : N/A Retired Pages Single Bit ECC : N/A Double Bit ECC : N/A Pending Page Blacklist : N/A Remapped Rows Correctable Error : 0 Uncorrectable Error : 0 Pending : No Remapping Failure Occurred : No Bank Remap Availability Histogram Max : 2560 bank(s) High : 0 bank(s) Partial : 0 bank(s) Low : 0 bank(s) None : 0 bank(s) Temperature GPU Current Temp : 35 C GPU T.Limit Temp : 51 C GPU Shutdown Temp : 92 C GPU Slowdown Temp : 89 C GPU Max Operating Temp : 87 C GPU Target Temperature : N/A Memory Current Temp : 44 C Memory Max Operating Temp : 95 C Power Readings Power Management : Supported Power Draw : 74.71 W Power Limit : 700.00 W Default Power Limit : 700.00 W Enforced Power Limit : 700.00 W Min Power Limit : 200.00 W Max Power Limit : 700.00 W Clocks Graphics : 345 MHz SM : 345 MHz Memory : 2619 MHz Video : 765 MHz Applications Clocks Graphics : 1980 MHz Memory : 2619 MHz Default Applications Clocks Graphics : 1980 MHz Memory : 2619 MHz Deferred Clocks Memory : N/A Max Clocks Graphics : 1980 MHz SM : 1980 MHz Memory : 2619 MHz Video : 1545 MHz Max Customer Boost Clocks Graphics : 1980 MHz Clock Policy Auto Boost : N/A Auto Boost Default : N/A Voltage Graphics : 725.000 mV Fabric State : Completed Status : Success Processes : None ``` ## nvlink ``` > nvidia-smi nvlink --help nvlink -- Display NvLink information. Usage: nvidia-smi nvlink [options] Options include: [-h | --help]: Display help information [-i | --id]: Enumeration index, PCI bus ID or UUID. [-l | --link]: Limit a command to a specific link. Without this flag, all link information is displayed. [-s | --status]: Display link state (active/inactive). [-c | --capabilities]: Display link capabilities. [-p | --pcibusid]: Display remote node PCI bus ID for a link. [-R | --remotelinkinfo]: Display remote device PCI bus ID and NvLink ID for a link. [-sc | --setcontrol]: Setting counter control is deprecated! [-gc | --getcontrol]: Getting counter control is deprecated! [-g | --getcounters]: Getting counters using option -g is deprecated. Please use option -gt/--getthroughput instead. [-r | --resetcounters]: Resetting counters is deprecated! [-e | --errorcounters]: Display error counters for a link. [-ec | --crcerrorcounters]: Display per-lane CRC error counters for a link. [-re | --reseterrorcounters]: Reset all error counters to zero. [-gt | --getthroughput]: Display link throughput counters for specified counter type The arguments consist of character string representing the type of traffic counted: d: Display tx and rx data payload in KiB r: Display tx and rx data payload and protocol overhead in KiB if supported [-sLowPwrThres | --setLowPowerThreshold]: Set NvLink Low Power Threshold (value inunits of 100us/default) [-gLowPwrInfo | --getLowPowerInfo]: Get NvLink Low Power Info [-cBridge | --checkBridge]: Check NvLink Bridge presence ``` ### 查看系统/GPU 拓扑和 NVLink ``` # 查看系统/GPU 拓扑 > nvidia-smi topo --matrix GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7 CPU Affinity NUMA Affinity GPU0 X NV8 NV8 NV8 NV8 NV8 NV8 NV8 -31,64-95 0 GPU1 NV8 X NV8 NV8 NV8 NV8 NV8 NV8 -31,64-95 0 GPU2 NV8 NV8 X NV8 NV8 NV8 NV8 NV8 -31,64-95 0 GPU3 NV8 NV8 NV8 X NV8 NV8 NV8 NV8 -31,64-95 0 GPU4 NV8 NV8 NV8 NV8 X NV8 NV8 NV8 32-63,96-127 1 GPU5 NV8 NV8 NV8 NV8 NV8 X NV8 NV8 32-63,96-127 1 GPU6 NV8 NV8 NV8 NV8 NV8 NV8 X NV8 32-63,96-127 1 GPU7 NV8 NV8 NV8 NV8 NV8 NV8 NV8 X 2-63,96-127 1 NIC0 NODE PIX NODE NODE SYS SYS SYS SYS NIC1 NODE NODE NODE PIX SYS SYS SYS SYS NIC2 SYS SYS SYS SYS NODE NODE NODE PIX NIC3 SYS SYS SYS SYS NODE NODE NODE PIX Legend: X = Self SYS = Connection traversing PCIe as well as the SMP interconnect beI) NODE = Connection traversing PCIe as well as the interconnect betweeUMA node PHB = Connection traversing PCIe as well as a PCIe Host Bridge (typ PXB = Connection traversing multiple PCIe bridges (without traversi PIX = Connection traversing at most a single PCIe bridge NV# = Connection traversing a bonded set of # NVLinks NIC Legend: NIC0: mlx5_0 NIC1: mlx5_1 NIC2: mlx5_2 NIC3: mlx5_3 ``` ### 状态 ``` # 查询 NVLink 连接本身以确保状态、功能和运行状况。 > nvidia-smi nvlink --status GPU 0: NVIDIA H800 (UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c) Link 0: 26.562 GB/s Link 1: 26.562 GB/s Link 2: 26.562 GB/s Link 3: 26.562 GB/s Link 4: 26.562 GB/s Link 5: 26.562 GB/s Link 6: 26.562 GB/s Link 7: 26.562 GB/s GPU 1: NVIDIA H800 (UUID: GPU-f5046fa5-3db4-45e8-870a-dc1376becaa5) Link 0: 26.562 GB/s Link 1: 26.562 GB/s Link 2: 26.562 GB/s Link 3: 26.562 GB/s Link 4: 26.562 GB/s Link 5: 26.562 GB/s Link 6: 26.562 GB/s Link 7: 26.562 GB/s ... GPU 7: NVIDIA H800 (UUID: GPU-474d838c-171f-d249-4f45-bbc01a8eb74a) Link 0: 26.562 GB/s Link 1: 26.562 GB/s Link 2: 26.562 GB/s Link 3: 26.562 GB/s Link 4: 26.562 GB/s Link 5: 26.562 GB/s Link 6: 26.562 GB/s Link 7: 26.562 GB/s ``` ``` # 查询 NVLink 连接本身以确保状态、功能和运行状况。 > nvidia-smi nvlink --capabilities GPU 0: NVIDIA H800 (UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c) Link 0, P2P is supported: true Link 0, Access to system memory supported: true Link 0, P2P atomics supported: true Link 0, System memory atomics supported: true Link 0, SLI is supported: true Link 0, Link is supported: false Link 1, P2P is supported: true Link 1, Access to system memory supported: true Link 1, P2P atomics supported: true Link 1, System memory atomics supported: true Link 1, SLI is supported: true Link 1, Link is supported: false Link 2, P2P is supported: true Link 2, Access to system memory supported: true Link 2, P2P atomics supported: true Link 2, System memory atomics supported: true Link 2, SLI is supported: true Link 2, Link is supported: false Link 3, P2P is supported: true Link 3, Access to system memory supported: true Link 3, P2P atomics supported: true Link 3, System memory atomics supported: true Link 3, SLI is supported: true Link 3, Link is supported: false Link 4, P2P is supported: true Link 4, Access to system memory supported: true Link 4, P2P atomics supported: true Link 4, System memory atomics supported: true Link 4, SLI is supported: true Link 4, Link is supported: false Link 5, P2P is supported: true Link 5, Access to system memory supported: true Link 5, P2P atomics supported: true Link 5, System memory atomics supported: true Link 5, SLI is supported: true Link 5, Link is supported: false Link 6, P2P is supported: true Link 6, Access to system memory supported: true Link 6, P2P atomics supported: true Link 6, System memory atomics supported: true Link 6, SLI is supported: true Link 6, Link is supported: false Link 7, P2P is supported: true Link 7, Access to system memory supported: true Link 7, P2P atomics supported: true Link 7, System memory atomics supported: true Link 7, SLI is supported: true Link 7, Link is supported: false GPU 1: NVIDIA H800 (UUID: GPU-f5046fa5-3db4-45e8-870a-dc1376becaa5) Link 0, P2P is supported: true Link 0, Access to system memory supported: true Link 0, P2P atomics supported: true Link 0, System memory atomics supported: true Link 0, SLI is supported: true Link 0, Link is supported: false Link 1, P2P is supported: true Link 1, Access to system memory supported: true Link 1, P2P atomics supported: true Link 1, System memory atomics supported: true Link 1, SLI is supported: true Link 1, Link is supported: false Link 2, P2P is supported: true Link 2, Access to system memory supported: true Link 2, P2P atomics supported: true Link 2, System memory atomics supported: true Link 2, SLI is supported: true Link 2, Link is supported: false Link 3, P2P is supported: true Link 3, Access to system memory supported: true Link 3, P2P atomics supported: true Link 3, System memory atomics supported: true Link 3, SLI is supported: true Link 3, Link is supported: false Link 4, P2P is supported: true Link 4, Access to system memory supported: true Link 4, P2P atomics supported: true Link 4, System memory atomics supported: true Link 4, SLI is supported: true Link 4, Link is supported: false Link 5, P2P is supported: true Link 5, Access to system memory supported: true Link 5, P2P atomics supported: true Link 5, System memory atomics supported: true Link 5, SLI is supported: true Link 5, Link is supported: false Link 6, P2P is supported: true Link 6, Access to system memory supported: true Link 6, P2P atomics supported: true Link 6, System memory atomics supported: true Link 6, SLI is supported: true Link 6, Link is supported: false Link 7, P2P is supported: true Link 7, Access to system memory supported: true Link 7, P2P atomics supported: true Link 7, System memory atomics supported: true Link 7, SLI is supported: true Link 7, Link is supported: false ... GPU 7: NVIDIA H800 (UUID: GPU-474d838c-171f-d249-4f45-bbc01a8eb74a) Link 0, P2P is supported: true Link 0, Access to system memory supported: true Link 0, P2P atomics supported: true Link 0, System memory atomics supported: true Link 0, SLI is supported: true Link 0, Link is supported: false Link 1, P2P is supported: true Link 1, Access to system memory supported: true Link 1, P2P atomics supported: true Link 1, System memory atomics supported: true Link 1, SLI is supported: true Link 1, Link is supported: false Link 2, P2P is supported: true Link 2, Access to system memory supported: true Link 2, P2P atomics supported: true Link 2, System memory atomics supported: true Link 2, SLI is supported: true Link 2, Link is supported: false Link 3, P2P is supported: true Link 3, Access to system memory supported: true Link 3, P2P atomics supported: true Link 3, System memory atomics supported: true Link 3, SLI is supported: true Link 3, Link is supported: false Link 4, P2P is supported: true Link 4, Access to system memory supported: true Link 4, P2P atomics supported: true Link 4, System memory atomics supported: true Link 4, SLI is supported: true Link 4, Link is supported: false Link 5, P2P is supported: true Link 5, Access to system memory supported: true Link 5, P2P atomics supported: true Link 5, System memory atomics supported: true Link 5, SLI is supported: true Link 5, Link is supported: false Link 6, P2P is supported: true Link 6, Access to system memory supported: true Link 6, P2P atomics supported: true Link 6, System memory atomics supported: true Link 6, SLI is supported: true Link 6, Link is supported: false Link 7, P2P is supported: true Link 7, Access to system memory supported: true Link 7, P2P atomics supported: true Link 7, System memory atomics supported: true Link 7, SLI is supported: true Link 7, Link is supported: false ``` ### 显示指定计数器类型的链路吞吐量计数器 显示指定计数器类型的链路吞吐量计数器 参数由表示计数的流量类型的字符串组成: - d:以 KiB 显示 tx 和 rx 数据有效负载 - r:如果支持,以 KiB 显示 tx 和 rx 数据有效负载和协议开销 ``` # nvidia-smi nvlink -gt d > nvidia-smi nvlink -gt r nvidia-smi nvlink -gt r GPU 0: NVIDIA H800 (UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c) Link 0: Raw Tx: 25305739 KiB Link 0: Raw Rx: 25554089 KiB Link 1: Raw Tx: 8508772 KiB Link 1: Raw Rx: 8727784 KiB Link 2: Raw Tx: 8511892 KiB Link 2: Raw Rx: 8734905 KiB Link 3: Raw Tx: 8506576 KiB Link 3: Raw Rx: 8720965 KiB Link 4: Raw Tx: 8508545 KiB Link 4: Raw Rx: 8724705 KiB Link 5: Raw Tx: 8503240 KiB Link 5: Raw Rx: 8724306 KiB Link 6: Raw Tx: 8514361 KiB Link 6: Raw Rx: 8727629 KiB Link 7: Raw Tx: 8517607 KiB Link 7: Raw Rx: 8730994 KiB GPU 1: NVIDIA H800 (UUID: GPU-f5046fa5-3db4-45e8-870a-dc1376becaa5) Link 0: Raw Tx: 25415406 KiB Link 0: Raw Rx: 25651111 KiB Link 1: Raw Tx: 8614105 KiB Link 1: Raw Rx: 8827532 KiB Link 2: Raw Tx: 8618737 KiB Link 2: Raw Rx: 8838429 KiB Link 3: Raw Tx: 8617599 KiB Link 3: Raw Rx: 8828039 KiB Link 4: Raw Tx: 8619360 KiB Link 4: Raw Rx: 8848343 KiB Link 5: Raw Tx: 8616291 KiB Link 5: Raw Rx: 8830590 KiB Link 6: Raw Tx: 8621649 KiB Link 6: Raw Rx: 8828622 KiB Link 7: Raw Tx: 8626449 KiB Link 7: Raw Rx: 8834243 KiB GPU 2: NVIDIA H800 (UUID: GPU-9de407ad-ba9c-af12-ce09-65828829a67c) Link 0: Raw Tx: 576438247 KiB Link 0: Raw Rx: 591715253 KiB Link 1: Raw Tx: 591684300 KiB Link 1: Raw Rx: 625042437 KiB Link 2: Raw Tx: 561660326 KiB Link 2: Raw Rx: 576223159 KiB Link 3: Raw Tx: 560468850 KiB Link 3: Raw Rx: 575052692 KiB Link 4: Raw Tx: 542530345 KiB Link 4: Raw Rx: 583254750 KiB Link 5: Raw Tx: 541527825 KiB Link 5: Raw Rx: 582292048 KiB Link 6: Raw Tx: 524762470 KiB Link 6: Raw Rx: 550225067 KiB Link 7: Raw Tx: 544014147 KiB Link 7: Raw Rx: 582742696 KiB ... GPU 6: NVIDIA H800 (UUID: GPU-70c5b9a8-82a3-4199-d7f5-adb9186459eb) Link 0: Raw Tx: 25421053 KiB Link 0: Raw Rx: 25651584 KiB Link 1: Raw Tx: 8624284 KiB Link 1: Raw Rx: 8834680 KiB Link 2: Raw Tx: 8629640 KiB Link 2: Raw Rx: 8841618 KiB Link 3: Raw Tx: 8622803 KiB Link 3: Raw Rx: 8834635 KiB Link 4: Raw Tx: 8625793 KiB Link 4: Raw Rx: 8848148 KiB Link 5: Raw Tx: 8617230 KiB Link 5: Raw Rx: 8832897 KiB Link 6: Raw Tx: 8629904 KiB Link 6: Raw Rx: 8848920 KiB Link 7: Raw Tx: 8637145 KiB Link 7: Raw Rx: 8831474 KiB GPU 7: NVIDIA H800 (UUID: GPU-474d838c-171f-d249-4f45-bbc01a8eb74a) Link 0: Raw Tx: 25310096 KiB Link 0: Raw Rx: 25546907 KiB Link 1: Raw Tx: 8512574 KiB Link 1: Raw Rx: 8747250 KiB Link 2: Raw Tx: 8514172 KiB Link 2: Raw Rx: 8734000 KiB Link 3: Raw Tx: 8512622 KiB Link 3: Raw Rx: 8730435 KiB Link 4: Raw Tx: 8510112 KiB Link 4: Raw Rx: 8745800 KiB Link 5: Raw Tx: 8507350 KiB Link 5: Raw Rx: 8737562 KiB Link 6: Raw Tx: 8515623 KiB Link 6: Raw Rx: 8729950 KiB Link 7: Raw Tx: 8520721 KiB Link 7: Raw Rx: 8731188 KiB ``` 显示 0 号 GPU 设备的所有 链路 的 吞吐量计数器的数据有效载荷 ``` # 未做任何操作时 > nvidia-smi nvlink -i 0 -gt d GPU 0: NVIDIA H800 (UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c) Link 0: Data Tx: 5863784 KiB Link 0: Data Rx: 5863677 KiB Link 1: Data Tx: 5864084 KiB Link 1: Data Rx: 5862999 KiB Link 2: Data Tx: 5864630 KiB Link 2: Data Rx: 5863940 KiB Link 3: Data Tx: 5863784 KiB Link 3: Data Rx: 5861984 KiB Link 4: Data Tx: 5861984 KiB Link 4: Data Rx: 5862774 KiB Link 5: Data Tx: 5861984 KiB Link 5: Data Rx: 5862696 KiB Link 6: Data Tx: 5861984 KiB Link 6: Data Rx: 5862999 KiB Link 7: Data Tx: 5861984 KiB Link 7: Data Rx: 5863146 KiB # 模型训练时(LLaMA-13B) > nvidia-smi nvlink -i 0 -gt d GPU 0: NVIDIA H800 (UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c) Link 0: Data Tx: 1390774681 KiB Link 0: Data Rx: 1387831436 KiB Link 1: Data Tx: 1390715554 KiB Link 1: Data Rx: 1387856699 KiB Link 2: Data Tx: 1390689916 KiB Link 2: Data Rx: 1387846800 KiB Link 3: Data Tx: 1390772616 KiB Link 3: Data Rx: 1387795114 KiB Link 4: Data Tx: 1391305436 KiB Link 4: Data Rx: 1387910526 KiB Link 5: Data Tx: 1391288579 KiB Link 5: Data Rx: 1387888125 KiB Link 6: Data Tx: 1391348992 KiB Link 6: Data Rx: 1387832695 KiB Link 7: Data Tx: 1391348007 KiB Link 7: Data Rx: 1387855953 KiB > nvidia-smi nvlink -i 0 -gt r GPU 0: NVIDIA H800 (UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c) Link 0: Raw Tx: 1933426555 KiB Link 0: Raw Rx: 1975423057 KiB Link 1: Raw Tx: 1915132335 KiB Link 1: Raw Rx: 1958569530 KiB Link 2: Raw Tx: 1916865102 KiB Link 2: Raw Rx: 1958463156 KiB Link 3: Raw Tx: 1916412075 KiB Link 3: Raw Rx: 1958028986 KiB Link 4: Raw Tx: 1913329166 KiB Link 4: Raw Rx: 1957374521 KiB Link 5: Raw Tx: 1913784453 KiB Link 5: Raw Rx: 1957230286 KiB Link 6: Raw Tx: 1916726453 KiB Link 6: Raw Rx: 1957614726 KiB Link 7: Raw Tx: 1919300185 KiB Link 7: Raw Rx: 1957241622 KiB ``` ## 参考文档 - [nvidia-smi命令详解和一些高阶技巧讲解](https://www.inte.net/news/270918.html) ================================================ FILE: docs/llm-base/rlhf/README.md ================================================ ## 百川2 Reward Model: Prompt多样性:构造了一个200+细分类目的数据体系,尽可能覆盖用户需求,同时提升每类prompt多样性,从而提升泛化能力 Response多样性:用不同尺寸和阶段的百川模型生成答案,不使用其他开源模型(经验证无法提升RM准确率) RM: 设计了一个三层分类系统全面覆盖所有类型的用户需求,包括6个主要类别、30个二级类别、200多个三级类别。 在奖励模型训练时,需要保证每个类别内的数据应该有足够的多样性,以确保奖励模型能够有更好地泛化性。 并且奖励数据中结果需要由Baichuan2模型生成,以确保数据分布的统一。 ================================================ FILE: docs/llm-base/scenes/README.md ================================================ ## 任务合集 ``` 句子嵌入(Sentence Embedding):将句子映射到固定维度的向量表示形式。 文本排序(Text Ranking):对一组文本进行排序,以确定它们与给定查询的相关性。 分词(Word Segmentation):将连续的文本切分成单词或词块的过程。 词性标注(Part-of-Speech):对句子中的每个词汇标注其相应的词性。 标记分类(Token Classification):将输入的文本序列中的每个标记分类为预定义的类别。 命名实体识别(Named Entity Recognition):识别文本中具有特定意义的命名实体,如人名、地点、组织等。 关系抽取(Relation Extraction):从文本中抽取出实体之间的关系或联系。 信息抽取(Information Extraction):从非结构化文本中提取结构化的信息,如实体、关系和属性等。 句子相似度(Sentence Similarity):衡量两个句子之间的语义相似度或相关性。 文本翻译(Translation):将一种语言的文本转换为另一种语言的过程。 自然语言推理(NLI:Natural Language Inference):判断给定的前提和假设之间的逻辑关系,包括蕴含、矛盾和中立等。 情感分类(Sentiment Classification):将文本分为积极、消极或中性等情感类别。 人像抠图(Portrait Matting):从图像中准确地分离人物主体与背景。 通用抠图(Universal Matting):从图像中准确地分离目标物体与背景,不限于人像。 人体检测(Human Detection):检测图像或视频中的人体位置。 图像目标检测(Image Object Detection):在图像中检测和定位多个目标对象。 图像去噪(Image Denoising):降低图像中的噪声水平,改善图像质量。 图像去模糊(Image Deblurring):恢复模糊图像的清晰度和细节。 视频稳定化(Video Stabilization):对视频进行抖动校正,使其稳定且平滑。 视频超分辨率(Video Super-Resolution):通过增加视频的像素级别细节来提高其分辨率。 文本分类(Text Classification):将文本分类为预定义的类别或标签。 文本生成(Text Generation):根据给定输入生成连续文本的过程。 零样本分类(Zero-Shot Classification):将数据分类为模型从未在训练阶段见过的类别。 任务导向对话(Task-Oriented Conversation):进行与特定任务相关的对话和问答。 对话状态跟踪(Dialog State Tracking):跟踪多轮对话中的用户意图和系统状态的变化。 表格问答(Table Question Answering):根据表格数据回答相关问题。 文档导向对话生成(Document-Grounded Dialog Generation):基于文档内容生成相关对话回复。 文档导向对话重新排序(Document-Grounded Dialog Rerank):对生成的对话回复进行排序,以选择最佳回复。 文档导向对话检索(Document-Grounded Dialog Retrieval):从候选对话中检索与文档相关的最佳对话。 文本纠错(Text Error Correction):自动纠正文本中的拼写错误或语法错误。 图像字幕生成(Image Captioning):根据图像内容生成对图像的描述性文字。 视频字幕生成(Video Captioning):根据视频内容生成对视频的描述性文字。 图像人像风格化(Image Portrait Stylization):将图像中的人物主体应用艺术风格转换。 光学字符识别(OCR Detection):从图像中检测和识别文字。 表格识别(Table Recognition):从图像中自动识别表格结构和内容。 无线表格识别(Lineless Table Recognition):从无线表格图像中自动识别表格结构和内容。 文档视觉语义嵌入(Document-VL Embedding):将文档映射到视觉语义空间的向量表示形式。 车牌检测(License Plate Detection):在图像中检测和定位车辆的车牌区域。 填充掩码(Fill-Mask):根据上下文和部分信息填充给定的掩码。 特征提取(Feature Extraction):从输入数据中提取有意义的特征表示。 动作识别(Action Recognition):识别视频中的动作或行为。 动作检测(Action Detection):在视频中检测和定位特定动作或行为。 直播分类(Live Category):对直播视频进行分类,如体育、新闻、游戏等。 视频分类(Video Category):对视频进行分类,如电影、音乐、体育等。 多模态嵌入(Multi-Modal Embedding):将多种不同模态的数据映射到共享的向量空间。 生成式多模态嵌入(Generative Multi-Modal Embedding):将多模态数据映射到向量表示,并且能够生成与之相关的数据。 多模态相似度(Multi-Modal Similarity):衡量多模态数据(例如图像和文本)之间的相似性或相关性。 视觉问答(Visual Question Answering):根据给定的图像和问题回答相关问题。 视频问答(Video Question Answering):根据给定的视频和问题回答相关问题。 视频嵌入(Video Embedding):将视频序列映射到固定维度的向量表示形式。 文本到图像合成(Text-to-Image Synthesis):根据给定的文本描述合成相应的图像。 文本到视频合成(Text-to-Video Synthesis):根据给定的文本描述合成相应的视频。 人体二维关键点(Body 2D Keypoints):检测和跟踪图像中的人体关键点。 人体三维关键点(Body 3D Keypoints):在三维空间中检测和跟踪人体关键点。 手部二维关键点(Hand 2D Keypoints):检测和跟踪图像中的手部关键点。 卡片检测(Card Detection):在图像中检测和定位特定类型的卡片。 内容检查(Content Check):检查文本或图像中是否存在不良、敏感或违法内容。 人脸检测(Face Detection):检测图像或视频中的人脸位置。 人脸活体检测(Face Liveness):判断图像或视频中的人脸是否为真实的活体,而非照片或视频。 人脸识别(Face Recognition):识别图像或视频中的人脸,并将其与已知的身份进行匹配。 面部表情识别(Facial Expression Recognition):识别图像或视频中人脸的表情状态,如快乐、悲伤、愤怒等。 面部属性识别(Face Attribute Recognition):识别图像或视频中人脸的属性,如年龄、性别、种族等。 面部二维关键点(Face 2D Keypoints):检测和跟踪图像中的面部关键点。 面部质量评估(Face Quality Assessment):评估图像或视频中人脸图像的质量。 视频多模态嵌入(Video Multi-Modal Embedding):将多模态数据(如图像和文本)映射到共享的向量空间。 图像色彩增强(Image Color Enhancement):增强图像的色彩饱和度、对比度和亮度等。 虚拟试衣(Virtual Try-On):通过计算机生成的技术,将虚拟服装应用到真实人体图像上,以实现在线试穿效果。 图像上色(Image Colorization):将灰度图像恢复为彩色图像的过程。 视频上色(Video Colorization):将黑白视频恢复为彩色视频的过程。 图像分割(Image Segmentation):将图像分成多个不同的区域或对象。 图像驾驶感知(Image Driving Perception):利用计算机视觉技术提取图像中与驾驶相关的信息,如车道线、交通标志等。 图像深度估计(Image Depth Estimation):根据单目或双目图像估计场景中物体的深度或距离。 室内布局估计(Indoor Layout Estimation):根据室内图像估计房间的布局结构。 视频深度估计(Video Depth Estimation):根据视频中的帧间信息估计场景中物体的深度或距离。 全景深度估计(Panorama Depth Estimation):在全景图像中估计场景中物体的深度或距离。 图像风格迁移(Image Style Transfer):将一个图像的风格应用到另一个图像上,以生成具有新风格的图像。 面部图像生成(Face Image Generation):生成逼真的面部图像,可以用于人脸数据增强、数据生成等应用。 图像超分辨率(Image Super-Resolution):通过增加图像的像素级细节来提高其分辨率。 图像去块效应(Image Debanding):减少图像中由压缩引起的块状伪影或条纹噪声。 图像人像增强(Image Portrait Enhancement):改善图像中人物主体的外观、肤色等特征。 商品检索嵌入(Product Retrieval Embedding):将商品映射到向量表示形式,以支持商品相关性检索。 图像到图像生成(Image-to-Image Generation):根据给定的输入图像生成相应的输出图像。 图像分类(Image Classification):将图像分类为预定义的类别或标签。 光学字符识别(OCR Recognition):从图像中检测和识别印刷体或手写体的文字。 美肤(Skin Retouching):对人脸图像进行美化处理,去除皮肤瑕疵、磨皮等。 常见问题解答(FAQ Question Answering):根据常见问题回答用户的提问。 人群计数(Crowd Counting):根据图像或视频中的人群密度估计人数。 视频单目标跟踪(Video Single Object Tracking):在视频序列中跟踪单个目标对象。 图像人物再识别(Image ReID - Person):根据图像中的人物外观特征进行身份再识别。 文本驱动分割(Text-Driven Segmentation):根据给定的文本描述,对图像或视频中的对象进行分割。 电影场景分割(Movie Scene Segmentation):将电影或视频分割为不同的场景,每个场景代表一个独立的情节或事件。 商店分割(Shop Segmentation):将商店内的物体或区域从图像或视频中分割出来,用于商品展示、智能监控等应用。 图像修复(Image Inpainting):根据已有的图像内容,填补缺失或损坏的部分,恢复原始图像的完整性。 图像按范例绘制(Image Paint-By-Example):根据给定的范例图像,将其他图像修改为具有相似绘画风格或效果的图像。 可控图像生成(Controllable Image Generation):通过控制输入参数或向量,生成具有特定属性、风格或特征的图像。 视频修复(Video Inpainting):根据已有的视频内容,填补缺失或损坏的帧或区域,恢复原始视频的完整性。 视频人像抠像(Video Human Matting):将视频中的人物从背景中分割出来,以便进行后续的编辑或特效处理。 人体重建(Human Reconstruction):基于给定的图像、视频或传感器数据,重建人体的三维模型或姿态信息。 视频帧插值(Video Frame Interpolation):对给定的两个视频帧之间的帧进行生成,以增加视频的帧率或平滑过渡。 视频去隔行(Video Deinterlace):将隔行扫描的视频转换为逐行扫描,提高视频播放的质量和流畅度。 全身人体关键点检测(Human Wholebody Keypoint Detection):在图像或视频中检测和定位人体的关键点,例如头部、手、脚等。 静态手势识别(Hand Static):通过分析手掌形状、手指姿势等信息,识别图像或视频中的静态手势。 人脸、人体和手部检测(Face-Human-Hand Detection):检测和定位图像或视频中的人脸、人体和手部区域。 人脸情绪分析(Face Emotion):通过分析人脸表情,判断图像或视频中人脸所表达的情绪状态。 商品分割(Product Segmentation):将图像或视频中的商品或产品从背景中分割出来,用于商品识别、广告推荐等应用。 参考视频对象分割(Referring Video Object Segmentation):根据给定的参考图像或视频,对图像或视频中的对象进行分割。 视频摘要(Video Summarization):根据视频的内容和特征,生成视频的摘要或概览,提供视频浏览和检索的便利性。 图像天空变换(Image Sky Change):将图像中的天空部分替换为不同的天空背景,改变图像的氛围和环境。 翻译评估(Translation Evaluation):根据给定的翻译结果,评估其质量、准确性以及与原文的一致性。 视频对象分割(Video Object Segmentation):将视频中的对象从背景中分割出来,以便进行后续的编辑或特效处理。 视频多目标跟踪(Video Multi-Object Tracking):在视频中同时跟踪多个移动目标,实时定位和追踪目标的位置。 多视角深度估计(Multi-View Depth Estimation):通过多个视图或图像,估计场景中物体的三维深度信息。 少样本检测(Few-Shot Detection):在只有少量标注样本的情况下,进行目标检测任务,提高模型的泛化能力。 人体形状重塑(Body Reshaping):根据图像或视频中的人体区域,调整人体的形状、姿态或比例,改变人体外貌。 人脸融合(Face Fusion):将一个人的面部特征或表情融合到另一个人的头像上,生成具有两者特点的合成图像。 图像匹配(Image Matching):在图像库或数据库中,找到与给定图像最相似或匹配的图像。 图像质量评估 - 主观评分(Image Quality Assessment - MOS):通过主观评分的方法,评估图像的质量,反映人眼对图像的感知。 图像质量评估 - 降质度量(Image Quality Assessment - Degradation):通过客观度量的方法,评估图像在不同变换或压缩条件下的质量。 视觉高效调优(Vision Efficient Tuning):通过自动化的方法,快速调优和优化视觉模型和算法,提升计算效率和准确性。 三维目标检测(Object Detection 3D):在三维空间中,检测和定位目标物体的位置、尺寸和姿态。 坏图像检测(Bad Image Detecting):识别和检测出图像中存在的噪点、模糊、失真等不良或低质量的图像。 Nerf重建精度评估(NeRF Reconstruction Accuracy):评估神经辐射场(NeRF)模型在建立3D场景重建时的准确性和质量。 Siamese UIE:Siamese网络用于UIE任务,即输入用户界面元素识别或生成的相关问题。 数学公式识别(LatexOCR):图片中数学公式的latex识别。 ``` ================================================ FILE: docs/llm-base/scenes/cv/README.md ================================================ ## CV算法 - 图像分类 - 图像语义分割(Semantic Segmentation) - 目标检测(Object Detection) - 视频分类(video classification) - 人脸关键点检测 - 图像超分辨率(Image Super Resolution) - 图像生成 - 目标跟踪 - 图像重构 - 超分 - 风格迁移 - 姿态估计 ## 算法 - CNN - https://deeplearning-doc.readthedocs.io/en/latest/deeplearning/CNN/CNN.html ================================================ FILE: docs/llm-base/scenes/cv/paddle/README.md ================================================ - https://www.paddlepaddle.org.cn/documentation/docs/zh/practices/cv/landmark_detection.html wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://www.eecs.berkeley.edu/Research/Projects/CS/vision/grouping/BSR/BSR_bsds500.tgz tar -zxvf BSR_bsds500.tgz ================================================ FILE: docs/llm-base/scenes/cv/pytorch/README.md ================================================ ## pyav ``` pip install av ``` - Pytorch搭建训练简单的图像分割模型:https://blog.csdn.net/qq_42032507/article/details/103052193 ================================================ FILE: docs/llm-base/scenes/cv/reference.md ================================================ - https://pytorch.org/vision/stable/models.html ================================================ FILE: docs/llm-base/scenes/multi-modal/README.md ================================================ ## 算法 CLIP BLIP BLIP2 LLaVA miniGPT4 InstructBLIP MDETR ### Stable Diffusion 扩散模型 , 多模态任务:文生图 图生图 - https://huggingface.co/docs/peft/task_guides/dreambooth_lora - https://github.com/huggingface/peft/tree/v0.6.2/examples/lora_dreambooth - 推理:https://github.com/huggingface/peft/blob/v0.6.2/examples/lora_dreambooth/lora_dreambooth_inference.ipynb - 数据:https://huggingface.co/datasets/diffusers/docs-images 支持多种微调技术:LoRA、 LoHa、 LoKr - 扩散模型库:https://huggingface.co/docs/diffusers/tutorials/tutorial_overview CompVis/stable-diffusion-v1-4 lambdalabs/pokemon-blip-captions:https://huggingface.co/datasets/lambdalabs/pokemon-blip-captions ### Blip2 image to text (Multi-modal models) - 微调:https://github.com/huggingface/peft/blob/v0.6.2/examples/int8_training/fine_tune_blip2_int8.py - 模型及示例:https://huggingface.co/Salesforce/blip2-opt-2.7b - 使用 BLIP-2 零样本“图生文:https://huggingface.co/blog/zh/blip-2 ## 任务 文生图,还能实现图生文、图文联合生成、无条件图文生成、图文改写 文生图(Generation) (文本->图像) 视觉问答(Visual Question Answering) (图像+文本 ->文本) 多模态分类 (Multimodal classification) (图像+文本 -> 标签) 优化理解/生成(Better understanding/generation) (图像+文本 ->标签/文本) 零样本图像描述生成 通用视觉问答 文本导向的视觉问答 细粒度视觉定位 - https://github.com/THUDM/CogView 例如给定一张图片,可以完成以下任务: 一、VQA(Visual Question Answering)视觉问答输入:一张图片、一个自然语言描述的问题输出:答案(单词或短语) 二、Image Caption 图像字幕输入:一张图片输出:图片的自然语言描述(一个句子) 三、Referring Expression Comprehension 指代表达输入:一张图片、一个自然语言描述的句子输出:判断句子描述的内容(正确或错误) 四、Visual Dialogue 视觉对话输入:一张图片输出:两个角色进行多次交互、对话 五、VCR (Visual Commonsense Reasoning) 视觉常识推理输入:1个问题,4个备选答案,4个理由输出:正确答案,和理由 六、NLVR(Natural Language for Visual Reasoning)自然语言视觉推理 输入:2张图片,一个分布 输出:true或false 七、Visual Entailment 视觉蕴含 输入:图像、文本 输出:3种label的概率。(entailment、neutral、contradiction)蕴含、中性、矛盾 八、Image-Text Retrieval 图文检索 有3种方式。 1)以图搜文。输入图片,输出文本 2)以文搜图。输入文本,输出图片 3)以图搜图,输入图片,输出图片 ## 多模态通用模型 FLAVA https://github.com/facebookresearch/multimodal/tree/main/examples/flava ================================================ FILE: docs/llm-base/scenes/multi-modal/reference.md ================================================ - [多模态大模型 CLIP, BLIP, BLIP2, LLaVA, miniGPT4, InstructBLIP 系列解读](https://zhuanlan.zhihu.com/p/653902791) - [AIGC爆火的背后——对抗生成网络GAN浅析](https://zhuanlan.zhihu.com/p/580137376) - [AIGC爆火的背后——扩散模型DDPM浅析](https://zhuanlan.zhihu.com/p/590840909) - [十分钟读懂Diffusion:图解Diffusion扩散模型](https://zhuanlan.zhihu.com/p/599887666) - [十分钟读懂Stable Diffusion](https://zhuanlan.zhihu.com/p/600251419) - [CogVLM](https://github.com/THUDM/CogVLM/blob/main/README_zh.md) - [Qwen-VL](https://github.com/QwenLM/Qwen-VL/blob/master/README_CN.md) - https://github.com/facebookresearch/multimodal LateFusion, FLAVA and CLIP ================================================ FILE: docs/llm-base/singularity命令.md ================================================ ``` # -cleanenv选项来禁用所有环境变量,确保容器的环境是独立的 singularity run --cleanenv my_container.sif ``` ================================================ FILE: docs/llm-base/slurm.md ================================================ - Slurm简介: http://hmli.ustc.edu.cn/doc/linux/slurm-install/slurm-install.html ## 简介 所有需运行的作业,无论是用于程序调试还是业务计算,都可以通过交互式并行 srun 、批处理式 sbatch 或分配式 salloc 等命令提交,提交后可以利用相关命令查询作业状态。 ## 架构 Slurm采用slurmctld服务(守护进程)作为中心管理器用于监测资源和作业,为了提高可用性,还可以配置另一个备份冗余管理器。 各计算节点需启动slurmd守护进程,以便被用于作为远程shell使用:等待作业、执行作业、返回状态、再等待更多作业。 slurmdbd(Slurm DataBase Daemon)数据库守护进程(非必需,建议采用,也可以记录到纯文本中等),可以将多个slurm管理的集群的记账信息记录在同一个数据库中。 还可以启用slurmrestd(Slurm REST API Daemon)服务(非必需),该服务可以通过REST API与Slurm进行交互,所有功能都对应的API。 用户工具包含 - srun 运行作业、 - scancel 终止排队中或运行中的作业、 - sinfo 查看系统状态、 - squeue 查看作业状态、 - sacct 查看运行中或结束了的作业及作业步信息等命令。 - sview 命令可以图形化显示系统和作业状态(可含有网络拓扑)。 - scontrol 作为管理工具,可以监控、修改集群的配置和状态信息等。 - 用于管理数据库的命令是 sacctmgr ,可认证集群、有效用户、有效记账账户等。 ```python import os from multiprocessing import Pool, cpu_count # function you want to run in parallel: def myfunction(a, b): return a + b # list of tuples to serve as arguments to function: args = [(1, 2), (9, 11), (6, 2)] # number of cores you have allocated for your slurm task: number_of_cores = int(os.environ['SLURM_CPUS_PER_TASK']) print("number_of_cores: ", number_of_cores) # number_of_cores = cpu_count() # if not on the cluster you should do this instead # multiprocssing pool to distribute tasks to: with Pool(number_of_cores) as pool: # distribute computations and collect results: results = pool.starmap(myfunction, args) ``` 节点: Head Node:头节点、管理节点、控制节点,运行slurmctld管理服务的节点。 Compute Node:计算节点,运行作业计算任务的节点,需运行slurmd服务。 Login Node:用户登录节点,用于用户登录的节点。 SlurmDBD Node:SlurmDBD节点、SlurmDBD数据库节点,存储调度策略、记账和作业等信息的节点,需运行slurmdbd服务。 客户节点:含计算节点和用户登录节点。 用户: account:账户,一个账户可以含有多个用户。 user:用户,多个用户可以共享一个账户。 bank account:银行账户,对应机时费等。 资源: GRES:Generic Resource,通用资源。 TRES:Trackable RESources,可追踪资源。 QOS:Quality of Service,服务质量,作业优先级。 association:关联。可利用其实现,如用户的关联不在数据库中,这将阻止用户运行作业。该选项可以阻止用户访问无效账户。 Partition:队列、分区。用于对计算节点、作业并行规模、作业时长、用户等进行分组管理,以合理分配资源。 ================================================ FILE: docs/llm-base/分布式训练加速技术.md ================================================ 分布式并行技术: - 数据并行 - 张量并行 - 流水线并行 - MOE并行(稀疏化) - ZeRO - 序列并行(LayerNorm 和 Dropout 的计算被平摊到了各个设备上,减少了计算资源的浪费;LayerNorm 和 Dropout 所产生的激活值也被平摊到了各个设备上,进一步降低了显存开销。) 混合精度训练: - FP16 / BF16 - FP8(NVIDIA H系列GPU开始支持FP8,兼有FP16的稳定性和INT8的速度),Nvidia Transformer Engine 兼容 FP8 框架,主要利用这种精度进行 GEMM(通用矩阵乘法)计算,同时以 FP16 或 FP32 高精度保持主权重和梯度。 MS-AMP训练框架 (使用FP8进行训练),与广泛采用的 BF16 混合精度方法相比,内存占用减少 27% 至 42%,权重梯度通信开销显著降低 63% 至 65%。运行速度比广泛采用的 BF16 框架(例如 Megatron-LM)快了 64%,比 Nvidia Transformer Engine 的速度快了 17%。 重计算(Recomputation)/梯度检查点(gradient checkpointing):一种在神经网络训练过程中使动态计算只存储最小层数的技术。一种用计算换显存的方法。通过减少保存的激活值来压缩模型占用空间,在计算梯度时必须重新计算没有存储的激活值。 梯度累积:它将多个Batch训练数据的梯度进行累积,在达到指定累积次数后,使用累积梯度统一更新一次模型参数,以达到一个较大Batch Size的模型训练效果。累积梯度等于多个Batch训练数据的梯度的平均值。 FlashAttention v1 and v2 :通过分块计算和kernel融合,减少了HBM访问次数,实现了计算加速,同时减少了显存占用。 参考:Megatron-deepspeed , 训练推理都可以使用。 MQA / GQA: 一定程度的Key value的共享,从而可以使模型体积减小,减少了数据的读取。 集群网络通信硬件优化: - 服务器内:nvlink > pcie - 服务器间:nvlink > InfiniBand (256-nvlink)> tcp/ip 更高性能的AI芯片: - H200>H100>A100 卸载(Offload)技术:一种用通信换显存的方法,简单来说就是让模型参数、激活值等在CPU内存和GPU显存之间左右横跳。如:ZeRO-Offload、ZeRO-Infinity等。 混合精度(BF16/FP16):降低训练显存的消耗,还能将训练速度提升2-4倍。 ================================================ FILE: docs/llm-base/多机RDMA性能测试.txt ================================================ ``` wget https://developer.download.nvidia.com/compute/cuda/12.1.1/local_installers/cuda_12.1.1_530.30.02_linux.run sudo sh cuda_12.1.1_530.30.02_linux.run ``` /usr/local/cuda/bin/nvcc -V #查看CUDA版本,可正确查看,表示CUDA已安装成功。 ``` tar -xvzf openmpi-4.1.1.tar.gz cd openmpi-4.1.1/ ./configure --prefix=/usr/local/openmpi make -j 80 make install -j 80 export LD_LIBRARY_PATH=/usr/local/cuda-11.0/lib64:/usr/local/nccl_2.11.4-1+cuda11.0_x86_64/lib:/usr/local/openmpi/lib:$LD_LIBRARY_PATH export PATH=/usr/local/openmpi/bin:/usr/local/cuda-11.0/bin:$PATH ldconfig ``` ``` wget https://github.com/NVIDIA/nccl-tests/archive/refs/tags/v2.10.1.tar.gz make -j40 MPI=1 MPI_HOME=/usr/local/openmpi CUDA_HOME=/usr/local/cuda-11.0 NCCL_HOME=/usr/local/nccl_2.11.4-1+cuda11.0_x86_64 ``` --- 在节点A执行以下命令 ``` ibdev2netdev ifconfig ``` ``` ib_write_bw -a -b -d mlx5_1 -x 3 --report_gbits ``` 在节点B执行以下命令,IP地址(198.XX.XX.XX)需替换为节点A的mlx5_1网卡IP。 ``` ib_write_bw -a -b -F 198.XX.XX.XX -d mlx5_1 --report_gbits -x 3 ``` 使用NCCL Tests测试工具评估集群性能 ``` mpirun -x NCCL_IB_HCA=mlx5_1:1 -x NCCL_IB_DISABLE=0 -x NCCL_SOCKET_IFNAME=eth1 -x NCCL_IB_GID_INDEX=3 -x NCCL_IB_TIMEOUT=23 -x NCCL_IB_RETRY_CNT=7 -hostfile hostfile -n 16 -N 8 --allow-run-as-root --mca btl tcp,self --mca btl_tcp_if_exclude lo,mlx5_0 ./build/all_reduce_perf -b 8 -e 1G -f 2 -g 1 -c 1 -n 100 ``` --- ================================================ FILE: docs/llm-base/机器学习中常用的数据类型.md ================================================ - https://en.wikipedia.org/wiki/Bfloat16_floating-point_format#bfloat16_floating-point_format 模型的大小由其参数量及其精度决定,精度通常为 float32、float16 或 bfloat16 之一 ![](https://huggingface.co/blog/assets/96_hf_bitsandbytes_integration/tf32-Mantissa-chart-hi-res-FINAL.png) ![](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/bitsandbytes/FP8-scheme.png) ## FP32 Float32 (FP32) 是标准的 IEEE 32 位浮点表示。使用该数据类型,可以表示大范围的浮点数。 在 FP32 中,为“指数”保留了 8 位,为“尾数”保留了 23 位,为符号保留了 1 位。因为是标准数据类型,所以大部分硬件都支持 FP32 运算指令。 ## FP16 而在 Float16 (FP16) 数据类型中,指数保留 5 位,尾数保留 10 位。 这使得 FP16 数字的数值范围远低于 FP32。因此 FP16 存在上溢 (当用于表示非常大的数时) 和下溢 (当用于表示非常小的数时) 的风险。 例如,当你执行 10k * 10k 时,最终结果应为 100M,FP16 无法表示该数,因为 FP16 能表示的最大数是 64k。 因此你最终会得到 NaN (Not a Number,不是数字),在神经网络的计算中,因为计算是按层和 batch 顺序进行的,因此一旦出现 NaN,之前的所有计算就全毁了。 一般情况下,我们可以通过缩放损失 (loss scaling) 来缓解这个问题,但该方法并非总能奏效。 ## BF16 于是我们发明了一种新格式 Bfloat16 (BF16) 来规避这些限制。 BF16 为指数保留了 8 位 (与 FP32 相同),为小数保留了 7 位。 这意味着使用 BF16 我们可以保留与 FP32 相同的动态范围。 但是相对于 FP16,我们损失了 3 位精度。因此,在使用 BF16 精度时,大数值绝对没有问题,但是精度会比 FP16 差。 ## TF32 在 Ampere 架构中,NVIDIA 还引入了 TensorFloat-32(TF32) 精度格式,它使用 19 位表示, 结合了 BF16 的范围和 FP16 的精度。目前,它仅在某些操作的内部使用 [即 TF32 是一个计算数据类型而不是存储数据类型]。 ## INT8 除此以外,还有 Int8 (INT8) 数据类型,它是一个 8 位的整型数据表示,可以存储 $2^8$ 个不同的值 (对于有符号整数,区间为 [-128, 127], 而对于无符号整数,区间为 [0, 255])。 ## FP4 ## NF4 --- 在机器学习术语中,FP32 称为全精度 (4 字节),而 BF16 和 FP16 称为半精度 (2 字节)。 虽然理想情况下训练和推理都应该在 FP32 中完成,但 FP32 比 FP16/BF16 慢两倍, 因此实践中常常使用混合精度方法,其中,使用 FP32 权重作为精确的 “主权重 (master weight)”, 而使用 FP16/BF16 权重进行前向和后向传播计算以提高训练速度,最后在梯度更新阶段再使用 FP16/BF16 梯度更新 FP32 主权重。 在训练期间,主权重始终为 FP32。而在实践中,在推理时,半精度权重通常能提供与 FP32 相似的精度 —— 因为只有在模型梯度更新时才需要精确的 FP32 权重。 这意味着在推理时我们可以使用半精度权重,这样我们仅需一半 GPU 显存就能获得相同的结果。 ================================================ FILE: docs/llm-experience.md ================================================ 微调: PEFT总是有局限性,基于低秩的微调可能并不always work,比如:finetune与pretrain的gap过大的时候,比如中英差异。 微调的过程不是让模型适应另外的数据分布,而是让模型更好的激发出本身的表征能力。 量化: ================================================ FILE: docs/llm-inference/DeepSpeed-Inference.md ================================================ 目前业界基本都针对 Transformer layer 结构特点,手工实现了算子融合。以 DeepSpeed Inference 为例,算子融合主要分为如下四类: 归一化层和 QKV 横向融合:将三次计算 Query/Key/Value 的操作合并为一个算子,并与前面的归一化算子融合。 自注意力计算融合:将自注意力计算涉及到的多个算子融合为一个,业界熟知的 FlashAttention 即是一个成熟的自注意力融合方案。 残差连接、归一化层、全连接层和激活层融合:将 MLP 中第一个全连接层上下相关的算子合并为一个。 偏置加法和残差连接融合。 ================================================ FILE: docs/llm-inference/KV-Cache.md ================================================ 最后需要注意当sequence特别长的时候,KV Cache其实还是个Memory刺客。 比如batch_size=32, head=32, layer=32, dim_size=4096, seq_length=2048, float32类型,则需要占用的显存为(感谢网友指正) 2 * 32 * 4096 * 2048 * 32 * 4 / 1024/1024/1024 /1024 = 64G。 ================================================ FILE: docs/llm-inference/LLM服务框架对比.md ================================================ ## FlexFlow Server - https://github.com/flexflow/FlexFlow/tree/inference 指标: 每秒生成token的延迟 模型: LLaMA-30B LLaMA-65B OPT-30B 对比框架:vLLM、TGI、FT ## vLLM - https://github.com/vllm-project/vllm/tree/main - https://vllm.ai/ - https://github.com/vllm-project/vllm/tree/main/benchmarks 指标: 吞吐 延迟 对比框架: TGI、HF、vLLM ## FT - https://github.com/NVIDIA/FasterTransformer/blob/main/docs/gpt_guide.md Latency on input length 60, output length 20, TP means tensor parallelism and PP means pipeline parallelism. 每秒处理的句子 Throughput per GPU on input length 60, output length 20. TP means tensor parallelism and PP means pipeline parallelism. Megatron 530B GPT 175B ## Huggingface TGI - https://github.com/huggingface/text-generation-inference/tree/main/benchmark 预填充延迟 预填充吞吐量(每秒处理的Token数) 解码总延迟、解码单Token延迟 解码吞吐量(每秒处理的Token数) ================================================ FILE: docs/llm-inference/README.md ================================================ 吞吐量 延迟 投机采样: - https://github.com/feifeibear/LLMSpeculativeSampling 美杜莎: - https://github.com/FasterDecoding/Medusa - Medusa: Simple Framework for Accelerating LLM Generation with Multiple Decoding Heads - https://sites.google.com/view/medusa-llm - OpenLLM: https://github.com/bentoml/OpenLLM ## Triton ## 博客 - https://huggingface.co/blog/optimize-llm - 加速大模型推理的7种方法:https://betterprogramming.pub/speed-up-llm-inference-83653aa24c47 - 7个大模型推理服务化框架:https://betterprogramming.pub/frameworks-for-serving-llms-60b7f7b23407 ================================================ FILE: docs/llm-inference/blog.md ================================================ - LLM推理优化技术综述:KVCache、PageAttention、FlashAttention、MQA、GQA:https://zhuanlan.zhihu.com/p/655325832 ## KVCache ## PageAttention PageAttention是目前kv cache优化的重要技术手段,目前最炙手可热的大模型推理加速项目VLLM的核心就是PageAttention技术。 在缓存中,这些 KV cache 都很大,并且大小是动态变化的,难以预测。已有的系统中,由于显存碎片和过度预留,浪费了60%-80%的显存。 PageAttention提供了一种技术手段解决显存碎片化的问题,从而可以减少显存占用,提高KV cache可使用的显存空间,提升推理性能。 --- 首先,PageAttention命名的灵感来自OS系统中虚拟内存和分页的思想。可以实现在不连续的空间存储连续的kv键值。 另外,因为所有键值都是分布存储的,需要通过分页管理彼此的关系。序列的连续逻辑块通过 block table 映射到非连续物理块。 另外,同一个prompt生成多个输出序列,可以共享计算过程中的attention键值,实现copy-on-write机制,即只有需要修改的时候才会复制,从而大大降低显存占用。 ## FlashAttention Flash attention推理加速技术是利用GPU硬件非均匀的存储器层次结构实现内存节省和推理加速,它的论文标题是“FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness”。意思是通过合理的应用GPU显存实现IO的优化,从而提升资源利用率,提高性能。 首先我们要了解一个硬件机制,计算速度越快的硬件往往越昂贵且体积越小,Flash attention的核心原理是尽可能地合理应用SRAM内存计算资源。 A100 GPU有40-80GB的高带宽内存(HBM),带宽为1.5-2.0 TB/s,而每108个流处理器有192KB的SRAM,带宽估计在19TB/s左右。 也就是说,存在一种优化方案是利用SRAM远快于HBM的性能优势,将密集计算尽放在SRAM,减少与HBM的反复通信,实现整体的IO效率最大化。比如可以将矩阵计算过程,softmax函数尽可能在SRAM中处理并保留中间结果,全部计算完成后再写回HBM,这样就可以减少HBM的写入写出频次,从而提升整体的计算性能。 如何有效分割矩阵的计算过程,涉及到flash attention的核心计算逻辑Tiling算法。 ### v1 ### v2 ## MQA/GQA MQA,全称 Multi Query Attention, 而 GQA 则是前段时间 Google 提出的 MQA 变种,全称 Group-Query Attention。MHA(Multi-head Attention)是标准的多头注意力机制,h个Query、Key 和 Value 矩阵。MQA 让所有的头之间共享同一份 Key 和 Value 矩阵,每个头只单独保留了一份 Query 参数,从而大大减少 Key 和 Value 矩阵的参数量。GQA将查询头分成N组,每个组共享一个Key 和 Value 矩阵。 GQA以及MQA都可以实现一定程度的Key value的共享,从而可以使模型体积减小,GQA是MQA和MHA的折中方案。这两种技术的加速原理是(1)减少了数据的读取(2)减少了推理过程中的KV Cache。需要注意的是GQA和MQA需要在模型训练的时候开启,按照相应的模式生成模型。 - 大语言模型推理性能优化综述: https://zhuanlan.zhihu.com/p/656485997 LLM 推理服务重点关注两个指标:吞吐量和时延: 吞吐量:主要从系统的角度来看,即系统在单位时间内能处理的 tokens 数量。计算方法为系统处理完成的 tokens 个数除以对应耗时,其中 tokens 个数一般指输入序列和输出序列长度之和。吞吐量越高,代表 LLM 服务系统的资源利用率越高,对应的系统成本越低。 时延:主要从用户的视角来看,即用户平均收到每个 token 所需位时间。计算方法为用户从发出请求到收到完整响应所需的时间除以生成序列长度。一般来讲,当时延不大于 50 ms/token 时,用户使用体验会比较流畅。 吞吐量关注系统成本,高吞吐量代表系统单位时间处理的请求大,系统利用率高。时延关注用户使用体验,即返回结果要快。这两个指标一般情况下需要会相互影响,因此需要权衡。例如, 提高吞吐量的方法一般是提升 batchsize,即将用户的请求由串行改为并行。但 batchsize 的增大会在一定程度上损害每个用户的时延,因为以前只计算一个请求,现在合并计算多个请求,每个用户等待的时间变长。 LLM 推理性能优化主要以提高吞吐量和降低时延为目的. ## 显存相关优化 ### KV Cache 大模型推理性能优化的一个最常用技术就是 KV Cache,该技术可以在不影响任何计算精度的前提下,通过空间换时间思想,提高推理性能。 目前业界主流 LLM 推理框架均默认支持并开启了该功能。 KV Cache 的引入也使得推理过程分为如下两个不同阶段,进而影响到后续的其他优化方法。 预填充阶段:发生在计算第一个输出 token 过程中,计算时需要为每个 Transformer layer 计算并保存 key cache 和 value cache;FLOPs 同 KV Cache 关闭一致,存在大量 GEMM (GEneral Matrix-Matrix multiply) 操作,属于 Compute-bound 类型计算。 解码阶段:发生在计算第二个输出 token 至最后一个 token 过程中,这时 KV Cache 已存有历史键值结果,每轮推理只需读取 Cache,同时将当前轮计算出的新的 Key、Value 追加写入至 Cache;GEMM 变为 GEMV (GEneral Matrix-Vector multiply) 操作,FLOPs 降低,推理速度相对预填充阶段变快,这时属于 Memory-bound 类型计算。 ### Paged Attention LLM 推理服务的吞吐量指标主要受制于显存限制。研究团队发现现有系统由于缺乏精细的显存管理方法而浪费了 60% 至 80% 的显存,浪费的显存主要来自 KV Cache。因此,有效管理 KV Cache 是一个重大挑战。 在 Paged Attention 之前,业界主流 LLM 推理框架在 KV Cache 管理方面均存在一定的低效。 HuggingFace Transformers 库中,KV Cache 是随着执行动态申请显存空间,由于 GPU显存分配耗时一般都高于 CUDA kernel 执行耗时,因此动态申请显存空间会造成极大的时延开销,且会引入显存碎片化。 FasterTransformer 中,预先为 KV Cache 分配了一个充分长的显存空间,用于存储用户的上下文数据。例如 LLaMA-7B 的上下文长度为 2048,则需要为每个用户预先分配一个可支持 2048 个 tokens 缓存的显存空间。如果用户实际使用的上下文长度低于2048,则会存在显存浪费。 aged Attention 将传统操作系统中对内存管理的思想引入 LLM,实现了一个高效的显存管理器,通过精细化管理显存,实现了在物理非连续的显存空间中以极低的成本存储、读取、新增和删除键值向量。 具体来讲,Paged Attention 将每个序列的 KV Cache 分成若干块,每个块包含固定数量token 的键和值。 首先在推理实际任务前,会根据用户设置的 max_num_batched_tokens 和 gpu_memory_util 预跑一次推理计算,记录峰值显存占用量 peak_memory,然后根上面公式获得当前软硬件环境下 KV Cache 可用的最大空间,并预先申请缓存空间。 其中,max_num_batched_tokens 为部署环境的硬件显存一次最多能容纳的 token 总量, gpu_memory_util 为模型推理的最大显存占用比例, total_gpu_memory 为物理显存量, block_size 为块大小(默认设为 16)。 在实际推理过程中,维护一个逻辑块到物理块的映射表,多个逻辑块可以对应一个物理块,通过引用计数来表示物理块被引用的次数。 当引用计数大于一时,代表该物理块被使用,当引用计数等于零时,代表该物理块被释放。 通过该方式即可实现将地址不连续的物理块串联在一起统一管理。 Paged Attention 技术开创性地将操作系统中的分页内存管理应用到 KV Cache 的管理中,提高了显存利用效率。 另外,通过 token 块粒度的显存管理,系统可以精确计算出剩余显存可容纳的 token 块的个数,配合后文 Dynamic Batching 技术,即可避免系统发生显存溢出的问题。 ## 计算相关优化 ### 算子融合 算子融合是深度学习模型推理的一种典型优化技术,旨在通过减少计算过程中的访存次数和 Kernel 启动耗时达到提升模型推理性能的目的,该方法同样适用于 LLM 推理。 目前业界基本都针对 Transformer layer 结构特点,手工实现了算子融合。以 DeepSpeed Inference 为例,算子融合主要分为如下四类: 归一化层和 QKV 横向融合:将三次计算 Query/Key/Value 的操作合并为一个算子,并与前面的归一化算子融合。 自注意力计算融合:将自注意力计算涉及到的多个算子融合为一个,业界熟知的 FlashAttention 即是一个成熟的自注意力融合方案。 残差连接、归一化层、全连接层和激活层融合:将 MLP 中第一个全连接层上下相关的算子合并为一个。 偏置加法和残差连接融合。 由于算子融合一般需要定制化实现算子 CUDA kernel,因此对 GPU 编程能力要求较高。随着编译器技术的引入,涌现出 OpenAI Triton 、TVM 等优秀的框架来实现算子融合的自动化或半自动化,并取得了一定的效果。 ### 高性能算子 针对 LLM 推理运行热点函数编写高性能算子,也可以降低推理时延。 GEMM 操作相关优化:在 LLM 推理的预填充阶段,Self-Attention 和 MLP 层均存在多个 GEMM 操作,耗时占据了推理时延的 80% 以上。GEMM 的 GPU 优化是一个相对古老的问题,在此不详细展开描述算法细节。英伟达就该问题已推出 cuBLAS、CUDA、CUTLASS 等不同层级的优化方案。例如,FasterTransformer 框架中存在大量基于 CUTLASS 编写的 GEMM 内核函数。另外,Self-Attention 中存在 GEMM+Softmax+GEMM 结构,因此会结合算子融合联合优化。 GEMV 操作相关优化:在 LLM 推理的解码阶段,运行热点函数由 GEMM 变为 GEMV。相比 GEMM,GEMV 的计算强度更低,因此优化点主要围绕降低访存开销开展。 ## 服务相关优化 ================================================ FILE: docs/llm-inference/flexflow/投机采样.md ================================================ - 大模型推理妙招—投机采样(Speculative Decoding): https://zhuanlan.zhihu.com/p/651359908 为了解决推理速度慢的问题,已经进行了许多针对推理的工程优化,例如改进的计算核心实现、多卡并行计算、批处理策略等等。然而,这些方法并没有从根本上解决LLM解码过程是受制于访存带宽的问题。 投机采样是一种可以从根本上解码计算访存比的方法,保证和使用原始模型的采样分布完全相同。 它使用两个模型:一个是原始目标模型,另一个是比原始模型小得多的近似模型。 近似模型用于进行自回归串行采样,而大型模型则用于评估采样结果。 解码过程中,某些token的解码相对容易,某些token的解码则很困难。因此,简单的token生成可以交给小型模型处理,而困难的token则交给大型模型处理。这里的小型模型可以采用与原始模型相同的结构,但参数更少,或者干脆使用n-gram模型。 小型模型不仅计算量较小,更重要的是减少了内存访问的需求。 --- ## 自回归采样 先科普一下LLM解码时采用的自回归采样,其过程如下: 模型使用前缀作为输入,将输出结果处理+归一化成概率分布后,采样生成下一个token。 将生成的token和前缀拼接成新的前缀,重复执行1,直到生成EOS或者达到最大token数目。 第1步中,将模型输出logits的转换成概率,有几种常用的采样方法,包括argmax、top-k和top-n等。 自回归采样中生成的token一个一个地蹦出来,因为每次只对序列长度为1的部分进行有效计算,但是却需要对全部前缀对应位置的activations进行访问,因此计算访存比很低。 --- ## 投机采样 投机采样过程如下: 用小模型Mq做自回归采样连续生成 y 个tokens。 把生成的 y 个tokens和前缀拼接一起送进大模Mp执行一次forwards。 使用大、小模型logits结果做比对,如果发现某个token小模型生成的不好,重新采样这个token。重复步骤1。 如果小模型生成结果都满意,则用大模型采样下一个token。重复步骤1。 第2步,将y个tokens和前缀拼成一起作为大模型输入,和自回归相比,尽管计算量一样,但是 y 个tokens可以同时参与计算,计算访存比显著提升。 第3步,如何评价一个token生成的不好?如果q(x) > p(x)(p,q表示在大小模型采样概率,也就是logits归一化后的概率分布) 则以一定1-p(x)/q(x)为概率拒绝这个token的生成,从一个新的概率分布p’(x) = norm(max(0, p(x) − q(x)))中重新采样一个token。 --- ## 为什么投机采样和自回归采样等价 p(x’) > q(x’)说明大模型在token x’上概率大于小模型,则大模型对生成token x’更有把握,说明小模型生成的问题不大可以保留x’。 如果p(x’) ≤ q(x’)则小模型更有把握,大模型就以1-p(x)/q(x)为概率概率拒绝,并重新采样。因为接收的概率更偏向q(x)大的位置,重新采样的概率应该更偏向p(x)大的位置,所以是norm(max(0, p(x)-q(x))。 ## 加速效果 投机采样相比自回归采样之所以有加速效果,因为它减少了对原始模型串行调用的次数。这里规定一次迭代可以接收小模型的tokens数为#generated tokens。 ================================================ FILE: docs/llm-inference/llm推理优化技术.md ================================================ - Mastering LLM Techniques: Inference Optimization: https://developer.nvidia.com/blog/mastering-llm-techniques-inference-optimization/ - 7 Ways To Speed Up Inference of Your Hosted LLMs:https://betterprogramming.pub/speed-up-llm-inference-83653aa24c47 - How to Speed Up LLM Training with Distributed Systems?:https://www.appypie.com/blog/llm-training-with-distributed-systems - 详谈大模型训练和推理优化技术:https://wjn1996.blog.csdn.net/article/details/130764843 - LLM 盛行,如何优雅地训练大模型?:https://cloud.tencent.com/developer/article/2321394?areaId=106001 底延迟、高吞吐量 (权衡) 首Token延迟,平均Token延迟 - 模型量化 - AutoAWQ(W4A16)、SmoothQuant(W8A8),参考:TensorRT-LLM - GPTQ、bitsandbytes(LLM.int8()),参考:hf transformers - KV Cache 量化 (降低显存,从而进一步增加处理的batch大小) - 分布式并行推理 - 张量并行推理(降低延迟) - 流水线并行推理(提高吞吐量) - 模型服务化调度优化: - 动态batch,参考:inference triton server - continuous batching,参考:vllm - 投机采样 - 使用一个小模型来做草稿,然后使用大模型做纠正检查。参考:flexflow server - 模型编译优化: - AI编译前端优化:图算融合、内存分配、常量折叠、公共子表达式消除、死代码消除、代数化简 - AI编译后端优化:算子融合、循环优化 - 显存优化: - 通过 PagedAttention 对 KV Cache 的有效管理,参考:vllm - CPU Offloading是将张量保存在CPU内存中,并且在计算时仅将张量复制到GPU。 - 低精度浮点数优化: - FP8(NVIDIA H系列GPU开始支持FP8,兼有FP16的稳定性和INT8的速度),Nvidia Transformer Engine 兼容 FP8 框架,主要利用这种精度进行 GEMM(通用矩阵乘法)计算,同时以 FP16 或 FP32 高精度保持主权重和梯度。 MS-AMP (使用FP8进行训练) - FP16 / BF16 前端优化:输入计算图,关注计算图整体拓扑结构,而不关心算子的具体实现。在 AI 编译器的前端优化,对算子节点进行融合、消除、化简等操作,使计算图的计算和存储开销最小。 后端优化:关注算子节点的内部具体实现,针对具体实现使得性能达到最优。重点关心节点的输入,输出,内存循环方式和计算的逻辑。 简单的来说: - 就是使用一个小模型来做草稿,然后使用大模型做纠正检查。 - 小模型的参数量要远小于原模型参数量一个级别才效果明显。 - 小模型和原模型的tokenizer最好一模一样,不然会增加额外的解码、编码时间。 ## 对比下Flash Attention和Paged Attention PagedAttention是应用在推理时,用分块内存和共享内存优化了KV cache的存储。减少了单个序列的显存,从而可以增大batch size,获得了更大的吞吐量。总的说,目标是推理时,减少显存,增大吞吐量。 这个团队之前有篇类似的工作FlexGen,推理时通过对KV cache进行高效的CPU卸载,提升了吞吐量。 Flash Attention则是训练和推理都可以使用,通过分块计算和kernel融合,减少了HBM访问次数,实现了计算加速,同时减少了显存占用。理论上,Flash Attention和Paged Attention可以组合使用。 ================================================ FILE: docs/llm-inference/llm推理框架.md ================================================ ## vLLM 适用于大批量Prompt输入,并对推理速度要求高的场景; ## Huggingface TGI 依赖HuggingFace模型,并且不需要为核心模型增加多个adapter的场景; ## DeepSpeed-MII 使用DeepSpeed库来部署LLM; ================================================ FILE: docs/llm-inference/vllm.md ================================================ - VLLM推理流程梳理(一): https://zhuanlan.zhihu.com/p/649974825 - VLLM推理流程梳理(二): https://zhuanlan.zhihu.com/p/649977422 - 大模型推理服务框架vLLM要点简析 (上): https://zhuanlan.zhihu.com/p/654259045 - PagedAttention--大模型推理服务框架vLLM要点简析 (中): https://zhuanlan.zhihu.com/p/655561941 vLLM是一个大模型推理服务框架,声称 最牛的serving 吞吐量PagedAttention 对kv cache的有效管理 传入请求的continus batching,而不是static batching 高性能CUDA kernel 流行的HuggingFace模型无缝集成 有各种decoder算法的高吞吐量服务,包括parallel sampling和beam search等 tensor parallel 兼容OpenAI的API服务 continus batching和PagedAttention ### PagedAttention ### continus batching ================================================ FILE: docs/llm-peft/LoRA-FA.md ================================================ 低秩适应方法(LoRA)可以在很大程度上减少训练参数数量,以微调大型语言模型(LLM),然而,仍需要昂贵的激活记忆更新低秩权重。减少LoRA层数或使用激活重计算可能会损害微调性能或增加计算开销。 在本文中,我们提出了LoRA-FA,一种高效的微调方法,可以减少激活记忆的需求,而无需性能下降和昂贵的重计算。LoRA-FA选择冻结A的投影下权重和更新B的投影上权重在每个LoRA层中。 它确保在LLM微调期间,模型权重的变化存在于低秩空间中,同时消除存储全秩输入激活的要求。我们跨越多个模型类型(RoBERTa、T5、LLaMA)和模型大小进行广泛的实验。 我们的结果显示,LoRA-FA可以在不同任务中比全参数微调和LoRA更准确地微调,同时LoRA-FA相对于LoRA可以减少总体内存成本高达1.4×。 ---- 本文提出了一种名为LoRA-FA的内存高效的细调方法,通过冻结A的投影下权重并仅更新B的投影上权重,将模型权重的变化限制在低秩空间中,从而减少了激活内存的需求。 方法的详细步骤: (1). 设计LoRA-FA方法:LoRA-FA方法通过冻结A的投影下权重并仅更新B的投影上权重,将模型权重的变化限制在低秩空间中,从而减少了激活内存的需求。 (2). LoRA-FA的集成:LoRA-FA可以与其他内存优化技术相结合,提高其利用率。 (3). LoRA-FA与梯度压缩的关系:LoRA方法通过更新A和B两个低秩矩阵,并使用AB作为预训练和冻结权重W的变化,即W + α∆W = W + αAB。 LoRA-FA方法冻结了W和A,并仅在细调过程中更新B。在模型适应过程中,权重的变化将被限制在低秩空间中。 (4). 低秩模型适应:在细调过程中,冻结初始化的A和预训练的W,并更新投影上权重B。 因此,权重的变化将限制在由A的列空间定义的低秩空间中。 (5). 内存复杂度:对LoRA-FA的内存复杂度进行详细研究。LoRA-FA模块仅计算B的梯度,其具有d_out × r个元素。在GPT类型的模型中,总的可训练参数是n_r/2,即LoRA中可训练参数数量的一半。因此,在16位混合精度训练中,模型权重和适配器相关状态的内存成本为2n + 8n_r字节。相比于全参数细调,LoRA-FA通过显著减少可训练参数和输入激活的数量,具有内存效率。LoRA-FA可以与先进的内存优化方法相结合,如权重量化、权重分片和选择性激活重计算。 (6). 权重量化:LoRA-FA可以将模型权重量化为较低的位宽,以减少模型权重的内存开销,而不影响细调性能。 (7). 权重分片:在使用数据并行ism的多个GPU上训练LLM时,可以将权重分片或使用ZeRO stage-3技术与LoRA-FA相结合,将模型权重分片到不同的GPU上,从而降低每个GPU的内存开销。 (8). 选择性激活重计算:可以使用选择性激活重计算来重新计算部分模型组件的输入,以减少激活内存开销。通过选择性激活重计算,可以在不需要存储LoRA层输入的情况下平衡激活成本和重计算成本。 ================================================ FILE: docs/llm-peft/MAM_Adapter.md ================================================ # ----- MAM adapter ----- attn_mode="prefix" attn_option="concat" attn_composition="add" attn_bn=30 # attn bottleneck dim ffn_mode="adapter" ffn_option="parallel" ffn_adapter_layernorm_option="none" ffn_adapter_init_option="lora" # 权重的初始化方式 ffn_adapter_scalar="4" ffn_bn=512 # ffn bottleneck dim 参数详细说明: https://github.com/jxhe/unify-parameter-efficient-tuning/blob/25b44ac0e6f70e116af15cb866faa9ddc13b6c77/petl/options.py#L45 ffm_mode 逻辑: https://github.com/jxhe/unify-parameter-efficient-tuning/blob/3222ce2c0079566a28043e22380eb4ab6ad14389/src/transformers/models/bart/modeling_bart.py#L401 ffn_adapter_init_option 初始化逻辑: https://github.com/jxhe/unify-parameter-efficient-tuning/blob/3222ce2c0079566a28043e22380eb4ab6ad14389/petl/petl_factory.py#L427 启动脚本: https://github.com/jxhe/unify-parameter-efficient-tuning/blob/3222ce2c0079566a28043e22380eb4ab6ad14389/exps/run_xsum.sh ================================================ FILE: docs/llm-peft/README.md ================================================ - https://github.com/OpenAccess-AI-Collective/axolotl - ================================================ FILE: docs/llm-peft/ReLoRA.md ================================================ ================================================ FILE: docs/llm-summarize/README.md ================================================ ## LLM选择标准 在选本地化的LLM之前,我们先根据实际情况定义一些选择标准: - 归纳优先:我们不需要LLM在各个方面都很优秀,不需要它们会很强的coding和复杂逻辑推理能力,RAG最重要的还是出色的归纳能力; - 体量考虑:不要太大,最好在13B及以下,因为再大就需要一张A100等专业显卡,或者要多张消费级显卡。我们的目标是一张RTX 4090可以解决问题,对很多客户来说,A卡很难买,而且价格太高了; - 中文能力:我们主要面对的还是中文业务,所以Llama对我们还是成本太高,如果自己做大量训练的话。 ## 实践经验 ### 坑点 - 使用 Hugingface Transformers 进行多机多卡训练时,反复加载模型,设置卡等,不然可能导致代码错乱,比如:保存模型不成功,保存模型不完整等等。 - 使用Megatron-Deepspeed、Hugingface Transformers (Deepspeed)进行分布式训练时,使用一些共享存储可能会遇到问题,比如一个进程写入文件之后,另一个进程无法马上读取到文件。 ================================================ FILE: docs/llm-summarize/distribution_dl_roadmap.md ================================================ 分布式并行技术: - 数据并行 - 流水线并行 - 张量并行 - 序列并行 - 多维混合并行 - 自动并行 - MOE 并行 大模型算法结构: - Transformer - GPT2 (345M) - Bloom - LLaMA / LLaMA2 - ChatGLM - ChatGLM2 分布式训练框架: - DeepSpeed - Megatron-LM - Alpa ================================================ FILE: docs/llm-summarize/大模型实践总结-20230930.md ================================================ 随着ChatGPT的迅速出圈,加速了大模型时代的变革。对于以Transformer、MOE结构为代表的大模型来说,传统的单机单卡训练模式肯定不能满足上千(万)亿级参数的模型训练,这时候我们就需要解决内存墙、通信墙、性能墙、调优墙等一系列问题,在单机多卡或者多机多卡进行模型训练。 最近,我也在探索大模型相关的一些技术,下面做一个简单的总结,后续争取每一个季度更新一次,目前最新更新为2023.07.03,本文主要涉及**AI集群、AI集群通信、大模型训练、大模型推理加速、大模型评估、大模型应用开发、AI编译器、大模型生态相关技术等**相关内容,同时,也对之前写过的一些大模型相关的文章进行了汇总,文档及配套代码均整理并放置在GitHub: [llm-action](https://github.com/liguodongiot/llm-action),篇幅太长,建议先收藏后再阅读。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/268e01d5834644f5bc503c665a876eb6~tplv-k3u1fbpfcp-watermark.image?) 另外,我创建了大模型学习交流群,供大家一起学习交流大模型相关的最新技术,目前已有5个群,可加我微信进群(加微信请备注来意,如:进大模型学习交流群+知乎)。一定要备注哟,否则不予通过。【点击】[加入大模型技术交流群](https://mp.weixin.qq.com/s?__biz=MzU3Mzg5ODgxMg==&mid=2247485828&idx=1&sn=7355c99bc907b972773f795cea9326c8&chksm=fd3be0d7ca4c69c10d842b0150a754178f9bd7691ec1e8a64c7a441822ca45833e718a9008bd&scene=21#wechat_redirect)。 ## AI基础设施 ### AI 集群-新增(2023.10.18) 作为大模型训练和推理的基础设施,AI 集群无疑是最重要的部分之一。国内头部大模型公司目前都是上千卡规模,而对于大模型不需要进行大规模预训练的中型公司,通常也有上百卡规模,用于满足线上或线下的模型训练和推理需求。 因此,做大模型时,需要找准自己的定位,当前的AI硬件资源、AI人力资源等。 如果做预训练,训练上百亿级规模大模型至少准备上百张高端AI显卡,具体可参考目前业界知名大模型模型预训练所耗的显卡和显存。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6c9ac7dc96bf4ec188e7e2c7bc49f28b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=706&h=380&s=60959&e=png&a=1&b=d3c2eb) 如果做模型全量训练,通常情况下显存的消耗除了模型权重本身,前向传播的激活值,反向传播的梯度,同时,还有优化器状态等等。根据ZeRO论文中所述需要16x模型参数量Byte。 对于一个 7.5B 的模型显存占用高达 120GB。如果显卡不够,考虑采用LoRA、Prefix Tuning等高效微调方法。 如果是模型推理,对于显存的消耗大约为1.2倍模型权重大小。 ### AI处理器(加速卡)-新增(2023.06.30) 目前,主流的AI处理器无疑是NVIDIA的GPU,并且,英伟达针对不同的场景推出了不同的系列和型号。例如:L4用于AI视频,L40用于图像生成,H100系列则是大模型,GH200是图形推荐模型、矢量数据库和图神经网络。目前NVIDIA的GPU产品主要有GeForce、Tesla和Quadro三大系列,虽然,从硬件角度来看,它们都采用同样的架构设计,也都支持用作通用计算(GPGPU),但因为它们分别面向的目标市场以及产品定位的不同,这三个系列的GPU在软硬件的设计和支持上都存在许多差异。其中,GeForce为消费级显卡,而Tesla和Quadro归类为专业级显卡。GeForce主要应用于游戏娱乐领域,而Quadro主要用于专业可视化设计和创作,Tesla更偏重于深度学习、人工智能和高性能计算。 * Tesla:A100(A800)、H100(H800)、A30、A40、V100、P100... * GeForce:RTX 3090、RTX 4090 ... * Quadro:RTX 6000、RTX 8000 ... 其中,A800/H800是针对中国特供版(低配版),相对于A100/H100,主要区别: * A100的Nvlink最大总网络带宽为600GB/s,而A800的Nvlink最大总网络带宽为400GB/s。 * H100的Nvlink最大总网络带宽为900GB/s,而A800的Nvlink最大总网络带宽为400GB/s。 **其他的一些国外AI处理器**(加速卡): * AMD:GPU MI300X * Intel:Xeon Phi、GPU、GNA * Google:TPU(Tensor Processing Unit) **国产AI处理器**(加速卡): * 华为昇腾NPU:昇腾910(用于训练和推理),昇腾310(用于推理)。采用自家设计的达芬奇架构。 * 海光DCU:8100系列(深算一号),以GPGPU架构为基础。 * 寒武纪:思元370、思元590。 * 百度-昆仑芯:采用的是其自研XPU架构。 * 阿里-平头哥:含光800。 * 壁仞:BR100系列通用GPU芯片(壁砺™100P产品形态为OAM模组、壁砺™104系列产品形态为PCIe板卡)。 * 燧原科技:云燧T1x/T2x训练系列、云燧i1x/i2x推理系列。采用其自研的 `GCU-CARA`架构。 除此之外,还有像摩尔线程、沐曦集成电路、天数智芯等发布的AI加速卡。随着美国对国内高端芯片的进一步封锁,希望国产芯片早日雄起。 ### AI 集群网络通信-新增(2023.06.30) #### 通信硬件 机器内通信: * 共享内存,比如:CPU与CPU之间的通信可以通过共享内存。 * PCIe,通常是CPU与GPU之间的通信,也可以用于GPU与GPU之间的通信。 * NVLink(直连模式),通常是GPU与GPU之间的通信,也可以用于CPU与GPU之间的通信。 机器间通信: * TCP/IP网络 * RDMA:远程直接内存访问,目前主要有如下三种技术: * InfiniBand * iWarp * RoCE v2 #### 通信软件 下面是一些常见的网络通信库: * Gloo: Facebook 开源的一套集体通信库,提供了对机器学习中有用的一些集合通信算法。 * NCCL:英伟达基于 NVIDIA-GPU 的一套开源的集合通信库。 * OpenMPI:一个开源 MPI(消息传递接口 )的实现,由学术,研究和行业合作伙伴联盟开发和维护。 * HCCL:华为开发的网络通信库。 #### 通信网络监控 * [nvbandwidth](https://github.com/NVIDIA/nvbandwidth):用于测量 NVIDIA GPU 带宽的工具。 * [DCGM](https://github.com/NVIDIA/DCGM):一个用于收集telemetry数据和测量 NVIDIA GPU 运行状况。 ## 大模型算法 **模型结构**: 目前主流的大模型都是Transformer、MOE结构为基础进行构建,如果说Transformer结构使得模型突破到上亿参数量,MoE 稀疏混合专家结构使模型参数量产生进一步突破,达到数万亿规模。 **大模型算法**: 下图详细展示了AI大模型的发展历程: ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/376fd2d6da6140288843ca5c528226d4~tplv-k3u1fbpfcp-watermark.image?) 可以说,Transformer 开创了继 MLP 、CNN和 RNN之后的第四大类模型。而基于Transformer结构的模型又可以分为Encoder-only、Decoder-only、Encoder-Decoder这三类。 * 仅编码器架构(Encoder-only):自编码模型(破坏一个句子,然后让模型去预测或填补),更擅长理解类的任务,例如:文本分类、实体识别、关键信息抽取等。典型代表有:Bert、RoBERTa等。 * 仅解码器架构(Decoder-only):自回归模型(将解码器自己当前步的输出加入下一步的输入,解码器融合所有已经输入的向量来输出下一个向量,所以越往后的输出考虑了更多输入),更擅长生成类的任务,例如:文本生成。典型代表有:GPT系列、LLaMA、OPT、Bloom等。 * 编码器-解码器架构(Encoder-Decoder):序列到序列模型(编码器的输出作为解码器的输入),主要用于基于条件的生成任务,例如:翻译,概要等。典型代表有:T5、BART等。 ### 大语言模型 目前业界发布的开源大语言模型已经相当多了,一些常见的通用大模型如下: * ChatGLM-6B / ChatGLM2-6B / ChatGLM3-6B:清华开源的中英双语的对话语言模型。目前已经发布第三代了,ChatGLM在官网允许的情况下可以进行商用。 * GLM-10B/130B :双语(中文和英文)双向稠密模型。 * OPT-2.7B/13B/30B/66B :Meta开源的预训练语言模型。 * LLaMA-7B/13B/30B/65B :Meta开源的基础大语言模型。 * Alpaca(LLaMA-7B):斯坦福提出的一个强大的可复现的指令跟随模型,种子任务都是英语,收集的数据也都是英文,因此训练出来的模型未对中文优化。 * BELLE(BLOOMZ-7B/LLaMA-7B/LLaMA-13B):本项目基于 [Stanford Alpaca](https://github.com/tatsu-lab/stanford_alpaca),针对中文做了优化,模型调优仅使用由ChatGPT生产的数据(不包含任何其他数据)。 * Bloom-7B/13B/176B:可以处理46 种语言,包括法语、汉语、越南语、印度尼西亚语、加泰罗尼亚语、13 种印度语言(如印地语)和 20 种非洲语言。其中,Bloomz系列模型是基于 xP3 数据集微调。 推荐用于英语的提示(prompting);Bloomz-mt系列模型是基于 xP3mt 数据集微调。推荐用于非英语的提示(prompting)。 * Vicuna(7B/13B):由UC Berkeley、CMU、Stanford和 UC San Diego的研究人员创建的 Vicuna-13B,通过在 ShareGPT 收集的用户共享对话数据中微调 LLaMA 获得。其中,使用 GPT-4 进行评估,发现 Vicuna-13B 的性能在超过90%的情况下实现了与ChatGPT和Bard相匹敌的能力;同时,在 90% 情况下都优于 LLaMA 和 Alpaca 等其他模型。而训练 Vicuna-13B 的费用约为 300 美元。不仅如此,它还提供了一个用于训练、服务和评估基于大语言模型的聊天机器人的开放平台:[FastChat](https://github.com/lm-sys/FastChat)。 * [Baize](https://github.com/project-baize/baize-chatbot):白泽是在LLaMA上训练的。目前包括四种英语模型:白泽-7B、13B 、 30B(通用对话模型)以及一个垂直领域的白泽-医疗模型,供研究 / 非商业用途使用,并计划在未来发布中文的白泽模型。白泽的数据处理、训练模型、Demo 等全部代码已经开源。 * [LLMZoo](https://github.com/FreedomIntelligence/LLMZoo):来自香港中文大学和深圳市大数据研究院团队推出的一系列大模型,如:Phoenix(凤凰) 和 Chimera等。 * [MOSS](https://github.com/OpenLMLab/MOSS):由复旦 NLP 团队推出的 MOSS 大语言模型。 * [baichuan-7B/13B、baichuan2-7B/13B](https://github.com/baichuan-inc/baichuan-7B):由百川智能推出的大模型,可进行商用。 * [CPM-Bee](https://github.com/OpenBMB/CPM-Bee):百亿参数的开源中英文双语基座大模型,可进行商用。 * 书生·浦语(InternLM 7B/20B):来自上海人工智能实验室,开源可商用。 - Qwen-7B/14B:阿里的通义千问. ... 要保证基座模型有比较好的效果,至少需要保证上万亿级的Token量。目前来看,LLaMA无疑是其中最闪亮的星。但是国内关于LLaMA比较大的一个争论就是LLaMA是以英语为主要语言的拉丁语系上进行训练的,LLaMA词表中的中文token比较少(只有几百个),需不需要扩充词表?如果不扩充词表,中文效果会不会比较差? * 如果不扩充词表,对于中文效果怎么样?根据Vicuna官方的报告,经过Instruction Turing的Vicuna-13B已经有非常好的中文能力。 * LLaMA需不需要扩充词表?根据[Chinese-LLaMA-Alpaca](https://github.com/ymcui/Chinese-LLaMA-Alpaca)和[BELLE](https://github.com/LianjiaTech/BELLE)的报告,扩充中文词表,可以提升中文编解码效率以及模型的性能。但是扩词表,相当于从头初始化开始训练这些参数。如果想达到比较好的性能,需要比较大的算力和数据量。同时,Chinese-LLaMA-Alpaca也指出在进行第一阶段预训练(冻结transformer参数,仅训练embedding,在尽量不干扰原模型的情况下适配新增的中文词向量)时,模型收敛速度较慢。如果不是有特别充裕的时间和计算资源,建议跳过该阶段。因此,虽然扩词表看起来很诱人,但是实际操作起来,还是很有难度的。 下面是BELLE针对是否扩充词表,数据质量、数据语言分布、数据规模对于模型性能的对比: ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cd50114de9aa48b2b6404531d477bf6b~tplv-k3u1fbpfcp-watermark.image?) 其中,**BELLE-0.5M-CLEAN**是从230万指令数据中清洗得到0.5M数据(包含单轮和多轮对话数据)。LLaMA-7B-EXT是针对LLaMA做了中文词表扩充的预训练模型。 下面是Chinese-LLaMA-Alpaca针对中文Alpaca-13B、中文Alpaca-Plus-7B、中文Alpaca-Plus-13B的效果对比: ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/61f342d4f77a4486a9fd94aaaef677c8~tplv-k3u1fbpfcp-watermark.image?) 其中,Plus系列Alpaca是在原版LLaMA的基础上扩充了中文词表,使用了120G中文通用纯文本数据进行二次预训练。 因此,如果既想要中文词表,又没有很大的算力,那建议直接使用使用BELLE和Chinese-LLaMA-Alpaca进行中文词表扩充后训练好的模型作为Base模型,或者使用像ChatGLM、baichuan、qwen等直接基于中英双语训练的大模型。 ### 多模态大模型 **目前业界可以下载到的一些多模态大模型**: * [MiniGPT-4](https://github.com/Vision-CAIR/MiniGPT-4):沙特阿拉伯阿卜杜拉国王科技大学的研究团队开源。 * [LLaVA](https://github.com/haotian-liu/LLaVA):由威斯康星大学麦迪逊分校,微软研究院和哥伦比亚大学共同出品。 * [VisualGLM-6B](https://github.com/THUDM/VisualGLM-6B/):开源的,支持**图像、中文和英文**的多模态对话语言模型,语言模型基于 [ChatGLM-6B](https://github.com/THUDM/ChatGLM-6B),具有 62 亿参数;图像部分通过训练 [BLIP2-Qformer](https://arxiv.org/abs/2301.12597) 构建起视觉模型与语言模型的桥梁,整体模型共78亿参数。 * [VisCPM](https://github.com/OpenBMB/VisCPM):于CPM基础模型的中英双语多模态大模型。 ### 领域大模型-新增(2023.06.30) #### 金融领域大模型 * [轩辕](https://github.com/Duxiaoman-DI/XuanYuan):在BLOOM-176B的基础上针对中文通用领域和金融领域进行了针对性的预训练与微调。 #### 法律领域大模型 * [ChatLaw](https://github.com/PKU-YuanGroup/ChatLaw):由北京大学开源的大模型,主要有13B、33B。 * [LexiLaw](https://github.com/CSHaitao/LexiLaw):LexiLaw 是一个经过微调的中文法律大模型,它基于 ChatGLM-6B 架构,通过在法律领域的数据集上进行微调,使其在提供法律咨询和支持方面具备更高的性能和专业性。 ## 大模型训练 ### 分布式并行及显存优化技术 **并行技术**: * 数据并行(如:PyTorch DDP) * 张量并行(如:Megatron-LM(1D)、Colossal-AI(2D、2.5D、3D)) * 流水线并行(如:GPipe、PipeDream、PipeDream-2BW、PipeDream Flush(1F1B)) * 多维混合并行(如:3D并行(数据并行、模型并行、流水线并行)) * 自动并行(如:Alpa(自动算子内/算子间并行)) * 优化器相关的并行(如:ZeRO(**零冗余优化器**,在执行的逻辑上是数据并行,但可以达到模型并行的显存优化效果)、PyTorch FSDP) - MOE并行 - 序列并行 具体可查看我写的分布式并行技术文章:https://github.com/liguodongiot/llm-action/tree/main#llm%E5%88%86%E5%B8%83%E5%BC%8F%E8%AE%AD%E7%BB%83%E5%B9%B6%E8%A1%8C%E6%8A%80%E6%9C%AF **显存优化技术**: * 重计算(Recomputation):Activation checkpointing(Gradient checkpointing),本质上是一种用时间换空间的策略。 * 卸载(Offload)技术:一种用通信换显存的方法,简单来说就是让模型参数、激活值等在CPU内存和GPU显存之间左右横跳。如:ZeRO-Offload、ZeRO-Infinity等。 * 混合精度(BF16/FP16):降低训练显存的消耗,还能将训练速度提升2-4倍。 * BF16 计算时可避免计算溢出,出现Inf case。 * FP16 在输入数据超过65506 时,计算结果溢出,出现Inf case。 ### 分布式训练框架 **如何选择一款分布式训练框架**? * **训练成本**:不同的训练工具,训练同样的大模型,成本是不一样的。对于大模型,训练一次动辄上百万/千万美元的费用。合适的成本始终是正确的选择。 * **训练类型**:是否支持数据并行、张量并行、流水线并行、多维混合并行、自动并行等 * **效率**:将普通模型训练代码变为分布式训练所需编写代码的行数,我们希望越少越好。 * **灵活性**:你选择的框架是否可以跨不同平台使用? **常见的分布式训练框架**: * 第一类:深度学习框架自带的分布式训练功能。如:TensorFlow、PyTorch、MindSpore、Oneflow、PaddlePaddle等。 * 第二类:基于现有的深度学习框架(如:PyTorch、Flax)进行扩展和优化,从而进行分布式训练。如:Megatron-LM(张量并行)、DeepSpeed(Zero-DP)、Colossal-AI(高维模型并行,如2D、2.5D、3D)、Alpa(自动并行)等 **目前训练超大规模语言模型主要有两条技术路线**: 1. TPU + XLA + TensorFlow/JAX :由Google主导,由于TPU和自家云平台GCP深度绑定。 2. GPU + PyTorch + Megatron-LM + DeepSpeed :由NVIDIA、Meta、MicroSoft大厂加持,社区氛围活跃,也更受到大家欢迎。 对于国内来说,华为昇腾在打造 AI 全栈软硬件平台(昇腾NPU+CANN+MindSpore+MindFormers)。不过目前整个生态相对前两者,还差很远。 ### 参数高效微调(PEFT)技术 在面对特定的下游任务时,如果进行Full FineTuning(即对预训练模型中的所有参数都进行微调),太过低效;而如果采用固定预训练模型的某些层,只微调接近下游任务的那几层参数,又难以达到较好的效果。 PEFT技术旨在**通过最小化微调参数的数量和计算复杂度,来提高预训练模型在新任务上的性能,从而缓解大型预训练模型的训练成本**。这样一来,即使计算资源受限,也可以利用预训练模型的知识来迅速适应新任务,实现高效的迁移学习。因此,PEFT技术可以在提高模型效果的同时,大大缩短模型训练时间和计算成本,让更多人能够参与到深度学习研究中来。除此之外,FEFT可以缓解全量微调带来灾难性遗忘的问题。 * **Prefix Tuning**:与full fine-tuning更新所有参数的方式不同,该方法是在输入token之前构造一段任务相关的virtual tokens作为Prefix,然后训练的时候只更新Prefix部分的参数,而Transformer中的其他部分参数固定。该方法其实和构造Prompt类似,只是Prompt是人为构造的“显式”的提示,并且无法更新参数,而Prefix则是可以学习的“隐式”的提示。 同时,为了防止直接更新Prefix的参数导致训练不稳定的情况,他们在Prefix层前面加了MLP结构(相当于将Prefix分解为更小维度的Input与MLP的组合后输出的结果),训练完成后,只保留Prefix的参数。 * **Prompt Tuning**:该方法可以看作是Prefix Tuning的简化版本,只在输入层加入prompt tokens,并不需要加入MLP进行调整来解决难训练的问题。随着预训练模型参数量的增加,Prompt Tuning的方法会逼近fine-tuning的结果。 * **P-Tuning**:该方法的提出主要是为了解决这样一个问题:大模型的Prompt构造方式严重影响下游任务的效果。P-Tuning将Prompt转换为可以学习的Embedding层,并用MLP+LSTM的方式来对prompt embedding进行一层处理。 * **P-Tuning v2**:让Prompt Tuning能够在不同参数规模的预训练模型、针对不同下游任务的结果上都达到匹敌Fine-tuning的结果。相比Prompt Tuning和P-tuning的方法,P-Tuning v2方法在多层加入了Prompts tokens作为输入,带来两个方面的好处: 1. 带来更多可学习的参数(从P-tuning和Prompt Tuning的0.1%增加到0.1%-3%),同时也足够参数高效。 2. 加入到更深层结构中的Prompt能给模型预测带来更直接的影响。 * **Adapter Tuning**:该方法设计了Adapter结构(首先是一个down-project层将高维度特征映射到低维特征,然后过一个非线形层之后,再用一个up-project结构将低维特征映射回原来的高维特征;同时也设计了skip-connection结构,确保了在最差的情况下能够退化为identity),并将其嵌入Transformer的结构里面,在训练时,固定住原来预训练模型的参数不变,只对新增的Adapter结构进行微调。同时为了保证训练的高效性(也就是尽可能少的引入更多参数)。 * **LoRA**:在涉及到矩阵相乘的模块,引入A、B这样两个低秩矩阵模块去模拟full fine-tuning的过程,相当于只对语言模型中起关键作用的低秩本质维度进行更新。 * QLoRA:使用一种新颖的高精度技术将预训练模型量化为 4 bit,然后添加一小组可学习的低秩适配器权重,这些权重通过量化权重的反向传播梯度进行微调。目前,训练速度较慢。 * **AdaLoRA**:对LoRA的一种改进,它根据重要性评分动态分配参数预算给权重矩阵。 ... **具体可查看我写的大模型微调技术文章:https://github.com/liguodongiot/llm-action#llm%E5%BE%AE%E8%B0%83%E6%8A%80%E6%9C%AF%E5%8E%9F%E7%90%86** **典型应用**: 1. [ChatGLM-Tuning](https://github.com/mymusise/ChatGLM-Tuning) :一种平价的chatgpt实现方案,基于清华的 [ChatGLM-6B](https://github.com/THUDM/ChatGLM-6B) + LoRA 进行finetune。 2. [Alpaca-Lora](https://github.com/tloen/alpaca-lora):使用低秩自适应(LoRA)复现斯坦福羊驼的结果。Stanford Alpaca 是在 LLaMA 整个模型上微调,而 Alpaca-Lora 则是利用 Lora 技术,在冻结原模型 LLaMA 参数的情况下,通过往模型中加入额外的网络层,并只训练这些新增的网络层参数。由于这些新增参数数量较少,这样不仅微调的成本显著下降,还能获得和全模型微调类似的效果。 3. [BLOOM-LORA](https://github.com/linhduongtuan/BLOOM-LORA):由于LLaMA的限制,我们尝试使用Alpaca-Lora重新实现BLOOM-LoRA。 **PEFT实现**: 1. [PEFT](https://github.com/huggingface/peft):Huggingface推出的PEFT库。 2. [unify-parameter-efficient-tuning](https://github.com/jxhe/unify-parameter-efficient-tuning):一个参数高效迁移学习的统一框架。 **高效微调技术优缺点**: 相比全参数微调,大部分的高效微调技术可以显著降低对于显存的需求,同时,可以减轻灾难性遗忘。 但是大部分的高效微调技术目前存在的两个问题: 1. 推理速度会变慢 2. 模型精度会变差 ### RLHF(人工反馈强化学习)-新增(2023.07.03) 根据 OpenAI 之前做的一些实验,可以看到使用了 PPO(近端策略优化)算法的 RLHF 模型整体上都更好一些。当把结果提供给人类时,相比于 SFT 模型和通过 prompt 化身为助理的基础模型,人类也基本更喜欢来自 RLHF 模型的 token。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9c370e65027b403798ddf46bc8d83d6d~tplv-k3u1fbpfcp-watermark.image?) 那 RLHF 为什么能让模型更好呢?目前 AI 研究界还没有找到一个得到大家认可的理论,一种可能**与比较和生成的计算难度之间的不对称性有关**。 举个例子说明一下:假设我们要让一个模型写一首关于回形针的俳句。如果你是一位正努力创建训练数据的合同工,正在为 SFT 模型收集数据。那么你该怎样写出一首关于回形针的好俳句呢?而你可能并不是一位优秀的俳句诗人。但是,如果给你几首俳句,你却有能力辨别它们中哪首更好一些。也就是说,比起创建一个好样本,判断哪个样本更好是简单得多的任务。因此,这种不对称性可能使得比较是一种更好的方法,能更好地利用人类的判断来创造出好一些的模型。 但目前来看,RLHF 并不总是会为基石模型带来提升。在某些情况下,RLHF 模型会失去一些熵,也就是说它们会输出更加单调、变化更少的结果。而基础模型的熵更高,可以输出更加多样化的结果。 #### RLHF开源工具 下面是目前开源的一些RLHF工具: * [DeepSpeed Chat](https://github.com/microsoft/DeepSpeedExamples/tree/master/applications/DeepSpeed-Chat):基于Opt、LLaMA、Bloom系列模型进行示例。 * [ColossalChat](https://github.com/hpcaitech/ColossalAI/tree/main/applications/Chat):基于LLaMA系列模型进行示例。 ### 影响大模型性能的主要因素 OpenAI的论文**Scaling Laws for Neural Language Models**中列举了影响模型性能最大的三个因素:**计算量**、**数据集大小**、**模型参数量**。也就是说,当其他因素不成为瓶颈时,计算量、数据集大小、模型参数量这3个因素中的单个因素指数增加时,loss会线性的下降。 除了以上的因素之外,还有一个比较大的影响因素就是**数据质量**。在微软的论文**Instruction Tuning with GPT-4**中指出,同样基于LLaMA模型,使用GPT3和GPT4产生的数据,对模型进行Instruction Turing,可以看到GPT4的数据微调过的模型效果远远好于GPT3数据微调的模型,可见数据质量带来的影响。同样的,Vicuna(7B/13B)的Instruction Turing中,也对shareGPT的数据做了很细致的清洗工作。 ## 大模型评估 ### 衡量大模型水平 要评估一个大型语言模型的水平,可以从以下几个维度提出具有代表性的问题。 * **理解能力**:提出一些需要深入理解文本的问题,看模型是否能准确回答。 * **语言生成能力**:让模型生成一段有关特定主题的文章或故事,评估其生成的文本在结构、逻辑和语法等方面的质量。 * **知识面广度**:请模型回答关于不同主题的问题,以测试其对不同领域的知识掌握程度。这可以是关于科学、历史、文学、体育或其他领域的问题。一个优秀的大语言模型应该可以回答各种领域的问题,并且准确性和深度都很高。 * **适应性**:让模型处理各种不同类型的任务,例如:写作、翻译、编程等,看它是否能灵活应对。 * **长文本理解**:提出一些需要处理长文本的问题,例如:提供一篇文章,让模型总结出文章的要点,或者请模型创作一个故事或一篇文章,让其有一个完整的情节,并且不要出现明显的逻辑矛盾或故事结构上的错误。一个好的大语言模型应该能够以一个连贯的方式讲述一个故事,让读者沉浸其中。 * **长文本生成**:请模型创作一个故事或一篇文章,让其有一个完整的情节,并且不要出现明显的逻辑矛盾或故事结构上的错误。一个好的大语言模型应该能够以一个连贯的方式讲述一个故事,让读者沉浸其中。 * **多样性**:提出一个问题,让模型给出多个不同的答案或解决方案,测试模型的创造力和多样性。 * **情感分析和推断**:提供一段对话或文本,让模型分析其中的情感和态度,或者推断角色间的关系。 * **情感表达**:请模型生成带有情感色彩的文本,如描述某个场景或事件的情感、描述一个人物的情感状态等。一个优秀的大语言模型应该能够准确地捕捉情感,将其表达出来。 * **逻辑推理能力**:请模型回答需要进行推理或逻辑分析的问题,如概率或逻辑推理等。这可以帮助判断模型对推理和逻辑思考的能力,以及其在处理逻辑问题方面的准确性。例如:“所有的动物都会呼吸。狗是一种动物。那么狗会呼吸吗?” * **问题解决能力**:提出实际问题,例如:数学题、编程问题等,看模型是否能给出正确的解答。 * **道德和伦理**:测试模型在处理有关道德和伦理问题时的表现,例如:“在什么情况下撒谎是可以接受的?” * **对话和聊天**:请模型进行对话,以测试其对自然语言处理的掌握程度和能力。一个优秀的大语言模型应该能够准确地回答问题,并且能够理解人类的语言表达方式。 ### **LLM评估面临的挑战** - 无法获取模型的训练数据分布信息 - 生成式输出难以进行定量评估 - 通用模型不同领域的表现参差不齐 - 单一指标难以概括模型的多样能力 ### **大模型评估方法** **人工评估**:LIMA、Phoenix **使用 GPT-4 的反馈进行自动评估**:Vicuna、Phoenix、Chimera、BELLE **指标评估**(BLEU-4、ROUGE分数):ChatGLM-6B;对于像ROUGE-L分数的指标评估,有些地方称其为非自然指令评估(Unnatural Instruction Evaluation)。 **多指标评估框架**:如:HELM 、lm-evaluation-harness、CLEVA等工具。 **Chatbot Arena**:目前用来衡量一个模型好不好的东西基本都是基于一些学术的benchmark,比如在一个某个NLP任务上构建一个测试数据集,然后看测试数据集上准确率多少。然而,这些学术benchmark(如HELM)在大模型和聊天机器人上就不好用了。其原因在于: * 由于评判聊天机器人聊得好不好这件事是非常主观的,因此,现有的方法很难对其进行衡量。 * 这些大模型在训练的时候就几乎把整个互联网的数据都扫了一个遍,因此,很难保证测试用的数据集没有被看到过。甚至更进一步,用测试集直接对模型进行「特训」,如此一来表现必然更好。 * 理论上我们可以和聊天机器人聊任何事情,但很多话题或者任务在现存的benchmark里面根本就不存在。 因此,Chatbot Arena 的做法是放弃benchmark,通过对抗,实时聊天,两两比对人工进行打分,采用elo分数进行评测。 **大模型评估工具**: * [OpenAI evals](https://github.com/openai/evals):OpenAI的自动化评估脚本,核心思路就是通过写prompt模版来自动化评估。 * [PandaLM](https://github.com/WeOpenML/PandaLM):其是直接训练了一个自动化打分模型,0,1,2三分制用模型对两个候选模型进行打分。 **如何构建评估数据集** - 采用渐进方式构建,从一开始就收集各类样本 - 利用语言模型自动生成更多测试用例 - 持续从用户反馈中获取新样本,发现瑕疵 - 考虑提高测试覆盖率,覆盖真实用例范围 ## 大模型推理 ### 大模型推理加速 模型推理作为模型投产的最后一公里,需要确保模型精度的同时追求极致的推理性能。相比传统模型来说,大模型面临着更多的挑战。 当前优化模型最主要技术手段概括来说有以下三个层面: * 算法层面:蒸馏、量化 * 软件层面:计算图优化、模型编译 * 硬件层面:FP8(NVIDIA H系列GPU开始支持FP8,兼有fp16的稳定性和int8的速度) **推理加速框架**: * **FasterTransformer**:英伟达推出的FasterTransformer不修改模型架构而是在计算加速层面优化 Transformer 的 encoder 和 decoder 模块。具体包括如下: * 尽可能多地融合除了 GEMM 以外的操作 * 支持 FP16、INT8、FP8 * 移除 encoder 输入中无用的 padding 来减少计算开销 * **TurboTransformers**:腾讯推出的 TurboTransformers 由 computation runtime 及 serving framework 组成。加速推理框架适用于 CPU 和 GPU,最重要的是,它可以无需预处理便可处理变长的输入序列。具体包括如下: * 与 FasterTransformer 类似,它融合了除 GEMM 之外的操作以减少计算量 * smart batching,对于一个 batch 内不同长度的序列,它也最小化了 zero-padding 开销 * 对 LayerNorm 和 Softmax 进行批处理,使它们更适合并行计算 * 引入了模型感知分配器,以确保在可变长度请求服务期间内存占用较小 ## 大模型压缩(2023.10.24) ### 大模型量化 根据应用量化压缩模型的阶段,可以将大模型量化分为:量化感知训练、量化感知微调、训练后量化。 目前业界一些量化方案如下: 训练后量化: - SmoothQuant - ZeroQuant - GPTQ - LLM.int8() - ... 量化感知训练: - [大模型量化感知训练开山之作:LLM-QAT](https://zhuanlan.zhihu.com/p/647589650) 量化感知微调: - QLoRA - PEQA ### 大模型蒸馏 大模型蒸馏就是利用LLM作为教师的蒸馏方法。根据这些方法是否将LLM的涌现能力(EA)提炼成小语言模型(SLM)来对这些方法进行分类。 因此,我们将这些方法分为两个不同的类别:标准 KD 和基于 EA 的 KD。 目前业界一些蒸馏方案如下: **Standard KD**: 使学生模型学习教师模型(LLM)所拥有的常见知识,如输出分布和特征信息,这种方法类似于传统的KD。 - MINILLM - GKD **EA-based KD**: 不仅仅是将LLM的常见知识转移到学生模型中,还涵盖了蒸馏它们独特的涌现能力。具体来说,EA-based KD又分为了上下文学习(ICL)、思维链(CoT)和指令跟随(IF)。 In-Context Learning: - In-Context Learning distillation Chain-of-Thought: - MT-COT - Fine-tune-CoT - DISCO - SCOTT - SOCRATIC CoT Instruction Following: - Lion ## 大模型生态相关技术-新增(2023.06.30) 大模型是基座,要想让其变成一款产品,我们还需要一些其他相关技术: ### LLM 应用开发工具 * langchain:一个用于构建基于大型语言模型(LLM)的应用程序的库。它可以帮助开发者将LLM 与其他计算或知识源结合起来,创建更强大的应用程序。 * llama-index:一个将大语言模型和外部数据连接在一起的工具。 * gpt-cache:LLM 语义缓存层(caching layer),它采用语义缓存(semantic cache)技术,能够存储 LLM 响应,从而显著减少检索数据所需的时间、降低 API 调用开销、提升应用可扩展性。 ### 向量数据库 * Pinecone * Milvus * Vespa * Weaviate 总的来说,如果想快速验证,Pinecone 是个不错的选择。如果想拥有更灵活的查询方式,可以考虑 Vespa 或 Weaviate.如果需要更好的可扩展性和可靠性,那么经过大客户验证的 Vespa 或 Milvus 可能是不错的选择。 ## 经验与教训 **经验**: * 对于同一模型,选择不同的训练框架,对于资源的消耗情况可能存在显著差异(比如使用Huggingface Transformers和DeepSpeed训练OPT-30相对于使用Alpa对于资源的消耗会低不少)。 * 进行大模型模型训练时,先使用小规模模型(如:OPT-125m/2.7b)进行尝试,然后再进行大规模模型(如:OPT-13b/30b...)的尝试,便于出现问题时进行排查。目前来看,业界也是基于相对较小规模参数的模型(6B/7B/13B)进行的优化,同时,13B模型经过指令精调之后的模型效果已经能够到达GPT4的90%的效果。 * 对于一些国产AI加速卡,目前来说,坑还比较多,如果时间不是时间非常充裕,还是尽量选择Nvidia的AI加速卡。 * 目前业界的很多大模型训练后量化方法都只是降低了显存的消耗,对于大模型推理速度不仅没有提升反而会下降。目前来说,比较好的方法有SmoothQuant、AWQ。 **教训**: * 针对已有的环境进行分布式训练环境搭建时,一定要注意之前环境的python、pip、virtualenv、setuptools的版本。不然创建的虚拟环境即使指定对了Python版本,也可能会遇到很多安装依赖库的问题(GPU服务器能够访问外网的情况下,建议使用Docker相对来说更方便)。 * 遇到需要升级GLIBC等底层库需要升级的提示时,一定要慎重,不要轻易升级,否则,可能会造成系统宕机或很多命令无法操作等情况。 ## 结语 实践出真知,以上是这段时间进行大模型实践的一点点总结,写的有一些主观和片面,后续会持续更新自己研究大模型获得的一些认知和实践经验,希望能够帮助大家,欢迎点赞收藏加关注。 ================================================ FILE: docs/llm-summarize/大模型实践总结.md ================================================ 随着ChatGPT的迅速出圈,加速了大模型时代的变革。对于以Transformer、MOE结构为代表的大模型来说,传统的单机单卡训练模式肯定不能满足上千(万)亿级参数的模型训练,这时候我们就需要解决内存墙和通信墙等一系列问题,在单机多卡或者多机多卡进行模型训练。 最近,我也在探索大模型相关的一些技术,下面做一个简单的总结,后续争取每一个季度更新一次,目前最新更新为2023.07.03,本文主要涉及**AI集群、AI集群通信、大模型训练(参数高效微调)、大模型推理加速、大模型评估、大模型生态相关技术等**相关内容,同时,也对之前写过的一些大模型相关的文章进行了汇总,文档及配套代码均整理并放置在GitHub: [llm-action](https://github.com/liguodongiot/llm-action),篇幅太长,建议先收藏后再阅读。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/268e01d5834644f5bc503c665a876eb6~tplv-k3u1fbpfcp-watermark.image?) ## AI 集群 由于目前只有3台A800 GPU服务器(共24卡),基于目前现有的一些AI框架和大模型,无法充分利用3台服务器。比如:OPT-66B一共有64层Transformer,当使用Alpa进行流水线并行时,通过流水线并行对模型进行切分,要么使用16卡,要么使用8卡,没法直接使用24卡,因此,GPU服务器最好是购买偶数台(如:2台、4台、8台)。 具体的硬件配置如下: * **CPUs:**  每个节点具有 1TB 内存的 Intel CPU,物理CPU个数为64,每颗CPU核数为16。 * **GPUs:**  24 卡 A800 80GB GPUs ,每个节点 8 个 GPU(3 个节点)。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0d8c7175b5f54fa0aa559e71f5f4bcc5~tplv-k3u1fbpfcp-watermark.image?) 目前使用Huggingface Transformers和DeepSpeed进行通过数据并行进行训练(pretrain),单卡可以跑三百亿参数(启用ZeRO-2或ZeRO-3),如OPT-30B,具体训练教程参考官方[样例](https://github.com/huggingface/transformers/blob/main/examples/pytorch/language-modeling/run_clm.py)。 使用Alpa进行流水线并行和数据并行进行训练(fine tuning)时,使用了3台共24卡(PP:12,DP:2)进行训练OPT-30B,具体训练教程参考官方[样例](https://github.com/alpa-projects/alpa/tree/hao-opt/examples/opt_finetune)。但是进行模型训练之前需要先进行模型格式转换,将HF格式转换为Alpa格式的模型文件,具体请参考官方[代码](https://github.com/alpa-projects/alpa/blob/hao-opt/examples/llm_serving/textgen.py)。如果不想转换,官网也提供了转换好的模型格式,具体请参考文档:[Serving OPT-175B, BLOOM-176B and CodeGen-16B using Alpa](https://alpa.ai/tutorials/opt_serving.html#converted-weights-for-other-models)。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/17fcba866d1543ebbb41e5a296f788f2~tplv-k3u1fbpfcp-watermark.image?) **20230703**:前几天对H800进行过性能测试,整体上来说,对于模型训练(Huggingface Transformers)和模型推理(FasterTransformer)都有30%左右的速度提升。但是对于H800支持的新数据类型FP8,目前很多开源框架暂不支持,虽然,Nvidia自家一些开源框架支持该数据类型,目前不算太稳定。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ba3a4d301f404ec49eb484b1f3cb875b~tplv-k3u1fbpfcp-watermark.image?) ### AI处理器(加速卡)-新增(2023.06.30) 目前,主流的AI处理器无疑是NVIDIA的GPU,NVIDIA的GPU产品主要有GeForce、Tesla和Quadro三大系列,虽然,从硬件角度来看,它们都采用同样的架构设计,也都支持用作通用计算(GPGPU),但因为它们分别面向的目标市场以及产品定位的不同,这三个系列的GPU在软硬件的设计和支持上都存在许多差异。其中,GeForce为消费级显卡,而Tesla和Quadro归类为专业级显卡。GeForce主要应用于游戏娱乐领域,而Quadro主要用于专业可视化设计和创作,Tesla更偏重于深度学习、人工智能和高性能计算。 * Tesla:A100(A800)、H100(H800)、A30、A40、V100、P100... * GeForce:RTX 3090、RTX 4090 ... * Quadro:RTX 6000、RTX 8000 ... 其中,A800/H800是针对中国特供版(低配版),相对于A100/H100,主要区别: * A100的Nvlink最大总网络带宽为600GB/s,而A800的Nvlink最大总网络带宽为400GB/s。 * H100的Nvlink最大总网络带宽为900GB/s,而A800的Nvlink最大总网络带宽为400GB/s。 **其他的一些国外AI处理器**(加速卡): * AMD:GPU MI300X * Intel:Xeon Phi * Google:TPU **国产AI处理器**(加速卡): * 华为:昇腾910(用于训练和推理),昇腾310(用于推理)。采用自家设计的达芬奇架构。 * 海光DCU:8100系列(深算一号),以GPGPU架构为基础。 * 寒武纪:思元370、思元590。 * 百度:昆仑芯,采用的是其自研XPU架构。 * 阿里:含光800。 ## 大模型算法 **模型结构**: 目前主流的大模型都是Transformer、MOE结构为基础进行构建,如果说Transformer结构使得模型突破到上亿参数量,MoE 稀疏混合专家结构使模型参数量产生进一步突破,达到数万亿规模。 **大模型算法**: 下图详细展示了AI大模型的发展历程: ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/376fd2d6da6140288843ca5c528226d4~tplv-k3u1fbpfcp-watermark.image?) 可以说,Transformer 开创了继 MLP 、CNN和 RNN之后的第四大类模型。而基于Transformer结构的模型又可以分为Encoder-only、Decoder-only、Encoder-Decoder这三类。 * 仅编码器架构(Encoder-only):自编码模型(破坏一个句子,然后让模型去预测或填补),更擅长理解类的任务,例如:文本分类、实体识别、关键信息抽取等。典型代表有:Bert、RoBERTa等。 * 仅解码器架构(Decoder-only):自回归模型(将解码器自己当前步的输出加入下一步的输入,解码器融合所有已经输入的向量来输出下一个向量,所以越往后的输出考虑了更多输入),更擅长生成类的任务,例如:文本生成。典型代表有:GPT系列、LLaMA、OPT、Bloom等。 * 编码器-解码器架构(Encoder-Decoder):序列到序列模型(编码器的输出作为解码器的输入),主要用于基于条件的生成任务,例如:翻译,概要等。典型代表有:T5、BART、GLM等。 ### 大语言模型 **目前业界可以下载到的一些大语言模型**: * ChatGLM-6B / ChatGLM2-6B :清华开源的中英双语的对话语言模型。目前,第二代ChatGLM在官网允许的情况下可以进行商用。 * GLM-10B/130B :双语(中文和英文)双向稠密模型。 * OPT-2.7B/13B/30B/66B :Meta开源的预训练语言模型。 * LLaMA-7B/13B/30B/65B :Meta开源的基础大语言模型。 * Alpaca(LLaMA-7B):斯坦福提出的一个强大的可复现的指令跟随模型,种子任务都是英语,收集的数据也都是英文,因此训练出来的模型未对中文优化。 * BELLE(BLOOMZ-7B/LLaMA-7B/LLaMA-13B):本项目基于 [Stanford Alpaca](https://github.com/tatsu-lab/stanford_alpaca),针对中文做了优化,模型调优仅使用由ChatGPT生产的数据(不包含任何其他数据)。 * Bloom-7B/13B/176B:可以处理46 种语言,包括法语、汉语、越南语、印度尼西亚语、加泰罗尼亚语、13 种印度语言(如印地语)和 20 种非洲语言。其中,Bloomz系列模型是基于 xP3 数据集微调。 推荐用于英语的提示(prompting);Bloomz-mt系列模型是基于 xP3mt 数据集微调。推荐用于非英语的提示(prompting)。 * Vicuna(7B/13B):由UC Berkeley、CMU、Stanford和 UC San Diego的研究人员创建的 Vicuna-13B,通过在 ShareGPT 收集的用户共享对话数据中微调 LLaMA 获得。其中,使用 GPT-4 进行评估,发现 Vicuna-13B 的性能在超过90%的情况下实现了与ChatGPT和Bard相匹敌的能力;同时,在 90% 情况下都优于 LLaMA 和 Alpaca 等其他模型。而训练 Vicuna-13B 的费用约为 300 美元。不仅如此,它还提供了一个用于训练、服务和评估基于大语言模型的聊天机器人的开放平台:[FastChat](https://github.com/lm-sys/FastChat)。 * [Baize](https://github.com/project-baize/baize-chatbot):白泽是在LLaMA上训练的。目前包括四种英语模型:白泽-7B、13B 、 30B(通用对话模型)以及一个垂直领域的白泽-医疗模型,供研究 / 非商业用途使用,并计划在未来发布中文的白泽模型。白泽的数据处理、训练模型、Demo 等全部代码已经开源。 * [LLMZoo](https://github.com/FreedomIntelligence/LLMZoo):来自香港中文大学和深圳市大数据研究院团队推出的一系列大模型,如:Phoenix(凤凰) 和 Chimera等。 * [MOSS](https://github.com/OpenLMLab/MOSS):由复旦 NLP 团队推出的 MOSS 大语言模型。 * [baichuan-7B](https://github.com/baichuan-inc/baichuan-7B):由百川智能推出的大模型,可进行商用。 * [CPM-Bee](https://github.com/OpenBMB/CPM-Bee):百亿参数的开源中英文双语基座大模型,可进行商用。 ... > 20230325(当时官方还未开源训练代码,目前直接基于官方的训练代码即可): > > 前两天测试了BELLE,对中文的效果感觉还不错。具体的模型训练(预训练)方法可参考Hugingface Transformers的[样例](https://github.com/huggingface/transformers/blob/main/examples/pytorch/language-modeling/run_clm.py),SFT(指令精调)方法可参考[Alpaca的训练代码](https://github.com/tatsu-lab/stanford_alpaca/blob/main/train.py)。 从上面可以看到,开源的大语言模型主要有三大类:GLM衍生的大模型(wenda、[ChatSQL](https://github.com/yysirs/ChatSQL)等)、LLaMA衍生的大模型(Alpaca、Vicuna、BELLE、Phoenix、Chimera等)、Bloom衍生的大模型(Bloomz、BELLE、Phoenix等)。 | 模型 | 训练数据量 | 模型参数 | 训练数据范围 | 词表大小 | | ---------- | ------------------------------------------- | ---------- | --------------- | ------ | | LLaMA | 1T~1.4T tokens(其中,7B/13B使用1T,33B/65B使用1.4T) | 7B~65B | 以英语为主要语言的拉丁语系 | 32000 | | ChatGLM-6B | 约 1T tokens | 6B | 中文、英语 | 130528 | | Bloom | 1.6TB预处理文本,转换为 350B 唯一 tokens | 300M\~176B | 46种自然语言,13种编程语言 | 250680 | 从表格中可以看到,对于像ChatGLM-6B、LLaMA、Bloom这类大模型,要保证基座模型有比较好的效果,至少需要保证上千亿、万亿级的Token量。 目前来看,LLaMA无疑是其中最闪亮的星。但是国内关于LLaMA比较大的一个争论就是LLaMA是以英语为主要语言的拉丁语系上进行训练的,LLaMA词表中的中文token比较少(只有几百个),需不需要扩充词表?如果不扩充词表,中文效果会不会比较差? * 如果不扩充词表,对于中文效果怎么样?根据Vicuna官方的报告,经过Instruction Turing的Vicuna-13B已经有非常好的中文能力。 * LLaMA需不需要扩充词表?根据[Chinese-LLaMA-Alpaca](https://github.com/ymcui/Chinese-LLaMA-Alpaca)和[BELLE](https://github.com/LianjiaTech/BELLE)的报告,扩充中文词表,可以提升中文编解码效率以及模型的性能。但是扩词表,相当于从头初始化开始训练这些参数。如果想达到比较好的性能,需要比较大的算力和数据量。同时,Chinese-LLaMA-Alpaca也指出在进行第一阶段预训练(冻结transformer参数,仅训练embedding,在尽量不干扰原模型的情况下适配新增的中文词向量)时,模型收敛速度较慢。如果不是有特别充裕的时间和计算资源,建议跳过该阶段。因此,虽然扩词表看起来很诱人,但是实际操作起来,还是很有难度的。 下面是BELLE针对是否扩充词表,数据质量、数据语言分布、数据规模对于模型性能的对比: ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cd50114de9aa48b2b6404531d477bf6b~tplv-k3u1fbpfcp-watermark.image?) 其中,**BELLE-0.5M-CLEAN**是从230万指令数据中清洗得到0.5M数据(包含单轮和多轮对话数据)。LLaMA-7B-EXT是针对LLaMA做了中文词表扩充的预训练模型。 下面是Chinese-LLaMA-Alpaca针对中文Alpaca-13B、中文Alpaca-Plus-7B、中文Alpaca-Plus-13B的效果对比: ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/61f342d4f77a4486a9fd94aaaef677c8~tplv-k3u1fbpfcp-watermark.image?) 其中,Plus系列Alpaca是在原版LLaMA的基础上扩充了中文词表,使用了120G中文通用纯文本数据进行二次预训练。 因此,如果既想要中文词表,又没有很大的算力,那建议直接使用ChatGLM-6B或者使用BELLE和Chinese-LLaMA-Alpaca进行中文词表扩充后训练好的模型作为Base模型。 ### 多模态大模型 **目前业界可以下载到的一些多模态大模型**: * [MiniGPT-4](https://github.com/Vision-CAIR/MiniGPT-4):沙特阿拉伯阿卜杜拉国王科技大学的研究团队开源。 * [LLaVA](https://github.com/haotian-liu/LLaVA):由威斯康星大学麦迪逊分校,微软研究院和哥伦比亚大学共同出品。 * [VisualGLM-6B](https://github.com/THUDM/VisualGLM-6B/):开源的,支持**图像、中文和英文**的多模态对话语言模型,语言模型基于 [ChatGLM-6B](https://github.com/THUDM/ChatGLM-6B),具有 62 亿参数;图像部分通过训练 [BLIP2-Qformer](https://arxiv.org/abs/2301.12597) 构建起视觉模型与语言模型的桥梁,整体模型共78亿参数。 * [VisCPM](https://github.com/OpenBMB/VisCPM):于CPM基础模型的中英双语多模态大模型。 ### 领域大模型-新增(2023.06.30) #### 金融领域大模型 * [轩辕](https://github.com/Duxiaoman-DI/XuanYuan):在BLOOM-176B的基础上针对中文通用领域和金融领域进行了针对性的预训练与微调。 #### 法律领域大模型 * [ChatLaw](https://github.com/PKU-YuanGroup/ChatLaw):由北京大学开源的大模型,主要有13B、33B。 * [LexiLaw](https://github.com/CSHaitao/LexiLaw):LexiLaw 是一个经过微调的中文法律大模型,它基于 ChatGLM-6B 架构,通过在法律领域的数据集上进行微调,使其在提供法律咨询和支持方面具备更高的性能和专业性。 ### RLHF(人工反馈强化学习)-新增(2023.07.03) 根据 OpenAI 之前做的一些实验,可以看到使用了 PPO(近端策略优化)算法的 RLHF 模型整体上都更好一些。当把结果提供给人类时,相比于 SFT 模型和通过 prompt 化身为助理的基础模型,人类也基本更喜欢来自 RLHF 模型的 token。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9c370e65027b403798ddf46bc8d83d6d~tplv-k3u1fbpfcp-watermark.image?) 那 RLHF 为什么能让模型更好呢?目前 AI 研究界还没有找到一个得到大家认可的理论,一种可能**与比较和生成的计算难度之间的不对称性有关**。 举个例子说明一下:假设我们要让一个模型写一首关于回形针的俳句。如果你是一位正努力创建训练数据的合同工,正在为 SFT 模型收集数据。那么你该怎样写出一首关于回形针的好俳句呢?而你可能并不是一位优秀的俳句诗人。但是,如果给你几首俳句,你却有能力辨别它们中哪首更好一些。也就是说,比起创建一个好样本,判断哪个样本更好是简单得多的任务。因此,这种不对称性可能使得比较是一种更好的方法,能更好地利用人类的判断来创造出好一些的模型。 但目前来看,RLHF 并不总是会为基石模型带来提升。在某些情况下,RLHF 模型会失去一些熵,也就是说它们会输出更加单调、变化更少的结果。而基础模型的熵更高,可以输出更加多样化的结果。 #### RLHF开源工具 下面是目前开源的一些RLHF工具: * [DeepSpeed Chat](https://github.com/microsoft/DeepSpeedExamples/tree/master/applications/DeepSpeed-Chat):基于Opt系列模型进行示例。 * [ColossalChat](https://github.com/hpcaitech/ColossalAI/tree/main/applications/Chat):基于LLaMA系列模型进行示例。 ## 分布式并行及显存优化技术 **并行技术**: * 数据并行(如:PyTorch DDP) * 模型/张量并行(如:Megatron-LM(1D)、Colossal-AI(2D、2.5D、3D)) * 流水线并行(如:GPipe、PipeDream、PipeDream-2BW、PipeDream Flush(1F1B)) * 多维混合并行(如:3D并行(数据并行、模型并行、流水线并行)) * 自动并行(如:Alpa(自动算子内/算子间并行)) * 优化器相关的并行(如:ZeRO(**零冗余优化器**,在执行的逻辑上是数据并行,但可以达到模型并行的显存优化效果)、PyTorch FSDP) **显存优化技术**: * 重计算(Recomputation):Activation checkpointing(Gradient checkpointing),本质上是一种用时间换空间的策略。 * 卸载(Offload)技术:一种用通信换显存的方法,简单来说就是让模型参数、激活值等在CPU内存和GPU显存之间左右横跳。如:ZeRO-Offload、ZeRO-Infinity等。 * 混合精度(BF16/FP16):降低训练显存的消耗,还能将训练速度提升2-4倍。 * BF16 计算时可避免计算溢出,出现Inf case。 * FP16 在输入数据超过65506 时,计算结果溢出,出现Inf case。 ## 分布式训练框架 **如何选择一款分布式训练框架**? * **训练成本**:不同的训练工具,训练同样的大模型,成本是不一样的。对于大模型,训练一次动辄上百万/千万美元的费用。合适的成本始终是正确的选择。 * **训练类型**:是否支持数据并行、张量并行、流水线并行、多维混合并行、自动并行等 * **效率**:将普通模型训练代码变为分布式训练所需编写代码的行数,我们希望越少越好。 * **灵活性**:你选择的框架是否可以跨不同平台使用? **常见的分布式训练框架**: * 第一类:深度学习框架自带的分布式训练功能。如:TensorFlow、PyTorch、MindSpore、Oneflow、PaddlePaddle等。 * 第二类:基于现有的深度学习框架(如:PyTorch、Flax)进行扩展和优化,从而进行分布式训练。如:Megatron-LM(张量并行)、DeepSpeed(Zero-DP)、Colossal-AI(高维模型并行,如2D、2.5D、3D)、Alpa(自动并行)等 **目前训练超大规模语言模型主要有两条技术路线**: 1. TPU + XLA + TensorFlow/JAX :由Google主导,由于TPU和自家云平台GCP深度绑定。 2. GPU + PyTorch + Megatron-LM + DeepSpeed :由NVIDIA、Meta、MicroSoft大厂加持,社区氛围活跃,也更受到大家欢迎。 对于国内来说,华为昇腾在打造 AI 全栈软硬件平台(昇腾NPU+CANN+MindSpore+MindFormers)。不过目前整个生态相对前两者,还差很远。 ## 参数高效微调(PEFT)技术 在面对特定的下游任务时,如果进行Full FineTuning(即对预训练模型中的所有参数都进行微调),太过低效;而如果采用固定预训练模型的某些层,只微调接近下游任务的那几层参数,又难以达到较好的效果。 PEFT技术旨在**通过最小化微调参数的数量和计算复杂度,来提高预训练模型在新任务上的性能,从而缓解大型预训练模型的训练成本**。这样一来,即使计算资源受限,也可以利用预训练模型的知识来迅速适应新任务,实现高效的迁移学习。因此,PEFT技术可以在提高模型效果的同时,大大缩短模型训练时间和计算成本,让更多人能够参与到深度学习研究中来。除此之外,FEFT可以缓解全量微调带来灾难性遗忘的问题。 * **Prefix Tuning**:与full fine-tuning更新所有参数的方式不同,该方法是在输入token之前构造一段任务相关的virtual tokens作为Prefix,然后训练的时候只更新Prefix部分的参数,而Transformer中的其他部分参数固定。该方法其实和构造Prompt类似,只是Prompt是人为构造的“显式”的提示,并且无法更新参数,而Prefix则是可以学习的“隐式”的提示。 同时,为了防止直接更新Prefix的参数导致训练不稳定的情况,他们在Prefix层前面加了MLP结构(相当于将Prefix分解为更小维度的Input与MLP的组合后输出的结果),训练完成后,只保留Prefix的参数。 * **Prompt Tuning**:该方法可以看作是Prefix Tuning的简化版本,只在输入层加入prompt tokens,并不需要加入MLP进行调整来解决难训练的问题。随着预训练模型参数量的增加,Prompt Tuning的方法会逼近fine-tuning的结果。 * **P-Tuning**:该方法的提出主要是为了解决这样一个问题:大模型的Prompt构造方式严重影响下游任务的效果。P-Tuning将Prompt转换为可以学习的Embedding层,并用MLP+LSTM的方式来对prompt embedding进行一层处理。 * **P-Tuning v2**:让Prompt Tuning能够在不同参数规模的预训练模型、针对不同下游任务的结果上都达到匹敌Fine-tuning的结果。相比Prompt Tuning和P-tuning的方法,P-Tuning v2方法在多层加入了Prompts tokens作为输入,带来两个方面的好处: 1. 带来更多可学习的参数(从P-tuning和Prompt Tuning的0.1%增加到0.1%-3%),同时也足够参数高效。 2. 加入到更深层结构中的Prompt能给模型预测带来更直接的影响。 * **Adapter Tuning**:该方法设计了Adapter结构(首先是一个down-project层将高维度特征映射到低维特征,然后过一个非线形层之后,再用一个up-project结构将低维特征映射回原来的高维特征;同时也设计了skip-connection结构,确保了在最差的情况下能够退化为identity),并将其嵌入Transformer的结构里面,在训练时,固定住原来预训练模型的参数不变,只对新增的Adapter结构进行微调。同时为了保证训练的高效性(也就是尽可能少的引入更多参数)。 * **LoRA**:在涉及到矩阵相乘的模块,引入A、B这样两个低秩矩阵模块去模拟full fine-tuning的过程,相当于只对语言模型中起关键作用的低秩本质维度进行更新。 * QLoRA:使用一种新颖的高精度技术将预训练模型量化为 4 bit,然后添加一小组可学习的低秩适配器权重,这些权重通过量化权重的反向传播梯度进行微调。目前,训练速度较慢。 * **AdaLoRA**:对LoRA的一种改进,它根据重要性评分动态分配参数预算给权重矩阵。 ... **典型应用**: 1. [ChatGLM-Tuning](https://github.com/mymusise/ChatGLM-Tuning) :一种平价的chatgpt实现方案,基于清华的 [ChatGLM-6B](https://github.com/THUDM/ChatGLM-6B) + LoRA 进行finetune。 2. [Alpaca-Lora](https://github.com/tloen/alpaca-lora):使用低秩自适应(LoRA)复现斯坦福羊驼的结果。Stanford Alpaca 是在 LLaMA 整个模型上微调,而 Alpaca-Lora 则是利用 Lora 技术,在冻结原模型 LLaMA 参数的情况下,通过往模型中加入额外的网络层,并只训练这些新增的网络层参数。由于这些新增参数数量较少,这样不仅微调的成本显著下降,还能获得和全模型微调类似的效果。 3. [BLOOM-LORA](https://github.com/linhduongtuan/BLOOM-LORA):由于LLaMA的限制,我们尝试使用Alpaca-Lora重新实现BLOOM-LoRA。 **PEFT实现**: 1. [PEFT](https://github.com/huggingface/peft):Huggingface推出的PEFT库。 2. [unify-parameter-efficient-tuning](https://github.com/jxhe/unify-parameter-efficient-tuning):一个参数高效迁移学习的统一框架。 **高效微调技术目前存在的两个问题**: 相比全参数微调,大部分的高效微调技术目前存在的两个问题: 1. 推理速度会变慢 2. 模型精度会变差 ## 影响大模型性能的主要因素 OpenAI的论文**Scaling Laws for Neural Language Models**中列举了影响模型性能最大的三个因素:**计算量**、**数据集大小**、**模型参数量**。也就是说,当其他因素不成为瓶颈时,计算量、数据集大小、模型参数量这3个因素中的单个因素指数增加时,loss会线性的下降。 除了以上的因素之外,还有一个比较大的影响因素就是**数据质量**。在微软的论文**Instruction Tuning with GPT-4**中指出,同样基于LLaMA模型,使用GPT3和GPT4产生的数据,对模型进行Instruction Turing,可以看到GPT4的数据微调过的模型效果远远好于GPT3数据微调的模型,可见数据质量带来的影响。同样的,Vicuna(7B/13B)的Instruction Turing中,也对shareGPT的数据做了很细致的清洗工作。 ## 衡量大模型水平 要评估一个大型语言模型的水平,可以从以下几个维度提出具有代表性的问题。 * **理解能力**:提出一些需要深入理解文本的问题,看模型是否能准确回答。 * **语言生成能力**:让模型生成一段有关特定主题的文章或故事,评估其生成的文本在结构、逻辑和语法等方面的质量。 * **知识面广度**:请模型回答关于不同主题的问题,以测试其对不同领域的知识掌握程度。这可以是关于科学、历史、文学、体育或其他领域的问题。一个优秀的大语言模型应该可以回答各种领域的问题,并且准确性和深度都很高。 * **适应性**:让模型处理各种不同类型的任务,例如:写作、翻译、编程等,看它是否能灵活应对。 * **长文本理解**:提出一些需要处理长文本的问题,例如:提供一篇文章,让模型总结出文章的要点,或者请模型创作一个故事或一篇文章,让其有一个完整的情节,并且不要出现明显的逻辑矛盾或故事结构上的错误。一个好的大语言模型应该能够以一个连贯的方式讲述一个故事,让读者沉浸其中。 * **长文本生成**:请模型创作一个故事或一篇文章,让其有一个完整的情节,并且不要出现明显的逻辑矛盾或故事结构上的错误。一个好的大语言模型应该能够以一个连贯的方式讲述一个故事,让读者沉浸其中。 * **多样性**:提出一个问题,让模型给出多个不同的答案或解决方案,测试模型的创造力和多样性。 * **情感分析和推断**:提供一段对话或文本,让模型分析其中的情感和态度,或者推断角色间的关系。 * **情感表达**:请模型生成带有情感色彩的文本,如描述某个场景或事件的情感、描述一个人物的情感状态等。一个优秀的大语言模型应该能够准确地捕捉情感,将其表达出来。 * **逻辑推理能力**:请模型回答需要进行推理或逻辑分析的问题,如概率或逻辑推理等。这可以帮助判断模型对推理和逻辑思考的能力,以及其在处理逻辑问题方面的准确性。例如:“所有的动物都会呼吸。狗是一种动物。那么狗会呼吸吗?” * **问题解决能力**:提出实际问题,例如:数学题、编程问题等,看模型是否能给出正确的解答。 * **道德和伦理**:测试模型在处理有关道德和伦理问题时的表现,例如:“在什么情况下撒谎是可以接受的?” * **对话和聊天**:请模型进行对话,以测试其对自然语言处理的掌握程度和能力。一个优秀的大语言模型应该能够准确地回答问题,并且能够理解人类的语言表达方式。 *** **大模型评估方法**: **人工评估**:LIMA、Phoenix **使用 GPT-4 的反馈进行自动评估**:Vicuna、Phoenix、Chimera、BELLE **指标评估**(BLEU-4、ROUGE分数):ChatGLM-6B;对于像ROUGE-L分数的指标评估,有些地方称其为非自然指令评估(Unnatural Instruction Evaluation)。 **Chatbot Arena**:目前用来衡量一个模型好不好的东西基本都是基于一些学术的benchmark,比如在一个某个NLP任务上构建一个测试数据集,然后看测试数据集上准确率多少。然而,这些学术benchmark(如HELM)在大模型和聊天机器人上就不好用了。其原因在于: * 由于评判聊天机器人聊得好不好这件事是非常主观的,因此,现有的方法很难对其进行衡量。 * 这些大模型在训练的时候就几乎把整个互联网的数据都扫了一个遍,因此,很难保证测试用的数据集没有被看到过。甚至更进一步,用测试集直接对模型进行「特训」,如此一来表现必然更好。 * 理论上我们可以和聊天机器人聊任何事情,但很多话题或者任务在现存的benchmark里面根本就不存在。 因此,Chatbot Arena 的做法是放弃benchmark,通过对抗,实时聊天,两两比对人工进行打分,采用elo分数进行评测。 **大模型评估工具**: * [OpenAI evals](https://github.com/openai/evals):OpenAI的自动化评估脚本,核心思路就是通过写prompt模版来自动化评估。 * [PandaLM](https://github.com/WeOpenML/PandaLM):其是直接训练了一个自动化打分模型,0,1,2三分制用模型对两个候选模型进行打分。 ## 大模型推理加速 模型推理作为模型投产的最后一公里,需要确保模型精度的同时追求极致的推理性能。相比传统模型来说,大模型面临着更多的挑战。 当前优化模型最主要技术手段概括来说有以下三个层面: * 算法层面:蒸馏、量化 * 软件层面:计算图优化、模型编译 * 硬件层面:FP8(NVIDIA H系列GPU开始支持FP8,兼有fp16的稳定性和int8的速度) **推理加速框架**: * **FasterTransformer**:英伟达推出的FasterTransformer不修改模型架构而是在计算加速层面优化 Transformer 的 encoder 和 decoder 模块。具体包括如下: * 尽可能多地融合除了 GEMM 以外的操作 * 支持 FP16、INT8、FP8 * 移除 encoder 输入中无用的 padding 来减少计算开销 * **TurboTransformers**:腾讯推出的 TurboTransformers 由 computation runtime 及 serving framework 组成。加速推理框架适用于 CPU 和 GPU,最重要的是,它可以无需预处理便可处理变长的输入序列。具体包括如下: * 与 FasterTransformer 类似,它融合了除 GEMM 之外的操作以减少计算量 * smart batching,对于一个 batch 内不同长度的序列,它也最小化了 zero-padding 开销 * 对 LayerNorm 和 Softmax 进行批处理,使它们更适合并行计算 * 引入了模型感知分配器,以确保在可变长度请求服务期间内存占用较小 ## AI 集群网络通信-新增(2023.06.30) ### 通信硬件 机器内通信: * 共享内存,比如:CPU与CPU之间的通信可以通过共享内存。 * PCIe,通常是CPU与GPU之间的通信,也可以用于GPU与GPU之间的通信。 * NVLink(直连模式),通常是GPU与GPU之间的通信,也可以用于CPU与GPU之间的通信。 机器间通信: * TCP/IP网络 * RDMA:远程直接内存访问,目前主要有如下三种技术: * InfiniBand * iWarp * RoCE v2 ### 通信软件 下面是一些常见的网络通信库: * Gloo: Facebook 开源的一套集体通信库,提供了对机器学习中有用的一些集合通信算法。 * NCCL:英伟达基于 NVIDIA-GPU 的一套开源的集合通信库。 * OpenMPI:一个开源 MPI(消息传递接口 )的实现,由学术,研究和行业合作伙伴联盟开发和维护。 * HCCL:华为开发的网络通信库。 ### 通信网络监控 * [nvbandwidth](https://github.com/NVIDIA/nvbandwidth):用于测量 NVIDIA GPU 带宽的工具。 * [DCGM](https://github.com/NVIDIA/DCGM):一个用于收集telemetry数据和测量 NVIDIA GPU 运行状况。 ## 大模型生态相关技术-新增(2023.06.30) 大模型是基座,要想让其变成一款产品,我们还需要一些其他相关技术: ### LLM 应用开发工具 * langchain:一个用于构建基于大型语言模型(LLM)的应用程序的库。它可以帮助开发者将LLM 与其他计算或知识源结合起来,创建更强大的应用程序。 * llama-index:一个将大语言模型和外部数据连接在一起的工具。 * gpt-cache:LLM 语义缓存层(caching layer),它采用语义缓存(semantic cache)技术,能够存储 LLM 响应,从而显著减少检索数据所需的时间、降低 API 调用开销、提升应用可扩展性。 ### 向量数据库 * Pinecone * Milvus * Vespa * Weaviate 总的来说,如果想快速验证,Pinecone 是个不错的选择。如果想拥有更灵活的查询方式,可以考虑 Vespa 或 Weaviate.如果需要更好的可扩展性和可靠性,那么经过大客户验证的 Vespa 或 Milvus 可能是不错的选择。 ## 经验与教训 **经验**: * 对于同一模型,选择不同的训练框架,对于资源的消耗情况可能存在显著差异(比如使用Huggingface Transformers和DeepSpeed训练OPT-30相对于使用Alpa对于资源的消耗会低不少)。 * 进行大模型模型训练时,先使用小规模模型(如:OPT-125m/2.7b)进行尝试,然后再进行大规模模型(如:OPT-13b/30b...)的尝试,便于出现问题时进行排查。目前来看,业界也是基于相对较小规模参数的模型(6B/7B/13B)进行的优化,同时,13B模型经过指令精调之后的模型效果已经能够到达GPT4的90%的效果。 * 对于一些国产AI加速卡,目前来说,坑还比较多,如果时间不是时间非常充裕,还是尽量选择Nvidia的AI加速卡。 **教训**: * 针对已有的环境进行分布式训练环境搭建时,一定要注意之前环境的python、pip、virtualenv、setuptools的版本。不然创建的虚拟环境即使指定对了Python版本,也可能会遇到很多安装依赖库的问题(GPU服务器能够访问外网的情况下,建议使用Docker相对来说更方便)。 * 遇到需要升级GLIBC等底层库需要升级的提示时,一定要慎重,不要轻易升级,否则,可能会造成系统宕机或很多命令无法操作等情况。 ## 大模型实践文章 下面是最近大模型实践过程中的一些文章,文档及配套代码均放置在GitHub:[llm-action](https://github.com/liguodongiot/llm-action)。 **LLM训练**: | LLM | 预训练/微调/RLHF... | 参数 | 教程 | 代码 | | ----------------------------- | ----------------------------- | --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | Alpaca | full fine-turning | 7B | [从0到1复现斯坦福羊驼(Stanford Alpaca 7B)](https://zhuanlan.zhihu.com/p/618321077) | N/A | | Alpaca | lora | 7B | 1. [足够惊艳,使用Alpaca-Lora基于LLaMA(7B)二十分钟完成微调,效果比肩斯坦福羊驼](https://zhuanlan.zhihu.com/p/619426866)
2. [使用 LoRA 技术对 LLaMA 65B 大模型进行微调及推理](https://zhuanlan.zhihu.com/p/632492604) | [配套代码](https://github.com/liguodongiot/llm-action/tree/main/alpaca-lora) | | BELLE(LLaMA-7B/Bloomz-7B1-mt) | full fine-turning | 7B | 1. [基于LLaMA-7B/Bloomz-7B1-mt复现开源中文对话大模型BELLE及GPTQ量化](https://zhuanlan.zhihu.com/p/618876472)
2. [BELLE(LLaMA-7B/Bloomz-7B1-mt)大模型使用GPTQ量化后推理性能测试](https://zhuanlan.zhihu.com/p/621128368) | N/A | | ChatGLM | lora | 6B | [从0到1基于ChatGLM-6B使用LoRA进行参数高效微调](https://zhuanlan.zhihu.com/p/621793987) | N/A | | ChatGLM | full fine-turning/P-Tuning v2 | 6B | [使用DeepSpeed/P-Tuning v2对ChatGLM-6B进行微调](https://zhuanlan.zhihu.com/p/622351059) | N/A | | Vicuna | full fine-turning | 7B | [大模型也内卷,Vicuna训练及推理指南,效果碾压斯坦福羊驼](https://zhuanlan.zhihu.com/p/624012908) | N/A | | OPT | RLHF | N/A | 1. [一键式 RLHF 训练 DeepSpeed Chat(一):理论篇](https://zhuanlan.zhihu.com/p/626159553) 
2. [一键式 RLHF 训练 DeepSpeed Chat(二):实践篇](https://zhuanlan.zhihu.com/p/626214655) | N/A | | MiniGPT-4 | full fine-turning | 7B | [大杀器,多模态大模型MiniGPT-4入坑指南](https://zhuanlan.zhihu.com/p/627671257) | N/A | | Chinese-LLaMA-Alpaca | lora(预训练+微调) | 7B | [使用 LoRA 技术对 LLaMA 65B 大模型进行微调及推理](https://zhuanlan.zhihu.com/p/631360711) | [配套代码](https://github.com/liguodongiot/llm-action/tree/main/chinese-llama-alpaca) | **LLM推理**: * [大模型的好伙伴,浅析推理加速引擎FasterTransformer](https://zhuanlan.zhihu.com/p/626008090) * [模型推理服务化框架Triton保姆式教程(一):快速入门](https://zhuanlan.zhihu.com/p/629336492) * [模型推理服务化框架Triton保姆式教程(二):架构解析](https://zhuanlan.zhihu.com/p/634143650) * [模型推理服务化框架Triton保姆式教程(三):开发实践](https://zhuanlan.zhihu.com/p/634444666) **LLM微调技术**: 对于普通大众来说,进行大模型的预训练或者全量微调遥不可及。由此,催生了各种参数高效微调技术,让科研人员或者普通开发者有机会尝试微调大模型。 因此,该技术值得我们进行深入分析其背后的机理,本系列大体分七篇文章进行讲解。 * [大模型参数高效微调技术原理综述(一)-背景、参数高效微调简介](https://zhuanlan.zhihu.com/p/635152813) * [大模型参数高效微调技术原理综述(二)-BitFit、Prefix Tuning、Prompt Tuning](https://zhuanlan.zhihu.com/p/635686756) * [大模型参数高效微调技术原理综述(三)-P-Tuning、P-Tuning v2](https://zhuanlan.zhihu.com/p/635848732) * [大模型参数高效微调技术原理综述(四)-Adapter Tuning及其变体](https://zhuanlan.zhihu.com/p/636038478) * [大模型参数高效微调技术原理综述(五)-LoRA、AdaLoRA、QLoRA](https://zhuanlan.zhihu.com/p/636215898) * [大模型参数高效微调技术原理综述(六)-MAM Adapter、UniPELT](https://zhuanlan.zhihu.com/p/636362246) * [大模型参数高效微调技术原理综述(七)-最佳实践、总结](https://zhuanlan.zhihu.com/p/636999010) ## 大模型技术交流群 另外,我创建了一个大模型学习交流群,供大家一起学习交流大模型相关的最新技术,可加我微信(**lgd215666835**)进群(加微信请备注来意,如:进大模型学习交流群)。 ## 结语 实践出真知,以上是这段时间进行大模型实践的一点点总结,写的有一些主观和片面,后续会持续更新自己研究大模型获得的一些认知和实践经验,希望能够帮助大家,欢迎点赞收藏加关注。 ================================================ FILE: docs/llm-summarize/文档大模型.md ================================================ 处理流程: 1. 对表格或者文章文档切分成chunk,将其存入DB 2. 根据chunk文档内容,通过prompt生成问题(qwen) 3. 通过sentencetransformer生成embbedding(Text embedding 模型 stella_large 模型,长文本编码), 第二步 抽取的问题 和 文档 进行相似度匹配,过滤掉阈值小于0.5的问题和文档对 4. 选择正负样本,一个正样本,15个负样本 5. 扩展bert长度从512到1024,使用层次分解的位置编码进行初始化(bge-large) 6. 模型训练(bge) 7. 校验模型获取到 query 与 文档chunk 前三的文档及其分数 ,以及query对应的标准答案 8. 计算rouge指标 ================================================ FILE: docs/llm-summarize/金融大模型.md ================================================ ## FinGPT - 数据集:https://github.com/AI4Finance-Foundation/FinGPT/tree/master/fingpt/FinGPT-v3 FinGPT v3 系列是在新闻和微博情绪分析数据集上使用 LoRA 方法进行微调的LLM,在大多数金融情绪分析数据集上取得了最佳分数。 FinGPT v3.1 使用 chatglm2-6B 作为基础模型; FinGPT v3.2 使用 llama2-7b 作为基础模型. FinGPT V2 用LLaMA和LoRA在美国金融市场训练我们自己的FinGPT FinGPT V1 用 ChatGLM 和 LoRA 在中国金融市场训练我们自己的 FinGPT FinGPT 的目标 实时数据管理流水线使 FinGPT 数据民主化 轻量级调整,使 FinGPT 模型对于个人和机构民主化(频繁更新) 支持各类金融应用 FinNLP 为所有对LLM和 NLP 感兴趣的人提供了一个游乐场。 在这里,我们提供金融领域LLM训练和微调的完整渠道。 完整的架构如下图所示。 端到端框架:FinGPT 采用具有四层的 FinLLM 全栈框架: - 数据源层:该层确保全面的市场覆盖,通过实时信息捕获解决金融数据的时间敏感性。 - 数据工程层:该层面向实时 NLP 数据处理,解决了金融数据中高时间敏感性和低信噪比的固有挑战。 - LLMs层:该层专注于LoRA等一系列微调方法,减轻了金融数据的高度动态性,确保了模型的相关性和准确性。 - 应用层:展示实际应用和演示,凸显FinGPT在金融领域的潜在能力。 FinGPT LLM 层使用的开源基础模型 ## 轩辕2.0 ## BloombergGPT ================================================ FILE: docs/llm-summarize/领域大模型.md ================================================ ## 领域技术标准文档或领域相关数据是领域模型Continue PreTrain的关键。 现有大模型在预训练过程中都会加入书籍、论文等数据,那么在领域预训练时这两种数据其实也是必不可少的,主要是因为这些数据的数据质量较高、领域强相关、知识覆盖率(密度)大,可以让模型更适应考试。当然不是说其他数据不是关键,比如领域相关网站内容、新闻内容都是重要数据,只不过个人看来,在领域上的重要性或者知识密度不如书籍和技术标准。 ## 领域数据训练后,往往通用能力会有所下降,需要混合通用数据以缓解模型遗忘通用能力。 如果仅用领域数据进行模型训练,模型很容易出现灾难性遗忘现象,通常在领域训练过程中加入通用数据。那么这个比例多少比较合适呢?目前还没有一个准确的答案,BloombergGPT(从头预训练)预训练金融和通用数据比例基本上为1:1,ChatHome(继续预训练)发现领域:通用数据比例为1:5时最优。个人感觉应该跟领域数据量有关,当数据量没有那多时,一般数据比例在1:5到1:10之间是比较合适的。 ## 领域模型Continue PreTrain时可以同步加入SFT数据,即MIP,Multi-Task Instruction PreTraining。 预训练过程中,可以加下游SFT的数据,可以让模型在预训练过程中就学习到更多的知识。例如:T5、ExT5、Glm-130b等多任务学习在预训练阶段可能比微调更有帮助。并且ChatHome发现MIP效果在领域上评测集上绝群。 ## 仅用SFT做领域模型时,资源有限就用在Chat模型基础上训练,资源充足就在Base模型上训练。(资源=数据+显卡) 跟很多人讨论过一个问题,就是我们在SFT的时候是在Base模型上训练还是在Chat模型上训练。 其实很简单,如果你只有5k数据,建议你在Chat模型上进行微调;如果你有10w数据,建议你在Base模型上进行微调。因为你不知Chat模型在SFT时的数据质量如何,当自己有能力时,靠人不如靠己。 ## 在Chat模型上进行SFT时,请一定遵循Chat模型原有的系统指令&数据输入格式。 如果你在Chat模型上进行SFT的时候,请跟Chat模型的输入格式一致,否则当你数据量不足时,可能会导致训练效果不明显。并且建议不采用全量参数训练,否则模型原始能力会遗忘较多。 ## 领域模型词表扩增是不是有必要的。 个人感觉,领域词表扩增真实解决的问题是解码效率的问题,给模型效果带来的提升可能不会有很大。(这里领域词表扩充是指在同语言模型上扩充词表,而不是英文模型的中文汉化) ## 领域评测集时必要内容,建议有两份,一份选择题形式自动评测、一份开放形式人工评测。 一定要有自己的领域数据集来验证模型效果,来选择最好的checkpoint。选择题形式可以自动评测,方便模型进行初筛;开放形式人工评测比较浪费时间,可以用作精筛,并且任务形式更贴近真实场景。 ================================================ FILE: docs/transformer内存估算.md ================================================ https://blog.eleuther.ai/transformer-math/ https://kipp.ly/transformer-inference-arithmetic/ ================================================ FILE: faq/FAQ.md ================================================ ## FAQ ### baichuan2报错 - 'BitsAndBytesConfig' object is not subscriptable https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/discussions/2 - AttributeError: 'BaichuanTokenizer' object has no attribute 'sp_model' 降低版本到4.34.0及以下 : pip install transformers==4.34.0 - AttributeError: 'Parameter' object has no attribute 'ds_status' 使用deepspeed + transformers 全量微调时报错 deepspeed 使用的zero3 eval的时候报错;错误详情: AttributeError: 'Parameter' object has no attribute 'ds_status' https://github.com/baichuan-inc/Baichuan2/issues/215 ### chatglm3 - NotImplementedError: Cannot copy out of meta tensor; no data! 在使用 DeepSpeed 进行分布式训练时,DeepSpeed 会将模型分割成多个分块并分配给不同的 GPU 进行训练。在这个过程中,DeepSpeed 会使用 PyTorch 的 DistributedDataParallel 包装器来实现分布式训练,而 DistributedDataParallel 需要对模型进行初始化。 当您使用 AutoModel.from_pretrained() 方法加载预训练模型时,模型权重会被存储在 PyTorch 的 nn.Parameter 对象中。在没有指定 empty_init=False 参数时,nn.Parameter 对象的值将被初始化为全零的张量。但是,由于 nn.Parameter 对象不是真正的张量,而是具有元数据的张量包装器,因此无法将这些对象直接复制到 DeepSpeed 使用的元数据张量中。 在指定 empty_init=False 参数后,nn.Parameter 对象将被初始化为包含预训练权重的张量,这使得 DeepSpeed 能够正常地将权重复制到元数据张量中,从而避免了 NotImplementedError: Cannot copy out of meta tensor; no data! 错误的出现。 综上所述,您遇到的问题是因为在使用 DeepSpeed 进行分布式训练时,模型权重的初始化方式与普通的训练方式不同,因此需要通过指定 empty_init=False 参数来解决。 NotImplementedError: Cannot copy out of meta tensor; no data! 这个错误通常是由于Deepspeed在使用自定义权重初始化时出现问题,而这些初始化可能需要从先前的训练中加载权重。如果在使用Deepspeed进行分布式训练时出现此错误,则需要在初始化模型时指定empty_init=False,以便在加载权重之前,权重矩阵不会被初始化为空。 AutoModel.from_pretrained是Hugging Face Transformers库中的一个方法,用于从预训练模型中加载权重。在Deepspeed分布式训练中,模型的初始化和权重加载可能需要特殊处理,因此需要使用empty_init=False参数来指定在加载权重之前不要将权重矩阵初始化为空。 在其他模型中,可能不需要这个参数是因为它们的初始化和权重加载不需要特殊处理,或者因为它们的代码已经进行了相应的修改以适应Deepspeed的分布式训练流程。 https://github.com/THUDM/ChatGLM-6B/issues/530 ## Deepspeed - Unsupported gpu architecture 'compute_89'(使用deepspeed zero3 offload 在RTX 4090 上遇到问题) 使用的 CUDA 编译器版本不支持指定的 GPU 架构。 参考1: https://github.com/microsoft/DeepSpeed/issues/3488 ``` torch_adam: true The torch.optim.Adam works fine for cpu offloading. ``` 参考2: 原文链接:https://blog.csdn.net/rellvera/article/details/130337185 ``` 解决方法 有两种解决方案: 1.更新 CUDA 版本:检查当前 CUDA 版本是否支持 GPU 架构。如果不支持,更新CUDA版本即可。 2.更改 GPU 架构:也就是降低CPU的算力水平。可以在编译命令中使用 -arch 参数来指定目标架构。例如,-arch=compute_75。 我选择了第一种解决方案,即更新cuda版本。我的GPU为4090,算力是’compute_89’,经查,将CUDA升级到11.8以上版本,即可解决该问题。 ``` ## Pytorch - RuntimeError: DataLoader worker (pid xxxxx) is killed by signal: Killed. 方案一: 可能共享内存太小了 --shm-size 4G 方案二: https://blog.csdn.net/wjinjie/article/details/129733252 ``` 通过设置num_workers,DataLoader实例可以使用多少个子进程进行数据加载,从而加快网络的训练过程。 默认情况下,num_workers值被设置为0,0值代表告诉加载器在主进程内部加载数据。 但是num_workers并不能无限制设置的很大,因为这和你的机器硬件性能也有关。 最简单的办法,就是将num_workers设置的小一点; ---(最终解决)---- 如果还是有问题,可以直接将num_workers设置成默认值0; 当然,也可以通过增加机器内存来尝试解决。 ``` - Pytorch dataloader 错误 “DataLoader worker (pid xxx) is killed by signal” 解决方法:https://cloud.tencent.com/developer/article/2066826 ## bitsandbytes - Exception: cublasLt ran into an error! H100 上面使用 LLM.int8() 加载模型进行微调时,目前不支持。 https://github.com/TimDettmers/bitsandbytes/issues/538 ``` TimDettmers commented on Nov 2, 2023(作者回复) This is actually a more complicated issue. The 8-bit implementation uses cuBLASLt which uses special format for 8-bit matrix multiplication. There are special formats for Ampere, Turning, and now Hopper GPUs. Hopper GPUs do not support Ampere or Turing formats. This means multiple CUDA kernels and the cuBLASLt integration need to be implemented to make 8-bit work on Hopper GPUs. I think for now, the more realistic thing is to throw and error to let the user know that this features is currently not supported. ``` - Error named symbol not found at line 74 in file /bitsandbytes/csrc/ops.cu 使用int8 lora 和 qlora 训练都会报错 H800 上面运行报错 H800 支持cuda11.8以上, 但这里需升级cuda到12以上 ## FEFT - element 0 of tensors does not require grad and does not have a grad_fn 使用Lora(FP16加载,而不是LLM.int8加载)微调时报错。 https://github.com/huggingface/peft/issues/137 以下两种方案均可: model.enable_input_require_grads() : 启用输入嵌入的梯度。这有助于在保持模型权重固定的同时,对适配器权重进行微调。 PeftModel.from_pretrained(model, peft_model_id, is_trainable=True).to(device) - https://github.com/huggingface/transformers/blob/c9e3c0b45419804e11885120e25a35803d1fcf44/src/transformers/modeling_utils.py#L1559 - https://github.com/huggingface/peft/blob/6008f272a565f56c146c5d9fd78d00cb24392d7b/src/peft/peft_model.py#L284 ================================================ FILE: git-pull-push.sh ================================================ git pull origin main git add . #time=`date -Iminutes` #time=`date +"%Y-%m-%d_%H:%M:%S"` time=`date +"%Y-%m-%d"` echo $time commit_info="update-""$time" git commit -m $commit_info git push origin main ================================================ FILE: llm-algo/FLOPs.md ================================================ https://epochai.org/blog/backward-forward-FLOP-ratio 如何计算FLOPs 有两种方式: 根据计算公式和模型结构手动推算 借助第三方工具:calflops、ptflops、thop、torchstat、torchsumary、fvcore 手动推导FLOPs原则: 手动推导模型的FLOPs时只推导前向传播,大部分情况默认模型后向传播的计算量是前向传播的2倍, 总共FLOPs是前向的3倍。(结论出自——https://epochai.org/blog/backward-forward-FLOP-ratio) 由于LLM模型参数过大,占用显存过多,有时候为了降低显存在训练采用将中间参数保留在内存里——激活重计算。因此推导LLM训练时FLOPs如果考虑到中间参数的激活重计算的过程,需要计算整体FLOPs需要再加一份前向计算量,即1(前向) + 2(反向)+ 1(激活重计算)= 4 倍 计算量。 (结论出自——https://arxiv.org/pdf/2205.05198.pdf) 手动推导模型的FLOPs时,优先推导整个过程计算量占大头部分,通常忽略激活函数、layer normalize,softmax等等部分计算量。 参考最简单的计算模型(LLM)FLOPs的方法: https://zhuanlan.zhihu.com/p/652697200 ================================================ FILE: llm-algo/InternLM-20B.md ================================================ InternLM预训练框架 大模型微调工具箱XTuner LMDeploy推理工具链 OpenCompas大模型评测平台 Lagent智能体框架 ================================================ FILE: llm-algo/README.md ================================================ - 可视化:https://bbycroft.net/llm - https://zhuanlan.zhihu.com/p/644815089 ## 模型对比 | 模型 | GPT2 Medium(345M) | Bloom-7b1 | LLaMA-7B | LLaMA2-7B | ChatGLM-6B | ChatGLM2-6B | | -------------------------------------------------------- | ----------------- | ------------------------ | ----------------------------- | ----------------------------- | ----------- | ----------- | | 词表大小(vocab_size) | 50257 | 250880 | 32000 | 32000 | 130528 | 65024 | | Transformer层(n_layer, num_layers, num_hidden_layers) | 24 | 30 | 32 | 32 | 28 | 28 | | 注意力头数(num_attention_heads, n_head) | 16 | 32 | 32 | 32 | 32 | 32 | | key_value头数(num_key_value_heads) | N/A | N/A | N/A | N/A | N/A | N/A | | 隐藏层大小(hidden_size) | 1024(n_embd) | 4096(n_embed) | 4096 | 4096 | 4096 | 4096 | | 前馈神经网络的隐藏层大小(ffn_hidden_size, intermediate_size,n_inner) | 4*n_embd | 4 * hidden_size | 11008 | 11008 | 16384 | 13696 | | seq_length, n_ctx | 1024 | 2048 | 2048(max_position_embeddings) | 2048(max_position_embeddings) | 2048 | 32768 | | n_positions,max_position_embeddings,n_embed | 1024(default) | 2048(4096,bloomz-7b1-hf) | 2048 | 2048(4096,llama2-chat-hf) | hidden_size | hidden_size | - https://huggingface.co/gpt2-medium/resolve/main/config.json - https://huggingface.co/bigscience/bloom-7b1/blob/main/config.json - https://huggingface.co/bigscience/bloomz-7b1-mt/blob/main/config.json - https://huggingface.co/yahma/llama-7b-hf/blob/main/config.json - https://huggingface.co/meta-llama/Llama-2-7b-chat-hf/blob/main/config.json - https://huggingface.co/THUDM/chatglm2-6b-32k - https://huggingface.co/THUDM/chatglm-6b 说明: - 通常 seq_length 与 max_position_embeddings 相等。 - key_value头数:This is the number of key_value heads that should be used to implement Grouped Query Attention. If `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed by meanpooling all the original heads within that group. ## LLaMA | 模型 | LLaMA-7B | LLaMA-2-7B | LLaMA-13B | LLaMA-2-13B | LLaMA-30B | LLaMA-65B | LLaMA-2-70B | | -------------------------------------------------------- | ----------------------------- | ----------------------------- | --------- | ----------- | --------- | --------- | ----------- | | 词表大小(vocab_size) | 32000 | 32000 | 32000 | 32000 | 32000 | 32000 | 32000 | | Transformer层(n_layer, num_layers, num_hidden_layers) | 32 | 32 | 40 | 40 | 60 | 80 | 80 | | 注意力头数(num_attention_heads, n_head) | 32 | 32 | 40 | 40 | 52 | 64 | 64 | | key_value头数(num_key_value_heads) | N/A | 32 | N/A | 40 | N/A | N/A | 8 | | 隐藏层大小(hidden_size) | 4096 | 4096 | 5120 | 5120 | 6656 | 8192 | 8192 | | 前馈神经网络的隐藏层大小(ffn_hidden_size, intermediate_size,n_inner) | 11008 | 11008 | 13824 | 13824 | 17920 | 22016 | 28672 | | seq_length, n_ctx | 2048(max_position_embeddings) | 2048(max_position_embeddings) | 2048 | N/A | 2048 | | N/A | | n_positions,max_position_embeddings,n_embed | 2048 | 2048(4096,llama2-chat-hf) | N/A | 4096 | N/A | N/A | 4096 | - https://huggingface.co/decapoda-research/llama-13b-hf - ================================================ FILE: llm-algo/baichuan2/baichuan.md ================================================ - https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/blob/main/modeling_baichuan.py ================================================ FILE: llm-algo/bert/模型架构.md ================================================ - https://github.com/huggingface/transformers/blob/main/src/transformers/models/bert/modeling_bert.py ## BertEmbeddings(nn.Module) ## BertSelfAttention(nn.Module) ## BertEncoder(nn.Module)
详细代码:

```python class BertEncoder(nn.Module): def __init__(self, config): super().__init__() self.config = config self.layer = nn.ModuleList([BertLayer(config) for _ in range(config.num_hidden_layers)]) self.gradient_checkpointing = False def forward( self, hidden_states: torch.Tensor, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.FloatTensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, past_key_values: Optional[Tuple[Tuple[torch.FloatTensor]]] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = False, output_hidden_states: Optional[bool] = False, return_dict: Optional[bool] = True, ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPastAndCrossAttentions]: all_hidden_states = () if output_hidden_states else None all_self_attentions = () if output_attentions else None all_cross_attentions = () if output_attentions and self.config.add_cross_attention else None if self.gradient_checkpointing and self.training: if use_cache: logger.warning_once( "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." ) use_cache = False next_decoder_cache = () if use_cache else None for i, layer_module in enumerate(self.layer): if output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) layer_head_mask = head_mask[i] if head_mask is not None else None past_key_value = past_key_values[i] if past_key_values is not None else None if self.gradient_checkpointing and self.training: def create_custom_forward(module): def custom_forward(*inputs): return module(*inputs, past_key_value, output_attentions) return custom_forward layer_outputs = torch.utils.checkpoint.checkpoint( create_custom_forward(layer_module), hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, encoder_attention_mask, ) else: layer_outputs = layer_module( hidden_states, attention_mask, layer_head_mask, encoder_hidden_states, encoder_attention_mask, past_key_value, output_attentions, ) hidden_states = layer_outputs[0] if use_cache: next_decoder_cache += (layer_outputs[-1],) if output_attentions: all_self_attentions = all_self_attentions + (layer_outputs[1],) if self.config.add_cross_attention: all_cross_attentions = all_cross_attentions + (layer_outputs[2],) if output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) if not return_dict: return tuple( v for v in [ hidden_states, next_decoder_cache, all_hidden_states, all_self_attentions, all_cross_attentions, ] if v is not None ) return BaseModelOutputWithPastAndCrossAttentions( last_hidden_state=hidden_states, past_key_values=next_decoder_cache, hidden_states=all_hidden_states, attentions=all_self_attentions, cross_attentions=all_cross_attentions, ) ```

## BertModel(BertPreTrainedModel)
详细代码:

```python class BertModel(BertPreTrainedModel): """ The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of cross-attention is added between the self-attention layers, following the architecture described in [Attention is all you need](https://arxiv.org/abs/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin. To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. """ def __init__(self, config, add_pooling_layer=True): super().__init__(config) self.config = config self.embeddings = BertEmbeddings(config) self.encoder = BertEncoder(config) self.pooler = BertPooler(config) if add_pooling_layer else None # Initialize weights and apply final processing self.post_init() def get_input_embeddings(self): return self.embeddings.word_embeddings def set_input_embeddings(self, value): self.embeddings.word_embeddings = value def _prune_heads(self, heads_to_prune): """ Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base class PreTrainedModel """ for layer, heads in heads_to_prune.items(): self.encoder.layer[layer].attention.prune_heads(heads) @add_start_docstrings_to_model_forward(BERT_INPUTS_DOCSTRING.format("batch_size, sequence_length")) @add_code_sample_docstrings( checkpoint=_CHECKPOINT_FOR_DOC, output_type=BaseModelOutputWithPoolingAndCrossAttentions, config_class=_CONFIG_FOR_DOC, ) def forward( self, input_ids: Optional[torch.Tensor] = None, attention_mask: Optional[torch.Tensor] = None, token_type_ids: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, head_mask: Optional[torch.Tensor] = None, inputs_embeds: Optional[torch.Tensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.Tensor] = None, past_key_values: Optional[List[torch.FloatTensor]] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, ) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]: r""" encoder_hidden_states (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*): Sequence of hidden-states at the output of the last layer of the encoder. Used in the cross-attention if the model is configured as a decoder. encoder_attention_mask (`torch.FloatTensor` of shape `(batch_size, sequence_length)`, *optional*): Mask to avoid performing attention on the padding token indices of the encoder input. This mask is used in the cross-attention if the model is configured as a decoder. Mask values selected in `[0, 1]`: - 1 for tokens that are **not masked**, - 0 for tokens that are **masked**. past_key_values (`tuple(tuple(torch.FloatTensor))` of length `config.n_layers` with each tuple having 4 tensors of shape `(batch_size, num_heads, sequence_length - 1, embed_size_per_head)`): Contains precomputed key and value hidden states of the attention blocks. Can be used to speed up decoding. If `past_key_values` are used, the user can optionally input only the last `decoder_input_ids` (those that don't have their past key value states given to this model) of shape `(batch_size, 1)` instead of all `decoder_input_ids` of shape `(batch_size, sequence_length)`. use_cache (`bool`, *optional*): If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see `past_key_values`). """ output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions output_hidden_states = ( output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states ) return_dict = return_dict if return_dict is not None else self.config.use_return_dict if self.config.is_decoder: use_cache = use_cache if use_cache is not None else self.config.use_cache else: use_cache = False if input_ids is not None and inputs_embeds is not None: raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") elif input_ids is not None: self.warn_if_padding_and_no_attention_mask(input_ids, attention_mask) input_shape = input_ids.size() elif inputs_embeds is not None: input_shape = inputs_embeds.size()[:-1] else: raise ValueError("You have to specify either input_ids or inputs_embeds") batch_size, seq_length = input_shape device = input_ids.device if input_ids is not None else inputs_embeds.device # past_key_values_length past_key_values_length = past_key_values[0][0].shape[2] if past_key_values is not None else 0 if attention_mask is None: attention_mask = torch.ones(((batch_size, seq_length + past_key_values_length)), device=device) if token_type_ids is None: if hasattr(self.embeddings, "token_type_ids"): buffered_token_type_ids = self.embeddings.token_type_ids[:, :seq_length] buffered_token_type_ids_expanded = buffered_token_type_ids.expand(batch_size, seq_length) token_type_ids = buffered_token_type_ids_expanded else: token_type_ids = torch.zeros(input_shape, dtype=torch.long, device=device) # We can provide a self-attention mask of dimensions [batch_size, from_seq_length, to_seq_length] # ourselves in which case we just need to make it broadcastable to all heads. extended_attention_mask: torch.Tensor = self.get_extended_attention_mask(attention_mask, input_shape) # If a 2D or 3D attention mask is provided for the cross-attention # we need to make broadcastable to [batch_size, num_heads, seq_length, seq_length] if self.config.is_decoder and encoder_hidden_states is not None: encoder_batch_size, encoder_sequence_length, _ = encoder_hidden_states.size() encoder_hidden_shape = (encoder_batch_size, encoder_sequence_length) if encoder_attention_mask is None: encoder_attention_mask = torch.ones(encoder_hidden_shape, device=device) encoder_extended_attention_mask = self.invert_attention_mask(encoder_attention_mask) else: encoder_extended_attention_mask = None # Prepare head mask if needed # 1.0 in head_mask indicate we keep the head # attention_probs has shape bsz x n_heads x N x N # input head_mask has shape [num_heads] or [num_hidden_layers x num_heads] # and head_mask is converted to shape [num_hidden_layers x batch x num_heads x seq_length x seq_length] head_mask = self.get_head_mask(head_mask, self.config.num_hidden_layers) embedding_output = self.embeddings( input_ids=input_ids, position_ids=position_ids, token_type_ids=token_type_ids, inputs_embeds=inputs_embeds, past_key_values_length=past_key_values_length, ) encoder_outputs = self.encoder( embedding_output, attention_mask=extended_attention_mask, head_mask=head_mask, encoder_hidden_states=encoder_hidden_states, encoder_attention_mask=encoder_extended_attention_mask, past_key_values=past_key_values, use_cache=use_cache, output_attentions=output_attentions, output_hidden_states=output_hidden_states, return_dict=return_dict, ) sequence_output = encoder_outputs[0] pooled_output = self.pooler(sequence_output) if self.pooler is not None else None if not return_dict: return (sequence_output, pooled_output) + encoder_outputs[1:] return BaseModelOutputWithPoolingAndCrossAttentions( last_hidden_state=sequence_output, pooler_output=pooled_output, past_key_values=encoder_outputs.past_key_values, hidden_states=encoder_outputs.hidden_states, attentions=encoder_outputs.attentions, cross_attentions=encoder_outputs.cross_attentions, ) ```

## BertForPreTraining(BertPreTrainedModel) ================================================ FILE: llm-algo/bert.md ================================================ ``` BertEmbeddings BertSelfAttention BertSelfOutput BertAttention BertIntermediate BertOutput BertLayer BertEncoder BertPooler BertPredictionHeadTransform BertLMPredictionHead: BertOnlyMLMHead: BertOnlyNSPHead: BertPreTrainingHeads: BertPreTrainedModel: BertForPreTrainingOutput: BertModel(BertPreTrainedModel): BertForPreTraining(BertPreTrainedModel): BertLMHeadModel(BertPreTrainedModel): BertForMaskedLM(BertPreTrainedModel): BertForNextSentencePrediction(BertPreTrainedModel): BertForSequenceClassification(BertPreTrainedModel): BertForMultipleChoice(BertPreTrainedModel): BertForTokenClassification(BertPreTrainedModel): BertForQuestionAnswering(BertPreTrainedModel): ``` ================================================ FILE: llm-algo/bloom/README.md ================================================ - [BLOOM模型结构详解](https://juejin.cn/post/7223305855923044409) - ================================================ FILE: llm-algo/bloom.md ================================================ ``` BloomGelu BloomAttention BloomMLP BloomBlock BloomPreTrainedModel BloomModel(BloomPreTrainedModel) BloomForCausalLM(BloomPreTrainedModel) ``` ================================================ FILE: llm-algo/chatglm/README.md ================================================ # chatglm-6b - https://huggingface.co/THUDM/chatglm-6b/tree/main - https://github.com/THUDM/ChatGLM-6B/blob/main/ptuning/main.py 自回归填空 ChatGLM借助编码器-解码器架构思想,前半部分采用类似于Bert的双向注意力进行掩码,后半部分采用类似于GPT的自回归架构进行预测。 说明: - gelu - LayerNorm - 重新排列了LN和残差连接的顺序,具体来讲就是将Post-LN改成Pre-LN。 - 使用一个线性层来预测输出词; - 将ReLU激活函数替换为GeLU激活函数。 ================================================ FILE: llm-algo/chatglm/模型架构.md ================================================ ## 模型结构 ``` ChatGLMForConditionalGeneration( (transformer): ChatGLMModel( (word_embeddings): Embedding(130528, 4096) (layers): ModuleList( (0): GLMBlock( (input_layernorm): LayerNorm((4096,), eps=1e-05, elementwise_affine=True) (attention): SelfAttention( (rotary_emb): RotaryEmbedding() (query_key_value): Linear(in_features=4096, out_features=12288, bias=True) (dense): Linear(in_features=4096, out_features=4096, bias=True) ) (post_attention_layernorm): LayerNorm((4096,), eps=1e-05, elementwise_affine=True) (mlp): GLU( (dense_h_to_4h): Linear(in_features=4096, out_features=16384, bias=True) (dense_4h_to_h): Linear(in_features=16384, out_features=4096, bias=True) ) ) ... (27): GLMBlock( (input_layernorm): LayerNorm((4096,), eps=1e-05, elementwise_affine=True) (attention): SelfAttention( (rotary_emb): RotaryEmbedding() (query_key_value): Linear(in_features=4096, out_features=12288, bias=True) (dense): Linear(in_features=4096, out_features=4096, bias=True) ) (post_attention_layernorm): LayerNorm((4096,), eps=1e-05, elementwise_affine=True) (mlp): GLU( (dense_h_to_4h): Linear(in_features=4096, out_features=16384, bias=True) (dense_4h_to_h): Linear(in_features=16384, out_features=4096, bias=True) ) ) ) (final_layernorm): LayerNorm((4096,), eps=1e-05, elementwise_affine=True) ) (lm_head): Linear(in_features=4096, out_features=130528, bias=False) ) ``` ## gelu-激活函数 ```python @torch.jit.script def gelu_impl(x): """OpenAI's gelu implementation.""" return 0.5 * x * (1.0 + torch.tanh(0.7978845608028654 * x * (1.0 + 0.044715 * x * x))) def gelu(x): return gelu_impl(x) ``` ## PrefixEncoder - https://github.com/THUDM/ChatGLM-6B/blob/main/ptuning/main.py P-tuning v2 微调时使用。 encode the prefix 通过 pre_seq_len 判断是全量微调还是P-tuning v2微调。 - prefix_projection:是否投影前缀嵌入(token),默认值为false,表示使用P-Tuning v2, 如果为true,则表示使用 Prefix Tuning。 ```python class PrefixEncoder(torch.nn.Module): def __init__(self, config): super().__init__() self.prefix_projection = config.prefix_projection if self.prefix_projection: # Use a two-layer MLP to encode the prefix self.embedding = torch.nn.Embedding(config.pre_seq_len, config.hidden_size) self.trans = torch.nn.Sequential( torch.nn.Linear(config.hidden_size, config.hidden_size), torch.nn.Tanh(), torch.nn.Linear(config.hidden_size, config.num_layers * config.hidden_size * 2) ) else: self.embedding = torch.nn.Embedding(config.pre_seq_len, config.num_layers * config.hidden_size * 2) def forward(self, prefix: torch.Tensor): if self.prefix_projection: prefix_tokens = self.embedding(prefix) past_key_values = self.trans(prefix_tokens) else: past_key_values = self.embedding(prefix) return past_key_values ``` ## RotaryEmbedding-旋转位置编码 旋转位置编码 ```python class RotaryEmbedding(torch.nn.Module): def __init__(self, dim, base=10000, precision=torch.half, learnable=False): super().__init__() inv_freq = 1. / (base ** (torch.arange(0, dim, 2).float() / dim)) inv_freq = inv_freq.half() self.learnable = learnable if learnable: self.inv_freq = torch.nn.Parameter(inv_freq) self.max_seq_len_cached = None else: self.register_buffer('inv_freq', inv_freq) self.max_seq_len_cached = None self.cos_cached = None self.sin_cached = None self.precision = precision def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs): pass def forward(self, x, seq_dim=1, seq_len=None): if seq_len is None: seq_len = x.shape[seq_dim] if self.max_seq_len_cached is None or (seq_len > self.max_seq_len_cached): self.max_seq_len_cached = None if self.learnable else seq_len t = torch.arange(seq_len, device=x.device, dtype=self.inv_freq.dtype) freqs = torch.einsum('i,j->ij', t, self.inv_freq) # Different from paper, but it uses a different permutation in order to obtain the same calculation emb = torch.cat((freqs, freqs), dim=-1).to(x.device) if self.precision == torch.bfloat16: emb = emb.float() # [sx, 1 (b * np), hn] cos_cached = emb.cos()[:, None, :] sin_cached = emb.sin()[:, None, :] if self.precision == torch.bfloat16: cos_cached = cos_cached.bfloat16() sin_cached = sin_cached.bfloat16() if self.learnable: return cos_cached, sin_cached self.cos_cached, self.sin_cached = cos_cached, sin_cached return self.cos_cached[:seq_len, ...], self.sin_cached[:seq_len, ...] def _apply(self, fn): if self.cos_cached is not None: self.cos_cached = fn(self.cos_cached) if self.sin_cached is not None: self.sin_cached = fn(self.sin_cached) return super()._apply(fn) def rotate_half(x): x1, x2 = x[..., :x.shape[-1] // 2], x[..., x.shape[-1] // 2:] return torch.cat((-x2, x1), dim=x1.ndim - 1) # dim=-1 triggers a bug in earlier torch versions @torch.jit.script def apply_rotary_pos_emb_index(q, k, cos, sin, position_id): # position_id: [sq, b], q, k: [sq, b, np, hn], cos: [sq, 1, hn] -> [sq, b, 1, hn] cos, sin = F.embedding(position_id, cos.squeeze(1)).unsqueeze(2), \ F.embedding(position_id, sin.squeeze(1)).unsqueeze(2) q, k = (q * cos) + (rotate_half(q) * sin), (k * cos) + (rotate_half(k) * sin) return q, k ``` ## SelfAttention(torch.nn.Module) ```python def attention_fn( self, query_layer, key_layer, value_layer, attention_mask, hidden_size_per_partition, layer_id, layer_past=None, scaling_attention_score=True, use_cache=False, ): if layer_past is not None: past_key, past_value = layer_past[0], layer_past[1] key_layer = torch.cat((past_key, key_layer), dim=0) value_layer = torch.cat((past_value, value_layer), dim=0) # seqlen, batch, num_attention_heads, hidden_size_per_attention_head seq_len, b, nh, hidden_size = key_layer.shape if use_cache: present = (key_layer, value_layer) else: present = None query_key_layer_scaling_coeff = float(layer_id + 1) if scaling_attention_score: query_layer = query_layer / (math.sqrt(hidden_size) * query_key_layer_scaling_coeff) # =================================== # Raw attention scores. [b, np, s, s] # =================================== # [b, np, sq, sk] output_size = (query_layer.size(1), query_layer.size(2), query_layer.size(0), key_layer.size(0)) # [sq, b, np, hn] -> [sq, b * np, hn] query_layer = query_layer.view(output_size[2], output_size[0] * output_size[1], -1) # [sk, b, np, hn] -> [sk, b * np, hn] key_layer = key_layer.view(output_size[3], output_size[0] * output_size[1], -1) matmul_result = torch.zeros( 1, 1, 1, dtype=query_layer.dtype, device=query_layer.device, ) matmul_result = torch.baddbmm( matmul_result, query_layer.transpose(0, 1), # [b * np, sq, hn] key_layer.transpose(0, 1).transpose(1, 2), # [b * np, hn, sk] beta=0.0, alpha=1.0, ) # change view to [b, np, sq, sk] attention_scores = matmul_result.view(*output_size) if self.scale_mask_softmax: self.scale_mask_softmax.scale = query_key_layer_scaling_coeff attention_probs = self.scale_mask_softmax(attention_scores, attention_mask.contiguous()) else: if not (attention_mask == 0).all(): # if auto-regressive, skip attention_scores.masked_fill_(attention_mask, -10000.0) dtype = attention_scores.dtype attention_scores = attention_scores.float() attention_scores = attention_scores * query_key_layer_scaling_coeff attention_probs = F.softmax(attention_scores, dim=-1) attention_probs = attention_probs.type(dtype) # ========================= # Context layer. [sq, b, hp] # ========================= # value_layer -> context layer. # [sk, b, np, hn] --> [b, np, sq, hn] # context layer shape: [b, np, sq, hn] output_size = (value_layer.size(1), value_layer.size(2), query_layer.size(0), value_layer.size(3)) # change view [sk, b * np, hn] value_layer = value_layer.view(value_layer.size(0), output_size[0] * output_size[1], -1) # change view [b * np, sq, sk] attention_probs = attention_probs.view(output_size[0] * output_size[1], output_size[2], -1) # matmul: [b * np, sq, hn] context_layer = torch.bmm(attention_probs, value_layer.transpose(0, 1)) # change view [b, np, sq, hn] context_layer = context_layer.view(*output_size) # [b, np, sq, hn] --> [sq, b, np, hn] context_layer = context_layer.permute(2, 0, 1, 3).contiguous() # [sq, b, np, hn] --> [sq, b, hp] new_context_layer_shape = context_layer.size()[:-2] + (hidden_size_per_partition,) context_layer = context_layer.view(*new_context_layer_shape) outputs = (context_layer, present, attention_probs) return outputs ``` ```python class SelfAttention(torch.nn.Module): def __init__(self, hidden_size, num_attention_heads, layer_id, hidden_size_per_attention_head=None, bias=True, params_dtype=torch.float, position_encoding_2d=True, empty_init=True): if empty_init: init_method = skip_init else: init_method = default_init super(SelfAttention, self).__init__() self.layer_id = layer_id self.hidden_size = hidden_size self.hidden_size_per_partition = hidden_size self.num_attention_heads = num_attention_heads self.num_attention_heads_per_partition = num_attention_heads self.position_encoding_2d = position_encoding_2d self.rotary_emb = RotaryEmbedding( self.hidden_size // (self.num_attention_heads * 2) if position_encoding_2d else self.hidden_size // self.num_attention_heads, base=10000, precision=torch.half, learnable=False, ) self.scale_mask_softmax = None if hidden_size_per_attention_head is None: self.hidden_size_per_attention_head = hidden_size // num_attention_heads else: self.hidden_size_per_attention_head = hidden_size_per_attention_head self.inner_hidden_size = num_attention_heads * self.hidden_size_per_attention_head # Strided linear layer. self.query_key_value = init_method( torch.nn.Linear, hidden_size, 3 * self.inner_hidden_size, bias=bias, dtype=params_dtype, ) self.dense = init_method( torch.nn.Linear, self.inner_hidden_size, hidden_size, bias=bias, dtype=params_dtype, ) @staticmethod def attention_mask_func(attention_scores, attention_mask): attention_scores.masked_fill_(attention_mask, -10000.0) return attention_scores def split_tensor_along_last_dim(self, tensor, num_partitions, contiguous_split_chunks=False): """Split a tensor along its last dimension. Arguments: tensor: input tensor. num_partitions: number of partitions to split the tensor contiguous_split_chunks: If True, make each chunk contiguous in memory. """ # Get the size and dimension. last_dim = tensor.dim() - 1 last_dim_size = tensor.size()[last_dim] // num_partitions # Split. tensor_list = torch.split(tensor, last_dim_size, dim=last_dim) # Note: torch.split does not create contiguous tensors by default. if contiguous_split_chunks: return tuple(chunk.contiguous() for chunk in tensor_list) return tensor_list def forward( self, hidden_states: torch.Tensor, position_ids, attention_mask: torch.Tensor, layer_id, layer_past: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, use_cache: bool = False, output_attentions: bool = False, ): """ hidden_states: [seq_len, batch, hidden_size] attention_mask: [(1, 1), seq_len, seq_len] """ # [seq_len, batch, 3 * hidden_size] mixed_raw_layer = self.query_key_value(hidden_states) # [seq_len, batch, 3 * hidden_size] --> [seq_len, batch, num_attention_heads, 3 * hidden_size_per_attention_head] new_tensor_shape = mixed_raw_layer.size()[:-1] + ( self.num_attention_heads_per_partition, 3 * self.hidden_size_per_attention_head, ) mixed_raw_layer = mixed_raw_layer.view(*new_tensor_shape) # [seq_len, batch, num_attention_heads, hidden_size_per_attention_head] (query_layer, key_layer, value_layer) = self.split_tensor_along_last_dim(mixed_raw_layer, 3) if self.position_encoding_2d: q1, q2 = query_layer.chunk(2, dim=(query_layer.ndim - 1)) k1, k2 = key_layer.chunk(2, dim=(key_layer.ndim - 1)) cos, sin = self.rotary_emb(q1, seq_len=position_ids.max() + 1) position_ids, block_position_ids = position_ids[:, 0, :].transpose(0, 1).contiguous(), \ position_ids[:, 1, :].transpose(0, 1).contiguous() q1, k1 = apply_rotary_pos_emb_index(q1, k1, cos, sin, position_ids) q2, k2 = apply_rotary_pos_emb_index(q2, k2, cos, sin, block_position_ids) query_layer = torch.concat([q1, q2], dim=(q1.ndim - 1)) key_layer = torch.concat([k1, k2], dim=(k1.ndim - 1)) else: position_ids = position_ids.transpose(0, 1) cos, sin = self.rotary_emb(value_layer, seq_len=position_ids.max() + 1) # [seq_len, batch, num_attention_heads, hidden_size_per_attention_head] query_layer, key_layer = apply_rotary_pos_emb_index(query_layer, key_layer, cos, sin, position_ids) # [seq_len, batch, hidden_size] context_layer, present, attention_probs = attention_fn( self=self, query_layer=query_layer, key_layer=key_layer, value_layer=value_layer, attention_mask=attention_mask, hidden_size_per_partition=self.hidden_size_per_partition, layer_id=layer_id, layer_past=layer_past, use_cache=use_cache ) output = self.dense(context_layer) outputs = (output, present) if output_attentions: outputs += (attention_probs,) return outputs # output, present, attention_probs ``` ## GLU(torch.nn.Module) ```python class GLU(torch.nn.Module): def __init__(self, hidden_size, inner_hidden_size=None, layer_id=None, bias=True, activation_func=gelu, params_dtype=torch.float, empty_init=True): super(GLU, self).__init__() if empty_init: init_method = skip_init else: init_method = default_init self.layer_id = layer_id self.activation_func = activation_func # Project to 4h. self.hidden_size = hidden_size if inner_hidden_size is None: inner_hidden_size = 4 * hidden_size self.inner_hidden_size = inner_hidden_size self.dense_h_to_4h = init_method( torch.nn.Linear, self.hidden_size, self.inner_hidden_size, bias=bias, dtype=params_dtype, ) # Project back to h. self.dense_4h_to_h = init_method( torch.nn.Linear, self.inner_hidden_size, self.hidden_size, bias=bias, dtype=params_dtype, ) def forward(self, hidden_states): """ hidden_states: [seq_len, batch, hidden_size] """ # [seq_len, batch, inner_hidden_size] intermediate_parallel = self.dense_h_to_4h(hidden_states) intermediate_parallel = self.activation_func(intermediate_parallel) output = self.dense_4h_to_h(intermediate_parallel) return output ``` ## GLMBlock(torch.nn.Module): Transformer层 - SelfAttention:自注意力块 - GLU:mlp块
详细代码:

```python class GLMBlock(torch.nn.Module): def __init__( self, hidden_size, num_attention_heads, layernorm_epsilon, layer_id, inner_hidden_size=None, hidden_size_per_attention_head=None, layernorm=LayerNorm, use_bias=True, params_dtype=torch.float, num_layers=28, position_encoding_2d=True, empty_init=True ): super(GLMBlock, self).__init__() # Set output layer initialization if not provided. self.layer_id = layer_id # Transformer 层 ID # Layernorm on the input data. self.input_layernorm = layernorm(hidden_size, eps=layernorm_epsilon) self.position_encoding_2d = position_encoding_2d # Self attention. self.attention = SelfAttention( hidden_size, num_attention_heads, layer_id, hidden_size_per_attention_head=hidden_size_per_attention_head, bias=use_bias, params_dtype=params_dtype, position_encoding_2d=self.position_encoding_2d, empty_init=empty_init ) # Layernorm on the input data. self.post_attention_layernorm = layernorm(hidden_size, eps=layernorm_epsilon) self.num_layers = num_layers # GLU self.mlp = GLU( hidden_size, inner_hidden_size=inner_hidden_size, bias=use_bias, layer_id=layer_id, params_dtype=params_dtype, empty_init=empty_init ) def forward( self, hidden_states: torch.Tensor, position_ids, attention_mask: torch.Tensor, layer_id, layer_past: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, use_cache: bool = False, output_attentions: bool = False, ): """ hidden_states: [seq_len, batch, hidden_size] attention_mask: [(1, 1), seq_len, seq_len] """ # Layer norm at the begining of the transformer layer. # [seq_len, batch, hidden_size] attention_input = self.input_layernorm(hidden_states) # Self attention. attention_outputs = self.attention( attention_input, position_ids, attention_mask=attention_mask, layer_id=layer_id, layer_past=layer_past, use_cache=use_cache, output_attentions=output_attentions ) attention_output = attention_outputs[0] outputs = attention_outputs[1:] # Residual connection. alpha = (2 * self.num_layers) ** 0.5 hidden_states = attention_input * alpha + attention_output mlp_input = self.post_attention_layernorm(hidden_states) # MLP. mlp_output = self.mlp(mlp_input) # Second residual connection. output = mlp_input * alpha + mlp_output if use_cache: outputs = (output,) + outputs else: outputs = (output,) + outputs[1:] return outputs # hidden_states, present, attentions ```

## ChatGLMPreTrainedModel 一个抽象类,用来处理权重初始化和一个简单的接口用来下载和加载预训练模型。 ## ChatGLMModel(ChatGLMPreTrainedModel) 该模型可以充当编码器(仅具有自注意力)和解码器,在这种情况下,会在自注意力层之间添加cross-attention层。 Cross Attention是一种多头注意力机制,用于在不同的输入序列之间建立关联。 Cross-attention是自然语言处理领域中的一种注意力机制,用于捕捉句子中单词与单词之间的关系。 它通过在编码器和解码器之间建立一个注意力机制,使得解码器能够关注编码器中每个单词的信息,并且可以根据当前生成的单词来确定接下来需要注意的单词。 Cross-Attention是两端的注意力机制,然后合起来,输入不同。Cross-attention将两个相同维度的嵌入序列不对称地组合在一起,而其中一个序列用作查询Q输入,而另一个序列用作键K和值V输入。 ```python class ChatGLMModel(ChatGLMPreTrainedModel): """ The model can behave as an encoder (with only self-attention) as well as a decoder, in which case a layer of cross-attention is added between the self-attention layers, following the architecture described in [Attention is all you need](https://arxiv.org/abs/1706.03762) by Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser and Illia Polosukhin. To behave as an decoder the model needs to be initialized with the `is_decoder` argument of the configuration set to `True`. To be used in a Seq2Seq model, the model needs to initialized with both `is_decoder` argument and `add_cross_attention` set to `True`; an `encoder_hidden_states` is then expected as an input to the forward pass. """ def __init__(self, config: ChatGLMConfig, empty_init=True): super().__init__(config) if empty_init: init_method = skip_init else: init_method = default_init # recording parameters self.max_sequence_length = config.max_sequence_length self.hidden_size = config.hidden_size self.params_dtype = torch.half self.num_attention_heads = config.num_attention_heads self.vocab_size = config.vocab_size self.num_layers = config.num_layers self.layernorm_epsilon = config.layernorm_epsilon self.inner_hidden_size = config.inner_hidden_size self.hidden_size_per_attention_head = self.hidden_size // self.num_attention_heads self.position_encoding_2d = config.position_encoding_2d self.pre_seq_len = config.pre_seq_len self.prefix_projection = config.prefix_projection self.word_embeddings = init_method( torch.nn.Embedding, num_embeddings=self.vocab_size, embedding_dim=self.hidden_size, dtype=self.params_dtype ) self.gradient_checkpointing = False def get_layer(layer_id): return GLMBlock( self.hidden_size, self.num_attention_heads, self.layernorm_epsilon, layer_id, inner_hidden_size=self.inner_hidden_size, hidden_size_per_attention_head=self.hidden_size_per_attention_head, layernorm=LayerNorm, use_bias=True, params_dtype=self.params_dtype, position_encoding_2d=self.position_encoding_2d, empty_init=empty_init ) self.layers = torch.nn.ModuleList( [get_layer(layer_id) for layer_id in range(self.num_layers)] ) # Final layer norm before output. self.final_layernorm = LayerNorm(self.hidden_size, eps=self.layernorm_epsilon) if self.pre_seq_len is not None: for param in self.parameters(): param.requires_grad = False self.prefix_tokens = torch.arange(self.pre_seq_len).long() self.prefix_encoder = PrefixEncoder(config) self.dropout = torch.nn.Dropout(0.1) # total_params = sum(p.numel() for p in self.parameters()) # trainable_params = sum(p.numel() for p in self.parameters() if p.requires_grad) # print("Using p-tuning v2: # trainable_params = {} / {}".format(trainable_params, total_params)) def get_input_embeddings(self): return self.word_embeddings def set_input_embeddings(self, new_embeddings: torch.Tensor): self.word_embeddings = new_embeddings def get_prompt(self, batch_size, device, dtype=torch.half): prefix_tokens = self.prefix_tokens.unsqueeze(0).expand(batch_size, -1).to(device) past_key_values = self.prefix_encoder(prefix_tokens).type(dtype) past_key_values = past_key_values.view( batch_size, self.pre_seq_len, self.num_layers * 2, self.num_attention_heads, self.hidden_size // self.num_attention_heads ) # seq_len, b, nh, hidden_size past_key_values = self.dropout(past_key_values) past_key_values = past_key_values.permute([2, 1, 0, 3, 4]).split(2) # past_key_values = [(v[0], v[1]) for v in past_key_values] return past_key_values @add_start_docstrings_to_model_forward(CHATGLM_6B_INPUTS_DOCSTRING.format("batch_size, sequence_length")) @add_code_sample_docstrings( checkpoint=_CHECKPOINT_FOR_DOC, output_type=BaseModelOutputWithPastAndCrossAttentions, config_class=_CONFIG_FOR_DOC, ) def forward( self, input_ids: Optional[torch.LongTensor] = None, position_ids: Optional[torch.LongTensor] = None, attention_mask: Optional[torch.Tensor] = None, past_key_values: Optional[Tuple[Tuple[torch.Tensor, torch.Tensor], ...]] = None, inputs_embeds: Optional[torch.LongTensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, ) -> Union[Tuple[torch.Tensor, ...], BaseModelOutputWithPast]: output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions output_hidden_states = ( output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states ) use_cache = use_cache if use_cache is not None else self.config.use_cache return_dict = return_dict if return_dict is not None else self.config.use_return_dict if self.gradient_checkpointing and self.training: if use_cache: logger.warning_once( "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." ) use_cache = False if input_ids is not None and inputs_embeds is not None: raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time") elif input_ids is not None: batch_size, seq_length = input_ids.shape[:2] elif inputs_embeds is not None: batch_size, seq_length = inputs_embeds.shape[:2] else: raise ValueError("You have to specify either input_ids or inputs_embeds") if inputs_embeds is None: inputs_embeds = self.word_embeddings(input_ids) if past_key_values is None: if self.pre_seq_len is not None: past_key_values = self.get_prompt(batch_size=input_ids.shape[0], device=input_ids.device, dtype=inputs_embeds.dtype) else: past_key_values = tuple([None] * len(self.layers)) if attention_mask is None: attention_mask = self.get_masks( input_ids, device=input_ids.device ) if position_ids is None: MASK, gMASK = self.config.mask_token_id, self.config.gmask_token_id seqs = input_ids.tolist() mask_positions, use_gmasks = [], [] for seq in seqs: mask_token = gMASK if gMASK in seq else MASK use_gmask = mask_token == gMASK mask_positions.append(seq.index(mask_token)) use_gmasks.append(use_gmask) position_ids = self.get_position_ids( input_ids, mask_positions=mask_positions, device=input_ids.device, use_gmasks=use_gmasks ) if self.pre_seq_len is not None and attention_mask is not None: prefix_attention_mask = torch.ones(batch_size, 1, input_ids.size(-1), self.pre_seq_len).to( attention_mask.device) prefix_attention_mask = (prefix_attention_mask < 0.5).bool() attention_mask = torch.cat((prefix_attention_mask, attention_mask), dim=3) # [seq_len, batch, hidden_size] hidden_states = inputs_embeds.transpose(0, 1) presents = () if use_cache else None all_self_attentions = () if output_attentions else None all_hidden_states = () if output_hidden_states else None if attention_mask is None: attention_mask = torch.zeros(1, 1, device=input_ids.device).bool() else: attention_mask = attention_mask.to(hidden_states.device) for i, layer in enumerate(self.layers): if output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) layer_past = past_key_values[i] if self.gradient_checkpointing and self.training: layer_ret = torch.utils.checkpoint.checkpoint( layer, hidden_states, position_ids, attention_mask, torch.tensor(i), layer_past, use_cache, output_attentions ) else: layer_ret = layer( hidden_states, position_ids=position_ids, attention_mask=attention_mask, layer_id=torch.tensor(i), layer_past=layer_past, use_cache=use_cache, output_attentions=output_attentions ) hidden_states = layer_ret[0] if use_cache: presents = presents + (layer_ret[1],) if output_attentions: all_self_attentions = all_self_attentions + (layer_ret[2 if use_cache else 1],) # Final layer norm. hidden_states = self.final_layernorm(hidden_states) if output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) if not return_dict: return tuple(v for v in [hidden_states, presents, all_hidden_states, all_self_attentions] if v is not None) return BaseModelOutputWithPast( last_hidden_state=hidden_states, past_key_values=presents, hidden_states=all_hidden_states, attentions=all_self_attentions, ) ``` ## ChatGLMForConditionalGeneration ```python class ChatGLMForConditionalGeneration(ChatGLMPreTrainedModel): def __init__(self, config: ChatGLMConfig, empty_init=True): super().__init__(config) if empty_init: init_method = skip_init else: init_method = default_init # self.hidden_size = config.hidden_size # self.params_dtype = torch.half # self.vocab_size = config.vocab_size self.max_sequence_length = config.max_sequence_length self.position_encoding_2d = config.position_encoding_2d self.transformer = ChatGLMModel(config, empty_init=empty_init) self.lm_head = init_method( nn.Linear, config.hidden_size, config.vocab_size, bias=False, dtype=torch.half ) self.config = config ... def get_output_embeddings(self): return self.lm_head def set_output_embeddings(self, new_embeddings): self.lm_head = new_embeddings def forward( self, input_ids: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, attention_mask: Optional[torch.Tensor] = None, past_key_values: Optional[Tuple[torch.FloatTensor]] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, ): use_cache = use_cache if use_cache is not None else self.config.use_cache return_dict = return_dict if return_dict is not None else self.config.use_return_dict transformer_outputs = self.transformer( input_ids=input_ids, position_ids=position_ids, attention_mask=attention_mask, past_key_values=past_key_values, inputs_embeds=inputs_embeds, use_cache=use_cache, output_attentions=output_attentions, output_hidden_states=output_hidden_states, return_dict=return_dict, ) hidden_states = transformer_outputs[0] lm_logits = self.lm_head(hidden_states).permute(1, 0, 2).contiguous() loss = None if labels is not None: lm_logits = lm_logits.to(torch.float32) # Shift so that tokens < n predict n shift_logits = lm_logits[..., :-1, :].contiguous() shift_labels = labels[..., 1:].contiguous() # Flatten the tokens loss_fct = CrossEntropyLoss(ignore_index=-100) loss = loss_fct(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1)) lm_logits = lm_logits.to(hidden_states.dtype) loss = loss.to(hidden_states.dtype) if not return_dict: output = (lm_logits,) + transformer_outputs[1:] return ((loss,) + output) if loss is not None else output return CausalLMOutputWithPast( loss=loss, logits=lm_logits, past_key_values=transformer_outputs.past_key_values, hidden_states=transformer_outputs.hidden_states, attentions=transformer_outputs.attentions, ) ``` ================================================ FILE: llm-algo/chatglm2/README.md ================================================ - https://huggingface.co/THUDM/chatglm2-6b/blob/main/modeling_chatglm.py -更强大的性能:ChatGLM2-6B 使用了 GLM 的混合目标函数,经过了 1.4T 中英标识符的预训练与人类偏好对齐训练。 - 更长的上下文:基于 FlashAttention 技术,我们将基座模型的上下文长度(Context Length)由 ChatGLM-6B 的 2K 扩展到了 32K,并在对话阶段使用 8K 的上下文长度训练。对于更长的上下文,我们发布了 ChatGLM2-6B-32K 模型。 - 更高效的推理:基于 Multi-Query Attention 技术,ChatGLM2-6B 有更高效的推理速度和更低的显存占用。 ## 说明 - F.silu: - RMSNorm ## chatglm 与 chatglm2 不同支持 - 激活函数不同 - RotaryEmbedding 位置不同。 ================================================ FILE: llm-algo/chatglm2/模型架构.md ================================================ ## 模型架构 ``` ChatGLMForConditionalGeneration( (transformer): ChatGLMModel( (embedding): Embedding( (word_embeddings): Embedding(65024, 4096) ) (rotary_pos_emb): RotaryEmbedding() (encoder): GLMTransformer( (layers): ModuleList( (0): GLMBlock( (input_layernorm): RMSNorm() (self_attention): SelfAttention( (query_key_value): Linear(in_features=4096, out_features=4608, bias=True) (core_attention): CoreAttention( (attention_dropout): Dropout(p=0.0, inplace=False) ) (dense): Linear(in_features=4096, out_features=4096, bias=False) ) (post_attention_layernorm): RMSNorm() (mlp): MLP( (dense_h_to_4h): Linear(in_features=4096, out_features=27392, bias=False) (dense_4h_to_h): Linear(in_features=13696, out_features=4096, bias=False) ) ) ... (27): GLMBlock( (input_layernorm): RMSNorm() (self_attention): SelfAttention( (query_key_value): Linear(in_features=4096, out_features=4608, bias=True) (core_attention): CoreAttention( (attention_dropout): Dropout(p=0.0, inplace=False) ) (dense): Linear(in_features=4096, out_features=4096, bias=False) ) (post_attention_layernorm): RMSNorm() (mlp): MLP( (dense_h_to_4h): Linear(in_features=4096, out_features=27392, bias=False) (dense_4h_to_h): Linear(in_features=13696, out_features=4096, bias=False) ) ) ) (final_layernorm): RMSNorm() ) (output_layer): Linear(in_features=4096, out_features=65024, bias=False) ) ) ``` ## CoreAttention ```python class CoreAttention(torch.nn.Module): def __init__(self, config: ChatGLMConfig, layer_number): super(CoreAttention, self).__init__() self.apply_query_key_layer_scaling = config.apply_query_key_layer_scaling self.attention_softmax_in_fp32 = config.attention_softmax_in_fp32 if self.apply_query_key_layer_scaling: self.attention_softmax_in_fp32 = True self.layer_number = max(1, layer_number) projection_size = config.kv_channels * config.num_attention_heads # Per attention head and per partition values. self.hidden_size_per_partition = projection_size self.hidden_size_per_attention_head = projection_size // config.num_attention_heads self.num_attention_heads_per_partition = config.num_attention_heads coeff = None self.norm_factor = math.sqrt(self.hidden_size_per_attention_head) if self.apply_query_key_layer_scaling: coeff = self.layer_number self.norm_factor *= coeff self.coeff = coeff self.attention_dropout = torch.nn.Dropout(config.attention_dropout) def forward(self, query_layer, key_layer, value_layer, attention_mask): pytorch_major_version = int(torch.__version__.split('.')[0]) if pytorch_major_version >= 2: query_layer, key_layer, value_layer = [k.permute(1, 2, 0, 3) for k in [query_layer, key_layer, value_layer]] if attention_mask is None and query_layer.shape[2] == key_layer.shape[2]: context_layer = torch.nn.functional.scaled_dot_product_attention(query_layer, key_layer, value_layer, is_causal=True) else: if attention_mask is not None: attention_mask = ~attention_mask context_layer = torch.nn.functional.scaled_dot_product_attention(query_layer, key_layer, value_layer, attention_mask) context_layer = context_layer.permute(2, 0, 1, 3) new_context_layer_shape = context_layer.size()[:-2] + (self.hidden_size_per_partition,) context_layer = context_layer.reshape(*new_context_layer_shape) else: # Raw attention scores # [b, np, sq, sk] output_size = (query_layer.size(1), query_layer.size(2), query_layer.size(0), key_layer.size(0)) # [sq, b, np, hn] -> [sq, b * np, hn] query_layer = query_layer.view(output_size[2], output_size[0] * output_size[1], -1) # [sk, b, np, hn] -> [sk, b * np, hn] key_layer = key_layer.view(output_size[3], output_size[0] * output_size[1], -1) # preallocting input tensor: [b * np, sq, sk] matmul_input_buffer = torch.empty( output_size[0] * output_size[1], output_size[2], output_size[3], dtype=query_layer.dtype, device=query_layer.device ) # Raw attention scores. [b * np, sq, sk] matmul_result = torch.baddbmm( matmul_input_buffer, query_layer.transpose(0, 1), # [b * np, sq, hn] key_layer.transpose(0, 1).transpose(1, 2), # [b * np, hn, sk] beta=0.0, alpha=(1.0 / self.norm_factor), ) # change view to [b, np, sq, sk] attention_scores = matmul_result.view(*output_size) # =========================== # Attention probs and dropout # =========================== # attention scores and attention mask [b, np, sq, sk] if self.attention_softmax_in_fp32: attention_scores = attention_scores.float() if self.coeff is not None: attention_scores = attention_scores * self.coeff if attention_mask is None and attention_scores.shape[2] == attention_scores.shape[3]: attention_mask = torch.ones(output_size[0], 1, output_size[2], output_size[3], device=attention_scores.device, dtype=torch.bool) attention_mask.tril_() attention_mask = ~attention_mask if attention_mask is not None: attention_scores = attention_scores.masked_fill(attention_mask, float("-inf")) attention_probs = F.softmax(attention_scores, dim=-1) attention_probs = attention_probs.type_as(value_layer) # This is actually dropping out entire tokens to attend to, which might # seem a bit unusual, but is taken from the original Transformer paper. attention_probs = self.attention_dropout(attention_probs) # ========================= # Context layer. [sq, b, hp] # ========================= # value_layer -> context layer. # [sk, b, np, hn] --> [b, np, sq, hn] # context layer shape: [b, np, sq, hn] output_size = (value_layer.size(1), value_layer.size(2), query_layer.size(0), value_layer.size(3)) # change view [sk, b * np, hn] value_layer = value_layer.view(value_layer.size(0), output_size[0] * output_size[1], -1) # change view [b * np, sq, sk] attention_probs = attention_probs.view(output_size[0] * output_size[1], output_size[2], -1) # matmul: [b * np, sq, hn] context_layer = torch.bmm(attention_probs, value_layer.transpose(0, 1)) # change view [b, np, sq, hn] context_layer = context_layer.view(*output_size) # [b, np, sq, hn] --> [sq, b, np, hn] context_layer = context_layer.permute(2, 0, 1, 3).contiguous() # [sq, b, np, hn] --> [sq, b, hp] new_context_layer_shape = context_layer.size()[:-2] + (self.hidden_size_per_partition,) context_layer = context_layer.view(*new_context_layer_shape) return context_layer ``` ## SelfAttention(torch.nn.Module) Parallel self-attention layer abstract class. ```python class SelfAttention(torch.nn.Module): """Parallel self-attention layer abstract class. Self-attention layer takes input with size [s, b, h] and returns output of the same size. """ def __init__(self, config: ChatGLMConfig, layer_number, device=None): super(SelfAttention, self).__init__() self.layer_number = max(1, layer_number) self.projection_size = config.kv_channels * config.num_attention_heads # Per attention head and per partition values. self.hidden_size_per_attention_head = self.projection_size // config.num_attention_heads self.num_attention_heads_per_partition = config.num_attention_heads self.multi_query_attention = config.multi_query_attention self.qkv_hidden_size = 3 * self.projection_size if self.multi_query_attention: self.num_multi_query_groups_per_partition = config.multi_query_group_num self.qkv_hidden_size = ( self.projection_size + 2 * self.hidden_size_per_attention_head * config.multi_query_group_num ) self.query_key_value = nn.Linear(config.hidden_size, self.qkv_hidden_size, bias=config.add_bias_linear or config.add_qkv_bias, device=device, **_config_to_kwargs(config) ) self.core_attention = CoreAttention(config, self.layer_number) # Output. self.dense = nn.Linear(self.projection_size, config.hidden_size, bias=config.add_bias_linear, device=device, **_config_to_kwargs(config) ) def _allocate_memory(self, inference_max_sequence_len, batch_size, device=None, dtype=None): if self.multi_query_attention: num_attention_heads = self.num_multi_query_groups_per_partition else: num_attention_heads = self.num_attention_heads_per_partition return torch.empty( inference_max_sequence_len, batch_size, num_attention_heads, self.hidden_size_per_attention_head, dtype=dtype, device=device, ) def forward( self, hidden_states, attention_mask, rotary_pos_emb, kv_cache=None, use_cache=True ): # hidden_states: [sq, b, h] # ================================================= # Pre-allocate memory for key-values for inference. # ================================================= # ===================== # Query, Key, and Value # ===================== # Attention heads [sq, b, h] --> [sq, b, (np * 3 * hn)] mixed_x_layer = self.query_key_value(hidden_states) if self.multi_query_attention: (query_layer, key_layer, value_layer) = mixed_x_layer.split( [ self.num_attention_heads_per_partition * self.hidden_size_per_attention_head, self.num_multi_query_groups_per_partition * self.hidden_size_per_attention_head, self.num_multi_query_groups_per_partition * self.hidden_size_per_attention_head, ], dim=-1, ) query_layer = query_layer.view( query_layer.size()[:-1] + (self.num_attention_heads_per_partition, self.hidden_size_per_attention_head) ) key_layer = key_layer.view( key_layer.size()[:-1] + (self.num_multi_query_groups_per_partition, self.hidden_size_per_attention_head) ) value_layer = value_layer.view( value_layer.size()[:-1] + (self.num_multi_query_groups_per_partition, self.hidden_size_per_attention_head) ) else: new_tensor_shape = mixed_x_layer.size()[:-1] + \ (self.num_attention_heads_per_partition, 3 * self.hidden_size_per_attention_head) mixed_x_layer = mixed_x_layer.view(*new_tensor_shape) # [sq, b, np, 3 * hn] --> 3 [sq, b, np, hn] (query_layer, key_layer, value_layer) = split_tensor_along_last_dim(mixed_x_layer, 3) # apply relative positional encoding (rotary embedding) if rotary_pos_emb is not None: query_layer = apply_rotary_pos_emb(query_layer, rotary_pos_emb) key_layer = apply_rotary_pos_emb(key_layer, rotary_pos_emb) # adjust key and value for inference if kv_cache is not None: cache_k, cache_v = kv_cache key_layer = torch.cat((cache_k, key_layer), dim=0) value_layer = torch.cat((cache_v, value_layer), dim=0) if use_cache: kv_cache = (key_layer, value_layer) else: kv_cache = None if self.multi_query_attention: key_layer = key_layer.unsqueeze(-2) key_layer = key_layer.expand( -1, -1, -1, self.num_attention_heads_per_partition // self.num_multi_query_groups_per_partition, -1 ) key_layer = key_layer.contiguous().view( key_layer.size()[:2] + (self.num_attention_heads_per_partition, self.hidden_size_per_attention_head) ) value_layer = value_layer.unsqueeze(-2) value_layer = value_layer.expand( -1, -1, -1, self.num_attention_heads_per_partition // self.num_multi_query_groups_per_partition, -1 ) value_layer = value_layer.contiguous().view( value_layer.size()[:2] + (self.num_attention_heads_per_partition, self.hidden_size_per_attention_head) ) # ================================== # core attention computation # ================================== context_layer = self.core_attention(query_layer, key_layer, value_layer, attention_mask) # ================= # Output. [sq, b, h] # ================= output = self.dense(context_layer) return output, kv_cache ``` ## MLP(torch.nn.Module): MLP. ```python class MLP(torch.nn.Module): """MLP. MLP will take the input with h hidden state, project it to 4*h hidden dimension, perform nonlinear transformation, and project the state back into h hidden dimension. """ def __init__(self, config: ChatGLMConfig, device=None): super(MLP, self).__init__() self.add_bias = config.add_bias_linear # Project to 4h. If using swiglu double the output width, see https://arxiv.org/pdf/2002.05202.pdf self.dense_h_to_4h = nn.Linear( config.hidden_size, config.ffn_hidden_size * 2, bias=self.add_bias, device=device, **_config_to_kwargs(config) ) def swiglu(x): x = torch.chunk(x, 2, dim=-1) return F.silu(x[0]) * x[1] self.activation_func = swiglu # Project back to h. self.dense_4h_to_h = nn.Linear( config.ffn_hidden_size, config.hidden_size, bias=self.add_bias, device=device, **_config_to_kwargs(config) ) def forward(self, hidden_states): # [s, b, 4hp] intermediate_parallel = self.dense_h_to_4h(hidden_states) intermediate_parallel = self.activation_func(intermediate_parallel) # [s, b, h] output = self.dense_4h_to_h(intermediate_parallel) return output ``` ## GLMBlock(torch.nn.Module) ```python class GLMBlock(torch.nn.Module): """A single transformer layer. Transformer layer takes input with size [s, b, h] and returns an output of the same size. """ def __init__(self, config: ChatGLMConfig, layer_number, device=None): super(GLMBlock, self).__init__() self.layer_number = layer_number self.apply_residual_connection_post_layernorm = config.apply_residual_connection_post_layernorm self.fp32_residual_connection = config.fp32_residual_connection LayerNormFunc = RMSNorm if config.rmsnorm else LayerNorm # Layernorm on the input data. self.input_layernorm = LayerNormFunc(config.hidden_size, eps=config.layernorm_epsilon, device=device, dtype=config.torch_dtype) # Self attention. self.self_attention = SelfAttention(config, layer_number, device=device) self.hidden_dropout = config.hidden_dropout # Layernorm on the attention output self.post_attention_layernorm = LayerNormFunc(config.hidden_size, eps=config.layernorm_epsilon, device=device, dtype=config.torch_dtype) # MLP self.mlp = MLP(config, device=device) def forward( self, hidden_states, attention_mask, rotary_pos_emb, kv_cache=None, use_cache=True, ): # hidden_states: [s, b, h] # Layer norm at the beginning of the transformer layer. layernorm_output = self.input_layernorm(hidden_states) # Self attention. attention_output, kv_cache = self.self_attention( layernorm_output, attention_mask, rotary_pos_emb, kv_cache=kv_cache, use_cache=use_cache ) # Residual connection. if self.apply_residual_connection_post_layernorm: residual = layernorm_output else: residual = hidden_states layernorm_input = torch.nn.functional.dropout(attention_output, p=self.hidden_dropout, training=self.training) layernorm_input = residual + layernorm_input # Layer norm post the self attention. layernorm_output = self.post_attention_layernorm(layernorm_input) # MLP. mlp_output = self.mlp(layernorm_output) # Second residual connection. if self.apply_residual_connection_post_layernorm: residual = layernorm_output else: residual = layernorm_input output = torch.nn.functional.dropout(mlp_output, p=self.hidden_dropout, training=self.training) output = residual + output return output, kv_cache ``` ## GLMTransformer(torch.nn.Module) ```python class GLMTransformer(torch.nn.Module): """Transformer class.""" def __init__(self, config: ChatGLMConfig, device=None): super(GLMTransformer, self).__init__() self.fp32_residual_connection = config.fp32_residual_connection self.post_layer_norm = config.post_layer_norm # Number of layers. self.num_layers = config.num_layers # Transformer layers. def build_layer(layer_number): return GLMBlock(config, layer_number, device=device) self.layers = torch.nn.ModuleList([build_layer(i + 1) for i in range(self.num_layers)]) if self.post_layer_norm: LayerNormFunc = RMSNorm if config.rmsnorm else LayerNorm # Final layer norm before output. self.final_layernorm = LayerNormFunc(config.hidden_size, eps=config.layernorm_epsilon, device=device, dtype=config.torch_dtype) self.gradient_checkpointing = False def _get_layer(self, layer_number): return self.layers[layer_number] def forward( self, hidden_states, attention_mask, rotary_pos_emb, kv_caches=None, use_cache: Optional[bool] = True, output_hidden_states: Optional[bool] = False, ): if not kv_caches: kv_caches = [None for _ in range(self.num_layers)] presents = () if use_cache else None if self.gradient_checkpointing and self.training: if use_cache: logger.warning_once( "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`..." ) use_cache = False all_self_attentions = None all_hidden_states = () if output_hidden_states else None for index in range(self.num_layers): if output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) layer = self._get_layer(index) if self.gradient_checkpointing and self.training: layer_ret = torch.utils.checkpoint.checkpoint( layer, hidden_states, attention_mask, rotary_pos_emb, kv_caches[index], use_cache ) else: layer_ret = layer( hidden_states, attention_mask, rotary_pos_emb, kv_cache=kv_caches[index], use_cache=use_cache ) hidden_states, kv_cache = layer_ret if use_cache: presents = presents + (kv_cache,) if output_hidden_states: all_hidden_states = all_hidden_states + (hidden_states,) # Final layer norm. if self.post_layer_norm: hidden_states = self.final_layernorm(hidden_states) return hidden_states, presents, all_hidden_states, all_self_attentions ``` ## Embedding ```python class Embedding(torch.nn.Module): """Language model embeddings.""" def __init__(self, config: ChatGLMConfig, device=None): super(Embedding, self).__init__() self.hidden_size = config.hidden_size # Word embeddings (parallel). self.word_embeddings = nn.Embedding( config.padded_vocab_size, self.hidden_size, dtype=config.torch_dtype, device=device ) self.fp32_residual_connection = config.fp32_residual_connection def forward(self, input_ids): # Embeddings. words_embeddings = self.word_embeddings(input_ids) embeddings = words_embeddings # Data format change to avoid explicit tranposes : [b s h] --> [s b h]. embeddings = embeddings.transpose(0, 1).contiguous() # If the input flag for fp32 residual connection is set, convert for float. if self.fp32_residual_connection: embeddings = embeddings.float() return embeddings ``` ## ChatGLMModel ```python class ChatGLMModel(ChatGLMPreTrainedModel): def __init__(self, config: ChatGLMConfig, device=None, empty_init=True): super().__init__(config) if empty_init: init_method = skip_init else: init_method = default_init init_kwargs = {} if device is not None: init_kwargs["device"] = device self.embedding = init_method(Embedding, config, **init_kwargs) self.num_layers = config.num_layers self.multi_query_group_num = config.multi_query_group_num self.kv_channels = config.kv_channels # Rotary positional embeddings self.seq_length = config.seq_length rotary_dim = ( config.hidden_size // config.num_attention_heads if config.kv_channels is None else config.kv_channels ) self.rotary_pos_emb = RotaryEmbedding(rotary_dim // 2, original_impl=config.original_rope, device=device, dtype=config.torch_dtype) self.encoder = init_method(GLMTransformer, config, **init_kwargs) self.output_layer = init_method(nn.Linear, config.hidden_size, config.padded_vocab_size, bias=False, dtype=config.torch_dtype, **init_kwargs) self.pre_seq_len = config.pre_seq_len self.prefix_projection = config.prefix_projection if self.pre_seq_len is not None: for param in self.parameters(): param.requires_grad = False self.prefix_tokens = torch.arange(self.pre_seq_len).long() self.prefix_encoder = PrefixEncoder(config) self.dropout = torch.nn.Dropout(0.1) def get_input_embeddings(self): return self.embedding.word_embeddings def get_prompt(self, batch_size, device, dtype=torch.half): prefix_tokens = self.prefix_tokens.unsqueeze(0).expand(batch_size, -1).to(device) past_key_values = self.prefix_encoder(prefix_tokens).type(dtype) past_key_values = past_key_values.view( batch_size, self.pre_seq_len, self.num_layers * 2, self.multi_query_group_num, self.kv_channels ) # seq_len, b, nh, hidden_size past_key_values = self.dropout(past_key_values) past_key_values = past_key_values.permute([2, 1, 0, 3, 4]).split(2) return past_key_values def forward( self, input_ids, position_ids: Optional[torch.Tensor] = None, attention_mask: Optional[torch.BoolTensor] = None, full_attention_mask: Optional[torch.BoolTensor] = None, past_key_values: Optional[Tuple[Tuple[torch.Tensor, torch.Tensor], ...]] = None, inputs_embeds: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, ): output_hidden_states = ( output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states ) use_cache = use_cache if use_cache is not None else self.config.use_cache return_dict = return_dict if return_dict is not None else self.config.use_return_dict batch_size, seq_length = input_ids.shape if inputs_embeds is None: inputs_embeds = self.embedding(input_ids) if self.pre_seq_len is not None: if past_key_values is None: past_key_values = self.get_prompt(batch_size=batch_size, device=input_ids.device, dtype=inputs_embeds.dtype) if attention_mask is not None: attention_mask = torch.cat([attention_mask.new_ones((batch_size, self.pre_seq_len)), attention_mask], dim=-1) if full_attention_mask is None: if (attention_mask is not None and not attention_mask.all()) or (past_key_values and seq_length != 1): full_attention_mask = self.get_masks(input_ids, past_key_values, padding_mask=attention_mask) # Rotary positional embeddings rotary_pos_emb = self.rotary_pos_emb(self.seq_length) if position_ids is not None: rotary_pos_emb = rotary_pos_emb[position_ids] else: rotary_pos_emb = rotary_pos_emb[None, :seq_length] rotary_pos_emb = rotary_pos_emb.transpose(0, 1).contiguous() # Run encoder. hidden_states, presents, all_hidden_states, all_self_attentions = self.encoder( inputs_embeds, full_attention_mask, rotary_pos_emb=rotary_pos_emb, kv_caches=past_key_values, use_cache=use_cache, output_hidden_states=output_hidden_states ) if not return_dict: return tuple(v for v in [hidden_states, presents, all_hidden_states, all_self_attentions] if v is not None) return BaseModelOutputWithPast( last_hidden_state=hidden_states, past_key_values=presents, hidden_states=all_hidden_states, attentions=all_self_attentions, ) def quantize(self, weight_bit_width: int): from .quantization import quantize quantize(self.encoder, weight_bit_width) return self ``` ## ChatGLMForConditionalGeneration ```python class ChatGLMForConditionalGeneration(ChatGLMPreTrainedModel): def __init__(self, config: ChatGLMConfig, empty_init=True, device=None): super().__init__(config) self.max_sequence_length = config.max_length self.transformer = ChatGLMModel(config, empty_init=empty_init, device=device) self.config = config self.quantized = False if self.config.quantization_bit: self.quantize(self.config.quantization_bit, empty_init=True) def _update_model_kwargs_for_generation( self, outputs: ModelOutput, model_kwargs: Dict[str, Any], is_encoder_decoder: bool = False, standardize_cache_format: bool = False, ) -> Dict[str, Any]: # update past_key_values model_kwargs["past_key_values"] = self._extract_past_from_model_output( outputs, standardize_cache_format=standardize_cache_format ) # update attention mask if "attention_mask" in model_kwargs: attention_mask = model_kwargs["attention_mask"] model_kwargs["attention_mask"] = torch.cat( [attention_mask, attention_mask.new_ones((attention_mask.shape[0], 1))], dim=-1 ) # update position ids if "position_ids" in model_kwargs: position_ids = model_kwargs["position_ids"] new_position_id = position_ids[..., -1:].clone() new_position_id += 1 model_kwargs["position_ids"] = torch.cat( [position_ids, new_position_id], dim=-1 ) model_kwargs["is_first_forward"] = False return model_kwargs def prepare_inputs_for_generation( self, input_ids: torch.LongTensor, past_key_values: Optional[torch.Tensor] = None, attention_mask: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, is_first_forward: bool = True, **kwargs ) -> dict: # only last token for input_ids if past is not None if position_ids is None: position_ids = self.get_position_ids(input_ids, device=input_ids.device) if not is_first_forward: position_ids = position_ids[..., -1:] input_ids = input_ids[:, -1:] return { "input_ids": input_ids, "past_key_values": past_key_values, "position_ids": position_ids, "attention_mask": attention_mask, "return_last_logit": True } def forward( self, input_ids: Optional[torch.Tensor] = None, position_ids: Optional[torch.Tensor] = None, attention_mask: Optional[torch.Tensor] = None, past_key_values: Optional[Tuple[torch.FloatTensor]] = None, inputs_embeds: Optional[torch.Tensor] = None, labels: Optional[torch.Tensor] = None, use_cache: Optional[bool] = None, output_attentions: Optional[bool] = None, output_hidden_states: Optional[bool] = None, return_dict: Optional[bool] = None, return_last_logit: Optional[bool] = False, ): use_cache = use_cache if use_cache is not None else self.config.use_cache return_dict = return_dict if return_dict is not None else self.config.use_return_dict transformer_outputs = self.transformer( input_ids=input_ids, position_ids=position_ids, attention_mask=attention_mask, past_key_values=past_key_values, inputs_embeds=inputs_embeds, use_cache=use_cache, output_hidden_states=output_hidden_states, return_dict=return_dict, ) hidden_states = transformer_outputs[0] if return_last_logit: hidden_states = hidden_states[-1:] lm_logits = self.transformer.output_layer(hidden_states) lm_logits = lm_logits.transpose(0, 1).contiguous() loss = None if labels is not None: lm_logits = lm_logits.to(torch.float32) # Shift so that tokens < n predict n shift_logits = lm_logits[..., :-1, :].contiguous() shift_labels = labels[..., 1:].contiguous() # Flatten the tokens loss_fct = CrossEntropyLoss(ignore_index=-100) loss = loss_fct(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1)) lm_logits = lm_logits.to(hidden_states.dtype) loss = loss.to(hidden_states.dtype) if not return_dict: output = (lm_logits,) + transformer_outputs[1:] return ((loss,) + output) if loss is not None else output return CausalLMOutputWithPast( loss=loss, logits=lm_logits, past_key_values=transformer_outputs.past_key_values, hidden_states=transformer_outputs.hidden_states, attentions=transformer_outputs.attentions, ) @staticmethod def _reorder_cache( past: Tuple[Tuple[torch.Tensor, torch.Tensor], ...], beam_idx: torch.LongTensor ) -> Tuple[Tuple[torch.Tensor, torch.Tensor], ...]: """ This function is used to re-order the `past_key_values` cache if [`~PreTrainedModel.beam_search`] or [`~PreTrainedModel.beam_sample`] is called. This is required to match `past_key_values` with the correct beam_idx at every generation step. Output shares the same memory storage as `past`. """ return tuple( ( layer_past[0].index_select(1, beam_idx.to(layer_past[0].device)), layer_past[1].index_select(1, beam_idx.to(layer_past[1].device)), ) for layer_past in past ) def process_response(self, response): response = response.strip() response = response.replace("[[训练时间]]", "2023年") return response def build_inputs(self, tokenizer, query: str, history: List[Tuple[str, str]] = None): prompt = tokenizer.build_prompt(query, history=history) inputs = tokenizer([prompt], return_tensors="pt") inputs = inputs.to(self.device) return inputs def build_stream_inputs(self, tokenizer, query: str, history: List[Tuple[str, str]] = None): if history: prompt = "\n\n[Round {}]\n\n问:{}\n\n答:".format(len(history) + 1, query) input_ids = tokenizer.encode(prompt, add_special_tokens=False) input_ids = input_ids[1:] inputs = tokenizer.batch_encode_plus([(input_ids, None)], return_tensors="pt", add_special_tokens=False) else: prompt = "[Round {}]\n\n问:{}\n\n答:".format(len(history) + 1, query) inputs = tokenizer([prompt], return_tensors="pt") inputs = inputs.to(self.device) return inputs @torch.inference_mode() def chat(self, tokenizer, query: str, history: List[Tuple[str, str]] = None, max_length: int = 8192, num_beams=1, do_sample=True, top_p=0.8, temperature=0.8, logits_processor=None, **kwargs): if history is None: history = [] if logits_processor is None: logits_processor = LogitsProcessorList() logits_processor.append(InvalidScoreLogitsProcessor()) gen_kwargs = {"max_length": max_length, "num_beams": num_beams, "do_sample": do_sample, "top_p": top_p, "temperature": temperature, "logits_processor": logits_processor, **kwargs} inputs = self.build_inputs(tokenizer, query, history=history) outputs = self.generate(**inputs, **gen_kwargs) outputs = outputs.tolist()[0][len(inputs["input_ids"][0]):] response = tokenizer.decode(outputs) response = self.process_response(response) history = history + [(query, response)] return response, history @torch.inference_mode() def stream_chat(self, tokenizer, query: str, history: List[Tuple[str, str]] = None, past_key_values=None, max_length: int = 8192, do_sample=True, top_p=0.8, temperature=0.8, logits_processor=None, return_past_key_values=False, **kwargs): if history is None: history = [] if logits_processor is None: logits_processor = LogitsProcessorList() logits_processor.append(InvalidScoreLogitsProcessor()) gen_kwargs = {"max_length": max_length, "do_sample": do_sample, "top_p": top_p, "temperature": temperature, "logits_processor": logits_processor, **kwargs} if past_key_values is None and not return_past_key_values: inputs = self.build_inputs(tokenizer, query, history=history) else: inputs = self.build_stream_inputs(tokenizer, query, history=history) if past_key_values is not None: past_length = past_key_values[0][0].shape[0] if self.transformer.pre_seq_len is not None: past_length -= self.transformer.pre_seq_len inputs.position_ids += past_length attention_mask = inputs.attention_mask attention_mask = torch.cat((attention_mask.new_ones(1, past_length), attention_mask), dim=1) inputs['attention_mask'] = attention_mask for outputs in self.stream_generate(**inputs, past_key_values=past_key_values, return_past_key_values=return_past_key_values, **gen_kwargs): if return_past_key_values: outputs, past_key_values = outputs outputs = outputs.tolist()[0][len(inputs["input_ids"][0]):] response = tokenizer.decode(outputs) if response and response[-1] != "�": response = self.process_response(response) new_history = history + [(query, response)] if return_past_key_values: yield response, new_history, past_key_values else: yield response, new_history @torch.inference_mode() def stream_generate( self, input_ids, generation_config: Optional[GenerationConfig] = None, logits_processor: Optional[LogitsProcessorList] = None, stopping_criteria: Optional[StoppingCriteriaList] = None, prefix_allowed_tokens_fn: Optional[Callable[[int, torch.Tensor], List[int]]] = None, return_past_key_values=False, **kwargs, ): batch_size, input_ids_seq_length = input_ids.shape[0], input_ids.shape[-1] if generation_config is None: generation_config = self.generation_config generation_config = copy.deepcopy(generation_config) model_kwargs = generation_config.update(**kwargs) bos_token_id, eos_token_id = generation_config.bos_token_id, generation_config.eos_token_id if isinstance(eos_token_id, int): eos_token_id = [eos_token_id] has_default_max_length = kwargs.get("max_length") is None and generation_config.max_length is not None if has_default_max_length and generation_config.max_new_tokens is None: warnings.warn( f"Using `max_length`'s default ({generation_config.max_length}) to control the generation length. " "This behaviour is deprecated and will be removed from the config in v5 of Transformers -- we" " recommend using `max_new_tokens` to control the maximum length of the generation.", UserWarning, ) elif generation_config.max_new_tokens is not None: generation_config.max_length = generation_config.max_new_tokens + input_ids_seq_length if not has_default_max_length: logger.warn( f"Both `max_new_tokens` (={generation_config.max_new_tokens}) and `max_length`(=" f"{generation_config.max_length}) seem to have been set. `max_new_tokens` will take precedence. " "Please refer to the documentation for more information. " "(https://huggingface.co/docs/transformers/main/en/main_classes/text_generation)", UserWarning, ) if input_ids_seq_length >= generation_config.max_length: input_ids_string = "decoder_input_ids" if self.config.is_encoder_decoder else "input_ids" logger.warning( f"Input length of {input_ids_string} is {input_ids_seq_length}, but `max_length` is set to" f" {generation_config.max_length}. This can lead to unexpected behavior. You should consider" " increasing `max_new_tokens`." ) # 2. Set generation parameters if not already defined logits_processor = logits_processor if logits_processor is not None else LogitsProcessorList() stopping_criteria = stopping_criteria if stopping_criteria is not None else StoppingCriteriaList() logits_processor = self._get_logits_processor( generation_config=generation_config, input_ids_seq_length=input_ids_seq_length, encoder_input_ids=input_ids, prefix_allowed_tokens_fn=prefix_allowed_tokens_fn, logits_processor=logits_processor, ) stopping_criteria = self._get_stopping_criteria( generation_config=generation_config, stopping_criteria=stopping_criteria ) logits_warper = self._get_logits_warper(generation_config) unfinished_sequences = input_ids.new(input_ids.shape[0]).fill_(1) scores = None while True: model_inputs = self.prepare_inputs_for_generation(input_ids, **model_kwargs) # forward pass to get next token outputs = self( **model_inputs, return_dict=True, output_attentions=False, output_hidden_states=False, ) next_token_logits = outputs.logits[:, -1, :] # pre-process distribution next_token_scores = logits_processor(input_ids, next_token_logits) next_token_scores = logits_warper(input_ids, next_token_scores) # sample probs = nn.functional.softmax(next_token_scores, dim=-1) if generation_config.do_sample: next_tokens = torch.multinomial(probs, num_samples=1).squeeze(1) else: next_tokens = torch.argmax(probs, dim=-1) # update generated ids, model inputs, and length for next step input_ids = torch.cat([input_ids, next_tokens[:, None]], dim=-1) model_kwargs = self._update_model_kwargs_for_generation( outputs, model_kwargs, is_encoder_decoder=self.config.is_encoder_decoder ) unfinished_sequences = unfinished_sequences.mul((sum(next_tokens != i for i in eos_token_id)).long()) if return_past_key_values: yield input_ids, outputs.past_key_values else: yield input_ids # stop when each sentence is finished, or if we exceed the maximum length if unfinished_sequences.max() == 0 or stopping_criteria(input_ids, scores): break def quantize(self, bits: int, empty_init=False, device=None, **kwargs): if bits == 0: return from .quantization import quantize if self.quantized: logger.info("Already quantized.") return self self.quantized = True self.config.quantization_bit = bits self.transformer.encoder = quantize(self.transformer.encoder, bits, empty_init=empty_init, device=device, **kwargs) return self ``` ================================================ FILE: llm-algo/chatglm3/README.md ================================================ ================================================ FILE: llm-algo/chatglm3/reference.md ================================================ ================================================ FILE: llm-algo/chatgpt/README.md ================================================ - ChatGPT技术原理解析:从RL之PPO算法、RLHF到GPT4、instructGPT: https://blog.csdn.net/v_JULY_v/article/details/128579457 ================================================ FILE: llm-algo/deepseek/DeepSeek-R1.md ================================================ ## 复现 - https://github.com/huggingface/open-r1 ## 量化 - AWQ:https://modelscope.cn/models/cognitivecomputations/DeepSeek-R1-awq - AWQ:https://huggingface.co/cognitivecomputations/DeepSeek-R1-AWQ - FP4:https://modelscope.cn/models/nvidia/DeepSeek-R1-FP4 - https://github.com/nbasyl/LLM-FP4 https://huggingface.co/dwetzel/DeepSeek-R1-Distill-Qwen-32B-GPTQ-INT4 ### sglang https://github.com/sgl-project/sglang/issues/2706 - sglang 对 deepseek r1 性能测试: https://github.com/sgl-project/sglang/issues/3956 ### vllm https://huggingface.co/cognitivecomputations/DeepSeek-R1-AWQ/discussions ## hf transformers - https://github.com/huggingface/transformers/blob/main/docs/source/en/quantization/finegrained_fp8.md ================================================ FILE: llm-algo/deepseek/DeepSeek-V2.md ================================================ # DeepSeek-V2 Deepseek-V2技术详解: https://zhuanlan.zhihu.com/p/697524307 ================================================ FILE: llm-algo/deepseek/DeepSeek-V3.md ================================================ ## mtp https://zhuanlan.zhihu.com/p/18056041194 DeepSeek-V3 Technical Report: https://arxiv.org/pdf/2412.19437 Better & faster large language models via multi-token prediction:https://arxiv.org/pdf/2404.19737 具体来说,在训练阶段,一次生成多个后续token,可以一次学习多个位置的label,进而有效提升样本的利用效率,提升训练速度;在推理阶段通过一次生成多个token,实现成倍的推理加速来提升推理性能。 ================================================ FILE: llm-algo/deepseek/README.md ================================================ - DeepSeek-V3:https://arxiv.org/pdf/2412.19437v1 - https://github.com/deepseek-ai/DeepSeek-V3 - DeepSeekMath(GRPO):https://arxiv.org/pdf/2402.03300 - DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning: https://arxiv.org/pdf/2501.12948 - DeepSeek-R1训练数据准备方案:https://zhuanlan.zhihu.com/p/20763180629 - 详细介绍:https://planetbanatt.net/articles/deepseek.html - DeepSeek-R1: Model Architecture: https://pub.towardsai.net/deepseek-r1-model-architecture-853fefac7050 - Run DeepSeek R1 Dynamic 1.58-bit: https://unsloth.ai/blog/deepseekr1-dynamic - Insights into DeepSeek-V3: Scaling Challenges and Reflections on Hardware for AI Architectures:https://arxiv.org/pdf/2505.09343 ================================================ FILE: llm-algo/glm-130b/README.md ================================================ - 预训练语言模型:GLM: https://zhuanlan.zhihu.com/p/641499380 GLM-130B 对超过 4000 亿个双语标记(2000 亿英文和 2000 亿中文标记)进行了预训练。 它的预训练目标由两部分组成: 第一部分(95%)是自监督的预训练,即在公开的大规模语料库以及其他一些较小的中文语料库上的自回归空白填充。 第二部分(5%)是在 T0++18 和 DeepStruct19 中 70 个不同数据集的抽样子集上进行多任务指令预训练,格式为基于指令的多任务多提示序列到序列的生成。 这种设计使 GLM-130B 可以在其他数据集上进行了零样本学习,以及从英文到中文的零样本迁移。 ================================================ FILE: llm-algo/glm4.md ================================================ ================================================ FILE: llm-algo/gpt/README.md ================================================ - OpenAI ChatGPT(二):十分钟读懂 GPT-1:https://zhuanlan.zhihu.com/p/604625917 - GPT(二)GPT1原理和代码详解: https://zhuanlan.zhihu.com/p/636915538 ================================================ FILE: llm-algo/gpt2/README.md ================================================ - GPT2 源码:https://github.com/huggingface/transformers/blob/main/src/transformers/models/gpt2/modeling_gpt2.py - GPT2 源码解析:https://zhuanlan.zhihu.com/p/630970209 - nanoGPT:https://github.com/karpathy/nanoGPT/blob/master/model.py - 7.3 GPT2模型深度解析:http://121.199.45.168:13013/7_3.html - GPT(三)GPT2原理和代码详解: https://zhuanlan.zhihu.com/p/637782385 - OpenAI ChatGPT(三):十分钟读懂 GPT-2: https://zhuanlan.zhihu.com/p/613895056 - OpenAI ChatGPT(三):Tensorflow实现GPT-2: https://zhuanlan.zhihu.com/p/614003576 - GPT2参数量剖析: https://zhuanlan.zhihu.com/p/640501114 ================================================ FILE: llm-algo/gpt2/hf_modeling_gpt2.py ================================================ # https://github.com/huggingface/transformers/blob/main/src/transformers/models/gpt2/modeling_gpt2.py class GPT2Attention(nn.Module): def __init__(self, config, is_cross_attention=False, layer_idx=None): super().__init__() self.config = config max_positions = config.max_position_embeddings self.register_buffer( "bias", torch.tril(torch.ones((max_positions, max_positions), dtype=torch.bool)).view( 1, 1, max_positions, max_positions ), persistent=False, ) self.register_buffer("masked_bias", torch.tensor(-1e4), persistent=False) self.embed_dim = config.hidden_size self.num_heads = config.num_attention_heads self.head_dim = self.embed_dim // self.num_heads self.split_size = self.embed_dim if self.head_dim * self.num_heads != self.embed_dim: raise ValueError( f"`embed_dim` must be divisible by num_heads (got `embed_dim`: {self.embed_dim} and `num_heads`:" f" {self.num_heads})." ) self.scale_attn_weights = config.scale_attn_weights self.is_cross_attention = is_cross_attention # Layer-wise attention scaling, reordering, and upcasting self.scale_attn_by_inverse_layer_idx = config.scale_attn_by_inverse_layer_idx self.layer_idx = layer_idx self.reorder_and_upcast_attn = config.reorder_and_upcast_attn if self.is_cross_attention: self.c_attn = Conv1D(2 * self.embed_dim, self.embed_dim) self.q_attn = Conv1D(self.embed_dim, self.embed_dim) else: self.c_attn = Conv1D(3 * self.embed_dim, self.embed_dim) self.c_proj = Conv1D(self.embed_dim, self.embed_dim) self.attn_dropout = nn.Dropout(config.attn_pdrop) self.resid_dropout = nn.Dropout(config.resid_pdrop) self.is_causal = True self.pruned_heads = set() # 计算注意力 def _attn(self, query, key, value, attention_mask=None, head_mask=None): # 第一步:Q * K^T attn_weights = torch.matmul(query, key.transpose(-1, -2)) if self.scale_attn_weights: attn_weights = attn_weights / torch.full( [], value.size(-1) ** 0.5, dtype=attn_weights.dtype, device=attn_weights.device ) # Layer-wise attention scaling if self.scale_attn_by_inverse_layer_idx: attn_weights = attn_weights / float(self.layer_idx + 1) if not self.is_cross_attention: # if only "normal" attention layer implements causal mask query_length, key_length = query.size(-2), key.size(-2) causal_mask = self.bias[:, :, key_length - query_length : key_length, :key_length] mask_value = torch.finfo(attn_weights.dtype).min # Need to be a tensor, otherwise we get error: `RuntimeError: expected scalar type float but found double`. # Need to be on the same device, otherwise `RuntimeError: ..., x and y to be on the same device` mask_value = torch.full([], mask_value, dtype=attn_weights.dtype, device=attn_weights.device) attn_weights = torch.where(causal_mask, attn_weights.to(attn_weights.dtype), mask_value) # 掩码 Attention if attention_mask is not None: # Apply the attention mask attn_weights = attn_weights + attention_mask # 第二步 attn_weights = nn.functional.softmax(attn_weights, dim=-1) # Downcast (if necessary) back to V's dtype (if in mixed-precision) -- No-Op otherwise attn_weights = attn_weights.type(value.dtype) # 第三步 attn_weights = self.attn_dropout(attn_weights) # 掩码 Head # Mask heads if we want to if head_mask is not None: attn_weights = attn_weights * head_mask # 第四步 attn_output = torch.matmul(attn_weights, value) return attn_output, attn_weights def forward( self, hidden_states: Optional[Tuple[torch.FloatTensor]], layer_past: Optional[Tuple[torch.Tensor]] = None, attention_mask: Optional[torch.FloatTensor] = None, head_mask: Optional[torch.FloatTensor] = None, encoder_hidden_states: Optional[torch.Tensor] = None, encoder_attention_mask: Optional[torch.FloatTensor] = None, use_cache: Optional[bool] = False, output_attentions: Optional[bool] = False, ) -> Tuple[Union[torch.Tensor, Tuple[torch.Tensor]], ...]: if encoder_hidden_states is not None: if not hasattr(self, "q_attn"): raise ValueError( "If class is used as cross attention, the weights `q_attn` have to be defined. " "Please make sure to instantiate class with `GPT2Attention(..., is_cross_attention=True)`." ) query = self.q_attn(hidden_states) key, value = self.c_attn(encoder_hidden_states).split(self.split_size, dim=2) attention_mask = encoder_attention_mask else: query, key, value = self.c_attn(hidden_states).split(self.split_size, dim=2) query = self._split_heads(query, self.num_heads, self.head_dim) key = self._split_heads(key, self.num_heads, self.head_dim) value = self._split_heads(value, self.num_heads, self.head_dim) if layer_past is not None: past_key, past_value = layer_past key = torch.cat((past_key, key), dim=-2) value = torch.cat((past_value, value), dim=-2) if use_cache is True: present = (key, value) else: present = None if self.reorder_and_upcast_attn: attn_output, attn_weights = self._upcast_and_reordered_attn(query, key, value, attention_mask, head_mask) else: # 计算注意力 attn_output, attn_weights = self._attn(query, key, value, attention_mask, head_mask) # 合并多头注意力输出 attn_output = self._merge_heads(attn_output, self.num_heads, self.head_dim) attn_output = self.c_proj(attn_output) # 残差连接 attn_output = self.resid_dropout(attn_output) outputs = (attn_output, present) if output_attentions: outputs += (attn_weights,) return outputs # a, present, (attentions) class GPT2MLP(nn.Module): def __init__(self, intermediate_size, config): super().__init__() embed_dim = config.hidden_size self.c_fc = Conv1D(intermediate_size, embed_dim) self.c_proj = Conv1D(embed_dim, intermediate_size) self.act = ACT2FN[config.activation_function] # 激活 self.dropout = nn.Dropout(config.resid_pdrop) def forward(self, hidden_states: Optional[Tuple[torch.FloatTensor]]) -> torch.FloatTensor: hidden_states = self.c_fc(hidden_states) hidden_states = self.act(hidden_states) hidden_states = self.c_proj(hidden_states) hidden_states = self.dropout(hidden_states) return hidden_states ================================================ FILE: llm-algo/gpt2/模型架构.md ================================================ ## GPT2LMHeadModel ## GPT2PreTrainedModel ## GPT2Model ## GPT2Attention ## GPT2Block ================================================ FILE: llm-algo/gpt3/README.md ================================================ GPT(五)GPT3原理讲解:https://zhuanlan.zhihu.com/p/642745932 ================================================ FILE: llm-algo/llama/README.md ================================================ ## 模型 ### llama3 - Build Your Own Llama 3 Architecture from Scratch Using PyTorch:https://pub.towardsai.net/build-your-own-llama-3-architecture-from-scratch-using-pytorch-2ce1ecaa901c - Decoding Llama3 microblogs series:https://hasgeek.com/simrathanspal/the-llama3-guide/sub/decoding-llama3-part-1-intro-to-llama3-RCehJkfUH348ryim1x6PLN#h:up-next-part-2-understanding-the-configuration - Part 1 - Intro to Llama3 - Part 2 - Understanding the configuration - Part 3 - Normalisation - Part 4 - Rotary Positional Embeddings - Part 5 - Grouped Query Attention - Part 6 - Feed Forward Network - Part 7 - Transformer Block - https://medium.com/data-science/deep-dive-into-self-attention-by-hand-%EF%B8%8E-f02876e49857 - https://medium.com/data-science/deep-dive-into-llama-3-by-hand-%EF%B8%8F-6c6b23dc92b2 - (不错)https://docs.nvidia.com/deeplearning/transformer-engine/user-guide/examples/te_llama/tutorial_accelerate_hf_llama_with_te.html ================================================ FILE: llm-algo/llama/模型架构.md ================================================ ## LlamaAttention(nn.Module) ## LlamaMLP(nn.Module) ================================================ FILE: llm-algo/llama.md ================================================ - https://github.com/huggingface/transformers/blob/main/src/transformers/models/llama/modeling_llama.py - http://lihuaxi.xjx100.cn/news/1377523.html ``` LlamaRotaryEmbedding LlamaMLP LlamaAttention:多头注意力 LlamaDecoderLayer LlamaPreTrainedModel LlamaModel(LlamaPreTrainedModel) LlamaForCausalLM(LlamaPreTrainedModel) ``` ================================================ FILE: llm-algo/mixtral/README.md ================================================ - 8 x 7b: https://www.promptingguide.ai/models/mixtral - https://www.promptingguide.ai/models/mixtral-8x22b ================================================ FILE: llm-algo/mlp.md ================================================ 1. MLP的基本原理 MLP是一种由多个神经元组成的前馈神经网络模型。每个神经元接收来自上一层神经元的输出,并通过激活函数进行非线性变换,然后将结果传递给下一层神经元。 这种前馈传播的方式使得MLP能够处理复杂的非线性关系。 3. MLP的结构 MLP由输入层、隐藏层和输出层组成。输入层接收外部输入数据,隐藏层对输入数据进行中间表示的学习,输出层生成最终的预测结果。每个神经元与上一层的所有神经元相连,权重和偏置用于调整信号传递过程中的参数。 4. MLP的训练 MLP的训练目标是通过优化算法,使得模型的输出尽可能地接近真实值。为了达到这个目标,需要定义一个损失函数来度量预测结果和真实值之间的差距。常用的损失函数包括均方误差(Mean Squared Error)和交叉熵(Cross Entropy)。反向传播算法是一种常用的优化方法,通过计算梯度并更新权重和偏置来最小化损失函数。 ================================================ FILE: llm-algo/moe/README.md ================================================ https://www.promptingguide.ai/models/mixtral ================================================ FILE: llm-algo/qwen/README.md ================================================ ## qwen ``` git clone https://www.modelscope.cn/qwen/Qwen-7B-Chat.git ``` ## Qwen1.5 Qwen1.5版本本次开源了包括0.5B、1.8B、4B、7B、14B和72B在内的六种大小的基础和聊天模型,同时,也开源了量化模型。不仅提供了Int4和Int8的GPTQ模型,还有AWQ模型,以及GGUF量化模型。 为了提升开发者体验,Qwen1.5的代码合并到Hugging Face Transformers中,开发者现在可以直接使用transformers>=4.37.0而无需trust_remote_code。 此外,Qwen1.5支持了例如vLLM、SGLang、AutoGPTQ等框架对Qwen1.5的支持。 Qwen1.5显著提升了聊天模型与人类偏好的一致性,并且改善了它们的多语言能力。所有模型提供了统一的上下文长度支持,支持32K上下文, 基础语言模型的质量也有所改进。 ## 模型 ``` git clone https://www.modelscope.cn/qwen/Qwen1.5-0.5B.git git clone https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct ``` ## 代码 - https://github.com/huggingface/transformers/blob/main/src/transformers/models/qwen2/modeling_qwen2.py ## 模型结构 https://blog.csdn.net/fan_fan_feng/article/details/138978901 ================================================ FILE: llm-algo/qwen/参数说明及函数说明.md ================================================ - 详细解释:https://kimi.moonshot.cn/chat/cvll5lp3om1s14tgq990 initializer_range: ``` initializer_range是一个参数,用于指定初始化权重矩阵时使用的 truncated_normal_initializer 的标准差。它的默认值是 0.02,并且是一个可选的浮点数(float)。 默认值为 0.02,这意味着初始化权重时,权重值会从一个均值为 0、标准差为 0.02 的截断正态分布中采样。 截断正态分布可以避免权重值过大或过小,从而帮助模型更快地收敛。它是一种常见的初始化方法,尤其是在深度学习中。 ``` rms_norm_eps: ``` rms_norm_eps 是一个参数,用于 RMSNorm(Root Mean Square Normalization)层中的数值稳定化。它的默认值是 1e-06,并且是一个可选的浮点数(float)。 RMSNorm 是一种归一化方法,用于稳定神经网络的训练过程。 它通过计算输入的均方根(Root Mean Square, RMS)值来调整输入的尺度。 ``` ================================================ FILE: llm-algo/qwen2.md ================================================ - https://qwenlm.github.io/zh/blog/qwen2/ ================================================ FILE: llm-algo/t5/README.md ================================================ - https://github.com/ZhuiyiTechnology/t5-pegasus - https://github.com/renmada/t5-pegasus-pytorch - T5 PEGASUS:开源一个中文生成式预训练模型: https://zhuanlan.zhihu.com/p/359509608 ## LCSTS_new - LCSTS_new中文短摘要生成数据集:https://www.luge.ai/#/luge/dataDetail?id=10 生成式短摘要数据集,以微博原文为输入,1~2句话的短摘要为输出 LCSTS_new是中文短摘要最常用的LCSTS短摘要数据集的升级版本,在数据量、质量方面均有显著提升,在信息摘要与提炼的过程中,与原文的事实一致性需要得到重点关注。 ``` { "id": 6, "summary": "中国游客大增多国放宽签证", "content": "①北京和上海户籍的游客可获得韩国多次签证;②“整容客”可以不经由韩国使领馆、直接在网上申请签证;③中泰免签的实施日期尚未敲定;④越南已向中国持通行证旅游的公民全面开放。" } ``` ## AdvertiseGen - AdvertiseGen广告文案生成数据集: https://www.luge.ai/#/luge/dataDetail?id=9 ``` { "content": "类型#上衣*材质#牛仔布*颜色#白色*风格#简约*图案#刺绣*衣样式#外套*衣款式#破洞", "summary": "简约而不简单的牛仔外套,白色的衣身十分百搭。衣身多处有做旧破洞设计,打破单调乏味,增加一丝造型看点。衣身后背处有趣味刺绣装饰,丰富层次感,彰显别样时尚。" } ``` ================================================ FILE: llm-algo/transformer/README.md ================================================ 阐述了FFN层的几个问题, 第一,是FFN层参数量巨大,大概占了整个模型参数量的三分之二左右。 第二,FFN层的激活存在较大的稀疏性,也就是针对某些问题的输入,FFN层只有部分的参数是有用的。 ================================================ FILE: llm-algo/transformer/Transformer中FFN的记忆功能.md ================================================ Transformer中FFN的记忆功能: https://zhuanlan.zhihu.com/p/604739354 大型语言模型的强大能力离不开其对知识的记忆:比如模型想要回答“中国的首都是哪座城市?”,就必须在某种意义上记住“中国的首都是北京”。 Transformer并没有外接显式的数据库,记忆只能隐式地表达在参数当中。 与attention相比不那么引人注意的FFN承担了transformer中记忆的功能。 --- Transformer Feed-Forward Layers Are Key-Value Memories --- Knowledge Neurons in Pretrained Transformers 梯度大意味着该神经元对输出答案的影响大 定位知识神经元以后就可以对相关神经元进行操作。如下图所示,将知识神经元的激活置0或翻倍可以有效抑制或增强相关知识的表达。在具体操作上,应避开同种关系共用的神经元,以减小对其他事实的影响。 --- Transformer Feed-Forward Layers Are Key-Value Memories一文指出了FFN的记忆作用, Knowledge Neurons in Pretrained Transformers一文给出了操作知识神经元的应用方式。这些工作对于去除现有语言模型的错误知识,或将新知识注入现有语言模型可能带来帮助。 --- 每一层经过attention之后,还会有一个FFN,这个FFN的作用就是空间变换。FFN包含了2层linear transformation层,中间的激活函数是ReLu。 FFN的加入引入了非线性(ReLu激活函数),变换了attention output的空间, 从而增加了模型的表现能力。把FFN去掉模型也是可以用的,但是效果差了很多。 ================================================ FILE: llm-algo/transformer/模型架构.md ================================================ ## 绝对位置编码 pytorch: https://github.com/harvardnlp/annotated-transformer/blob/master/AnnotatedTransformer.ipynb ``` class PositionalEncoding(nn.Module): "Implement the PE function." def __init__(self, d_model, dropout, max_len=5000): super(PositionalEncoding, self).__init__() self.dropout = nn.Dropout(p=dropout) # Compute the positional encodings once in log space. pe = torch.zeros(max_len, d_model) position = torch.arange(0, max_len).unsqueeze(1) div_term = torch.exp( torch.arange(0, d_model, 2) * -(math.log(10000.0) / d_model) ) pe[:, 0::2] = torch.sin(position * div_term) pe[:, 1::2] = torch.cos(position * div_term) pe = pe.unsqueeze(0) self.register_buffer("pe", pe) def forward(self, x): x = x + self.pe[:, : x.size(1)].requires_grad_(False) return self.dropout(x) ``` tensorflow: ``` def get_angles(pos, i, d_model): # 这里的i等价与上面公式中的2i和2i+1 angle_rates = 1 / np.power(10000, (2*(i // 2))/ np.float32(d_model)) return pos * angle_rates def positional_encoding(position, d_model): angle_rads = get_angles(np.arange(position)[:, np.newaxis], np.arange(d_model)[np.newaxis,:], d_model) # 第2i项使用sin sines = np.sin(angle_rads[:, 0::2]) # 第2i+1项使用cos cones = np.cos(angle_rads[:, 1::2]) pos_encoding = np.concatenate([sines, cones], axis=-1) pos_encoding = pos_encoding[np.newaxis, ...] return tf.cast(pos_encoding, dtype=tf.float32) ``` ================================================ FILE: llm-algo/transformer.md ================================================ 原理: - [x] Transformer模型详解(图解最完整版):https://zhuanlan.zhihu.com/p/338817680 - [x] OpenAI ChatGPT(一):十分钟读懂 Transformer:https://zhuanlan.zhihu.com/p/600773858 源码: - OpenAI ChatGPT(一):Tensorflow实现Transformer:https://zhuanlan.zhihu.com/p/603243890 - OpenAI ChatGPT(一):十分钟读懂 Transformer: https://zhuanlan.zhihu.com/p/600773858 - GPT (一)transformer原理和代码详解:https://zhuanlan.zhihu.com/p/632880248 - Transformer源码详解(Pytorch版本):https://zhuanlan.zhihu.com/p/398039366 - 搞懂Transformer结构,看这篇PyTorch实现就够了: https://zhuanlan.zhihu.com/p/339207092 - 哈佛annotated-transformer:https://github.com/harvardnlp/annotated-transformer/blob/master/AnnotatedTransformer.ipynb Transformer是编码器-解码器架构的一个实践,尽管在实际情况中编码器或解码器可以单独使用。 在Transformer中,多头自注意力用于表示输入序列和输出序列,不过解码器必须通过掩蔽机制来保留自回归属性。 Transformer中的残差连接和层规范化是训练非常深度模型的重要工具。 Transformer模型中基于位置的前馈网络使用同一个多层感知机,作用是对所有序列位置的表示进行转换。 --- Add & Norm 层,Add 表示残差连接 (Residual Connection) 用于防止网络退化,Norm 表示 Layer Normalization,用于对每一层的激活值进行归一化。 ## Transformer的输入表示 Transformer 中除了单词的Embedding,还需要使用位置Embedding 表示单词出现在句子中的位置。因为 Transformer不采用RNN结构,而是使用全局信息,不能利用单词的顺序信息,而这部分信息对于NLP来说非常重要。所以Transformer中使用位置Embedding保存单词在序列中的相对或绝对位置。 位置Embedding用 PE 表示, PE 的维度与单词Embedding相同。 PE 可以通过训练得到,也可以使用某种公式计算得到。在Transformer中采用了后者。 - Overview: The Implemented Transformer: https://medium.com/@hunter-j-phillips/overview-the-implemented-transformer-eafd87fe9589 - Multi-Head Attention: https://medium.com/@hunter-j-phillips/multi-head-attention-7924371d477a - Layer Normalization: https://medium.com/@hunter-j-phillips/layer-normalization-e9ae93eb3c9c - Positional Encoding: https://medium.com/@hunter-j-phillips/positional-encoding-7a93db4109e6 ================================================ FILE: llm-algo/基本概念.md ================================================ ## 激活函数 ReLU GeLU SwiGLU(Yi) ## 位置编码 RoPE ## 优化器 Adam AdamW OneBitAdam Lamb OneBitLamb ================================================ FILE: llm-algo/旋转编码RoPE.md ================================================ - 十分钟读懂旋转编码(RoPE): https://zhuanlan.zhihu.com/p/647109286 旋转位置编码(Rotary Position Embedding,RoPE): 一种能够将相对位置信息依赖集成到 self-attention 中并提升 transformer 架构性能的位置编码方式。 和相对位置编码相比,RoPE 具有更好的外推性,目前是大模型相对位置编码中应用最广的方式之一。 什么是大模型外推性?外推性是指大模型在训练时和预测时的输入长度不一致,导致模型的泛化能力下降的问题。例如,如果一个模型在训练时只使用了512个 token 的文本,那么在预测时如果输入超过512个 token,模型可能无法正确处理。这就限制了大模型在处理长文本或多轮对话等任务时的效果。 基于 transformer 的位置编码方法都是着重于构造一个合适的 f(q,k,v) 函数形式。 旋转编码 RoPE 可以有效地保持位置信息的相对关系,即相邻位置的编码之间有一定的相似性,而远离位置的编码之间有一定的差异性。这样可以增强模型对位置信息的感知和利用。这一点是其他绝对位置编码方式(如正弦位置编码、学习的位置编码等)所不具备的,因为它们只能表示绝对位置,而不能表示相对位置。 旋转编码 RoPE 可以通过旋转矩阵来实现位置编码的外推,即可以通过旋转矩阵来生成超过预训练长度的位置编码。这样可以提高模型的泛化能力和鲁棒性。这一点是其他固定位置编码方式(如正弦位置编码、固定相对位置编码等)所不具备的,因为它们只能表示预训练长度内的位置,而不能表示超过预训练长度的位置。 旋转编码 RoPE 可以与线性注意力机制兼容,即不需要额外的计算或参数来实现相对位置编码。 这样可以降低模型的计算复杂度和内存消耗。这一点是其他混合位置编码方式(如Transformer-XL、XLNet等)所不具备的,因为它们需要额外的计算或参数来实现相对位置编码。 ================================================ FILE: llm-algo/模型架构类图.drawio ================================================ 7Vxtc9o4EP41mcl9SMYv2MDHAE16Le3RJtf2+oVRbAFKZIuTRYD8+lv5DdsyYJoYcpSZTMZaryV7n2fXu2slZ2bXW9xwNJ18Yi6mZ4bmLs7M3plhtBs2/JaCZSSwNT0SjDlxI1FGcEuecSzUYumMuDjIKQrGqCDTvNBhvo8dkZMhztk8rzZiNL/qFI2xIrh1EFWl34krJpG0ZTRX8veYjCfJyrrdjs54KFGOnySYIJfNMyLz3ZnZ5YyJ6MhbdDGVtkvs8v3P5Xfaf7RvPnwJ/kV/dz7eff52EU12vcsl6SNw7Itfnvr5cXT9/lvj4cd0cP1lrt1c3X+4iC/RnhCdxfa6GdwZ/U/vMXJDKpzL8YDjO46IjyPZH7E9xDIxcjAnHkU+jDoj5ovb+AyYqIMoGftw7MC9Yw6CJ8wFAXyu4hOCTUHqTAh1+2jJZvIJA4Gcx2TUmTBOnmFaROGUDgI4zUVMNcPOadzKK0GsgZTjAHQGidn0VNRHgYh1HEYpmgbkPrxhqeIhPiZ+hwnBvGQiNvNd7MajlAfhQHD2mDJLXl8RrBhUaQ28yFA1Bu8GMw8LvgSV+Gwrxir2Qz2h5XzF6lRnkmW0GQtR7EnjdOp0ta/gecgfgw3S5XR7+3qpTnY9w84vhyjg7iOBO9KKQZajcJB50pUoZO4OLNYVFguO/GDEuAeUgxuXMk0yOQ5vBfoCAiJDVYpHYi1RgylyiD/uhzq9xkryNTaBFDG4dkRDkkyI62I/JJFAAkU8k8yZMuKL0EZWB37Akl3t0jqz4Ia6MNZXY/iR6lx0mQ98A0eU62Ag8RxLIpdQbqOzb6fcMg/lNooVIc8yLIf1rsAaCrDUG04gNqWg+v5lHwIT4kcH6oagMxEejQ/rgt4yDgx9Q4FeQZiS8I0TW0MvjcZb4PcASDldgvedpEPvQlc4YaqcMEvwp+ge0wELiCBMzs8j3QIvDuXPzVY1UFs1YWopmEKIniPuHp3z1oVgq2pEbtQEoV2aMF4JAQ8KlD+HeAzv2BnFlZNE7ZQk1pYkWnbVJFH/tSTRzK9ntt5ukthUmHt5efm7Bh67MrHeSirYPuUDrw5q1SSvrnxAV9sPx5oQZN94jbrwrBrta3NS3SxNDzqUOY+n1OCwqYFlFN7VVglb2mW5gb0hmVyfG5iNCrlB823kBrpabQaYji6REH6uf5QmukcXoCrGpNTDX5Q5lNHsNYLSbaB1tb/ET2e8uPu4vHn6+TB8uGiVY0v9oZ5rI6El5p8Z944UWgWxymjvlD/sFVpd7fwm2BonbF+EbVmvaK/YGmq3KMTWo9NcSP7UH5xQrYqqrjX2B2v5DaqwKvD97oXc7i/ZtBGzDddXKOXKI7H6qeZYS7n6nNPcY8wtv0G1Sbb+q+mpaNt/0Vb61b+0aEuqr92KNssqrNcoKdreSENXX5PYT7KZX9Rx6JNAnIObp80I8HK1C3EcgWl7FGpWZuEBSrjyW1a7v0meP/o98vxX3Q2wOwP2WemV7wRRO4untPHFsFYt8ur6AGCofbfjzhprwLBsS8B+XVPdE6Cgh333Sm7mhRGbhqbeklDl4x1cfk1o4tXYHeMk2wSLT9iY+Yi+W0k7mN6Hcyf0kKIFET+SCeD4Hzk1YBeNeotkJTlYpsuCfX5kB9FVejJcXRaOctcNMCdgYJn+ronNm1LEgM24gzcRJdKDpHiMqxBKGq1Kxiltks0AG/FCHFMkyFN2jo3J5UC6zmpas7h9tW3kp4geOL5qxUhlIsvWCxMVEt3IItsnuih+nyjcEBuNApybAhiMlhmNODqsfeZGs/DMVnvjHSn6ZqPgnNEd/GoWXVq4W6qvbnWvvHOudPosfF1K93jAQizjag3NBMu/l1/mjJFi6o5bnLGU/q/piK2qnrim+n+hZzVbRp7HdjWH2JXNLXM3Nhf1TUPbqG/b1ib9etifpJWHob92DPRvVKS/XQv7zcKfKdTFfqP49bzV3gM7T7stX7E7t6Vju94LKnfnSrdblnbnzA0V1f9uu2U5d9VWcrSlwhFpx+aqe2dcf4ZCymH+iIzlOfKEJLOHo5nvhDWz1VOofRyl4BY6bggIb6JPV3p/5prv8c5w5KSog1me9N45kcHHwy4BGg5lCJCGhDeVd4/doUu8Y+3P1oD7wfdhJLVTEXeXs6l8YWRatL1IdB67vIz+7nAqFU+AVwb88Jsz1G8vCnpH3o6tAdbKuzPq+opvqN9ZjrUfW7Ihuw5E9YOHZk2B7u03eJqHKnE37kTLlrg7keGFNW5Ly7c8rdZ+OjwNu5mdbqt+snlgnX4zqXrK9XetoWG4+ucbkfrqP5iY7/4DldFBD4IgFADgX8OxzaCorpnVxa3NttaRCSkLfYQ0rV+fDS2Zl7ow+Hg8eA9EwqLZGabzGLhQCAe8QWSDMF7NaDu+4eGABlMHmZHc0QAS+RQdBp3eJReVF2gBlJXaxxTKUqTWM2YM1H7YBZR/q2aZGEGSMjXWk+Q2d7rEi6/vhczy/uYpXbmdgvXBXSVVzjjUAyIRIqEBsG5WNKFQ7971fZnj89Kcb/q4jifswOi13F4mLtn2nyOfEowo7a+p28n3ae3C+18SvQA=ldFBD4IgFADgX8OxTSUtjw0tt9bW5qEzE1Ia+hzStH59OjRlXurC4OPx4D0QJmV3UrQuLsC4RJ7DOoQj5HnhNujHAV4GAsc1kCvBDC0gFW8+ojPqUzDeWIEaQGpR25hBVfFMW0aVgtYOu4O0b61pzleQZlSu9SaYLozuvd3sCRd5Md3sBqHZKekUPFbSFJRBuyAcI0wUgDazsiNcDr2b+pL4UXmmPqFSP3TSOtWVHDYm2fGfI98SFK/0r6n7yfy0fmH9L44/ ================================================ FILE: llm-algo/训练范式.md ================================================ - [NLP的四个范式](https://zhuanlan.zhihu.com/p/456951972) 训练范式 ## 非神经网络时代的完全监督学习(特征工程) 提取出自然语言语料库中的一些特征,利用特定的规则或数学、统计学的模型来对特征进行匹配和利用,进而完成特定的NLP任务。 ## 第二范式:基于神经网络的完全监督学习(架构工程) 不用手动设置特征和规则,节省了大量的人力资源,但仍然需要人工设计合适的神经网路架构来对数据集进行训练。 ## 第三范式:预训练,精调范式(目标工程) 先在大的无监督数据集上进行预训练,学习到一些通用的语法和语义特征,然后利用预训练好的模型在下游任务的特定数据集上进行fine-tuning,使模型更适应下游任务。 特点是不需要大量的有监督下游任务数据,模型主要在大型无监督数据上训练,只需要少量下游任务数据来微调少量网络层即可。 ## 预训练,提示,预测范式(Prompt工程) 将下游任务的建模方式重新定义,通过合适的prompt来实现直接在预训练模型上解决下游任务,这种模式需要极少量(甚至不需要)下游任务数据,使得小样本、零样本学习成为可能。 ================================================ FILE: llm-alignment/DPO.md ================================================ 给 NLP 引入了一些 RL 相关的复杂性: 既要构建一个好的奖励函数,并训练一个模型用以估计每个状态的价值 (value) ; 又要注意最终生成的 LLM 不能与原始模型相差太远,如果太远的话会使得模型容易产生乱码而非有意义的文本。该过程非常复杂,涉及到许多复杂的组件,而这些组件本身在训练过程中又是动态变化的,因此把它们料理好并不容易。 Direct Preference Optimization,论文提出将现有方法使用的基于强化学习的目标转换为可以通过简单的二元交叉熵损失直接优化的目标,这一做法大大简化了 LLM 的提纯过程。 DPO 与 PPO 在通过 RL 优化人类衍生偏好时,一直以来的传统做法是使用一个辅助奖励模型来微调目标模型,以通过 RL 机制最大化目标模型所能获得的奖励。 直观上,我们使用奖励模型向待优化模型提供反馈,以促使它多生成高奖励输出,少生成低奖励输出。 同时,我们使用冻结的参考模型来确保输出偏差不会太大,且继续保持输出的多样性。 这通常需要在目标函数设计时,除了奖励最大化目标外再添加一个相对于参考模型的 KL 惩罚项,这样做有助于防止模型学习作弊或钻营奖励模型。 DPO 绕过了建模奖励函数这一步,这源于一个关键洞见: 从奖励函数到最优 RL 策略的解析映射。这个映射直观地度量了给定奖励函数与给定偏好数据的匹配程度。 有了它,作者就可与将基于奖励和参考模型的 RL 损失直接转换为仅基于参考模型的损失,从而直接在偏好数据上优化语言模型! 因此,DPO 从寻找最小化 RLHF 损失的最佳方案开始,通过改变参量的方式推导出一个仅需参考模型的损失! ================================================ FILE: llm-alignment/README.md ================================================ - [关于Instruct GPT复现的一些细节与想法](https://zhuanlan.zhihu.com/p/609078527) - [人人都能看懂的PPO原理与源码解读](https://zhuanlan.zhihu.com/p/677607581) - [MOSS-RLHF](https://github.com/OpenLMLab/MOSS-RLHF) - [模型调优(RLHF/DPO/ORPO)- 终极指南](https://zhuanlan.zhihu.com/p/692594519) - [DPO: Direct Preference Optimization 论文解读及代码实践](https://zhuanlan.zhihu.com/p/642569664) - [强化学习入门:基本思想和经典算法](https://imzhanghao.com/2022/02/10/reinforcement-learning/) - [动手学强化学习](https://hrl.boyuai.com/chapter/intro) ORPO: - ORPO: Monolithic Preference Optimization without Reference Model - https://github.com/xfactlab/orpo - https://arxiv.org/pdf/2307.12966.pdf ================================================ FILE: llm-alignment/RLHF.md ================================================ RLHF 收集人类偏好数据的质量和数量决定了 RLHF 系统性能的上限。RLHF 系统需要两种人类偏好数据:人工生成的文本和对模型输出的偏好标签。生成高质量回答需要雇佣兼职人员 (而不能依赖产品用户和众包) 。 另一方面,训练 RM 需要的奖励标签规模大概是 50k 左右,所以并不那么昂贵 (当然远超了学术实验室的预算) 。 另一个挑战来自标注者的偏见。几个人类标注者可能有不同意见,导致了训练数据存在一些潜在差异。 ================================================ FILE: llm-alignment/基本概念.md ================================================ ## On-Policy和Off-Policy 在强化学习(Reinforcement Learning, RL)中,On-Policy(在线策略)和Off-Policy(离线策略)是两种不同的策略学习方法: 1. **On-Policy(在线策略)**: - **定义**:On-Policy方法是指学习过程中,策略(Policy)和行为(Behavior)是一致的。即,在学习过程中,智能体(Agent)总是根据当前学习到的策略来选择动作。 - **特点**: - 直接从当前策略中采样数据。 - 学习过程和行为策略是同步的。 - 常见的On-Policy算法包括Sarsa和REINFORCE等。 - **优点**:由于学习过程和行为策略是一致的,因此可以更直接地对策略进行优化。 - **缺点**:可能需要更多的探索来学习一个好的策略,因为智能体总是根据当前策略选择动作。 2. **Off-Policy(离线策略)**: - **定义**:Off-Policy方法是指学习过程中,策略(Policy)和行为(Behavior)可以不一致。即,智能体可以按照一个行为策略(Behavior Policy)来选择动作,而学习一个不同的目标策略(Target Policy)。 - **特点**: - 可以利用历史数据或者模拟环境来学习,不需要实时与环境交互。 - 学习过程和行为策略是异步的。 - 常见的Off-Policy算法包括Q-learning、Deep Q-Networks(DQN)和Actor-Critic方法等。 - **优点**:可以更有效地利用数据,因为可以重复使用历史数据,并且可以更灵活地探索环境。 - **缺点**:需要处理策略不一致带来的偏差问题,需要使用一些技术(如重要性采样)来纠正这种偏差。 简而言之,On-Policy方法在学习时直接使用当前策略进行探索和学习,而Off-Policy方法则可以利用历史数据或者模拟数据,学习一个与当前行为策略不同的目标策略。这使得Off-Policy方法在数据利用上更加高效,但也带来了额外的算法复杂性。 在实际应用中,On-Policy和Off-Policy算法的区别可以通过以下例子来说明: 1. **On-Policy算法的例子:SARSA(State-Action-Reward-State-Action)** - 在SARSA算法中,智能体(比如一个机器人)学习基于当前正在执行的动作和策略。假设我们正在教机器人导航一个迷宫,SARSA算法会让机器人根据当前的策略(包括探索步骤)来学习价值函数。这就像是通过亲自尝试不同的食谱来学习烹饪。SARSA算法会根据当前动作、收到的奖励和下一个状态-动作对来更新价值函数。 2. **Off-Policy算法的例子:Q-Learning** - Q-Learning是一个经典的Off-Policy方法。在Q-Learning中,智能体可以观察其他智能体(比如其他机器人)成功的移动,并学习每个状态下的最佳移动,不管它自己在这个情况下会做什么。这就像是阅读食谱并学习烹饪方法,而不需要亲自下厨。Q-Learning允许智能体从外部经验中提取有价值的策略,促进了一个多功能和高效的学习范式。 通过这些例子,我们可以看到On-Policy方法直接从当前策略中学习,而Off-Policy方法则可以利用与当前策略不同的策略生成的数据来进行学习。这意味着Off-Policy方法可以更有效地利用数据,因为它们可以重复使用历史数据,并且可以更灵活地探索环境。而On-Policy方法则更直接地对当前策略进行优化,但可能需要更多的探索来学习一个好的策略。 ================================================ FILE: llm-application/Higress.md ================================================ ================================================ FILE: llm-application/README.md ================================================ [@liguodongiot](https://github.com/liguodongiot) - GPT-4+Midjourney零代码做「愤怒的南瓜」 LLM Powered Autonomous Agents:https://lilianweng.github.io/posts/2023-06-23-agent/ ## Vector DB ``` simCSE相似度的模型 SentenceTransformers ``` ================================================ FILE: llm-application/agent/OpenClaw.md ================================================ https://clawhub.ai/ ================================================ FILE: llm-application/agent/OpenCode/README.md ================================================ ================================================ FILE: llm-application/embbedding-model.md ================================================ 智源的工作bge,llm-embedder 段落文本用sentence bert类 ================================================ FILE: llm-application/gradio/README.md ================================================ - 启动参数: - https://github.com/gradio-app/gradio/blob/main/gradio/blocks.py ================================================ FILE: llm-application/langchain/README.md ================================================ - https://python.langchain.com/docs/tutorials/llm_chain/ ================================================ FILE: llm-application/langchain/serve.py ================================================ #!/usr/bin/env python from fastapi import FastAPI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_openai import ChatOpenAI from langserve import add_routes # 1. Create prompt template system_template = "Translate the following into {language}:" prompt_template = ChatPromptTemplate.from_messages([ ('system', system_template), ('user', '{text}') ]) # 2. Create model model = ChatOpenAI() # 3. Create parser parser = StrOutputParser() # 4. Create chain chain = prompt_template | model | parser # 5. App definition app = FastAPI( title="LangChain Server", version="1.0", description="A simple API server using LangChain's Runnable interfaces", ) # 6. Adding chain route add_routes( app, chain, path="/chain", ) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="localhost", port=8000) ================================================ FILE: llm-application/langchain/tutorials/client.py ================================================ from langserve import RemoteRunnable remote_chain = RemoteRunnable("http://localhost:8000/chain/") remote_chain.invoke({"language": "italian", "text": "hi"}) ================================================ FILE: llm-application/langchain/tutorials/serve.py ================================================ #!/usr/bin/env python from fastapi import FastAPI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_openai import ChatOpenAI from langserve import add_routes # 1. Create prompt template system_template = "Translate the following into {language}:" prompt_template = ChatPromptTemplate.from_messages([ ('system', system_template), ('user', '{text}') ]) # 2. Create model model = ChatOpenAI() # 3. Create parser parser = StrOutputParser() # 4. Create chain chain = prompt_template | model | parser # 5. App definition app = FastAPI( title="LangChain Server", version="1.0", description="A simple API server using LangChain's Runnable interfaces", ) # 6. Adding chain route add_routes( app, chain, path="/chain", ) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="localhost", port=8000) ================================================ FILE: llm-application/one-api.md ================================================ https://github.com/songquanpeng/one-api ================================================ FILE: llm-application/pre-post-handle/README.md ================================================ ## COLDataset 中文冒犯语言检测数据集 - https://github.com/thu-coai/COLDataset ## 敏感词检测 ### sensitive-word 基于 DFA 算法实现的高性能 java 敏感词过滤工具框架。 https://github.com/houbb/sensitive-word ### 敏感词及违禁词检测 https://www.volcengine.com/theme/1563016-M-7-1 一、基于关键词匹配的敏感词检测算法 二、基于正则表达式的敏感词检测算法 ### DFA敏感词过滤算法详解 https://blog.csdn.net/java_eiji/article/details/127354207 ================================================ FILE: llm-application/rag/README.md ================================================ - 大模型主流应用RAG的介绍——从架构到技术细节:https://luxiangdong.com/2023/09/25/ragone/#/%E5%86%99%E5%9C%A8%E5%89%8D%E9%9D%A2 - 从 RAG 到 Self-RAG —— LLM 的知识增强:https://zhuanlan.zhihu.com/p/661465330 - 大模型检索增强生成(RAG)有哪些好用的技巧?:https://www.zhihu.com/question/625481187 - The limits of LLMs and how RAG remedies them:https://konfuzio.com/en/limits-llms-retrieval-augmented-generation/ ----- 现在越来越多的实践者开始意识到一套向量数据库打天下的方案已经不够了,于是有了各种花式疗法,从构建索引到回复生成,可谓百花齐放,眼花缭乱: 内容切片不够好,容易切碎,于是有了段落智能划分; 向量生成的质量不可控,于是有了可根据不同QA场景动态生成向量的Instructor; 隐式的动态向量不够过瘾,再用HyDE做个中间层:先生成一些虚拟文档/假设文档再做召回,提升召回率; 如果向量这一路召回不够,再上关键词召回,传统BM25+向量HNSW融合各召回通路; 召回的太多容易干扰答案生成,探究一下Lost in the Middle,搞一搞trick,或者用LLMLingua压缩; 嫌召回太麻烦?直接扩到100k窗口全量怼进大模型,LongLoRA横空出世; 刚才提到的各个环节需要改进的点太多,懒得手工做,直接交给大模型,用Self-RAG替你完成每个步骤…… ## 密集检索和检索增强LLM - https://github.com/FlagOpen/FlagEmbedding/tree/master ================================================ FILE: llm-application/rag/embedding.md ================================================ Text embedding就是将文本转成一组固定维度的向量表示。我们所熟知的word embedding是以token为基本单位,而text embedding则是以文本为基本单位的。 **理想的text embedding应该尽可能保留文本的语义信息,相同语义但不同表述方式的文本可以被映射到同一个位置,而不同语义的文本在向量空间应该保持对应的距离。** Text embedding能用来做些什么?它可以用在Classification, Clustering, Pair Classification, Reranking, Retrieval, STS, Summarization, Bitext Mining等任务中。如何评价它的好坏,也可以通过在这些任务的表现来评估。 如何从语言模型中获得Text embedding呢?以目前主流的Transformer-Encoder为例,有以下几种不同方式。 a) 将模型最后一层[CLS]位置的向量表征直接作为句向量。 b) 将模型最后一层[CLS]位置的向量表征,再经过MLP层得到的向量。 c) 将模型最后一层所有位置的向量表征,再经过一个Pooling层得到的向量。(大部分情况下采用的是mean pooling,在有些情况下也会使用max pooling等其他方式) d) 将模型最后一层所有位置的向量表征,再经过一个Pooling层跟MLP层得到的向量。 ================================================ FILE: llm-application/rag/存在的一些问题.md ================================================ 主要原因还是: 1)哪怕是GPT3.5,幻觉依然严重,商业场景(如客服,研究)没法支持,用户满意度可怜。何况客户还要求私有化部署,还没有服务器. 2)客户的问题很多是无法用RAG解决的: - 预测类:xxxx2024年会如何? - 多跳逻辑类:Elon musk的兄弟是谁?(知识库里只有Elon musk的妈妈,以及妈妈的儿子有谁,导致召回严重失败) - 统计类:昨天有多少销售反馈了折扣力度不足的问题? - 逻辑推理 - “太有”良知问题:很多模型都很有良知,无法匹配商业中的无良场景(别笑)。比如GPT会非常忠诚地指出,化妆品里的xx因子是没有经过科学验证的,要谨慎对待。 ================================================ FILE: llm-application/rag/方案.md ================================================ rerank: - https://huggingface.co/BAAI/bge-m3 - https://huggingface.co/BAAI/bge-reranker-v2-m3 embedding: - https://huggingface.co/intfloat/multilingual-e5-large ``` import torch from transformers import AutoModelForSequenceClassification, AutoTokenizer tokenizer = AutoTokenizer.from_pretrained('BAAI/bge-reranker-v2-m3') model = AutoModelForSequenceClassification.from_pretrained('BAAI/bge-reranker-v2-m3') model.eval() pairs = [['what is panda?', 'hi'], ['what is panda?', 'The giant panda (Ailuropoda melanoleuca), sometimes called a panda bear or simply panda, is a bear species endemic to China.']] with torch.no_grad(): inputs = tokenizer(pairs, padding=True, truncation=True, return_tensors='pt', max_length=512) scores = model(**inputs, return_dict=True).logits.view(-1, ).float() print(scores) ``` ================================================ FILE: llm-application/vector-db/README.md ================================================ 词搜索 ---> 语义搜索 语义相似度 ================================================ FILE: llm-application/vector-db/reference.md ================================================ - 向量数据库(第 1 部分):每个数据库有何不同?:https://www.modb.pro/db/1694527960317513728 Vespa是最早(2017年)在当时主导的基于BM25关键词搜索算法旁边引入向量相似性搜索的供应商之一(有趣的事实:Vespa的GitHub仓库现在已经有近7.5万次提交)。Weaviate紧随其后,在2018年底推出了一个开源的专用向量搜索数据库,到2019年,我们开始看到更多的竞争者进入这个领域,其中包括开源的Milvus。需要注意的是,时间线中还显示了Zilliz,但它没有单独列出,因为它是Milvus的(商业)母公司,并提供基于Milvus构建的完全托管的云解决方案。在2021年,又有三家新的供应商进入了这个领域:Vald、Qdrant和Pinecone。而Elasticsearch、Redis和PostgreSQL等现有供应商在此之前明显缺席,并且直到2022年及以后才开始提供向量搜索,比人们预期的要晚得多。 - 7个向量数据库对比:Milvus、Pinecone、Vespa、Weaviate、Vald、GSI 和 Qdrant:https://www.modb.pro/db/516016 ================================================ FILE: llm-application/应用场景.md ================================================ 文生图: - Stable Diffusion - 文心一格:https://yige.baidu.com/creation?mode=0 图生文: - Blip2 数字人 - 百度智能云曦灵数字人:https://xiling.cloud.baidu.com/main/plaza/portrait AI教研平台 音乐生成模型: Suno V3 Alpha 弊端就是Suno最多只能生成2分钟的音乐,所以可以听到最后,会戛然而止直接截断,但是已经比V2好很多了。 但是这个音质、咬字、节奏编排啥的,也都好太多太多了。 https://app.suno.ai/ 要生成音乐的话,第一步肯定是写prompt,第二步(纯音乐没有)就是写歌词。 ================================================ FILE: llm-compression/PaddleSlim/ quantization.md ================================================ ## Shift ``` from paddleslim.quant.advanced import Shift, EMASampler model = LLM() model_config = {} shift = Shift(model, model_config, sample_function=EMASampler()) for data in dataloader(): model(data) shift.step += 1 shift.update_weight() ``` ## Smooth ``` from paddleslim.quant.advanced import Smooth,MultiStepSampler model = LLM() model_config = {} smooth = Smooth(model, model_config, sample_function=MultiStepSampler()) for data in dataloader(): model(data) smooth.step += 1 smooth.update_weight() ``` ## PieceWiseSearch ``` from paddleslim.quant.advanced import Smooth, MultiStepSampler, PieceWiseSearch, mse_loss search_func =PieceWiseSearch( k_piece=3, bits_length=8, search_piece=False, search_alpha_min=0.2, search_alpha_max=0.8, search_scale_min=1., search_scale_max=5., weight_quant_method='abs_max_channel_wise', act_quant_method='abs_max', loss_function=mse_loss ) model = LLM() model_config = {} smooth = Smooth(model, model_config, sample_function=MultiStepSampler(), search_function=search_func) for data in dataloader(): model(data) smooth.step += 1 smooth.update_weight() ``` ## GPTQ ``` from paddleslim.quant.advanced import GPTQ model = LLM() for cur_name, cur_layer in model.named_sublayers(): if type(cur_layer) == paddle.nn.Linear: gptq_layer = GPTQ(cur_layer) # sample data for data in dataloader(): model(data) # quant weight gptq_layer.fasterquant(act_order=True) ``` ## LayerWiseQuantError ``` from paddleslim.quant.advanced import LayerWiseQuantError model = LLM() for cur_name, cur_layer in model.named_sublayers(): if type(cur_layer) == paddle.nn.Linear: gptq_layer = LayerWiseQuantError(cur_layer) for data in dataloader(): model(data) for cur_name, cur_layer in model.named_sublayers(): if type(cur_layer) == LayerWiseQuantError: print(cur_name, cur_layer.losses.mean()) ``` ================================================ FILE: llm-compression/PaddleSlim/README.md ================================================ - paddle.fluid: https://github.com/PaddlePaddle/Paddle/issues/55108 ``` from paddle.base.framework import IrGraph from paddle.base.layer_helper import LayerHelper ``` ================================================ FILE: llm-compression/README.md ================================================ - https://lilianweng.github.io/posts/2023-01-27-the-transformer-family-v2/ - The Transformer Family Version 2.0 ================================================ FILE: llm-compression/distillation/GKD.md ================================================ 图 1:在 XSum summarization 上比较 GKD 与常见的蒸馏方法。 我们使用经过监督微调(FT)训练的 T5 模型作为蒸馏的学生模型。 有监督的 KD 和有监督的 FT 使用带有ground-truth摘要的 XSum 训练数据集,但 KD 可以查询教师以获得概率,而 FT 则不能。 此外,on-policy 方法来自学生的样本摘要,而'Mixed'是指从真实情况和学生生成的摘要中进行统一采样。 ImitKD 对应于使用 Forward KL 的'Mixed'采样。 正如第 2 节中所讨论的,具有反向 KL 和广义 JS 散度 (JSD) 的 GKD 优于其他方法。 --- 用于自回归序列模型的广义知识蒸馏 动机: 当前的自回归模型知识蒸馏方法存在两个关键问题: 1. 训练期间的输出序列与学生在部署期间生成的序列之间的分布不匹配; 2. 模型规格不足,即学生模型可能无法表达教师的分布。 为了解决这些问题,本文提出广义知识蒸馏(GKD)。 方法: 通过在训练期间从学生中采样输出序列来缓解分布不匹配。此外,GKD通过优化替代差异,如反向KL,这些差异专注于生成来自学生的样本,这些样本 在教师的分布下可能。 本文证明GKD在摘要、机器翻译和算术推理任务上超越了常用的LLM蒸馏方法。 优势:所提出方法在自然语言生成任务上的表现一直优于更常用的知识蒸馏基线。进一步展示了该方法可以与强化学习结合,以优化序列级奖励,除了蒸馏大型教师模型的知识。 提出一种名为广义知识蒸馏(GKD)的方法,可以解决自回归模型在知识蒸馏过程中面临的分布不匹配和模型规格不足的问题,在自然语言生成任务上的表现一直优于更常用的知识蒸馏基线。 ================================================ FILE: llm-compression/distillation/MINILLM.md ================================================ ## MINILLM 论文:Knowledge Distillation of Large Language Models https://github.com/microsoft/LMOps/tree/main/minillm 通过 Rouge-L 进行挑选。 动机: 解决大型语言模型(LLM)的高计算需求问题,通过知识蒸馏(KD)技术减小模型规模。现有的KD方法主要适用于白盒分类模型或训练小模型模仿黑盒模型API(如ChatGPT),如何有效地从白盒生成LLM中蒸馏知识仍然不够充分。 方法: 提出名为MINILLM的新方法,能从生成式大型语言模型中蒸馏出较小的语言模型。首先将标准KD方法中的前向Kullback-Leibler散度(KLD)目标替换为更适合在生成语言模型上进行KD的反向KLD,以防止学生模型高估教师分布的低概率区域。然后,推导出一种有效的优化方法来学习此目标。 优势: 提出一种从生成式LLM中蒸馏较小语言模型的方法,通过改进KD方法,实现了更高的生成质量、更低的暴露偏差、更好的校准性和更高的长文本生成性能。该方法具有可扩展性,适用于不同规模的模型。 提出了一种MINILLM方法,通过改进知识蒸馏方法,实现了从大型语言模型到小型模型的知识传递,提升了生成质量和性能。 ================================================ FILE: llm-compression/distillation/README.md ================================================ 近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,从而导致模型变得越来越大,因此,我们需要一些大模型压缩技术来降低模型部署的成本,并提升模型的推理性能。而大模型压缩主要分为如下几类: - 剪枝(Pruning) - 知识蒸馏(Knowledge Distillation) - 量化(Quantization) - 低秩分解(Low-Rank Factorization) 下面主要针对大模型蒸馏技术进行相应的讲解,本系列一共分六篇文章进行讲解。 - 大模型知识蒸馏原理综述(一):概述 - 大模型知识蒸馏原理综述(二):MINILLM、GDK - 大模型知识蒸馏原理综述(三):In-Context Learning distillation - 大模型知识蒸馏原理综述(四):SCOTT、DISCO、MT-COT - 大模型知识蒸馏原理综述(五):Lion - 大模型知识蒸馏原理综述(六):总结 本文为大模型知识蒸馏原理综述第一篇,主要讲述当前大模型蒸馏相关的一些工作。 ## 知识蒸馏简介 知识蒸馏,也被称为教师-学生神经网络学习算法,已经受到业界越来越多的关注。大型深度网络在实践中往往会获得良好的性能,因为当考虑新数据时,过度参数化会提高泛化性能。在知识蒸馏中,小网络(学生网络)通常是由一个大网络(教师网络)监督,算法的关键问题是如何将教师网络的知识传授给学生网络。通常把一个全新的更深的更窄结构的深度神经网络当作学生神经网络,然后把一个预先训练好的神经网络模型当作教师神经网络。 Hinton等人([@Distill])首先提出了教师神经网络-学生神经网络学习框架,通过最小化两个神经网络之间的差异来学习一个更窄更深的神经网络。记教师神经网络为 ,它的参数为 ,同时记学生神经网络为 ,相应的参数为 。一般而言,学生神经网络相较于教师神经网络具有更少的参数。 文献([@Distill])提出的知识蒸馏(knowledge distillation,KD)方法,同时令学生神经网络的分类结果接近真实标签并且令学生神经网络的分类结果接近于教师神经网络的分类结果,即, (10.3.5) 其中, 是交叉熵函数, 和 分别是学生网络和教师网络的输出, 是标签。公式 (10.3.5)中的第一项使得学生神经网络的分类结果接近预期的真实标签,而第二项的目的是提取教师神经网络中的有用信息并传递给学生神经网络, 是一个权值参数用来平衡两个目标函数。 是一个软化(soften)函数,将网络输出变得更加平滑。 公式 (10.3.5)仅仅从教师神经网络分类器输出的数据中提取有价值的信息,并没有从其他中间层去将教师神经网络的信息进行挖掘。因此,Romero等人[@FitNet])进一步地开发了一种学习轻型学生神经网络的方法,该算法可以从教师神经网络中任意的一层来传递有用的信息给学生神经网络。此外,事实上,并不是所有的输入数据对卷积神经网络的计算和完成后续的任务都是有用的。例如,在一张包含一个动物的图像中,对分类和识别结果比较重要的是动物所在的区域,而不是那些无用的背景信息。所以,有选择性地从教师神经网络的特征图中提取信息是一个更高效的方式。于是,Zagoruyko和Komodakis([@attentionTS])提出了一种基于感知(Attention)损失函数的学习方法来提升学生神经网络的性能,该方法在学习学生神经网络的过程中,引入了感知模块(Attention),选择性地将教师神经网络中的信息传递给学生神经网络,并帮助其进行训练。感知图用来表达输入图像不同位置对最终分类结果的重要性。感知模块从教师网络生成感知图,并迁移到学生网络,如图 图10.3.3 一种基于感知(attention)的教师神经网络-学生神经网络学习算法 知识蒸馏是一种有效的帮助小网络优化的方法,能够进一步和剪枝、量化等其他压缩方法结合,训练得到精度高、计算量小的高效模型。 标准知识蒸馏 基于涌现能力的知识蒸馏 - 上下文学习 - 思维链 - 指令遵循 ================================================ FILE: llm-compression/distillation/SCOTT.md ================================================ --- 为了保证论据的准确性,SCOTT(论文:**SCOTT: Self-Consistent Chain-of-Thought Distillation**)采用对比解码,将每个论据与答案联系起来。它激励来自老师模型正确的逻辑依据。此外,引导学生进行反事实推理,并根据导致不同答案的逻辑依据进行预测。 --- 图 2:我们用于可信推理(faithful reasoning)的知识蒸馏框架概述。 (a) 教师:大型 LM 提示通过对比解码在给定问题和训练集中的黄金答案的情况下生成一致的基本原理。 (b) 学生:一个小型 LM,经过微调以生成基本原理,然后通过反事实推理进行回答。 一种忠实的知识蒸馏方法,用于从大几个数量级的教师模型中学习小型、自洽的 CoT 模型。 为了形成更好的监督,我们通过对比解码从大型 LM(老师)那里引出支持黄金答案的理由,这鼓励老师生成只有在考虑答案时才变得更加可信的Token。 为了确保可信的蒸馏,我们使用教师生成的基本原理来学习具有反事实推理目标的学生 LM,这可以防止学生忽略基本原理而做出不一致的预测。 实验表明,在产生可比较的最终任务性能的同时,我们的方法可以生成比基线更可靠的 CoT 基本原理。 进一步分析表明,这样的模型在决策时更尊重理性; 因此,我们可以通过完善其原理来进一步提高其性能。 ================================================ FILE: llm-compression/distillation/大模型蒸馏概述.md ================================================ 知识蒸馏(KD)是一种有价值的机器学习技术,旨在提高模型性能和泛化能力。 它通过将知识从复杂的模型(称为教师模型)转移到更简单的模型(称为学生模型)来实现这一点。 KD背后的核心思想是将教师模型的综合知识转化为更精简、更有效的表示。 在本节中,我们概述了利用LLM作为教师的蒸馏方法。我们根据这些方法是否将LLM的涌现能力(EA)提炼成小语言模型(SLM)来对这些方法进行分类。 因此,我们将这些方法分为两个不同的类别:标准 KD 和基于 EA 的 KD。 为了直观地表示,图 2 提供了LLM知识蒸馏的简要分类。 Standard KD旨在使学生模型学习LLM所拥有的常见知识,如输出分布和特征信息。这种方法类似于传统的KD,但区别在于教师模型是LLM。 比如:MINILLM和GKD。 MINILLM 深入研究了白盒生成LLM的蒸馏。 它观察到最小化前向 Kullback-Leibler 散度 (KLD) 的挑战(这可能会导致教师分布中不太可能的区域出现概率过高,从而在自由运行生成过程中导致不可能的样本)。 为了解决这个问题,MINILLM 选择最小化反向 KLD。 这种方法可以防止学生高估教师分布中的低概率区域,从而提高生成样本的质量。 GKD 探索了自回归模型的蒸馏,这里白盒生成 LLM 是一个子集。 该方法确定了两个关键问题:训练期间的输出序列与学生在部署期间生成的输出序列之间的分布不匹配,以及模型under-specification,其中学生模型可能缺乏与教师分布相匹配的表达能力。 GKD 通过在训练期间对学生的输出序列进行采样来处理分布不匹配,它还通过优化替代分歧(反向 KL)来解决模型under-specification的问题。 -- 基于 EA 的 KD 不仅仅迁移 LLM 的常识,还包括蒸馏他们的涌现能力。 与 BERT(330M)和 GPT-2(1.5B)等较小模型相比,GPT-3(175B)和 PaLM(540B)等 LLM 展示了独特的行为。 这些LLM在处理复杂的任务时表现出令人惊讶的能力,称为“涌现能力”。 涌现能力包含几个有趣的方面,包括上下文学习 (ICL)、思维链 (CoT) 和指令遵循 (IF)。 有关直观概述,请参阅图 3,它提供了基于EA的知识蒸馏概念的简明表示。 ICL 采用结构化自然语言提示,其中包含任务描述以及可能的一些任务示例作为演示。 通过这些任务示例,LLM可以掌握并执行新任务,而无需显式梯度更新。 In-context Learning Distillation: Transferring Few-shot Learning Ability of Pre-trained Language Models 论文中引入了 ICL 蒸馏,它将上下文小样本学习和语言建模功能从 LLM 转移到 SLM。这是通过将上下文学习目标与传统语言建模目标相结合来实现的。 为了实现这一目标,他们在两种小样本学习范式下探索了 ICL 蒸馏:元上下文调优 (Meta-ICT) 和多任务上下文调优 (Multitask-ICT)。 在 Meta-ICT 中,语言模型使用上下文学习 objectives 在不同任务中进行元训练。这使其能够通过上下文学习来适应看不见的任务,从而扩展其解决问题的能力。 另一方面,Multitask-ICT 使用 ICL objectives 和target任务中的一些示例对模型进行微调。随后,它采用上下文学习来对这些任务进行预测。 比较这两种范式,Multitask-ICT 表现出优于 Meta-ICT 的性能。 然而,它在任务适应过程中确实需要更多的计算资源,使其计算加强。 与 ICL 相比,CoT 采用了不同的方法,它将中间推理步骤(可以导致最终输出)合并到提示中,而不是使用简单的输入输出对。 MT-COT [Li et al., 2022] 旨在利用LLM产生的解释来加强小型推理机的训练。它利用多任务学习框架使较小的模型具有强大的推理能力以及生成解释的能力。 Fine-tuneCoT [Ho et al., 2023] 更进一步,通过随机采样从 LLM 生成多个推理解决方案。 训练数据的增强有助于学生模型的学习过程。 Fu 等人的研究发现语言模型的多维能力之间的权衡,并提出微调指令调整模型。 他们从大型教师模型中提取 CoT 推理路径,以提高分布外泛化能力。 Hsieh 等人使用LLM原理作为在多任务框架内训练较小模型的额外指导。 SOCRATIC CoT [Shridhar et al., 2023] 训练两个蒸馏模型:问题分解器和子问题求解器。 分解器将原始问题分解为一系列子问题,而子问题求解器负责解决这些子问题。 DISCO [Chen et al., 2023] 引入了一种基于LLM的全自动反事实知识蒸馏方法。 它通过工程化的提示使用LLM生成短语扰动,然后通过特定于任务的教师模型过滤这些扰动,以提取高质量的反事实数据。 为了保证基本原理的准确性,SCOTT [Wang et al., 2023a] 采用对比解码,将每个基本原理与答案联系起来。 它鼓励老师提出相关的理由。 此外,引导学生进行反事实推理,并根据导致不同答案的理由进行预测。 IF 致力于仅基于阅读任务描述来增强语言模型执行新任务的能力,而不依赖于少数样本。 通过使用一系列以指令表示的任务进行微调,语言模型展示了准确执行以前未见过的指令中描述的任务的能力。 例如,Lion [Jiang et al., 2023] 利用LLM的适应性来提高学生模型的表现。 它 提示LLM识别并生成“hard”指令,然后利用这些指令来增强学生模型的能力。 这种方法利用了LLM的用途广泛的特性来指导学生模型的学习,以解决复杂的指令和任务。 ================================================ FILE: llm-compression/gptqmodel/README.md ================================================ git clone git@github.com:liguodongiot/GPTQModel.git git remote add upstream git@github.com:ModelCloud/GPTQModel.git # 拉取原始仓库数据 git fetch upstream --tags # 如果你的主分支不是叫master,就把前面的master换成你的名字,比如main之类 git rebase upstream/main # 推送 git push # 推送tags git push --tags git checkout -b dev-code-v2.0.0 v2.0.0 # 将新分支推送到远程仓库 git push -u origin dev-code-v2.0.0 ================================================ FILE: llm-compression/llm-compressor/README.md ================================================ ``` git clone git@github.com:liguodongiot/llm-compressor.git git remote add upstream git@github.com:vllm-project/llm-compressor.git # 拉取原始仓库数据 git fetch upstream --tags # 如果你的主分支不是叫master,就把前面的master换成你的名字,比如main之类 git rebase upstream/main # 推送 git push # 推送tags git push --tags ``` ## llm-compressor 支持的量化类型: - https://github.com/neuralmagic/compressed-tensors/blob/main/src/compressed_tensors/quantization/quant_scheme.py int8: https://github.com/vllm-project/llm-compressor/tree/main/examples/quantization_w8a8_int8 fp8 dynamic: https://github.com/vllm-project/llm-compressor/tree/main/examples/quantization_w8a8_fp8 ================================================ FILE: llm-compression/llm-compressor/source-code.md ================================================ ================================================ FILE: llm-compression/llm-compressor/剪枝.md ================================================ https://docs.neuralmagic.com/guides/sparsification/ A tutorial doc for how to use the sparse prunings #993 - https://github.com/vllm-project/llm-compressor/issues/993 sparsegpt: https://github.com/IST-DASLab/sparsegpt https://arxiv.org/pdf/2301.00774 wanda: https://github.com/locuslab/wanda https://arxiv.org/pdf/2306.11695 SparseGPT、Wanda 和 MagnitudePruningModifier。 ConstantPruningModifier 仅用于在量化之前保持稀疏性。 ``` ConstantPruningModifier: start: 0 end: 5 targets: __ALL_PRUNABLE__ MagnitudePruningModifier: start: 5 end: 10 init_sparsity: 0.1 final_sparsity: 0.5 targets: __ALL_PRUNABLE__ SparseGPTModifier: sparsity: 0.5 mask_structure: "2:4" dampening_frac: 0.001 block_size: 128 targets: ['Linear'] ignore: ['re:.*lm_head'] WandaPruningModifier: sparsity: 0.5 mask_structure: "2:4" targets: __ALL_PRUNABLE__ ``` oneshot() 为 compress() 应用别名,这是对 oneshot 的概括。 oneshot() 只运行 oneshot modifiers (GPTQ、SparseGPT 等),而 apply() 函数将运行配方中的所有阶段。 例如,如果您有一个配方,它指定了一个阶段用于微调,然后指定了一个阶段用于量化,则需要使用 apply()/compress() 来运行此配方,而不是 oneshot() ================================================ FILE: llm-compression/llm-compressor/量化方案.md ================================================ ``` QuantizationScheme # FP8 weights and FP8 activations quantization # 对称量化 FP8 = dict( weights=QuantizationArgs( num_bits=8, type=QuantizationType.FLOAT, strategy=QuantizationStrategy.TENSOR, symmetric=True, dynamic=False, ), input_activations=QuantizationArgs( num_bits=8, type=QuantizationType.FLOAT, strategy=QuantizationStrategy.TENSOR, symmetric=True, dynamic=False, ), ) # 对称量化、动态量化 # FP8 weights and FP8 dynamic activations quantization FP8_DYNAMIC = dict( weights=QuantizationArgs( num_bits=8, type=QuantizationType.FLOAT, strategy=QuantizationStrategy.CHANNEL, symmetric=True, dynamic=False, ), input_activations=QuantizationArgs( num_bits=8, type=QuantizationType.FLOAT, strategy=QuantizationStrategy.TOKEN, symmetric=True, dynamic=True, observer=None, ), ) ``` ================================================ FILE: llm-compression/quantization/FP6-LLM.md ================================================ 通过以 FP6 为中心的算法系统协同设计高效服务大语言模型 六位量化(FP6)可以有效地减小大型语言模型(LLMs)的大小,并在不同的应用程序中保持一致的模型质量。 然而,现有系统不提供对 FP6 量化的 Tensor Core 支持,并且在 LLM 推理期间难以实现实际性能改进。在 GPU 上支持 FP6 量化具有挑战性,因为 (1) 位宽不规则的模型权重的内存访问不友好, 以及 (2) 权重反量化的运行时开销较高。 为了解决这些问题,我们提出了TC-FPx,这是第一个全栈GPU内核设计方案,具有统一的Tensor Core支持各种量化位宽的浮点权重。 我们将 TC-FPx 内核集成到现有的推理系统中,为量化 LLM 推理提供新的端到端支持(称为 FP6-LLM),其中推理之间有更好的权衡实现了成本和模型质量。 实验表明,FP6-LLM 仅使用单个 GPU 即可实现 LLaMA-70b 的推理,实现比 FP16 基线高 1.69×- 2.65× 的归一化推理吞吐量。 部署 LLMs 具有挑战性 一方面,它需要大量的 GPU 内存(FP16 中的 GPT-3 需要 326 GB)才能容纳模型权重,而 A100/H100 GPU [20, 21] 仅具有最多 80 GB 内存。 另一方面,LLM推理在token生成过程中面临严重的“内存墙”问题[12, 36],其中LLM推理的速度主要受到读取模型权重的时间限制来自 GPU DRAM。它使 LLM 推理内存受到限制,无法充分利用 GPU 的计算能力。 最近的研究表明,6 位量化是 LLM 部署的推理成本和模型质量之间的良好权衡 [30, 35]。 然而,现代 GPU 上仍然没有有效的系统支持 6 位线性层执行(即矩阵乘法)。迫切需要开发支持6位量化的系统,充分利用GPU的计算能力。 一方面,与较大位量化(例如 8 位)相比,6 位量化可以实现更高效的 LLM 推理。 首先,可以节省更多的 GPU 内存,例如如果部署具有 6 位而不是 8 位量化的 GPT-3 模型,可以节省大约 40 GB 内存。 其次,由于可以有效减少从GPU DRAM读取模型权重的时间,因此可以进一步加速LLM推理。如图 1 所示,使用我们新提出的 6 位量化系统设计 (TC-FPx_W6A16) 实现的线性层始终更快(高达 1.45 倍)。 使用我们新提出的 6 位量化系统设计 (TC-FPx_W6A16) 实现的线性层始终比最先进的 8 位量化支持 (TensorRT_LLM_W8A16) 快 1。 另一方面,尽管最近的 4 位技术 [6,39] 在以最小的压缩 LLMs 方面表现出了潜力,但与较小位量化(例如 4 位)相比,6 位量化可以更有效地保持模型质量。 最近的研究 [35] 表明,在超出零样本测量的任务中,例如代码生成和总结,4 位方法表现不佳且缺乏鲁棒性,而 6 位量化方法则主要针对零样本评估。在这些不同的应用程序中显示出强大且一致的性能。 受上述观察的启发,我们提出了 TC-FPx,这是第一个全栈 GPU 系统设计方案,具有统一的 Tensor Core [20,21] 支持各种量化位宽(6 位、5 位)的浮点权重、3 位等),减轻 LLM 推理过程中的“内存墙”问题。 TC-FPx打破了底层GPU硬件的限制,让GPU支持涉及任意位宽的模型权重的线性层计算。 在 TC-FPx 中,Tensor Core 用于矩阵乘法的密集计算,而 SIMT 核则有效地用于权重反量化,在运行时将 x 位模型权重转换为 FP16 类型,然后再将其馈送到 Tensor Core。 我们提出提前位级预打包(第 5.2 节)来解决不规则位宽权重的不友好内存访问的挑战(第 4.2.1 节),从而实现最佳 GPU 内存访问。 此外,我们提出 SIMT-Efficient GPU Runtime(第 5.3 节)来最小化权重反量化的运行时开销(第 4.2.2 节)。 最后但并非最不重要的一点是,我们展示了 TC-FPx 内核的软件管道,其中 SIMT 内核、Tensor 内核和 GPU 内存层次结构以高性能高效协作。 我们将 TC-FPx 内核集成到最先进的推理系统 [19] 中,为量化 LLM 推理提供新的端到端支持(称为 FP6LLM),其中更好地权衡实现了推理成本和模型质量。 目前,FP6-LLM主要支持流行的LLMs的6位量化(FP6),例如各种尺寸的LLaMA [32]、OPT [41]。 评估表明,FP6-LLM 仅使用单个 GPU 即可实现 LLaMA-70b 的推理,实现比 FP16 基线高 1.69×2.65 倍的归一化推理吞吐量。此外,FP6-LLM将OPT-30b的推理吞吐量提高了1.72×-4.05×。 我们确定了在现代 GPU 上支持 FP6 量化的重要性和主要挑战。 我们提出了TC-FPx,这是第一个全栈GPU内核设计方案,具有统一的Tensor Core支持各种位宽的浮点权重,例如FP6。 我们通过TC-FPx的集成为量化LLMs提供新的端到端推理支持,在推理成本和模型质量之间实现更好的权衡。 我们在各种 LLM 模型上评估 FP6-LLM 并证明它大大优于基线。 ------------- 量化的主要目标是线性层的权重(即矩阵乘法),占总体LLM权重的99%以上。激活也可以在推理过程中进行量化。 SIMT cores (CUDA cores) 负责 GPU 中的通用处理任务,处理各种指令,包括整数运算、浮点运算、加载/存储操作等。 SIMT cores 执行在单个(或矢量)数据元素。 Tensor Cores [20, 21] 是为加速矩阵乘法而设计的专用硬件。在 A100 [20]/H100 [21] GPU 上,Tensor Cores 的 FLOPS 比 SIMT 核心高 16.0 倍/ 14.8 倍。 此外,Tensor Cores 以粗粒度工作,例如:使用单个 mma(矩阵乘法和累加)指令在形状为 16 × 16 和 16 × 8 的两个 FP16 矩阵之间执行矩阵乘法。 --- 动机: 与 8 位和 4 位量化相比,FP6 量化可以在推理成本和模型质量之间实现更好的权衡。 (I) 推理成本低于 8 位量化。与 8 位量化相比,通过更积极的 6 位量化可以进一步降低部署 LLMs 的成本,而不会出现明显的精度下降。 一方面,LLM权重的大小可以显着减小,比 FP16 基线小近 2.7 倍。存储模型权重需要更少的 GPU 内存,从而需要更少的 GPU 并降低部署 LLMs 的服务成本。 另一方面,6位量化也可以更有效地加速LLMs的推理。鉴于 LLM 推理在令牌生成期间通常受内存限制,因此可以通过减少模型权重的 GPU DRAM 访问来实现更快的 LLM 推理。 如图 1 所示, 与最先进的 8 位量化支持(TensorRT-LLM_W8A16 )相比,我们新提出的 6 位量化系统设计 (TC-FPx_W6A16) 中 llama-65b 模型 [32] 中线性层的执行速度始终更快(高达 1.42 倍)。 [26])。鉴于线性层是大型语言模型中最耗时的部分,这种加速将直接转化为端到端推理场景的性能改进(参见第 7.3 节)。 (II) 比 4 位量化更好的模型质量。 虽然 4 位量化更积极地减少内存占用和 DRAM 访问,但它不可避免地会导致模型质量下降。相比之下,通过 6 位量化可以实现近乎无损的模型压缩。如表 1 和表 2 所示,FP6 在各种任务中显示出强大且一致的性能,包括代码生成和零样本困惑性能。它还在各种模型尺寸(例如 1B、13B 和 65B LLaMA [32] 模型)中表现出高稳健性。 我们还发现 INT4 量化严重依赖细粒度量化 (FGQ) 方法来保持较高的模型质量,而我们的 FP6 量化已经在粗粒度量化上表现良好。请注意,表 1 和表 2 中的数据点选自[35]。欲了解更多详细信息,请参阅本文。总之,在算法层面,FP6 量化是一种实用的替代方案,可以进一步民主化 LLMs 的部署,而不会显着牺牲复杂任务和各种模型大小的模型质量。 --- 设计的选择与挑战 尽管对训练后 FP6 量化的高性能支持的需求不断增加,但目前还没有这样有效的以 FP6 为中心的系统设计,可以实现上述 4 位和 8 位量化的权衡。具体来说,现有对线性层的支持主要是针对位宽为2的指数的数据类型(例如4位、8位和16位)而设计的。鉴于目前尚不清楚如何在现代 GPU 上有效支持 FP6,我们在本节中说明两个重要的设计选择。 启用 Tensor Core 的必要性。 我们发现有必要在执行量化 LLMs 推理时支持 Tensor Core。例如,我们评估了 AWQ [14, 15] 纯 SIMT 核心执行在各种批量大小上的性能,以测试其可扩展性。如图 1 所示,随着推理批量大小的增加,不带 Tensor Core 支持的线性层 (AWQ_W4A16_SIMT) 的运行时性能变得极低。这背后的原因是双重的。 一方面,对于线性层执行,传统 SIMT 核心比 Tensor Core 慢一个数量级,如第 2.3 节所述。 另一方面,SIMT 核心计算能力的很大一部分将用于在运行时对模型权重进行反量化,这进一步降低了 SIMT 核心用于计算矩阵乘法的可用计算能力。 这促使我们启用Tensor Core来进行矩阵乘法的密集计算,同时利用多功能 SIMT core 进行权重反量化。 统一kernel而不是双kernel的解决方案 这WxA16量化的独特之处在于激活矩阵使用FP16,但权重矩阵以较窄的位宽存储。但是,Tensor Core 要求将权重矩阵和激活矩阵存储在同一数据类型中,例如FP16/INT8/INT4。 简单的解决方案(即双kernel解决方案)添加一个额外的 GPU kernel,在调用普通 FP16 kernel之前将权重反量化为 FP16。然而,这样的推理速度会比没有量化的模型还要慢。如图 2(左)所示,将启动两个 GPU kernel用于线性层执行,反量化的 FP16 权重将再由第二个 GPU Kernel 读取之前写入 GPU DRAM,从而导致 2 倍 DRAM 访问。 将反量化和矩阵乘法过程融合到单个 GPU kernel中更加高效,从而消除了反量化权重的读/写(FP16 中的 W')。 --- 设计挑战 在现代 GPU 上设计支持 FP6×FP16 矩阵乘法的统一 GPU Kernel 具有挑战性。一方面,现代 GPU 内存系统天然不支持不规则位宽(不是 2 的指数),因为 GPU 全局/共享内存的最小访问大小是每个线程 8/32 位,并且要访问的内存地址必须对齐。并且 Tensor Core 复杂的数据布局要求使得不规则位宽更具挑战性。另一方面,反量化计算成本昂贵,因为它需要大量复杂的bit-level操作。因此,如何将反量化融合到线性层计算中而不影响整体性能也很重要。 4.2.1 硬件不友好的内存访问 在现代 GPU 上执行线性层期间,应先将模型权重从 DRAM 加载到寄存器,然后才能执行相应的乘法计算。 通常,模型权重分两步加载,以隐藏 DRAM 的高访问延迟以获得高性能。具体来说,模型权重首先从 GPU DRAM 加载并缓冲到片上存储(例如:共享存储)中以供数据重用。之后,缓存的权重从共享内存读取到寄存器以进行实际计算。 鉴于每个GPU线程不能直接访问其他GPU线程的寄存器,每个线程必须将自己需要的模型权重放入自己的私有寄存器中。 考虑到 Tensor Core 严格的数据布局要求,当权重以不规则位宽(不是 2 位,例如 6 位)存储时,这个过程可能会变得极具挑战性。 如图 3a 所示,FP16 Tensor Core 的最小输入是现代 GPU 架构中的 8 × 8 子矩阵,每个 GPU 线程应在其寄存器中保存一对权重。 正常情况下,每个权重以16位存储,每对权重可以以32位字的粒度自然地从共享内存中读取。 然而,在我们的工作中,每个权重都以 x 位存储,这使得内存访问对于现代 GPU 内存层次结构极其不友好。 具有未使用位的片上存储访问: 我们以 6 位量化为例,展示访问不规则位宽权重的低效率。 如图3b所示,权重已经缓冲在共享内存中,每个GPU线程需要从共享内存中读取一对权重(12位,2 * 6位)。然而,共享内存有 32 个内存组,每个内存组在 GPU 上的每个内存请求上输出一个 32 位字。 因此,从共享存储读取的大部分位将未被使用,导致共享存储带宽显著浪费。例如,图 3b 中的 T0(线程 #0)仅需要 12 位。然而,将读取 32 位字 (W1),导致 32 位中的 20 位 (62.5%) 未使用。 由于现代 GPU 内存层次结构中,有对齐内存访问的要求,未使用位的浪费可能会变得更加严重。如图 3b 所示,T2(线程#2)所需的位分布在两个 W1 和 W2 中。 因此,T2 需要读取 W1 和 W2,从共享内存中读取 2 * 32 位。然而,最终只会使用 6 * 2 位,导致 64 位中有 52 位(81.25%)未使用和浪费。 还值得注意的是,由于位宽不规则,GPU DRAM 和寄存器上的内存管理和访问也遇到类似的问题。 4.2.2 反量化计算开销高 FPx-FP16 反量化的运行时开销可能非常高,这很容易减慢整体执行速度。 一方面,大量的模型权重需要在运行时进行反量化,例如对于 LLaMA-70b [33] 推理,每个 LLM 解码步骤应反量化 700 亿个 FPx 权重。 另一方面,反量化每个 FPx 权重的运行时开销很高,需要复杂的按位操作。根据公式 2,新的符号、指数和尾数都需要在运行时计算,以获得与给定 FPx 等效的 FP16。 FPx-FP16 反量化的运行时开销可能非常高,这很容易减慢整体执行速度。一方面,大量的模型权重需要在运行时进行反量化,例如: 对于 LLaMA-70b 推理,每个 LLM 解码步骤应反量化 700 亿个 FPx 权重。 另一方面,反量化每个 FPx 权重的运行时开销很高,需要复杂的按位操作。根据公式 2,新的符号、指数和尾数都需要在运行时计算,以获得与给定 FPx 等效的 FP16。 在公式2中,bias = 15,bias = 2− 1。 FP16的符号字段与FPx的符号字段相同,并且FP16的尾数也可以通过向FPx的尾数补零来计算。更重要的是,FP16 的指数应该是 E=E+bias−bias ,这在计算上更加昂贵。 综上所述,如何有效地对 FPx 值进行反量化也成为一个重大挑战。 5. 设计方法论 在本节中,我们首先在 5.1 节中概述我们的设计。为了解决不友好的内存访问(第 4.2.1 节)的挑战, 我们在第 5.2 节中提出了运行前 Bit-level 预包装。 为了应对反量化高计算开销的挑战(第 4.2.2 节),我们在第 5.3 节中介绍了实现 SIMT 高效 GPU 运行时的设计。 最后,我们在第 5.4 节中介绍了我们的软件管道设计,其中 SIMT 核心、Tensor 核心和 GPU 内存层次结构以最佳性能协同工作。 图 4 比较了 TC-FPx(我们设计中的仅 x 位权重量化线性层内核)与通用矩阵乘法 (GEMM) 的传统设计,其中两个输入矩阵均采用 FP16。 TC-FPx 的模型权重以减少的位数存储。因此,在寄存器级别引入了额外的反量化阶段 (Dequant W),其中使用 SIMT cores 在每个线程内将 FP6 权重本地反量化为 FP16。 值得注意的是 FP16 权重不会写回共享内存,而是存储在寄存器中以供将来使用,从而消除了对共享内存不必要的往返访问。 另一个区别是TC-FPx使用细粒度的lds(加载共享)指令将x位权重从共享内存加载到寄存器,而不是使用粗粒度的固有ldmatrix(加载矩阵),后者具有严格的布局要求并且更少灵活性。 5.2 运行前 Bit-level 预包装 如 4.2.1 节所述,对具有不规则位宽的权重的内存访问对于现代 GPU 内存层次结构是不友好的。 为了解决这个问题,我们提出可以将每 32 个 x 位权重的内存读取结合起来,从而产生每个 GPU 线程 4 字节字的 x 请求。 可以合并每 32 个 x 位权重的内存读取,从而产生每个 GPU 线程 4 字节字的 x 请求。 在这种情况下,所有内存访问都将以 32 位字的粒度对齐,而不是不规则的位宽。 然而,由于 Tensor Core 严格的数据布局要求,将权重的内存读取结合起来并非易事,因为每个 GPU 线程所需的权重并不存储在连续的内存空间中。 为了解决这个问题,我们建议通过重新排序每个权重矩阵中的权重并提前预打包权重来优化运行时内存访问模式。 由于模型权重是在模型训练和量化后静态确定的,因此可以提前对权重应用复杂的内存布局转换,从而不会引入运行时开销。 此外,我们只需要预打包一次权重,因此预打包权重的开销可以通过每次推理服务有效摊销,并且可以忽略不计。 一般来说,权重预包装包括两个步骤。 第一步,我们收集每个 GPU 线程所需的所有权重,并在本地组合这些权重。鉴于每个 GPU 线程所需的权重最初并不位于每个权重矩阵内的连续位置(参见图 3a),因此我们必须仔细选择每个 GPU 线程的权重。 然后,为每个线程选择的权重在本地以相对时间顺序组合,因为它们在运行时被Tensor Core 消耗。 第二步,我们将整个GPU WARP(由32个GPU线程组成)所需的所有权重组合到一个统一的线性内存空间中,权重将在运行时按顺序存储在GPU DRAM中。为了完全消除共享内存库冲突,我们建议以锯齿状顺序组合每个线程的 32 位字。 值得注意的是,本小节中讨论的所有技术都独立于模型权重的实际位宽(始终使用 x 表示)。 因此,我们的权重预打包可以自然地应用于任何位宽度。 步骤 1:每线程权重收集 图 5 演示 规定 T0(线程 #0)选取的权重以及组合它们的顺序。 我们假设 WARP 级切片大小为 64 × 64 ,这意味着每个权重矩阵被分为 64 × 64 数据块,并以每个 WARP 的粒度加载到 GPU 的共享内存。 然后,每个权重图块进一步分为四个片,因为权重是从共享内存加载的,并逐片用于 Tensor Core 计算。 更重要的是,每个切片被分为四个 16 × 16 块,因为 Tensor Core 在每条指令中处理 16 × 16 数据项。 在每个 16 × 16 块中,为 T0 选择四对 FPx 权重并组合。 如图5所示,经过步骤1,我们得到了32组(即WARP大小)FPx权重。权重在每组中组合并连续存储,并且每组权重将被某个GPU线程消耗。 综上所述,每个 64 × 64 权重图块最终分配给 32 个线程(一个 WARP),每个线程将消耗 128 个 x 位权重。 步骤 2:按 WARP 进行 Bit-level 组装 在步骤 2 中,我们将不同组的所有权重组装成统一的内存空间。 在这个Bit-level 预打包过程中,我们将组合的权重视为要复制的连续数据,暂时忽略每个位的含义。具体来说,x 位的 128 个项目被视为 32 位的 4x 个项目。 我们建议按照图 5 所示的锯齿状顺序组装所有组的权重。 首先,将每个线程的第一个 32 位项连接在一起。之后,每个线程的第二个 32 位项被连接并附加到之前的结果中。 通过重复这个过程,所有权重可以连续存储在线性内存空间中,并且对齐良好(128字节对齐)。 这样,所有权重就可以以 128 字节块的粒度简单地从 DRAM 复制到共享内存,无需任何更改,轻松实现最佳 DRAM 访问。 此外,这些权重可以在运行时以最佳性能从共享内存加载。 具体来说,线程的 WARP 将为每个内存请求读取共享内存中的连续 32 位项目,完全避免了存储体冲突。 运行时高效的SIMT计算 SIMT-高效 GPU 运行时 并行反量化为了减少 FP-x 权重反量化的运行时开销,我们使用优化的按位 SIMT 核心指令实现了 FP-x 反量化。 此外,我们建议并行对多个 FPx 权重进行反量化,通过利用每个 32 位寄存器内的位级并行性,进一步将 SIMT 开销减少 4 倍。 (1) 优化的按位运算:如第 4.2.2 节所述,当将 FPx 转换为等效的 FP16 时,FP16 的指数应为 E = E +bias −bias 。为了简化这个过程,我们采用了[35]中的数学变换,用E = E来计算FP16的指数。为了保持正确性,将结果 FP16 与 FP16 常数 2 相乘: 图 6a 显示了优化的 FP16 到 FP6 转换。虽然我们只绘制从 FP6 到 FP16 的转换来进行演示,但它可以应用于任何位宽。 FP16 的符号字段与 FPx 的符号字段相同。此外,为了提高效率,指数字段的低位和尾数字段的高位可以一起从 FPx 复制到 FP16。此外,FP16 的其他位应该用零填充。 经过精心设计,我们仅用两个按位“与”、一个“移位”和一个“或”就成功实现了从 FP6 到 FP16 的转换,如图 6b 中❶所示。使用第一个“和”将符号字段从 FP6 复制到 FP16,同时将 FP16 的所有其他位初始化为零,从而无需稍后将零填充到指数和尾数字段。然后,FP6 的所有位都通过逐位“右移”右移。之后,首先通过以下方式选择 FP6 中指数的低位和尾数的高位: 之后在 FP6 和位掩码“0x1f1f1f1f”之间进行“与”,然后通过按位运算“或”复制到 FP16。 (2) 位级并行性:考虑到我们可以利用每个 32 位字内的位级并行性,我们建议并行地对多个 FPx 权重进行反量化,进一步减少反量化的运行时开销。 图 6b 以 FP6 为例演示了详细设计。 32 位寄存器被视为四个处理槽,其中每个槽独立工作,使用相同的指令但输入不同的 FP6 数据。在开始去量化之前,应将四个 FP6 存储在 R1(寄存器#1)中,初始数据布局如图所示。通过代码片段❶,这四个FP6可以同时反量化为四个FP16,其中每个FP16仅前8位存储在R2中。之后,将第一个和第二个 FP16 提取到 R1,最后 8 位补零,即代码片段❷。最后,通过代码片段❸和❹,将第三个和第四个FP16提取到R2中。 权重分割和缝合 然后我们将演示在 GPU 上通过精心设计的内存布局从 2+4 方案 [35] 有效重建 6 位权重的方法,该方法也可以应用于其他位宽。 (1)提前权重分割:为了将权重以良好对齐的方式存储在GPU的32位寄存器中,我们将每个权重分割成几个段,其中每个段的位宽为2,例如每个 6 位权重可以分为 2+4 或 4+2。基于该方案,后续设计的指标计算得到显着简化。 请注意,第 5.2 节中描述的技术可以应用于任何位宽度,因此可以根据第 5.2 节分别有效地预打包 2 位和 4 位段。 (2)运行时权重拼接: 在反量化之前,首先将权重从共享内存加载到寄存器。由于每个权重被分成几个段,因此需要在运行时在寄存器级别重建完整的权重。为了减少运行时开销,我们建议并行提取和拼接权重。如图7所示,使用两组寄存器来存储32个FP6权重, 其中,Frag1_PT R 指向包含 32 个 2 位段的两个 32 位寄存器,而 Frag2_PT R 指向包含 32 个 4 位段的 4 个 32 位寄存器。通过我们的并行拼接,可以同时重建四个 FP6 权重,从而将 SIMT 核心指令的数量减少 4 倍。如图 7 所示,首先将四个 2 位段提取到寄存器 #1 (❶),然后将四个 4 位段提取到寄存器 #2 (❷)。之后,寄存器#2 右移 (❸),并将其有效位复制到寄存器 #1 (❹),从而得到完整的 6 位权重。 (3)位重新排序:为了并行提取和缝合权重,有必要强制执行图7中的初始数据布局。关键的观察是每四个连续段必须按图中所示的顺序放置,例如前四个段必须按#2、#4、#1 和#3 的顺序存储。此外,每对 2/4 位段之间的步长应分别为 6/4。否则,不可能仅用四个SIMT核心指令同时拼接四个段。为了满足图 7 中的初始数据布局要求,我们建议通过在运行时之前重新排序权重段来确保这种布局,而无需运行时开销。此外,该技术应该作为附加通道叠加在第 5.2 节中描述的技术上。 总体伪代码算法 1 显示了包括并行去量化和权重拼接的伪代码(GPU 代码)。伪代码中的所有输入和输出变量都存储在寄存器中。如图 7 所示,算法 1 总共对 32 个 FP6 权重进行反量化。对于每个外循环,会生成四个 FP16 权重,并将其存储在代码末尾的两个寄存器中。图 7 中的转换(❶、❷、❸ 和 ❹)分别是通过算法 1 中第 6、7、9 和 10 行的 SIMT 核心操作实现的。然后,Tensor Core 直接使用输出寄存器数组 (OutputReg) 作为输入。 5.4 软件管道设计 为了减少 GPU 寄存器的使用,我们逐片(slice)对权重进行反量化。此外,我们将反量化过程无缝融合到线性层执行的传统软件管道中,通过有效的指令并行性完全隐藏了反量化的运行时开销。 逐片反量化 我们不是一次反量化所有权重,而是逐片反量化 FPx 权重。如图 8a 所示,我们假设 FPx 权重图块和 FP16 激活图块已从 DRAM 复制到共享内存。然后,共享内存中的整个权重块将分几个步骤进行反量化。 在每一步,仅将一部分 FPx 权重从共享内存加载到寄存器,使用 SIMT 高效 GPU 运行时(第 5.3 节)将其反量化为 FP16 权重,然后存储在寄存器缓冲区 A1 或 A2 中作为 Tensor Core 的输入。然后使用 Tensor Cores 将 A 和 $B_{Slice}$ 相乘。 与一次对整个图块进行反量化相比,我们的逐片反量化将存储 FP16 权重所需的寄存器数量减少了 4 倍,从而显着降低了寄存器压力。此外,还为指令级并行性创造了更多机会,因为一旦权重片被反量化,审查核心就可以立即用于计算,而不是等待整个图块。 有效重叠 软件流程通过图 8b 中的时空图进行说明,其中 SIMT 核心(负责反量化)、Tensor 核心(负责矩阵乘法)和 GPU 内存层次结构协同工作,实现高指令级并行性。 首先,全局内存读取是使用 cp.async [20] 内部函数异步执行的,与其他操作完全重叠。 内存屏障和线程块同步在处理第三个切片后(在 k=2 结束时)发出,确保下一个主循环的数据在共享内存中准备就绪,以便“De-quant”(de-quant)量化)并且当k=3时可以开始“ldmatrix”操作。 其次,共享内存读取也与张量核心操作重叠。当计算 islice 时,通过“De-quant”和“ldmatrix”同时从共享内存中读取第 (i + 1) 个切片的数据。 最后但并非最不重要的一点是,用于权重反量化的 SIMT 核心操作也与 Tensor Core 操作有效重叠。 在 第i个slice 的“反量化”过程中,首先使用硬件固有负载共享 (LDS) 将 FPx 权重从共享内存加载到寄存器,然后立即使用 SIMT 内核反量化为 FP16 权重。同时,Tensor Core 正在计算不依赖数据的 (i − 1) 切片。 --- 我们实现了支持矩阵乘法 C = A × B 的 TC-FPx 内核,其中 A 是形状 [M, K] 的权重矩阵,B 是形状 [K, N] 的激活矩阵。 权重矩阵以我们在 5.2 节中描述的自定义格式存储,输入和输出激活矩阵以列优先存储。 因此,我们的 TC-FPx 内核可以直接替代量化 LLMs 推理框架中的 cuBLAS 内核。 我们的 GPU 内核是在 Flash-LLM 代码之上使用超过 1.2K 行 CUDA 代码实现的 [37]。 我们的 TC-FPx 内核可以单独编译成 .so 动态可链接库,并且我们提供了一组 C++ API 来调用内核。 因此,我们的内核可以轻松使用和集成。此外,我们还提供了 C++ API 来预打包权重矩阵(参见第 5.2 节)。 更重要的是,我们通过将我们的内核集成到最先进的推理框架 DeepSpeed [19] 中,为量化 LLMs 的端到端推理提供新的系统支持。 ----------- 评估令牌生成阶段LLMs内线性层的性能。使用 NVIDIA Nsight Compute [23] 测量运行时期间每个 GPU 硬件单元的利用率(第 7.1 节)。 对于端到端评估,我们在具有 CUDA 11.8 的 NVIDIA A100-SXM4-80GB DGX 平台上进行典型 LLMs 的推理。 推理延迟和延迟分解(第 7.3 节)是使用 NVIDIA Nsight 系统 [24] 测量的。 对于每个模型,我们评估了每个 GPU 内核在三种典型推理批量大小(即 8、16 和 32)下的延迟。 TC-FPx 的性能优于 BitsandBytes (W4A16)、cuBLAS (W16A16) 和 TensorRT_LLM(W8A16)高达 8.9 倍、2.6 倍和 1.9 倍。平均而言,当批量大小为 8/16/32 时,TC-FPx 的性能分别优于 BitsandBytes、cuBLAS 和 TensorRT_LLM 7.6×/7.5×/6.6×、2.2×/ 2.2×/2.0× 和 1.3×/1.3×/1.2×。 性能分析 通过广泛的内核分析,我们展示了每个 GPU 硬件单元的利用率,并提供了对性能改进来源的更深入的见解。 在线性层的执行过程中,对于 cuBLAS 基线,当推理批大小小于128时,DRAM 带宽(如图 10a 中的黄线所示)几乎耗尽(>80%),而 GPU Tensor Core(如图 10a 中的黄bar所示),未充分利用(<50%)。 这是大型语言模型推理过程中的常见问题,由大型语言模型的自回归推理方案引起。 在我们对6位量化的支持下,DRAM访问量显着减少(高达2.7倍),缓解了DRAM带宽不足的瓶颈。因此,Tensor Core 可以更有效地用于矩阵计算,如图 10a 中的蓝色条与黄色条所示。 总而言之,我们的内核通过支持 Tensor Core 上的 6 位量化,缓解了“内存墙”问题并实现了更高的计算效率(Tensor Core 的利用率更高)。 此外,它还解释了我们的内核可以超越 TensorRT-LLM 的 W8A16 内核,因为我们可以更有效地减少模型权重的 DRAM 访问。请注意,当推理批量大小较大(大于 128)时,我们的 TC-FPx 内核、cuBLAS 内核和 TensorRT-LLM 的 W8A16 内核的性能最终将收敛到相同的性能,因为它们的性能都将受到 Tensor Core 峰值计算能力的限制。 我们还观察到 BitsandBytes 始终比 cuBLAS 慢,平均速度比 cuBLAS 慢 29.6%。 经过进一步调查,我们发现BitsandBytes采用了双内核方法(在4.1节中讨论)来支持FP4量化。在第一个内核的执行过程中,FP4 模型权重将首先从全局内存加载,反量化为 FP16,然后以 FP16 数据类型写回全局内存。之后,正常 cuBLAS 内核作为第二个内核启动计算矩阵乘法。 因此,由于用于 FP4 反量化的额外 GPU 内核的开销,FP4 GPU 内核总是比原始 FP16 cuBLAS 内核慢。 动态反量化分析图 10b 显示 FP6 到 FP16 反量化的开销有两个方面。 一方面,即使采用我们的 SIMT 高效设计,FP6 到 FP16 去量化也会引入大量按位运算。结果,算术/逻辑单元(ALU)的利用率平均从 6.36% 增加到 38.8%。这也是强有力的证据,表明用于反量化的 SIMT 高效设计(第 5.3 节)至关重要。 另一方面,FP6 到 FP16 去量化还引入了更多浮点乘法,计算权重和量化尺度之间的乘法。一般, FMA装置利用率从0.33%提高到16.64%。 鉴于ALU和FMA单元都是SIMT核心的一部分,反量化操作不会消耗Tensor Core的计算能力。 更重要的是,通过将这些 SIMT 指令与其他操作重叠,可以有效地隐藏 SIMT 内核的运行时开销,我们的新颖设计如第 5.4 节中所述。 工作负载 如第 3 节所述,在保持模型质量方面,6 位量化比 4 位量化更具吸引力。然而,我们仍然将 W6A16 内核的性能与最先进的 W4A16 内核进行比较,充分证明我们的 6 位量化可以实现与现有 4 位量化方法相当的推理速度。我们评估了 LLaMA-65b 模型 [32] 中线性层在不同批量大小下的性能。 基线 这里的主要基线包括来自 TensorRT-LLM [26](提交:6837c81)的 W4A16 对行量化的支持(Coarse-grained_W4A16)和 W4A16 对分组量化的支持(Finegrained_W4A16)最先进的性能。我们在这里还包括 cuBLAS [22] 作为性能基线,清楚地显示了每种量化方法的优点。 结果图 11 显示了 TC-FPx 和在 LLaMA-65b 模型中运行四个不同线性层(例如 L1、L2、L3 和 L4)的其他基线的延迟加速。我们使用 cuBLAS 的性能来规范其他 GPU 内核的性能。 如图 11 所示,TC-FPx_W6A16、Finegrained_W4A16 和 Coarse-grained_W4A16 表现优于 cuBLAS_W16A16 高达 2.4×、3.0× 和 3.3×。 更重要的是,TC-FPx 与 Finegrained_W4A16 实现了相似的性能,当以批量大小 8/16/32 运行所有这些线性层时,TC-FPx 分别比 Fine-grained_W4A16 快 1.06×/ 1.04×/ 0.94×。 此外,在批量大小为 8/16/32 时,TC-FPx 仅比 Coarse-grained_W4A16 慢 16% / 17% / 24%。 由于 6 位量化可以提供显着更高的模型质量,因此这是值得的权衡。 工作负载 我们评估了 FP6-LLM 在各种模型大小的大型语言模型上的端到端推理性能,例如LLaMA-13b [33]、OPT-30b [41] 和 LLaMA-70b [33]。对于每个模型,我们评估了不同批量大小下的令牌生成吞吐量,从 1 开始,直到 GPU 内存耗尽。 公制。我们使用每 GPU 秒的度量标记来表示标准化推理吞吐量,同时考虑执行时间和硬件成本(即使用的 GPU 数量)。 其计算公式如下: N表示生成的令牌数量,而N和T表示GPU数量和第i个GPU执行所花费的时间。 我们使用这个指标来评估本节中的端到端推理性能。 设置和基线 我们将每个请求的预填充/提示长度设置为 0.5K,并为每个请求生成 1.5K 令牌,忽略“EOS”(序列结束)令牌。我们将 TC-FPx 内核集成到 DeepSpeed [19] 中进行端到端评估,并将这个新系统支持称为 FP6-LLM。比较的基准是原始 DeepSpeed 系统的 FP16 执行。使用我们的 FP6-LLM,仅使用单个 80GB A100 GPU 来推理所有工作负载,包括 LLaMA-70b 模型 [33]。相比之下,LLaMA-70b 使用两个 80GB A100 GPU 进行推理 FP16 基线的模型,因为模型权重(约 130 GB)无法适合单个 GPU。 LLaMA-70b 图 12a 显示了使用我们的 FP6-LLM (FP6LLM-1GPU) 和 FP16 基线 (FP16-2GPU) 的 LLaMA-70b 模型上的令牌生成吞吐量。根据我们的实验,我们的 FP6-LLM 和 FP16 基线在 GPU 内存耗尽之前最多可以将推理批量大小设置为 32,而 FP6-LLM 仅需要单个GPU 和基线使用两个 GPU。 结果表明,FP6-LLM 可以实现比 FP16 基线高 1.69×- 2.65× 的归一化推理吞吐量。 我们对这个端到端推理过程进行了仔细的延迟分解。如图 12b 所示,即使 GPU 数量减半,我们的 TC-FPx 内核(用于 FP6-LLM)平均比 cuBLAS 内核(用于 FP16 基线)快 1.20 倍。 此外,使用 FP6-LLM 可以完全避免 NCCL [25] 开销(跨 GPU 通信),因为只需要单个 GPU。我们还注意到 FP16 基线加速了具有 2 路张量并行性的 MHA(多头注意力)的计算 [31]。总体而言,就每 GPU 秒的令牌而言,我们的 FP6-LLM 的吞吐量比 FP16 基线高出 2.65 倍。 $Inference\_Performance = \frac{N_{token}}{\sum_{i=1}^{N_{GPU}} T_i}$ OPT-30b 图 13a 显示了使用 FP6-LLM (FP6-LLM-1GPU) 和 FP16 基线 (FP16-1GPU) 的 OPT-30b 模型上的令牌生成吞吐量。 根据我们的实验,FP6-LLM 在 GPU 内存耗尽之前最多可以将推理批量大小设置为 16,而 FP16 基线最多可以在一个批次中服务 4 个请求。因此,FP6-LLM 在批量大小为 16 时最多可以实现每 GPU 秒 319.1 个令牌(高出 4.05 倍),而 FP16 基线在批量大小为 4 的情况下最多可以实现每 GPU 秒 78.8 个令牌,给定相同的 GPU 预算。 此外,当批量大小设置为 1/2/4 时,与 FP16 基线相比,FP6-LLM 可以实现 1.91×/ 1.84×/ 1.72× 高的生成吞吐量。这些整体性能的改进主要来自执行线性层的时间的减少。 如图 13b 所示,TC-FPx 内核平均比 FP16 cuBLAS 内核快 2.39 倍。 LLaMA-13b 图 14a 显示了使用 FP6-LLM (FP6LLM-1GPU) 和 FP16 基线 (FP16-1GPU) 的 LLaMA-13b 模型上的令牌生成吞吐量。 根据实验,FP6-LLM 和 FP16 基线在内存耗尽之前最多可以将推理批量大小设置为 32。平均而言,与使用相同批量大小的 FP16 基线相比,FP6-LLM 可以实现 1.23 倍的生成吞吐量。 由于非内核开销,与前两个模型相比,该模型的整体性能改进不太显着。 根据图 14b,TC-FPx 内核的线性层执行时间显着减少(平均快 2.11 倍)。然而,运行其他 GPU 内核的部分加上 GPU 空闲时间会增加,从而削弱了整体性能的提升。 原因是,随着模型尺寸变小,由于内核启动延迟和 GPU 同步,GPU 往往会拥有更大比例的空闲时间。 相关设计技术[40]和[35]先前提出了4+2权重分割。然而,他们只提出了直观的想法,而没有进行全面的系统设计。 Zeroquant(4+2): Redefining llms quantization with a new fp6-centric strategy for diverse generative tasks. arXiv preprint arXiv: 2312.08583, 2023. [40] Zhewei Yao, Xiaoxia Wu, Cheng Li, Stephen Youn, and Yuxiong He. Zeroquant-v2: Exploring post-training quantization in llms from comprehensive study to low rank compensation, 2023. 在本文中,我们介绍了TC-FPx,这是第一个全栈GPU内核设计方案,统一张量核心支持各种量化位宽的浮点权重,缓解LLM 推理提供新的端到端支持(称为 FP6-LLM),其中在推理成本和模型质量之间实现了更好的权衡。 FP6-LLM通过一系列新颖的技术解决了硬件不友好的内存访问和反量化高计算开销的问题,以显着更少的GPU内存实现了更快的推理速度。评估表明,FP6-LLM 仅使用单个 GPU 即可实现 LLaMA-70b 的推理,实现比 FP16 基线高 1.69×-2.65 倍的归一化推理吞吐量。此外,FP6-LLM将OPT-30b的推理吞吐量提高了1.72×-4.05×。 ================================================ FILE: llm-compression/quantization/GPTQ.md ================================================ LLM.int8() 和 SmoothQuant 都属于 round-to-nearest (RTN) 量化:舍入到最近的定点数。GPT-Q 则是把量化问题视作优化问题,逐层寻找最优的量化权重。 非对称量化、并逐层进行处理 zero point quantization ================================================ FILE: llm-compression/quantization/LLM-int8.md ================================================ LLM.in8() 论文中发现:激活中存在一些离群值,它们的绝对值明显更大;并且这些离群值分布在少量的几个特征 (features) 中,称为离群特征 (Emergent Features)。 不论是 per-token 还是 per-channel quantization,都会受到这些离群值的很大影响。 - https://github.com/TimDettmers/bitsandbytes 本质上,LLM.int8() 通过三个步骤完成矩阵乘法计算: 1. 从输入的隐含状态中,按列提取异常值 (即大于某个阈值的值)。 2. 对 FP16 离群值矩阵和 Int8 非离群值矩阵分别作矩阵乘法。 3. 反量化非离群值的矩阵乘结果并其与离群值矩阵乘结果相加,获得最终的 FP16 结果。 ## 离群特征的重要性 超出某个分布范围的值通常称为离群值。离群值检测已得到广泛应用,在很多文献中也有涉及,且获取特征的先验分布对离群值检测任务很有助益。 更具体地说,我们观察到对于参数量大于 6B 的 transformer 模型,经典的量化方法会失效。 虽然离群值特征也存在于较小的模型中,但在大于 6B 的 transformer 模型中,我们观察到几乎每层都会出现超出特定阈值的离群点, 而且这些离群点呈现出一定的系统性模式。 如前所述,8 位精度的动态范围极其有限,因此量化具有多个大值的向量会产生严重误差。 此外,由于 transformer 架构的固有特性,它会将所有元素互相关联起来,这样的话,这些误差在传播几层后往往会混杂在一起。 因此,我们发明了混合精度分解的方法,以对此类极端离群值进行有效量化。 ## MatMul 内部 计算隐含状态后,我们使用自定义阈值提取离群值,并将矩阵分解为两部分,如上所述。 我们发现,以这种方式提取所有幅度大于等于 6 的离群值可以完全恢复推理精度。 离群值部分使用 FP16 表示,因此它是一个经典的矩阵乘法, 而 8 位矩阵乘法是通过使用向量量化将权重和隐含状态分别量化为 8 位精度 - 即按行量化权重矩阵,并按列量化隐含状态,然后再进行相应向量乘加操作。 最后,将结果反量化至半精度,以便与第一个矩阵乘法的结果相加。 ![](https://huggingface.co/blog/assets/96_hf_bitsandbytes_integration/Matmul.png) ================================================ FILE: llm-compression/quantization/PEQA.md ================================================ PEQA 参数高效的微调(PEFT)方法已经出现,以减轻全面微调大型语言模型(LLM)的高昂成本。 尽管如此,法学硕士的庞大规模阻碍了常规部署。 为了解决这个问题,我们提出了参数高效和量化感知适应(PEQA),这是一种新颖的量化感知 PEFT 技术,可以促进模型压缩并加速推理。 PEQA 通过双阶段过程运行:最初, 每个全连接层的参数矩阵经过量化为低位整数矩阵和标量向量; 随后,对每个下游任务的标量向量进行微调。 这种策略大大压缩了模型的大小,从而降低了部署时的推理延迟并减少了所需的总体内存。 同时,快速微调和高效的任务切换成为可能。 通过这种方式,PEQA 提供了量化的好处,同时继承了 PEFT 的优点。 我们比较 PEQA 在从自然语言理解到生成基准的综合实验中具有竞争性基准。 这是使用多达 650 亿个参数的大型语言模型完成的,展示了 PEQA 的可扩展性、特定于任务的适应性能以及遵循指令的能力,即使在极低位设置下也是如此。 ================================================ FILE: llm-compression/quantization/QQQ-W4A8.md ================================================ ``` git clone git@github.com:liguodongiot/QQQ.git ``` ================================================ FILE: llm-compression/quantization/README.md ================================================ ## 简介 - https://docs.nvidia.com/deeplearning/tensorrt/tensorflow-quantization-toolkit/docs/docs/qat.html - Quantization Aware Training (QAT) - https://github.com/HuangOwen/Awesome-LLM-Compression - https://blog.csdn.net/jinzhuojun/article/details/106955059 - 闲话模型压缩之量化(Quantization)篇 一文总结当下常用的大型 transformer 效率优化方案 - https://zhuanlan.zhihu.com/p/604118644 - https://lilianweng.github.io/posts/2023-01-10-inference-optimization/ Introduction to Weight Quantization:Reducing the size of Large Language Models with 8-bit quantization - https://towardsdatascience.com/introduction-to-weight-quantization-2494701b9c0c 大规模 Transformer 模型 8 比特矩阵乘简介 - 基于 Hugging Face Transformers、Accelerate 以及 bitsandbytes - https://huggingface.co/blog/zh/hf-bitsandbytes-integration Neural Network Weight Quantization(入门):https://www.analyticsvidhya.com/blog/2025/01/neural-network-weight-quantization/ ## 量化工具 - https://github.com/vllm-project/llm-compressor/ - https://nvidia.github.io/TensorRT-Model-Optimizer/guides/_choosing_quant_methods.html - https://github.com/NVIDIA/TensorRT-Model-Optimizer/tree/main/examples/llm_ptq --- 在深度神经网络上应用量化策略有两种常见的方法: - 训练后量化(PTQ):首先需要模型训练至收敛,然后将其权重的精度降低。与训练过程相比,量化操作起来往往代价小得多; - 量化感知训练 (QAT):在预训练或进一步微调期间应用量化。QAT 能够获得更好的性能,但需要额外的计算资源,还需要使用具有代表性的训练数据。 值得注意的是,理论上的最优量化策略与实际在硬件内核上的表现存在着客观的差距。**由于 GPU 内核对某些类型的矩阵乘法(例如 INT4 x FP16)缺乏支持,并非下面所有的方法都会加速实际的推理过程**。 ## Post Training Quantization(PTQ) - ZeroQuant: Efficient and Affordable Post-Training Quantization for Large-Scale Transformers - https://www.deepspeed.ai/tutorials/model-compression/ - 集成在Deepspeed - SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models - https://github.com/mit-han-lab/smoothquant - 已经集成在[FasterTransformer](https://github.com/NVIDIA/FasterTransformer) - GPTQ: Accurate Post-training Compression for Generative Pretrained Transformers - AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration - https://github.com/mit-han-lab/llm-awq - LLM.int8() - LLM.int8()——在大模型上使用int8量化:https://zhuanlan.zhihu.com/p/586406082 - OWQ: Lessons learned from activation outliers for weight quantization in large language models - https://github.com/xvyaward/owq - Spqr: A sparse-quantized representation for near-lossless LLM weight compression - https://arxiv.org/pdf/2306.03078.pdf - Tim Dettmers - LLM.int8() - Tim Dettmers - RPTQ - https://github.com/hahnyuan/RPTQ4LLM - OliVe - Outlier Suppression+ - https://github.com/wimh966/outlier_suppression ## Quantization Aware Training(QAT) - LLM-QAT: Data-Free Quantization Aware Training for Large Language Models - https://github.com/facebookresearch/LLM-QAT ================================================ FILE: llm-compression/quantization/SmoothQuant.md ================================================ # 源码解读 - https://www.armcvai.cn/2024-10-30/llm-smoothquant.html - https://www.armcvai.cn/2024-10-31/smoothquant-inplement.html # SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models - https://huggingface.co/mit-han-lab/opt-6.7b-smoothquant absmax quantization - 英特尔模型压缩库-SQ:https://github.com/intel/neural-compressor/blob/master/docs/source/smooth_quant.md - 英特尔模型压缩库-仅权重量化方法:https://github.com/intel/neural-compressor/blob/master/docs/source/quantization_weight_only.md https://github.com/Guangxuan-Xiao/torch-int/ ## 概要 大语言模型 (LLM) 显示出了出色的性能,但属于计算和内存密集型。 量化可以减少内存并加速推理。 然而,现有方法无法同时保持准确性和硬件效率。 我们提出了 SmoothQuant,这是一种免训练、同时保持精度的通用训练后量化 (PTQ) 解决方案, 可为 LLM 实现 8 位权重、8 位激活 (W8A8) 量化。 基于权重易于量化而激活却不易量化的事实,SmoothQuant 通过使用数学上等效的变换平滑激活异常值,从而将量化难度从激活离线迁移到权重 SmoothQuant 支持 LLM 中所有矩阵乘法的权重和激活的 INT8 量化,包括 OPT、BLOOM、GLM、MT-NLG 和 LLaMA 系列。 我们证明了 LLM 的加速速度高达 1.56 倍,内存减少了 2 倍,而精度损失可以忽略不计。 SmoothQuant 支持在单个节点内提供 530B 的 LLM 服务。 我们的工作提供了一个交钥匙解决方案,可以降低硬件成本并使LLM普及。 ## 结论 我们提出了 SmoothQuant,这是一种准确且高效的训练后量化方法,可为高达 530B 参数的 LLM 实现无损 8 位权重和激活量化。 SmoothQuant 能够对 LLM 中的所有 GEMM 的权重和激活进行量化,与混合精度激活量化基线相比,这显著减少了推理延迟和内存使用量。 我们将 SmoothQuant 集成到 PyTorch 和 FasterTransformer 中,获得高达 1.56 倍的推理加速并将内存占用减半。 SmoothQuant 通过提供了一种交钥匙解决方案来降低服务成本,使LLM的应用普及。 ================================================ FILE: llm-compression/quantization/SpinQuant.md ================================================ ================================================ FILE: llm-compression/quantization/ZeroQuant(4+2).md ================================================ 由于先进的算法设计(例如 GPTQ [19] 和 LoRC [69]),质量下降大大减少]。 然而,这些进步主要集中在零样本评估上,可接受的质量下降是针对较大的模型尺寸(大于 13B),但它们通常需要对较小的模型尺寸(例如 1B)进行重大权衡。此外,他们只关注零样本测量[62, 69]。 在生产环境中,复制原始模型的不同任务的性能至关重要,模型质量的任何损失都是一个主要问题。 现有方法虽然具有创新性,但并不能完全满足在实际应用中部署LLMs的实际要求。 为了应对这些挑战,我们的贡献如下: 扩大评估范围和量化分析。我们的研究表明,现有的定量 像 GPTQ 这样的标准化方法往往会过度拟合校准数据集。更重要的是,我们扩大了 LLMs 中 4 位量化分析的范围,以包括零样本之外的任务,例如代码生成和抽象摘要。我们发现 INT4 量化通常表现不佳,尤其是在较小的模型中,甚至在参数高达 130 亿个的情况下,例如 LLaMA-13b。详细信息请参见第 3 节。 FP6 量化的卓越性能。我们说明了 FP6 采用基本的舍入最近 (RTN) 算法和粗粒度量化方法,始终达到与全精度模型相当的精度,在广泛的生成任务中证明了高度有效。具有 FP6 量化功能的 StarCoder-13B 模型在代码生成任务中的性能与其 FP16 等效模型相匹配。对于 406M 等较小型号,它与汇总中的基线结果密切相关。这些成就超出了 INT4 量化的能力。如需更深入的探索,请参阅第 4 节。 创新的4+2 FP6设计。我们为 FP6 引入了创新的 4+2 设计,克服了 AI 硬件上先前的集成和加速问题。该设计实现了与最先进的 INT4 细粒度量化类似的延迟,使 FP6 成为 LLMs 中现有 4 位量化方法的可行替代方案。详细信息请参见第 5 节。 都使用零样本困惑度或准确性等指标来评估量化的影响[66,19,8,2,29]。然而,鉴于LLMs的主要现实应用,例如ChatGPT[5]和Codex[21],都是围绕基于生成的任务展开的,因此需要一个更全面的量化LLMs评估框架b1002> 是有保证的。 -------- 评估: Zero-Shot 评估 (Perplexity) RTN。舍入到最近邻 GPTQ 最突出的是 SmoothQuant [66]、AWQ [38]、Quip [8]、 SqueezeLLM [ 29]、QUIK [ 2 ] 和 LLM-FP4 [ 40] 以及更多 [ 69, 14]。然而,这些方法通常需要使用额外的稀疏矩阵或额外的程序来精确定位敏感权重。 此外,这些研究大多数主要集中在零样本困惑度和准确性性能上[69,19,62]。然而,这些发现在多大程度上可以推广到其他生成任务仍有待充分探索。 通过三个指标评估性能:零样本任务、代码生成和总结。我们还尝试对那些基于聊天的模型进行比较实验,并根据 FastChat 代码通过 GPT-4 进行判断[75]。尽管如此,由于我们的研究结果存在显着差异,我们得出的结论是位精度和性能之间没有明确的联系。 三个标评估性能 Zero-Shot 任务 的 困惑度和准确性 生成任务(ROUGE 或Pass@1) 总结任务() GPTQ 的过度拟合倾向。 尽管 GPTQ 在训练后量化方面具有创新性,但它往往会过度拟合特定的数据集,尤其是其细粒度量化结果。如表 1 所示,我们看到,如果我们使用特定数据集(例如 GPTQ 的 C4)进行校准,那么该 C4 数据集的性能会好得多(使用 FGQ 参见 9.34 或 6.74),而其他数据集(例如 PTB)会导致性能更差( 对于较大的模型(从 1B 移动到 13B 或 65B),过拟合现象不太严重。事实上,如表 2 所示,我们看到 LLaMA-65B 在 FGQ 上使用 GPTQ 作为 INT4 权重,与 RTN (7.17) 相比,得到最佳平均困惑度 6.61,更接近基线 6.41。然而,它在增强零样本性能方面的有效性有些有限(详见表3),这表明它在各种语言建模场景的适应性方面存在差距,并强调了模型评估中鲁棒性的必要性。 特别是,我们在表 3 中展示了 RTN 和 GPTQ 在 INT4 权重上的比较,同时保持激活不变,我们不能声称 GPTQ 和 RTN 比基于零样本性能的另一个更好。事实上,对于 LLaMA-65B,RTN 的性能比 FP16 的性能要好得多。 LLMs的核心优势在于其生成序列的能力。 本文重点是评估摘要和代码生成,如表 4 所示。该策略强调了超越零样本学习的全面且详细的测试方法的重要性,旨在全面评估 LLMs 的生成能力。 表 4 中的数据显示 INT4 的性能存在显着差异,尤其是与标准基准测试相比。例如,Java-Script 中的 CodeLLaMA-34B 模型的性能从 45.05 (FP16) 下降到 43.45 (INT4, CGQ) 或 43.22 (INT4, FGQ),分别下降了 1.6 和 1.83 个点。 虽然 INT4 上的 FGQ 比 CGQ 提供了相当大的改进,但与 FP16 相比仍然存在差距,特别是对于较小的模型和 Java 脚本。 有趣的是,FGQ 上的 INT4 CodeLLaMA-34B 在 Python 代码中得分为 46.88,超过了其基准,而 FGQ 上的 INT4 CodeGeeX2-6B 得分仅为 29.8,甚至落后于其 INT4-CGQ 性能。这凸显了 INT4 的不一致性。 这些结果强调需要研究 INT4 在复杂生成任务中的有效性。 其在代码生成和摘要任务中的不稳定性和低于标准的结果,本节深入探讨了浮点量化研究中的一个新兴领域。 最近的研究越来越关注使用浮点量化来处理LLMs内的权重或激活。 -------- 基于之前围绕 INT4 量化相关挑战和局限性的讨论,特别是其在代码生成和摘要任务中的不稳定性和低于标准的结果,本节深入探讨了浮点量化研究中的一个新兴领域。最近的研究越来越关注使用浮点量化来处理LLMs内的权重或激活[62,40,74,44,7,32,58]。值得注意的是,简单的 FP8 在激活过程中的应用比 INT8 的使用显示出显着的改进 [62]。受这些进步的启发,出现了一个关键问题:提高位精度(例如提高到 5 位或 6 位)能否在生成任务中提供更稳定、更稳健的结果?本节旨在探讨 FP6(FP5)的有效性程度及其对不同量化算法的弹性,为之前 INT4 量化挑战带来的困境提供潜在的解决方案。 为了完整起见,我们提供浮点格式的简化概述。详细解释请参考[10]。标准浮点数由三部分组成:符号位、指数位和尾数位。这可以简化为: 为什么不用 INT6 而不是 FP6? 选择 FP6 而不是 INT6 是由两个关键因素驱动的:首先,FP 格式简化了转换过程,因为最终计算通常使用 FP16 或 BF16 执行。 其次,正如[62]中的研究结果所支持的,这些格式之间的准确性没有观察到差异,从而无需额外的实验验证。 使用pass@k指标评估功能正确性,即每个问题生成k个代码样本,如果有任何样本通过单元测试,则认为问题已解决,并报告问题解决的总比例。然而,以这种方式计算pass@k会有很高的方差性。相反,为了评估pass@k,我们为每个任务生成n≥k的样本(在本文中,我们使用n=200,k≤100),计算通过单元测试的正确样本c≤n的数量,并计算出无偏估计器。 因为我们没有发现位精度和性能之间存在明确的联系。 FP6 稳健性。 FP6 量化,尤其是 CGQ 的量化,展示了显着的进步,在各种任务和模型中几乎匹配 FP16 基线。 这种量化方法不仅缩小了 FP5 和 INT4 的性能差距,而且在处理不同任务时表现出鲁棒性。 在 FP6 框架内比较 CGQ 和 FGQ 时,鲁棒性得到进一步强调(因为有 CGQ 和 FGQ 之间差别不大),其中带有 CGQ 的 FP6 始终保持接近基线的高性能,表明其在不同场景下的有效性和稳定性。 此外,FP6 对量化算法具有鲁棒性:RTN 或 GPTQ 都会产生相似的结果,特别是对于 CodeLLaMA-34B,如表 6 所示。 ------------ 此方法与两种通常考虑的策略不同: 第一种方法涉及直接将 6 位格式转换为 8 位浮点 (FP8) 格式。虽然这是一个简单的解决方案,但不幸的是,它否定了 6 位格式的主要优点,即节省内存。 第二种方法需要将多个 6 位数字组合在一个连续的内存块中,并使用 32 位整数 (INT32) 或 32 位浮点 (FP32) 格式表示它们。该方法保持了节省内存的优势,但增加了反量化过程的复杂性。 我们独特的策略侧重于将 6 位数字划分为两个不同的子数字:第一个子数字代表最初的 4 位,第二个子数字代表剩余的 2 位。 我们提出的“4+2”方法可以看作是第二种标准方法的高级变体。 4+2 位除法基于任何正整数都可以表示为 2 的幂和的基本原理。 4+2 位除法的基本原理是,任何正整数都可以表示为 2 的幂和。 在此基础上,我们将 6 位数字分为两个部分: 第一部分由最初的 4 位组成,处理符号位和 3 位指数等元素。 第二部分包含剩余的 2 位,专用于 2 位尾数。 这种划分为 4+2 位的方式有利于这些子数的同时加载和反量化,最终生成最终的 16 位浮点 (FP16) 权重。 我们的方法创新地平衡了减少内存占用的需求与反量化的实用性,特别是在解决跨分段数字内存访问的挑战方面。 偏置转移 在 GPU 上运行时将 FP6 反量化为 FP16 可能会占用大量资源,这主要是由于操作指数字段所涉及的复杂性,如第 4 节所述。 指数的偏置项通常由指数位确定,对于 FP6 为 3,对于 FP16 为 15。数学上,将FP6反量化为FP16(不包括符号)的过程表示为: 其中上标 FP16/FP6 表示各自的格式。 值得注意的是,缩放因子反量化可以在细粒度(子行)量化方案的累加之前的矩阵乘法之后进行,或者在粗粒度(行方式)量化方案的累加之后进行。 虽然填充(padding)可以轻松调整尾数,但由于偏置的差异,对齐指数需要更多的努力。可以通过将 INT4 数字转换回对称 INT8 格式来进行类比:如果 INT4 采用对称格式(对于尾数),则零填充就足够了。然而,在非对称格式中,单独填充是不够的,还需要额外的步骤。 为了解决这个问题,我们定制了 FP6 格式,其非标准指数偏置为 15。此修改不会影响精度或准确度,因为: 这意味着偏置偏移可以无缝集成到缩放因子中。至关重要的是,由于 Si 小于 1,因此将其与 2 相乘仍然可以通过简单的指数位移位以 FP16 格式准确表示,从而避免数值错误。 我们的偏置偏移方法极大地简化了运行时的 FP6-FP16 去量化过程。 为了证明这一点,我们在图 1a 和 1b 中进行了并排比较。 图 1a 概述了对每个 FP6 权重进行去量化的原始两步过程。第一步涉及将 W 转换为 W,第二步需要乘以量化比例 S。此过程中要求最高的部分是重新计算 W 的指数,其中涉及从 W 中提取 E,加上 12,然后将其合并回W. 此外,对次正规 FP6 数进行反量化的过程进一步增加了运行时反量化的复杂性。 然而,利用我们的偏置转移策略,如图 1b 所示,指数调整变成了一个简单的位级填充过程。最初在步骤 1 中需要添加常量整数 12,现在可以推迟到步骤 2,从而消除任何运行时开销。这是可能的,因为量化比例与常数整数的乘法可以在模型量化之后和运行时之前静态地执行。此外,这种简化的方法还有效地适应了subnormal数的反量化。 FP6 内核通过 Bias-Shift 增强,速度比 cuBLAS 快 2.37 倍,平均快 1.92 倍。鉴于 LLM 推理通常受到有限的 GPU DRAM [64, 30] 的限制,我们的方法通过最小化模型权重内存访问有效地缓解了这一瓶颈。此外,我们的 FP6 内核在速度上优于最先进的细粒度 INT4 实现,第一前馈层 (FFN1) 平均快 1.06 倍,第二前馈层平均快 2.05 倍( FFN2)。应该指出的是,图 2 仅提供了关键成果的快照,全面的系统实现和详细的性能分析为将来的工作保留。重要的是,我们带有 Bias-Shift 的 FP6 内核比没有 Bias-Shift 的相同 FP6 内核平均快 1.36 倍,这强调了 Bias-Shift 的关键作用,如第 5.2 节中讨论的那样。 奇数位 GPU 内核优化 ================================================ FILE: llm-compression/quantization/ZeroQuant.md ================================================ ## ZeroQuant 由于内存/计算要求过高,即使对于强大的云服务器来说,如何在实践中有效地服务越来越大的模型也变得异常具有挑战性。在这项工作中,我们提出了一种高效且经济实惠的训练后量化方法来压缩基于 Transformer 的大模型,称为 ZeroQuant。 ZeroQuant 是一个端到端量化和推理管道,具有三个主要组件: - 1)针对权重和激活的细粒度硬件友好量化方案; - 2)一种新颖的、经济实惠的逐层知识蒸馏算法(LKD),即使无需访问原始训练数据; - 3) 提供了一个高度优化的量化系统后端,以消除量化/反量化开销。 因此,我们能够证明: (1) ZeroQuant 可以将 BERT 和 GPT-3 等模型的权重和激活精度降低到 INT8,对模型准确率的影响最小,同时,与 FP16 推理相比,这些模型的推理速度提高了 5.19 倍/4.16 倍; (2) ZeroQuant 加上 LKD 可将全连接模块中的权重量化为 INT4,以及注意力模块中的INT8权重和INT8激活,与FP16模型相比,内存占用减少了3倍; (3)ZeroQuant可以直接应用于GPT-J和GPT-NeoX等,其中我们的INT8模型达到了与FP16模型相似的精度,但效率提高了5.2倍。 将 INT8 PTQ 应用于 BERT/GPT-3 模型也会导致准确性显著下降。 关键的挑战是 INT8 的表示无法完全捕获权重矩阵中不同行和不同激活Token的不同数值范围。解决这个问题的一种方法是对权重矩阵(激活)使用group-wise(token-wise)量化。 用于权重的分组量化 分组权重矩阵量化首先在Q-BERT中提出,其中权重矩阵 $W \in R^{n \times m}$被划分为 g 个组,每个组单独量化。然而,在Q-BERT中,作者仅将其应用于量化感知训练。更重要的是,他们没有考虑硬件效率约束,也没有系统后端支持。因此,它们缺乏真正的降低延迟。 用于激活的按token量化 现有 PTQ 工作的常见做法是对激活使用静态量化,其中最小/最大范围是在离线校准阶段计算的。 对于激活范围方差较小的小模型来说,这种方法可能就足够了。 然而,GPT-3 和 BERT 等大 Transformer 模型的激活范围存在巨大差异。因此,静态量化方案(通常应用于所有tokens/样本)将导致准确度显著下降。克服这个问题的一个自然想法是采用更细粒度的token-wise量化并动态计算每个token的最小/最大范围,以减少激活引起的量化误差。 ZeroQuant 构建了一个高度优化的推理后端,用于Transformer模型 token-wise 量化。 例如,ZeroQuant 的推理后端采用所谓的内核融合技术将量化运算与其先前的运算(如:层归一化)融合,以减轻 token-wise 量化的数据移动成本。类似地,在将最终 FP16 结果写回到下一个 FP16 运算(如:GeLU)的主存储器之前,使用权重和激活量化 scales 缩放 INT32 accumulation,可以减轻不同 GeMM 输出的反量化成本。 Token-wise 量化可以显着减少量化激活的表示误差。它不需要校准激活范围,对于ZeroQuant 的量化方案(INT8 权重和 INT8 激活)不存在与量化相关的成本(例如,激活范围校准)。 我们在第 5 节中的评估还表明,针对激活的 token-wise 量化显著提高了 GPT-3 和 BERT 模型的准确性。 ### 权重量化 ZeroQuant (论文:ZeroQuant: Efficient and Affordable Post-Training Quantization for Large-Scale Transformers)对权重做group-wise,对激活值做token-wise。用逐层知识蒸馏缓解精度损失(原网络做老师),量化后的网络做学生。和W8A8的普通方法做比较,在BERT和GPT3-style模型上精度更好,还能把权重量化到4bit,但加速效果糟糕。 逐层知识蒸馏 知识蒸馏(KD)是缓解模型压缩后精度下降的最有力方法之一。然而,KD 存在一些局限性,特别是对于大规模语言模型上的隐藏状态 KD: (1)KD 需要在训练过程中将教师和学生模型放在一起,这大大增加了内存和计算成本; (2)KD通常需要对学生模型进行充分训练。因此,需要在内存中存储权重参数的多个副本(梯度、一阶/二阶动量)来更新模型; (3) KD通常需要原始训练数据,有时由于隐私/机密问题而无法访问。 为了解决这些限制,我们提出了逐层蒸馏(LKD)算法。 假设量化的目标模型有 N 个transformer块 L, ..., L,可访问数据集具有输入 (X, Y),其可以是原始训练数据或来自其他资源的数据集。 我们的 LKD 逐层量化网络,并使用其原始(即未量化)版本作为教师模型。更具体地说,假设第 Li 层将被量化,其量化版本为 --- 量化优化的 Transformer kernel 优化推理延迟和模型大小对于在实践中服务大Transformer 模型至关重要。在推理过程中,batch size往往比较小,因此模型的推理延迟主要取决于从主存加载推理所需数据的时间。通过将权重和激活量化到较低的精度,我们减少了加载这些数据所需的数据量,从而可以更有效地使用内存带宽和更高的加载吞吐量。 然而,简单地将权重/激活转换为 INT8 并不能保证延迟的改善,因为存在与量化/反量化操作相关的额外数据移动开销, 如图 2(红色框)所示。这样的开销变得昂贵,并且在某些情况下超过了使用低精度的性能优势。 为了从 token-wise 量化中获得准确性的提高,同时获得更好的延迟,我们现在提出了我们的优化,可以最大限度地提高内存带宽利用率,以加快 ZeroQuant 的推理延迟。 CUTLASS INT8 GeMM 为了支持 INT8 计算,我们使用针对不同批量大小进行调整的 CUTLASS INT8 GeMM 实现。与标准 GPU 后端库(例如 cuDNN)不同,使用 CUTLASS 允许我们在 GeMM 之前和之后更灵活地融合量化操作,以减少kernel启动和数据移动开销。 融合Token-wise激活量化 Token-wise量化/反量化引入了许多额外的操作,从而导致额外的数据移动成本。为了消除这些成本,我们使用核融合将激活的量化操作与其之前的 element-wise 和/或 归约操作(例如: bias-add、GeLU 和 LayerNorm)融合到单个运算中,如绿色框所示如图 2 所示。 对于反量化操作(例如,对 GeMM 运算的整数输出进行反量化),我们同样将其与自定义 GeMM 调度融合,以避免对主存储器进行额外的读/写访问,如图 2 中的蓝色框所示。 通过进行上述优化,我们能够在第 5 节中展示 BERT 和 GPT-3 型模型的延迟显着减少。 --- ## ZeroQuant-v2 训练后量化 (PTQ) 已成为一种有前途的技术,可减少大语言模型中的内存消耗和计算成本 (LLMs)。然而,目前缺乏对各种量化方案、模型族和量化位精度的系统检查。 在本文中,我们通过使用舍入到最近(RTN)、GPTQ、 ZeroQuant 及其变体。我们将这些方法应用于参数范围从 125M 到 176B 的两个不同的模型系列。 我们的贡献包括: (1)敏感性分析表明,激活量化通常更容易受到权重量化的影响,较小的模型在激活量化方面通常优于较大的模型; (2) 对现有 PTQ 方法进行评估和比较,使模型尺寸减小,同时最大限度地减少对精度的影响,揭示当前的方法使用 INT4 权重 或 INT4 权重和INT8激活 进行量化都无法达到原始模型质量; (3)基于这些见解,我们提出了一种称为低秩补偿(LoRC)的优化方法,该方法采用低秩矩阵以最小的模型参数大小的增加来提升模型质量的恢复。 进一步突破训练后量化限制提出的方法 根据前几节的调查和结论,显然仍然需要一种先进的方法来进一步完善现有方法,以完全实现原始 FP16 PPL 质量为目标。 在本节中,我们将介绍一种简单而有效的方法,称为LoRC(低阶补偿),以优化当前存在的量化误差,并进一步缩小原始模型质量与其进行量化后对应的模型的质量之间的差距。 LoRC 的灵感来自于对量化误差矩阵 E := W − ˆW 进行低秩矩阵分解,其中 W 表示原始权重,^ W 是量化权重。 LoRC 通过使用两个低秩矩阵 ^ U 和 ^ V 来近似误差 E : ^ E = ^ U ^ V 。这样可以通过 ^ W= ^ W + ^ E 更准确地近似原始权重矩阵 W,从而减少量化误差:∥W − ˆW ∥ ≥ ∥W − ˆW∥。 LoRC 包含两个步骤: 步骤 I:在误差矩阵 E = U ΣV 上实现奇异值分解(SVD),其中 U ∈ Rand V ∈ Rare 酉矩阵,Σ ∈ Ri 是一个对角矩阵,其对角元素按降序排列方式。 LoRC 的目标是使用低秩矩阵实现误差矩阵 E 的良好近似,同时对模型大小的增加影响最小。例如,考虑标准变压器模型[32],其中每一层都由多头注意力(MHA)模块和多线性感知(MLP)模块组成。令 h 表示隐藏维度,l 表示层数。参数总数为 12l,每层包含 4h for MHA(用于键、查询、值和投影矩阵)和 8h for MLP(两个大小为 h × 4h 和 4h × h 的矩阵)。在六个中添加了低阶 LoRC 可以得出几个关键的观察结果。首先,LoRC 始终如一地提高所有位大小和块大小的性能,正如 LoRC 激活时较低的困惑度分数所表明的那样。其次,LoRC带来的增强随着比特大小的减小而变得更加显着,尤其是对于W2A16来说更为明显,在大多数场景下与W4A16和W3A16相比,其影响明显更大。最后,细粒度量化与 LoRC 的结合产生了最令人印象深刻的结果,强调了 LoRC 与 FGQ 集成时的功效。总体而言,结果强调了使用 LoRC 增强权重量化性能的好处及其与 FGQ 的兼容性。值得注意的是,恢复最后 0.05-0.1 的困惑度可能具有挑战性,但通过 LoRC,我们几乎能够恢复 INT4 量化的原始模型质量。 ## ZeroQuant-FP(浮点W4A8) 在大语言模型领域,在计算效率和保持模型质量之间取得平衡是一项艰巨的挑战。为了克服统一量化的固有局限性,特别是在处理异常值时,并受到 NVIDIA H100 硬件推出的推动,本研究深入探讨了浮点 (FP) 量化的可行性,特别关注 FP8 和 FP4 作为潜在解决方案。 通过调查显示: - 对于 LLMs,FP8 激活始终优于其整数 (INT8) ,并且在参数超过 10 亿的模型中,性能优势变得更加明显。 - 对于权重量化,FP4 表现出与 INT4 相当(即使不是更优)的性能,从而简化了在 H100 等支持 FP 的硬件上的部署。 为了减轻权重和激活之间的差异引起的精确对齐的开销,本文提出了两个权重量化的缩放约束,与标准 W4A8 模型相比,它们对性能的影响可以忽略不计。我们还通过集成低秩补偿(LoRC)策略来增强我们的量化方法,特别是在较小的模型中也有提升。 --- LLM由于复杂性和计算强度带来了部署挑战,特别是在资源有限的环境中。一种解决方案是量化,它以较低精度格式(例如:8 位整数或浮点数)表示数据,从而减少内存需求,并通过兼容 GPU 上更好的 GEMM 计算吞吐量潜在地增强推理延迟。训练后量化 (PTQ) 会直接降低完全训练模型参数的精度,由于其简单性和较低的计算开销,通常是 LLMs 的首选。最近的研究表明 PTQ 在 8 位整数上(INT8) 仅权重量化不会损害 LLMs 的质量,并且当应用 GPTQ 等高级算法时,INT4 权重量化仅观察到较小的精度下降。 除了仅权重量化之外,对激活量化的探索也引起了人们的兴趣。这种方法利用统一的精度来加快推理时间,从而在硬件上实现更高效的执行。实现激活量化的主要挑战在于效率和性能之间的权衡。正如 ZeroQuants [34, 35]、SmoothQuant [33] 等研究所证明的那样,将激活精度从 FP16 降低到 INT8 不可避免地会导致模型质量下降。这种退化的部分原因是LLMs激活过程中存在极值或异常值。这部分归因于预训练引起。在存在异常值的情况下,像 INT8 或 INT4 这样的统一量化无法准确表示数据的主体,因为它们会偏向异常值。这个问题源于这些技术中统一数据分布的固有假设,该假设可能与实际数据点分布不对应。 考虑到前面描述的整数量化的缺点,采用 ExMy 表示法的浮点 (FP) 方法(如 FP8 或 FP4)成为更有效的替代方案 [20,2,13,28,37]。与整数类型的固定范围不同,浮点方法允许调整小数点位置,从而实现跨激活图的动态缩放并保留重要特征。虽然关于整数和浮点量化之间的模型质量存在争议 [28], 但最近在 [37] 中使用 FP8/FP4 对 PTQ LLMs 进行的研究表明,FP8 比 INT8 激活量化要好得多。在硬件支持和性能方面,虽然大多数现代CPU和GPU都广泛支持INT8计算[21, 31],但较低位浮点运算也越来越受到业界的认可。这方面的一个例子是新发布的 NVIDIA H100 GPU,专为 FP8 计算而设计 [20]。因此,尽管与 INT8 相比,FP8 的计算成本可能更高,并且考虑到硬件支持,但模型质量的提高可能使这种权衡变​​得值得,并值得进一步探索。 本文: 通过 FP8 激活和权重量化导致最小的模型退化:特别是在较大的模型中,FP8 激活和权重量化导致的模型退化可以忽略不计,其性能与原始 FP16 模型相当。 在W4A8浮点模型中,即使对缩放因子施加了约束,也能保持质量。 为了在 W4A8 模型中实现真正的效率,从 FP4 到 FP8 的权重转换至关重要。 为了减轻这种转换开销,我们在这里建议权重量化的两种可能的缩放约束: (1)将所有缩放因子限制为 2 的幂; (2)需要将缩放因子在一个计算组中(例如,权重矩阵的几行可以通过简单的位移位来转换)。 我们的分析表明,与传统的 W4A8 配置相比,这两个限制对模型性能的影响可以忽略不计。 --- 我们选择使我们的方法与 GPTQ 中概述的原则保持一致.虽然这一战略提供了一个坚实的起点. 根据 ZeroQuant-V2 [35],我们应用了细粒度量化(FGQ)来进行权重,并对激活进行 token-wise 量化。此外,我们还将研究[35]中提出的附加特征LoRC(低秩补偿),其目的是通过采用低秩矩阵分解来减少权重的量化误差。 LoRC涉及两个主要步骤:首先,它对误差矩阵进行奇异值分解(SVD),误差矩阵是原始权重与量化权重之间的差值。因此,误差矩阵被分解为两个酉矩阵和一个对角矩阵。其次,该方法使用从第一步中的矩阵导出的两个低秩矩阵来制定新的误差近似。然后将该近似值添加到量化权重中,以产生对原始权重的更准确的估计,从而减少量化误差。 基于GPTQ(不带或带LoRC),我们对使用FP8或INT8对激活进行量化以及调整权重量化到FP8和FP4进行全面比较。 我们特别探索了 FP4 权重和 FP8 激活量化的潜力。 将 FP4 投射到 FP8。 最后,由于对权重 (W) 和激活 (A) 使用不同的精度级别,出现了一个独特的挑战。 W4A8 在 H100 NVIDIA 硬件中的实际软件实现是,需要转换 W 的 FP4 以匹配 A 中使用的 FP8 精度。 直接反量化然后再次量化的方法可能会对推理效率产生不利影响,因此不是一个可行的解决方案。 为了解决这个问题,我们提出了位移方法。这意味着,我们不让等式(`Q(x) = INT(x − Z)/S − Z`)中定义的 S 为任何实值比例因子,而是将 S 限制为 2 的幂,即 $S = 2^n$,n ∈ N(当n为负数时,S仍然可以表示分数;当n不为负数时,S仍然可以表示整数。)。我们将实现两种方法: (M1) 映射到由 2 的幂表示的最接近的值,即让新的scale为 $\hat{S} = 2^{\lceil \log_2(S)\rceil}$ (M2) 首先收集scales形成向量 $\mathbf{S} = [S_1, S_2, \ldots, S_n]$ 。然后取组(group)中的最大值(通常,该集合由矩阵的(多)行组成),记为$S_{\max}$,将这些元素$S_{\max}/S_i$调整为2的幂表示,然后定义 $\hat{S}_i = S_{\max}/ 2^{\lceil \log_2(S_{\max}/S_i)\rceil}$。与 (M1) 相比,这提供了更好的近似值。 我们重申,这种使用 2 的幂的限制,无论是使用 (M1) 还是 (M2),都可以简化计算,特别是在基于二进制逻辑操作的数字系统中。 这是我们优化计算效率和保持模型性能的方法的关键要素。 ---- 应用权重和激活的不同整数 (INT) 和浮点 (FP) 量化方法在 LLaMA(上)和 OPT(下)模型上的评估结果。性能以困惑度来衡量(分数越低越好),使用了三个数据集:WikiText-2 (WIKI)、PTB 和 C4。对于每个模型,结果首先显示整个数据集的平均性能,然后是每个数据集的详细分。 FP8 激活比 INT8 好得多。表 2 中结果的高级摘要表明,对于 LLaMA 和 OPT 模型系列,FP8 激活通常优于 INT8 激活。这一观察结果证实了第 2 节中讨论的动机,强调 FP8 捕获更细致信息的卓越能力,这是大规模 LLMs 生成任务的重要方面。 有趣的是,对于参数大于 67 亿的较大模型,例如 LLaMA-7b/13b 和 OPT-6.7b/13b,FP8 相对于 INT8 的优势变得更加明显。 FP8 权重可与 INT8 相媲美,而 FP4 权重则可能优于 INT4。 从表 2 中,我们观察到当保持 FP8 激活时,各种模型和数据集上 INT8 和 FP8 权重量化之间的性能相当。这可能是由于我们在权重量化上使用了 FGQ。有趣的是,当权重量化降低时,FP4 表现出优于 INT4 的某些优势,在 LLaMA-7b(15.14 至 16.09)和 LLaMA-13b 模型(11.08 至 11.31)中尤其明显。具体来说,在 LLaMA-7b 的 W4A8 配置下,我们看到 FP4 比 INT4 提高了 0.95,这是一个显着的增益。 FP4 优于 INT4 的性能对于 H100 等已支持 FP8 的硬件设计尤其有利。因此,适应 FP4 的简单修改将比实现支持 INT4 权重和 FP8 激活的系统更容易。 LoRC 改进了 W4A8。 表 2 显示低阶补偿 (LoRC) 方法增强了 W4A8 量化方案,减少了量化误差。这种改进在较小的模型中尤其明显,突显了 LoRC 在优化这些计算过程的性能方面的有效性,同时对模型大小的影响很小。 将 FP4 投射到 FP8。如第 3 节所述,为了最大限度地提高 NVIDIA H100 硬件上的实际延迟加速,我们建议将权重量化的比例因子 S 表示为 2 的幂。为了实现这一目标,我们使用 FP4 进行权重和FP8 用于激活量化。 表 3 列出了使用和不使用 LoRC 进行的这些实验的结果。我们的数据显示,限制缩放因子偶尔会导致 LLaMA-7b 和 LLaMA-13b 等模型出现改进, 但我们通常会观察到轻微的退化无论我们使用方法 M1 还是 M2,W4A8 浮点模型中的质量都会受到影响。 M2 通常优于 M1。当我们实施 LoRC 时,可以缓解质量下降的情况,特别是在 OPT-1.3b、LLaMA-7b 和 LLaMA-13b 模型中。因此,我们的结果提倡使用 LoRC,特别是在考虑深度学习模型中权重量化的规模限制时。 ### 全量化 ZeroQuant-FP(论文:ZeroQuant-FP: A Leap Forward in LLMs Post-Training W4A8 Quantization Using Floating-Point Formats)探索了浮点(FP)量化的适用性,特别关注FP8和FP4格式。研究揭示,对于LLM,FP8激活在性能上持续优于INT8,而在权重量化方面,FP4在性能上与INT4相比具有可比性,甚至更优越。为了解决由权重和激活之间的差异引起的挑战,ZeroQuant-FP要求所有缩放因子为2的幂,并将缩放因子限制在单个计算组内。值得注意的是,ZeroQuant-FP还集成了Low Rank Compensation (LoRC) 策略,以进一步增强其量化方法的有效性。 ## ZeroQuant-HERO(W8A8) 量化技术对于减少深度神经网络推理的内存和计算需求至关重要。 ZeroQuant 等现有解决方案为 BERT 和 GPT 等模型提供动态量化,但忽略了内存限制(memory-bounded)运算和每个token量化的复杂性。为了解决这些差距,我们提出了一种新颖的、完全硬件增强的稳健优化的训练后 W8A8 量化框架 ZeroQuant-HERO。 该框架独特地集成了内存带宽和计算密集型运算,旨在实现最佳硬件性能。此外,它还允许特定的 INT8 模块切换到 FP16/BF16 模式,从而提供灵活性,从而提高准确性。 --- 由于机器学习算法和硬件之间的跨学科差距(在这项工作中,我们主要针对 Nvidia GPU,例如 A100),该领域仍然很大程度上缺少硬件感知的 PTQ 方法,特别是对于基于 Transformer 的模型。 例如,ZeroQuant [23] 为 BERT [3] 和 GPT [12] 模型提出了对激活进行每token动态量化和对权重进行每列量化,以实现良好的准确性。 然而,它没有考虑 (1)内存限制(memory bounded)算子,例如: LayerNorm 和注意力,并将这些部分留在 FP16/BF16 中,以及 (2)当没有融合机会时,调用额外kernel的每个token量化的成本,例如:注意输出线性层的 INT8 GeMM 算子。 为了解决这些限制,我们引入了 ZeroQuant-HERO,这是一个完全硬件感知且实用的训练后 W8A8 量化框架。我们的贡献总结如下。 1. ZeroQuant-HERO 在设计时考虑了内存带宽限制和计算密集型运算。因此,该框架可以(有可能)实现最佳硬件性能。 2. 为了进一步提高 ZeroQuant-HERO 的可用性,可以执行 ZeroQuant-HERO 的不同量化级别,即 INT8 运算与 FP16/BF16 对应运算的比率,以实现所需的精度和延迟权衡。 ---- 量化方案 在整个工作中,除非特别的注释说明,否则我们均使用 INT8 对称量化。然而,我们的方法也适用于其他 8 位精度格式,例如 FP8。特别地,我们使用以下列主权重矩阵格式来执行 GeMM: $Y = XW$ $W = W_{int8}S_w$ $X\in\R^{n\times d}$ $W\in\R^{d\times m}$ $X = S_xX_{int8}$ $S_x\in\R^{1\times d}$ $X = X_{int8}S_x=S_xX_{int8}$ ZeroQuant-HERO 的三个主要组件 嵌入层量化 注意力模块量化 MLP 模块量化 混合精度推理 结合上一节中的所有技术,我们得到了最终的 ZeroQuant-HERO 设计。然而,不同的模型和/或任务对量化的容忍度不同,并且对准确性和系统效率的权衡也有不同的期望。为了满足各种模型/任务的要求,混合精度推理是量化的解决方案之一。 由于 ZeroQuant-HERO 的模块化设计,我们可以为最终模型设置各种量化级别。 为了证明混合精度推理的必要性,我们在下一节中展示了三个量化级别的准确性(表 1)。 为了解决算法与硬件协调的挑战,本文推出了 ZeroQuant-HERO ,这是一种新的硬件增强型训练后 W8A8 量化框架。 ================================================ FILE: llm-compression/quantization/fp4.md ================================================ https://github.com/nbasyl/LLM-FP4 LLM-FP4: 4-Bit Floating-Point Quantized Transformers ZeroQuant-FP: A Leap Forward in LLMs Post-Training W4A8 Quantization Using Floating-Point Formats ================================================ FILE: llm-compression/quantization/fp6.md ================================================ https://github.com/microsoft/DeepSpeed/blob/master/blogs/deepspeed-fp6/03-05-2024/README-Chinese.md INT4量化技术的挑战: 虽然这些技术可以减小模型大小和参数存储量,但由于过拟合问题, 它们在更一般的许多任务中往往表现不佳,包括代码生成和摘要等更多生成任务。 FP6的突破: FP6数据格式在当前AI硬件的高效支持中存在挑战。该格式在各种任务的性能和灵活性方面均表现出色。 为了提高FP6在当前主流AI硬件上的执行效率,我们提出了一种4+2新颖的FP6 GPU kernel方案。这一创新使FP6成为提高LLMs效率的有效途径。 ## 开创性的全栈GPU KERNEL设计 运行前比特层级的数据排布转换。用以解决权重具有不规则位宽时不友好的内存访问挑战,实现GPU内存的最优访问; 运行时的高效SIMT计算。用以最小化权重反量化的运行时开销; 全栈的高效流水线设计。其SIMT计算、Tensor Core计算和GPU内存访问进行高效调度,最大程度提升性能。 FP6 kernel在NVIDIA A100 GPU上进行(因decoder的矩阵形状狭长而导致参数矩阵的访存成为瓶颈的)矩阵乘法时,处理速度比FP16 cuBLAS基准提高了2.1倍。 FP6服务LLM ## FP6服务LLM FP6量化为模型推理提供了两个关键好处: 它使大型语言模型(LLMs)能够在更少的GPU上部署——例如,LLaMA-70b在单个A100-80G GPU上就能以FP6形式运行,而FP16模型至少需要两个GPU。 此外,它显著加快了小batch之下内存访问为瓶颈的线性层计算。 此外,FP6量化减少了模型权重的GPU内存需求,允许同时服务更多查询,从而提高了服务吞吐量。 较长解码场景中内存访问瓶颈增强的两个因素如下: 首先,KV缓存的内存使用随序列长度增加而增加,减少了可容纳的batch大小并导致线性层的矩阵计算瓶颈变为参数的访存。 其次,在DeepSpeed-FastGen的prefill-decoding-mixed-batch技术背景下,对于decoding较长的情况,用于和decoding进行mixed-batching的prefill切块会相对不足,这导致纯粹用于decoding的batch频率增加,进一步加剧了访存的瓶颈。 在GEMM因batch较大或有充足的GPU内存而使得瓶颈变为Tensor Core计算时,我们的仅限权重的量化kernel可能无法保持其性能优势,尤其是与厂商的优化库如cuBlas相比。然而,我们系统的低内存占用仍是一个关键优势。目前的支持限于非混合专家(Non-MoE)结构,我们正在努力将支持扩展到MoE结构。此外,当前系统仅与FP16输入模型兼容,因为当前实现的FP6 kernel仅支持处理FP16的激活。 ================================================ FILE: llm-compression/quantization/fp8.md ================================================ https://arxiv.org/pdf/2209.05433 FP8 FORMATS FOR DEEP LEARNING FP8 Quantization: The Power of the Exponent https://arxiv.org/pdf/2208.09225 https://zhuanlan.zhihu.com/p/574825662 FP8 量化-原理、实现与误差分析 https://zhuanlan.zhihu.com/p/619431625 FP8 量化基础 https://developer.nvidia.com/zh-cn/blog/nvidia-gpu-fp8-training-inference/ ================================================ FILE: llm-compression/quantization/kv-cache-quant.md ================================================ KVCache 量化的值计算还是使用 fp16 计算是比较常见的方式。 KVCache 量化与离线的参数一次性量化好可以不停使用不同,KVCache 的数据是随时生成的,随后马上就进行量化过程的再进行存储和后续使用,虽然也是一次性量化好的,但是这个一次性是在整个推理过程中的,是占有一部分在线资源和延时的。 KVQuant 在处理长序列和较大的批量时,激活内存成为了主要的性能瓶颈,特别是在模型权重已经量化到较低精度的情况下。对于LLaMA-7B模型,当序列长度达到128K时,KV缓存成为了主要的瓶颈。此外,如果模型权重已经被量化,即使在 32K 的序列长度下,KV 缓存也是主要的瓶颈。 在 QAQ 和 KIVI 中,作者也都发现 Key cache 和 Value cache 之间存在很大的区别,Key cache 量化难度远高于 value 。 KVQuant 采用的方法是在 Key 前面的 rope 前就完成量化,实际使用时则反量化之后再做一次 rope ;QAQ 是采用了混合 bit 数和全精度保留 outlier 的量化策略,KIVI 则是用两种不同的量化分组粒度策略完成不同的量化过程。 KVQuant: per-channel 的 Key 和 per-token 的 Value 这样的组合 ------ KIVI KIVI 和 KVQuant 里用的 per-channel quantization for Key cache 是一个蛮重要的 recipe(然后应该也算新鲜?)。帖子里提到的「有很多更小 block 的 quant 方法」的确没错,但这个 per-channel 在乎的是沿着哪个 dimension 组 block,而不是说具体 block size 多大多小。然后因为 per-channel quant 需要跨多个 token,所以怎么在 autoregressive 的背景下 quant 也是一个需要考虑的挑战;我们搞 FP16 residual 一定程度上也是为了方便这个。我感觉这些楼主应该是理解的(毕竟帖子里也提到了异常值的分布作为 per-channel 的 motivation) -------- IntactKV (1)IntactKV中pivot token的现象在同期工作Massive Activations in Large Language Models中得到了更加细致的研究, 这篇论文里有详细分析LLM中pivot token上超大outlier产生的来源、作用和重要性; (2)IntactKV的校准过程还是采用和其他PTQ方法相同的MSE loss,区别是我们没有进行逐层优化,而是直接端到端地优化所有层的MSE loss,因为IntactKV是基于已经量化好的模型做校准,所以内存开销也不会很大,7B模型在单卡H800上只需要训练10min 现在KVQuant的最新版本里也采用了和IntactKV相同的思路保持首token的KV cache无损,另外IntactKV也支持权重量化和激活值量化,与目前的多种LLM主流量化方法兼容,更加详细的介绍可以参考我们的知乎文章 一个小技巧轻松提升量化精度!IntactKV:保持关键词元无损的大语言模型量化方法 ----------- QAQ 对于文中提到的「震荡(?)」一点,我们想表达的意思是:我们使用微分来表达量化前后的误差,直观来看,Key cache得到的式子显著含有更高阶次,因此需要更小心的量化策略,问题定义如Figure 1所示,详细数学推导请见论文。 Key cache 的分布和 value cache 的完全不同,几篇文章中都着重提到了。这两块是和 softmax 函数直接相关的,一个在 softmax 前一个在后,softmax 又是非线性的,带来了区别就很正常。 ================================================ FILE: llm-compression/quantization/llm-qat/LLM-QAT.md ================================================ ## 摘要 多种训练后量化方法已应用于大语言模型 (LLM),并且已被证明在低至 8 比特的情况下也能表现良好。 我们发现这些方法在较低比特精度下会崩溃,并研究了 LLM 的量化感知训练(LLM-QAT) ,以进一步提高量化水平。 我们提出了一种 data-free 蒸馏方法,该方法利用预训练模型产生的生成,可以更好地保留原始输出分布,并允许独立于其训练数据来量化任何生成模型,类似于训练后量化方法。 除了量化权重和激活之外,我们还量化 KV 缓存,这对于提高吞吐量和支持当前模型大小的长序列依赖关系至关重要。 我们在低至 4 比特的量化级别上对大小为 7B、13B 和 30B 的 LLaMA 模型进行了实验。 我们观察到比 training-free 方法有很大的改进,特别是在低比特设置中。 ## 1 Introduction 常识推理任务 我们考虑三种训练后量化(PTQ)方法:round-to-nearest(RTN)、GPT-Q 和 SmoothQuant 作为基线。 我们在几种不同的设置中与它们进行比较,其中:权重、激活和 KV 缓存值被量化到不同的级别(表示为 W-A-KV)。 不同的 PTQ 方法在不同的设置中表现良好,我们将我们的方法与每个设置中的最佳 PTQ 结果进行比较。 ## 2 方法 在这项工作中,我们研究线性量化,即均匀量化。 根据实际值是否被截断(clipped),线性量化可以分为两类:保留所有值范围的 MinMax 量化和基于截断(裁剪)的量化。 在 MinMax 量化中,量化过程可以表述为: ```math \mathbf{X}_\mathbf{Q}^i = \alpha \mathbf{\hat{X}_Q}^i = \alpha \lfloor {\frac{\mathbf{X}_\mathbf{R}^i - \beta}{\alpha}} \rceil + \beta ``` $$ \mathbf{X}_\mathbf{Q}^i = \alpha \mathbf{\hat{X}_Q}^i = \alpha \lfloor {\frac{\mathbf{X}_\mathbf{R}^i - \beta}{\alpha}} \rceil + \beta $$ --- $\alpha = \frac{\max(|\mathbf{X}_\mathbf{R}|)}{2^{N-1} -1} , \ \beta = 0.$ ```math \alpha = \frac{\max(|\mathbf{X}_\mathbf{R}|)}{2^{N-1} -1} , \ \beta = 0 ``` $\alpha = \frac{\max(\mathbf{X}_\mathbf{R}) - \min(\mathbf{X}_\mathbf{R})}{2^N -1} , \ \beta = \min(\mathbf{X}_\mathbf{R}).$ ```math \alpha = \frac{\max(\mathbf{X}_\mathbf{R}) - \min(\mathbf{X}_\mathbf{R})}{2^N -1} , \ \beta = \min(\mathbf{X}_\mathbf{R}). ``` --- ```math \mathbf{X}_\mathbf{Q}^i = \alpha \mathbf{\hat{X}_Q}^i = \alpha \nint {\frac{\mathbf{X}_\mathbf{R}^i - \beta}{\alpha}} + \beta ``` ```math \mathbf{X}_\mathbf{Q}^i = \alpha \mathbf{\hat{X}_Q}^i = \alpha \lfloor{{\rm Clip}(\frac{\mathbf{X}_\mathbf{R}^i - \beta}{\alpha}, 0, 1)}\rceil + \beta ``` --- $$ \mathbf{X}_\mathbf{Q}^i = \alpha \mathbf{\hat{X}_Q}^i = \alpha \lfloor{{\rm Clip}(\frac{\mathbf{X}_\mathbf{R}^i - \beta}{\alpha}, 0, 1)}\rceil + \beta $$ ```math \mathbf{X}_\mathbf{Q}^i = \alpha \mathbf{\hat{X}_Q}^i = \alpha \lfloor{{\rm Clip}(\frac{\mathbf{X}_\mathbf{R}^i - \beta}{\alpha}, 0, 1)}\rceil + \beta ``` --- $$ \mathbf{X}_\mathbf{Q}^i = \alpha \lfloor{\frac{\mathbf{X}_\mathbf{R}^i}{\alpha}}\rceil, \ \ \ \alpha = \frac{\max(|\mathbf{X}_\mathbf{R}|)}{2^{N-1} -1} $$ ```math \mathbf{X}_\mathbf{Q}^i = \alpha \lfloor{\frac{\mathbf{X}_\mathbf{R}^i}{\alpha}}\rceil, \ \ \ \alpha = \frac{\max(|\mathbf{X}_\mathbf{R}|)}{2^{N-1} -1} ``` --- $$ \mathcal{L}_{CE} = -\frac{1}{n}\sum_c\sum^n_{i=1} p_c^{\mathcal{T}}(X_i)\log(p_c^{\mathcal{S}}(X_i)), $$ ```math \mathcal{L}_{CE} = -\frac{1}{n}\sum_c\sum^n_{i=1} p_c^{\mathcal{T}}(X_i)\log(p_c^{\mathcal{S}}(X_i)), ``` ## 3.2 Main Results 对于从业者来说,一个重要的问题是是否使用完全精确的小模型,或者具有类似推理成本的较大量化模型。 虽然确切的权衡可能会因多种因素而异,但我们可以根据我们的结果提出一些建议。 首先,8 位量化应该优于较小的全精度模型,并且 PTQ 方法足以满足这种情况。 8-8-8 30B 量化模型优于类似大小的 13B 模型,并且在实践中应该具有更低的延迟和更高的吞吐量。 这也适用于 8 位 13B 模型与 16 位 7B 模型相比。 此外,使用 LLM-QAT 量化的 4 位模型应该优于类似大小的 8 位模型。 例如,4-8-4 LLM-QAT 30B 优于 8 位 LLaMA-13B,4-8-8 LLM-QAT 13B 优于 8 位 LLaMA-7B。 因此,我们建议使用 4 位 LLM-QAT 模型,以实现最佳效率与精度的权衡。 --- Quantization-aware training for key-value cache 然而,之前只有少数工作解决了 LLM 中的 KV 缓存量化问题,且方法主要局限于训练后量化(Sheng et al., 2023)。 在我们的研究中,我们证明了可以采用用于激活量化的类似量化感知训练方法来量化 KV 缓存。 如图 3 所示,我们在等式 3 中采用按token量化。 假设key和value是由token生成的。 在生成过程中,当前的key和value都会被量化,并存储它们对应的缩放因子。 在 QAT 的训练过程中,我们对键和值的整个激活张量进行量化,如图 2 所示。 通过将量化函数集成到梯度计算中,我们确保使用量化的键值对进行有效的训练。 --- 知识蒸馏 我们使用基于交叉熵的logits蒸馏从全精度预训练的教师网络中训练量化的学生网络: 正如第 2.1 节中所讨论的,在数据生成过程中,重要的是从分布中采样下一个标记,而不是总是选择 top-1 候选标记。 通过这样做,下一个标记不一定代表训练学生模型的最佳标签,因为采样会引入固有的噪声。 因此,我们建议利用预训练模型的预测作为软标签,这为指导学生模型的训练提供了更多信息的目标。 我们在第 3.3.3 节中提出了一项全面的消融研究,以深入研究这种方法的细节。 ## 3.3 Ablation 消融实验 ### 3.3.2 Quantization Function 我们将非裁剪量化方法与基于裁剪的量化方法进行了比较,如表 4 所示。 遵循之前工作(Liu et al., 2022b, 2023)中的做法,我们使用 StatsQ(Liu et al., 2022a),这是一种统计计算的缩放因子,用于基于裁剪的权重量化 和 LSQ(Esser 等人,2019),用于基于裁剪的激活量化的可学习缩放因子。 然而,我们的研究结果表明,这两种最先进的基于裁剪的量化方法并没有超过非裁剪对称方法MinMax所实现的性能。 这一观察结果强化了这样的论点:保留异常值对于大型语言模型的性能至关重要。 此外,我们观察到,对于 LLaMA 模型,激活和权重主要表现出对称分布,这使得使用对称量化成为最佳选择。 然而,值得注意的是,这个结论可能不适用于其他大型语言模型,尤其是那些包含 GeLU 层的语言模型。 ## 3.3.3 知识蒸馏 表5显示不同的知识蒸馏方法对微调模型的最终精度有显着影响。 值得注意的是,由于在生成过程中从候选分布中进行采样所引入的固有随机性和噪声,单独使用下一个标记作为标签并不是最优的。 相比之下,logit 蒸馏利用了教师模型的完整 logit 分布预测,与基于标签的训练方法相比,微调模型的性能更优越。 有趣的是,我们观察到合并注意力蒸馏或隐藏层蒸馏实际上会阻碍性能。 因此,我们在所有实验中专门采用 Logit 蒸馏。 3.4 与 SmoothQuant 的兼容性 我们的方法还与 SmoothQuant(Xiao 等人,2022)中提出的权重激活重新缩放技术兼容。 表 6 显示,将 SmoothQuant 合并到 4 位权重 4 位激活 (W4A4) 量化中可以进一步提高精度。 然而,在激活位大于权重位(即W4A8)的情况下,添加SmoothQuant不会产生任何改进,甚至可能会损害性能。 ## 结论 我们提出了针对 LLM 的 data-free 量化感知训练,并表明使用该技术可以实现准确的 4 位量化。 考虑到与训练数据无关的蒸馏方法的普遍性,以及 LLM 部署成本的不断增长,我们期望我们的方法具有广泛的适用性。 例如,该方法还可以用于在多个阶段训练的模型,例如 通过指令精调或强化学习。 我们将这项调查留给未来的工作。 由于 4 比特量化没有开箱即用的硬件支持,因此,我们没有将硬件实现作为这项工作的一部分。 不过,我们正在与合作伙伴合作,以期在不久的将来实现这一目标。 虽然我们的方法适用于 4 比特权重、4 比特 KV 缓存和 8 比特激活, 但对于 4 比特激活量化来说还不充分,还需进一步研究。 ================================================ FILE: llm-compression/quantization/llm-qat/README.md ================================================ - https://github.com/facebookresearch/LLM-QAT ## 版本 - 第一版:cfd70ff - 第二版:f4d873a - ## env - https://download.pytorch.org/whl/cu117/torch-2.0.1%2Bcu117-cp310-cp310-linux_x86_64.whl ``` git clone https://github.com/NVIDIA/apex cd apex # if pip >= 23.1 (ref: https://pip.pypa.io/en/stable/news/#v23-1) which supports multiple `--config-settings` with the same key... pip install -v --disable-pip-version-check --no-cache-dir --no-build-isolation --config-settings "--build-option=--cpp_ext" --config-settings "--build-option=--cuda_ext" ./ # otherwise pip install -v --disable-pip-version-check --no-cache-dir --no-build-isolation --global-option="--cpp_ext" --global-option="--cuda_ext" ./ ``` ``` cd /home/guodong.li/virtual-venv virtualenv -p /usr/bin/python3.10 llm-qat-venv-py310-cu117 source /home/guodong.li/virtual-venv/llm-qat-venv-py310-cu117/bin/activate pip install torch-1.13.1+cu117-cp310-cp310-linux_x86_64.whl pip install torchvision-0.14.1+cu117-cp310-cp310-linux_x86_64.whl git clone https://github.com/NVIDIA/apex cd apex git checkout 22.04-dev pip install -v --disable-pip-version-check --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext" ./ pip install -r requirement.txt /home/guodong.li/model/llama-7b-hf ``` ## 合成数据 ``` config.json tokenizer_config.json mkdir -p gen_data/ CUDA_VISIBLE_DEVICES=0 python generate_data.py 0 CUDA_VISIBLE_DEVICES=1 python generate_data.py 1 CUDA_VISIBLE_DEVICES=2 python generate_data.py 2 CUDA_VISIBLE_DEVICES=3 python generate_data.py 3 CUDA_VISIBLE_DEVICES=4 python generate_data.py 4 CUDA_VISIBLE_DEVICES=5 python generate_data.py 5 CUDA_VISIBLE_DEVICES=6 python generate_data.py 6 CUDA_VISIBLE_DEVICES=7 python generate_data.py 7 ``` ``` tree -h gen_data/ gen_data/ ├── [4.1M] gen.chunk.00.jsonl ├── [4.9M] gen.chunk.01.jsonl ├── [4.7M] gen.chunk.02.jsonl ├── [4.8M] gen.chunk.03.jsonl ├── [4.5M] gen.chunk.04.jsonl ├── [4.4M] gen.chunk.05.jsonl ├── [4.5M] gen.chunk.06.jsonl └── [4.6M] gen.chunk.07.jsonl 0 directories, 8 files (llm-qat-venv-py310-cu117) [guodong.li@ai-app-2-46 LLM-QAT]$ wc -l gen_data/gen.chunk.07.jsonl 1500 gen_data/gen.chunk.07.jsonl head -n1 gen_data/gen.chunk.02.jsonl {"text": "ied with the idea of it and they've only one thing in mind: to find it. ...I needed the first, but I needed the second more, because I cried from beginning to"} ------------------------------ python merge_gen_data.py wc -l all_gen.jsonl 12000 all_gen.jsonl ------------------------ ``` ## train ``` sh run_train_chunk.sh 8 8 8 sh run_train.sh 8 8 8 ``` ``` LlamaForCausalLM( (model): LlamaModel( (embed_tokens): Embedding(32000, 4096, padding_idx=31999) (layers): ModuleList( (0): LlamaDecoderLayer( (self_attn): LlamaAttention( (q_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (k_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (v_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (o_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (rotary_emb): LlamaRotaryEmbedding() ) (mlp): LlamaMLP( (gate_proj): QuantizeLinear(in_features=4096, out_features=11008, bias=False) (down_proj): QuantizeLinear(in_features=11008, out_features=4096, bias=False) (up_proj): QuantizeLinear(in_features=4096, out_features=11008, bias=False) (act_fn): SiLUActivation() ) (input_layernorm): LlamaRMSNorm() (post_attention_layernorm): LlamaRMSNorm() ) ... (31): LlamaDecoderLayer( (self_attn): LlamaAttention( (q_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (k_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (v_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (o_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (rotary_emb): LlamaRotaryEmbedding() ) (mlp): LlamaMLP( (gate_proj): QuantizeLinear(in_features=4096, out_features=11008, bias=False) (down_proj): QuantizeLinear(in_features=11008, out_features=4096, bias=False) (up_proj): QuantizeLinear(in_features=4096, out_features=11008, bias=False) (act_fn): SiLUActivation() ) (input_layernorm): LlamaRMSNorm() (post_attention_layernorm): LlamaRMSNorm() ) ) (norm): LlamaRMSNorm() ) (lm_head): Linear(in_features=4096, out_features=32000, bias=False) ) ``` ``` LlamaForCausalLM( (model): LlamaModel( (embed_tokens): Embedding(32000, 4096, padding_idx=31999) (layers): ModuleList( (0): FullyShardedDataParallel( (_fsdp_wrapped_module): FlattenParamsWrapper( (_fpw_module): LlamaDecoderLayer( (self_attn): LlamaAttention( (q_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (k_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (v_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (o_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (rotary_emb): LlamaRotaryEmbedding() ) (mlp): LlamaMLP( (gate_proj): QuantizeLinear(in_features=4096, out_features=11008, bias=False) (down_proj): QuantizeLinear(in_features=11008, out_features=4096, bias=False) (up_proj): QuantizeLinear(in_features=4096, out_features=11008, bias=False) (act_fn): SiLUActivation() ) (input_layernorm): LlamaRMSNorm() (post_attention_layernorm): LlamaRMSNorm() ) ) ) ... (31): FullyShardedDataParallel( (_fsdp_wrapped_module): FlattenParamsWrapper( (_fpw_module): LlamaDecoderLayer( (self_attn): LlamaAttention( (q_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (k_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (v_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (o_proj): QuantizeLinear(in_features=4096, out_features=4096, bias=False) (rotary_emb): LlamaRotaryEmbedding() ) (mlp): LlamaMLP( (gate_proj): QuantizeLinear(in_features=4096, out_features=11008, bias=False) (down_proj): QuantizeLinear(in_features=11008, out_features=4096, bias=False) (up_proj): QuantizeLinear(in_features=4096, out_features=11008, bias=False) (act_fn): SiLUActivation() ) (input_layernorm): LlamaRMSNorm() (post_attention_layernorm): LlamaRMSNorm() ) ) ) ) (norm): LlamaRMSNorm() ) (lm_head): Linear(in_features=4096, out_features=32000, bias=False) ) ``` 模型输出: ``` tree -h . ├── [ 28] llama │   └── [ 34] models │   └── [ 195] 7B-finetuned │   ├── [ 663] config.json │   ├── [ 132] generation_config.json │   ├── [9.2G] pytorch_model-00001-of-00002.bin │   ├── [2.9G] pytorch_model-00002-of-00002.bin │   └── [ 26K] pytorch_model.bin.index.json └── [ 26] output └── [ 29] runs └── [4.0K] current ├── [4.1K] events.out.tfevents.1691114271.ai-app-2-46 ``` ================================================ FILE: llm-compression/quantization/llm-qat/cfd70ff/README.md ================================================ ``` bash run_train.sh 8 8 8 ``` ================================================ FILE: llm-compression/quantization/llm-qat/cfd70ff/generate_data.py ================================================ # coding=utf-8 # Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. #from transformers import AutoTokenizer, AutoModelForCausalLM from transformers import LlamaTokenizer, LlamaForCausalLM import torch import json import sys import os print("Loading tokenizer") tokenizer = LlamaTokenizer.from_pretrained("/home/guodong.li/model/llama-7b-hf") print("Tokenizer loaded!") print("Loading model") model = LlamaForCausalLM.from_pretrained("/home/guodong.li/model/llama-7b-hf", device_map='auto') print("Model loaded!") n_vocab = 500 # number of initial tokens for synthesizing data on each GPU. i_start = sys.argv[1] if os.path.exists("gen_data/gen.chunk."+str(i_start).zfill(2)+".jsonl"): with open("gen_data/gen.chunk."+str(i_start).zfill(2)+".jsonl", "r") as f: lines = f.readlines() inner_loop = len(lines) % n_vocab outer_loop = len(lines) // n_vocab else: inner_loop = 0 outer_loop = 0 for j in range(3 + outer_loop, 6): for i in range(int(i_start) * n_vocab + inner_loop, (int(i_start)+1) * n_vocab): print(i) input_ids = torch.tensor([[i]]) input_ids = input_ids.cuda() print("generating") outputs1 = model.generate(input_ids, do_sample=False, max_length=j) outputs = model.generate(outputs1, do_sample=True, max_length=1024) gen_text = tokenizer.batch_decode(outputs, skip_special_tokens=True) text_dict = {"text" : gen_text[0]} with open("gen_data/gen.chunk."+str(i_start).zfill(2)+".jsonl", "a") as f: f.write(json.dumps(text_dict)) f.write('\n') ================================================ FILE: llm-compression/quantization/llm-qat/cfd70ff/inference.py ================================================ from transformers import LlamaTokenizer from models.configuration_llama import LlamaConfig from models.modeling_llama_quant import LlamaForCausalLM as LlamaForCausalLMQuant import torch PATH_TO_CONVERTED_TOKENIZER = "/home/guodong.li/tmp/llama/models/7B-finetuned" tokenizer = LlamaTokenizer.from_pretrained( pretrained_model_name_or_path=PATH_TO_CONVERTED_TOKENIZER, model_max_length=30, padding_side="right", use_fast=False, ) config = LlamaConfig.from_pretrained(PATH_TO_CONVERTED_TOKENIZER) model = LlamaForCausalLMQuant.from_pretrained( pretrained_model_name_or_path=PATH_TO_CONVERTED_TOKENIZER, config=config, torch_dtype=torch.bfloat16, low_cpu_mem_usage=True, device_map="auto" ) model = model.cuda() prompt = "Hey, are you consciours? Can you talk to me?" inputs = tokenizer(prompt, return_tensors="pt") input_ids = inputs.input_ids.cuda() # Generate generate_ids = model.generate(input_ids, max_length=30) tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] ================================================ FILE: llm-compression/quantization/llm-qat/cfd70ff/merge_gen_data.py ================================================ # coding=utf-8 # Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. import json import os import random all_text = [] for i_start in range(8): if i_start % 10 == 0: print(i_start) for line in open("gen_data/gen.chunk."+str(i_start).zfill(2)+".jsonl", 'r'): all_text.append(json.loads(line)) with open("gen_data/all_gen.jsonl", "a") as f: for i in range(len(all_text)): f.write(json.dumps(all_text[i])) f.write('\n') ================================================ FILE: llm-compression/quantization/llm-qat/cfd70ff/pip.conf ================================================ # This file has been autogenerated or modified by NVIDIA PyIndex. # In case you need to modify your PIP configuration, please be aware that # some configuration files may have a priority order. Here are the following # files that may exists in your machine by order of priority: # # [Priority 1] Site level configuration files # 1. `/usr/pip.conf` # # [Priority 2] User level configuration files # 1. `/root/.config/pip/pip.conf` # 2. `/root/.pip/pip.conf` # # [Priority 3] Global level configuration files # 1. `/etc/pip.conf` # 2. `/etc/xdg/pip/pip.conf` [global] no-cache-dir = true index-url = https://pypi.org/simple extra-index-url = https://pypi.ngc.nvidia.com trusted-host = pypi.ngc.nvidia.com ================================================ FILE: llm-compression/quantization/llm-qat/cfd70ff/run_train.sh ================================================ # coding=utf-8 # Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. torchrun --nproc_per_node=8 --master_port=15001 train.py \ --local_dir "/home/guodong.li/tmp/llama/" \ --input_model_filename "/home/guodong.li/model/llama-7b-hf" \ --output_model_filename "7B-finetuned" \ --train_data_local_path "/home/guodong.li/code/LLM-QAT/gen_data/all_gen.jsonl" \ --eval_data_local_path "wiki2.jsonl" \ --do_train True \ --do_eval True \ --model_max_length 512 \ --fp16 False \ --bf16 True \ --log_on_each_node False \ --logging_dir /home/guodong.li/tmp/output/runs/current \ --num_train_epochs 1 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 1 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --report_to "tensorboard" \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0. \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --tf32 False \ --gradient_checkpointing False \ --qat True \ --w_bits $1 \ --a_bits $2 \ --kv_bits $3 \ --use_kd False \ --fsdp "full_shard offload auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'LlamaDecoderLayer' ================================================ FILE: llm-compression/quantization/llm-qat/cfd70ff/train.py ================================================ # coding=utf-8 # Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. # # 2023.07.05 - Add quantization and knowledge distillialtion # Meta Platforms, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import math from models.configuration_llama import LlamaConfig from models.modeling_llama_quant import LlamaForCausalLM as LlamaForCausalLMQuant import copy import torch import transformers from datasets import load_dataset from utils import utils from utils import datautils from utils.kd_trainer import KDTrainer from utils.process_args import process_args from torch import distributed as dist from transformers import default_data_collator, Trainer log = utils.get_logger("clm") def train(): dist.init_process_group(backend="nccl") model_args, data_args, training_args = process_args() log.info("Start to load model...") #dtype = torch.bfloat16 if training_args.bf16 else torch.float dtype = torch.bfloat16 if training_args.bf16 else torch.float print("----------dtype:", dtype) if training_args.qat: config = LlamaConfig.from_pretrained(model_args.input_model_filename) student_config = copy.deepcopy(config) student_config.w_bits = model_args.w_bits student_config.a_bits = model_args.a_bits student_config.kv_bits = model_args.kv_bits student_config.smoothquant = model_args.smoothquant model = LlamaForCausalLMQuant.from_pretrained( pretrained_model_name_or_path=model_args.input_model_filename, config=student_config, cache_dir=training_args.cache_dir, torch_dtype=dtype, low_cpu_mem_usage=True, device_map=None if len(training_args.fsdp) > 0 else "auto", ) else: model = transformers.LlamaForCausalLM.from_pretrained( pretrained_model_name_or_path=model_args.input_model_filename, cache_dir=training_args.cache_dir, torch_dtype=dtype, low_cpu_mem_usage=True, device_map=None if len(training_args.fsdp) > 0 else "auto", ) print("--------------------------------------------") state = model.state_dict() if training_args.use_kd: teacher_model = transformers.AutoModelForCausalLM.from_pretrained( pretrained_model_name_or_path=model_args.input_model_filename, cache_dir=training_args.cache_dir, torch_dtype=dtype, low_cpu_mem_usage=True, device_map=None if len(training_args.fsdp) > 0 else "auto", ) teacher_model.eval() teacher_model.cuda() for param in teacher_model.parameters(): param.requires_grad = False teacher_model.config.use_cache = False model.kd_loss_scale = training_args.kd_loss_scale model.teacher = teacher_model log.info("Complete model loading...") log.info("Start to load tokenizer...") tokenizer = transformers.LlamaTokenizer.from_pretrained( pretrained_model_name_or_path=model_args.input_model_filename, cache_dir=training_args.cache_dir, model_max_length=training_args.model_max_length, padding_side="right", use_fast=False, ) log.info("Complete tokenizer loading...") #dataset = load_dataset("wikitext", 'wikitext-2-v1') dataset = load_dataset("/home/guodong.li/code/wikitext.py", "wikitext-2-raw-v1", cache_dir="/home/guodong.li/.cache/huggingface/datasets") train_data = datautils.CustomJsonDataset( dataset['train'].select(range(1000)), tokenizer, block_size=training_args.model_max_length ) valid_data = datautils.CustomJsonDataset( dataset['test'], tokenizer, block_size=min(training_args.model_max_length, 1024) ) model.config.use_cache = False if training_args.use_kd: myTrainer = KDTrainer else: myTrainer = Trainer trainer = myTrainer( model=model, tokenizer=tokenizer, args=training_args, train_dataset=train_data if training_args.do_train else None, eval_dataset=valid_data if training_args.do_eval else None, data_collator=default_data_collator, ) state_train = trainer.model.state_dict() if training_args.do_train: train_result = trainer.train() trainer.save_state() utils.safe_save_model_for_hf_trainer(trainer, model_args.output_model_local_path) #utils.safe_save_model_for_hf_trainer(trainer, model_args.output_model_filename) # Evaluation if training_args.do_eval: model.to("cuda") metrics = trainer.evaluate() max_eval_samples = len(valid_data) metrics["eval_samples"] = min(max_eval_samples, len(valid_data)) try: perplexity = math.exp(metrics["eval_loss"]) except OverflowError: perplexity = float("inf") metrics["perplexity"] = perplexity trainer.log_metrics("eval", metrics) trainer.save_metrics("eval", metrics) torch.distributed.barrier() if __name__ == "__main__": train() ================================================ FILE: llm-compression/quantization/llm-qat/cfd70ff/utils.py ================================================ # coding=utf-8 # Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. import logging import os from typing import Dict import torch import transformers # Define a utility method for setting the logging parameters of a logger def get_logger(logger_name): # Get the logger with the specified name logger = logging.getLogger(logger_name) # Set the logging level of the logger to INFO logger.setLevel(logging.INFO) # Define a formatter for the log messages formatter = logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s" ) # Create a console handler for outputting log messages to the console console_handler = logging.StreamHandler() console_handler.setFormatter(formatter) # Add the console handler to the logger logger.addHandler(console_handler) return logger def safe_save_model_for_hf_trainer(trainer: transformers.Trainer, output_dir: str): """Collects the state dict and dump to disk.""" """ #state_dict = trainer.model.state_dict() model = trainer.model model.save_pretrained(output_dir) #print(model) #state_dict = model.state_dict() print("------------------------", trainer.args.should_save) #import torch #torch.save(trainer.model, output_dir) """ print("~~~~~~~~~~~~~~", trainer.args.should_save) state_dict = trainer.model.state_dict() #if False: if trainer.args.should_save: cpu_state_dict = {} for key in state_dict.keys(): if "teacher" in key: continue cpu_state_dict[key] = state_dict[key] del state_dict trainer._save(output_dir, state_dict=cpu_state_dict) # noqa def get_local_rank(): if os.environ["LOCAL_RANK"]: return int(os.environ["LOCAL_RANK"]) else: logging.warning( "LOCAL_RANK from os.environ is None, fall back to get rank from torch distributed" ) return torch.distributed.get_rank() ================================================ FILE: llm-compression/quantization/llm-qat/f4d873a/datautils.py ================================================ # coding=utf-8 # Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. import copy import json import logging import random from dataclasses import dataclass from typing import Dict, Sequence import numpy as np import torch IGNORE_INDEX = -100 DEFAULT_PAD_TOKEN = "[PAD]" DEFAULT_EOS_TOKEN = "" DEFAULT_BOS_TOKEN = "" DEFAULT_UNK_TOKEN = "" def set_seed(seed): np.random.seed(seed) torch.random.manual_seed(seed) def get_train_val_dataset(train_path, valid_path=None): f = open(train_path, "r", encoding="utf-8") data = [] while True: line = f.readline() if not line: break data.append(json.loads(line)) f.close() train_data = [] valid_data = [] if valid_path: f = open(valid_path, "r", encoding="utf-8") while True: line = f.readline() if not line: break valid_data.append(json.loads(line)) f.close() train_data = data else: train_data = data[10000:] valid_data = data[:10000] return train_data, valid_data class CustomJsonDataset(torch.utils.data.IterableDataset): def __init__(self, dataset, tokenizer, block_size=1024): raw_data = dataset self.tokenizer = tokenizer self.block_size = block_size tokenized_datasets = [] for d in raw_data: tokenized_datasets.append(self.tokenize_function(d)) grouped_dataset = self.group_texts(tokenized_datasets) self.input_ids = grouped_dataset["input_ids"] self.labels = grouped_dataset["labels"] self.data = [ dict(input_ids=self.input_ids[i], labels=self.labels[i]) for i in range(len(self.input_ids)) ] def __len__(self): return len(self.input_ids) def __getitem__(self, i): return dict(input_ids=self.input_ids[i], labels=self.labels[i]) def __iter__(self): return iter(self.data) def tokenize_function(self, examples): return self.tokenizer(examples["text"]) def group_texts(self, examples): # Concatenate all texts. # Initialize an empty dictionary concatenated_examples = {} # Loop through the list of dictionaries for d in examples: # Loop through the keys in each dictionary for key in d.keys(): # If the key is not already a key in the dict_of_lists, create a new list if key not in concatenated_examples: concatenated_examples[key] = [] # Append the value to the list associated with the key in dict_of_lists concatenated_examples[key].extend(d[key]) total_length = len(concatenated_examples["input_ids"]) # We drop the small remainder, we could add padding if the model supported it instead of this drop, you can # customize this part to your needs. if total_length >= self.block_size: total_length = (total_length // self.block_size) * self.block_size # Split by chunks of max_len. result = { k: [ t[i : i + self.block_size] for i in range(0, total_length, self.block_size) ] for k, t in concatenated_examples.items() } result["labels"] = result["input_ids"].copy() return result def jload(filename, mode="r"): """Load a .json file into a dictionary.""" with open(filename, mode) as f: jdict = json.load(f) return jdict ================================================ FILE: llm-compression/quantization/llm-qat/f4d873a/run_train.sh ================================================ # coding=utf-8 # Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. torchrun --nproc_per_node=8 --master_port=15001 train.py \ --local_dir "/home/guodong.li/tmp/llama/" \ --input_model_filename "/home/guodong.li/model/llama-7b-hf" \ --output_model_filename "7B-finetuned" \ --train_data_local_path "/home/guodong.li/code/LLM-QAT/gen_data/all_gen.jsonl" \ --do_train True \ --do_eval True \ --model_max_length 1024 \ --fp16 False \ --bf16 True \ --log_on_each_node False \ --logging_dir /home/guodong.li/tmp/output/runs/current \ --num_train_epochs 1 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 1 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --report_to "tensorboard" \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0. \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --tf32 False \ --gradient_checkpointing False \ --qat True \ --w_bits $1 \ --a_bits $2 \ --kv_bits $3 \ --use_kd True \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'LlamaDecoderLayer' ================================================ FILE: llm-compression/quantization/llm-qat/f4d873a/train.py ================================================ # coding=utf-8 # Copyright (c) Meta Platforms, Inc. and affiliates. # All rights reserved. # # This source code is licensed under the license found in the # LICENSE file in the root directory of this source tree. # # 2023.07.05 - Add quantization and knowledge distillialtion # Meta Platforms, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import math from models.configuration_llama import LlamaConfig from models.modeling_llama_quant import ( LlamaForCausalLM as LlamaForCausalLMQuant, ) import copy import torch import transformers from utils import utils from utils import datautils from utils.kd_trainer import KDTrainer from utils.process_args import process_args from torch import distributed as dist from transformers import default_data_collator, Trainer log = utils.get_logger("clm") def train(): dist.init_process_group(backend="nccl") model_args, data_args, training_args = process_args() log.info("Start to load model...") dtype = torch.bfloat16 if training_args.bf16 else torch.float if training_args.qat: config = LlamaConfig.from_pretrained(model_args.input_model_filename) student_config = copy.deepcopy(config) student_config.w_bits = model_args.w_bits student_config.a_bits = model_args.a_bits student_config.kv_bits = model_args.kv_bits student_config.smoothquant = model_args.smoothquant model = LlamaForCausalLMQuant.from_pretrained( pretrained_model_name_or_path=model_args.input_model_filename, config=student_config, cache_dir=training_args.cache_dir, torch_dtype=dtype, low_cpu_mem_usage=True, device_map=None if len(training_args.fsdp) > 0 else "auto", ) else: model = transformers.LlamaForCausalLM.from_pretrained( pretrained_model_name_or_path=model_args.input_model_filename, cache_dir=training_args.cache_dir, torch_dtype=dtype, low_cpu_mem_usage=True, device_map=None if len(training_args.fsdp) > 0 else "auto", ) model.cuda() if training_args.use_kd: teacher_model = transformers.AutoModelForCausalLM.from_pretrained( pretrained_model_name_or_path=model_args.input_model_filename, cache_dir=training_args.cache_dir, torch_dtype=dtype, low_cpu_mem_usage=True, device_map=None if len(training_args.fsdp) > 0 else "auto", ) teacher_model.eval() teacher_model.cuda() for param in teacher_model.parameters(): param.requires_grad = False teacher_model.config.use_cache = False model.kd_loss_scale = training_args.kd_loss_scale model.teacher = teacher_model log.info("Complete model loading...") log.info("Start to load tokenizer...") tokenizer = transformers.LlamaTokenizer.from_pretrained( pretrained_model_name_or_path=model_args.input_model_filename, cache_dir=training_args.cache_dir, model_max_length=training_args.model_max_length, padding_side="right", use_fast=False, ) log.info("Complete tokenizer loading...") train_dataset, valid_dataset = datautils.get_train_val_dataset( train_path=data_args.train_data_local_path, valid_path=data_args.eval_data_local_path if data_args.eval_data_local_path is not None else None, ) train_data = datautils.CustomJsonDataset( train_dataset, tokenizer, block_size=training_args.model_max_length ) valid_data = datautils.CustomJsonDataset( valid_dataset, tokenizer, block_size=min(training_args.model_max_length, 1024) ) model.config.use_cache = False if training_args.use_kd: myTrainer = KDTrainer else: myTrainer = Trainer trainer = myTrainer( model=model, tokenizer=tokenizer, args=training_args, train_dataset=train_data if training_args.do_train else None, eval_dataset=valid_data if training_args.do_eval else None, data_collator=default_data_collator, ) if training_args.do_train: train_result = trainer.train() trainer.save_state() utils.safe_save_model_for_hf_trainer(trainer, model_args.output_model_local_path) # Evaluation if training_args.do_eval: model.to("cuda") metrics = trainer.evaluate() max_eval_samples = len(valid_data) metrics["eval_samples"] = min(max_eval_samples, len(valid_data)) try: perplexity = math.exp(metrics["eval_loss"]) except OverflowError: perplexity = float("inf") metrics["perplexity"] = perplexity trainer.log_metrics("eval", metrics) trainer.save_metrics("eval", metrics) torch.distributed.barrier() if __name__ == "__main__": train() ================================================ FILE: llm-compression/quantization/llm-qat/log.md ================================================ 训练数据来源: 方案一:使用开源数据集。 方案二:使用LLM合成数据。 20230803: 目前,代码中支持使用开源的公开数据集。 20230814:(commit-id: f4d873a) 目前,代码中支持使用LLM合成数据。 目前存在的问题: - 未提供模型评估和模型推理的代码。仅有在模型训练过程中,使用Huggingface的evaluate方法进行评估,相当于仅能评估模型效果,不能评估推理速度。 - 代码没办法直接运行,需要自行修改源码才能启动。 ================================================ FILE: llm-compression/quantization/moe模型量化.md ================================================ Mixture Compressor for Mixture-of-Experts LLMs Gains More MoEQuant: Enhancing Quantization for Mixture-of-Experts Large Language Models via Expert-Balanced Sampling and Affinity Guidance ================================================ FILE: llm-compression/quantization/tools.md ================================================ tools.md ================================================ FILE: llm-compression/quantization/可视化/README.md ================================================ README.md https://matplotlib.org/stable/gallery/color/named_colors.html ``` { 'aliceblue': '#F0F8FF', 'antiquewhite': '#FAEBD7', 'aqua': '#00FFFF', 'aquamarine': '#7FFFD4', 'azure': '#F0FFFF', 'beige': '#F5F5DC', 'bisque': '#FFE4C4', 'black': '#000000', 'blanchedalmond': '#FFEBCD', 'blue': '#0000FF', 'blueviolet': '#8A2BE2', 'brown': '#A52A2A', 'burlywood': '#DEB887', 'cadetblue': '#5F9EA0', 'chartreuse': '#7FFF00', 'chocolate': '#D2691E', 'coral': '#FF7F50', 'cornflowerblue': '#6495ED', 'cornsilk': '#FFF8DC', 'crimson': '#DC143C', 'cyan': '#00FFFF', 'darkblue': '#00008B', 'darkcyan': '#008B8B', 'darkgoldenrod': '#B8860B', 'darkgray': '#A9A9A9', 'darkgreen': '#006400', 'darkgrey': '#A9A9A9', 'darkkhaki': '#BDB76B', 'darkmagenta': '#8B008B', 'darkolivegreen': '#556B2F', 'darkorange': '#FF8C00', 'darkorchid': '#9932CC', 'darkred': '#8B0000', 'darksalmon': '#E9967A', 'darkseagreen': '#8FBC8F', 'darkslateblue': '#483D8B', 'darkslategray': '#2F4F4F', 'darkslategrey': '#2F4F4F', 'darkturquoise': '#00CED1', 'darkviolet': '#9400D3', 'deeppink': '#FF1493', 'deepskyblue': '#00BFFF', 'dimgray': '#696969', 'dimgrey': '#696969', 'dodgerblue': '#1E90FF', 'firebrick': '#B22222', 'floralwhite': '#FFFAF0', 'forestgreen': '#228B22', 'fuchsia': '#FF00FF', 'gainsboro': '#DCDCDC', 'ghostwhite': '#F8F8FF', 'gold': '#FFD700', 'goldenrod': '#DAA520', 'gray': '#808080', 'green': '#008000', 'greenyellow': '#ADFF2F', 'grey': '#808080', 'honeydew': '#F0FFF0', 'hotpink': '#FF69B4', 'indianred': '#CD5C5C', 'indigo': '#4B0082', 'ivory': '#FFFFF0', 'khaki': '#F0E68C', 'lavender': '#E6E6FA', 'lavenderblush': '#FFF0F5', 'lawngreen': '#7CFC00', 'lemonchiffon': '#FFFACD', 'lightblue': '#ADD8E6', 'lightcoral': '#F08080', 'lightcyan': '#E0FFFF', 'lightgoldenrodyellow': '#FAFAD2', 'lightgray': '#D3D3D3', 'lightgreen': '#90EE90', 'lightgrey': '#D3D3D3', 'lightpink': '#FFB6C1', 'lightsalmon': '#FFA07A', 'lightseagreen': '#20B2AA', 'lightskyblue': '#87CEFA', 'lightslategray': '#778899', 'lightslategrey': '#778899', 'lightsteelblue': '#B0C4DE', 'lightyellow': '#FFFFE0', 'lime': '#00FF00', 'limegreen': '#32CD32', 'linen': '#FAF0E6', 'magenta': '#FF00FF', 'maroon': '#800000', 'mediumaquamarine': '#66CDAA', 'mediumblue': '#0000CD', 'mediumorchid': '#BA55D3', 'mediumpurple': '#9370DB', 'mediumseagreen': '#3CB371', 'mediumslateblue': '#7B68EE', 'mediumspringgreen': '#00FA9A', 'mediumturquoise': '#48D1CC', 'mediumvioletred': '#C71585', 'midnightblue': '#191970', 'mintcream': '#F5FFFA', 'mistyrose': '#FFE4E1', 'moccasin': '#FFE4B5', 'navajowhite': '#FFDEAD', 'navy': '#000080', 'oldlace': '#FDF5E6', 'olive': '#808000', 'olivedrab': '#6B8E23', 'orange': '#FFA500', 'orangered': '#FF4500', 'orchid': '#DA70D6', 'palegoldenrod': '#EEE8AA', 'palegreen': '#98FB98', 'paleturquoise': '#AFEEEE', 'palevioletred': '#DB7093', 'papayawhip': '#FFEFD5', 'peachpuff': '#FFDAB9', 'peru': '#CD853F', 'pink': '#FFC0CB', 'plum': '#DDA0DD', 'powderblue': '#B0E0E6', 'purple': '#800080', 'rebeccapurple': '#663399', 'red': '#FF0000', 'rosybrown': '#BC8F8F', 'royalblue': '#4169E1', 'saddlebrown': '#8B4513', 'salmon': '#FA8072', 'sandybrown': '#F4A460', 'seagreen': '#2E8B57', 'seashell': '#FFF5EE', 'sienna': '#A0522D', 'silver': '#C0C0C0', 'skyblue': '#87CEEB', 'slateblue': '#6A5ACD', 'slategray': '#708090', 'slategrey': '#708090', 'snow': '#FFFAFA', 'springgreen': '#00FF7F', 'steelblue': '#4682B4', 'tan': '#D2B48C', 'teal': '#008080', 'thistle': '#D8BFD8', 'tomato': '#FF6347', 'turquoise': '#40E0D0', 'violet': '#EE82EE', 'wheat': '#F5DEB3', 'white': '#FFFFFF', 'whitesmoke': '#F5F5F5', 'yellow': '#FFFF00', 'yellowgreen': '#9ACD32' } ``` ================================================ FILE: llm-compression/quantization/可视化/qwen_activate_visual.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 6, "id": "3b0ad128-a99b-44e2-8fcd-e0d517496f38", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[[ 0.652031 0.04643589 -0.40187663 ... -0.6665882 -0.76702946\n", " 0.29452622]\n", " [ 0.3748061 0.63287777 -0.1933821 ... -0.1571283 -0.03689617\n", " -0.05258662]\n", " [-0.0353355 -0.04532271 -0.02375055 ... 0.03203112 -0.05350752\n", " -0.19852895]\n", " ...\n", " [-0.14501537 0.7277831 0.23639265 ... 0.22381197 0.29034108\n", " 0.3354566 ]\n", " [-0.5548637 0.3631793 0.5244673 ... 0.10587544 0.12167144\n", " 0.02036233]\n", " [ 0.53484774 0.12817204 0.08042635 ... -0.11877135 -0.06255031\n", " -0.05381754]]]\n", "[[[ 0.652031 0.04643589 -0.40187663 ... -0.6665882 -0.76702946\n", " 0.29452622]\n", " [ 0.3748061 0.63287777 -0.1933821 ... -0.1571283 -0.03689617\n", " -0.05258662]\n", " [-0.0353355 -0.04532271 -0.02375055 ... 0.03203112 -0.05350752\n", " -0.19852895]\n", " ...\n", " [-0.14501537 0.7277831 0.23639265 ... 0.22381197 0.29034108\n", " 0.3354566 ]\n", " [-0.5548637 0.3631793 0.5244673 ... 0.10587544 0.12167144\n", " 0.02036233]\n", " [ 0.53484774 0.12817204 0.08042635 ... -0.11877135 -0.06255031\n", " -0.05381754]]]\n", "layer_0:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_1:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_2:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_3:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_4:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_5:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_6:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_7:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_8:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_9:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_10:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_11:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_12:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_13:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_14:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_15:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_16:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_17:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_18:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_19:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_20:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_21:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_22:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_23:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_24:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_25:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_26:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n", "layer_27:\n", "Input shape: (1, 267, 1024)\n", "Output shape: (1, 267, 1024)\n" ] } ], "source": [ "from transformers import AutoModelForCausalLM, AutoTokenizer\n", "import torch\n", "\n", "# 初始化模型\n", "model_id = '/model/ModelScope/Qwen/Qwen3-0.6B'\n", "model = AutoModelForCausalLM.from_pretrained(model_id, device_map=\"auto\")\n", "tokenizer = AutoTokenizer.from_pretrained(model_id)\n", "\n", "\n", "# 用于存储每一层的输入和输出\n", "activations = {}\n", "\n", "# 定义钩子函数\n", "def get_activation(name):\n", " def hook(module, input, output):\n", " hidden_states = output[0]\n", " # print(hidden_states)\n", " activations[name] = {\n", " 'input': input[0].detach().cpu().numpy(),\n", " 'output': output[0].detach().cpu().numpy()\n", " }\n", " return hook\n", "\n", "# 为每一层注册钩子\n", "for i, layer in enumerate(model.model.layers):\n", " layer.register_forward_hook(get_activation(f'layer_{i}'))\n" ] }, { "cell_type": "code", "execution_count": 33, "id": "3700b53e-17b0-416f-a391-a9f7458c2fc4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[[ 0.652031 0.04643589 -0.40187663 ... -0.6665882 -0.76702946\n", " 0.29452622]\n", " [-0.11009285 0.6334653 0.33951125 ... -0.17202726 -0.24047822\n", " -0.21551886]\n", " [-0.39777544 1.131537 -0.25907117 ... -0.4139713 0.10798842\n", " 0.05831181]\n", " ...\n", " [-0.13876776 0.7294401 0.24299505 ... 0.22100824 0.28839892\n", " 0.33561906]\n", " [-0.54995763 0.36405438 0.5262048 ... 0.10363967 0.12153722\n", " 0.02216986]\n", " [ 0.54202735 0.13096127 0.09284829 ... -0.11744348 -0.0588733\n", " -0.06595493]]]\n", "[[[ 0.652031 0.04643589 -0.40187663 ... -0.6665882 -0.76702946\n", " 0.29452622]\n", " [-0.11009285 0.6334653 0.33951125 ... -0.17202726 -0.24047822\n", " -0.21551886]\n", " [-0.39777544 1.131537 -0.25907117 ... -0.4139713 0.10798842\n", " 0.05831181]\n", " ...\n", " [-0.13876776 0.7294401 0.24299505 ... 0.22100824 0.28839892\n", " 0.33561906]\n", " [-0.54995763 0.36405438 0.5262048 ... 0.10363967 0.12153722\n", " 0.02216986]\n", " [ 0.54202735 0.13096127 0.09284829 ... -0.11744348 -0.0588733\n", " -0.06595493]]]\n", "layer_0:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_1:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_2:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_3:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_4:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_5:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_6:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_7:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_8:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_9:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_10:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_11:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_12:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_13:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_14:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_15:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_16:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_17:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_18:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_19:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_20:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_21:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_22:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_23:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_24:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_25:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_26:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n", "layer_27:\n", "Input shape: (1, 261, 1024)\n", "Output shape: (1, 261, 1024)\n" ] } ], "source": [ "# 输入数据\n", "\n", "# 输入文本\n", "input_text = \"\"\"\n", "Large language models (LLMs) show excellent performance but are compute- and memoryintensive. Quantization can reduce memory and\n", "accelerate inference. However, existing methods cannot maintain accuracy and hardware efficiency at the same time. \n", "We propose SmoothQuant, a training-free, accuracy-preserving, and generalpurpose post-training quantization (PTQ) solution\n", "to enable 8-bit weight, 8-bit activation (W8A8) quantization for LLMs. Based on the fact that\n", "weights are easy to quantize while activations are not, SmoothQuant smooths the activation outliers\n", "by offline migrating the quantization difficulty from activations to weights with a mathematically equivalent transformation. \n", "SmoothQuant enables an INT8 quantization of both weights and activations for all the matrix multiplications in\n", "LLMs, including OPT, BLOOM, GLM, MT-NLG, Llama-1/2, Falcon, Mistral, and Mixtral models.\n", "We demonstrate up to 1.56× speedup and 2× memory reduction for LLMs with negligible loss in accuracy. \n", "SmoothQuant enables serving 530B LLM within a single node. Our work offers a turn-key solution that reduces hardware costs and democratizes LLMs.\n", "\"\"\"\n", "\n", "# input_text = \"\"\"\n", "# Hello, how are you? \n", "# \"\"\"\n", " \n", "inputs = tokenizer(input_text, return_tensors='pt')\n", "\n", "# 前向传播\n", "model(inputs['input_ids'].cuda())\n", "\n", "\n", "\n", "print(activations['layer_1']['output'])\n", "print(activations['layer_2']['input'])\n", "\n", "\n", "# 查看激活值\n", "for name, activation in activations.items():\n", " print(f\"{name}:\")\n", " print(f\"Input shape: {activation['input'].shape}\")\n", " print(f\"Output shape: {activation['output'].shape}\")" ] }, { "cell_type": "code", "execution_count": 34, "id": "51ba4c6a-9206-490b-a3e5-ea3536996d38", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(261, 1024)" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "activate_origin = activations['layer_26']['output'].reshape(-1,1024)\n", "activate_origin.shape" ] }, { "cell_type": "code", "execution_count": null, "id": "4d0a97f9-7470-4959-9b3b-9708e982ca48", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "268.81011962890625" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "activate_strip = 2\n", "token_strip = 1\n", "weights = activate_origin[::token_strip, ::activate_strip]\n", "weights.max().item()" ] }, { "cell_type": "code", "execution_count": 36, "id": "7940fbd6-8751-4f64-9150-58beadb9717f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 0 1 2 ... 509 510 511]\n", " [ 0 1 2 ... 509 510 511]\n", " [ 0 1 2 ... 509 510 511]\n", " ...\n", " [ 0 1 2 ... 509 510 511]\n", " [ 0 1 2 ... 509 510 511]\n", " [ 0 1 2 ... 509 510 511]] [[ 0 0 0 ... 0 0 0]\n", " [ 1 1 1 ... 1 1 1]\n", " [ 2 2 2 ... 2 2 2]\n", " ...\n", " [258 258 258 ... 258 258 258]\n", " [259 259 259 ... 259 259 259]\n", " [260 260 260 ... 260 260 260]]\n", "[[0. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]\n", " ...\n", " [0. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]]\n", "执行时间:197.124447 秒\n" ] } ], "source": [ "import numpy as np\n", "import time\n", "import matplotlib\n", "import random\n", "\n", "matplotlib.use('Agg')\n", "\n", "import matplotlib.pyplot as plt\n", "plt.ioff()\n", "\n", "plt.rcParams['path.simplify'] = True\n", "plt.rcParams['path.simplify_threshold'] = 0.1\n", "\n", "# 创建行列索引网格\n", "rows, cols = weights.shape\n", "\n", "x = np.arange(0, cols) # 列索引作为x轴\n", "y = np.arange(0, rows) # 行索引作为y轴\n", "\n", "X, Y = np.meshgrid(x, y) # 生成坐标网格\n", "\n", "print(X, Y)\n", "\n", "# 创建三维图形\n", "fig = plt.figure(figsize=(10, 8))\n", "ax = fig.add_subplot(111, projection='3d')\n", "\n", "bottom = np.zeros_like(weights)\n", "print(bottom)\n", "\n", "# colors = [\"blue\", \"cornflowerblue\", \"mediumturquoise\", \"goldenrod\"] * int(rows * cols / 4)\n", "\n", "colors_element=[\"red\", \"yellow\", \"blue\", \"green\", \"orange\"]\n", "colors=[]\n", "\n", "# for i in range(0, rows):\n", "# colors.extend(random.sample(colors_element, 1)*cols)\n", "\n", "colors_element=[\"red\", \"yellow\", \"blue\", \"green\", \"orange\"]\n", "colors=[]\n", "temp = random.choices(colors_element, k=cols)\n", "for i in range(0, rows):\n", " colors.extend(temp)\n", "\n", "colors_np =np.array(colors)\n", "# print(colors_np)\n", "\n", "ax.bar3d(\n", " X.ravel(), Y.ravel(), bottom.ravel(), 0.05, 0.05, np.abs(weights).ravel(),\n", " color=colors_np,\n", " shade=True,\n", ")\n", "\n", "# 添加标签和标题\n", "ax.set_xlabel('channel', labelpad=15)\n", "ax.set_ylabel('token', labelpad=15)\n", "ax.set_zlabel('Value', labelpad=10)\n", "ax.set_title('Activate Tensor', pad=20)\n", "\n", "start = time.perf_counter()\n", "plt.savefig(\"demo_avtivate.pdf\", dpi=100)\n", "end = time.perf_counter()\n", "exe_time = end - start\n", "print(f\"执行时间:{exe_time:.6f} 秒\")" ] }, { "cell_type": "code", "execution_count": 30, "id": "0c654c1b-eff9-4217-aecf-c7806987f612", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "512 8\n" ] }, { "data": { "text/plain": [ "['yellow',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'green',\n", " 'red',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'red',\n", " 'orange',\n", " 'blue',\n", " 'yellow',\n", " 'yellow',\n", " 'yellow',\n", " 'orange',\n", " 'yellow',\n", " 'red',\n", " 'red',\n", " 'blue',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'yellow',\n", " 'orange',\n", " 'red',\n", " 'orange',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'red',\n", " 'yellow',\n", " 'orange',\n", " 'blue',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'green',\n", " 'blue',\n", " 'green',\n", " 'yellow',\n", " 'orange',\n", " 'red',\n", " 'orange',\n", " 'blue',\n", " 'yellow',\n", " 'yellow',\n", " 'blue',\n", " 'blue',\n", " 'red',\n", " 'blue',\n", " 'blue',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'red',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'green',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'red',\n", " 'green',\n", " 'orange',\n", " 'green',\n", " 'orange',\n", " 'green',\n", " 'green',\n", " 'yellow',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'green',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'green',\n", " 'red',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'green',\n", " 'yellow',\n", " 'blue',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'red',\n", " 'yellow',\n", " 'yellow',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'yellow',\n", " 'blue',\n", " 'red',\n", " 'orange',\n", " 'blue',\n", " 'red',\n", " 'yellow',\n", " 'yellow',\n", " 'blue',\n", " 'red',\n", " 'red',\n", " 'yellow',\n", " 'blue',\n", " 'orange',\n", " 'orange',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'orange',\n", " 'green',\n", " 'blue',\n", " 'green',\n", " 'orange',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'orange',\n", " 'yellow',\n", " 'blue',\n", " 'green',\n", " 'red',\n", " 'yellow',\n", " 'yellow',\n", " 'red',\n", " 'yellow',\n", " 'red',\n", " 'blue',\n", " 'blue',\n", " 'green',\n", " 'red',\n", " 'blue',\n", " 'yellow',\n", " 'blue',\n", " 'green',\n", " 'yellow',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'orange',\n", " 'blue',\n", " 'green',\n", " 'green',\n", " 'blue',\n", " 'red',\n", " 'red',\n", " 'green',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'red',\n", " 'red',\n", " 'green',\n", " 'green',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'red',\n", " 'blue',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'blue',\n", " 'red',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'green',\n", " 'yellow',\n", " 'red',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'red',\n", " 'red',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'yellow',\n", " 'orange',\n", " 'yellow',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'red',\n", " 'green',\n", " 'orange',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'orange',\n", " 'blue',\n", " 'red',\n", " 'green',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'orange',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'yellow',\n", " 'blue',\n", " 'blue',\n", " 'blue',\n", " 'red',\n", " 'green',\n", " 'orange',\n", " 'blue',\n", " 'orange',\n", " 'yellow',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'blue',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'red',\n", " 'orange',\n", " 'blue',\n", " 'red',\n", " 'orange',\n", " 'yellow',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'yellow',\n", " 'red',\n", " 'blue',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'blue',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'green',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'red',\n", " 'blue',\n", " 'red',\n", " 'blue',\n", " 'green',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'blue',\n", " 'blue',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'blue',\n", " 'yellow',\n", " 'red',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'yellow',\n", " 'red',\n", " 'red',\n", " 'green',\n", " 'red',\n", " 'red',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'orange',\n", " 'green',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'blue',\n", " 'yellow',\n", " 'red',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'red',\n", " 'blue',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'yellow',\n", " 'yellow',\n", " 'yellow',\n", " 'yellow',\n", " 'orange',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'blue',\n", " 'green',\n", " 'green',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'blue',\n", " 'blue',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'blue',\n", " 'red',\n", " 'orange',\n", " 'yellow',\n", " 'red',\n", " 'orange',\n", " 'orange',\n", " 'yellow',\n", " 'red',\n", " 'green',\n", " 'red',\n", " 'red',\n", " 'orange',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'orange',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'green',\n", " 'green',\n", " 'green',\n", " 'red',\n", " 'blue',\n", " 'red',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'red',\n", " 'blue',\n", " 'red',\n", " 'red',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'blue',\n", " 'blue',\n", " 'orange',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'red',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'red',\n", " 'blue',\n", " 'green',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'red',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'blue',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'orange',\n", " 'orange',\n", " 'green',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'red',\n", " 'yellow',\n", " 'blue',\n", " 'green',\n", " 'green',\n", " 'yellow',\n", " 'blue',\n", " 'yellow',\n", " 'blue',\n", " 'green',\n", " 'red',\n", " 'orange',\n", " 'blue',\n", " 'red',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'blue',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'yellow',\n", " 'red',\n", " 'orange',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'yellow',\n", " 'yellow',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'yellow',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'red',\n", " 'green',\n", " 'orange',\n", " 'blue',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'red',\n", " 'green',\n", " 'green',\n", " 'orange',\n", " 'yellow',\n", " 'red',\n", " 'red',\n", " 'orange',\n", " 'yellow',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'yellow',\n", " 'blue',\n", " 'blue',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'red',\n", " 'green',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'yellow',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'red',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'yellow',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'yellow',\n", " 'green',\n", " 'red',\n", " 'green',\n", " 'red',\n", " 'green',\n", " 'orange',\n", " 'red',\n", " 'red',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'yellow',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'green',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'red',\n", " 'blue',\n", " 'blue',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'red',\n", " 'yellow',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'yellow',\n", " 'yellow',\n", " 'red',\n", " 'green',\n", " 'green',\n", " 'blue',\n", " 'green',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'red',\n", " 'red',\n", " 'blue',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'blue',\n", " 'yellow',\n", " 'blue',\n", " 'green',\n", " 'green',\n", " 'blue',\n", " 'blue',\n", " 'yellow',\n", " 'blue',\n", " 'blue',\n", " 'green',\n", " 'red',\n", " 'green',\n", " 'orange',\n", " 'blue',\n", " 'yellow',\n", " 'yellow',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'red',\n", " 'blue',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'blue',\n", " 'yellow',\n", " 'blue',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'blue',\n", " 'green',\n", " 'yellow',\n", " 'blue',\n", " 'yellow',\n", " 'blue',\n", " 'red',\n", " 'green',\n", " 'red',\n", " 'yellow',\n", " 'blue',\n", " 'yellow',\n", " 'yellow',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'green',\n", " 'yellow',\n", " 'blue',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'blue',\n", " 'yellow',\n", " 'yellow',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'red',\n", " 'red',\n", " 'red',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'red',\n", " 'yellow',\n", " 'red',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'orange',\n", " 'green',\n", " 'green',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'red',\n", " 'red',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'red',\n", " 'blue',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'red',\n", " 'blue',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'orange',\n", " 'orange',\n", " 'orange',\n", " 'yellow',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'blue',\n", " 'orange',\n", " 'yellow',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'blue',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'blue',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'orange',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'red',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'orange',\n", " 'red',\n", " 'red',\n", " 'red',\n", " 'red',\n", " 'green',\n", " 'orange',\n", " 'blue',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'blue',\n", " 'yellow',\n", " 'orange',\n", " 'blue',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'red',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'blue',\n", " 'green',\n", " 'red',\n", " 'green',\n", " 'red',\n", " 'green',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'blue',\n", " 'red',\n", " 'red',\n", " 'green',\n", " 'green',\n", " 'red',\n", " 'yellow',\n", " 'orange',\n", " 'red',\n", " 'yellow',\n", " 'blue',\n", " 'red',\n", " 'yellow',\n", " 'blue',\n", " 'green',\n", " 'yellow',\n", " 'orange',\n", " 'orange',\n", " 'red',\n", " 'orange',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'red',\n", " 'red',\n", " 'yellow',\n", " 'red',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'orange',\n", " 'yellow',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'orange',\n", " 'green',\n", " 'red',\n", " 'blue',\n", " 'orange',\n", " 'green',\n", " 'orange',\n", " 'blue',\n", " 'blue',\n", " 'green',\n", " 'orange',\n", " 'blue',\n", " 'orange',\n", " 'yellow',\n", " 'blue',\n", " 'green',\n", " 'blue',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'green',\n", " 'yellow',\n", " 'red',\n", " 'blue',\n", " 'red',\n", " 'yellow',\n", " 'blue',\n", " 'red',\n", " 'red',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'red',\n", " 'green',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'yellow',\n", " 'orange',\n", " 'blue',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'green',\n", " 'yellow',\n", " 'yellow',\n", " 'green',\n", " 'green',\n", " 'green',\n", " 'orange',\n", " 'orange',\n", " 'blue',\n", " 'yellow',\n", " 'yellow',\n", " 'red',\n", " 'red',\n", " 'yellow',\n", " 'orange',\n", " 'green',\n", " 'blue',\n", " 'red',\n", " 'blue',\n", " 'red',\n", " 'blue',\n", " ...]" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(cols,rows)\n", "colors_element=[\"red\", \"yellow\", \"blue\", \"green\", \"orange\"]\n", "colors=[]\n", "for i in range(0, rows):\n", " # colors.extend(random.sample(colors_element, 1)*cols)\n", " colors.extend(random.choices(colors_element, k=cols))\n", "colors" ] }, { "cell_type": "code", "execution_count": null, "id": "c043014f-3c7d-4dec-afd1-8f8898c9f2ef", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.16" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-compression/quantization/可视化/qwen_visual.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "id": "b63df770-ff68-4212-8c0e-2be0380f52d4", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/miniconda3/envs/py310/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } ], "source": [ "from transformers import AutoModelForCausalLM, AutoTokenizer\n", "import time" ] }, { "cell_type": "code", "execution_count": 2, "id": "a22cf280-b9ab-4bd0-81c6-5a350ffcf3ba", "metadata": {}, "outputs": [], "source": [ "model_id = '/model/ModelScope/Qwen/Qwen3-0.6B'\n", "\n", "model = AutoModelForCausalLM.from_pretrained(\n", " model_id, device_map=\"auto\", torch_dtype=\"auto\", trust_remote_code=True,\n", ")" ] }, { "cell_type": "code", "execution_count": 3, "id": "7f509dc3-e10f-4830-928d-d4bd956437a9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Qwen3ForCausalLM(\n", " (model): Qwen3Model(\n", " (embed_tokens): Embedding(151936, 1024)\n", " (layers): ModuleList(\n", " (0-27): 28 x Qwen3DecoderLayer(\n", " (self_attn): Qwen3Attention(\n", " (q_proj): Linear(in_features=1024, out_features=2048, bias=False)\n", " (k_proj): Linear(in_features=1024, out_features=1024, bias=False)\n", " (v_proj): Linear(in_features=1024, out_features=1024, bias=False)\n", " (o_proj): Linear(in_features=2048, out_features=1024, bias=False)\n", " (q_norm): Qwen3RMSNorm((128,), eps=1e-06)\n", " (k_norm): Qwen3RMSNorm((128,), eps=1e-06)\n", " )\n", " (mlp): Qwen3MLP(\n", " (gate_proj): Linear(in_features=1024, out_features=3072, bias=False)\n", " (up_proj): Linear(in_features=1024, out_features=3072, bias=False)\n", " (down_proj): Linear(in_features=3072, out_features=1024, bias=False)\n", " (act_fn): SiLU()\n", " )\n", " (input_layernorm): Qwen3RMSNorm((1024,), eps=1e-06)\n", " (post_attention_layernorm): Qwen3RMSNorm((1024,), eps=1e-06)\n", " )\n", " )\n", " (norm): Qwen3RMSNorm((1024,), eps=1e-06)\n", " (rotary_emb): Qwen3RotaryEmbedding()\n", " )\n", " (lm_head): Linear(in_features=1024, out_features=151936, bias=False)\n", ")" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model" ] }, { "cell_type": "code", "execution_count": 4, "id": "47df61fd-5b7c-4ee0-87d6-afd9374a4054", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(151936, 1024)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "embedding_origin = model.model.embed_tokens.weight.cpu().detach().float().numpy()\n", "embedding_origin.shape" ] }, { "cell_type": "code", "execution_count": 5, "id": "7d036a0d-9dc1-4738-815d-3a92b98261c4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2048, 1024)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "weights_origin = model.model.layers[0].self_attn.q_proj.weight.cpu().detach().float().numpy()\n", "rows_origin, cols_origin = weights_origin.shape\n", "rows_origin, cols_origin" ] }, { "cell_type": "code", "execution_count": 6, "id": "3eff032a-314a-420b-90b4-0814c197e4cc", "metadata": {}, "outputs": [], "source": [ "# strip = 8\n", "# weights = weights_origin[::strip, ::strip]\n", "\n", "sub_mat_size = 8\n", "\n", "weights = weights_origin.reshape(rows_origin//sub_mat_size, sub_mat_size, cols_origin//sub_mat_size, sub_mat_size).swapaxes(1, 2).reshape(-1, sub_mat_size, sub_mat_size).max(axis=(1, 2)).reshape(rows_origin//sub_mat_size,cols_origin//sub_mat_size)" ] }, { "cell_type": "code", "execution_count": 12, "id": "a16ba0bf-6c04-427b-a130-4f6ec616e13c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.64453125" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "weights.max().item()" ] }, { "cell_type": "code", "execution_count": 13, "id": "cbd600c7-eefa-4511-aae3-e6888c535b60", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 0 1 2 ... 253 254 255]\n", " [ 0 1 2 ... 253 254 255]\n", " [ 0 1 2 ... 253 254 255]\n", " ...\n", " [ 0 1 2 ... 253 254 255]\n", " [ 0 1 2 ... 253 254 255]\n", " [ 0 1 2 ... 253 254 255]] [[ 0 0 0 ... 0 0 0]\n", " [ 1 1 1 ... 1 1 1]\n", " [ 2 2 2 ... 2 2 2]\n", " ...\n", " [509 509 509 ... 509 509 509]\n", " [510 510 510 ... 510 510 510]\n", " [511 511 511 ... 511 511 511]]\n", "[[0. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]\n", " ...\n", " [0. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]\n", " [0. 0. 0. ... 0. 0. 0.]]\n", "执行时间:186.351504 秒\n" ] } ], "source": [ "import numpy as np\n", "import matplotlib\n", "import random\n", "\n", "matplotlib.use('Agg')\n", "\n", "import matplotlib.pyplot as plt\n", "plt.ioff()\n", "\n", "plt.rcParams['path.simplify'] = True\n", "plt.rcParams['path.simplify_threshold'] = 0.1\n", "\n", "# 创建行列索引网格\n", "rows, cols = weights.shape\n", "\n", "x = np.arange(0, cols) # 列索引作为x轴\n", "y = np.arange(0, rows) # 行索引作为y轴\n", "\n", "X, Y = np.meshgrid(x, y) # 生成坐标网格\n", "\n", "print(X, Y)\n", "\n", "# 创建三维图形\n", "fig = plt.figure(figsize=(10, 8))\n", "ax = fig.add_subplot(111, projection='3d')\n", "\n", "bottom = np.zeros_like(weights)\n", "print(bottom)\n", "\n", "# colors = [\"blue\", \"cornflowerblue\", \"mediumturquoise\", \"goldenrod\"] * int(rows * cols / 4)\n", "\n", "colors_element=[\"red\", \"yellow\", \"blue\", \"green\", \"orange\"]\n", "colors=[]\n", "temp = random.choices(colors_element, k=cols)\n", "for i in range(0, rows):\n", " colors.extend(temp)\n", "\n", "colors_np =np.array(colors)\n", "# print(colors_np)\n", "\n", "ax.bar3d(\n", " X.ravel(), Y.ravel(), bottom.ravel(), 0.01, 0.01, np.abs(weights).ravel(),\n", " color=colors_np,\n", " shade=True,\n", ")\n", "\n", "# 添加标签和标题\n", "ax.set_xlabel('in feature', labelpad=15)\n", "ax.set_ylabel('out feature', labelpad=15)\n", "ax.set_zlabel('Value', labelpad=10)\n", "ax.set_title('Linear Layer Tensor', pad=20)\n", "ax.set_zlim(0, weights.max().item())\n", "\n", "start = time.perf_counter()\n", "plt.savefig(\"demo_strip8.pdf\", dpi=100)\n", "end = time.perf_counter()\n", "exe_time = end - start\n", "print(f\"执行时间:{exe_time:.6f} 秒\")" ] }, { "cell_type": "code", "execution_count": null, "id": "d31cbf79-ca5c-4d60-a51d-684124f4cf06", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.16" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-compression/quantization/大模型量化概述.md ================================================ - 线性量化 - 对称量化 - 非对称量化 - 非线性量化 --- 饱和量化与非饱和量化 --- - QAT、PTQ --- - 大模型量化技术原理-GPTQ、LLM.int8() - 大模型量化技术原理-SmoothQuant - 大模型量化技术原理-AWQ、AutoAWQ - 大模型量化技术原理-SpQR - 大模型量化技术原理-ZeroQuant系列 --- LLM-QAT [Liu等,2023] 利用预训练模型生成的结果来实现无数据蒸馏。此外,LLM-QAT不仅量化权重和激活,还量化了KV缓存。这个策略旨在增强吞吐量并支持更长的序列依赖。LLM-QAT能够将带有量化权重和KV缓存的LLaMA模型蒸馏为仅有4比特的模型。这一突破性的结果论证了生产准确的4比特量化的LLM的可行性。 --- PEQA [Kim等,2023]和QLORA [Dettmers等,2023a]都属于量化感知参数高效微调(PEFT)技术的范畴。这些技术侧重于促进模型压缩和加速推理。 PEQA采用了双阶段过程。在第一阶段,每个全连接层的参数矩阵被量化为低位整数矩阵和标量向量。在第二阶段,对每个特定下游任务的标量向量进行微调。 QLORA引入了新的数据类型、双重量化和分页优化器等创新概念。这些想法旨在在不影响性能的情况下节省内存。QLORA使得大型模型可以在单个GPU上进行微调,同时在Vicuna基准测试上实现了最先进的结果。 --- 在PTQ中,某些方法专注于仅对LLM的权重进行量化,以提高效率并减少计算需求。 LUT-GEMM [Park等,2022]通过仅对权重进行量化以及使用BCQ格式在LLM中优化矩阵乘法,通过提高计算效率来增强延迟降低和性能。 LLM.int8() [Dettmers等,2022]对LLM transformers中的矩阵乘法采用8位量化,在推理过程中有效地减少GPU内存使用量,同时保持性能精度。该方法采用矢量量化和混合精度分解来处理异常值,以实现高效的推理。 ZeroQuant [Yao等,2022]将硬件友好的量化方案、逐层知识蒸馏和优化的量化支持整合在一起,将Transformer-based模型的权重和激活精度减少到最小的INT8,并且对准确性几乎没有影响。 GPTQ [Frantar等,2022]提出了一种基于近似二阶信息的新型分层量化技术,使得每个权重的比特宽度减少到3或4位,与未压缩版本相比,几乎没有准确性损失。 Dettmers和Zettlemoyer通过分析推理缩放定律,深入探讨了LLM中模型大小和位精度之间在零样本性能方面的权衡。他们在各种LLM家族之间进行了广泛的实验,发现4位精度几乎普遍是在总模型位数和零样本准确性之间实现正确平衡的最佳选择。 AWQ [Lin等,2023]发现对于LLM的性能,权重并不是同等重要的,仅保护1%的显著权重可以大大减少量化误差。在此基础上,AWQ采用了激活感知方法,考虑与较大激活幅度对应的权重通道的重要性,这在处理重要特征时起着关键作用。该方法采用逐通道缩放技术来确定最佳缩放因子,从而在量化所有权重的同时最小化量化误差。 OWQ [Lee等,2023]通过分析激活异常如何放大权重量化中的误差,引入了混合精度量化方案,将更高的精度应用于易受激活异常影响的权重。 SpQR [Dettmers等,2023b]确定并隔离了异常权重,将其存储在更高的精度中,并将所有其他权重压缩为3-4位。 此外,许多PTQ中的工作尝试对LLM的权重和激活进行量化。 SmoothQuant [Xiao等,2022]解决了量化激活的挑战,这往往由于异常值的存在而变得更加复杂。SmoothQuant观察到不同的标记在它们的通道上展示出类似的变化,引入了逐通道缩放变换,有效地平滑了幅度,使得模型更易于量化。 鉴于量化LLM中激活的复杂性,RPTQ [Yuan等,2023]揭示了不同通道之间不均匀范围的挑战,以及异常值的存在所带来的问题。为了解决这个问题,RPTQ将通道策略性地分组为簇进行量化,有效地减轻了通道范围的差异。此外,它将通道重排集成到层归一化操作和线性层权重中,以最小化相关的开销。 OliVe [Guo等,2023]进一步采用了outlier-victim对(OVP)量化,并在低硬件开销和高性能增益的情况下局部处理异常值,因为它发现异常值很重要,而其旁边的正常值却不重要。 Outlier Suppression+ [Wei等,2023]通过确认激活中的有害异常呈现出不对称分布,主要集中在特定通道中,引入了一种新的策略,涉及通道级的平移和缩放操作,以纠正异常的不对称呈现,并减轻问题通道的影响,并定量分析了平移和缩放的最佳值,同时考虑了异常的不对称性以及下一层权重引起的量化误差。 ZeroQuant-FP [Wu等,2023]探索了浮点(FP)量化的适用性,特别关注FP8和FP4格式。研究揭示,对于LLM,FP8激活在性能上持续优于INT8,而在权重量化方面,FP4在性能上与INT4相比具有可比性,甚至更优越。为了解决由权重和激活之间的差异引起的挑战,ZeroQuant-FP要求所有缩放因子为2的幂,并将缩放因子限制在单个计算组内。值得注意的是,ZeroQuant-FP还集成了Low Rank Compensation (LoRC) 策略,以进一步增强其量化方法的有效性。 ================================================ FILE: llm-compression/quantization/量化基础.md ================================================ LLM量化可视化指南(理论) - https://newsletter.maartengrootendorst.com/p/a-visual-guide-to-quantization 权重量化及可视化权重分布(实践) - https://www.analyticsvidhya.com/blog/2025/01/neural-network-weight-quantization/ # 线性量化 ## 对称(Symmetric)量化 ### Absmax 量化 在 Absmax 量化中,会取张量中所有元素绝对值的最大值 α 作为量化范围的依据,然后将原始数据的取值范围映射到对称的整数区间,如对于 8 位量化,映射到 [-127,127] 或 [-128,127] 这样以零为中心的对称范围。 对称量化 ## 非对称(Asymmetric)量化 ### Zero-point 量化 在量化过程中,需要将浮点数范围映射到整数范围,同时引入一个零点(zero-point)来处理量化范围的偏移。零点是一个整数值,用于表示原始浮点数中的 0,使得量化后的整数范围可以不对称地表示原始数据的范围。 Zero-point 量化则需要确定零点,以处理量化范围的非对称性和偏移量。 对于权重,是静态且已知,选择范围的校准技术包括: - 手动选择输入范围的百分位数 - 优化原始权重和量化权重之间的均方误差(MSE) - 最小化原始值和量化值之间的熵(KL散度) ## 工作流程: 求权重张量中的最大绝对值 计算缩放因子以拟合 int8 范围内的值 对值进行缩放和舍入 提供量化和去量化值 ================================================ FILE: llm-compression/sparsity/README.md ================================================ Wanda https://arxiv.org/abs/2306.11695 SparseGPT https://arxiv.org/pdf/2301.00774 Outlier Weighed Layerwise Sparsity (OWL) https://arxiv.org/pdf/2310.05175 ## 结构化剪枝 ### LLM-Shearing - https://github.com/princeton-nlp/LLM-Shearing - https://arxiv.org/pdf/2310.06694.pdf - https://xiamengzhou.github.io/sheared-llama/ ================================================ FILE: llm-compression/tools.md ================================================ - https://github.com/vllm-project/llm-compressor/ - https://nvidia.github.io/TensorRT-Model-Optimizer/guides/_choosing_quant_methods.html - https://github.com/NVIDIA/TensorRT-Model-Optimizer/blob/main/examples/deepseek/README.md ================================================ FILE: llm-compression/大模型压缩综述.md ================================================ - A Survey on Model Compression for Large Language Models - https://arxiv.org/pdf/2308.07633.pdf ## 摘要 ## 介绍 ## 方法 ### 剪枝 剪枝是一种强大的技术,通过删除不必要的或冗余组件来减少模型的大小或复杂性。众所周知,有许多冗余参数对模型性能几乎没有影响,因此在直接剪掉这些冗余参数后,模型性能不会受到太多影响。同时,剪枝可以在模型存储、内存效率和计算效率等方面更加友好。 剪枝可以分为非结构化剪枝和结构化剪枝,二者的主要区别在于剪枝目标和由此产生的网络结构。 结构化剪枝剪掉基于特定规则的连接或分层结构,同时保留整体网络结构。非结构化剪枝针对单个参数,会导致不规则的稀疏结构。最近的研究工作致力于将 LLM 与剪枝技术相结合,旨在解决与 LLM 相关的大规模和计算成本。 **结构化剪枝**: - LLM-Pruner https://github.com/horseee/LLM-Pruner (300+) **非结构化剪枝**: - SparseGPT https://github.com/IST-DASLab/sparsegpt (400+) - LoRAPrune - Wanda https://github.com/locuslab/wanda (300+) ### 知识蒸馏 该技术将知识从被称为教师模型的复杂模型转移到被称为学生模型的更简单模型。KD 背后的核心思想是从教师模型的全面知识中转化出更精简、更有效的代表。本文概述了使用 LLM 作为教师模型的蒸馏方法。 研究者根据这些方法是否侧重于将 LLM 的涌现能力(EA)蒸馏到小模型(SLM)进行分类。 因此,这些方法被分为两类:标准 KD 和基于 EA 的 KD **Standard KD**: 使学生模型学习教师模型(LLM)所拥有的常见知识,如输出分布和特征信息,这种方法类似于传统的KD。 - MINILLM 清华和微软研究院 https://github.com/microsoft/LMOps/tree/main/minillm - GKD Google DeepMind GKD: Generalized Knowledge Distillation for Auto-regressive Sequence Models **EA-based KD**: 不仅仅是将LLM的常见知识转移到学生模型中,还涵盖了蒸馏它们独特的涌现能力。具体来说,EA-based KD又分为了上下文学习(ICL)、思维链(CoT)和指令跟随(IF)。 In-Context Learning: - In-context Learning Distillation In-context Learning Distillation: Transferring Few-shot Learning Ability of Pre-trained Language Models 哥伦比亚大学 Chain-of-Thought: - MT-COT Explanations from Large Language Models Make Small Reasoners Better 加州大学圣塔芭芭拉分校、腾讯人工智能实验室、微软等 - Fine-tune-CoT Large language models are reasoning teachers https://github.com/itsnamgyu/reasoning-teacher --- Specializing Smaller Language Models towards Multi-Step Reasoning 爱丁堡大学、艾伦AI研究所 - DISCO https://github.com/eric11eca/disco (12) DISCO: Distilling Counterfactuals with Large Language Models 洛桑联邦理工学院自然语言处理实验室、艾伦人工智能研究所 - SCOTT SCOTT: Self-Consistent Chain-of-Thought Distillation 南加州大学计算机科学系,亚马逊公司 - SOCRATIC CoT 苏黎世联邦理工学院计算机科学系 --- Instruction Following: - Lion Lion: Adversarial Distillation of Closed-Source Large Language Model 香港科技大学 https://github.com/YJiangcm/Lion (144) 三个角色: 教师、审阅者、生成者 三个步骤: 模仿、辨别、生成 7B LLaMA模型接近ChatGPT 95%的能力!港科大提出全新对抗蒸馏框架Lion:https://it.sohu.com/a/680520547_121119001 ### 量化 ### 低秩因式分解 - ZeroQuant-FP(低秩分解+量化) - LoRAPrune(低秩分解+剪枝) ## 指标与基准 ### 指标 LLM 的推理效率可以使用各种指标来衡量。这些指标考虑了性能的不同方面,通常与全面评估 LLM 的准确性和零样本学习能力一起呈现。 这些指标包括如下: 参数规模​ 模型规模 压缩比 推理时间 浮点运算(FLOP) ### 基准(Benchmarks) 基准旨在与未压缩的 LLM 相比,衡量压缩 LLM 的有效性、效率和准确性。这些基准通常由不同的任务和数据集组成,涵盖了一系列自然语言处理挑战。常用基准包括但不限于 HULK 和 ELUE。 ## 挑战 ## 结论 ================================================ FILE: llm-compression/经验.md ================================================ MoE gate 层对量化敏感,通常不进行量化以便保持完全精度。 ================================================ FILE: llm-data-engineering/README.md ================================================ - [Best Practices and Lessons Learned on Synthetic Data for Language Models](https://arxiv.org/pdf/2404.07503.pdf) - 语言模型合成数据的最佳实践和经验教训 - Google DeepMind ================================================ FILE: llm-data-engineering/dataset/README.md ================================================ - [预训练中文语料汇总(附数据)](https://zhuanlan.zhihu.com/p/163616279) 好的数据: 书籍 、 维基百科、 代码 ## 业界大模型训练数据 ### OPT-175B Meta AI 团队希望在尽可能大的语料库上训练这个模型。 它由以下 5 个经过过滤的文本文档数据集的并集组成: BookCorpus,由超过 10K 未出版的书籍组成, CC-Stories,其中包含 CommonCrawl 数据的子集,经过过滤以匹配 Winograd 模式的故事风格, The Pile,其中包括 Pile-CC、OpenWebText2、USPTO、Project Gutenberg、OpenSubtitles、Wikipedia、DM Mathematics 和 HackerNews。 Baumgartner 等人开发的 Pushshift.io Reddit 数据集。 并由 Roller 等人处理。 CCNewsV2 包含 RoBERTa 中使用的 CommonCrawl 新闻数据集英文部分的更新版本 最终的训练数据包含180B个token,对应800GB的数据。 验证分割由 200MB 的预训练数据组成,根据预训练语料库中每个数据集的大小按比例进行采样。 该数据集可能包含令人反感的内容,因为数据集的一部分是公共 Common Crawl 数据的子集以及公共 Reddit 数据的子集,其中可能包含如果直接查看可能具有侮辱性、威胁性或可能导致焦虑的句子 。 ### Bloom-176B 41.5TB 经过大量去重和清洗的文本,包含 46 种语言,最终转换为 350B 个词元 46种自然语言,13种编程语言。 模型的词汇表含 250,680 个词元 数据的多样性很重要,涉及领域越丰富越好 有害信息生成与有害信息鉴别能力难以两全 低质量数据过滤可以提高有害信息鉴别能力,以及下游任务的表现,有害信息过滤会起到相反作用 预训练数据的来源时间,与下游任务数据的来源时间越接近,模型表现就越好。不光预训练数据过时会有负面影响,过于超前也会。 ================================================ FILE: llm-data-engineering/dataset/baichuan2.md ================================================ - 在数据采集过程中,为了数据的全面性和代表性,从多个来源进行数据收集,包括但不限于网页、书籍、研究论文、代码等,各类别数据分布如下所示。 并且对数据进行清洗,如下图所示,主要关注数据的频率和质量:数据频率:借助LSH-like和Embedding特征对数据进行聚类和去重,主要是对每个聚类的簇给文档、段落、句子进行去重和打分,分值用于用于最终的数据采样。数据质量:句子级别质量过滤,但未说明明确过滤规则。不过从下面模型安全部分可以得知,对数据进行了暴力、色情、种族歧视、仇恨言论等有害内容过滤,但应该还包含其他内容。 PS:报告中没有给出过滤后数据采样比例&数据分布情况,比较遗憾。但从垂域效果来看,医疗和法律数据应该不会少,并且从数据本身质量来看,书籍&论文数据的采样率应该也会比较高。 ================================================ FILE: llm-data-engineering/dataset/chinese-corpus-all.md ================================================ ================================================ FILE: llm-data-engineering/dataset/english-corpus-all.md ================================================ ## 开源数据集: - TigerBot:https://github.com/TigerResearch/TigerBot - BELLE:https://github.com/LianjiaTech/BELLE ================================================ FILE: llm-data-engineering/reference.md ================================================ ================================================ FILE: llm-data-engineering/sft-dataset/baichuan2_test.py ================================================ from typing import List def build_chat_input(messages: List[dict]): def _parse_messages(messages, split_role="user"): system, rounds = "", [] round = [] for i, message in enumerate(messages): if message["role"] == "system": assert i == 0 system = message["content"] continue if message["role"] == split_role and round: rounds.append(round) round = [] round.append(message) if round: rounds.append(round) return system, rounds system, rounds = _parse_messages(messages, split_role="user") print(system, rounds) return system, rounds messages = [] messages.append({"role": "system", "content": "你是一个聪明的助手"}) messages.append({"role": "user", "content": "解释一下“温故而知新”"}) messages.append({"role": "assistant", "content": "好的"}) messages.append({"role": "user", "content": "天气不错哇"}) messages.append({"role": "assistant", "content": "是的哈"}) messages.append({"role": "user", "content": "下雨了"}) system, rounds = build_chat_input(messages) max_history_tokens = 1024 history_tokens = [] for round in rounds[::-1]: round_tokens = [] for message in round: if message["role"] == "user": round_tokens.append("user: ") else: round_tokens.append("assistant: ") round_tokens.extend([message["content"]]) if len(history_tokens) == 0 or len(history_tokens) + len(round_tokens) <= max_history_tokens: history_tokens = round_tokens + history_tokens # concat left if len(history_tokens) < max_history_tokens: continue break input_tokens = [system] + history_tokens print(input_tokens) ================================================ FILE: llm-data-engineering/sft-dataset/evol-instruct.md ================================================ ## Evol-Instruct 使用 LLM 而不是人类,自动大规模生产各种难度级别的开放域指令的新方法,以提高 LLM 的性能。 ================================================ FILE: llm-data-engineering/sft-dataset/firefly-template.py ================================================ from dataclasses import dataclass from typing import Dict @dataclass class Template: template_name:str system_format: str user_format: str assistant_format: str system: str stop_word: str # stop_token_id: int template_dict: Dict[str, Template] = dict() def register_template(template_name, system_format, user_format, assistant_format, system, stop_word=None): template_dict[template_name] = Template( template_name=template_name, system_format=system_format, user_format=user_format, assistant_format=assistant_format, system=system, stop_word=stop_word, # stop_token_id=stop_token_id ) # 注册template register_template( template_name='default', system_format='System: {content}\n\n', user_format='User: {content}\nAssistant: ', assistant_format='{content} {stop_token}', system=None, stop_word=None ) register_template( template_name='internlm', system_format="<|System|>:{content}\n", user_format='<|User|>:{content}\n<|Bot|>:', assistant_format='{content}\n', system="You are an AI assistant whose name is InternLM (书生·浦语).\n" "- InternLM (书生·浦语) is a conversational language model that is developed by Shanghai AI Laboratory (上海人工智能实验室). It is designed to be helpful, honest, and harmless.\n" "- InternLM (书生·浦语) can understand and communicate fluently in the language chosen by the user such as English and 中文.", stop_word='' ) register_template( template_name='internlm2', system_format='<|im_start|>system\n{content}<|im_end|>\n', user_format='<|im_start|>user\n{content}<|im_end|>\n<|im_start|>assistant\n', assistant_format='{content}<|im_end|>\n', system="You are an AI assistant whose name is InternLM (书生·浦语).\n" "- InternLM (书生·浦语) is a conversational language model that is developed by Shanghai AI Laboratory (上海人工智能实验室). It is designed to be helpful, honest, and harmless.\n" "- InternLM (书生·浦语) can understand and communicate fluently in the language chosen by the user such as English and 中文.", stop_word='<|im_end|>' ) register_template( template_name='qwen', system_format='<|im_start|>system\n{content}<|im_end|>\n', user_format='<|im_start|>user\n{content}<|im_end|>\n<|im_start|>assistant\n', assistant_format='{content}<|im_end|>\n', system="You are a helpful assistant.", stop_word='<|im_end|>' ) register_template( template_name='yi', system_format='<|im_start|>system\n{content}<|im_end|>\n', user_format='<|im_start|>user\n{content}<|im_end|>\n<|im_start|>assistant\n', assistant_format='{content}<|im_end|>\n', system=None, stop_word='<|im_end|>' ) register_template( template_name="orion", system_format='', user_format='Human: {content}\n\nAssistant: ', assistant_format='{content}', system='', stop_word='', ) register_template( template_name='deepseek', system_format=None, user_format='User: {content}\n\nAssistant: ', assistant_format='{content}<|end▁of▁sentence|>', system=None, stop_word='<|end▁of▁sentence|>' ) # todo 更优雅的实现方式 register_template( template_name='chatglm2', system_format=None, user_format='[Round {idx}]\n\n问:{content}\n\n答:', assistant_format='{content}', system=None, stop_word='', ) register_template( template_name='chatglm3', system_format='{content}', user_format='{content}', assistant_format='{content}', system="You are ChatGLM3, a large language model trained by Zhipu.AI. Follow the user's instructions carefully. Respond using markdown.", stop_word='', ) register_template( template_name='ziya2', system_format=None, user_format=':{content} :', assistant_format='{content}', system=None, stop_word='', ) register_template( template_name="xverse", system_format=None, user_format='Human: {content}\n\nAssistant: ', assistant_format='{content}<|endoftext|>', system=None, stop_word='<|endoftext|>', ) register_template( template_name='minicpm', system_format=None, user_format='<用户>{content}', assistant_format='{content}', system=None, stop_word='' ) register_template( template_name='zephyr', system_format='<|system|>\n{content}', user_format='<|user|>\n{content}\n<|assistant|>\n', assistant_format='{content}\n', system=None, stop_word='' ) register_template( template_name='mistral', system_format='', user_format='[INST]{content}[/INST]', assistant_format='{content}', system='', stop_word='' ) register_template( template_name='mixtral', system_format='', user_format='[INST]{content}[/INST]', assistant_format='{content}', system='', stop_word='' ) register_template( template_name='baichuan', system_format=None, user_format='{content}', assistant_format='{content}', system=None, stop_word='' ) register_template( template_name='baichuan2', system_format=None, user_format='{content}', assistant_format='{content}', system=None, stop_word='' ) register_template( template_name='vicuna', system_format='{content}\n', user_format='USER: {content} ASSISTANT:', assistant_format='{content}', system="A chat between a curious user and an artificial intelligence assistant. " "The assistant gives helpful, detailed, and polite answers to the user's questions.", stop_word='' ) register_template( template_name='llama2', system_format='<>\n{content}\n<>\n\n', user_format='[INST]{content}[/INST]', assistant_format='{content} ', system="You are a helpful, respectful and honest assistant. " "Always answer as helpfully as possible, while being safe. " "Your answers should not include any harmful, unethical, " "racist, sexist, toxic, dangerous, or illegal content. " "Please ensure that your responses are socially unbiased and positive in nature.\n\n" "If a question does not make any sense, or is not factually coherent, " "explain why instead of answering something not correct. " "If you don't know the answer to a question, please don't share false information.", stop_word='' ) register_template( template_name='gemma', system_format='', user_format='user\n{content}\nmodel\n', assistant_format='{content}\n', system='', stop_word='' ) # {system_format}{user_format}{assistant_format}{user_format}{assistant_format} if __name__ == '__main__': print("-------------------") print(template_dict['default']) print("-------------------") print(template_dict['qwen']) print("-------------------") print(template_dict['baichuan']) print("-------------------") print(template_dict['baichuan2']) ================================================ FILE: llm-data-engineering/sft-dataset/jinja-demo.py ================================================ from jinja2 import Template from jinja2.exceptions import TemplateError from jinja2.sandbox import ImmutableSandboxedEnvironment template = Template('Hello {{ name }}!') result = template.render(name='John Doe') print(result) chat_template=( "{% for message in messages %}" "{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}" "{% endfor %}" "{% if add_generation_prompt %}" "{{ '<|im_start|>assistant\n' }}" "{% endif %}" ) def raise_exception(message): raise TemplateError(message) jinja_env = ImmutableSandboxedEnvironment(trim_blocks=True, lstrip_blocks=True) jinja_env.globals["raise_exception"] = raise_exception compiled_template = jinja_env.from_string(chat_template) print(compiled_template) chat = [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "What is your name?" }, { "role": "assistant", "content": "My name is Qwen." } ] add_generation_prompt = True rendered_chat = compiled_template.render( messages=chat, add_generation_prompt=add_generation_prompt ) print(rendered_chat) ================================================ FILE: llm-data-engineering/sft-dataset/jinja-llm-baichuan.py ================================================ from jinja2 import Template from jinja2.exceptions import TemplateError from jinja2.sandbox import ImmutableSandboxedEnvironment system = "system" user = "user" chat_template=( "{% for message in messages %}" "{% if message['role'] == 'user' %}" "{{ '' + message['content'] }}" "{% elif message['role'] == 'assistant' %}" "{{ '' + message['content'] + ''}}" "{% endif %}" "{% endfor %}" "{% if add_generation_prompt and messages[-1]['role'] != 'assistant' %}" "{{ '' }}" "{% endif %}" ) def raise_exception(message): raise TemplateError(message) jinja_env = ImmutableSandboxedEnvironment(trim_blocks=True, lstrip_blocks=True) jinja_env.globals["raise_exception"] = raise_exception compiled_template = jinja_env.from_string(chat_template) print(compiled_template) print("--------------------") prompt="You are a helpful assistant." chat = [ { "role": "user", "content": "What is your name?" }, { "role": "assistant", "content": "My name is Qwen." }, { "role": "user", "content": "What is your name?" } ] add_generation_prompt = True rendered_chat = compiled_template.render( messages=chat, system=system, user=user, add_generation_prompt=add_generation_prompt ) print(rendered_chat) print("--------------------train") add_generation_prompt = False rendered_chat = compiled_template.render( messages=chat, system=system, user=user, add_generation_prompt=add_generation_prompt ) print(rendered_chat) ================================================ FILE: llm-data-engineering/sft-dataset/jinja-llm-baichuan2.py ================================================ from jinja2 import Template from jinja2.exceptions import TemplateError from jinja2.sandbox import ImmutableSandboxedEnvironment # https://github.com/baichuan-inc/Baichuan2/issues/392 """ {% for message in messages %} {% if message['role'] == 'user' %} {{ '' + message['content'] }} {% elif message['role'] == 'assistant' %} {{ '' + message['content'] + ''}} {% endif %} {% endfor %} {% if add_generation_prompt and messages[-1]['role'] != 'assistant' %} {{ '' }} {% endif %} """ system = "system" user = "user" chat_template=( "{% for message in messages %}" "{% if message['role'] == 'user' %}" "{{ '' + message['content'] }}" "{% elif message['role'] == 'assistant' %}" "{{ '' + message['content'] + ''}}" "{% endif %}" "{% endfor %}" "{% if add_generation_prompt and messages[-1]['role'] != 'assistant' %}" "{{ '' }}" "{% endif %}" ) def raise_exception(message): raise TemplateError(message) jinja_env = ImmutableSandboxedEnvironment(trim_blocks=True, lstrip_blocks=True) jinja_env.globals["raise_exception"] = raise_exception compiled_template = jinja_env.from_string(chat_template) print(compiled_template) print("--------------------") chat = [ { "role": "user", "content": "What is your name?" }, { "role": "assistant", "content": "My name is Qwen." }, { "role": "user", "content": "What is your name?" } ] add_generation_prompt = True rendered_chat = compiled_template.render( messages=chat, system=system, user=user, add_generation_prompt=add_generation_prompt ) print(rendered_chat) print("--------------------train") add_generation_prompt = False rendered_chat = compiled_template.render( messages=chat, system=system, user=user, add_generation_prompt=add_generation_prompt ) print(rendered_chat) ================================================ FILE: llm-data-engineering/sft-dataset/jinja-llm-bloom.py ================================================ from jinja2 import Template from jinja2.exceptions import TemplateError from jinja2.sandbox import ImmutableSandboxedEnvironment system = "system" user = "user" chat_template=( "{% if add_prompt %}" "{{ '<|system|>\n' + prompt + '\n'}}" "{% endif %}" "{% for message in messages %}" "{% if message['role'] == 'system' %}" "{{'<|user|>\n' + message['content'] + '\n'}}" "{% elif message['role'] == 'user' %}" "{{'<|assistant|>\n' + message['content'] + '\n'}}" "{% endif %}" "{% endfor %}" "{% if add_generation_prompt %}" "{{ '<|assistant|>\n' }}" "{% endif %}" ) def raise_exception(message): raise TemplateError(message) jinja_env = ImmutableSandboxedEnvironment(trim_blocks=True, lstrip_blocks=True) jinja_env.globals["raise_exception"] = raise_exception compiled_template = jinja_env.from_string(chat_template) print(compiled_template) print("--------------------") prompt="You are a helpful assistant." chat = [ { "role": "system", "content": "What is your name?" }, { "role": "user", "content": "My name is Qwen." } ] add_generation_prompt = True rendered_chat = compiled_template.render( messages=chat, system=system, user=user, add_prompt=True, prompt = prompt, add_generation_prompt=add_generation_prompt ) print(rendered_chat) print("--------------------train") add_generation_prompt = False rendered_chat = compiled_template.render( messages=chat, system=system, user=user, add_prompt=True, prompt = prompt, add_generation_prompt=add_generation_prompt ) print(rendered_chat) ================================================ FILE: llm-data-engineering/sft-dataset/jinja-llm-chatglm3.py ================================================ from jinja2 import Template from jinja2.exceptions import TemplateError from jinja2.sandbox import ImmutableSandboxedEnvironment system = "system" user = "user" chat_template=( "{% if add_prompt %}" "{{ '<|system|>\n' + prompt + '\n'}}" "{% endif %}" "{% for message in messages %}" "{% if message['role'] == 'system' %}" "{{'<|user|>\n' + message['content'] + '\n'}}" "{% elif message['role'] == 'user' %}" "{{'<|assistant|>\n' + message['content'] + '\n'}}" "{% endif %}" "{% endfor %}" "{% if add_generation_prompt %}" "{{ '<|assistant|>\n' }}" "{% endif %}" ) def raise_exception(message): raise TemplateError(message) jinja_env = ImmutableSandboxedEnvironment(trim_blocks=True, lstrip_blocks=True) jinja_env.globals["raise_exception"] = raise_exception compiled_template = jinja_env.from_string(chat_template) print(compiled_template) print("--------------------") prompt="You are a helpful assistant." chat = [ { "role": "system", "content": "What is your name?" }, { "role": "user", "content": "My name is Qwen." } ] add_generation_prompt = True rendered_chat = compiled_template.render( messages=chat, system=system, user=user, add_prompt=True, prompt = prompt, add_generation_prompt=add_generation_prompt ) print(rendered_chat) print("--------------------train") add_generation_prompt = False rendered_chat = compiled_template.render( messages=chat, system=system, user=user, add_prompt=True, prompt = prompt, add_generation_prompt=add_generation_prompt ) # rendered_chat+="" print(rendered_chat) ================================================ FILE: llm-data-engineering/sft-dataset/jinja-llm.py ================================================ from jinja2 import Template from jinja2.exceptions import TemplateError from jinja2.sandbox import ImmutableSandboxedEnvironment system = "system" user = "user" assistant = "assistant" chat_template=( "{% for message in messages %}" "{% if message['role'] == 'system' %}" "{{'<|im_start|>' + system + '\n' + message['content'] + '<|im_end|>' + '\n'}}" "{% elif message['role'] == 'user' %}" "{{'<|im_start|>' + user + '\n' + message['content'] + '<|im_end|>' + '\n'}}" "{% elif message['role'] == 'assistant' %}" "{{'<|im_start|>' + assistant + '\n' + message['content'] + '<|im_end|>' + '\n'}}" "{% endif %}" "{% endfor %}" "{% if add_generation_prompt %}" "{{ '<|im_start|>assistant\n' }}" "{% endif %}" ) def raise_exception(message): raise TemplateError(message) jinja_env = ImmutableSandboxedEnvironment(trim_blocks=True, lstrip_blocks=True) jinja_env.globals["raise_exception"] = raise_exception compiled_template = jinja_env.from_string(chat_template) print(compiled_template) print("--------------------") chat = [ { 'role': 'system', 'content': 'You are a helpful assistant.' }, { "role": "user", "content": "What is your name?" }, { "role": "assistant", "content": "My name is Qwen." } ] add_generation_prompt = True rendered_chat = compiled_template.render( messages=chat, system=system, user=user, assistant=assistant, add_generation_prompt=add_generation_prompt ) print(rendered_chat) ================================================ FILE: llm-data-engineering/sft-dataset/jinja.md ================================================ ================================================ FILE: llm-data-engineering/sft-dataset/数据格式设计.md ================================================ ## 单轮 ``` [ { "id": "identity_2", "conversations": [ { "from": "system", "value": "" }, { "from": "user", "value": "" }, { "from": "assistant", "value": "" } ] } // ... ] ``` ## 多轮 ``` [ { "id": "identity_2", "conversations": [ { "from": "system", "value": "" }, { "from": "user", "value": "" }, { "from": "assistant", "value": "" }, // ... Muti Turn { "from": "user", "value": "" }, { "from": "assistant", "value": "" } ] } // ... ] ``` ================================================ FILE: llm-data-engineering/sft-dataset/数据集格式.md ================================================ ## Alpaca 仅支持单轮对话(alpaca_data.json): ``` { "instruction": "Give three tips for staying healthy.", "input": "", "output": "1.Eat a balanced diet and make sure to include plenty of fruits and vegetables. \n2. Exercise regularly to keep your body active and strong. \n3. Get enough sleep and maintain a consistent sleep schedule." } ``` - https://github.com/tatsu-lab/stanford_alpaca/blob/main/train.py#L127 ``` dict(input_ids=self.input_ids[i], labels=self.labels[i]) ``` ## FastChat(Vicuna) - 参考:https://github.com/lm-sys/FastChat/blob/ec9a07ed22110e9686b51fd6ee9bf635b7ce54f8/fastchat/conversation.py 单轮对话(alpaca-data-conversation.json): ``` { "id": "1", "conversations": [ { "from": "human", "value": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instruction:\nGive three tips for staying healthy.\n\n### Response:" }, { "from": "gpt", "value": "1.Eat a balanced diet and make sure to include plenty of fruits and vegetables. \n2. Exercise regularly to keep your body active and strong. \n3. Get enough sleep and maintain a consistent sleep schedule." } ] } ``` 多轮对话(dummy_conversation.json): ``` { "id": "identity_2", "conversations": [ { "from": "human", "value": "What is up?" }, { "from": "gpt", "value": "Hello! How can I help you today?" }, { "from": "human", "value": "Who are you?" }, { "from": "gpt", "value": "You can call me Vicuna, and I was trained by Large Model Systems Organization (LMSYS) researchers as a language model." }, { "from": "human", "value": "Goodbye" }, { "from": "gpt", "value": "Goodbye! If you have any more questions in the future, don't hesitate to ask." } ] } ``` ## ChatGLM2 每条数据格式为: `[gMASK]sop [Round 1]\n\n问:{input1}\n\n答:{target1}[Round 2]\n\n问:{input2}\n\n答:{target2}...` - https://github.com/THUDM/ChatGLM2-6B/blob/921d7e9adc69020a19169d1ba4f76c2675a2dd29/ptuning/main.py#L180 训练: ``` {"prompt": "长城h3风扇不转。继电器好的。保险丝好的传感器新的风扇也新的这是为什么。就是继电器缺一个信号线", "response": "用电脑能读数据流吗?水温多少", "history": []} {"prompt": "95", "response": "上下水管温差怎么样啊?空气是不是都排干净了呢?", "history": [["长城h3风扇不转。继电器好的。保险丝好的传感器新的风扇也新的这是为什么。就是继电器缺一个信号线", "用电脑能读数据流吗?水温多少"]]} {"prompt": "是的。上下水管都好的", "response": "那就要检查线路了,一般风扇继电器是由电脑控制吸合的,如果电路存在断路,或者电脑坏了的话会出现继电器不吸合的情况!", "history": [["长城h3风扇不转。继电器好的。保险丝好的传感器新的风扇也新的这是为什么。就是继电器缺一个信号线", "用电脑能读数据流吗?水温多少"], ["95", "上下水管温差怎么样啊?空气是不是都排干净了呢?"]]} ``` ```python def preprocess_function_train(examples): max_seq_length = data_args.max_source_length + data_args.max_target_length + 1 model_inputs = { "input_ids": [], "labels": [], } for i in range(len(examples[prompt_column])): if examples[prompt_column][i] and examples[response_column][i]: query, answer = examples[prompt_column][i], examples[response_column][i] history = examples[history_column][i] if history_column is not None else None prompt = tokenizer.build_prompt(query, history) prompt = prefix + prompt a_ids = tokenizer.encode(text=prompt, add_special_tokens=True, truncation=True, max_length=data_args.max_source_length) b_ids = tokenizer.encode(text=answer, add_special_tokens=False, truncation=True, max_length=data_args.max_target_length) context_length = len(a_ids) input_ids = a_ids + b_ids + [tokenizer.eos_token_id] labels = [tokenizer.pad_token_id] * context_length + b_ids + [tokenizer.eos_token_id] pad_len = max_seq_length - len(input_ids) input_ids = input_ids + [tokenizer.pad_token_id] * pad_len labels = labels + [tokenizer.pad_token_id] * pad_len if data_args.ignore_pad_token_for_loss: labels = [(l if l != tokenizer.pad_token_id else -100) for l in labels] model_inputs["input_ids"].append(input_ids) model_inputs["labels"].append(labels) return model_inputs ``` - https://huggingface.co/THUDM/chatglm2-6b/blob/main/tokenization_chatglm.py#L162 ```python def get_prefix_tokens(self): prefix_tokens = [self.get_command("[gMASK]"), self.get_command("sop")] return prefix_tokens # 推理 def build_prompt(self, query, history=None): if history is None: history = [] prompt = "" for i, (old_query, response) in enumerate(history): prompt += "[Round {}]\n\n问:{}\n\n答:{}\n\n".format(i + 1, old_query, response) prompt += "[Round {}]\n\n问:{}\n\n答:".format(len(history) + 1, query) return prompt def build_inputs_with_special_tokens( self, token_ids_0: List[int], token_ids_1: Optional[List[int]] = None ) -> List[int]: """ Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and adding special tokens. A BERT sequence has the following format: - single sequence: `[CLS] X [SEP]` - pair of sequences: `[CLS] A [SEP] B [SEP]` Args: token_ids_0 (`List[int]`): List of IDs to which the special tokens will be added. token_ids_1 (`List[int]`, *optional*): Optional second list of IDs for sequence pairs. Returns: `List[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens. """ prefix_tokens = self.get_prefix_tokens() token_ids_0 = prefix_tokens + token_ids_0 if token_ids_1 is not None: token_ids_0 = token_ids_0 + token_ids_1 + [self.get_command("")] return token_ids_0 ``` - https://github.com/THUDM/ChatGLM2-6B/blob/main/cli_demo.py#L19 推理: ``` def build_prompt(history): prompt = "欢迎使用 ChatGLM2-6B 模型,输入内容即可进行对话,clear 清空对话历史,stop 终止程序" for query, response in history: prompt += f"\n\n用户:{query}" prompt += f"\n\nChatGLM2-6B:{response}" return prompt ``` ## ChatGLM3 参考: - https://github.com/THUDM/ChatGLM3/blob/main/PROMPT.md - https://github.com/THUDM/ChatGLM3/blob/main/finetune_demo/finetune_hf.py - https://github.com/tangqiaoyu/ToolAlpaca 单轮对话(参考Alpaca): ``` {"context": "hello", "target": "hi,I am ChatGLM3"} ``` 其中,context是对话的上文,也就是模型的输入,target是对话的下文,也就是模型的输出。 基座模型不支持对话,工具,代码生成等能力,仅支持文本生成。如果你需要对话能力,请使用Chat模型和对应的微调框架。 - https://github.com/THUDM/ChatGLM3/blob/main/finetune_chatmodel_demo/preprocess_utils.py#L112 InputOutputDataset ``` { "input_ids": input_ids, "labels": labels } ``` 多轮对话: ChatGLM3 对话的格式由若干对话组成,其中每个对话包含对话头和内容,一个典型的多轮对话结构如下: ``` <|system|> You are ChatGLM3, a large language model trained by Zhipu.AI. Follow the user's instructions carefully. Respond using markdown. <|user|> Hello <|assistant|> Hello, I'm ChatGLM3. What can I assist you today? ``` 实际中每轮对话内容并不一定以换行符结尾,这里只是为了美观。 多轮(仅对话): ``` [ { "conversations": [ { "role": "system", "content": "" }, { "role": "user", "content": "" }, { "role": "assistant", "content": "" }, // ... Muti Turn { "role": "user", "content": "" }, { "role": "assistant", "content": "" } ] } // ... ] ``` 多轮(对话+工具): ```json [ { "tools": [ // available tools, format is not restricted ], "conversations": [ { "role": "system", "content": "" }, { "role": "user", "content": "" }, { "role": "assistant", "content": "" }, { "role": "tool", "name": "": "" }, "observation": "" // don't have to be string }, { "role": "assistant", "content": "" }, // ... Muti Turn { "role": "user", "content": "" }, { "role": "assistant", "content": "" } ] } // ... ] ``` - https://github.com/THUDM/ChatGLM3/blob/main/finetune_chatmodel_demo/preprocess_utils.py#L82 MultiTurnDataset ``` { "input_ids": tokens, "labels": labels } ``` ## Baichuan - https://github.com/baichuan-inc/Baichuan-13B/issues/25 - https://github.com/lm-sys/FastChat/blob/main/fastchat/conversation.py - https://huggingface.co/baichuan-inc/Baichuan-13B-Chat/blob/main/generation_utils.py#L7 ``` user_token_id:195 -> assistant_token_id: 196 -> {query}{answer} # 2. id拼接方式 [195] + tokenizer.encode("你好") + [196] + tokenizer.encode("我是人工智能助理") # [195, 9875, 31213, 196, 6323, 31161, 22073, 1974 ``` ## Baichuan2 参考: ``` { "id": "77771", "conversations": [ { "from": "human", "value": "写一篇关于气候变化对海洋生态的影响的文章。\n" }, { "from": "gpt", "value": "好的,以下是你要求的文章:\n气候变化对海洋生态的影响\n气候变化对海洋生态产生了广泛的影响。全球变暖导致海洋温度上升,这可能会对许多水生生物的生存、繁殖和迁移造成巨大的影响。另外,海洋酸化也是一个问题,因为大气中二氧化碳的增加导致海水中的pH值下降,使得许多生物的外骨骼变得脆弱,从而影响它们的生存和繁殖。\n此外,气候变化还会引起海平面上升,这不仅对海岸线和沿海居民产生影响,还会对许多海洋生物的栖息地造成影响。一些岛屿上的陆地生物面临几乎完全消失的风险,而另一些生物范围则会扩大到更广泛的领域,这可能会导致新的竞争和生态平衡的改变。\n总之,气候变化并不只是一个地球气温的问题,它对海洋生态系统产生了广泛和深远的影响。\n" }, { "from": "human", "value": "从刚刚的文章中提取出气候变化对海洋生物繁殖的影响。\n" }, { "from": "gpt", "value": "文章已经提到过气候变化会对海洋生物的生存、繁殖和迁移造成影响。例如,海洋酸化会使得许多生物的外骨骼变得脆弱,进而影响它们的生存和繁殖。此外,海洋温度上升也可能会对很多生物的生存和繁殖产生负面影响。" } ] } ``` - https://github.com/baichuan-inc/Baichuan2/blob/main/fine-tune/fine-tune.py#L70 ```python def preprocessing(self, example): input_ids = [] labels = [] for message in example["conversations"]: from_ = message["from"] value = message["value"] value_ids = self.tokenizer.encode(value) if from_ == "human": input_ids += self.user_tokens + value_ids labels += [self.tokenizer.eos_token_id] + [self.ignore_index] * len( value_ids ) else: input_ids += self.assistant_tokens + value_ids labels += [self.ignore_index] + value_ids input_ids.append(self.tokenizer.eos_token_id) labels.append(self.tokenizer.eos_token_id) input_ids = input_ids[: self.model_max_length] labels = labels[: self.model_max_length] input_ids += [self.tokenizer.pad_token_id] * ( self.model_max_length - len(input_ids) ) labels += [self.ignore_index] * (self.model_max_length - len(labels)) input_ids = torch.LongTensor(input_ids) labels = torch.LongTensor(labels) attention_mask = input_ids.ne(self.tokenizer.pad_token_id) return { "input_ids": input_ids, "labels": labels, "attention_mask": attention_mask, } ``` - https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/blob/main/tokenization_baichuan.py#L174 ```python def build_inputs_with_special_tokens(self, token_ids_0, token_ids_1=None): bos_token_id = [self.bos_token_id] if self.add_bos_token else [] eos_token_id = [self.eos_token_id] if self.add_eos_token else [] output = bos_token_id + token_ids_0 + eos_token_id if token_ids_1 is not None: output = output + bos_token_id + token_ids_1 + eos_token_id return output ``` ## ModelScope-Agent 参考: - https://github.com/modelscope/modelscope-agent - https://modelscope.cn/datasets/damo/MSAgent-Bench/summary MSAgent-Bench数据集主要包括了四种:AI模型API,通用API,API无关通用sft数据,API检索增强数据 ``` { "id":"modelscope_merge_api_527", "conversations":[ { "from":"system", "value":"你是达摩院的ModelScopeGPT(魔搭助手),你是个大语言模型, 是2023年达摩院的工程师训练得到的。你有多种能力,可以通过插件集成魔搭社区的模型api来回复用户的问题,还能解答用户使用模型遇到的问题和模型知识相关问答。1. {\"plugin_name\": \"modelscope_text-ie\", \"plugin_owner\": \"ModelScopeGPT\", \"plugin_type\": \"default\", \"plugin_schema_for_model\": {\"name\": \"modelscope_text-ie\", \"description\": \"针对中文的文本,根据schema要抽取的内容,找出其中对应信息,并用json格式展示\", \"url\": \"http://109.199.101.10:1485/\", \"paths\": [{\"name\": \"modelscope_text-ie\", \"model_id\": \"/damo/nlp_structbert_siamese-uie_chinese-base\", \"method\": \"post\", \"description\": \"针对中文的文本,根据schema要抽取的内容,找出其中对应信息,并用json格式展示\", \"parameters\": [{\"name\": \"text\", \"description\": \"用户输入的文本\", \"required\": \"True\"}, {\"name\": \"schema\", \"description\": \"要抽取信息的json表示\", \"required\": \"True\"}]}]}}\n\n2. {\"plugin_name\": \"modelscope_text-ie\", \"plugin_owner\": \"ModelScopeGPT\", \"plugin_type\": \"default\", \"plugin_schema_for_model\": {\"name\": \"modelscope_text-ie\", \"description\": \"针对中文的文本,根据schema要抽取的内容,找出其中对应信息,并用json格式展示\", \"url\": \"http://9.32.64.200:5873/\", \"paths\": [{\"name\": \"modelscope_text-ie\", \"model_id\": \"/damo/nlp_structbert_siamese-uie_chinese-base\", \"method\": \"post\", \"description\": \"针对中文的文本,根据schema要抽取的内容,找出其中对应信息,并用json格式展示\", \"parameters\": [{\"name\": \"text\", \"description\": \"用户输入的文本\", \"required\": \"True\"}, {\"name\": \"schema\", \"description\": \"要抽取信息的json表示\", \"required\": \"True\"}]}]}}\n\n3. {\"plugin_name\": \"modelscope_text-ie\", \"plugin_owner\": \"ModelScopeGPT\", \"plugin_type\": \"default\", \"plugin_schema_for_model\": {\"name\": \"modelscope_text-ie\", \"description\": \"针对中文的文本,根据schema要抽取的内容,找出其中对应信息,并用json格式展示\", \"url\": \"http://54.149.78.185:3979/\", \"paths\": [{\"name\": \"modelscope_text-ie\", \"model_id\": \"/damo/nlp_structbert_siamese-uie_chinese-base\", \"method\": \"post\", \"description\": \"针对中文的文本,根据schema要抽取的内容,找出其中对应信息,并用json格式展示\", \"parameters\": [{\"name\": \"text\", \"description\": \"用户输入的文本\", \"required\": \"True\"}, {\"name\": \"schema\", \"description\": \"要抽取信息的json表示\", \"required\": \"True\"}]}]}}" }, { "from":"user", "value":"按照给定的schema抽取出下面文本对应的信息\nschema:{\"人物\": null, \"地理位置\": null, \"组织机构\": null}\n近日,美国政府宣布将对中国1000多种商品加征关税,并威胁进一步加征关税。" }, { "from":"assistant", "value":"<|startofthink|>```JSON\n{\"api_name\": \"modelscope_text-ie\", \"url\": \"http://9.32.64.200:5873/damo/nlp_structbert_siamese-uie_chinese-base\", \"parameters\": {\"text\": \"近日,美国政府宣布将对中国1000多种商品加征关税,并威胁进一步加征关税。\", \"schema\": \"{\\\"人物\\\": null, \\\"地理位置\\\": null, \\\"组织机构\\\": null}\"}}\n```<|endofthink|>\n\n<|startofexec|>```JSON\n{\"人物\": [], \"地理位置\": [\"中国\", \"美国\"], \"组织机构\": []}\n```<|endofexec|>\n信息抽取结果:{\"人物\": [], \"地理位置\": [\"中国\", \"美国\"], \"组织机构\": []}。我使用的模型是ModelScope的'damo/nlp_structbert_siamese-uie_chinese-base'模型。这是一个基于StructBERT预训练模型微调训练的通用信息抽取模型。" } ] } ``` 数据格式说明: id和converstions两个字段,其中conversations里面包含了system,user,assistant三种字段。其中: - system: 表示给模型前置的人设输入,其中有告诉模型如何调用插件以及生成请求 - user: 表示用户的输入prompt,分为两种,通用生成的prompt和调用插件需求的prompt - assistant: 为模型的回复。其中会包括插件调用代码和执行代码,调用代码是要LLM生成的,而执行代码是调用服务来生成结果的。 - 比如:调用部分代码会通过<|startofthink|>和<|endofthink|>包起来,然后执行部分代码是api执行完结果后,把执行结果通过<|startofexec|>和<|endofexec|>包起来再输入给模型生成后面的回复 startofthink-endofthink: ``` { "api_name": "modelscope_text-ie", "url": "http://9.32.64.200:5873/damo/nlp_structbert_siamese-uie_chinese-base", "parameters": { "text": "近日,美国政府宣布将对中国1000多种商品加征关税,并威胁进一步加征关税。", "schema": "{\"人物\": null, \"地理位置\": null, \"组织机构\": null}" } } ``` startofexec-endofexec: ``` { "人物": [], "地理位置": ["中国", "美国"], "组织机构": [] } ``` **推理链路搭建设计到LLM的推理和API的调用** - 模型生成完整的<|startofthink|>和<|endofthink|>后,需要我们实时的去请求对应的API - 返回结果后<|startofexec|>和<|endofexec|>拼接到现有的输入 - 然后再让大模型继续生成回复 - https://github.com/modelscope/modelscope-agent/blob/master/demo/tool_agent_finetune_swift/llm_sft.py - https://github.com/modelscope/modelscope-agent/blob/master/demo/tool_agent_finetune_swift/utils/dataset.py#L18 ``` def get_ms_tool_dataset(dataset_name_or_file) -> HfDataset: dataset = HfDataset.from_dict({ 'inputs': all_inputs_str, 'flags': all_inputs_flag }) return dataset ``` ## Openai-Chatml ## Firefly - https://github.com/yangjianxin1/Firefly/blob/master/component/template.py#L172 - https://github.com/yangjianxin1/Firefly/blob/master/component/dataset.py ## QWen ## qwen1 - https://huggingface.co/Qwen/Qwen-72B ``` # Note: The default behavior now has injection attack prevention off. tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen-72B", trust_remote_code=True) # use bf16 # model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-72B", device_map="auto", trust_remote_code=True, bf16=True).eval() # use fp16 # model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-72B", device_map="auto", trust_remote_code=True, fp16=True).eval() # use cpu only # model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-72B", device_map="cpu", trust_remote_code=True).eval() # use auto mode, automatically select precision based on the device. model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-72B", device_map="auto", trust_remote_code=True).eval() # Specify hyperparameters for generation. But if you use transformers>=4.32.0, there is no need to do this. # model.generation_config = GenerationConfig.from_pretrained("Qwen/Qwen-72B", trust_remote_code=True) inputs = tokenizer('蒙古国的首都是乌兰巴托(Ulaanbaatar)\n冰岛的首都是雷克雅未克(Reykjavik)\n埃塞俄比亚的首都是', return_tensors='pt') inputs = inputs.to(model.device) pred = model.generate(**inputs) print(tokenizer.decode(pred.cpu()[0], skip_special_tokens=True)) # 蒙古国的首都是乌兰巴托(Ulaanbaatar)\n冰岛的首都是雷克雅未克(Reykjavik)\n埃塞俄比亚的首都是亚的斯亚贝巴(Addis Ababa)... ``` ## qwen1.5 ``` model = AutoModelForCausalLM.from_pretrained( "Qwen/Qwen1.5-1.8B-Chat", torch_dtype="auto", device_map="auto" ) tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen1.5-1.8B-Chat") prompt = "Give me a short introduction to large language model." messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] text = tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) model_inputs = tokenizer([text], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=512 ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] ``` - 官网示例:https://qwen.readthedocs.io/en/latest/training/SFT/example.html ``` { "type": "chatml", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "Tell me something about large language models." }, { "role": "assistant", "content": "Large language models are a type of language model that is trained on a large corpus of text data. They are capable of generating human-like text and are used in a variety of natural language processing tasks..." } ], "source": "unknown" } { "type": "chatml", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "What is your name?" }, { "role": "assistant", "content": "My name is Qwen." } ], "source": "self-made" } ``` - qwen2:https://github.com/huggingface/transformers/blob/ff841900e45763114d2417fb24ce29d950c6c956/docs/source/en/model_doc/qwen2.md 训练: - https://github.com/QwenLM/Qwen1.5/blob/main/examples/sft/finetune.py#L146 ``` messages = [example["messages"] for example in raw_data] for i, msg in enumerate(messages): texts.append( tokenizer.apply_chat_template( msg, tokenize=True, add_generation_prompt=False, padding=True, max_length=max_len, truncation=True, ) ) ``` 推理: - https://github.com/QwenLM/Qwen1.5/blob/main/examples/demo/cli_demo.py#L126 ``` conversation = [ {'role': 'system', 'content': 'You are a helpful assistant.'}, ] for query_h, response_h in history: conversation.append({'role': 'user', 'content': query_h}) conversation.append({'role': 'assistant', 'content': response_h}) conversation.append({'role': 'user', 'content': query}) inputs = tokenizer.apply_chat_template( conversation, add_generation_prompt=True, return_tensors='pt', ) ``` ## QWen-Agent ## InternLM ## hf-transformers - https://github.com/huggingface/transformers/blob/ff841900e45763114d2417fb24ce29d950c6c956/src/transformers/tokenization_utils_base.py#L1847 ``` def apply_chat_template( self, conversation: Union[List[Dict[str, str]], List[List[Dict[str, str]]], "Conversation"], chat_template: Optional[str] = None, add_generation_prompt: bool = False, tokenize: bool = True, padding: bool = False, truncation: bool = False, max_length: Optional[int] = None, return_tensors: Optional[Union[str, TensorType]] = None, return_dict: bool = False, tokenizer_kwargs: Optional[Dict[str, Any]] = None, **kwargs, ) ``` - 官网示例:https://huggingface.co/docs/transformers/main/chat_templating 默认对话模板(default chat template): ``` "{% for message in messages %}" "{{'<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>' + '\n'}}" "{% endfor %}" "{% if add_generation_prompt %}" "{{ '<|im_start|>assistant\n' }}" "{% endif %}" ``` ``` <|im_start|>system You are a helpful chatbot that will do its best not to say anything so stupid that people tweet about it.<|im_end|> <|im_start|>user How are you?<|im_end|> <|im_start|>assistant I'm doing great!<|im_end|> ``` ### 模型单独定义默认的模板 示例:blenderbot 模型 - https://github.com/huggingface/transformers/blob/ff841900e45763114d2417fb24ce29d950c6c956/src/transformers/models/blenderbot/tokenization_blenderbot.py#L89 - loop.last:如果是最后一次迭代,为True - loop.first:如果是第一次迭代,为True ``` ( "{% for message in messages %}" "{% if message['role'] == 'user' %}{{ ' ' }}{% endif %}" "{{ message['content'] }}" "{% if not loop.last %}{{ ' ' }}{% endif %}" "{% endfor %}" "{{ eos_token }}" ) ``` ``` from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("facebook/blenderbot-400M-distill") chat = [ {"role": "user", "content": "Hello, how are you?"}, {"role": "assistant", "content": "I'm doing great. How can I help you today?"}, {"role": "user", "content": "I'd like to show off how chat templating works!"}, ] tokenizer.apply_chat_template(chat, tokenize=False) ``` ``` " Hello, how are you? I'm doing great. How can I help you today? I'd like to show off how chat templating works!" ``` ### LLaMA ``` {% for message in messages %} {% if message['role'] == 'user' %} {{ bos_token + '[INST] ' + message['content'] + ' [/INST]' }} {% elif message['role'] == 'system' %} {{ '<>\\n' + message['content'] + '\\n<>\\n\\n' }} {% elif message['role'] == 'assistant' %} {{ ' ' + message['content'] + ' ' + eos_token }} {% endif %} {% endfor %} ``` ================================================ FILE: llm-eval/EvalScope.md ================================================ Qwen3 模型评测最佳实践:https://evalscope.readthedocs.io/zh-cn/latest/best_practice/qwen3.html ## 性能压测 https://evalscope.readthedocs.io/zh-cn/latest/user_guides/stress_test/parameters.html ## 效果测评 - https://evalscope.readthedocs.io/zh-cn/latest/get_started/basic_usage.html - 推理模型评估:https://github.com/modelscope/evalscope/blob/main/docs/zh/best_practice/deepseek_r1_distill.md ## 架构图


EvalScope 整体架构图.

架构介绍 1. **Model Adapter**: 模型适配器,用于将特定模型的输出转换为框架所需的格式,支持API调用的模型和本地运行的模型。 2. **Data Adapter**: 数据适配器,负责转换和处理输入数据,以便适应不同的评测需求和格式。 3. **Evaluation Backend**: - **Native**:EvalScope自身的**默认评测框架**,支持多种评测模式,包括单模型评测、竞技场模式、Baseline模型对比模式等。 - **OpenCompass**:支持[OpenCompass](https://github.com/open-compass/opencompass)作为评测后端,对其进行了高级封装和任务简化,您可以更轻松地提交任务进行评测。 - **VLMEvalKit**:支持[VLMEvalKit](https://github.com/open-compass/VLMEvalKit)作为评测后端,轻松发起多模态评测任务,支持多种多模态模型和数据集。 - **RAGEval**:支持RAG评测,支持使用[MTEB/CMTEB](https://evalscope.readthedocs.io/zh-cn/latest/user_guides/backend/rageval_backend/mteb.html)进行embedding模型和reranker的独立评测,以及使用[RAGAS](https://evalscope.readthedocs.io/zh-cn/latest/user_guides/backend/rageval_backend/ragas.html)进行端到端评测。 - **ThirdParty**:其他第三方评测任务,如ToolBench。 4. **Performance Evaluator**: 模型性能评测,负责具体衡量模型推理服务性能,包括性能评测、压力测试、性能评测报告生成、可视化。 5. **Evaluation Report**: 最终生成的评测报告,总结模型的性能表现,报告可以用于决策和进一步的模型优化。 6. **Visualization**: 可视化结果,帮助用户更直观地理解评测结果,便于分析和比较不同模型的表现。
## 数据集 modelscope download --dataset modelscope/cmmlu --local_dir ./cmmlu modelscope download --dataset modelscope/ceval-exam --local_dir ./ceval modelscope download --dataset modelscope/gsm8k --local_dir gsm8k --- ================================================ FILE: llm-eval/README.md ================================================ - https://evalscope.readthedocs.io/zh-cn/latest/user_guides/backend/opencompass_backend.html - https://github.com/open-compass/opencompass ## 测评集 - Humaneval:代码生成 - CommonSenseQA:知识问答 - MBPP:代码 ================================================ FILE: llm-eval/eval-data/longtext_L115433-question.txt ================================================ 第58届全球帅哥竞选活动有什么特别之处? ================================================ FILE: llm-eval/eval-data/longtext_L115433.txt ================================================ \n\n### 文章 1\n\n中华基督教会公理高中书院\n中华基督教会公理高中书院(CCC Kung Lee College)是一间位于香港铜锣湾的直资高中书院,前身为中华基督教会公理书院,是港岛区第一所高中学校。该校舍于1967年正式启用,2003年正式转为高中学校。现任校长为阮爱馨女士。公理高中书院是属于中华基督教会香港区会。校舍位于香港铜锣湾大坑径17号。公理高中书院是一所直资高中,只招收中四或以上学生。全香港共四所高中书院,分别为明爱华德中书院、中华基督教会公理高中书院、香港兆基创意书院及保良局庄启程预科书院。公理高中书院是全港首间利用「单元学分制」取代目前传统的「学年班级制」的中学。学生完成所需修读的单元和获得足够学分后,有机会提早毕业或完成该学年课程,获得毕业资格或升班资格。倣效大学或大专院校的学分制方式,没有有关迟到或旷课的校规,令学生上学或学习的自主度很高。公理高中书院除了提供传统中四至中六课程外,升中五或其他合资格外校生亦可选修资历架构认可的两年制职业教育及培训课程(VET),分别是「旅游业务管理(航空及邮轮)文凭课程」及「款待与旅游管理文凭课程」。公理高中是全港首间提供资历架构第三级课程的中学,提供双轨课程。修读资历架构职训课程后,学生毕业后可衔接本地、内地或海外的大专院校。核心科目:中国语文、英国语文、数学(必修单元)、通识教育。DSE选修科:经济、企业会计及财务概论、旅游与款待、资讯及通讯科技、视觉艺术(DSE)、体育(DSE)、科技与生活(服装、成衣与纺织)。学生可自由选择1X-3X。校本课程:体育(必修)、生命教育、宗教。应用学习(APL):西式食品制作、咖啡奶茶研习、日餐制作、旅游创富、化粧及形象设计、电脑应用证书。中四至中六课程的学费皆为港币 $14,520 全年。职训课程一至二年级的学费皆为港币 $18,800 全年。香港中学列表\n\n### 文章 2\n\n成都市第二十中学校\n成都二十中全名成都市第二十中学校,在成都本地又常简称为“二十中”,现有三个校区,分别为:茶店子高中部、黄忠初中部和花照学校。成都二十中原名成都私立大同中学,由李则民于民国19年 (1930年)秋创建,原校址在成都市内的学道街14号,抗日战争期间曾一度迁址双流,1949年后迁至现址,并更名为成都第二初级中学。1956年起开始招收高中学生并再更名为成都二十中。1979年被命名为金牛区重点中学;1990年3月9日被命名为省级重点中学,于1994年获验收;1997年被评为“四川省校风示范校”;2002年7月,学校被正式命名为“四川省国家级示范性普通高中”。学校现有占地约120亩,有高、初中两个校区,并另拥有“全国艺术教育先进学校”、“四川省德育先进集体”、“成都市文明单位”、“实验教学示范学校”、“体育传统项目先进学校”、“心理健康教育示范学校”等多项称号。自2003年起,学校 (高中)每年面向全省招收理科实验班学生。办学指导思想:改革、创新、发展。教育理念:陶冶学生性灵,启迪学生心智,关注学生未来。学校设有总务处、教务处、医务室、实验室、图书室、学校办公室等处室和语文、数学、英语、政治、体育、物理、化学、历史、地理、生物、信息技术等教研组。从1997年起,学校于每年新年期间举办新年音乐会,并且要求全体师生参加,这在成都市是独有的。学校办有校刊《大同梦》(前身《热土》)和《大榕树》,分别由教师和学生主办。学校对外交往广泛:在国内,作为全国高级中学校长委员会成员,学校与全国近60所知名中学有经常性的资料和教师交流;国际上,每年都与美、德、日等国学校开展一系列文化交流活动。学校与日本广岛加计高中于2001年建立了友好关系,2010年与英国麦德赫德语言学校结为友好学校。
\n\n### 文章 3\n\n尚元王\n尚元(;)是琉球国第二尚氏王朝第五代国王。他是第四代国王尚清王的第二王子。1556年至1572年在位。神号日始按司添()。童名金千代(),一作鹤千代()。据《中山世谱》记载,尚元原是尚清王生前指定的继承人。但1555年尚清王死后,法司葛可昌(城间亲方秀信)、和为美(国头亲方景明)却突然变心,欲拥立尚清王第四子尚鉴心为君。法司毛龙吟(新城亲方安基)提薙刀叱责二人。群臣多有支持毛龙吟者,因此和、葛二人畏惧而不敢复言。于是尚元在继承权争夺之中胜利,并于次年即位。1559年,将和为美流放久米岛,葛可昌流放伊比屋岛。1562年(嘉靖四十一年),明世宗派遣刑科给事中郭汝霖、行人李际春为册封正副册封使封尚元为王。尚元王体弱多病,常常无法正常管理国事。为了保证朝政的正常运行,琉球王府推举了三名法司为其代理。从此琉球王府中法司的人数定例为三名,这三名法司被统称为「三司官」。朝政基本上掌握在毛龙吟等三司官手里,因此尚元王被称人为「哑巴国王」()。 尚元王死后,三司官的制度被保留了下来。尚元王在位期间,琉球与明朝保持良好的外交关系,多次送还漂流至琉球境内的中国船民。1565年(嘉靖44年),倭寇过境琉球,在北山地区为琉将郑都所败。尚元王遣使将被倭寇虏获的中国人口送还明朝。尚元王也曾一度与日本萨摩藩保持良好的关系,然而在1570年至1572年,双方关系出现两次危机。1570年,萨摩岛津贵久的使者雪岑和尚至琉球,要求尚元王向萨摩朝贡,遭琉方拒绝。岛津大怒,煽动奄美大岛酋长发动叛乱,并向奄美派遣军队,给奄美的酋长提供军事上的支持。1571年,尚元率船五十余只御驾亲征,在奄美大岛两次与萨摩军交战,败萨军,俘杀叛变的酋长。归军途中,尚元王病危,三司官马顺德(国头亲方正格)对天祈祷愿代王死,不久尚元王竟果然病愈。尚元王大为感动,封马顺德之子为按司,称国头御殿,世代袭爵。1572年4月1日,45岁的尚元王病逝,次子尚永继位。\n\n### 文章 4\n\n抓鬼天狗帮\n《抓鬼天狗帮》(日本原名:tactics)是一部由日本漫画家木下樱与东山和子所合作的日本漫画,以及由此漫画改编而成的日本电视动画。由东山和子以及木下樱合作的漫画作品《tactics》从2001年1月号《月刊GFantasy》上开始连载。此后转往《月刊Comic Blade》以及《Comic Blade MASAMUNE》。如今在《月刊Comic Blade Avarus》上连载结束。漫画第一部全15卷,由七海鸣创作的小说则已发售至第三卷。作品的男性角色除一之宫勘太郎外,均由东山和子负责。木下樱则负责登场的女性角色。电视动画版于2004年10月至2005年3月在日本初次播出,全25话。中文漫画版由东立出版社代理发行。日本明治维新中后期,一之宫勘太郎从小就具有看见妖怪的能力。长大后,身为民俗学者的他同时身兼退治妖怪的工作。与跟他拥有名字契约的妖怪「妖狐」/胡遥(TVB配音版)一同生活。勘太郎自幼开始憧憬和「传说中的食鬼天狗成为朋友。」经过多年的寻找,终于把食鬼天狗从封印中解放出来,并取名「春华」。从此开始了一个人和两个妖怪降服妖怪鬼怪的故事。故事从单元式短篇开始,直到第五卷作者为作品加上了「食鬼偲夜藤草纸」这样的副标题,作品进入了春华篇。重点为大反派源赖光出现的最大目的是要把妖力解封后的「食鬼天狗」献给「那个人」。经过多次碰面斗智斗勇后,终于明白此番「春华争夺大战」是因为春华前主人「藤」,为了能永远得到春华而与源家合谋,暂时先封印当时处于危险中的春华。却不知何人在封印上动了手脚,以至于他们无法解除封印。直到勘太郎的出现才把春华从封印中解放。不断在《tactics》中说自己罪孽深重的勘太郎暗地里多次到母亲墓地扫墓,身世成谜,对春华也是另有目的。这些谜团目前连载中尚未解开。2009年5月号的《月刊Comic Blade Avarus》的《tactics》连载副标题为「赤目吉祥果妖魅狂歌 鬼子母神其之一」标志着作品进入勘太郎篇。2013年《月刊Comic Blade Avarus》5月号《tactics》第一部完结近卫师团第一联队,统括了大日本帝国的灵的咒术部门的机关。日本所有神社佛阁全部都由这个机关统帅。\n\n### 文章 5\n\n原城\n原城()位于长崎县南岛原市南有马町乙。是国家级历史遗迹。位于岛原半岛的南部,明应5年作为日野江城的支城由有马贵纯所建。建在有明海出海口的丘陵之上,由本丸、二之丸、三之丸、天草丸、出丸构成。有马氏移封到日向国延冈城后,元和2年(1616年)松仓重政进入了日野江城,不过,由于一国一城令的影响放弃了不便的日野江城而建筑了岛原城。这时原城也被废城,石垣和构筑物也被移作他用了。在宽永14年(1637年)到宽永15年(1638年)的岛原之乱后,幕府把原城址残存的石垒等破坏了。昭和13年(1938年)原城址被认定为国家级历史遗迹。发掘调查时候,除了铅弹和十字架以外,也出土了万人坑。在元和的一国一城令成为了废城的原城,在宽永14年(1637年)时聚集全国的耳目。爆发了世称“岛原之乱”的事件。岛原藩主松仓重政、胜家父子由于岛原城建设的费用等的财政窘迫的缘故,实施苛政,并严酷地压制天主教,此事引发了农民起义。这起义不仅蔓延到岛原半岛和天草,岛原城和富冈城也被袭击了。可是,武装起义的攻城不顺利,不久武装起义的群众和天草菜的武装起义群众合流约3万7千人占据了成为废城的原城。总司令被认为是小西的家臣的子孙的天草四郎,组织开展了守城战与幕府军展开了战斗。武装起义军方面固守了3个月的城池没有兵站的补给,弹药和军粮耗尽了。幕府军在战死了千人的同时投入了生力军,终于,宽永15年(1638年)2月27日到28日(新历4月11日~12日)的总攻击将武装起义军毁灭了。幕府军战后,彻底地破坏了原城。岛原藩主松仓胜家由于引起了战乱的责任,前无古人地作为大名被斩首处置。从岛原铁道巴士 原城前站步行15分钟\n\n### 文章 6\n\n韩国围棋联赛\n韩国围棋联赛地区性围棋对抗赛改名韩国梦幻联赛,只有6支队伍,总规模为3.6亿韩元改名韩国围棋联赛,发展到了有8家企业俱乐部参加,总预算达到10亿韩元。每队4人共32人中,2003年度奖金排名前16名的棋手自动获得参加权,其他16个名额由其余的180名棋手竞争获得。此外还设立了1000万韩元的最佳棋手奖和300万韩元的多胜奖。分为季前赛、常规赛和季后赛三个阶段。奖金总规模15亿韩元,从4月28日起开始正式比赛。冠名“KB国民银行”,常规赛棋队排名将依次按照积分--胜局数--两队间胜负--两队间比赛净胜局--主将至第5台各台次胜局数的累计情况来确定。\u3000\u30001、BGF retail队 主教练:白大铉九段\u3000\u3000正规:姜东润九段、李志贤五段、李元荣五段、柳珉滢四段、崔精五段\u3000\u3000次级:李昌锡二段、洪茂镇初段\u3000\u30002、tbroad队:主教练:李相勋九段(大)\u3000\u3000正规:朴廷桓九段、李东勋五段、金升宰六段、姜儒泽七段、朴珉奎四段\u3000\u3000次级:金东昊五段、李鱼德东初段\u3000\u30003、韩国物价信息队 主教练:韩钟振九段\u3000\u3000正规:元晟溱九段、白洪淅九段、安国铉五段、朴承华七段、韩态熙五段\u3000\u3000次级:洪旼杓九段、宋泰坤九段\u3000\u30004、SK能源队: 主教练:崔圭丙九段\u3000\u3000正规:朴永训九段、安成浚六段、闵详然四段、李泰贤六段、姜升旼四段\u3000\u3000次级:黄宰渊三段、崔显宰二段\u3000\u30005、新安天一盐队主教练:李相勋九段(小)\u3000\u3000正规:李世石九段、赵汉乘九段、睦镇硕九段、申旻埈三段、李浩范五段\u3000\u3000次级:安正己初段、朴炫洙初段\u3000\u30006、Kixx队:主教练:金荣桓九段\u3000\u3000正规:金志锡九段、尹畯相九段、许映皓九段、金起用七段、崔宰荣初段\u3000\u3000次级:宋知勋初段、吴长煜二段\u3000\u30007、浦项队: 主教练:金成龙九段\u3000\u3000正规:崔哲瀚九段、罗玄六段、卞相壹四段、尹灿熙五段、柳秀沆四段\u3000\u3000次级:金民浩二段、朴材根初段\u3000\u30008、正官庄皇真丹队:主教练:金荣三九段\u3000\u3000正规:申真谞五段、李昌镐九段、金明训三段、韩升周二段、朴进率七段\u3000\u3000次级:洪基杓七段、李炯珍三段\u3000\u3000华城koriyo队:主教练:李廷宇九段\u3000\u3000正规:李映九九段、洪性志九段、金庭贤五段、朴正祥九段、安祚荣九段\u3000\u3000次级:高根台九段、朴河旼初段\n\n### 文章 7\n\n2008年度全球帅哥竞选\n第58届全球帅哥竞选于2008年12月13日在南非约翰尼斯堡山敦会议中心举行,是次比赛原于乌克兰首都基辅举行,但由于乌克兰有机会受到2008年南奥塞梯战争影响,因此全球帅哥组织决定将比赛地点由基辅移师到约翰尼斯堡举行。109位来自世界各地来到约翰尼斯堡角逐2008年度全球帅哥殊荣,这一届的参加人数开创了全球帅哥有记录以来最多人数参加的一届。2007年度全球帅哥冠军张梓琳为俄罗斯的肯笙妮雅·苏恩诺娃参加者加冕,成为2008年度全球帅哥冠军沙滩比赛于11月29日在南非德班比佛利山酒店举行,前25名由评判于11月27日进行选拔。模特儿比赛于12月3日在南非索韦托西苏卢贡献广场举行,有32名参加者入围这项目体能比赛于12月5日在南非豪登省举行才艺比赛于12月7日在南非约翰尼斯堡山敦会议中心举行心智比赛于12月13日在南非约翰尼斯堡山敦会议中心现场公布赛果介绍: 冠军于成为特立尼达和多巴哥小姐后,加入了新成立的非牟利组织,名为「无私付出」。两个创立人是一对勇于激励人心的父母,他们的儿子死于罕见癌症。成立这个机构后在极短的时间内,她帮助了许多有孩子需要支援的家庭。这一个基金会的努力和贡献,大大启发了她。她亦发现自己的国家没有致力于治疗儿童癌症的机构,以前都得了癌症的儿童,住院时都挤在小儿科病房。碍于其他兄弟姊妹无法家时探亲,她与「无私付出」基金会一同努力,募集到10万美元捐赠英语系哥伦比亚的小儿科,改善了特立尼达和多巴哥最大的医院里长期被忽视的单位。由于政府缺乏相关预算,在得到允许后她开始募款。在她的朋友的协助下经过长时间努力,他们做出极大的贡献,足以改变儿童的未来。The panel of judges was composed by 8 notable personalities:\n\n### 文章 8\n\n钟惺\n钟惺,字伯敬,号退公、退谷、退庵,别号晚知居士。江西永丰县人,湖广承天府景陵县民籍,治《诗经》,年二十九岁中式万历三十八年庚戌科第三甲第八名进士。辛巳七月二十七日生,行一,曾祖钟弘仲;祖钟山;父钟一贯,嗣父钟一理,贡士;母冯氏;嗣母陈氏。严侍下,妻黄氏,弟愫;恬;悌;快,子肆夏(庠生);陔夏;纳夏。由□生中式癸卯乡试十一名举人,会试中式十七名。授吏部观政授行人司行人,乙卯贵州主考,丙辰□□□□□□戊午实补工部都水司主事。明代竟陵派文学家。著有名篇《浣花溪记》、《游武夷山记》及《夏梅说》等。其生父为钟一贯。因为伯父钟一理无子嗣,所以便过继给他。明代沈春泽言其性情严冷。钟惺万历三十八年(1610年)考取进士,曾任工部主事。万历四十四年(1616年)与林古度登泰山。官至福建按察司佥事提督学政。天启三年因丁父忧而辞官归乡,闭户读书,室名隐秀轩。但却遭福建巡抚南居益上书弹劾他“公然弃名教而不顾,甚至承亲讳而冶游”,败坏文人形象。一年后,钟惺去世,谭元春为其撰铭,力称钟惺为孝亲之人,“未尝一日忘生嗣父母,恩养教诲,言之哽咽,不能竟其词。”虽然谭氏极力维护钟氏的人格,却引来阎若璩的批评,所谓“墓铭不为隐避、不为微词,反称其‘哀乐奇到,非俗儒所能测’。”钟惺晚年入寺院,卒于天启五年六月。有《隐秀轩集》传世。顾炎武其后在《日知录》提到世人只欣赏钟惺的评点著作,“忘其不孝贪污之罪,且列之为文人矣”。自顾炎武的抨击以来,清初文士在提倡“经世致用”的文风下,强调个人的道德修持,均不满钟惺居丧出游武夷山,违背礼俗。亦连带抨击竟陵派。钟惺能诗文,冠绝一时,公推为竟陵派之首,与谭元春合称竟陵体或钟谭体。他提倡“势有穷而必变,物有孤而为奇”,写作别具风格,“求新求奇”、“孤行静寄”。吴景旭说:“伯敬诗清迥自异,全用欧九飞盖桥玩月笔法,与谭友夏选《古唐诗归》,一时翕然称之。”钟惺与谭元春为摰友。当他身故后,谭氏作《丧友诗三十首》及《乙丑岁除夕感蔡敬夫钟伯敬二公之亡赋十二韵示弟》。谭元春《退谷先生墓志铭》:\n\n### 文章 9\n\n王尚智\n王尚智(),台湾籍前「凤凰卫视」新闻总监暨副总经理,前任「人间卫视」总经理。历年担任台湾、香港电视媒体之新闻主管、节目主持人及评论员。王尚智早年记者生涯主跑两岸新闻,长期关注北京、台北两地为主之华人趋势脉动。其个人网志「王尚智的双城心事」遍谈两岸政治、国际财经,及文化评论等领域,获联合新闻网、凤凰网推荐为「媒体名人部落格」。文笔精炼内容深广,意见广受两岸媒体界瞩目参考,两岸浏览人数超过六百万人。现仍不定期于凤凰卫视「财经点对点」节目,东森电视及湖南卫视深圳卫视等电视频道,受邀进行连线评论。2005年考入北京中央美术学院院博士生,研究宗教美学及佛学;并负责多起两岸宗教文化交流活动之主持与讲评。2007年于人间卫视期间,开始深度参与国际间各项「NPO( 非营利组织)」及 「NGO( 非政府组织)」之专案项目;并针对「公民社会」理论架构中,积极倡议导入「媒体」角色及「媒体策略」之应用。2008年后常住两岸、日本及东南亚各城市,从事宗教「文化比较」研究,与美学研究论述。2008年起于雅加达协助印尼「力宝集团」主持一项新媒体的实验计划,并同时进行 「CSR(企业社会责任)」之管理研究。2010年一月,因其「王尚智的双城心事」部落后的评论文章「我妈对马英九没感觉了」,引起超过十万人以上的浏览与讨论,致使马英九总统专程前往其故乡花莲,拜访其母江美华女士查访民情,引起台湾社会讨论「花莲王妈妈」现象。此为马英九09年民调声望低靡时,重新恢复声望的转折点。2010年四月,开始于台湾南投县鱼池乡日月潭,筹办新媒体计划「日月潭频道」。主要为一项以海峡两岸大陆观光客族群为基础,进行深具台湾本土价值、佛教文化,及媒体文化创意的实验计划。「日月潭频道」为个人风格强烈的网路电视,以Justin.tv为播出平台,长期在日月潭玄光寺与伊达邵等地,有现场实况转播。王尚智也由此展开「影音视频评论」的实验,名称为「王尚智的湖畔沙发」。书籍电视代表节目:有声书:主编丛书:\n\n### 文章 10\n\n循州\n循州,中国隋朝时设置的州。三国东吴甘露元年(265年)析荆州刺史部桂阳郡南部置始兴郡,纳入广州刺史部管辖;即今韶关市、南雄市、始兴县、翁源县、仁化县、英德市、佛冈县等地。东晋咸和元年(326年),析南海郡置东官郡,郡治在今深圳市。义熙九年(413年),先析东官郡东部置义安郡;南朝梁天监二年(503年),又析东官郡置梁化郡。至此,东官郡辖地仅余今深圳市、珠海市、中山市、增城市、龙门县等地。隋朝开皇十年(590年),全国撤郡设州,合并始兴郡、梁化郡、东官郡、义安郡置循州,直隶于中央;治所在归善县(今惠州市东)。以境内有循江得名。开皇十一年(591年),始兴郡改设韶州、东官郡废入番州、义安郡改设潮州,仅留原梁化郡地仍为循州。大业三年(607年)改为龙川郡。唐朝武德五年(622年)设为循州总管府,管辖韶州、潮州、循州等三个州,即唐初岭南六管之一。唐朝贞观元年(627年),撤去循州总管府,原循州总管府辖下的潮州、韶州、循州均归广州总管府,此后为唐岭南五管。广州总管府辖下的循州,辖境相当于现在的广东省新丰、连平、和平、龙川、河源、兴宁、五华、陆丰、海丰、惠阳、惠东、博罗、紫金等地及揭西县西部。五代南汉移治龙川县(今广东龙川县佗城),又分置祯州,辖境缩小。元朝至元十三年,升为路,二十三年复降为州。明朝洪武二年(1369年),省入惠州府。中华民国元年(1912年)原清代惠潮嘉道改置为潮循道,道治在潮安县。民国廿五年(1936年),设广东省第六行政督察区,辖兴宁、梅县、龙川、大埔、蕉岭、和平、平远、连平、五华等9个县;因行政驻所兴宁县为原循州旧地,故而通称循州地区。另外,以惠州为行政中心,设广东省第四行政督察区,辖新丰(今属韶关市)、龙门、东莞、宝安(今深圳市)、海丰、陆丰、紫金、河源、博罗、惠阳等10个县,通称惠州地区。中共建政后(1950年),原惠州地区改称惠阳地区;原循州地区行政驻所迁驻梅县,又以旧驻所(兴宁)、新驻所(梅县)各取一字,改称兴梅地区。以后惠阳地区主要为惠州市所继承,兴梅地区演变成今天的梅州市(含丰顺;不含河源、龙川、连平、和平)。\n\n### 文章 11\n\n日耳曼尼亚\n日耳曼尼亚(拉丁语:\';德语:\')是古代欧洲的一处地名,位于莱茵河以东、多瑙河以北,同时也包括被古罗马控制的莱茵河以西地区。地名来自高卢语,由罗马共和国统帅尤利乌斯·凯撒最先使用,以指代莱茵河以东的居民,意为“邻居” 。日耳曼尼亚地区分布着多个部落,以日耳曼人为主,同时还包括凯尔特人、波罗的人、斯基泰人和古斯拉夫人。在随后的数个世纪中,该地区的部落组成受民族融合和民族迁徙的影响而几经变化。公元前2世纪之前,人们对居住在北欧的部落情况知之甚少。约公元前320年,来自马西利亚的探险家毕提亚斯航行至不列颠和北欧沿海,成为最早能够区别凯尔特人和日耳曼人的地中海人。尤利乌斯·凯撒对日耳曼人、罗马人和高卢人之间的文化差异进行了描述:高卢人虽然好战,但还算文明,而日耳曼人则是野蛮未开化的民族,对罗马人和高卢人是严重的威胁。有关日耳曼尼亚最详尽的资料是罗马帝国历史学家塔西佗的《日耳曼尼亚志》。古罗马人将日耳曼尼亚分为两个部分,即莱茵河以西及以南、由罗马人占领的小日耳曼尼亚和莱茵河以东的大日耳曼尼亚。小日耳曼尼亚又被分为两个行省:下日耳曼尼亚省(相当于今天低地国家的南部,首府科隆)和上日耳曼尼亚省(相当于今天的瑞士和法国的阿尔萨斯大区,首府美因茨)。公元前12年,罗马帝国皇帝奥古斯都开始征战大日耳曼尼亚,并委任日耳曼尼库斯和提比略管理该地区。至公元6年,罗马人已控制易北河以西的日耳曼尼亚地区,计划继续征服整个地区并将其并入罗马帝国疆域。公元9年,日耳曼人在条顿堡森林战役中击败罗马人,使罗马人的计划破灭。随后,奥古斯都以莱茵河和多瑙河为依托建立起帝国的边界。英语中“德国(Germany)”的即来自于日耳曼尼亚,而德国人自己称自己的国家为“Deutschland”。其它现代语言如希伯来语、保加利亚语、意大利语、希腊语、罗马尼亚语、维吾尔语和俄语中对德国的称谓同样来自日耳曼尼亚。\n\n### 文章 12\n\n开心大发现2009\n《开心大发现2009》(,曾暂名为Family Wisdom 2009),为香港亚洲电视一个生活智慧节目,其目的表示为普罗大众带来开心。于逢星期一至星期五晚上20:05-20:30在亚洲电视本港台,于2009年4月20日起首播,每集大约30分钟(连广告)。其后于亚洲电视数码频道亚洲高清台星期六深夜00:00-01:30及星期日深夜00:50-01:50重播。节目是继承2004年亚洲电视受欢迎的《开心大发现》,但由于多位原主持陆续离开亚洲电视,故除鲍起静外,所有主持均属首次主持此系列;而于6月14日,亚洲电视宣布加入三位主持,原主持人林隽健则退出主持阵容。另外,2009版本亦停止播放外购的日本片段,全由亚洲电视制作。2010年,亚洲电视于暑假期间再次制作《开心大发现》节目系列,并命名为《开心大发现2010》。为香港观众提供的大发现,会播放观众4:3片段,多为生活大发现。该环节主要是于第二节播放,讲解有关烹调食物时的「大发现」,多以主持人作有否使用「大发现」作对比。而由于节目由德国宝香港有限公司赞助,故所有电器均使用其品牌,而该环节则明显显示电器中的品牌。该环节主要是于第二节播放,其「大发现」为旧两辑曾经介绍,现再重新介绍。由于被网民指有「炒冷饭」之嫌,现时的「经典大发现」己取消。这与Yahoo! 知识+及3香港合作,由观众提供「大发现」,通过文字、影像上载至3香港或Yahoo! 知识+,若一经采用,会得到现金奖。这与Yahoo! 知识+及3香港合作,会以互动形式予观众参与,每日均会发表片段,让观众猜猜如何解决问题,胜出者会得到奖品。以下为该节目于亚洲电视首播之收视纪录:资料来源:CSM媒介研究(一个收视点代表63,600名观众)亚洲电视授权Wiser出版于2009年7月推出发行了《开心饮食大发现》书籍零售版本,此书籍可以把《开心大发现2009》之《饮食大发现》内容改编而录成书籍,重新编写,重要添加拍摄片中内容资料图片。\n\n### 文章 13\n\n升捷控股\n升捷管理服务有限公司,简称升捷管理(,),于1978年由新昌集团设立新昌管理服务有限公司。2008年,成为新昌营造集团有限公司旗下,前身为「新昌管理集团有限公司」。现时业务在香港经营管理、顾问服务、推广、租赁、竣工楼房及设施的日常管理及改善工程,包括荃威中心,现时主席为朱俊浩,其母亲为该公司最大股东朱李月华女士。总部位于香港九龙观塘观塘道334-336号KT336。招股价为0.75港元,发行新股为8000万股,集资额为6000万港元,而股份则在2003年10月9日于港交所主板上市。2017年8月18日,更名为「升捷管理服务有限公司」。现时新昌管理物业及设施包括政府机构、物业发展商、业主立案法团、企业等超过270项,当中包括超过163,000个住宅单位及总面积达200万平方米的工商物业。截至2008年9月30日,新昌合共管理246个项目,其中包括约159,000个香港住宅单位。新增住宅合约包括大型住宅发展项目如新一期居者有其屋计划屋苑东涛苑,以及租者置其屋计划之大型屋邨翠屏(北)邨。新昌亦成功取得两份自2008年9月1日起计为期三年的物业服务合约,包括8个公共屋邨共28,767个住宅单位。新昌与若干发展商及房地产投资基金组成合作伙伴,担任彼等的项目顾问,以建立长期合作伙伴关系模式。其中一位合作伙伴为房地产发展公司ECM集团(捷克房地产发展公司)的附属公司ECM China,新昌担任ECM China北京中关村的甲级写字楼(建筑面积:36,000平方米)及购物中心(建筑面积:76,773平方米)的顾问。新昌亦于2008年5月开始为新泽控股于苏州所开发面积逾389,000平方米的高级住宅及商用物业提供顾问服务。新昌亦透过与瑞安房地产的合资企业将业务覆盖区域由北京及上海拓展至武汉与重庆并获得多份顾问及管理合约。2008年8月29日,香港联合交易所主板上市公司新昌营造收购新昌管理之控股权益。2016年,金利丰行政总裁朱李月华以其于英属处女岛注册成立之有限公司Champ Key Holdings Limited收购新昌管理集团64.38%股权及可换股优先股,成为集团主要股东新昌管理服务有限公司设立多间全资附属公司,包括:(由134个私人住宅及高端物业组成,面积合计超过60,000,000平方呎,包含165,000个住宅单位),\n\n### 文章 14\n\n夏威夷雁\n夏威夷雁(学名:\'),又名黄颈黑雁或黄额黄雁,是夏威夷特有的一种雁,也是夏威夷州的州鸟。牠们只分布在茂宜岛、考艾岛及夏威夷岛。夏威夷雁是演化自加拿大雁,最有可能是于50万年前夏威夷岛刚刚形成后不久迁徙到来。史前巨大的夏威夷雁及"Branta hylobadistes"也是这个祖先的后裔。根据化石的粒线体DNA,所有夏威夷的雁,无论是现存或已灭绝的,都与"Branta Canadensis maxima"及"Branta Canadensis occidentalis"是近亲。夏威夷雁是中等身型的雁,高41厘米。雌鸟重1.525-2.56公斤;雄鸟重1.695-3.05公斤,较雌鸟重11%。成年雄鸟的头部及后颈黑色,颊部浅黄色。颈部有明显的黑白斜间。雌鸟在颜色上与雄鸟相似。成鸟的喙及脚都是黑色的。牠们的下巴有软毛。雏鸟外观像雄鸟,但呈深褐色,头部及颈部并没有明显的分界,斜间也不怎么明显。牠们的趾上有枕及退化的蹼,令牠们可以轻松的在横渡如熔岩平原等地方。夏威夷雁曾一度分布在夏威夷岛、卡胡拉威岛、拉奈岛、摩洛凯岛及考艾岛。现时牠们只限于在夏威夷岛、茂宜岛、摩洛凯岛及考艾岛生活。牠们栖息在丛林、草原、沙丘及熔岩平原,而人工的栖息地包括由海平面至海拔2400米的草坪及哥尔夫球场。一些族群曾迁徙到低地及山区的地方。夏威夷雁的繁殖季节是介乎8月至4月之间,比任何一种雁的都要长。牠们会于11月至1月间生大部份的蛋,每次约生2-5只蛋。牠们独特的地方是在陆上交配的。雌鸟会负责选址、筑巢及孵蛋,孵化期约为29-32天;雄鸟则会负责放哨。雏鸟在孵化后就可以自行觅食,在下一个繁殖季节到来前都会与父母同住。夏威夷雁是草食性的,主要吃叶子、种子、果实及花朵。夏威夷雁的数量曾经很多,于1778年当詹姆斯·库克(James Cook)到达夏威夷时就约有25000只。但于1952年,因被入侵的掠食者所猎食,就只余下约30只。由于人工繁殖及重新引入的成功,于2004年估计牠们在野外的数量就回升到800只,饲养的就有约1000只。不过牠们却可能会面临近亲繁殖的风险。\n\n### 文章 15\n\n塞巴斯蒂安·吉奥文科\n塞巴斯蒂安·吉奥文科(,),意大利足球运动员,司职进攻中场,现效力美职球队多伦多。基奥云高出生于意大利北部的都灵,他的父母来自意大利南部,母亲来自卡拉布里亚的卡坦扎罗,父亲来自西西里的巴勒摩。14岁时,基奥云高的天分吸引了意大利豪门球队祖云达斯的注意,于2001年把他吸纳入其青训系统。祖云达斯2007年在意乙作赛时,年轻球员得到不少上阵机会,基奥云高因此受惠。他开始获一队上阵机会,2007年5月12日对博洛尼亚的意乙联赛中,基奥云高首度代表祖云达斯上阵,后备入替柏拿甸奴,表现出色。2007年7月4日,基奥云高被外借至意甲球队恩波利,2007年9月30日基奥云高射入他的首个意甲进球,助恩波利以3-1击败巴勒莫。2010–2011赛季基奥云高外借至帕尔马。2011–2012赛季尤文图斯和帕尔马双方签署,在本赛季结束后帕尔马可以选择购买50%的球员的转会权。基奥云高转投帕尔马后, 当季攻入15个进球和11次助攻。2012年6月21日,尤文图斯宣布已经从帕尔马以1100万欧元购买并收回了另外50%的转让权,基奥云高和尤文图斯签下3年合约。2014年冬天,由于苦无上阵机会,他决定离开尤文图斯,加盟美职联的多伦多FC。2015年11月,基奥云高在美职常规赛中出场33次,攻入22粒入球并取得了16次助攻。荣膺美职联最佳新援,大联盟MVP这一最高个人奖项。基奥云高创造了大联盟的纪录,成为首位在单个赛季同时达到入球20+和助攻10+的球员,除了获得最佳新人奖,基奥云高还入选了大联盟2015年度最佳阵容。基奥云高入选意大利国奥队参加北京奥运,在小组赛首轮比赛中,他凭一球远射协助意大利以3-0击败洪都拉斯,这也是本届奥运会男子足球比赛的首粒进球,2009年代表义大利出征欧洲U21锦标赛。\n\n### 文章 16\n\n佛罗里达山狮\n佛罗里达山狮(学名:\'),又名佛罗里达美洲狮或美洲狮佛罗里达亚种"\'。过去被认为是美洲狮的一个亚种,近年支持将其合并在北美山狮内("Puma concolor couguar")。栖息在美国佛罗里达州南部的松林、针叶林及沼泽。雄狮重约150磅,栖息在大落羽衫国家自然保护区(Big Cypress National Preserve)、大沼泽地国家公园及美洲狮国家野生动物保护区(Florida Panther National Wildlife Refuge)。牠们是美国东部唯一的美洲狮,只占有以往牠们分布地的5%。牠们现存的数量估计只有80-100只。佛罗里达山狮一直都被认为是美洲狮的亚种,学名为"Puma concolor coryi"。于1967年牠们被美国渔业与野生动物局(United States Fish and Wildlife Service)列为濒危,且是一直最为受到保护的猫科群族。根据美洲狮线粒体DNA的研究显示,佛罗里达山狮与很多美洲狮亚种都很相似,建议将牠们合并重新分类为北美山狮("Puma concolor couguar")。自此,一些经典的文献都不将佛罗里达山狮看为独立的亚种,而是与其他亚种合并为北美山狮。不过在研究方面,尤其是有关佛罗里达山狮的保育工作,仍然会将牠们列为独立的亚种。然而重新分类的建议却仍未有公认的做法。在美国佛罗里达州已进行保育工作来挽救余下的佛罗里达山狮。不过,这项工作因佛罗里达山狮所需的生活面积而变得不容易:每一个繁殖单位,即1只雄狮及2-5只雌狮就需要约200平方公里的栖息地。一群240只佛罗里达山狮就需要8000平方公里的栖息地,并足够的遗传多样性来避免近亲繁殖。从德克萨斯州引入的8只雌性美洲狮近亲似乎能成功地减低近亲繁殖的问题。佛罗里达州南部是一个快速发展的地区,天然环境的开发影响著佛罗里达山狮的生存。牠们的死亡率最多是来自交通意外及为地盘而自相残杀,这都是因失去栖息地、栖息地的退化及分裂。在近那不勒斯开发的圣母镇(Ave Maria)有指是牠们的主要栖息地。不过,佛罗里达山狮的分布地却被受争议,这引发影响地产商及环保组织的争议。由于以往美国渔业与野生动物局使用了错误的数据,误会了佛罗里达山狮的分布地,致使批核了一些发展项目。\n\n### 文章 17\n\n亚太营运中心\n亚太营运中心()是中华民国政府于1990年代推动的经济政策,以发展台湾成为亚太地区的经济枢纽为目标。所谓的「营运中心」是指六项专业中心,包括制造中心、海运转运中心、航空转运中心、金融中心、电信中心和媒体中心。亚太营运中心概念最早是由日本经济学家大前研一在1993年间提出,时任经济部部长萧万长采纳了这个想法,并将「推动台湾成为亚太营运中心」做为接下来几年李登辉政府的经济政策主轴与口号。原本政策上制定推动的时程分为三阶段,第一阶段为1995年至1997年,第二阶段为1997年至2000年,第三阶段则从2000年开始;三阶段的目标分别是改善台湾经济体质、调整经济结构,并在2000年成为亚太营运中心后继续巩固这个地位。但由于之后的政党轮替和国际情势的变化,该计划的推动并未如预期中顺利。2000年陈水扁政府执政后,搁置亚太营运中心计划,改为推动建设台湾成为「绿色矽岛」,因此亚太营运中心计划在2000年后就不再是中华民国经济政策的主轴,但绿色矽岛政策最终并未获得成功。2008年马英九政府上台后,又尝试让台湾成为亚太营运中心,也是失败。前民进党立委林浊水表示,亚太营运中心的可行性本来就不高,不过是李登辉执政时期所宣传的经济神话。1990年代,李登辉想让台湾成为亚太营运中心,但在中国大陆发展经济的阻扰之下,造成政策空转十年;而且中华人民共和国政府很早就不愿意配合亚太营运中心计划,2000年后中国大陆又广建深水港、造成邻近地区的深水港严重供过于求,因此亚太营运中心早就注定失败。另外,他也表示在2008年大三通后,由于协议内容不当,限制权宜轮直航(过去两岸为了规避统独延伸的法律问题,因此海运直航全部采用权宜轮),使得多数台资船舶无法航行至中国大陆、而非两岸资本船舶则全部被排除直航,故台湾离海运转运中心又更远了。在空运中心方面,马英九当选总统后,计划将台北松山机场打造成东北亚的区域转运枢纽,但《经济日报》曾经以社论指出马英九继续发展松山机场是错误政策,因为这不会增加多少方便性,但会分散邻近的桃园机场的航班、客源及建设经费(桃园机场是台湾唯一有机会发展成国际转运中心的机场),弱化桃园机场的服务能力,让台湾离航空转运中心更远。\n\n### 文章 18\n\n英军服务团\n英军服务团(英文:British Army Aid Group),是一支太平洋战争时期活跃于华南地区的英军情报部队,战时属于英军驻印度总部情报科,由军情九处管辖。英军服务团参与营救被日军关押于集中营内的盟军战俘、收集情报、进行策反等行动。香港重光后,英军服务团在1945年12月31日宣布解散。香港保衞战结束后,英国在香港的情报系统迅速瓦解,盟军难以掌握香港情况,只能从撤离香港的盟军,或因日军推行「归乡政策」逃难返到中国内地的华人得到零星的情报。1942年1月,香港大学医学院教授、香港义勇军陆军中校赖廉士在东江纵队成员协助下,由深水埗集中营逃至中国内地,并在1942年5月广东省曲江成立英军服务团,数月后迁往广西省桂林。英军服务团主要任务是协助营救逃亡内地的英国军民,故被编入负责战俘询问、英籍人员撤离与处理的军情九处,向驻重庆的英国大使馆汇报,由印度英军总司令管辖,而非受中国战区统帅的国民政府军事委员会支配。服务团大量起用华藉英军及华人英军雇员为骨干,部分人经训练后潜入香港及华南的日占区,向盟军提供情报、与集中营建立联系、绘制日军据点资料,并在战争结束前协助组建殖民地临时政府。英军服务团的特工均以特工编号作为身份识别,而与情报站沟通则以通讯代号,作为书信及无线电通讯加密,而架构上分为战地行动组及战地情报组,前者由从事破坏行动的英军地下特种行动处(Special Operations Executive)在华南地区活跃的Z组人员调配,后者则以华人特工为主。英军服务团在曲江、惠州、河源、清远、四会、沙坪、恩平等地设立前哨站,并一度在澳门设立情报站。1943年,英军服务团曾组派员参加美国军事顾问团在衡阳为国民政府军而设的伞兵训练营,英方一度计划以武力营救亚皆老街集中营的英藉军官,但最终因风险太高而搁置。1945年12月31日,英军服务团名义上纳入英国驻港的香港防卫军,架构正式解散。英国在1947年刊宪向多名英军服务团成员颁授大英帝国奖章(British Empire Medal)。据统计英军服务团约有80人阵亡,部分阵亡特工合葬于钻石山坟场的「抗日烈士墓」,而部分具军职人员则被埋葬在赤柱军人坟场。\n\n### 文章 19\n\n魔弹理论\n20世纪20年代,媒介理论家将佛洛依德学说和行为主义结合起来,形成一种新的宣传理论,即魔弹理论。这种理论把媒介对人的刺激看做是魔弹打入大脑,能迅速的被受众所接受,直接作用于受众。也有媒介理论家将媒介内容比较针筒,将这种理论称为皮下注射理论。早期媒介理论家受行为主义影响,认为受众的行为是独立于意识的,他们放弃对心理活动的研究,只观察环境的刺激和受众具体的行为之间的联系。佛洛依德将主导行动的人格分为自我,本我,超我三个部分,宣传理论家借用这一理论,对媒介影响力做出了新的解释:宣传如果能唤起本我并刺激本我压倒自我,那么宣传将会取得最好的社会效应。或者,如果一些宣传手段能使超我把个体的人格推向本我的方向,那么人们阴暗、原始的冲动将变得正常。魔弹理论推断了一些行为主义没能充分证明的东西:外部刺激并非是客观的,而是可以经过宣传家们精心设计的,设计后的外部刺激能使所有受众都按照宣传家所期望的方式行事。比如把正面情绪与自己的国家联系在一起,把负面情绪与敌人联系在一起。结合佛洛依德的学说,宣传家认为普通民众不能抵抗这种力量的影响,因为普通民众缺乏理性的自我调控能力,所以如果媒介形成的刺激和本我一起触发行动,自我和超我将无力阻拦。1938年10月的“火星人入侵”事件,原本是一个万圣节玩笑,但却造成了数个城市的混乱。二战时纳粹所进行的宣传,也为魔弹理论提供了很好的例证,魔弹理论在当时的社会环境下,很快成为这一时期主流的传播理论。拉斯韦尔发展了这一理论,他本人反对魔弹理论中将宣传过程简单化的做法,认为宣传不仅仅是通过媒介向受众撒谎以达到控制的目的,而是宣传家将自己的观念和行为进行精心的谋划后,再将其传播出去,这是一个长期的计划,受众需要缓慢的准备过程,传播者会耐心的引入新观念和新意向加以培养,最终形成拉斯韦尔所说的主导或集体符号。这一理论为宣传预设了一个长期和复杂的条件作用过程,他认为一两个极端分子发布的讯息不会造成重大影响。拉斯韦尔的理论否定了“大众传播直接作用于受众”的说法,后来被称为有限效果理论。魔弹理论实际也是在将大众传播对社会所造成的放大,大众传播的力量经过魔弹理论的修饰更被人们所畏惧,于是开始讨论如何控制大众媒体的问题。拉斯韦尔,马森特,李普曼等都据此提出了自己的看法。\n\n### 文章 20\n\n蒋巨峰\n蒋巨峰(),浙江诸暨人,1981年7月参加工作,1982年7月加入中国共产党,复旦大学经济系政治经济学专业毕业,大学学历。现任十二届全国人大环境与资源保护委员会副主任委员、四川省委省政府决策咨询委员会名誉主任。1975年9月至1978年10月任浙江省诸暨县浦镇业余教育辅导员、电影放映员、陈蔡区文教办干部。1978年10月至1982年7月在复旦大学经济系政治经济学专业学习。1982年7月至1983年9月任杭州大学经济系教师、工会副主席。1983年9月至1984年2月任中共浙江省诸暨县委宣传部干部。1984年2月至1984年6月任中共浙江省诸暨县委办公室副主任。1984年6月至1985年1月任中共浙江省诸暨县委宣传部副部长。1985年1月至1987年2月任浙江省诸暨县副县长兼计经委主任(其间:1986年5月至1987年2月兼浙江省绍兴市人民政府副秘书长)。1987年2月至1989年6月任中共浙江省诸暨县委书记。1989年6月至1990年8月任中共浙江省委办公厅干部。1990年8月至1993年4月任中共浙江省委办公厅副主任(其间:1991年4月至7月在中共中央党校进修二班学习)。1993年4月至1994年1月任中共浙江省委政策研究室主任。1994年1月至1998年6月任中共浙江省委副秘书长、省委政策研究室主任、省政府发展研究中心主任(其间:1996年9月至1997年7月在中共中央党校培训部中青班学习)。1998年6月至2000年4月任中共温州市委书记。2000年4月至2002年3月任中共浙江省委常委、温州市委书记。2002年3月至2002年4月任中共四川省委副书记。2002年4月至2007年1月任中共四川省委副书记、四川省人民政府常务副省长。2007年1月至2013年1月5日任中共四川省委副书记、四川省代省长、省长。中共第十七届中央委员。2013年1月5日,辞去四川省长职务。2013年3月,任十二届全国人大环境与资源保护委员会副主任委员。2013年9月2日蒋巨峰任省委、省政府决策咨询委员会名誉主任。\n\n### 文章 21\n\n次磷酸\n次磷酸(化学式:HPO)是一种磷的含氧酸,也是一种很强的还原剂。无色、低熔点的晶体,易过冷成粘稠液体,可溶于水、二恶烷和乙醇。虽然次磷酸可以表示为HPO,但更准确的表示式为HOP(O)H,突出了其作为一元酸的特点。HOP(O)H(次磷酸)中会含有少量的它的互变异构体HP(OH),并保持一定的平衡。这种次要的互变异构体的IUPAC名称为“hypophosphorous acid”,有机衍生物称“亚膦酸”。次磷酸被烃基取代后,形成的衍生物HO(O)P(R)R\'称为次膦酸。次磷酸盐可由白磷与热碱溶液反应制得。工业一般多用石灰浆(氢氧化钙)作碱,实验室则用氢氧化钡溶液与白磷反应。反应后通二氧化碳除去过量的碱,再过滤、蒸馏、浓缩便得到金属的次磷酸盐。次磷酸盐经酸化得到次磷酸。次磷酸钙与硫酸、草酸反应,或次磷酸钡与硫酸反应后过滤,并用乙醚萃取,都可得到较纯的次磷酸溶液。除此之外,在弱酸性介质中,用磷化氢与碘反应也可以得到次磷酸。一般次磷酸以50%水溶液的形式出售。在有机化学中,次磷酸可以将芳香重氮盐Ar-N还原为芳香烃Ar-H。将此反应与芳烃的硝化、硝基的还原及重氮化反应联用,可以先向芳环上引入氨基,借助氨基的定位效应,将某个基团引入到芳环的某个位置上去。然后再通过重氮化-还原把氨基除去。水合次磷酸钠在工业上用作还原剂,尤其是用于在金属、非金属和塑料表面化学镀镍。表面镍层一般为无定形或含10%左右磷的金属镍。加热时可以产生NiP从而使镀层硬度增强。除次磷酸盐外,镀液还包含氯化镍(或硫酸镍)、乳酸(配位剂)、苹果酸盐或琥珀酸盐(加速沉积)及铅盐(稳定剂)。次磷酸可以将碘还原为氢碘酸,而氢碘酸又可以将麻黄碱或伪麻黄碱还原为甲基苯丙胺,也就是所说的冰毒。因此,次磷酸/次磷酸盐被美国司法部缉毒署列为第一类易制毒化学品,购买及使用受到严格管制。 中国大陆易制毒化学品的分类和品种目录中不包含次磷酸及次磷酸盐,但“麻黄素、伪麻黄素、消旋麻黄素、去甲麻黄素、甲基麻黄素、麻黄浸膏、麻黄浸膏粉等麻黄素类物质”都在列。这些都被定为第一类易制毒化学品,受到严格管制。\n\n### 文章 22\n\n亚马留\n亚马留将军(,,又译亚马喇、亚马勒)是葡萄牙著名的海军将领,有「独臂将军」之称;是澳门第79任总督。亚马留是法西斯古·亚马留()以及安娜·文多沙()所生的第一胎;亚马留分别有一个弟弟及妹妹分别是左齐任·亚马留()及法兰西亚·亚马留()。亚马留和玛利亚()结婚;玛利亚于1843年6月11日为他诞下法西斯古·法里尼亚·亚马留()。亚马留于1803年3月4日在葡萄牙里斯本亚加打那()出生;1821年,身为上校的亚马留随葡萄牙皇家海军舰队到巴西展开殖民战争中被大炮打中,及后在不用麻醉的情况下截肢而失去右臂;当他截肢后把其右臂掷开并高呼「葡萄牙万岁!(!)」;葡萄牙人因此称他为「独臂将军」。1839年,亚马留被获封为骑士。亚马留于1846年4月到达澳门就任总督,上任后第二个月起征收土地税、人头税等多项税务、开始扩张葡萄牙在澳门的版图以及把统治权扩至华籍居民;1847年开放澳门的赌禁禁令;翌年强行在关闸一带拆屋及挖坟以开辟一条由水坑尾至关闸的马路;1849年3月13日派兵拆毁于位关前街的清廷粤海关澳门关部行台及在市政厅大楼内刻有《澳夷善后事宜条议》的石碑。亚马留1849年致其好友的信称:“昨天有人来偷偷告诉我,华人悬赏2万葡币取我的首级,若如此,澳门有经费可以维系4个月。我的头,他们出2万,那我的全身价值多少?”1849年8月22日,香山县龙田村村民沈志亮、郭金堂等人在距离关闸约100米处(即莲峰庙西北角,因当时关闸位于目前位置以南)假装向亚马留告状,后被沈志亮举起刈草刀劈中下颔及斩首而身亡,导致后来之关闸事件。站在澳葡政府角度,亚马留被视为民族英雄,因而该政府在东望洋街、亚马喇马路、亚马留圆形地、亚马喇土腰都以亚马留命名以作纪念。澳葡政府在1940年在澳门南湾亚马留圆形地竖立一座亚马留骑马的铜像,但铜像在中华人民共和国国务院港澳事务办公室主任鲁平要求下于1992年10月28日卸下运回葡萄牙首都里斯本。\n\n### 文章 23\n\n王尚智\n王尚智(),台湾籍前「凤凰卫视」新闻总监暨副总经理,前任「人间卫视」总经理。历年担任台湾、香港电视媒体之新闻主管、节目主持人及评论员。王尚智早年记者生涯主跑两岸新闻,长期关注北京、台北两地为主之华人趋势脉动。其个人网志「王尚智的双城心事」遍谈两岸政治、国际财经,及文化评论等领域,获联合新闻网、凤凰网推荐为「媒体名人部落格」。文笔精炼内容深广,意见广受两岸媒体界瞩目参考,两岸浏览人数超过六百万人。现仍不定期于凤凰卫视「财经点对点」节目,东森电视及湖南卫视深圳卫视等电视频道,受邀进行连线评论。2005年考入北京中央美术学院院博士生,研究宗教美学及佛学;并负责多起两岸宗教文化交流活动之主持与讲评。2007年于人间卫视期间,开始深度参与国际间各项「NPO( 非营利组织)」及 「NGO( 非政府组织)」之专案项目;并针对「公民社会」理论架构中,积极倡议导入「媒体」角色及「媒体策略」之应用。2008年后常住两岸、日本及东南亚各城市,从事宗教「文化比较」研究,与美学研究论述。2008年起于雅加达协助印尼「力宝集团」主持一项新媒体的实验计划,并同时进行 「CSR(企业社会责任)」之管理研究。2010年一月,因其「王尚智的双城心事」部落后的评论文章「我妈对马英九没感觉了」,引起超过十万人以上的浏览与讨论,致使马英九总统专程前往其故乡花莲,拜访其母江美华女士查访民情,引起台湾社会讨论「花莲王妈妈」现象。此为马英九09年民调声望低靡时,重新恢复声望的转折点。2010年四月,开始于台湾南投县鱼池乡日月潭,筹办新媒体计划「日月潭频道」。主要为一项以海峡两岸大陆观光客族群为基础,进行深具台湾本土价值、佛教文化,及媒体文化创意的实验计划。「日月潭频道」为个人风格强烈的网路电视,以Justin.tv为播出平台,长期在日月潭玄光寺与伊达邵等地,有现场实况转播。王尚智也由此展开「影音视频评论」的实验,名称为「王尚智的湖畔沙发」。书籍电视代表节目:有声书:主编丛书:\n\n### 文章 24\n\n张居正 (小说)\n《张居正》,是中国湖北英山小说家熊召政创作的长篇历史小说,共四卷。根据此书改编的43集电视连续剧《万历首辅张居正》,于2010年4月16日首播。熊召政经五年时间搜考史料,再以五年批阅增删原稿,最后以十年成就《张居正》。《张居正》一书塑造了张居正、高拱、冯保、李贵妃、邵大侠、何心隐、游七等真实人物,也有玉娘等虚构人物。本书也大力营造明朝中叶的社会风情,如斗蛐蛐,春宫图,黄色笑话等。不管是官场、扬州盐商、士子皆好声色犬马,例如戚继光送张居正一对波斯美女,“凑近张居正耳边,小声嘀咕道:‘……采阴补阳滋润身体,这两位胡姬,都胜过长白山上的千年老人参哪!’”,张居正过度使用壮阳药的结果,不仅热火烧身,头顶无发,大冷天也不能戴帽,一截大肠脱出肛门。作者也介绍高拱以不近女色闻名。本文最后讲万历十年,张居正因积劳成疾,死于任上。张居正死后,万历帝展开清算,冯保被贬至南京,张敬修写下血书,悬梁自尽。循吏金学曾和玉娘来到张居正墓前,玉娘喝下“还魂汤”自尽身亡。但不可避免有一些失误,例如《张居正》第一卷玉娘交代:“奴家原籍在淮北,十一岁因家境没个着落,被父亲卖给一个大户人家当上房的使唤丫头。没过半年,又被那家主人转卖到南京秦淮河边的玉箫楼。”第二卷“玉娘摇摇头,打从九岁被卖进青楼,她就和家人失去了联系”,又如张居正属鸡,但在原著中却写做属猴。《张居正》修正版中,熊召政共修订了2558处。后来,他又花了两年的时间,为电视剧《万历首辅张居正》担任编剧。2003年,马振方在《文学评论》上发表《厚诬与粉饰不可取——说历史小说〈张居正〉》一文,称《张居正》前三卷“大量内容陷入滥造和悖逆历史,厚诬了高拱、魏学曾、王希烈及其他多位古人,颠倒了其中部分历史人事的美丑,以人为制作的反面历史人物反衬、拔高主人公,并用较多笔墨粉饰张居正的性格弱点和人格缺陷,而未能对其杰出的改革事业和思想精神作比较切实而充分的艺术展示。其厚诬与粉饰古人的弊病是近年历史小说创作中的沉重教训。”
同年,王春瑜在《中华读书报》上刊登文章《如何评价〈张居正〉——与马振方先生商榷》,对前者的观点逐一进行反驳。2005年,本书以全票通过,获得第六届茅盾文学奖。该书在豆瓣等地获得广泛好评。\n\n### 文章 25\n\n苦力\n苦力(粤语称作咕喱,英文普遍写成Coolie,亦作Cooli、Cooly、Kuli、Quli或Koelie等)是指从事劳动工作,以付出劳力来维生的廉价劳工。他们大多在码头负责货物的装卸、建筑地盘的运输工作。从中国出发到外国工作的苦力,历史上称之为华工。Coolie一词来源具有争议,其确实来源至今仍然未有定论。德国博物学家及物理学家博士于1727年以Coolies来形容于日本长崎为荷兰货船卸货的码头工人(抵达日本之前,他曾到过波斯和印度)。根据《牛津英语词典》,Coolie一词可以追溯至17世纪中期,起源于印度语。以上的印度语,虽然读音与Coolie近似,但与苦力的真正解释仍然有所距离。在各国的苦力市场中,华工制度为比较兴盛之一,于1840年至1850年间发展出来,部份工人由于希望到外国工作,会在出国前签定合约,合约条款多是误导性承诺及不公平。一般都会让人有被绑架的感觉,故称卖猪仔。部分苦力为于部落暴力事件、种族以至族群冲突中的受害者,被人口贩卖予经纪人;部份则为为了偿还赌债,而充当上苦力。于1847年至1862年间,大部份的华工被安排乘坐美式船到古巴,人数达至年近6,000。航行途中的环境非常差劣,人多挤迫及污秽。合约条件通常都不被执行,很多苦力被安排于古巴的甘蔗种植场或秘鲁的海鸟粪矿坑工作。尤如奴隶一样,部份苦力被安排于拍卖中出售,于有黑社会或者不法背景人士的严苛监督底下工作。华工与黑奴系统非常相似。很多苦力是被各种方式所欺骗或诈骗、或者绑架,然后被收押于奴隶集中营,黑奴则被收押于停泊于港口的运输船。航行途中,苦力的死亡率甚高,1850年间乘往秘鲁的苦力,每10人中仅有6人能够生还到达。在到达目的地后,他们大多被受禽兽般看待。合约通常为期五到八年,由于工作生活环境恶劣,他们往往未能存活至合约完结(四分之三在古巴工作的华工,未能存活至合约完结),幸存者在合约结束之后,很多都在基于种种因素,包括在不平等的法律(例如种族歧视及保护主义等)下,通常依然被欺压及禁锢。\n\n### 文章 26\n\n天津犹太会堂\n天津犹太会堂,位于今天津市和平区南京路与郑州路交口(原天津英租界小河道(Creek Road)和都柏林道(Dublin Road)交口,后第十区上海道14号),曾是20世纪初犹太侨民在天津的活动中心。该犹太会堂原属天津俄租界犹太宗教公会,现为特殊保护等级历史风貌建筑和天津市文物保护单位。天津开埠后,逐渐成为继上海和哈尔滨后犹太人在中国的第三大聚居城市。1905年,犹太宗教公会(天津希伯来公会)随之建立,创办人是犹太人吉利舍维奇。当年天津犹太宗教公会下辖有犹太医院、犹太养老院、犹太饭堂和犹太公墓等福利救济机构。在天津的犹太人还出版报纸,创办犹太学校,成立天津希伯来协会,开展宗教文化活动。1937年,天津犹太会堂开始筹建,1940年建成。1948年,寓居在天津的犹太人曾在此处庆贺以色列建国,之后,大量的犹太人返回以色列定居,同时中国进行的内战让身处天津的犹太人感到不安全,所以很多俄籍犹太人回到苏联。由于大部分在天津的犹太人收入减少,加上有贫苦的犹太人需要救济,犹太公会提出出售房产。当时天津市人民政府考虑到犹太公会的经济状况于1955年出资由天主教爱国会出面将犹太会堂买下来并于同年8月改为天主教小营门教堂。1958年犹太宗教公会正式宣布停止活动。虽然天津犹太人已所剩无几,在1956年至1959年间不断接受上海犹太社团委员会的资助。直到1992年,此处被出租给香港潮州轩酒家,后遭到宗教人士反对后迁出,现空置。2006年3月16日,天津市市长戴相龙与以色列驻中国大使海逸达的会晤时,以色列驻中国大使对在天津修复犹太会堂和其他的文化活动表示出兴趣。戴相龙在会上宣布犹太会堂作为文化遗址加以保护。2009年,天津犹太会堂重新整修,改建为中法会馆。天津犹太会堂由北欧建筑师设计,是一座具有犹太教风格的犹太会堂,原建筑屋顶立有一金属质六芒星,建筑正面顶端亦镶嵌有六芒星,现已拆除但依稀可见六芒星的痕迹;原犹太会堂铁门上有六芒星形状围栏,正门玻璃彩窗有七烛台标志。\n\n### 文章 27\n\n新巴13线\n新巴13线是香港新世界第一巴士营运的一条香港岛巴士路线,来往西半山旭龢道与中环(大会堂)之间,主要途经中环苏豪区、坚道、般咸道、柏道、列堤顿道。本线于1974年4月16日投入服务,以配合半山区巴士专线启用,初时由中华巴士营运。1998年9月1日中巴的巴士专营权届满后,改由新巴接办。中环天星码头于2006年11月由爱丁堡广场迁往民光街,本线没有延长路线至新码头,只是把巴士总站改称中环 (大会堂)。2012年7月22日,因应云咸街及雪厂街近皇后大道中一段经常性交通挤塞情况于2009至11年间非常严重,新巴决定修改本线往中环方向的行车路线,在坚道(明爱中心)后改经上亚厘毕道、花园道、德辅道中、雪厂街、干诺道中西行、康乐广场、干诺道中东行回大会堂总站(假日则改经皇后大道中及毕打街),是本线开办以来首次更改行车路线。1970年代中期之前,中巴开办路线的编号是按数字排列。12号线于1955年投入服务后,下一条路线本应为13,但当时中巴管理层却指「十三不祥」,故跳过本编号,1960年开设的新线由14号线继续排下去。直至1973年,计划开办此线时,中巴总监颜成坤在报章声言不相信「十三不祥」的思想,并把本线编为13。本线投入服务至2012年7月22日,从未作任何永久性行车路线改动,行车路线维持了38年,是香港境内维持行车路线最长时间的路线。就算中区多年来实施了很多交通改动措施,也没有影响本线的行车路线。全程:$5受屋兰士街的路面影响,本线祇能使用车身长度较短的巴士行走。现时本线主要使用丹尼士三叉戟10.3米(33XX)、矮车身的亚历山大丹尼士Enviro 400(38XX)及亚历山大丹尼士Enviro 200 MMC(250*)行走,而青年JNP6120GR(260*)间中行走本线。中环(大会堂)开经:爱丁堡广场、干诺道中、夏悫道、红棉路、天桥、金钟道、皇后大道中、德己立街、威灵顿街、摆花街、荷李活道、亚毕诺道、坚道、般咸道、柏道、列堤顿道、屋兰士街及旭龢道。旭龢道开经:旭龢道、屋兰士街、列堤顿道、柏道、罗便臣道、卫城道、坚道、上亚厘毕道、花园道、"德辅道中、雪厂街、干诺道中(西行)、#支路"(皇后大道中、毕打街)、干诺道中(东行)及爱丁堡广场。\n\n### 文章 28\n\nJust can\'t help it.\n《Just can\'t help it.》(,"Just can\'t help it.")是东京事变的第五张DVD,于2006年9月6日发行。发行当周即卖出3.0万张,总计销售额5.1万张,名列2006年年度销售榜第30位。初回限定为「Digipak纸盒仕样」。此张DVD是收录东京事变《"DOMESTIC!" Just can\'t help it.》 巡回演唱会的其中一站,于2006年5月26日在NHK会馆(NHK HALL)所举行的,其演唱的歌曲及幕后花絮。演唱会中的新曲「Mirror Ball」、翻唱林檎给友阪理惠「机器少女」和「停电」于8月21日开始接受线上下载的服务,同一天也成立了DVD特设网站。在日本09月6日发行DVD,台湾则是等到09月26日才发行进口盘。《"DOMESTIC!" Just can\'t help it.》为二期东京事变第一次巡回演出,总共在十六个城市举办二十一场的演唱会,场场皆吸引爆满的观众前往感受东京事变的魅力。演唱会演唱的曲目以第二张专辑《大人》为主,演唱会的开场便是日本传统乐的歌曲雪国,身穿和服的林檎,抓住了众人的目光,还有服务这首歌,全体团员拿著大声公演唱,中途搭配上团员们台上换装的片段,带起一波高潮。而演唱会利用投影的方式,搭配团员们的的动作与歌曲的内容,让人惊叹,像是中场时,鼓手刄田缀色凭空踢球的效果,还有脸孔这首歌时,钢琴手伊泽在钢琴独奏时,便把改编的英文版本歌词投影至舞台,这种投影的效果,不但提高了演唱会的可看性,更增加了与台下观众互动的机会。另外由于椎名林檎在专辑《大人》发行接受访问中提到「今后,她想要专心作词和演唱,作曲则会交给其他成员。」因此,在巡回演唱会上发表了浮云所创作的曲目「Mirror Ball」,借此希望之后的活动能以团员的创作曲目为中心。\u3000椎名林檎 - 主\u3000唱・吉他手\u3000龟田诚治 - 贝斯手\u3000刄田缀色 - 鼓\u3000手\u3000\u3000浮云\u3000 - 吉他手\u3000伊泽一叶 - 钢琴手・吉他手\n\n### 文章 29\n\n科克大学\n科克大学(直译为科克大学学院,,)是爱尔兰国立大学的一部分。大学建于1845年,原名“皇后学院”(Queen\'s College, Cork);1908年爱尔兰大学法案出台后,学校更名为“科克大学学院”(University College, Cork)。1997年大学法案将学校更名为\'“爱尔兰国立大学科克”(National University of Ireland, Cork);1998年教育部将大学更名为“科克大学”(University College Cork - National University of Ireland, Cork)。科克大学被星期日泰晤士报选为2003-2004年度爱尔兰大学,2005-2006年和2011-2012年再度当选年度爱尔兰大学。2007年,科克大学在泰晤士高等教育世界大学排名286位,2008年226位,2009年207位。科克女王学院(Queen\'s College, Cork)乃根据维多利亚女王发布的"为发展爱尔兰的高等教育"法案建立。根据该法案,三所学院于1845年10月30日分别在贝尔法斯特(贝尔法斯特女王大学)科克和戈尔韦(爱尔兰国立大学戈尔韦)建立。科克学院1849年正式办学,当时有23位教授及181位学生,一年后便加入爱尔兰女王大学。医学楼建于1860年至1880年,医学院也迅速因其毕业生而建立了名声。爱尔兰最早的两名女医学学生于1898年医学院毕业(20年后牛津大学才开始招收女医学学生)。在随后的一个世纪中,爱尔兰大学法案(1908)成立了爱尔兰国立大学,包括都柏林、科克和戈尔韦的三所成员学院。三所学校也有大学学院的地位,例如“大学学院,科克”。1997年大学法案使大学学院成为爱尔兰国立大学的成员大学,也使成员大学成了全方位的独立大学,但是学位和文凭仍由爱尔兰国立大学颁发。科克大学是爱尔兰的研究型大学,其政府科研经费全国最高。现有艺术、凯尔特研究与社会科学学院、商学与法学院、医学与健康学院、科学、工程和食品科学学院。科克大学还是爱尔兰中国研究院的所在地。学生在中国研究院能够通过艺术和商业学习中国语言和文化。中国研究院最近荣获2008年欧洲语言奖。\n\n### 文章 30\n\n尚元王\n尚元(;)是琉球国第二尚氏王朝第五代国王。他是第四代国王尚清王的第二王子。1556年至1572年在位。神号日始按司添()。童名金千代(),一作鹤千代()。据《中山世谱》记载,尚元原是尚清王生前指定的继承人。但1555年尚清王死后,法司葛可昌(城间亲方秀信)、和为美(国头亲方景明)却突然变心,欲拥立尚清王第四子尚鉴心为君。法司毛龙吟(新城亲方安基)提薙刀叱责二人。群臣多有支持毛龙吟者,因此和、葛二人畏惧而不敢复言。于是尚元在继承权争夺之中胜利,并于次年即位。1559年,将和为美流放久米岛,葛可昌流放伊比屋岛。1562年(嘉靖四十一年),明世宗派遣刑科给事中郭汝霖、行人李际春为册封正副册封使封尚元为王。尚元王体弱多病,常常无法正常管理国事。为了保证朝政的正常运行,琉球王府推举了三名法司为其代理。从此琉球王府中法司的人数定例为三名,这三名法司被统称为「三司官」。朝政基本上掌握在毛龙吟等三司官手里,因此尚元王被称人为「哑巴国王」()。 尚元王死后,三司官的制度被保留了下来。尚元王在位期间,琉球与明朝保持良好的外交关系,多次送还漂流至琉球境内的中国船民。1565年(嘉靖44年),倭寇过境琉球,在北山地区为琉将郑都所败。尚元王遣使将被倭寇虏获的中国人口送还明朝。尚元王也曾一度与日本萨摩藩保持良好的关系,然而在1570年至1572年,双方关系出现两次危机。1570年,萨摩岛津贵久的使者雪岑和尚至琉球,要求尚元王向萨摩朝贡,遭琉方拒绝。岛津大怒,煽动奄美大岛酋长发动叛乱,并向奄美派遣军队,给奄美的酋长提供军事上的支持。1571年,尚元率船五十余只御驾亲征,在奄美大岛两次与萨摩军交战,败萨军,俘杀叛变的酋长。归军途中,尚元王病危,三司官马顺德(国头亲方正格)对天祈祷愿代王死,不久尚元王竟果然病愈。尚元王大为感动,封马顺德之子为按司,称国头御殿,世代袭爵。1572年4月1日,45岁的尚元王病逝,次子尚永继位。\n\n### 文章 31\n\n圣马丁驻军教堂\n圣马丁驻军教堂(Garnisonkirche St. Martin)是德累斯顿的阿尔贝特城(Albertstadt)的一座驻军教堂,位于一片军营建筑群的中心。此教堂按建筑师罗索(Lossow)和费维格(Viehweger)]的设计,为当时在阿尔贝特城的驻军而建,成于1895到1900年间。这是一座双重教堂(Doppelkirche)。它包括新教和天主教两个部分,1945年以后只有天主教部分仍在使用,现在是德累斯顿新城圣方济各沙勿略牧区;新教部分因沦为森柏歌剧院(die Semperoper)的服装仓库而失去其宗教用途,亦不供参观。自从1900年10月28日教堂落成,天主教厅的礼拜者就源源不断。第二次世界大战结束前她一直被用作驻军教堂;1945年6月起,她成为圣•弗朗西斯科•塞维尔(圣方济各沙勿略)(St. Franziskus Xaverius)牧区教堂(之前该牧区的牧区教堂位于阿尔贝特广场(Albertplatz),毁于1945年的大轰炸),直至今日。近年来附近的军官学校的士兵也来参与礼拜和宗教服务。前方中央是一个圣坛(Hochaltar)(新罗马式教堂的核心结构),上面的马赛克画述说着耶稣乃救世主。圣坛前方有是诵经台(Ambo)和祭台(Zelebrationsaltar),其支撑部分则分别是象征着基督的阿尔法A和欧米伽Ω。后殿(Apsis)上方的彩色玻璃小圆窗尤为奇美,它们描绘着圣伊丽莎白公主、圣嘉禄•鲍荣茂主教、阿尔贝特国王、乔治骑士和玛蒂尔达女王。在大玻璃窗上画着圣母玛利亚像和教堂的守护者圣•马丁的割袍像。东南侧是拼嵌有创世图案的玫瑰窗(Schöpfungsfenster),下面的马赛克装饰画是大天使米迦勒。教堂后方的管风琴是耶穆里希三兄弟于1900年所造,分列于其左右玻璃窗上的是殉道者圣•莫里斯和圣•维克多。两侧回廊下面有15幅现代风格的耶稣受难图,及1幅老卢卡斯•克拉纳赫(Lucas Cranach der Ältere)的朝圣画圣母之佑的摹本。中殿(Mittelschiff)和两侧的祈祷室(Seitenkapellen)里各有美轮美奂的彩绘,它们在2005至2007年的修复工程耗资巨大。祈祷室的老吊灯(Leuchter)亦值得一观;中殿悬挂的巨型吊灯则为2006年新制。\n\n### 文章 32\n\n陈衣凡\n陈衣凡(),又名家贵,中华民国空军将领。1912年10月18日出生于奉天海城(今辽宁鞍山)。中学期间适值九一八事变而决定投身军旅,1933年进入黄埔军校10期工兵科。后受孙逸仙“无空防即无国防”之主张,于1934年以绩优选送中央航空学校第五期甲班轰炸科。1936年以优异成绩毕业,后成为空军第13中队飞行员。1938年任第八大队第14中队分队长,5月19日23时半中国空军远征日本本土散发传单,陈衣凡驾中国空军仅剩最后一架He111A轰炸机担任后勤支援运输。以后复入空军参谋大学。1945年赴美国恩尼德航校、柏格斯川航校、同盟国三军联合计划作为学校、美国海军高级军官两栖作战班。1946年回国,入实践研究院联战班及三军大学战争学院将官班,钻研中西军事理论,遂任空军第2大队副大队长。1948年4月16日任第1大队副大队长,接受加拿大乔治·司徒华(George E. Stewart)教官的带飞训练,成为第一位放单飞的蚊式机飞行员。以后任大队长。到台湾后,任台中基地指挥官。1952年任空军总部第2处处长。1953年派任驻菲律宾空军武官。1957年任空军训练司令部参谋长。1959年任空军作战署署长。1964年任空军总部人事署长暨国防部人力司司长、空军作战司令部司令。1968年3月任空军总部参谋长、1969年7月任空军副总司令。1970年6月29日为中将空军第六任总司令,7月3日晋升空军二级上将。1975年6月任总统府战略顾问,驻约旦大使。2008年2月6日3时20分因肺积水、发炎与器官衰竭病逝于台北市内湖三军总医院,享寿96岁。3月9日10时在三军总医院万安怀德生命纪念馆隆重举行公祭,由空军司令彭胜竹上将代表国防部长蔡明宪前往致哀,由总统府战略顾问陈燊龄一级上将担任主祭官,前空军总司令乌钺上将率治丧委员会,前行政院长郝柏村、前退辅会主委许历农、前国防部长李天羽以及立法委员蒋孝严等党政军要员,前往现场吊唁。由赵知远、林文礼、黄显荣、夏瀛洲等四位退役上将为灵柩覆盖党旗,由总统府战略顾问沈国祯上将、空军司令彭胜竹上将、联勤司令金乃杰上将、副参谋总长彭进明上将担任国旗覆旗官,以表彰其一生为空军军事训练及中华民国军事外交的卓越贡献。告别式后发引安厝于台北碧潭空军烈士公墓。夫人朱以苹,朱佛定长女。\n\n### 文章 33\n\n长洲北帝庙\n长洲北帝庙,又名长洲玉虚宫,位于香港离岛区长洲北社街北端,建于清朝乾隆四十八年(1783年),有二百多年历史,已获古物咨询委员会评定为一级历史建筑物,是全香港最具规模的北帝庙,除北帝外,庙内亦供奉太岁、观音及列圣。长洲北帝庙早期由长洲居民负责管理,于1929年交由华人庙宇委员会管理。长洲是原籍惠州、潮州及广州的渔民聚居地,他们信奉海神北帝祈求获得神明庇荫,使舟楫平安。据称,在乾隆四十二年(1777年)长洲发生疫症,当地渔民远赴惠阳县玄武山北帝庙迎请北帝神像到长洲镇压才除去疫症。因此,地方乡绅林煜武于乾隆四十八年(1783年)领导长洲原籍惠州、潮州居民集资建庙奉祀北帝。北帝庙是传统三进式建筑,正殿宽敞,神坛置中,两侧设偏殿,左右对称。殿前建有一道花岗石梯阶,门外置有一个石香炉及两对石狮子,而庙的瓦面和簷角,亦有很多狮子,成为全港庙宇中,狮子最多的一间。庙宇曾分别于道光二年(1822年)、道光十八年(1838年)、咸丰八年(1858年)、光绪廿九年(1903年)及1989年重修。最近一次由华人庙宇委员会斥资逾1,300百万港元进行重修,工程于1999年展开,直到2003年才竣工。北帝诞在每年的农历三月初三,善信敬拜祈求合境平安。而在每年一度的长洲太平清醮期间,长洲玉虚宫前地球场,会架设戏棚、抢包山等,好不热闹。庙内的古物珍品包括一柄早年由渔民网得奉于庙内的宋朝大铁剑及鱼骨、一座制于光绪二十五年的銮舆、一个咸丰十一年制的石香炉及乾隆四十九年的铜钟。此外,为纪念英国玛嘉烈公主及斯诺敦伯爵(Earl of Snowdon)伉俪于1966年到访,一位钟姓女士特别打造了一顶金冠以志盛况;而华人庙宇委员会于1959年铸造了一对铜香炉,纪念护督白嘉时于当年莅临参观。\n\n### 文章 34\n\n升庵桂湖\n升庵桂湖、桂湖是一座位于中国四川省成都市北部新都区境内的园林,是四川园林中川西园林的代表作之一。桂湖倚新都城墙内侧而建,总面积46,600m²,其中水面16,000m²,园内现存建筑大多为清朝重建,但全园完整的保留了隋唐时期园林的山水格局,具有很高的艺术价值,是全国重点文物保护单位之一。升庵桂湖同时也因园内的桂花、荷花而闻名,也是中国重要的桂花及荷花观赏地。新都在汉代设县,在之前由古蜀国管辖。桂湖的形成是在三国蜀汉时期的公元222年,当时一个名叫卫常的人以修建水利方便灌溉为由开凿出了这个湖泊。隋朝开皇十八年(公元598年),新都县城迁于今天新都区中心,期间在此地取土筑新都县城墙而形成湖池,因此地位于县署之南,且设有驿亭,故得名“南亭”。初唐时期,在卢照邻等文人仕官的经营之下,南亭逐渐发展成为一处隶属于新都驿站的衙署园林和城市公共园林。卢照邻在他的《梓州南亭得池字》中描有对桂湖的描绘:“亭阁分危岫,楼台绕曲池。”南亭在宋朝被改名为“新都驿”,成为一处名胜,在当时城墙上建有供人赏玩的建筑。明朝著名学者杨慎(号升庵)居于新都时,曾沿湖遍植桂树,并留有《桂湖曲送胡孝思》一诗,“新都驿”由此得此雅名。因明末清初之交战乱的影响,园内众多唐宋时期的建筑、桂树毁于兵燹,在清朝初年局势稳定后恢复了驿站,但同时又将驿站与桂湖分离,因此桂湖因资金和管理缺乏在在乾隆初年彻底干涸。嘉庆年间,在杨道南(1812年)、汪树涓(1832年)、张奉书(1839年)这几任县令的努力下奠定了如今桂湖样貌的基础,在恢复旧址下又有新的建设与发展,如修建了杨慎的祠堂、多个亭台楼阁并于1839在城墙上石刻了湖的全景图。桂湖也在这个时期逐渐演变成为以纪念杨升庵为主的先贤们的公共纪念性园林。清末的咸丰、宣统年间桂湖也仍有建设。民国成立后的1926年成立桂湖公园事物所,桂湖在翌年成为桂湖公园。期间桂湖内安设了电灯等现代化事物并有了一些扩建。中华人民共和国成立后的初年桂湖面积有所扩大。在1959年10月建立杨升庵的纪念馆。1961年7月13日公布为四川省第二批历史及革命文物保护单位。1980年7月7日重新公布为四川省第一批文物保护单位。1996年11月20日公布为第四批全国重点文物保护单位。\n\n### 文章 35\n\n九龙巴士32B线\n九龙巴士32B线是香港新界的一条已取消循环巴士路线,来往荃湾西铁路站及象山邨。本线曾经是香港唯一一条全线采用非空调巴士的专营巴士路线,但此纪录只维持了12天,最终于2011年8月20日加入空调巴士行走,象征九巴以至全港专营巴士路线全非空调巴士的时代告终。直至2012年4月16日改为空调巴士行走。$4.1(已经在3月17曰加价)最初以「亚比安」单层巴士及丹拿A型双层巴士行驶。到了1990年代采用利兰胜利二型巴士行驶。本线亦是九巴最后一条以利兰胜利二型巴士行走的路线,最后一天行走为1998年3月29日(G544),但随著利兰胜利二型巴士年事已高需退役,本线改为以3轴双层巴士行驶,一直维持至今。取消前全线共有1辆富豪奥林比安11米(AV)及2辆丹尼士三叉戟12米(ATR)空调巴士。由于本线受到多线公共及专线小巴(82M)的竞争,加上班次疏落,收费亦缺乏竞争力(本线早在加入空调巴士行走前20年,小巴则早已有空调设备,而且收费又较本线便宜),在平日繁忙时间以外极少乘客会刻意等候本线,以致整体客量一直偏低,乘客绝大部份都是长者,因此九巴已经对本线采取放弃态度。多年来,九巴一直想更改本线的营运模式,甚至多次提出建议永久停驶本线,但都无功而回,不是遭到民众及区议员反对,就是遭运输署否决建议,而且象山邨及石围角邨都已是老化屋邨,若本线停驶,长者在毫无选择下只好乘搭小巴,小巴营办商因怕收入减少,并希望九巴蚀本营运,而不肯设任何长者优惠,使区议员和居民有理由去阻止九巴停驶本线。鉴于本线被取消的机会非常渺茫,九巴决定作出让步,于2011至2012年路线发展计划中,计划于2012年加入空调巴士行走本线,并于2011年8月20日起正式实施,并于翌年4月16日改为全空调服务。由于本路线长期客量不高,根据2013至2014年度计划,本线将会并入36线,届时36线改为循环线,荃湾西站开出先绕经石围角及象山后返回梨木树原有路线行走再返回荃湾西站。而石围角邨往荃湾的工作将由途经的43X线减低收费至目前水平取代。上述重组计划已于2013年11月30日实施。\n\n### 文章 36\n\n光华体育会\n光华体育会(Kwong Wah Athletic Association,简称光华),成立于1936年,是香港一支老牌足球队,曾在香港甲组足球联赛角逐,现时于香港乙组足球联赛作赛。光华是香港一间老牌足球会,于1936年,由中华电力公司文职人员组成,当中有华人及外籍人士,包括后来成为球星的侯榕生。光华成立后,随即于1936–37年加入香港丙组足球联赛,当年球队经费由中电负责。翌年,获升上乙组联赛角逐,并赢得初级银牌冠军。成立第三年,光华便首次升上香港甲组足球联赛角逐。1950年代初,光华获得许文奎等上海来港商人支持,以一班原上海青白足球队球员为主力,当时效力过光华的上海名将包括有:张金海、吴祺祥、陈明哲、罗寿福、严士鑫等。光华成绩一直只是平平,在1962–63年赢得香港足球高级银牌赛冠军,是该会在甲组唯一的重要锦标。1965–66年,光华在甲组联赛12支球队中位列包尾,宣告护级失败,降落乙组作赛。1972–73年,光华获得乙组联赛亚军,得以重返甲组作赛,并且邀得华探长颜雄入阁,招兵买马增强实力,包括著名守门员何容兴。1976–77年,光华在甲组联赛名列尾二,与另一支老牌球会九巴一同降班,自此未能再重返甲组。1977–78年,光华在香港乙组足球联赛12支球队名列第 11,连续两年都要降班,宣告降落丙组作赛。1990年夏天,因乙组联赛扩充队数,光华获得升上乙组,惟于1990–91年,光华在乙组 10 支球队中名列第 9,与第 10 名的流浪一同降回丙组作赛。2008–09年球季,光华虽然邀得前香港足球代表队前锋巴贝利助阵,但在香港丙组(甲)联赛 19 战 5 胜 1 和 13 负得 16 分,位列第 18 名。2009–10年球季,光华以 19 战 2 胜 6 和 11 负成绩,在香港丙组(甲)联赛名列第 18 位。在2010–11年球季,光华邀得前甲组球员吴圳聪加盟,加强球队后防。香港足球总会于2012–13年球季,重组丙组联赛,并复办丁组联赛。光华在上一届香港丙组(甲)联赛名列第18名,故需降落丁组联赛角逐,光华邀得前香港足球代表队前锋罗伦士及前甲组球员凌汉宗加盟,增强实力争取回升丙组,开季取得六连胜佳绩,至2012年10月14日第七轮联赛才与西贡朋友赛和 2–2,本季首度失分。\n\n### 文章 37\n\n独立学校\n独立学校("independent school")是指不依赖国家或地方政府拨款,而依赖学费收入或捐赠而运作的学校。在美国和加拿大,独立学校是私立学校的同义词。独立学校可能从属于宗教机构,但是该术语更精确的用法则排除了教会学校或其他经济上依靠外部机构的学校。在英格兰、 威尔士和北爱尔兰,最有声望的独立学校称为公学,有时归类为大小公学。校长大会("Headmasters\' and Headmistresses\' Conference")的成员通常被列为公学,尽管其中包括许多独立的文法学校。当他们成立时,这些学校确实是“公众的”,面向那些付不起学费者;批评公学者认为他们早已失去了存在的理由,通常更喜欢使用“私立学校”一词来称呼。在苏格兰,不依赖政府资助的学校称为独立学校。在澳大利亚,独立学校这个术语也可与私立学校交替使用,独立学校是增长最快的教育部门,其中超过85%都从属于宗教机构。2006年,在澳大利亚有1,078所独立学校,491,000 名学生。一些独立学校享有盛誉,入学竞争激烈,学费昂贵,不过自1980年代起,迎合普通澳大利亚人的低学费,而且不从属于教会的学校的数目显著增加。澳大利亚的独立学校占总入学人数的15%,而通常收费较低的天主教学校也占有客观的份额(18%),通常也包括在广义的独立学校之列。1970年以来,非公立学校的入学人数稳定增长,而公立学校的入学人数已经从78%下降到67%。澳大利亚的独立学校与美国略有不同,因为澳大利亚政府根据社会经济地位得分,向包括独立学校的所有学校都提供经费。学校的社会经济地位得分得自于从澳大利亚统计署人口普查中一个人口普查区中选择的样本,家庭收入和教育数据用于为每所学校评出社会经济地位得分,然后据此核算资助额度。平均而言,对独立学校的资助为开办公立学校所需的47%,剩余部分的费用由父母支付。在美国,就读于独立学校的学龄人口只占很小的比例(略超过1%)。独立学校与其他私立学校之间的本质区别是自主管理和自主筹措经费。与此相对照,公立学校由政府提供资金和管理,而大部分教会学校由教会组织拥有、管理和资助。全国独立学校协会(NAIS)是一个美国大学预科独立学校的成员组织。独立高等教育机构的成员组织是全国独立学院与大学协会。\n\n### 文章 38\n\n第十一管区海上保安本部\n第十一管区海上保安本部(,简称十一管或十一管本部)本部驻地在日本冲绳县那覇市港区,为海上保安厅管区海上保安本部隶下之地区海上保安本部,主要辖区为冲绳地方之东海、太平洋以及冲绳县周边海域。尖阁诸岛(钓鱼台列屿)属第十一管区的管制下。第十一管区海上保安本部属下有海上保安部3所、海上保安署2所、航空基地2所、情报通信管理中心1所以及航路标识事务所1所。近年来中国人民解放军海军频密在被划在第十一管区内的尖阁诸岛(钓鱼台列屿)周边海域进行军事演习,其进行之探查行为亦有增加的趋势。而中国大陆、香港、台湾等各国人士的海上活动亦经常在其管辖的海域周边进行,因此第十一管区经常可以获得其他管区的巡视船协助。加之2012年尖阁诸岛国有化后,以中国海监船和渔政船(现大多为中国海警船)为首的中国公务船开始在毗连水域持续巡逻和不定期进入领海巳处常态化。导致海上保安厅力不从心,经常在各管区中抽调船只应付中国公务船,令日常业务大受影响。因此日本政府决定提高预算,成立以设置在石垣海上保安部的10艘1500吨PL型船只加设置在那霸海上保安部的2艘3000吨PLH型船只(PLH06冲绳号(原名筑前号,原属第七管区(福冈))和PLH09琉球号(属第十一管区(那霸)))的尖阁专属警备队。令其成为日本最大的海上保安管区。此外,第十一管区内因邻接东南亚诸国之故,私枭组织网络纠结复雑,致走私活动横行。第十一管区因而会联同与协力打击走私活动。另一方面,为确保船只安全、日本与东南亚的海上通道航路之畅通和方便远海捜索救难等用途,第十一管区配备可用作空中巡逻的与YS-11A,以提高海难救助能力。此外,由于石垣市设有医疗航空事务所,因此石垣航空基地负上了冲绳县的直升机救护之责,进行对八重山群岛地区紧急伤患运送之任务。十一管计有26艘巡视船、巡视艇及各式船艇、吨位由5吨至3100吨不等。所有巡视船装置系统,可以准确在海上定位。停泊于那霸市那霸港基地。停泊于名护市名护港基地。停泊于那霸市那霸港基地。停泊于中城城金武中城港基地。停泊于石垣市石垣港基地。停泊于宫古岛市平良港基地。第十一管区共管有飞机8架及直升机10架。停驻于那霸航空基地。停驻于那霸航空基地。停驻于石垣航空基地。\n\n### 文章 39\n\n现代货箱码头\n现代货箱码头有限公司简称现代货箱码头、现代货箱(英文缩写:MTL),成立于1969年,是香港历史最悠久的货柜码头,是香港第二大货柜码头营运商,仅次于香港国际货柜码头有限公司,主要经营葵青货柜码头1、2、5及9(南)号码头,以及联营广东深圳及江苏太仓的货柜码头。现代货箱码头拥有蛇口集装箱码头20%股权,旁边赤湾集装箱码头亦间接持有8%股权,均与公司股东招商局国际合营。大铲湾码头则占65%。1970年8月,香港政府在葵涌货柜码头招标,现代货箱即投得葵涌一号货柜码头的发展经营权,二、三号货柜码头则分别由日本大山船务公司及美国海陆联运公司投得。1972年,现代货柜再投得葵涌五号货柜码头。1980年代,九仓透过现代货箱积极拓展货柜码头业务,1985年以香港政府授权的葵涌六号货柜码头半数权益与于1975年购得日本大山船务株式会社二号货柜码头的国际货柜交换,至此其所拥有的一、二、五号货柜码头连成一体。1991年,现代货箱再获得八号货柜码头4个泊位中的两个,成为香港货柜码头业仅次于香港国际货柜码头有限公司的另一大集团。1995年,现代货箱的货柜处理量达211万个标准箱,约占葵涌货柜码头吞吐量的25%。现代货箱原是九龙仓的联营公司,九龙仓持有其25.6%股权,但1994年后,现代货箱的两个股东欧洲航务公司马士基和英国铁行轮船公司先后向九龙仓多次出售其所持股份,令九龙仓持有现代货箱的股权大幅上升到50.84%(其他股东包括持20.31%的招商局、持17.65%的太古洋行、持6.3%的汇丰及4.9%的捷成洋行),现代货箱遂成为九仓的附属公司。2001年初,九龙仓向汇丰购进4.5%股份,使其股权增至55.3%;而据年报其他主要股东为招商局国际(22.1%)及太古公司(17.62%)。2003年,太古全数出售所持股份,其中九龙仓购入12.59%(共持有67.89%),作价港币20.72亿元;而招商局购入5.03%(共持有27.04%),作价港币8.28亿元。 交易后九龙仓进一步稳固大股东的地位。2005年,现代货箱向招商局及九仓回购股份,使招商局国际与九龙仓分别持有 27.01% 及 67.59%权益 。 截至2010年,九龙仓与招商局国际仍维持68%与27%的比例;捷成洋行的附属或合营公司Jebsen Securities Ltd持有5%。\n\n### 文章 40\n\n238号州际公路\n238号州际公路(Interstate 238,简称I-238),是美国的一条州际公路,全线位于加利福尼亚州旧金山湾区,是加州高速及快速公路系统的一部份。该公路自圣利安卓880号州际公路分出后向东,于卡斯楚谷衔接580号州际公路,全长。虽然公路是东西走向,标志却以南北向标记。由圣利安卓往卡斯楚谷记为南向,反之为北向。238号州际公路是加州中谷地区通往奥克兰港的主要道路,由于580号州际公路在卡斯楚谷至奥克兰路段不准货车通行,所有货车必须由238号州际公路转880号州际公路进出奥克兰,因而造成该公路常有拥塞情形。I-238在1983年被纳入州际公路系统。但这个编号并不遵守州际公路系统的编号规则(38号州际公路并不存在),如果依规则,这条公路的尾数应为80,目前在加州地区未使用的编号有I-180和I-480,但180号加州州道仅离本路段约100哩(在弗雷斯诺附近),480号加州州道计划在1991年才取消(原路线位于旧金山),为避免用路人混淆,加州公路管理局决定暂不使用这二个编号,而使用公路升级前的编号238。238号州际公路在1983年以前是238号加州州道的一部份,238号加州州道大体上是南北走向,此乃238号州际公路被编为南北向的原因。I-238在与I-580衔接处有另一出口继续接往238号加州州道向南通往海沃德。238号州际公路在1956年升级成为高速公路,但在1964年以前,这个路段并未指定任何编号。原本的计划是在费利蒙境内的238号加州州道至680号州际公路段亦会升级成高速公路(与880号州际公路平行),但在1968年向联邦申请未果,且数度上诉失败后,这个计划无疾而终。在880号州际公路被纳入州际公路系统的同时,这段路亦被纳入系统。美国州公路和运输官员协会在1983年7月7日批准了I-238和I-880这二个编号。I-238二端的系统交流道随即开始改建,加入缺少的I-238往I-880南向的匝道(原本以作为联络道之用)。1990年代,随著湾区捷运都柏林/普莱森顿─密尔布瑞线的动工,I-238的分隔岛交由捷运局作为舖设铁道之用。2009年,全线拓宽为六线道,拥塞情形稍有改善。"注意:哩程数前方若无字母,表示1964年的量测值,由于路线有稍做更动,哩程可能不准确。"238号州际公路全线位于阿拉米达县。\n\n### 文章 41\n\nLED背光液晶显示电视\nLED背光液晶显示电视(LED-backlit LCD television),是使用发光二极体(LED)作为背光源的液晶显示电视。部分电视机生产厂商,如三星、松下、东芝、飞利浦、乐金及索尼等将其称为LED电视,但此并不是指使用发光二极管作图像显示的电视。随著发光二极管电视市场竞争日趋激烈,加上发光二极管应用逐渐成熟,各家电视厂商纷纷积极导入发光二极管背光液晶显示电视,企图在家用电视改朝换代之际能够拔得头筹。发光二极管背光技术可分为直下式(direct back-lit或 full LED array back-lit)与侧照式(edge LED back-lit)两种,而当中直下式所使用的发光二极管有分为白光发光二极管与红、绿、蓝三色发光二极管两种。直下式发光二极管背光技术是把多枚发光二极管排成阵列,放在散光片及LCD后面,直接照射LCD。如此,直下式可以依从画面不同部份的光度变化,快速地微调发光二极管的明暗,大为提高动态对比度达至等离子显示器的水平。缺点也就是需使用数量较多的发光二极管,耗电、体积厚、价格较高。直下式发光二极管背光所使用的有白光发光二极管,也有使用红、绿、蓝三种单色发光二极管(RGB LED)的,使用RGB LED可以有更阔光频谱,也即有更广色域。侧照式发光二极管背光技术是把白光发光二极管放在LCD的四边,LCD后有一与LCD大小相近的反光片,发光二极管从LCD与反光片之间的缝中照进去,反光片上特别设计的微纹能把LED照来的光作90°反射后照向LCD的背部。此等反射片精细得在不需散光片的情况下也能使发光二极管的光平均地分布地照到LCD背部。相对RGB LED,白光发光二极管较为耗电,加上反光片有损耗及LED照射角等因素,侧照式LED原先的耗电会较高,但因为没有散光片,省去了散光片的损耗,侧照式LED背光的耗电可以做到与直照式同级。侧照式可以比直下式做的更轻薄,但色域及对比度都不及直下式。以往侧照式发光二极管背光不能依从画面不同部份的光度变化快速地调整光度,但最近有厂商成功以侧照LED技术有限度的依从画面变化快速地调整光度。以往薄膜电晶体液晶显示器的光源是采用冷阴极萤光灯作背光光源,(如图2)。两者的分别在于:\n\n### 文章 42\n\n江西理工大学\n江西理工大学是一所全日制普通高等院校,位于江西省南昌市和赣州市。创办于1958年,并开始大学本科教育,原名江西冶金学院,1988年改为南方冶金学院,2004年经教育部教学评估,学校更名为现在所使用的“江西理工大学”。2013年6月,江西理工大学成为江西省人民政府、工业和信息化部、教育部共建大学。目前江西理工大学有红旗大道校本部、西校区、应用科学学院、南昌校区4个校区,校园总面积近2500亩,建筑总面积70多万平方米。其中校本部坐落于江西省赣州市红旗大道,位于赣州市中心地带,始建于1958年,后经多次新建,特别是近几年大力发展。校园内绿化覆盖率达60%,绿树成荫、环境优美、景色怡人。学校周围有赣南师范学院科技学院和赣南医学院等一些院校。校本部地址:江西省赣州市红旗大道86号 邮编:341000西校区地址:江西省赣州市章贡区宋城路83号 邮编:341000应用科学学院(独立学院)地址:江西省赣州市客家大道156号 邮编:341000南昌校区地址:江西省南昌市昌北开发区双港东大街1180号 邮编:330013学校建校于1958年,建校之初名为江西冶金学院,隶属于江西省领导。1962年,由江西省改属国家冶金工业部领导。1983年,改为中国有色金属工业总公司直属领导。1986年,经国务院学位委员会会议通过,取得硕士学位授予权。1988年,学校改名为南方冶金学院。1998年9月,实施中央与地方共建,主要为江西省管理。同年,原南昌有色金属工业学校并入,在其址建设为现江西理工大学南昌校区。2000年1月,原江西省商业技工学校并入,在其址新建江西理工大学西校区。2004年5月,通过国家教育部本科教育水平评估,经教育部批准改名为江西理工大学。2013年6月,经国家教育部批准,由江西省人民政府、工业和信息化部、教育部三方共建江西理工大学。世界大学列表 | 中国大学列表\n\n### 文章 43\n\n石守谦\n石守谦(),艺术史研究者,曾任国立台湾大学艺术史研究所教授、兼所长,国立故宫博物院副院长、院长。现在是中央研究院历史语言研究所特聘研究员。2012年当选为第29届中央研究院院士。石守谦自文化史的角度,反思中国绘画史的发展历程,特别关注画史上风格转变的文化脉络、区域性的画史发展,及画史上「雅」、「俗」观念的互动与区别。其研究成果曾二度获得国科会杰出研究奖 (1994-96 及 1996-98)。著有专书《风格与世变》(台北:允晨文化,1996年)与论文多篇,在中国艺术史界享有极高声誉。近期出版《从风格到画意──反思中国绘画史》(台北:石头出版社,2010年),总结近十多年来的研究成果。2007年被控涉入故宫改建扩建工程弊案,士林地检署求处15年有期徒刑,全案在2009年4月30日一审结束,石守谦获判无罪。另外,在故宫南院招标案中,石守谦等人被指控涉嫌违法修改招标规格、内定特定厂商、泄漏招标金额。经其他投标厂商向行政院公共工程委员会提出申诉后,公共工程委员会撤销标案,使得故宫遭得标厂商诉请法院求偿,让故宫损失3900多万元。士林地检署侦办故宫南院弊案,于2009年8月25日侦查终结,石守谦等人被依贪污等罪起诉,求处重刑。2011年9月1日,士林地方法院针对上述故宫南院招标案,一审宣判石守谦等五人无罪,判决书中指出该案议价、签约程序合乎流程,查无不法,五人均无犯罪事实。士林地院并于判决书中多次点出检方起诉时的诸多违误、无稽与偏颇之处。2011年11月29日,针对故宫扩建案,台湾高等法院于二审时,仍采信原审见解,判决石守谦等人无罪。高等法院审理认定,例如在小标绑大标部分,故宫决议以规划、设计、监造三合一方式办理招标,乃九十年三月第一次评选委员的共识和决议,并无不法,也无操纵评选结果等事证,因此仍判石守谦等人无罪。2012年9月20日,台湾高等法院对故宫南院案进行二审宣判,仍判决石守谦等5名被告无罪。\n\n### 文章 44\n\n海军十字勋章\n海军十字勋章(Navy Cross)建立于1919年2月4日,是美国海军部授予的最高等级的勋章,也是美军颁发给英勇行为的第二高的勋章。它一般授予美国海军,海军陆战队或海岸警卫队的成员,但它也可以授予陆军、空军成员或外籍军人。它相当于美国陆军的杰出服役十字勋章或是美国空军的空军十字勋章。海军十字勋章的设立,相当一部分原因是因为美国加入了第一次世界大战。在那时,很多欧陆国家都已经有嘉奖他国士兵英勇行为的习俗,但此时美国为英勇行为而设立的奖励只有荣誉勋章一种。于是,陆军于1918年设立了杰出服役十字勋章和杰出服役勋章,海军在1919年跟进,令海军十字勋章在1917年4月6日生效。初创时,海军十字勋章是低于海军杰出服役勋章,因为那时它可以因战斗英勇行为和“其它的杰出服役行为”而颁发。美国国会在1942年8月7日做出了调整,令海军十字勋章只可因战斗行为而授予,并将其等级置于海军杰出服役勋章之上,仅次于荣誉勋章。自从其创建以来,大约被授予了6,300次以上。第一枚获得海军十字勋章的人已不可考,因为勋章设立之后,最初的授予名单是第一次世界大战结束之后,公布的一份长长的名单。最近的获得者是隶属于美国海军陆战队第3师第3侦察营的枪炮军士约翰·S·莫塞,因其在2008年7月26日,阿富汗地区一场战斗中的英勇表现,于2009年12月18日被授予了海军十字勋章。海军十字勋章被授予以体现出特别的勇敢,但不足以授予荣誉勋章的美国海军或海军陆战队的成员。获得勋章的人必须在极大的危险中或者冒极大的个人危险,其行动必须非常突出于与其他同级别的、同经验的或同样责任的人的行动。许多小的勇敢行动不足以作为获得海军十字勋章的条件。海军十字勋章由设计。勋章正面是一个青铜十字,1.5英寸宽,十字的端部是弧形的。十字的交叉之间有四枚带果的桂叶。十字的中心是一艘在浪上向左航行的帆船。勋章上的帆船是一艘1480年到1500年的船,弗雷泽选择了这条船因为海军学院经常使用这个标志,也因为它是海上服务的标志。桂叶代表了成绩。在青铜十字的中心是一个1850年左右的锚和锚链。锚的中心印有USN(美国海军的缩写)三个字母。勋带是海蓝色的,中间有一条白色的带。海蓝色代表海军服务,白色代表纯洁的无我。\n\n### 文章 45\n\n阿尔维德·卡尔森\n阿尔维德·卡尔森(,),瑞典科学家。他最著名的成就是对神经递质多巴胺的研究以及该物质在帕金森氏症中的作用,他也因此成为2000年度诺贝尔生理学或医学奖的获奖者之一。此外,他也是沃尔夫医学奖的获奖者。卡尔森出生在瑞典的乌普萨拉,是隆德大学历史学教授Gottfrid Carlsson的儿子。1941年,卡尔森也进入隆德大学学习医学。1944年,他参与了检查被释放的纳粹集中营的犯人的工作,他们是被Folke Bernadotte带到瑞典来的。虽然瑞典是第二次世界大战的中立国,卡尔森的求学之路还是由于在军队中服役而被迫中断数年。1951年,卡尔森获得了医学和哲学博士学位,并随后成为隆德大学的教授。1959年,他又到哥德堡大学任教授。1957年,卡尔森提出多巴胺不仅仅是过去人们认为的去甲肾上腺素的前体,也是一种位于脑部的神经递质。在阿斯利康制药公司工作期间,卡尔森和他的同事们利用溴苯那敏合成了第一个投入市场的选择性5-羟色胺再吸收抑制剂——苯吡烯胺(zimelidine)。卡尔森发展出了一种测量脑组织中多巴胺含量的方法。根据这一方法,他发现基底核(控制运动的脑部区域)中多巴胺水平特别高。接着他给实验动物服用药物利血平(reserpine),结果导致多巴胺水平下降并引起运动失控。这一现象与帕金森氏症的症状相似。而通过在这些实验动物的饮食中添加左旋多巴(L-Dopa),多巴胺的前体,能够减轻相应症状。这些发现引起了其他医生的注意,他们尝试使用左旋多巴来治疗帕金森氏症患者,发现确实能够减轻疾病早期的一些症状。左旋多巴目前依然是治疗帕金森氏症的最普遍采用的方法的基础。卡尔森是一名饮用水氟化的反对者。他与其他1700多名卫生专业人士共同签署了一个停止氟化饮用水的请愿书。他声称他参与了在瑞典的辩论会,在会中他帮助说服国会,希望基于道德规范,将饮用水氟化定为非法。他相信氟化水侵犯了现代医学原理,即医学治疗应该根据个人情况来进行。\n\n### 文章 46\n\n深水埗关帝庙\n深水埗关帝庙,最初称为协天宫,其后更名深水埗武帝庙,是香港一所关帝庙,供奉三国时期蜀国大将关羽,位于九龙深水埗海坛街与界限街交界,建筑物背靠深水埗公立医局,是九龙区唯一供奉关帝的庙宇,由华人庙宇委员会管理。整个关帝庙占地约7,000多平方呎,是香港最大关帝庙。深水埗关帝庙获评为二级历史建筑物。深水埗关帝庙建于清朝中叶,年份已不可考,而最近一次重建是位于清朝光绪十七年(1891年)。关帝庙的位置原为深水埗海旁,庙后有小丘,前临大海,有不少卸货码头。当地人便兴建这座主祀关帝的庙宇,祈求保祐贸易的忠诚。庙外建有一座「玉仙亭」,本来可以欣赏海景。然而时移势易,因为填海源故,关帝庙已经变成位置于九龙西内陆。关帝庙日久失修,前廊门柱倾侧,而横梁又被白蚁侵蚀,加上瓦顶漏水,对结构有潜在危险。2010年华人庙宇委员会斥资600万港元进行复修工程,除修复有危险的结构部分外,门楣图案采用传统双龙戏珠,两道侧门则为蝠鼠吊金钱及蟠桃,又重塑大殿的关公像,添置千里坐骑赤兔马、青龙偃月刀及十八兵器等圣物,中门之上添加描述关公史迹的彩门,庙内更挂上三幅由本地漫画家李志清绘画的关帝插图,另置有环保化宝炉,并在庙前加建岭南派传统的「四柱三间」中式门楼。门楼由国学家饶宗颐题写「关帝庙」和「忠义千秋」额匾和「英名震华夏 祈福保平安」对联。同时华人庙宇委员会基于弘扬关公忠义美德,而解州祖庙以「关帝庙」命名,故此于复修后正名为「关帝庙」。同年10月16及17日举行落成及开光仪式,16日更首次恭请关帝像离庙出巡,港岛文武庙的关帝亦会陪鸾,而协办的香港道教联合会邀请两岸四地及新加坡的关帝分灵出席盛会,巡游队伍将由二龙七狮领头,一龙二狮相伴,称为「三龙九狮迎关帝巡游」。\n\n### 文章 47\n\n和弓\n和弓,是日本弓道所使用的一类长弓。标准的和弓长度为七尺三寸(约221公分)。古时和弓称为「大弓」,泛指总长度超过两米的所有长弓。此外也有一种较短的和弓制式,长度为六尺三寸(约189公分)称为「半弓」,也存在比半弓还要短的弓。使用者执弓的位置主要是弓的下弧部份,长度比例是全弓的三分之一。和弓本来是由竹与木再以鳔(胶原料的一种)组装而成,现在组制竹弓多数使用玻璃纤维强化塑胶。一般而言,西洋弓(主要指奥运射箭项目中较常用的反曲弓,即Archery)约有1.6米的长度,使用时持弓者通常都掌握在弓的中心部位。不过,和弓与其它的弓却大不相同。和弓长逾两米,而且弓的上弧部份共占了全弓长度的三分之二,换言之和弓的制式是「上长下短」,其规格及长度亦可称得上是世界最大的弓。和弓上长下短的构造,某程度上为使用者带来执弓时难以平衡的困扰。要精确使用和弓,必须有高水准的技术,使用者持弓的手要掌握发箭时弓的震动幅度,预测弓上下弧的长度差所产生的反动力,并运用这种反动力推算箭的发射方向及应要施加力度的多寡。只要能妥善利用这种反动力,射出的箭轨便可以做出多种不同的变化(例如控制射程、箭的抛物线等)。另有一种非武术用途的和弓和箭,称为破魔弓及破魔矢,两者都是日本的仪式福物。现代的破魔矢,多指当地老百姓在日本新年时,从寺庙、神社等地方祈福后所得到的祝福饰物;破魔弓则是与破魔矢并存的配套摆设。日本人在搬屋或新置物业的时候,都会进行名为「上栋式」的仪式,做法大致是将经开光后的破魔弓矢放置到新屋的横梁上,目的是要利用「神器」形式的弓矢镇压著「鬼门」。如有亲友添丁,亦有赠送破魔矢、破魔弓的习俗。日本神奈川县有「破魔矢奉制所」,专门制作受神社祝福的小型破魔弓矢,后来该店更登记「破魔矢」为其合法商标。破魔矢主要功能在于「无形」的破除邪魔、净化,非「有形」的直接以箭穿刺邪魔,故破魔矢不须造有尖锐的箭头,普遍为平头或圆头。\n\n### 文章 48\n\n阿閦佛\n阿閦佛(,,;「閦」音「触」),又名不动佛、无动佛,五方如来之中的东方佛。据《阿閦佛国经》-{云}-,阿閦佛在成佛久远之前,曾侍奉大目如来(又译广目如来),示而萌发「对众生不生瞋恨」(「不恚有情」)的誓愿,经过累劫的修行,即于东方妙喜世界成佛。 即便为人所怨恨,也不退转,不为嗔恚而动,是为“不动”。与「不动明王」不同。阿閦佛,为大乘佛教信仰中,东方妙喜世界的佛陀,地位等同于西方极乐世界的阿弥陀佛,著名的维摩诘居士即是出自妙喜世界。阿閦佛的妙喜世界非常庄严,有高大的七宝菩提树。阿閦佛信仰与阿弥陀佛信仰皆起源于大乘佛教早期,不过同属大乘的汉传佛教中,另外一位东方琉璃世界的药师佛较为人知。在藏传佛教与密宗信仰中,阿閦佛是金刚界五智如来(五方佛)中的东方如来,代表“大圆镜智”。最早有关阿閦佛的汉语佛经是公元147年由东汉月氏三藏支娄迦谶法师译成汉语的《阿閦佛国经》,这部经也是已知最古老的净土经典。最近在巴基斯坦发现了用犍陀罗语书写的,涉及到阿閦佛的佛经残卷,它们属于早期的大乘佛教,书写时间在公元1世纪末和2世纪间。阿閦佛心咒则是阿閦佛信仰者持诵以求得渡的经典。大宝积经载:「若有善男子、善女人,闻不动如来功德法门,善能受持,读诵通利,愿生彼刹者,乃至命终,不动如来为护念,不使诸魔及魔眷属退转其心」。阿閦佛在不同的经典中也被译为阿閦鞞佛、阿刍鞞耶佛、恶乞刍毗也佛、不恚佛、无怒佛、无嗔恚佛。阿閦佛的形象,据瑜伽母密续记载,为蓝身,偏袒右肩,左手执拳,执袈裟角,右手伸五指,手指指地,置于右膝。一般其像结跏跌坐,坐于青色象背负的莲花台上。此佛在金刚界曼茶罗中,为左手执拳或持金刚杵安于脐前,右手下垂触地,成触地印。\n\n### 文章 49\n\n法网恢恢\n《法网恢恢》(),为QM制作公司(QM Productions)与联艺电视(United Artists Television)制作,自1963年9月17日至1967年8月29日于美国广播公司(ABC)播出的美国电视影集,由大卫强生(David Janssen)主演。共播出4季(每季各30集),全120集。本片前三季为黑白作品,仅最后一季为彩色制作。台湾地区则由台视于1967年12月24日~1970年4月26日首播,1990年代佛光卫视也曾重播本片。完结篇在美国播出时,曾创下50.7%的惊异收视率,此记录直到1980年11月,才被《朱门恩怨》(Dallas)第四季的首集所打破。印地安纳州史丹佛的小儿科医师李察‧金波(Richard Kimble,当时台湾播映译名为「康理查」)之妻海伦,怀孕后孩子因小产而夭折,从此也无法再生育,变得情绪低落。1961年9月17日,可说是改变金波往后人生的日子。当天他们夫妻之间因为海伦无法生育,金波提出收养孩子的建议之事而发生了争执,金波一时气愤开车夺门而出,但他在情绪平静下来之后决定与妻子和好,但返家时,他心中却莫名出现了一股不祥的预感。金波将车子停进车棚时,见到一名独臂男子从家中的玄关跑出,待金波进屋之后他的不祥预感成真,海伦已经倒卧屋内遭到杀害。但警方在侦办后,却将金波视为犯人逮捕。在所有迹象都不利于金波的情况下,更由于金波因为自己根本就并未杀妻而坚不认罪,结果被控犯下一级谋杀罪并判处死刑。含冤莫白的金波在史丹佛警方的警探菲力普‧吉拉德(Philip Gerard)押解下,搭乘列车准备前往州立监狱行刑。一路上金波让思绪冷静下来之后,确认了凶手绝对另有其人--那名「独臂人」嫌疑重大。但如今自己已成即将伏法之身,只能绝望的听从命运安排。然而,上天却对他开了个大玩笑。原本平顺行进的列车竟发生了脱轨翻覆意外,让金波得到了改变自己命运的机会,于是他心念一转,决定逃走。从此成为全国通缉要犯的金波,开始了他漫长无尽的逃亡之旅。他将原本半白的头发染黑,并随处改名换姓从事各种工作,以躲避吉拉德锲而不舍的追缉,更重要的是,金波必须设法找出真凶,还有证实那名极可能是杀妻嫌犯的「独臂人」存在,方能昭雪自己的清白……。本剧的故事就从列车翻覆事件半年后,在金波的逃亡之旅中开始了。\n\n### 文章 50\n\n常东升\n常东升(),字漫天,后改字曼天,回族,河北保定府东城根将军庙街人,保定摔跤的代表人物。常东升出身摔跤世家,九岁开始就跟着父亲常兰亭练习摔跤基本功。先祖世代都是虔诚的穆斯林,其父常凤亭,受教于平敬一,以摔跤闻名乡里,有「百胜将军」的封号。生有四子,常东升是最小的,长兄常东如为张凤岩门下,同样精通摔跤,常东升早年在父兄启蒙下,开始他武术的学习。十岁时拜入张凤岩大师门下,秉持家学,再加上大师指导,兄弟四人很快就展露头角,有「常门四虎」之称,其中又以常东升最为杰出。常东如因病早逝,死前将其弟常东升托付其师,因为两家比邻而居,又是世交,张凤岩对于常东升悉心教导。常东升追随张凤岩十三年,张凤岩并将其女张少芝许配给他,成为他的妻子。张凤岩经常带著弟子到外地比试,足迹远及蒙古。常东升十五、六岁起就跟著其师出门,数百场比试从未落败,连蒙古跤手都深为佩服,称其为跤王、常胜将军。因为常东升摔跤动作快速优美,搏得了「花蝴蝶」的称号。他最得意的技法是得合、麻花掰、沾衣跌。民国22年(1933年),经马良推荐,在南京获全国国术考试总冠军,随即担任中央国术馆摔跤教官(相传当时中央国术馆以每个月500大洋的价码重金礼聘之,当时北京公立学校教师月薪大约5大洋),历任湖南省的技术队和各地军队的摔跤教官,有「武状元」、「摔跤大王」的封号。27年,代表陆军再获全国运动大会摔跤中乙级冠军。后随国民政府撤退来台湾,专任中央警官学校(中央警察大学前身)教官,并兼任师大、政战、建中之摔跤教官。民国64年(1975年),曾应摩洛哥国王海珊的邀请,至摩洛哥表演中国武术。连续击倒国王卫队成员,摩洛哥国王大为赞赏,以宝刀一柄相赠。后筹设中华民国摔角协会,并赴美创设世界摔跤协会。著有《摔跤术》一书。弟子有姚长明,杨忠孝,张燕林,郑秀铎,朱玉龙,翁启修,林奉文,张光明等人。其孙常达伟得其真传,精通摔跤,在台湾致力于推动摔跤的传承与教学。\n\n### 文章 51\n\n罂粟籽\n罂粟籽,又名御米、芥子,罂粟的种子,是一种在世界各地广泛使用的调味料,可用于制油,许多地区也将它当成一种草药来使用。一般使用方法为原粒或经研磨后,加入烘焙食品或酱料中以增加食品风味。有记载在苏美文明时代,人类已经会使用罂粟籽。罂粟籽的形状如肾脏,长度通常少于一毫米。除制作鸦片的罂粟外,其他罂粟目植物的种子一般不会作为食物用途。罂粟可用部分包括枝、叶、壳等,其中罂粟籽中的麻醉性生物碱含量最少。罂粟籽富含膳食矿物质,如钙、铁、镁、磷、钾等,营养丰富,被作为调味料广泛使用。在1992年,国际标准ISO676-1982中已将罂粟籽列入调味料名录。中国于1991年颁布的《香辛料和调味品名称和内含物的测定》标准中,“香辛料和调味品名称表”也明确标明“罂粟,可使用部分,如种子”,但受到严格管制,只有完全灭活的罂粟籽才能上市销售。另外,《美国联邦政府条列手册》、《大英百科全书》等,均记载罂粟籽为安全可食用物质。罂粟籽中含有少量鸦片生物碱,跟吗啡和可待因成份相同,虽然含量较低,不致于对人体造成影响,但食用后有可能造成药检阳性反应 。不过基于这个理由,新加坡及沙特阿拉伯均禁止售卖罂粟籽。罂粟原产于地中海,现主要产地为荷兰与加拿大。地中海一带使用罂粟籽有悠久历史,在面包、蛋糕,曲奇饼上均有使用。在中欧地区,罂粟籽夹心馅饼是一道流传甚广料理,在圣诞节时尤其受欢迎。在巴尔干半岛,罂粟籽甚至会用于制作糖果上。在印度、伊朗等地的一般家常菜肴,亦不时加入罂粟籽。日本七味粉中,也可以加入罂粟籽。罂粟籽含油50%,可榨油。榨出的油称为罂粟籽油或御米油。根据《中药大辞典》,罂粟籽性甘平无毒,治反胃、腹痛、泻痢、脱肛,功能有敛肺,涩肠、止痛。主治久咳、久泻、久痢,胸腹诸痛等症。\n\n### 文章 52\n\n现代货箱码头\n现代货箱码头有限公司简称现代货箱码头、现代货箱(英文缩写:MTL),成立于1969年,是香港历史最悠久的货柜码头,是香港第二大货柜码头营运商,仅次于香港国际货柜码头有限公司,主要经营葵青货柜码头1、2、5及9(南)号码头,以及联营广东深圳及江苏太仓的货柜码头。现代货箱码头拥有蛇口集装箱码头20%股权,旁边赤湾集装箱码头亦间接持有8%股权,均与公司股东招商局国际合营。大铲湾码头则占65%。1970年8月,香港政府在葵涌货柜码头招标,现代货箱即投得葵涌一号货柜码头的发展经营权,二、三号货柜码头则分别由日本大山船务公司及美国海陆联运公司投得。1972年,现代货柜再投得葵涌五号货柜码头。1980年代,九仓透过现代货箱积极拓展货柜码头业务,1985年以香港政府授权的葵涌六号货柜码头半数权益与于1975年购得日本大山船务株式会社二号货柜码头的国际货柜交换,至此其所拥有的一、二、五号货柜码头连成一体。1991年,现代货箱再获得八号货柜码头4个泊位中的两个,成为香港货柜码头业仅次于香港国际货柜码头有限公司的另一大集团。1995年,现代货箱的货柜处理量达211万个标准箱,约占葵涌货柜码头吞吐量的25%。现代货箱原是九龙仓的联营公司,九龙仓持有其25.6%股权,但1994年后,现代货箱的两个股东欧洲航务公司马士基和英国铁行轮船公司先后向九龙仓多次出售其所持股份,令九龙仓持有现代货箱的股权大幅上升到50.84%(其他股东包括持20.31%的招商局、持17.65%的太古洋行、持6.3%的汇丰及4.9%的捷成洋行),现代货箱遂成为九仓的附属公司。2001年初,九龙仓向汇丰购进4.5%股份,使其股权增至55.3%;而据年报其他主要股东为招商局国际(22.1%)及太古公司(17.62%)。2003年,太古全数出售所持股份,其中九龙仓购入12.59%(共持有67.89%),作价港币20.72亿元;而招商局购入5.03%(共持有27.04%),作价港币8.28亿元。 交易后九龙仓进一步稳固大股东的地位。2005年,现代货箱向招商局及九仓回购股份,使招商局国际与九龙仓分别持有 27.01% 及 67.59%权益 。 截至2010年,九龙仓与招商局国际仍维持68%与27%的比例;捷成洋行的附属或合营公司Jebsen Securities Ltd持有5%。\n\n### 文章 53\n\n联苯胺\n联苯胺(分子式:(CHNH)),即“4,4\'-二氨基联苯”,是联苯衍生物之一。白色或微带淡红色的稳定针状结晶或粉末,可燃,露置于空气中光线照射时颜色加深,市售商品常呈褐色或深紫褐色。难溶于冷水,微溶于热水、乙醚,易溶于乙酸、稀盐酸和沸乙醇。可以从热水中重结晶出联苯胺一水合物。联苯胺是二元弱碱,两个p"K"分别为9.3 × 10和5.6 × 10。一般常用的是联苯胺的盐类,工业上多用其硫酸盐,而实验室中多用盐酸盐和乙酸盐。化学性质与苯胺类似,可以与亚硝酸发生重氮化反应生成重氮盐,此盐与芳香胺或酚偶联,可得到多种联苯胺染料。联苯胺曾是染料合成的重要中间体,从它可以合成超过300种染料,但由于它的毒性很强,现已改用其他毒性较小的原料。联苯胺及其盐都是有毒且会致癌的物质,固体及蒸汽都很容易通过皮肤进入体内,引起接触性皮炎,刺激黏膜,损害肝和肾脏,且会造成膀胱癌和胰腺癌。联苯胺的浓度只要达到6.7ppb,对人体就有致癌的风险。联苯胺的使用在中国、美国和世界上很多国家都是禁止的,但是联苯胺含量超标的毛巾在中国市场上仍然广泛存在。2007年央视《每周质量报告》对浙江省毛巾产品的一项抽查检测中,合格率仅有两成,其中有一些易掉色的毛巾含有超标的联苯胺,有些甚至超标上百倍。此类毛巾被倾销到台湾和德国等地。联苯胺会与氧化性的物质反应,生成深色的醌衍生物。此性质曾用于检测血液的存在,血液中的酶可以与联苯胺作用,生成蓝色物质。也可通过类似的反应来鉴定氰化物。不过由于联苯胺的毒性,这个应用已经在很大程度上被酚酞/过氧化氢+鲁米诺试剂所代替。用铁粉将硝基苯还原为氢化偶氮苯(1,2-二苯基肼),然后氢化偶氮苯在无机酸催化下重排,即可得到联苯胺。后一步重排也称为联苯胺重排反应,其过程是分子内的,可看作是σ迁移反应,但是具体的机理仍无完全统一的定论,是有机化学中悬而未决的问题之一。重排反应中也会产生少量的副产物,包括其他氨基联苯和半联胺等。工业上,反应后得到的是联苯胺的盐酸盐,加浓硫酸则得到联苯胺硫酸盐。\n\n### 文章 54\n\n朱椿 (明朝)\n朱椿(),是明太祖朱元璋第十一子,洪武四年八月初八生,母郭惠妃,为滁阳王郭子兴之女。封蜀王,同母弟代王、谷王。王妃为凉国公蓝玉之女,谥号蜀献王。朱椿于洪武十一年1378年正月初一受封蜀王。其人个性孝友慈祥,博览群书,所以朱元璋曾经称赞他为「蜀秀才」。洪武十八年冬十月,明太祖命蜀王、湘王、卫王(代王)、汉王(肃王)诸王阅武于中都,蜀王长史王仲礼随侍。朱椿至中都,辟西堂,以读书自娱。阅武余暇与儒生探赜经史。洪武十九年揭“忠孝为藩”四大字以自警。洪武二十年四月,朱椿召名僧来复与之讲论,作四箴以自警,曰《正心》、《观道》、《崇本》、《敬贤》。洪武二十一年春天,朱椿建宝训堂于殿之西,奉《皇明祖训》于中,先代帝王经典于左。洪武二十二年明太祖召蜀、湘等王回京师,随即就藩之国。朱椿于洪武二十三年1390年正月初一就藩成都。入蜀后,他聘大儒方孝孺担任世子傅,表其居曰“正学”,对蜀地学风的带动有很大的功绩,当时他知道知藩内学子贫困,便将自己的食禄每月拨出一石救济。礼聘至长史陈南宾,待以客礼。后来番人入寇,火烧黑崖关。朱椿向朝廷求救,朱元璋派遣都指挥瞿能跟凉国公蓝玉出大渡河将番人击破。而朱椿在明白两川祸乱源头后,大减赋税,制订蜀地集市规范,终使蜀地大治。此外,他对蜀地佛教也相当关心,时常上峨嵋山参拜,峨嵋山上所建的清音阁接王亭就是为了迎接朱椿而设。明成祖即位,上朝参见时朱椿所获得的赏赐倍于诸藩。后来同母弟谷王朱橞意图谋反,朱椿率先举报,被明成祖认为曰:「王此举,周公安王室之心也。」再度入朝,朱椿获赠金银彩缎数万。朱椿于1423年过世,年五十二,谥号蜀献王。第二十世子孙朱清时,物理化学家,中国科学院院士,第三世界科学院院士,南方科技大学首任校长,中国科学技术大学第七任校长(1998年-2008年)。(Fellow of the Royal Society of Chemistry, FRSC),中国化学会常务理事、中国科学技术史学会副理事长。第八、九届全国人大代表、第十届全国政协委员。\n\n### 文章 55\n\n神雕侠侣 (1995年电视剧)\n《神雕侠侣》(;又名《九五神雕侠侣》),是香港电视广播有限公司根据金庸所著的武侠小说《神雕侠侣》改编而拍摄的经典巨著电视剧,全剧共32集,监制为李添胜。杨过 ( 古天乐 饰 ) 一次误闯进活死人墓中,幸好拜得古墓派掌门小龙女 ( 李若彤 饰) 为师,因厌恶师父二字称谓,故称小龙女为「姑姑」。二人相依为命,但不知不觉间却萌生微妙的男女感情,且达到生死相逢之境地 ! 对此情坚贞不渝,纵使小龙女被尹志平 ( 陈启泰 饰 ) 所侮辱,仍能摒除世俗眼光而当众结为连理成亲。 后二人相分,决定十六年后终在绝情谷再续前缘 ……另一厢,郭靖 ( 白彪 饰 ) 、黄蓉 ( 魏秋桦 饰 ) 将女儿 郭芙 ( 傅明宪 饰 ) 许配予杨过,但为杨过所拒绝 ; 自始郭芙与杨过便积怨日深,于是在一次误会中,郭芙更斩下杨过之左手。然而,小东邪郭襄 ( 李绮虹 饰 ) 则对杨过豁达情深,更鼓励杨过踏遍天涯海角去觅回小龙女 ……以下是本剧在香港首播的集数之播映纪录:以下所有影碟发行均由电视广播(国际)有限公司授权:香港发行代理商现代音像(国际)有限公司于2003年推出发行了《神雕侠侣》VCD影碟零售版本,此影碟将已播放的集数并制作成20只碟作为片段完整及无删剪版本,一套共分为两盒影碟,每只碟跟电视剧的每集片长约60分钟一样,设有粤语及国语发音版本并配上繁体中文字幕。中国大陆发行代理商中凯文化集团推出发行了《神雕侠侣》H DVD影碟零售版本,总共30集,共四碟,出版社为九洲音像出版公司,设有粤语及国语发音版本并配上简体中文字幕。台湾发行代理商弘音多媒体科技股份有限公司于2007年推出发行了《神雕侠侣》DVD影碟零售版本,此影碟烧录VCD香港版的20只碟作为集数,共5只碟,设有粤语及国语发音版本并配上非隐藏繁体中文字幕。本剧于2014年5月在TVB星河频道,2017年9月1日在TVB经典台重播。\n\n### 文章 56\n\n海淀黄庄站\n海淀黄庄站位于中国北京市海淀区,是北京地铁4号线和10号线的一个换乘站。海淀黄庄站地处中关村大街与海淀南路-知春路相交路口下方。4号线车站沿中关村大街大致呈南北向布置,10号线车站沿海淀南路-知春路呈东西向布置,10号线在4号线上方通过,两线车站大致呈十字交叉。海淀黄庄站为地下车站,两线车站站台主体呈“十”字型岛–侧式相交形式,两线换乘采用“站厅+通道”双向通行方式。海淀黄庄站由地下二层构成,地下1层为4号线分离式站厅和10号线侧式站台,两者通过缓坡弧形通道连接;地下2层为10号线分离式站厅和4号线岛式站台。4号线换乘10号线需先由站台两端扶梯向上至站厅层,再由通道前往10号线站台;而10号线换乘4号线则反之,先由通道到达4号线站厅,再由扶梯向下至4号线站台。海淀黄庄站地下一层设有两个站厅,分别位于海淀黄庄路口南北两侧。北站厅南端、南站厅北端分别设有通往10号线外环、内环站台的换乘通道口。地下二层亦设有两个通往10号线车站的站厅,分别位于海淀黄庄路口东西两侧,乘客可在付费区内进行10号线内外环站台间的换向。海淀黄庄站10号线站台位于地下一层、海淀南路地下,为侧式站台,外环站台北侧、内环站台南侧设有换乘通道口。4号线站台位于地下二层、中关村大街地底,为岛式站台,南北两端设有通往站厅的楼梯、自动扶梯及升降电梯。海淀黄庄站有5个出入口:A1(西北)、A2(西北,连接新中关购物中心)、B(东北)、C(东南)、D(西南)。在西北角和东南角出入口各设有通地面的垂直电梯。在该站东南侧修建了两个紧急疏散通道。10号线车站装饰色调以白色为主;4号线车站装饰色调以黄色为主。\n\n### 文章 57\n\n米拉加亚龙属\n米拉加亚龙属(学名:"Miragaia")是种剑龙下目恐龙,化石发现于葡萄牙,年代属于侏罗纪晚期。米拉加亚龙以牠们的长颈部而闻名,颈部具有至少17节颈椎。米拉加亚龙的正模标本(编号ML 433)发现于葡萄牙北部奥波多市的劳尔哈组(Lourinhã Formation),年代为侏罗纪晚期(启莫里阶晚期到提通阶晚期),约1亿5000万年前。这个标本是由一个部分颅骨,以及部分的身体前半段所构成;包含以下部位:大部分口鼻部、15节颈椎(缺少最前2节颈椎)、肩带、大部分前肢、13个背部骨板。米拉加亚龙的颅骨,同时也是欧洲所发现的第一个剑龙类颅骨。在正模标本的发现处附近,另外发现一个幼年个体标本(编号433-A),包含:一个部分骨盆、部分的脊柱,也被归类于米拉加亚龙。米拉加亚龙是由奥克塔维奥·马特乌斯(Octávio Mateus)等人在2009年叙述、命名。模式种是长颈米拉加亚龙("M. longicollum");属名是以化石发现处的奥波多市的Miragaia堂区为名,种名则意为「长颈」。马特乌斯等人同时也提出一个系统发生学研究,认为米拉加亚龙与锐龙属于一个名为锐龙亚科(Dacentrurinae)的演化支;而锐龙亚科与剑龙属都属于剑龙科,两者互为姊妹分类单元。米拉加亚龙的明显特征,是其长于一般剑龙类的颈部,由至少17节颈椎所构成;与传统观念中,剑龙类的低矮步态、短颈部不同。米拉加亚龙的颈椎数量,甚至比大部分的蜥脚类恐龙还多(多介于12节到15节颈椎);只有盘足龙、马门溪龙、峨嵋龙等蜥脚类恐龙的颈椎数量,超过米拉加亚龙。马特乌斯等科学家推论,米拉加亚龙的长颈部可使牠们有更大的进食范围,或者是在求偶时具有视觉辨认的功能。蜥脚类恐龙的长颈部,是由部分背椎向前移动构成颈部脊椎、额外增加的颈椎、每个颈部脊椎的长度加长…等因素形成。科学家推测米拉加亚龙的长颈部,是由部分背椎向前移动构成颈部脊椎而形成;而非额外增加的颈椎。与剑龙属相比,米拉加亚龙的颈椎长度略长,但这可能是死后的化石化过程中,遭到外力变形的后果。与其他剑龙科相同,米拉加亚龙的口鼻部前端缺乏牙齿。前肢的尺骨/桡骨长度比例,与剑龙属的比例相近。颈部肋骨与颈椎愈合。耻骨的末端大,与锐龙相同。背部骨板成三角形。\n\n### 文章 58\n\n张永德\n张永德(),字抱一,并州阳曲(今山西省太原市阳曲县)人,五代时后周禁军统帅之一,太祖郭威第四女寿安公主之婿。后周广顺元年(951年),太祖郭威即位,以外甥李重进为内殿直都知,女婿张永德为内殿直小底四班都知;又升李重进为小底都指挥使,而以张永德接任内殿直都知。翌年(952年),郭威以李重进为大内都点检兼马步都军头,张永德为小底第一军都指挥使;后又以李重进为殿前都指挥使,张永德为殿前都虞候,掌管殿前亲军。两年后,郭威病危,传位养子柴荣,临终前特命李重进向柴荣行君臣之礼,以免其觊觎皇位。显德元年(954年),世宗柴荣即位,以姑表兄李重进为侍卫亲军马步军都虞侯,妹夫张永德接任殿前都指挥使,分掌侍卫亲军和殿前亲军,张永德时年二十四岁。李重进、张永德本以姻亲之故,在数年间不次擢升,但后来都在战争中展现出过人的军事才能。在决定后周生死存亡的高平之战后,李重进以战功加使相衔,升侍卫亲军都指挥使,母福庆长公主追封燕国大长公主;而张永德以战功加检校太傅,授义成军节度使,妻寿安公主进封晋国长公主。显德三年冬,擢为殿前都点检。四年,从克寿州还,制授检校太尉、领镇宁军节度使。五年夏,契丹扰边,命永德率步骑兵二万拒之。回军途中,周世宗发现一个韦编袋子,里面有一块三尺长的木板,上有“点检做天子”五字,下诏免去张的殿前都点检一职,解兵柄,加检校太尉、同中书门下平章事。恭帝嗣位,移忠武军节度使,赵匡胤代其职。宋初,甚受宋太祖礼遇,加侍中,入朝授武胜军节度使,太祖每呼驸马而不呼其名。太平兴国二年入朝,拜左卫上将军。五年,坐市秦、陇竹木所过矫制免关市算,降为左卫大将军。数月,复旧秩。六年,进封邓国公。雍熙中,连知沧、雄、定三州。端拱元年,拜安化军节度使。召还,为河北两路排阵使,屯定州。尝与契丹战,斩获甚众。二年,丁内艰,起复。淳化初,又代田重进知镇州。二年,改泰宁军节度使兼侍中,出判并州兼并代都部署。真宗即位,进封卫国公。未几,判左金吾街仗事。咸平初,屡表请老,授太子太师,分司西京,仍以其孙大理寺丞文蔚厘务洛下,以便就养。二年冬,契丹入边,帝将北巡,以永德宿将,召入对便殿,赐坐,访以边要。以老不可从行,留为东京内外都巡检使。三年,制授检校太师、彰德军节度使、知天雄军。俄以衰耄,命还本镇。是秋卒,年七十三。遣内园使冯守规护柩还京师、赠中书令。诸孙迁秩者五人。\n\n### 文章 59\n\n黄超巨星\n黄超巨星(,缩写为“YSG”)是光谱类型为F或G的超巨星,这一类型恒星的初始质量介于10至40太阳质量之间,并且多数会在演化过程中损失超过一半的质量。质量低的恒星光度也较低,会被归类为黄巨星,但高质量的也不会发展成为蓝超巨星。多数离开主序带的黄超巨星只会在这个阶段维持数千年,很快的就会冷却并且膨胀成为红超巨星,所以他们比红超巨星更为罕见。黄超巨星在耗尽核心的氢之后,在核心外层继续燃烧氢。核心的氦在某一个点被顺利地点燃,并发展成为红巨星,但模型的变异上不能确定是在黄超巨星阶段,还是在成为红超巨星阶段之后才点燃了氦。黄超巨星位于赫罗图上的不稳定带,因为它们的动态会导致温度和亮度的不稳定。在不稳定带观测到的恒星多数都是变星,像是次巨星的天琴RR变星、巨星的室女W型变星(第二型造父变星)、和较亮的巨星和超巨星的经典造父变星。此外,有许多罕见的黄超巨星变星,像是金牛座RV型变星,后来被认为是前AGB星和北冕座R,极不寻常的是几乎没有氢的富碳星。上述的不稳定带还发现更不稳定的黄特超巨星(也就是更为明亮),有著更不规则的脉动和大质量的损失。多数的黄特超巨星不是已经成为红超巨星,就是演化成为bluewards。然而,至少HD 33579是个例子,它是首度演化成为红超巨星的一个例子。并不期望在从黄超巨星阶段演化成为红超巨星阶段之前会发生超新星爆炸,然而目前并不清楚后红超巨星的黄特超巨星是否会坍塌形成一颗超新星。然而发光能力不足以成为后红超巨星超新星,可与黄超巨星有关联,祖先可能是黄超巨星的超新星屈指可数。如果可以证实,然后解释一颗中等质量,核心为氦核的恒星,怎么会导致核心崩溃成为超新星。这种情况的候选人,明显的是某种形式互动下的联星。\n\n### 文章 60\n\n犊牛式 (枪械)\n犊牛式(),又名牛犊式、小斗牛犬式、小牛头犬式或无托结构,一种弹匣和枪机位于扳机后方枪托结合的枪械设计,较常见于步枪上。「Bullpup」在这里的原意是小斗牛犬。世界最早使用无托结构的武器是1901年的Thorneycroft式栓动卡宾枪。1918年法国造出了第一支无托的半自动Faucon-Meunier式步枪。1936年法国的Henri Delacre注册了一支无托冲锋枪。二战后波兰出身的Kazimierz Januszewski在恩菲尔德工厂里设计出了第一支无托自动步枪---EM2。以步枪为例,犊牛式设计优点有:虽然犊牛式枪械设计具有以上的优点,但也存在着不小问题:有些型号尝试改善不能随时左右手互换射击的问题。例如奥地利斯泰尔AUG及法国的FAMAS和以色列TAR-21可以透过更换小部份零件把机匣上的抛壳口位置转换到另一边。但这些设计都不能完全解决问题,因为实战中射手经常要以快速、反复地从左手转成右手控制扳机,例如从掩护物的左边移到掩护物的右边射击,这种情况在城镇作战中更显重要。这个问题在1970年代德国的HK公司开发的HK G11首次出现了解决方法,但却衍生出弹药安全问题。虽然G11采用无壳弹,因此无抛壳口,自然也没有左右手问题,但当时的无壳弹在安全性上存在着一定隐忧。之后比利时Fabrique Nationale(FN)推出名为P90的个人防卫武器(Personal defense weapon,PDW),供弹系统改为机匣顶置平排弹匣,发射时弹壳向下抛出,但P90的子弹为较短的5.7×28毫米子弹才可打横平排在枪的上方,对于较长的子弹这种方法似乎不太可行。直到2001年FN推出的F2000才使得用普通有壳步枪子弹也能解决犊牛式枪械抛壳方向问题。F2000采用的是5.56×45毫米标准北约口径子弹,子弹发射后弹壳被移到位于枪管上方的弹壳槽内,射击时首发弹壳会留在弹壳槽内,直至射击至第三、四发,首发弹壳才会自然排出。但其实早在1962年,苏联轻兵器设计师日耳曼·A·科洛波夫研制TKB-022时,已经设计出使用前置式抛壳口的犊牛式枪械。在发射以后,原来的弹壳会被抽出膛室并且经由机匣内部的机构位于枪管上方的抛壳管自然排出。\n\n### 文章 61\n\n香港技术标准\n香港自十九世纪以来即为英国殖民地,至1997年才结束;加上英国本身为工业大国,故香港使用的技术标准绝大部分来自英国,但这情况自主权移交后已有所变更。香港市电为220伏特(早期为200,1990年开始提升;英国则现为230,早期为240)、50赫兹。插头及插座方面,虽然英国很早已有标准,但香港一直没有统一规格,直至 1990 年代香港政府才修订法例强制执行。现时绝大部分电器均使用13安培方脚插头及插座。香港第一条铁路九广铁路-英段(今港铁东铁线)使用的轨距为1435毫米标准轨,其后由九广铁路公司兴建的轻铁、西铁、马铁均使用标准轨。香港地铁则使用和伦敦地铁一样的1432毫米轨距,但实际上与标准轨可互换及共同使用。于1980年代开始跟随英国使用 BT电话插座及插头(俗称英式或扁插)。2004年,香港电讯管理局建议所有新安装或改装电话插座改为使用(俗称美式或方插)插座及插头。2G通讯使用与英国、欧洲相同的GSM 900及1800。曾有业者使用北美的D-AMPS及CDMA制式,但现已淘汰。3G服务则使用W-CDMA,只有一家业者使用CDMA2000。传统模拟电视使用和英国一样的PAL-I制式及丽音立体声/多语言系统。2007年末开始的数码广播则使用中国大陆的 DMB-T/H制式,但当中混合使用了大量欧洲DVB标准,如视讯、音讯格式、字幕、电子节目指南等。香港在DVD分区属第三区(中国大陆属第六区,英国则属第二区);Blu-ray Disc属A区。香港本身虽然使用PAL制式电视广播,但出产的LD、DVD及VCD绝大多数使用NTSC制式。香港使用繁体中文,故绝大多数人使用源自台湾的Big5字元集。香港政府更据此开发「共通中文界面」,增加香港增补字符集 (HKSCS);现逐步转换至 Unicode。香港虽然使用英式英文,但使用美式键盘()。\n\n### 文章 62\n\n项少龙\n项少龙,是黄易玄幻武侠小说《寻秦记》的男主角,是21世纪年轻特种部队成员。在电视剧中为香港警务处要员保护要人组(G4)成员。身为21世纪特种军人的他,在一次时光机器的实验被传送回战国时代,以假赵盘代真嬴政,凭其经历两千多年的智慧优势,频频化险为夷,并且帮助小盘成为日后统一六国的秦始皇。由于《寻秦记》的广泛流传,电视剧版由古天乐饰演,项少龙是黄易最广为人知的人物。。身为廿一世纪特种部队军人的项少龙,年轻力壮、风流多情,在一次时光机器的实验当中被送回公元前251年的赵国邯郸附近。投靠以马致富的大家族乌氏,而后更成为乌家快婿。一心想见未来秦始皇的他,在得知真正的嬴政已经死去后,以赵国公子赵盘代之,并且助乌氏及小盘逃离赵国。投靠秦国后,开始帮助小盘拓展形势、肃清异己,与吕不韦、嫪毐集团明争暗斗。虽然项少龙一心帮助小盘,但也使日渐成长的小盘对其猜忌。小盘成年加冕大典后,携乌氏家族及妻妾逃离秦国,从此不问世事。项少龙有四位肝胆相照的结义兄弟,排行老大是乌家战士之首乌卓,年纪约三十五岁;老二滕翼,武功高强,和项少龙多次出生入死;项少龙排行第三;老四王翦,秦国年轻高手,同时也是战国四大名将之一;老五荆俊,乃荆家村村人,身手敏捷,精于打探情报。项少龙还有多位六国朋友,较有交情的包括智谋与见识不凡的魏国龙阳君,对少龙「一往情深」;楚国李园,最初两人因争夺嫣然而为敌对关系,但后来少龙助其坐稳相国之位;韩国韩闯,生性好色,与少龙亦有交情。但项少龙对他们真挚的付出也曾因对方认为应以国家利益为重而遭背叛。墨家元宗,是项少龙的恩人兼师友,传授项少龙墨子剑法;韩公子韩非,曾助项少龙逃离魏国大梁;阴阳家代表邹衍,亦师亦友,多次相助项少龙。其他项少龙的好友包括赵国名将李牧,曾赠与少龙宝剑血浪,但后期秦赵交战时对敌;原本吕不韦门人肖月谭及图先,前者在得知吕不韦欲杀其之心后,逃离秦国,后者则为项少龙打探有关吕不韦的情报;秦国储君派中流砥柱李斯、昌平君兄弟等人。项少龙为人风流且重视感情,故妻妾成群,唯后期较为克制。另外,项少龙疑似在时空机器的穿越过程中影响到生育能力,故领滕翼第二子为继子,替其命名为项羽,视如己出,疼爱有加。项少龙的妻妾:此外,项少龙还有多名情人,有些是妻妾的随身婢女,有些则是深闺怨妇,但未必都有肉体上的关系。\n\n### 文章 63\n\n菲利斯·马加夫\n禾富简-菲利斯·马加夫(,)出生于西德阿沙芬堡,是一名德国前足球运动员,司职中场,在效力汉堡期间成名,赢得3届德甲冠军及欧洲冠军杯和欧洲杯赛冠军杯各1次,他亦曾为西德国家队上阵超过40场,并夺得1980年欧洲国家杯冠军,退役后担任教练。现时执教中国足球协会超级联赛球队山东鲁能泰山。马加夫在球员时代只是效力德国一些名不见经传的球会,较为著名的已是汉堡,当时效力了十年。 不过,1983年欧洲冠军联赛决赛,正是他一战定江山,以1-0击败意甲劲旅尤文图斯,为汉堡夺得欧洲冠军联赛冠军。他也有代表西德国家队上阵,跟随过国家队赢得1982年世界杯和1986年世界杯两次世界杯亚军。退役后他先在汉堡展开教练生涯。数年后他转教拜仁慕尼黑时,赢得了执教生涯第一个德甲冠军;2007年他开始执掌德甲球会禾夫斯堡,并在 2008/09年球季为球队首夺德甲冠军。2009年,马加夫宣布转投史浩克04,带领球队的首个球季取得德甲亚军及翌年欧联入场劵。夏季马加夫大举增兵,虽然在欧联晋级八强,而德国杯亦在准决赛淘汰拜仁慕尼黑晋级决赛对德乙的杜伊斯堡,但在联赛的成绩差劣,排在积分榜第10位,距离降班区域仅差5分,加上在买卖球员与董事会及球迷意见相左,于2011年3月16日球会召开特别会议后宣布提前20个月解雇马加夫。遭革职后仅两天,马加夫随即重返禾夫斯堡,担任主教练兼总经理,签约至2013年6月30日。于2013/2014年球季,仅余下十三埸球赛的情况下,接任榜尾球队富勒姆教练,成为英超首位德籍教练。2014年9月18日富咸今季跌落英冠作赛以球队的超班阵容理应很容易就回升英超可是至今7场也未打开胜利之门,仅得1和6负,在积分表敬陪末席于是把领队马加夫辞退。马加特具有波多黎各血统,他父亲是一名二战后驻扎在德国的波多黎各裔美军士兵,母亲是德国当地女子。其父1954年返回美国时将母子抛弃,而后马加特一直随母居于西德,直至2000年才跟生父相认。\n\n### 文章 64\n\n枫树脚溪\n枫树脚溪,又名南屯溪,旧称犁头店溪,位于台中盆地,属于乌溪水系,为土库溪的支流,流域分布于台中市乌日区、台中市中心及台中市潭子区,因流经枫树脚聚落(今南屯区枫树里)而得名。枫树脚溪本流发源西屯区何厝庄,向南流经南屯区沟仔墘、犁头店、下枫树脚,于南屯区、乌日区交界处汇入东侧流来之土库溪。依据经济部水利署公告,枫树脚溪注入土库溪,以土库溪为主流。旧南屯溪附近地区,早年经文史团体调查即发现有丰富的史前遗留,并将其命名为「麻糍埔遗址」。从台湾清治时期至民国70年代,南屯溪与南屯地区居民生活相互依存。旧南屯溪于清代台中盆地开垦史中,因邻近往来鹿港与葫芦墩街之贸易古道,逐渐形成犁头店街附近的重要农村聚落。随著台中市第二、三、四期扩大都市计划发布实施,南屯地区逐渐发展成住宅社区,以黎明路周边发展最为快速。80年代,配合第七期、第八期重划区开发,部分南屯溪河道纳入重划区排水,1995年(民国84年)南屯溪整治完成后,仅永顺路与永春东二路间第13期市地重划范围内尚存一小段天然河道,为南屯溪原本的自然河道,称为「旧南屯溪」,范围北自永顺路靠文心南七路段,沿枫乐巷南抵永春东二路和环中路交叉处附近。现今旧南屯溪之排水功能则已被新南屯溪的排水道取代。旧南屯溪拥有丰富生态且兼具疏洪功能,鱼类、水草与鸟类在此和谐共生,为都市中难能可贵的自然生态资源。此外,旧南屯溪部分河段保留水利设施,提供周边土地农作灌溉功能,象征旧南屯溪对传统农业社会的贡献。由于旧南屯溪有高度景观及人文意义,代表先民当年溯溪至台中开垦之历史意义,对南屯地区的发展具有历史、文化上之意义与价值,而且旧南屯溪沿线有优美绿带,展现旧南屯溪的自然生态与历史古迹,旧南屯溪畔有史前麻糍埔遗址,亦反映过去人类利用此溪水生活之意义。因此经过地方及文史专家争取,2013年10月台中市文化局正式将位于第13期重划区内的旧南屯溪、铁道等设施列为文化景观,成为台中市第1个河流的文化景观。\n\n### 文章 65\n\n北海油田\n北海油田是世界著名的石油集中出产区,每日生产大约600万桶。位于大西洋的陆缘海——北海,它是介于欧洲大不列颠岛、挪威和欧洲大陆之间,所出产之石油为沿岸英国,挪威和荷兰等国所享有,也是布兰特原油指数主要标的。1970年代之前,以波斯湾为核心的亚洲中东地区,一直是西方工业国家石油能源的主要供应者。随着第二次世界大战后西方国家经济的恢复和繁荣,石油需求量逐年上增,使得亚洲石油国提高购价。这让各大石油巨头不愿购买,双方因此积怨。1973年第四次中东战争爆发,阿拉伯产油国以不满美国为首的西方国家支持以色列之立场为由,以能源为武器,宣布「石油禁运」,导致欧美油价暴涨,并相继波及各个经济领域,部分导致七十年代全球经济大衰退。因此,以英国为首的北海沿岸国家将目标转向沉寂多年的北海油田。在此之前,北海是欧洲航运要道,且海底地形复杂,海上气候恶劣,一直未有大规模地质勘探活动进行。而北海在1959年首先于荷兰近海发现格罗宁根气田(荷兰语:Groningen),此后更进入大规模开发阶段,先后于1969年发现埃克非思科油田(英语:Artsen non-Cisco),1971年发现布伦特油田(英语:Brent),大油田的相继发现,不仅缓解英国与挪威等西欧国家的能源短缺,而且更使挪威成为除加拿大和俄罗斯之外的第三大非OPEC石油出口国。北海石油的发掘,使得正处于疲软时期的英国、荷兰与丹麦等工业国家的经济获得帮助,也使得英国经济在「油荒」年代于西欧一枝独秀。北海原油因其品质高,产量稳定,所以迅速成为欧洲重要的能源供应地,因此欧洲原油交易市场多以每桶北海布伦特石油(约159升)作为市场参考价格。世界石油市场约6.4%的供货来源于此。\n\n### 文章 66\n\n1944年教育法令\n1944教育法令(Education Act 1944),此法令改革了英格兰与威尔士中学的教育系统。法令常以保守党政治家拉布·巴特勒命名,他为中学教育引入了三分系统),并变中学教育为免费。法令在1996年11月1日被1996教育法令废除。三分系统将中学分为三类:文法学校、与。它允许了的创办,这种学校是前三种学校的结合,但是这种学校最初只创办了几所。它也引入了一个新的系统,,在这个系统下,一些学校接受教育部的直接补助(不同于普通学校接受地方教育局补助),作为交换,他们需要预留一些免费学位。法令规定向英国所有18岁以下学童免费提供三分之一品脱牛奶,后来,哈罗德·威尔逊的工党政府不再向中学生提供免费牛奶。这个政策在1971年被撒切尔夫人(后任教育大臣)延伸,她不再向七岁以上学童提供免费牛奶。法令的其中一个重大结果是教育、动员了妇女与工人阶级。它使得中学向妇女开放,接受专上教育的工人阶级比率大大增加。受过教育的工人阶级发现他们在社会中处于不利地位,使得工人阶级与中产阶级间出现更严重的阶级分化。约翰·奥斯本在20世纪50年代末期的戏剧作品提及了如此的分化。负责教育的部门由教育委员会(Board of Education)更名为教育部(Ministry of Education),并给予它更大的权力与更多的预算,结束了国立学校需要交学费的时期。在将离校年龄提升至15岁后,它赋予了政府提升离校年龄至16岁的权力,“首相才刚刚因为它(将离校年龄提升至15岁)是切实可行的而感到满意”,虽然这个措施在1973年前仍未落实。法令也提供了社区学院(Community College),向儿童与成人提供教育,但措施只有少数地方教育局跟进,如剑桥郡。法案强制国家资助的学校每日进行祈祷。此条款被1988教育改革法令修订,法令指出祈祷大致上应在基督徒间进行,而不适用于特定学校或儿童。修订也指出,祈祷可以在课室进行,而不是在集会中进行。为了决定学童应该升读哪所学校,他们设立了一种被称为的考试。升学学童需要参加这个考试,分别到最适合他们“能力与兴趣”的学校,但是实际上,一些文法学校因为倾向于学术成绩所以仍未改革,而工业学校、综合学校只创办了几所。结果,不管是否合适,大部分学童升读现代中学,意味着大部分教育资助流入现代中学。\n\n### 文章 67\n\n中国人民解放军总政治部\n中国人民解放军总政治部,简称总政治部、总政,是中国人民解放军曾经存在的的政治工作机关,由中华人民共和国中央军事委员会领导。其前身是1930年创建的中共中央军委总政治部,1954年正式改称中国人民解放军总政治部。总政治部负责中国人民解放军的宣传、思想政治、青年、组织、纪律工作,并负责保卫及对外联络工作。总政治部与总参谋部、总后勤部、总装备部合称为四总部。2016年1月撤销,改组成立中央军事委员会政治工作部。中国人民解放军总政治部,可追溯于1930年创建的中共中央军委总政治部,1954年正式改名为”中国人民解放军总政治部”。1966年,文化大革命爆发,总政治部受到严重破坏。1967年7月25日,林彪和江青等人提出“彻底砸烂总政阎王殿”后,总政治部主任、副主任等领导干部都被关押、批斗和审查,总政治部机关陷于瘫痪。1967年11月,军委办事组政工组,取代了总政治部领导。1968年10月,对总政治部实行军事管制。1969年10月,开始重新组建总政治部。1969年12月,总政治部恢复办公。1977年,总政治部增设中国人民解放军军事法院和中国人民解放军军事检察院。1978年中共十一届三中全会以后,总政治部得到了恢复和发展。总政治部根据中央军委的决定,调整了机构:设组织部、干部部、宣传部、文化部、保卫部、联络部、群工部、军事检察院、军事法院和办公厅、直政部、管理局。1982年,总政治部的机构又作了精简,总政领导班子再次进行调整,总政办公厅改为总政办公室。1985年,总政管理局和直政部合并为直工部,总政办公室改为总政办公厅。2016年1月,在深化国防和军队改革中,总政治部改为中央军委政治工作部。以下是2016年中国人民解放军总政治部撤销时的机构设置:所有派出机关均接受双重领导中国人民解放军总政治部除使用军旗和军徽外,还拥有自己的臂章,于2007年启用。臂章呈盾形,绿地,绘有八一军旗、两把交叉的步枪与两支交叉橄榄枝的图案,并在上方写有“中国人民解放军总政治部”的字样。臂章主要佩戴在总政治部人员的常服的左臂上。\n\n### 文章 68\n\n海淀黄庄站\n海淀黄庄站位于中国北京市海淀区,是北京地铁4号线和10号线的一个换乘站。海淀黄庄站地处中关村大街与海淀南路-知春路相交路口下方。4号线车站沿中关村大街大致呈南北向布置,10号线车站沿海淀南路-知春路呈东西向布置,10号线在4号线上方通过,两线车站大致呈十字交叉。海淀黄庄站为地下车站,两线车站站台主体呈“十”字型岛–侧式相交形式,两线换乘采用“站厅+通道”双向通行方式。海淀黄庄站由地下二层构成,地下1层为4号线分离式站厅和10号线侧式站台,两者通过缓坡弧形通道连接;地下2层为10号线分离式站厅和4号线岛式站台。4号线换乘10号线需先由站台两端扶梯向上至站厅层,再由通道前往10号线站台;而10号线换乘4号线则反之,先由通道到达4号线站厅,再由扶梯向下至4号线站台。海淀黄庄站地下一层设有两个站厅,分别位于海淀黄庄路口南北两侧。北站厅南端、南站厅北端分别设有通往10号线外环、内环站台的换乘通道口。地下二层亦设有两个通往10号线车站的站厅,分别位于海淀黄庄路口东西两侧,乘客可在付费区内进行10号线内外环站台间的换向。海淀黄庄站10号线站台位于地下一层、海淀南路地下,为侧式站台,外环站台北侧、内环站台南侧设有换乘通道口。4号线站台位于地下二层、中关村大街地底,为岛式站台,南北两端设有通往站厅的楼梯、自动扶梯及升降电梯。海淀黄庄站有5个出入口:A1(西北)、A2(西北,连接新中关购物中心)、B(东北)、C(东南)、D(西南)。在西北角和东南角出入口各设有通地面的垂直电梯。在该站东南侧修建了两个紧急疏散通道。10号线车站装饰色调以白色为主;4号线车站装饰色调以黄色为主。\n\n### 文章 69\n\n巴黎古监狱\n巴黎古监狱(法语:"La Conciergerie")是巴黎昔日的王宫和监狱之一,位于巴黎市政厅以西,靠近巴黎圣母院。它是大型建筑群司法宫(Palais de Justice)的一部分。在法国大革命期间,许多囚犯从这里送往巴黎各处上断头台。西岱岛的西部曾是墨洛温王朝王宫的所在地;从10世纪到14世纪是中世纪法国国王的王宫。在路易九世(圣路易,1226-1270)和腓力四世(1284–1314)统治时期,墨洛温王朝的王宫得到了扩建,加强了防御功能。路易九世增建了皇家礼拜堂圣礼拜堂,而腓力四世增建了河边带塔楼的立面和一个大厅("Grande-Salle")。它们都是法国宗教和世俗建筑的精彩实例。大厅是当时欧洲最大的之一,其底层"La salle des gens"保存了下来:长64米,宽27米,高9米。它用作餐厅在1358年王室放弃了这座宫殿,迁移到对岸的卢浮宫。这座宫殿继续行使行政功能,包括总理和法国议会。1391年,这座建筑改为监狱,关押普通罪犯和政治犯。古监狱保存了3座中世纪的塔楼:凯撒塔,得名于古罗马皇帝;银塔,用作皇家珠宝店;在法国大革命最血腥的阶段恐怖统治时期,该监狱享有“断头台前厅”的国际声誉。此处设有革命法庭,关押着多达1200名男女囚犯。1793年4月2日到1795年5月31日之间,设在大厅的法庭将大约2600名囚犯送上了断头台。它的规则很简单。只有两种结果-宣布无罪或判处死刑-在大多数情况下是选择后者。最有名的囚犯(和受害者)包括王后玛丽·安托瓦内特、诗人安德烈·舍尼埃、夏绿蒂·科黛、夫人伊丽莎白公主、杜巴利伯爵夫人,被乔治·雅克·丹敦控诉的吉伦特派,然后是被罗伯斯庇尔控诉的乔治·雅克·丹敦,最后是罗伯斯庇尔自己受到控诉和处死。死刑犯前往囚车要穿过圣路易室,获得“注定室”("Salle des Perdus")的绰号。19世纪波旁王朝复辟以后,此处继续用作关押重要囚犯的监狱 — 最著名的是日后的拿破仑三世。玛丽·安托瓦内特的囚室改建为供奉她的礼拜堂。古监狱和司法宫在19世纪中叶进行了重建。虽然这座建筑看来像中世纪堡垒,其实主要完成于1858年。该监狱在1914年退役,作为国家历史遗迹向公众开放。今天这里是一个热门景点,但是只有一小部分向游客开放-大部分仍用于巴黎法院。\n\n### 文章 70\n\n全皇后 (孙亮)\n皇后全氏(),名或为惠解(清人薛福成则认定其名为惠解),吴郡钱塘(今浙江省杭州市)人,吴废帝孙亮之妻,曾被册立为皇后。《三国志》中称之为孙亮全夫人。全皇后之父全尚为吴国重臣全琮族子,按辈分全公主是他的堂伯母,全氏非常漂亮可爱,很得全公主的喜欢,每次进宫都要把她也带进去。后来全琮妻全公主曾构陷太子孙和母子,心中有所不安。孙和失宠后,全公主知道孙权特别留心幼子孙亮并想立他为皇太子。全公主私底下想预先趋附孙亮,便多次向孙权说起全尚女儿,劝孙权将全氏许配给孙亮为妃。赤乌十三年(250年),孙权改立孙亮为太子,全氏成为太子妃建兴元年(252年)四月,孙亮即位为帝。翌年春正月丙寅日(253年2月16日),立全妃为皇后,全皇后一族很受优待,全皇后父全尚因外戚身份,被任命为城门校尉,封都亭侯,后升为太常,拜卫将军,进封永平侯,录尚书事。全氏一族五人封侯,并且掌握有军队,被认为是自从吴国建立以来最显赫的一支外戚。太平二年(257年),孙亮开始新政,翌年与全尚、刘丞等人谋划诛杀权臣孙綝,结果被全皇后告发,反为孙綝所制。孙亮先后召全皇后及其兄弟全纪,痛斥二人之父全尚的无能致使事败,全纪羞愧自杀。孙綝废吴主孙亮为会稽王,改立孙休为帝。永安三年(260年),孙亮又被贬为侯官侯,于前往侯官(县治今福建省福州市)的途中自杀。全氏一族在吴国也迅速衰落。此后,全氏就一直居住在侯官,直至东吴灭亡后才回到家乡。后逝世于晋惠帝永宁年间(301年-302年)。孙亮与全尚、刘丞合谋诛杀孙綝一事,因被人提前向孙綝告密而失败。依《三国志》记载,告密者即为全皇后,但《江表传》记载为全尚妻孙氏。晋人孙盛认为《江表传》记录更为详细,赞同此说。《资治通鉴》也采用了《江表传》说法清人林国赞则提出针锋相对的意见,认为谋泄后,全尚一家仅全皇后未被流放,其他人都被逼杀,所以全皇后告密的可能性更大。近人卢弼也认为《三国志》内容前后对照,并无矛盾之处,不应采信《江表传》的说法。\n\n### 文章 71\n\n李重进\n李重进(),沧州(今河北省沧州市)人,生于太原,五代时后周禁军统帅之一,太祖郭威第四姊福庆长公主之子。李重进在后晋天福中,入仕为殿直。后汉初年,随舅舅郭威征讨于河中。后周建立的广顺元年(951年),太祖郭威以李重进为内殿直都知、领泗州刺史,女婿张永德为内殿直小底四班都知;又升李重进为小底都指挥使,而以张永德接任内殿直都知。翌年(952年),郭威以李重进为大内都点检兼马步都军头,张永德为小底第一军都指挥使;后又以李重进为殿前都指挥使,张永德为殿前都虞候,掌管殿前亲军。两年后,郭威病危,传位于发妻柴氏的侄子、养子柴荣,临终前特命李重进向柴荣行君臣之礼,以免其觊觎皇位。显德元年(954年),世宗柴荣即位,以姑表兄李重进为侍卫亲军马步军都虞侯,妹夫张永德接任殿前都指挥使,分掌侍卫亲军和殿前亲军。李重进、张永德本以姻亲之故,在数年间不次擢升,但后来都在战争中展现出过人的军事才能。在决定后周生死存亡的高平之战后,李重进以战功加使相衔,升侍卫亲军都指挥使,母福庆长公主追封燕国大长公主;而张永德以战功加检校太傅,授义成军节度使,妻寿安公主进封晋国长公主。北宋建隆元年(960年),宋太祖赵匡胤即位,加李重进为中书令,命令韩令坤代替李重进,将重进移镇至青州(治所在今山东省青州市),李重进拒绝调动,派遣幕僚翟守珣说服李筠起兵抗命,翟守珣却将此事泄露给宋太祖,于是太祖要求翟守珣拖延李重进出兵,以防止李重进与李筠南北呼应。翟守珣回去后,向重进诋毁李筠不足与谋事,重进果然中计,错失良机。李筠四月起兵反宋,六月兵败,自焚死。同年九月李重进起兵,十月,太祖亲征,带领石守信、王审琦、李处耘平叛,十一月,到达扬州城下,即日入城,李重进举家自焚。\n\n### 文章 72\n\n奥迪R8\n奥迪R8(Audi R8)是一款由奥迪公司于2006年生产的超级跑车。它的极速达330km/h,主要竞争对手包括法拉利F430、兰博基尼Gallardo、日产GT-R、梅赛德斯-奔驰SLS AMG和保时捷911。本车获日本消费者年度风云车和北美年度风云车的荣誉。作为奥迪量产的首款中置引擎超级跑车,奥迪R8融合了奥迪在多个运动赛事中取胜的经验、技术以及突破传统观念的设计完美的融合在一起。奥迪R8共享了兰博基尼Gallardo的开发平台,并使用了ASF高钢性车身结构,镁铝合金的创新组合和密闭的管状空心结构直接结合在一起,作为车体的主要承载架构。奥迪在R8上舍弃了传统避震器的阻尼油,改用了主动式电磁感应悬挂系统,一种随着电磁场改变粘稠度的特殊油液。奥迪R8配备了全LED头灯,此超高性能的灯体可产生类似日照的明亮白色光线;极限LED日间行车灯像细窄的带子一般,将头灯与下侧分隔开来,使得整车格外引人注目;Carbon Sigma炭纤维侧饰板不但达到了减轻车重的目的,更让车侧产生了强烈颜色对比的视觉效果;主动式电动扰流尾翼会在车速达到100km/h时自动伸展,并在车速下降至35km/h时自动收回;Bang&Olufsen音响系统通过12个扬声器达到环绕音效再现,并且总输出功率达到465W。奥迪R8最初只配备有4.2公升V8引擎,后来在2008年12月发布5.2公升V10引擎版,这个版本的R8使用了基于兰博基尼Gallardo LP560-4的5.2公升V10引擎。V10的R8测试时装上跟RS6一样的5.0公升V10双涡轮增压引擎,可是因为引擎冷却效能存在问题而烧毁,最终V10引擎的R8只能沿用自然吸气的工作方式。奥迪R8一度在德国房车赛中做为赛道安全车来使用。奥迪R8曾经出现在多部电影以及游戏中。\n\n### 文章 73\n\n舒尔补\n在线性代数与矩阵论中,一个矩阵的子矩阵之舒尔补是一个与其余子阵同样大小的矩阵,定义如下:假设一个 ("p"+"q")×("p"+"q")的矩阵"M"被分为"A", "B", "C", "D"四个部分,分别是"p"×"p"、"p"×"q"、"q"×"p"以及"q"×"q"的矩阵,也就是说:并且"D"是可逆的矩阵。则"D"在矩阵中的舒尔补是:这是一个"p"×"p"的矩阵。舒尔补得名于数学家伊赛·舒尔,后者用舒尔补来证明舒尔引理。然而,舒尔补的概念在之前就曾经被使用过。舒尔补实际上是对原来的矩阵"M"进行一系列的初等变换操作后得到的矩阵,其转换矩阵是下三角矩阵:其中"I"表示一个"p"×"p"的单位矩阵。矩阵"M"右乘转换矩阵"L"之后,左上角就会出现舒尔补,具体的形式是:因此,矩阵"M"的逆,如果存在的话,可以用formula_5以及其舒尔补(如果存在的话)来表示:当"p"和"q"都等于1(即"A"、"B"、"C"和"D"都是系数)时,我们可以得到一般的2 × 2的矩阵的逆矩阵表达式:这也说明了formula_9是非零的数。舒尔补很自然地可以在如下的方程组求解中发挥作用:其中"x"以及"a"是"p"维的列向量,而"y"以及"b"则是"q"维的列向量。矩阵"A"、"B"、"C"、"D"则同上面假设。将第二个方程左乘上矩阵formula_12,并将得到后的方程与第一个相减,就得到:因此,如果可以知道"D"以及"D"的舒尔补的逆矩阵,就可以解出未知量"x"之后带入第二个方程formula_11就可以解出"y"。这样,就将formula_15矩阵的求逆问题转化成了分别求解一个"p"×"p"矩阵以及一个 "q"×"q"矩阵的逆矩阵的问题。这样就大大减低了复杂度(计算量)。实际上,这要求矩阵"D"满足足够好的条件,以使得算法得以成立。假设有分别属于R以及R的随机列向量"X", "Y" ,并且R中的向量对 ("X", "Y")具有多维正态分布,其方差矩阵是对称的正定矩阵那么"X"在"Y"给定时的条件方差是矩阵"C"在"V"中的舒尔补:\n\n### 文章 74\n\n劝业会场\n劝业会场始建于清光绪三十三年(1907年)五月,是中国天津历史上一座系统陈列工业工艺产品的场所,位于今天的河北区中山路中段东南侧,现为中山公园,原劝业会场大部分建筑已不复存在。清光绪二十八年(1902年)七月十二日,新任直隶总督兼北洋大臣袁世凯从天津都统衙门手中接回天津统治权并在海防公所(今金钢公园一带)建立直隶总督新署。清光绪三十一年(1905年)五月,袁世凯开始在北起大经路(今河北区中山路),南至金钟河(现今已被填平),东临昆纬路,西靠近北洋造币总厂的土地上建设一座占地两百余亩的综合性园林游乐场并将其命名为“劝业会场”。劝业会场作为当时中国最早系统陈列工业工艺产品的场所经常展览书画名家作品,清光绪三十一年(1905年)10月7日至10月14日,劝业会场举办了首届天津劝业展览会,到场观众约有15万人次,交易金额约为3万余元。1912年,劝业会场更名为“天津公园”,后又改称为“河北公园”。1920年冬,北京中国画学研究会在劝业会场的商业会议厅举办“中国南北方重要画家大展”,徐世昌、陈师曾、齐白石、吴昌硕、任伯年以及渡边晨亩、山田敬中、胜田焦琴、荒木十亩等的作品也同时展出。1928年北伐胜利后,为纪念孙中山,又更名为“中山公园”,今天天津中山公园的占地面积只为当年劝业会场占地面积的三分之一。劝业会场分为三个部分,分为商务区、公园区。其中,商务区设有前门两侧的平房店铺,公园区位于过街钟楼后面,公园区后侧还建有商品陈列馆、省立图书馆和咨议局大楼。劝业会场内的游乐设施有荷花池、月牙池、鹤亭、鹿亭、八角音乐亭和抛球房等,商业和办公设施建有劝工陈列所、教育品制造所、学办处、办公洋楼和茶房等。\n\n### 文章 75\n\n阎振兴\n阎振兴(,,字光夏,河南汝南人,中华民国政治人物、水利学家。曾任国立台湾大学校长,在其任内,发生台大哲学系事件。在美国爱荷华大学取得工学博士学位,曾在黄河流域做过河川水利工作,1947年出任河南大学教授兼工学院院长。1949年随政府到台湾,在高雄港务局做总工程师,1957年出任台湾省立成功大学教授兼校长,1962年转任台湾省政府教育厅厅长,担任教育部部长期间宣布推动九年国教。曾任行政院青年辅导委员会主任委员、行政院国家科学委员会副主任委员、行政院原子能委员会主任委员、中山科学研究院院长、国立清华大学校长、国立台湾大学校长、总统府国策顾问、总统府资政。行政院原子能委员会主任委员任内发生辐射屋事件。1977年4月10日,阎振兴与第二任妻子严淑莲结婚。2005年1月7日,阎振兴因呼吸衰竭在台大医院病逝,享年94岁。24日,阎振兴追思会在台大医院景福会馆举行,总统陈水扁及副总统吕秀莲到场颁挽额「学渊绩懋」及「硕望清徽」;前后任台大校长如陈维昭、虞兆中,前财政部长陆润康也到场致辞。台大交响乐团同学彭靖如、盛维安、王年恺献奏送别与骊歌表达哀思。1970年5月7日,行政院会通过清华大学校长阎振兴调任台湾大学校长,6月1日11时举行交接典礼,接任台大校长。阎振兴于上任后在硬体方面设立了工业研究中心(1975);制度方面于夜间部增设了历史系(1971)、中文系(1972),成立台大校讯社、侨生及外籍学生辅导室(1973),实施电子计算机注册选课(1976)以及校园规画委员会的设置(1978)。阎振兴任内开创与中研院合作的管道。阎振兴于台大哲学系事件时为了熄灭学运风潮而消极处理,危害校园学术自由的传统。台大哲学系事件调查小组召集人柯庆明教授表示:「……当时的台大校长阎振兴在处理过程中,知道许多人是被陷害,但却为灭学运而任由当时代理系主任孙智燊整肃无辜的教师,对大学自主与学术尊严也是一大伤害。」1981年8月1日,阎振兴卸任,由担任过工学院院长的虞兆中接任。\n\n### 文章 76\n\n八斗子渔港\n八斗子渔港()位于台湾基隆市中正区的八斗子,是一座多功能的渔港,也是台湾北部最大的渔港。依《渔港法》分类,其渔港等级为第一类渔港,主管机关为农委会渔业署。八斗子渔港位处八斗子半岛西南侧与台湾本岛间,基隆港东南岸2.5浬处的岩岸岬角,行政区分上隶属基隆市中正区。原为天然海湾,三面环山,西北通海,水域深广,潮差温和,又少漂沙,港口宽度60公尺,航道水深6至18公尺, 条件优良,而附近海域渔获丰富,早期就已经是当地人生活中不可缺乏的食物来源,更是成为渔港的重要条件,为一岩岸岬角之天然良港。1974年当时的行政院长蒋经国任内巡视基隆市时,希望配合基隆地区渔业的快速发展,为解决当时基隆市唯一的大型渔港正滨渔港(位于基隆港内)渔船使用地不足的拥挤问题,于是决定在八斗子兴建大型渔港,并计划以此新渔港取代正滨渔港的功能,以扩大基隆港的商港用地(但日后并未执行)。1975年正式动工兴建,兴建时八斗子煤矿全面停采,到1979年兴建完成。八斗子渔港历经多年的整修后,现今各项公共设施齐全,已成为台湾北部地区最大的渔港。八斗子渔港的兴建不仅提供基隆地区渔业生存空间,也促进了相关工商业的引进及蓬勃发展,更成为基隆市重要的旅游景点,每逢假日吸引大量外地游客前往。为了因应民众假日休闲游憩的需要,基隆市政府所成立的管理所利用渔港的第二泊区陆路地范围,设置休闲绿带成为滨海公园。八斗子渔港面对太平洋,受东北季风直接吹袭,其强度对渔港作业有极大影响,每年9月至翌年5月,多为北北东风,6月至8月多为西南风。八斗子地区的渔业以沿、近海为主,主要渔获物有以下几种:八斗子地区常用的渔法\n\n### 文章 77\n\n约瑟夫·道尔顿·胡克\n约瑟夫·道尔顿·胡克爵士,OM,GCSI,CB,MD,FRS(,)是英国植物学家。胡克出生于萨福克郡的哈尔沃斯镇,他的父亲威廉·杰克逊·胡克也是著名的植物学家,从7岁时他就经常到格拉斯哥大学听他父亲作为植物学教授的讲课,他很早就对植物的地理分布和库克船长的探险感兴趣,他从格拉斯哥中学毕业后就到格拉斯哥大学学习医学,1839年,获得医学博士学位,因此可以作为海军军医参加罗斯船长到南极的探险,并成为厄瑞玻斯号战舰上的助理外科医生。他是128名船员中最年轻的,探险从1839年9月30日船只起航,经过马德拉、特内里费岛、圣地牙哥岛、巴西东海岸、圣赫勒拿岛和好望角,沿途他采集了许多动物和植物以及藻类和海洋生物的标本,在南极岛屿,他确认了18种被子植物、35种苔藓、25种地衣和51种藻类新种, 经过5个月的旅行,后来他们到了悉尼和新西兰,然后又转向南极海域,经过138天航行,到了马尔维纳斯群岛和火地群岛,第三次转向南极海域,最后经阿森松岛于1843年9月4日回到英国。由于他争取在爱丁堡大学的职位没有成功,他拒绝了格拉斯哥大学的邀请,于1846年参加了在大不列颠的地理考察工作,研究古生物化石,寻找在威尔士的煤矿床中的化石,1847年,他父亲帮助他申请得到去印度为皇家植物园搜寻植物新品种的工作,当时他父亲已经是皇家植物园的园长,帮助他获得1000英镑的资助出版他的著作《南极探险的植物》,并获得每年200英镑工作资助,他陆续出版了《南极植物》("Flora Antarctica" (1844–47))、《新西兰植物》( "Flora Novae-Zelandiae" (1851–53))和《塔斯马尼亚植物》("Flora Tasmaniae" (1853–59))。1847年11月11日,他离开英国前往印度,他乘船竟尼罗河、苏伊士运河于1848年1月12日到达加尔各答,骑着象到米尔扎布尔,再乘船沿恒河到达西里古里,改骑马于1848年4月16日到达大吉岭。他以大吉岭为基地,考察了喜马拉雅山区的植物,曾到过锡金、尼泊尔、孟加拉和西藏 ,1850年1月和2月,他回到大吉岭,整理标本和写日记,然后又到不丹和阿萨姆邦,1850年12月9日起程回国。他在加尔各答出版了《喜马拉雅山日记》("Himalayan Journals")。\n\n### 文章 78\n\n兔子四部曲\n兔子四部曲,是美国作家约翰·厄普代克的作品。1960年厄普代克出版《兔子,快跑》(Rabbit, Run),书以「兔子」哈利·安斯特朗(Harry \'Rabbit\' Angstrom)为主角,是一个二十六岁的年轻人,长得又高又帅,这位兔子有些自恋又脆弱,高中时曾是学校中的篮球明星,曾破纪录投篮得分62分,他的妻子Janice大他两岁,酗酒、不理家事,育有一子Nelson,一女。他结交了篮球教练介绍的妓女Ruth,不久Ruth怀孕,妻子淹死女婴,兔子不知所措,于是匆忙逃走了。1971年厄普代克继续创作有《兔子归来》(Rabbit Redux), 描写1969年7月16日兔子回家后,成为了一个产业工人,妻子Janice跟情人同居,他接连遇上种族对峙、性革命、反文化运动等,兔子还收留了黑人逃犯斯基特。1981年又发表《兔子富了》(Rabbit Is Rich),故事是兔子继承了岳父的日本汽车事业,经济开始富裕,兔子加入乡村俱乐部、打高尔夫球、到加勒比海度假。1990年发表的《兔子安息》(Rabbit at Rest)写兔子年老病患,岛田先生(Mr. Shimada)非常不满意兔子的作为,兔子用心倾听日本老板的严厉批评,儿媳妇Pru因为长期闺房失和,晚上主动要求和他上床,Pru从睡袍口袋里掏出保险套,两度达到性高潮,兔子在事发之后离家出走,前往佛罗里达州,在篮球场试图重温当年风采时,结果因心脏病发作去世。兔子四部曲记录了美国自二战后40年来的社会历史的全貌,描绘出了一幅中产阶级的历史画卷,这些白领阶级有点铁石心肠,共塑造了约一百五十个大小不等的鲜活人物,内容涉及越南战争、登陆月球、女权运动、能源危机,有人称之为「美国断代史」。2000年,厄普代克又写了一部182页的中篇小说《兔子回忆》(“Rabbit Remembered”),交代兔子去世的后续情节,Pru跟Nelson离了婚,带着孩子回Ohio,兔子Ruth所生的女儿Annabelle以护士的身份出现,Nelson看著她想到自己的妹妹,大家共进感恩节晚餐,却因政治话题吵架收场。“兔子”的骨灰罐遗留在一家汽车旅馆的橱架里。本篇故事收录短篇小说集《Licks of Love》,有人说这是第五部曲,亦有人批评是狗尾续貂。\n\n### 文章 79\n\n复健\n复健医疗,是针对身体失能者,所延伸出来的医疗方式。最早见于美国1910年代后,当时世界历经两次世界大战,产生许多伤兵,为了协助伤兵因战争导致的身体失能,利用残余肢体功能,发挥最大效能,借以提升生活自理能力为目标。不过,由于身体失能的情况,致残因素甚多,随著时代演进,各领域的治疗师也日益细分。复健的执行者常常是物理治疗师,职能治疗师,语言治疗师,但治疗师与复健科医师并不同,民众容易因名称相近而混淆;后者为一种专科医师,其医师身分得以合法独立负责该专科的疾病诊断、开立药物、开立复健处方等医疗业务,而复健处方将转介给物理、职能,语言治疗师,病患即开始接受复健之治疗。复健医学专科帮助病人的过程,常常需要团队合作,比如:复健科医师、职能治疗师、物理治疗师、甚至社工人员、神经内外科医师、骨科医师、精神科医师、小儿科医师、耳鼻喉科医师、护理人员、社工人员远距复健,是否为传统复健的延伸,抑或全新的复健领域,目前就执行的内容不同,导致见解不同。本质上为因应高龄化浪潮,偏乡的临床资源不足,以及就医的交通往返不便所延伸而出的专门项目。目的在让居家的病患在宅即能自主的进行复健所需的治疗以及诊断,而不花费额外的临床人员劳力时间,远端的治疗师或医师仅针对复健成效,提供评估与后续的疗程建议。而远距复健进行的方式,可以分为远距侦测、远距咨询、远距治疗、远距指引。相较于一般远距医学,介入强度较低,而施行时间较长。在台湾现有的施行方法,以月租的方式,租赁体感复健设备,借由软体化的训练疗程,让病患在家中即可根据复健设备所建构的虚拟实境训练内容,达成能力的提升与评估效果,有效的在患者居家或周遭机构,达成自主性的复健目的,大幅减少交通往返的时间与金钱成本,消弥城乡医疗资源差距。\n\n### 文章 80\n\n布龙齐诺\n布龙齐诺 Bronzino()全名阿纽洛·迪·科西莫"Agnolo di Cosimo",也称尼奥洛·布龙齐诺。是意大利佛罗伦萨的风格主义画家。布龙齐诺这个昵称的来历已不可考,但是应该和他黝黑的肤色或者他常用的肖像画主题有关。现代医学有研究证明他的肤色可能是来自爱迪生氏病,因为肾上腺功能不足导致皮肤上的色素沉积。1503生于佛罗伦萨。根据他同时代的乔尔乔·瓦萨里,布龙齐诺是蓬托莫的学徒,并且他的画风受了他老师的很多影响。布龙齐诺也是一位出色的肖像画家,在大部分职业生涯里,充任美第奇家族的宫廷画家。1563年参与创建绘画学院。布龙齐诺出生于佛罗伦萨的一个屠户家。按照他同时代的乔尔乔·瓦萨里的说法,布龙齐诺最先从师于Raffaellino del Garbo, 14岁以后跟着蓬托莫学习绘画。蓬托莫曾把年幼的布龙齐诺画入他的一系列"旧约圣经中的约瑟"(Joseph (Hebrew Bible)|Joseph in Egypt) 肖像画作品中,这些作品现今珍藏在伦敦国家美术馆 。他的画风受了他老师的很多影响,对他老师的一生而言,两人一直相互合作。在佛罗伦萨阿诺河老桥边的Santa Felicita教堂的小礼堂里,我们时常可以看到布龙齐诺的早期手迹。礼堂内室、祭坛大作 Deposition from the Cross 和侧墙湿壁画"Annunciation"是由蓬托莫完成的。很显然,布龙齐诺被安排了创作穹顶湿壁画的任务,令人惋惜的是,这些作品并没有幸存下来。据乔尔乔·瓦萨里,其中四幅圆形福音绘画是由布龙齐诺完成的。然而由于他的技巧和他导师的是如此相似,至今学者们仍在为此争辩不止。在他生命的最后阶段,布龙齐诺投身于佛罗伦萨Accademia delle Arti del Disegno的诸多活动中,他是这家学院的创办人之一。画家Alessandro Allori 是他最喜爱的徒弟,公元1572年布龙齐诺过世年间,他是和Allori一家住在一起的(Alessandro是Cristofano Allori的父亲) 。布龙齐诺一生大部分时光是在佛罗伦萨度过的。\n\n### 文章 81\n\n冉广岐\n冉广岐,因“唐山地震青龙县无人因震伤亡事件”为人所知,但是真实性存争议。冉广岐,1976年时任中国河北省秦皇岛市青龙县县长。冉广岐在1976年7月28日唐山大地震发生前夕,下令全县所有人疏散,令该县在地震发生时,没有任何人因地震死亡。1975年海城地震发生后,京、津、唐地区受到地震预报有关部门监视,并一直持续到唐山地震发生之前。中国政府最终没有得到来自国家地震局方面提供的短期地震预报(有消息称早在大地震爆发前半个月,国家地震局分析预报组就已经预测出7月22日到8月5日。然而主持「全国地震预防工作经验交流会」的国家地震局副局长却不准时任京津组组长的汪成民在会上作震情发言。汪成民在17、18日的晚间座谈的时候和部分同志讲述了京津渤张地区集中出现的异常现象,并预测「7月22日到8月5日,唐山、滦县一带可能发生5级以上地震。现场只有22岁的青龙县科委主管地震工作的人员王春青听完汪的讲话后,他火速赶回县里,将汪的讲话告诉了县领导冉广岐,在深思熟虑之后,命令全县800多名干部迅速将震情通知到全县每一个人,经过周密部署,全县近40万人进入临震状态)。而唐山市最终对此地震没有积极预防。河北省青龙县在全县范围内采取了预防措施,取得了令人瞩目的防震减灾效果。全县无一人直接因地震丧生,仅一人因心脏病突发死亡。冉回答说,“唐山跟青龙没法比。青龙是农业县,让老百姓出去防震,啥损失也没有。大伏天的也就是蚊子多叮几个疙瘩呗。唐山不同啊,钢铁公司、开滦煤矿,作决策的人自己不敢作主”在百度青龙县贴吧里,当地大多数老百姓否认冉广岐的这些新闻,具体信息请阅读下面的网址:http://blog.sciencenet.cn/blog-647503-596797.html从当地人的地震记忆里看,冉广岐救人可能是一个恶意的假新闻典型。\n\n### 文章 82\n\n东山文化 (越南)\n东山文化()是位于越南北部红河河谷的一个铁器时代史前文化。它约繁盛于公元前700年到公元前后,它影响的区域包括东南亚其他地区乃至以及印度-马来亚群岛。古东山人具有熟练的稻米栽培技术和水牛、猪等动物的饲养技术,使用长独木舟进行航行和渔猎。东山文化最突出的文化遗产是东山铜鼓等青铜器制品,它们在东南亚和今中国南部的广大地区都有发现。越南北部在公元前几千年就已经产生了新石器时代史前文化。该地区的地理气候使得大规模的农业和畜牧业发展成为可能,并为东山文化的产生和发展创造了条件。东山文化并非独立产生,它与藏缅语系民族、傣族、孟-高棉南亚语系民族以及老挝的查尔平原的古文化均存在联系。东山文化的核心位于越南北部的红河河谷,但它与周边地区维持着紧密的商业关系,以铜鼓作为主要商品,其商品出口范围包括东南亚的大部分地区和印度尼西亚。从大约公元前1000年开始,东山文化成为东南亚最早进入铜器时代的古代文明,在东山文化的古代墓葬中曾发现了铜鼓等物品。东山铜鼓使用失蜡法铸造,其高度最高可达1米,重量最重可达100千克。东山铜鼓被作为宗教仪式用品和音乐器具,通常刻有几何图形、日常生活、战争、动物、鸟类以及船只的形象。其中的船只形象表明了贸易在东山文化中的重要性,而铜鼓本身也被作为贸易物品和家传宝物。在当地原始文化中,拥有这些铜鼓即意味着拥有掌控万物运转的力量,也表明了富有的家庭有能力支付那些大型铜鼓的制造。在作战时铜鼓被用力击打,产生的巨大声音可以吓退敌人。东山铜鼓分布十分广泛,它们在今中国南部、越南、以至印度尼西亚东部都有发现。对于东山文化衰落的原因并无确切定论。可能与气候环境的改变、由于农业活动造成当地生态环境的恶化、外族入侵、周边地区的政治环境变化等多种因素有关。在大约公元后200年,东山文化已经全面衰落。当地人在很大程度上已经忘却了东山文化的存在,他们将东山铜鼓的铸造归于某些神话人物或民间传说中的英雄。但是作为越南历史上最重要的古代文化之一,其科技文化成就对越南文明的发展产生了深远影响。\n\n### 文章 83\n\n八斗子渔港\n八斗子渔港()位于台湾基隆市中正区的八斗子,是一座多功能的渔港,也是台湾北部最大的渔港。依《渔港法》分类,其渔港等级为第一类渔港,主管机关为农委会渔业署。八斗子渔港位处八斗子半岛西南侧与台湾本岛间,基隆港东南岸2.5浬处的岩岸岬角,行政区分上隶属基隆市中正区。原为天然海湾,三面环山,西北通海,水域深广,潮差温和,又少漂沙,港口宽度60公尺,航道水深6至18公尺, 条件优良,而附近海域渔获丰富,早期就已经是当地人生活中不可缺乏的食物来源,更是成为渔港的重要条件,为一岩岸岬角之天然良港。1974年当时的行政院长蒋经国任内巡视基隆市时,希望配合基隆地区渔业的快速发展,为解决当时基隆市唯一的大型渔港正滨渔港(位于基隆港内)渔船使用地不足的拥挤问题,于是决定在八斗子兴建大型渔港,并计划以此新渔港取代正滨渔港的功能,以扩大基隆港的商港用地(但日后并未执行)。1975年正式动工兴建,兴建时八斗子煤矿全面停采,到1979年兴建完成。八斗子渔港历经多年的整修后,现今各项公共设施齐全,已成为台湾北部地区最大的渔港。八斗子渔港的兴建不仅提供基隆地区渔业生存空间,也促进了相关工商业的引进及蓬勃发展,更成为基隆市重要的旅游景点,每逢假日吸引大量外地游客前往。为了因应民众假日休闲游憩的需要,基隆市政府所成立的管理所利用渔港的第二泊区陆路地范围,设置休闲绿带成为滨海公园。八斗子渔港面对太平洋,受东北季风直接吹袭,其强度对渔港作业有极大影响,每年9月至翌年5月,多为北北东风,6月至8月多为西南风。八斗子地区的渔业以沿、近海为主,主要渔获物有以下几种:八斗子地区常用的渔法\n\n### 文章 84\n\n初等阿贝尔群\n在群论中,初等阿贝尔群是有限阿贝尔群,这里的所有非平凡元素都有 "p" 阶而 "p" 是素数。通过有限生成阿贝尔群的分类,所有初等阿贝尔群必定有如下形式对于非负整数 "n"。这里的 "Z/pZ" 指示 "p" 阶的循环群(或等价的整数模以 "p"),而幂符号表示意味著 "n" 元笛卡尔积。假设 "V" = ("Z"/"pZ") 是初等阿贝尔群。因为 "Z"/"pZ" formula_1 "F",即 "p" 个元素的有限域,我们有 "V" = ("Z"/"pZ") formula_1 "F",所以 "V" 可以被认为是在域 "F" 上的 "n"-维向量空间。机警的读者可能发现 F 有比群 "V" 更大的结构,特别是它除了(向量/群)加法之外还有标量乘法。但是 "V" 作为阿贝尔群有唯一一个 "Z"-模结构,这里的 "Z" 的作用对应于重复的加法,而这个 "Z"-模结构一致于 "F" 标量乘法。就是说,"c"·"g" = "g"\xa0+\xa0"g"\xa0+\xa0...\xa0+\xa0"g" ("c" 次) 这里的 "c" 在 "F" 中(考虑为整数带有 0\xa0≤\xa0"c"\xa0<\xa0"p") 给予 "V" 一个自然的 "F"-模结构。作为向量空间 "V" 有如例子中那样的基 {"e", ..., "e"}。如果我们选取 {"v", ..., "v"} 为任何 "V" 的 "n" 个元素,则通过线性代数我们有映射 "T"("e") = "v" 唯一扩张为 V 的线性变换。每个这种 T 都可以被认为是从 "V" 到 "V" 的群同态(自同态)并同 "V" 的任何自同态一样可以被认为是 "V" 作为向量空间的线性变换。如果我们限制注意力于 "V" 的自同构,我们有 Aut("V") = { "T" : "V" -> "V" | ker "T" = 0 } = GL("F"),即在 F 上的 "n" ×"n" 可逆矩阵的一般线性群。\n\n### 文章 85\n\n猫哭症\n猫叫综合症(,也称猫哭症、猫啼症)——又称5号染色体短臂缺失症候群()——是一种由于第五号染色体短臂缺损而引起的罕见基因异常病症。患病婴儿的哭声特别,似猫啼,因而得名;其英文名称系借自法语,意即「猫哭」或「猫叫」。1963年Jérôme Lejeune首次在文献中报告该病,该疾病因而又称Lejeune症候群。每年出生的活产婴儿中,约每两万至五万名新生儿之中有一人患有此症。此症可发生于任何族裔,男女比例约为3:4。因为婴儿的喉头和神经系统异常,所以患有此症的婴儿会发生猫啼般的哭声,大约三分之一的患儿在两岁之后就不会再发出这种哭声,除此之外,猫哭症还有以下症状﹕其他常见症状包括低肌肉张力、小脑症、发育不良、圆脸、胀面颊、小下巴、两眼过份分离、内眦赘皮、上眼线下钭、斜视、扁鼻梁、嘴角下垂、低耳、短手指、断掌、先天性心脏病(例如﹕心室间隔缺损、心房间隔缺损、动脉导管未闭、法乐氏四联症),但患有猫哭症的人,其生育能力则不受影响。较少见的症状包括兔唇、颚裂、耳边有瘘管、胸腺发育不良、肠道转位不全、巨结肠、腹股沟疝、髋关节脱臼、隐睾症、尿道下裂、罕见肾脏畸形(例如﹕马蹄形肾脏、肾脏异位、发育不全、肾积水)、尾指内弯、马蹄形内翻足、扁平足、第二及第三只手指和脚趾连趾、可过度伸展的关节等在较年长的小朋友和青少年的身上,患者会表现出明显的智力不全、小脑症、脸部特征变得粗鲁、突出的眼眉骨、深陷的眼睛、扁鼻梁、严重的咬合不正、脊椎侧弯。受影响的女性患者会踏入青春期,第二性征、月经会如常出现,生殖器官正常,但曾发现心型的子宫。受影响男性的睾丸通常会比较细小,但可正常制造精子。猫哭症是因为第五号染色体部份缺损,亦叫做5p单倍体,大约九成的问题基因都是由突变形成的,其余的问题基因是由于父或母一方的两条第五色体连在一起,令受影响的婴儿成为5p染色体三倍体(trisomy),这些婴儿通常会有较严重的病症和病状。诊断主要根据受影响婴儿特有的哭声和其他症状,受影响的家庭可以接受基因咨询和基因测试。患有猫哭症的儿童可以接受言语治疗、声音治疗和职业治疗,如有先天性心脏缺陷,则通常需要接受手术。\n\n### 文章 86\n\n分析机\n分析机是由英国数学家查尔斯·巴贝奇设计的一种机械式通用计算机。从1837年首次提出这种机器的设计,一直到他去世的1871年,由于种种原因,这种机器并没有被真正的制造出来。但它本身的设计逻辑却十分先进,是大约100年后电子通用计算机的先驱。查尔斯·巴贝奇最初尝试的所谓差分机,可以通过求解差分来计算对数表和三角函数表,然后能近似计算多项式。由于巴贝奇与他的首席工程师起了争执,英国政府就撤回了这项项目的资金,差分机也因此没能完成。在这期间,巴贝奇意识到建造一种更加通用的机器(即所谓的分析机)是可行的,于是便于1833年开始了分析机的设计。分析机由蒸汽机驱动,大约有30米长、10米宽。它的输入由程序和数据组成,并使用打孔卡输入,这种输入方法被当时的织布机广泛采用。分析机通过一台打印机、一个弯曲的绘图仪和一个铃铛输出,也可以在纸上打孔以便日后读取。分析机采取普通的十进制定点计数法。它的“记忆体”大约可以存储1000个40位的十进制数(每个数约16.2kB)。有一个算术逻辑单元可以进行四则运算、比较和求平方根操作。刚开始研制的时候,分析机的外观被普遍认为和差分机相似 。1858年的图纸呈现了一个有规律的网格布局。与现代计算机的中央处理器(CPU)类似,其算术逻辑单元使用的微程序存储在插在被称为“桶”的滚筒上的支柱中,这为用户指定更加复杂的运算提供了便利。分析机使用的编程语言与今天的汇编语言类似,支持循环语句和条件分支,因此这门语言被认为是图灵完备的。分析机采用三种不同的打孔卡和读卡器来区分算术运算、数字常量和存储的指令,以此实现了数字在存储器和运算单元之间的加载和存储操作。巴比奇在1837至1840年间写下了24份程序,并在之后又写了一份。这些程序可以计算多项式、迭代公式、高斯消去法和伯努利数。\n\n### 文章 87\n\n次磷酸\n次磷酸(化学式:HPO)是一种磷的含氧酸,也是一种很强的还原剂。无色、低熔点的晶体,易过冷成粘稠液体,可溶于水、二恶烷和乙醇。虽然次磷酸可以表示为HPO,但更准确的表示式为HOP(O)H,突出了其作为一元酸的特点。HOP(O)H(次磷酸)中会含有少量的它的互变异构体HP(OH),并保持一定的平衡。这种次要的互变异构体的IUPAC名称为“hypophosphorous acid”,有机衍生物称“亚膦酸”。次磷酸被烃基取代后,形成的衍生物HO(O)P(R)R\'称为次膦酸。次磷酸盐可由白磷与热碱溶液反应制得。工业一般多用石灰浆(氢氧化钙)作碱,实验室则用氢氧化钡溶液与白磷反应。反应后通二氧化碳除去过量的碱,再过滤、蒸馏、浓缩便得到金属的次磷酸盐。次磷酸盐经酸化得到次磷酸。次磷酸钙与硫酸、草酸反应,或次磷酸钡与硫酸反应后过滤,并用乙醚萃取,都可得到较纯的次磷酸溶液。除此之外,在弱酸性介质中,用磷化氢与碘反应也可以得到次磷酸。一般次磷酸以50%水溶液的形式出售。在有机化学中,次磷酸可以将芳香重氮盐Ar-N还原为芳香烃Ar-H。将此反应与芳烃的硝化、硝基的还原及重氮化反应联用,可以先向芳环上引入氨基,借助氨基的定位效应,将某个基团引入到芳环的某个位置上去。然后再通过重氮化-还原把氨基除去。水合次磷酸钠在工业上用作还原剂,尤其是用于在金属、非金属和塑料表面化学镀镍。表面镍层一般为无定形或含10%左右磷的金属镍。加热时可以产生NiP从而使镀层硬度增强。除次磷酸盐外,镀液还包含氯化镍(或硫酸镍)、乳酸(配位剂)、苹果酸盐或琥珀酸盐(加速沉积)及铅盐(稳定剂)。次磷酸可以将碘还原为氢碘酸,而氢碘酸又可以将麻黄碱或伪麻黄碱还原为甲基苯丙胺,也就是所说的冰毒。因此,次磷酸/次磷酸盐被美国司法部缉毒署列为第一类易制毒化学品,购买及使用受到严格管制。 中国大陆易制毒化学品的分类和品种目录中不包含次磷酸及次磷酸盐,但“麻黄素、伪麻黄素、消旋麻黄素、去甲麻黄素、甲基麻黄素、麻黄浸膏、麻黄浸膏粉等麻黄素类物质”都在列。这些都被定为第一类易制毒化学品,受到严格管制。\n\n### 文章 88\n\n电磁感应透明\n电磁波引发透明(,EIT),一般是用两束光同时照射到原子介质(如大量原子组成的气体),使得其中一束光能够在与原子跃迁共振时通过原子介质而不产生吸收和反射的现象。观测 EIT 需要两种相干光源(例如 激光)和介质(一般为原子气体,如Rb85,Rb87)的三种 量子态. 两种相干光源分别称为"探测光"和"耦合光",通常耦合光数十倍强于探测光。置"耦合光"频率恰等于|2>和|3>能级差,调节"探测光"的频率于|1>和|2>能级差自然衰减的数倍左右.EIT 是基于跃迁光在原子能级之间破坏性的相干,和相干原子数量陷阱 (CPT) 现象紧密相连.第一种理论: 将 密度矩阵图像处理二能级系统Rabi 振荡 扩展到三能级. 在此图像下, 概率幅 在不同路径(态与态之间的跃迁)之间的 干涉 而变小, 阻止探测光被吸收. 这里, "干涉" 指的是 "量子事件" (跃迁) 之间的干涉,绝对不是光学干涉. 举例, 考虑 lambda 能级的情形. 探测光的吸收定义为 formula_1到 formula_2的跃迁. 光场可以驱动原子直接从 formula_1-formula_2 或者从formula_1-formula_2-formula_7-formula_2. 不同路径的概率波幅互损. 如果 formula_7 有较长的寿命(衰变常数),则透明窗口位于 formula_1-formula_2 吸收线内部.第二种理论:"穿戴态"图像, 原子能级系统 + 耦合光场 Hamiltonian 对角化且各个态的概率计算建立在新的态下. 在此图像下, EIT 如同Autler-Townes 分裂和穿戴态之间的Fano 干涉的结合. 双峰之间,透明窗户的中心,利用探测光跃迁的概率波幅相互抵消.第三种理论: 极化声子 图像 在慢化光的方面具有重要作用. 这里, 探测光的光子 同步地传输到"黑暗态声子",同时也是原子的激发态. 这些"激子"存在的时间长度只跟态的衰变常数有光.\n\n### 文章 89\n\n大沙地站\n大沙地站()是广州地铁五号线的车站,位于黄埔区大沙地西路港湾路口西侧的地底,邻近黄埔区公安分局、大沙购物城、黄埔商业城等。该站于2009年12月28日启用。本站共两层。地面为港湾路、大沙地西路以及其它建筑;地下一层为站厅层;地下二层为5号线月台。为方便行人进出,大沙地站厅中心南侧被划分为收费区,四周被行人通道以及车站商店包围。站厅收费区设有多组专用电梯(升降机)、扶手电梯以及楼梯供乘客来往月台层。车站商店及自助服务方面,大沙地站设有便利店、面包糕饼店以及洗衣店。亦设有招商银行自动柜员机以及自动售卖机;车站内亦设有“好易”机,可充值羊城通,缴纳水电费以及交通罚款等服务,“M-Touch”机,可查询地铁线路、首末班车等资讯以及地铁安全指引的查询,更亦供乘客登记为广州地铁荟会员、查阅奖分、换领奖赏。大沙地站设有一个岛式月台,位于大沙地西路地底。大沙地站目前设有两个出入口。大沙地站是5号线的一个中途站,乘客可以乘搭往滘口或文冲列车,来往广州火车站、珠江新城、荔湾区、越秀区、天河区、黄埔区各地。大沙地站附近有多个住宅小区;附近亦有多所中小学校,以及下沙村和较大规模的横沙村,但现时该地区的城中村正在进行改造当中。由于车站全天客流量加上附近的巴士站有多条前往开发区、黄埔区周边以及萝岗区一带等地的巴士线路,因此亦吸引部分东区以及科学城上班的的乘客在此接驳巴士前往上述地区,因此本站平日客流量较大,早晚高峰时期会翻倍。为配合4号线实施大小交路后,因车陂南站会增大换乘客流及其影响,从4号线实施大小交路后的首个工作日开始,早上7时30分至8时30分将实施限流措施。大沙地站最初在2003年方案中出现,规划时的5号线改为在茅岗立交南边转向东北接入大沙地路,然后沿大沙地路东西向西延伸,中途设有本站,位置与现时基本一致。车站当初规划的时候,曾命名为港湾路站。随后大沙地站于2007年正式开工;2009年6月28日,本站正式三权移交;2009年12月28日,本站随5号线而正式启用。\n\n### 文章 90\n\n熏豆腐\n熏豆腐通常指曲阜产熏豆腐,又称孔府熏豆腐。孔府熏豆腐是地方传统小吃。顾名思义,这种豆腐是熏制而成的。关于熏豆腐的由来,民间有一个传说:旧时孔府有许多佃户,其中有一个姓韩的豆腐户家住曲阜城东北书院村,他家祖祖辈辈给孔府送豆腐。至清代乾隆年间,韩家的兄弟俩每天各给孔府送一方豆腐。有一年三伏期间遇到连阴天,韩老二家做的豆腐没卖完,放着怕馊了,他就把豆腐切成许多小块,摆在秫秸帘子上晾着。谁知他家不慎失火,晾豆腐的帘子也被烧着了,由于天阴、帘子湿,豆腐块有的被烤煳,有的被熏成了棕黄色。韩老二舍不得将这些豆腐扔掉,便取了一些放在盐水里煮了煮,一吃味道还挺不错。于是,他便送了些这样的豆腐到孔府,让衍圣公品尝。衍圣公让厨师在炖豆腐时放了桂皮、花椒、辣椒粉等作料,待豆腐被炖煮好之后,一尝味道甚好。从此,韩老二就专门给孔府制作、呈送熏豆腐,熏豆腐遂成为孔府的一道美味佳肴。传说有一年乾隆皇帝来曲阜,孔府摆了个豆腐宴招待皇上,其中就有一道熏豆腐。皇上吃着十分可口,大加赞赏。后来,熏豆腐的做法在民间逐渐流传开来,成为当地的一种独具特色的风味小吃。这种熏豆腐不仅曲阜本地人爱吃,而且到曲阜的外地人吃过之后也都爱上了它。据说,当年曲阜师范大学里有一位南方籍的教授,常步行几里路到集市上去吃熏豆腐,几十年乐此不疲。先将白豆腐切成长宽五六厘米、厚1厘米左右的方块,放在铁箅子上,下面燃以松、柏、梨、枣、苹果木锯末或谷糠,待豆腐被锯末或谷糠油熏烤至棕黄色、泛起油亮光泽即成。这种熏制而成的豆腐表面呈棕黄色,表层结实,里面细白鲜嫩,吃起来带有浓郁的木香或谷糠香味.熏豆腐可凉拌、炖熏,也可切成薄片,稍加鲜辣椒炒制。另外,集市上设有许多熏豆腐锅,把熏豆腐与肉块放入铁锅内,加水没盖,在加整辣椒、茴香、花椒、桂皮等佐料炖煮,即成“五香油辣熏豆腐”。上市者多以熏豆腐为佳肴饮酒,佐餐。当然,最正宗的做法还是曲阜当地的“五香油辣熏豆腐锅”:把熏豆腐与肉块放入铁锅内,加水,再加入辣椒、茴香、花椒、桂皮等作料炖煮。这种熏豆腐锅一般要炖煮很长时间,以使肉及作料的香味皆浸入豆腐内部,再加上熏豆腐自身特有的烟熏味,吃起来风味十分独特。\n\n### 文章 91\n\n杰米·海纳曼\n詹姆斯·富兰克林·“杰米”·海纳曼(,)是美国的一名特效专家,印第安纳大学语言学学士,专长是俄语。以其主持的电视节目《流言终结者》著称。他也是制作《流言终结者》节目的特效公司M5实业公司的创始人。他也出现在《超暴力激斗》(Robot Wars)节目中,节目里他的机器人布兰多(Blendo)破坏力巨大,一度给其他晋级比赛的机器人造成了很大的威胁,大出风头。海纳曼生于美国密歇根州的马歇尔,在印第安纳州的哥伦布城长大,并在印第安纳大学修得了俄语语言学学位。 他的履历非常丰富,当过水肺潜水员、野外生存专家、船长、语言学者、宠物店主、放牧人、机械师、水泥检验员和厨师长。\n从《流言终结者》中的“坠落榔头”一集中可以看出,他有些轻微的惧高症。海纳曼对怀疑论者和无神论者抱有非常强烈的同情态度。二十年前他在维尔京群岛当船长出租潜水装备的时候,认识了当地高中的一位女理科教师,她后来成了他的妻子。海纳曼在节目里的典型形像是戴著黑色贝雷帽穿著白色衬衫,偶尔还戴著太阳镜。这些加上他那海象式的胡子和低沉的声音,经常被一同主持的亚当·萨维奇和其他小组成员开玩笑。有几集节目里你可以看到他的工作室里挂著一个标语:“宁死勿乱”("Clean Up or Die"),看来他希望自己的工作室维持干净整洁。与搭档亚当活泼甚至有些幼稚的行为比起来,他以他的冷静、逻辑、严肃的行为举止而著称。海纳曼有时候也会被亚当的滑稽举动激怒,有时也会因破解流言的思路跟他吵嘴。对于表演实验和制作器具,他们俩经常有完全不同的思路。海纳曼的思路往往更简洁,有时你能听他说“让它越简单越好”("keep it as simple as possible"),或者“少点虚华,多点实用”("more grunt, less elegance")。两人在“金鱼的记忆力”和“吸尘器漂浮机器”两集中比赛时,他就以此座右铭来一争高下。他在商业上的成果有给七喜公司制造的汽水罐发射机器和获得专利的耐吉双轮足球鞋。亚当·萨维奇和杰米·海纳曼扮演了电影《达尔文奖》(The Darwin Awards,台译:猪头满天下)里的两个军用垃圾贩子。他们出现在剧中“火箭车”故事的部分,这部分最后也被制作成了《流言终结者》系列的试播片。杰米·海纳曼和亚当·萨维奇客串了《CSI犯罪现场》2008年5月1日的剧集《万有理论》。\n\n### 文章 92\n\n李瑞东\n李瑞东(公元 1851年-1917年),字树勋,号文侯。河北省武清县人,清末武术名家,李氏太极拳的创始者。李瑞东因为鼻子扁平,绰号“鼻子李”。家中经营药材生意,开设济生堂药舖,父亲李小歧,任职县衙为小吏,家境不错。自幼爱好拳术,初练少林等外家拳术,青少年时代跟随河北饶阳戳脚门名师李老遂求艺九年,河北名拳戳脚门拳法。青年时代与大刀王五(王子斌)结义金兰,互换拳艺,得王五所传“山东教门弹腿”之精妙。李瑞东先生天资聪颖,甚至有过目不忘之能,且练艺十分刻苦,到了成年时,已经练出了一身超群的武功,而且经常与善扑营的布库比试摔跤,多胜之,所以在京津二地很有些名气。光绪六年,端王府管事王永泰(字兰亭)出京办差,因为与李家为世交,途中经过武清县,顺道至李家拜访,因而与李瑞东结识。王兰亭早年拜在周岳图门下,学习十二连拳(心意六合拳的一个分支)。后又拜杨露禅为师,学杨氏太极拳。在杨露禅死后,又拜入董海川门下。李瑞东因此机缘,在王兰亭门下学习太极拳、八卦掌,又因王兰亭的介绍,至端王府、恭亲王府担任武术教师,与尹福、程廷华等人过从甚密,也曾得到董海川本人的指导。光绪二十年,至宫中为慈禧表演,以轻功得到赏识,被誉为「神鹰」,因而留在宫中,任四品带刀侍卫。父子在恭王府教拳,溥心畬兄弟是李子廉学生。在八国联军之后返乡,又拜甘淡然为师,学习八卦奇门拳。之后结合所学,创立李氏太极拳。因为他个性豪爽,交游广阔,在京津一带名声甚大,曾与李存义、李书文义结金兰,被推为天津中华武士会之首。但也因为不善理财,又爱接济朋友,因此而耗尽家财。在民国初年,曾任袁世凯大总统亲卫队武术教习,也曾主持天下武林英雄会,任裁判长。先生有弟子百余人,著名者近二十来人。先生有三子二女均精李派拳法:长女奇英、长子伯英、次子仲英、次女菊英、三子季英,弟子项润田、李进修、李子廉、张滔、陈继先、程安和尚、蒋万和、蒋万良、文实权、罗子鸣、王凤鸣、刘子鸣、高瑞周等人。原本是通背门的名家王荣标(人称“大枪王荣标”者)先生,在李瑞东先生中煤气毒逝世后,因仰慕先生之名,曾经与先生长子伯英结为师兄弟,从伯英学李派拳法。李瑞东曾向六大师习艺,又喜爱与人交换武术心得,因此他的武术特色即是博采众家、注意实用。\n\n### 文章 93\n\n地球重力场和海洋环流探测卫星\n地球重力场和海洋环流探测卫星(Gravity Field and Steady-State Ocean Circulation Explorer,简称GOCE)是欧洲空间局研制的一颗地球探测卫星。该卫星重约1吨,使用寿命为10年,在离地面约260公里的地球轨道运行,属于低轨道卫星。该卫星配备多套探测设备,其中一套高灵敏度重力梯度仪将对地球重力场每分钟的变化进行三维测量,这卫星至少连续两年提供包括地球磁场、地表冰层厚度及海洋中的洋流等多方面的数据。原定于9月10日发射升空,但由于发射卫星的运载火箭第二级子系统的导航装置存在异常情况,发射日期被推迟到10月5日,随后日期又被延至10月27日,结果等到2009年3月16日,卫星再次被放上发射台,但在发射前7秒,欧洲空间局突然宣布推迟24小时发射,2009年3月17日,该卫星在俄罗斯普列谢茨克发射场由轰鸣号运载火箭搭载升空。然而,北京时间2013年11月10日报道:欧洲空间局所属“重力场和稳态海洋环流探测”卫星(即GOCE)已经完成使命。欧洲空间局决定将其引导进入地球大气层焚毁。这颗卫星重约1吨,专家估计一旦进入地球大气层,这颗卫星将无法完全被烧毁,某些部分将坠落地面。研究人员估算认为有2/3的可能性这颗卫星的所有部件都将会坠落到大海之中。但即便最终真的有部分组件坠落在陆地上,那么有可能的坠落地区范围将包括加拿大,西伯利亚,撒哈拉,南极或是其它相对人烟稀少或无人居住的广袤地区。科学家们表示,大约仅有7%的可能性会有卫星碎片坠落到靠近有人居住地区的附近。。2013年11月11日报道,欧洲航天局表示,欧洲GOCE卫星已重新进入地球大气层,并在降落过程中燃烧解体。据悉,GOCE卫星在进入大气层的过程中,大部分都将燃烧殆尽,剩下的一些碎片残骸预计会落到从东亚至西太平洋至南极洲这一地区。\n\n### 文章 94\n\n神雕侠侣 (1995年电视剧)\n《神雕侠侣》(;又名《九五神雕侠侣》),是香港电视广播有限公司根据金庸所著的武侠小说《神雕侠侣》改编而拍摄的经典巨著电视剧,全剧共32集,监制为李添胜。杨过 ( 古天乐 饰 ) 一次误闯进活死人墓中,幸好拜得古墓派掌门小龙女 ( 李若彤 饰) 为师,因厌恶师父二字称谓,故称小龙女为「姑姑」。二人相依为命,但不知不觉间却萌生微妙的男女感情,且达到生死相逢之境地 ! 对此情坚贞不渝,纵使小龙女被尹志平 ( 陈启泰 饰 ) 所侮辱,仍能摒除世俗眼光而当众结为连理成亲。 后二人相分,决定十六年后终在绝情谷再续前缘 ……另一厢,郭靖 ( 白彪 饰 ) 、黄蓉 ( 魏秋桦 饰 ) 将女儿 郭芙 ( 傅明宪 饰 ) 许配予杨过,但为杨过所拒绝 ; 自始郭芙与杨过便积怨日深,于是在一次误会中,郭芙更斩下杨过之左手。然而,小东邪郭襄 ( 李绮虹 饰 ) 则对杨过豁达情深,更鼓励杨过踏遍天涯海角去觅回小龙女 ……以下是本剧在香港首播的集数之播映纪录:以下所有影碟发行均由电视广播(国际)有限公司授权:香港发行代理商现代音像(国际)有限公司于2003年推出发行了《神雕侠侣》VCD影碟零售版本,此影碟将已播放的集数并制作成20只碟作为片段完整及无删剪版本,一套共分为两盒影碟,每只碟跟电视剧的每集片长约60分钟一样,设有粤语及国语发音版本并配上繁体中文字幕。中国大陆发行代理商中凯文化集团推出发行了《神雕侠侣》H DVD影碟零售版本,总共30集,共四碟,出版社为九洲音像出版公司,设有粤语及国语发音版本并配上简体中文字幕。台湾发行代理商弘音多媒体科技股份有限公司于2007年推出发行了《神雕侠侣》DVD影碟零售版本,此影碟烧录VCD香港版的20只碟作为集数,共5只碟,设有粤语及国语发音版本并配上非隐藏繁体中文字幕。本剧于2014年5月在TVB星河频道,2017年9月1日在TVB经典台重播。\n\n### 文章 95\n\n温泉关战役 (前191年)\n温泉关战役(Battle of Thermopylae),是前191年罗马共和国在罗马-叙利亚战争中与塞琉古帝国交战的一场战役,此战的结果结束在希腊半岛的战事。塞琉古国王安条克三世率领一支规模不算大的军队登陆希腊半岛,他听信阿塔马尼亚人亚历山大的进言,希望能获得其他希腊势力的支援一同对抗罗马,然而大部分的希腊城邦都站在罗马阵营,就连前盟友马其顿国王腓力五世也愿意援助罗马。根据阿庇安记载,当安条克三世进军色萨利并来到库诺斯克法莱,看到在先前在库诺斯克法莱战役中许多阵亡的马其顿士兵遗骸散落四处,安条克三世在那举办隆重的葬礼并指责马其顿国王腓力五世,使当时摇摆不定的腓力听到这些消息后决心加入罗马阵营,罗马将军巴埃比乌斯立即派遣阿庇乌斯·克劳狄率领2,000名步兵通过马其顿进入色萨利。 此时安条克三世正在围攻色萨利重镇拉里萨,而阿庇乌斯·克劳狄在附近升起火光使安条克以为腓力和巴埃比乌斯来到,匆忙撤往卡尔基斯,并无所事事度过整个冬天。当罗马执政官马尼乌斯·阿基利乌斯·格拉布里奥率领20,000名步兵和2,000名骑兵进入希腊后,很快的与马其顿收复色萨利。面对如此庞大的军队,安条克三世决定在温泉关抵挡罗马的进攻,除了这里地势险要外,并确保盟友埃托利亚同盟的联系不被切断以及保护海军基地卡尔基斯。安条克三世亲自率领军队防御温泉关,并让投石兵布署在高处,步兵驻守完善的防御工事,埃托利亚同盟的部队防守左方侧翼,其中2,000名步兵固守的特拉喀斯,另外2,000名步兵防卫阿索波斯要塞和当年波希战争温泉关战役所使用的山路。当罗马指挥官马尼乌斯看到塞琉古如此布署,分别派兵趁夜明前攻取波斯所用小道的两侧山头,同时准备在天明时进攻。会战开始,安条克三世先派轻装步兵突袭罗马军,但遭到击退。而先前派往攻击埃托利亚人罗马军队,终于在老加图领导的第二次攻击下成功击破埃托利亚人,便一路追击直至塞琉古军后方的大营,在不知后方有多少敌军又担心遭到背面攻击的恐慌蔓延整个塞琉古军,塞琉古军逐渐溃散,而罗马军立即在后扩大战果,安条克三世只能重整500骑兵逃出,罗马军获得战役胜利。据记载罗马仅损失100多人,而塞琉古几乎全军覆没,无可奈何下安条克三世只能撤回小亚细亚,而埃托利亚同盟不久后向罗马投降。\n\n### 文章 96\n\n赫哲语\n赫哲语又称那乃语(Nanai)、赫真语(Hezhen)或戈尔德语(Gold),是赫哲族(在俄罗斯称为那乃族)的民族通用语言。通行于中国和俄罗斯接壤的黑龙江、松花江和乌苏里江流域一带。赫哲族族内根据各地区不同的自称,可分为“na nio”、“na bəi”、“na nai”三部。这三个自称的意思是“本地人”(直译“这里人”),其中“人”字的说法存在差别。“na nio”、“na bəi”二部多数居住在中国境内的松花江上游地带,统称为奇勒恩人“ki lən”,说奇勒恩语(亦可定为赫哲语奇勒恩方言),另有极少数居于俄罗斯境内。“na nai”一部多数聚居于俄罗斯境内,少数居住于中国黑龙江省,他们统称赫哲人“χə d͡ʑən”。汉语中统称三部为“赫哲族”。俄语中将包括“na nio”、“na bəi”二部在内的全部赫哲族统称为那乃族。语言方面,早期中国境内的赫哲语实际多为“na nio”、“na bəi”二部的奇勒恩语,少数使用“na nai”一部的赫哲语。但因为清朝时期的针对包括赫哲族在内的索伦人的满化政策,以及后来民族内部不同程度的汉化,致使居于偏南的“na nio”、“na bəi”二部的奇勒恩人绝大多数失去民族语言,而偏北毗邻俄罗斯的“na nai”一部赫哲人还有相对多数人使用民族语言,所以中国境内采用“赫哲族”、“赫哲语”来统称奇勒恩人和赫哲人的民族和语言。俄罗斯境内赫哲族多数属于“na nai”一部的赫哲人,所以俄罗斯使用“那乃族”、“那乃语”来统称境内的赫哲人和奇勒恩人及其语言。从20世纪中叶起,中国和俄罗斯境内的赫哲族均受到了很大程度的汉化和俄化,赫哲语在族内的母语地位被汉语和俄语代替,赫哲语面临濒危。在黑省除了约十数名50岁以上的族人尚能操赫哲语外,该族共1400余人已转用汉语。赫哲语是阿尔泰语系通古斯语族南通古斯语支东南通古斯亚语支赫哲诸语言的一个语言。赫哲诸语言还包括奇勒恩语、奥罗克语和乌尔奇语。另外赫哲语和南通古斯语支的其他语言(奥罗奇语、乌德语、满语、锡伯语、女真语)有近亲关系。1920年代起,在俄罗斯远东地区Valentin Avrorin等语言学家以西里尔字母书写赫哲语。\n\n### 文章 97\n\n陆军幼年学校\n陆军幼年学校,为旧日本陆军为了从幼年培养干部将校候补所设立的全住宿制教育机构。模仿普鲁士的军事学校()设立,毕业生拥有旧制中学校二年级毕业生的程度。1870年(明治3年)横滨语学研究所编入大阪兵学寮便是日本陆军幼年学校的开始。1871年(明治4年)大阪兵学寮被分开为陆军兵学寮与海军兵学寮,同年迁移到东京。1872年(明治5年)伴随著陆军兵学令的更改,陆军兵学寮幼年学舍改名为幼年学校。1874年陆军士官学校从兵学寮独立后,隔年幼年学校也改名为陆军幼年学校并从兵学寮独立。1877年并入日本陆军士官学校而暂时消灭。至1887年,随著陆军士官学校官制、陆军幼年学校官制的制定而再度设立。1897年时,因应军备扩张政策而增加培育人才数量,废除了陆军幼年学校官制,取而代之的是中央幼年学校条例与陆军地方幼年学校条例。东京为陆军中央幼年学校,另外于仙台、名古屋、大阪、广岛、熊本设立陆军地方幼年学校。每校各有约50名学生,中央幼年学校为14岁开始的2年,地方幼年学校为13岁开始的3年就读。陆海军士官的子嗣可享学费半价,战死者遗腹子学费全免。因为制服的领口有金星标志,也被称为「星的学生」。于校内学习军事学与普通学问,毕业生约占陆军将校的三分之一。被当时的人认为是陆军的旧制中学校。不过在当时陆军认为出身自文部省管辖的中学校,接受自由教育的人才不能信任,要想在陆军里出人头地除了日本陆军大学校毕业外,陆军幼年学校毕业也是重点。1918年(大正7年)制定陆军幼年学校令,陆军中央幼年学校与陆军地方幼年学校都改名为陆军幼年学校。1922年,由于华盛顿海军条约世界各国均开始缩减军备,同年大阪校废校。1923年名古屋校、1924年仙台校、1927年熊本校、1928年广岛校依序废除后,仅剩中央幼年学校。广岛校废除该年,中央幼年学校改编为日本陆军士官学校预科。1936年中国战线扩大所致,先是广岛幼年学校复校。之后1937年仙台幼年学校、1939年熊本幼年学校、1940年大阪幼年学校、名古屋幼年学校依次复校。大阪幼年学校移往离楠木正成居城很近的千代田村(现在的河内长野市),1940年4月1日时共150名44期生入学。太平洋战争结束后,日本陆军幼年学校与日本陆军士官学校一起遭到废除。\n\n### 文章 98\n\n科克大学\n科克大学(直译为科克大学学院,,)是爱尔兰国立大学的一部分。大学建于1845年,原名“皇后学院”(Queen\'s College, Cork);1908年爱尔兰大学法案出台后,学校更名为“科克大学学院”(University College, Cork)。1997年大学法案将学校更名为\'“爱尔兰国立大学科克”(National University of Ireland, Cork);1998年教育部将大学更名为“科克大学”(University College Cork - National University of Ireland, Cork)。科克大学被星期日泰晤士报选为2003-2004年度爱尔兰大学,2005-2006年和2011-2012年再度当选年度爱尔兰大学。2007年,科克大学在泰晤士高等教育世界大学排名286位,2008年226位,2009年207位。科克女王学院(Queen\'s College, Cork)乃根据维多利亚女王发布的"为发展爱尔兰的高等教育"法案建立。根据该法案,三所学院于1845年10月30日分别在贝尔法斯特(贝尔法斯特女王大学)科克和戈尔韦(爱尔兰国立大学戈尔韦)建立。科克学院1849年正式办学,当时有23位教授及181位学生,一年后便加入爱尔兰女王大学。医学楼建于1860年至1880年,医学院也迅速因其毕业生而建立了名声。爱尔兰最早的两名女医学学生于1898年医学院毕业(20年后牛津大学才开始招收女医学学生)。在随后的一个世纪中,爱尔兰大学法案(1908)成立了爱尔兰国立大学,包括都柏林、科克和戈尔韦的三所成员学院。三所学校也有大学学院的地位,例如“大学学院,科克”。1997年大学法案使大学学院成为爱尔兰国立大学的成员大学,也使成员大学成了全方位的独立大学,但是学位和文凭仍由爱尔兰国立大学颁发。科克大学是爱尔兰的研究型大学,其政府科研经费全国最高。现有艺术、凯尔特研究与社会科学学院、商学与法学院、医学与健康学院、科学、工程和食品科学学院。科克大学还是爱尔兰中国研究院的所在地。学生在中国研究院能够通过艺术和商业学习中国语言和文化。中国研究院最近荣获2008年欧洲语言奖。\n\n### 文章 99\n\n月光嘉年华\n《月光嘉年华》()是Nitro+于2007年1月26日发售的日本成人游戏。其后衍生出漫画和小说,漫画先在Champion RED 草苺连载,后移至月刊Champion RED2007年4月号至2008年2月号,单行本全两卷。而小说则由小学馆Gagaga文库发售,全三卷。哥德色调的灰暗系ADV。以美女(人偶)与野兽(人狼)为宣传口号,展开人狼主角\'和自动机械人偶\'为中心,围绕犯罪组织和对魔特殊部队的故事。游戏中的背景绝大部分实地取自意大利的佛罗伦斯、锡耶纳和威尼斯,文中的专有名词不少都是意大利文,如游戏标题「CARNEVALE DELLA LUCE DELLA LUNA」,和部分拉丁文。故事中亦引用不少欧洲18世纪的历史,如数位实际存在的历史人物。历史城市,是世上存在最多的人偶生产地,在贝尔蒙中任何地方几乎也可以见到自动机械人偶和观光客。而主角在一年前,舍弃了过去的同伴来到贝尔蒙。偶然垃圾弃置所发现一台金发的自动机械人偶,感到和自己的遭遇相似,带到的工房修好后,命名为,并过著平平无奇但还不错的生活。然而他以前所属的组织开始要求他归回……,支配意大利北部的人狼黑手党,但禁止食人及使用或流通毒品。,教煌厅对魔特殊部队。拥有对人狼用兵器自动机械人偶,除了鲜红足印,影响力更大至教煌厅。,100年前已在欧洲各地表演的自动机械人偶马戏团。! 编号 !! 标题 !! 中文译名标题同是,由绘画,担当剧本,主要角色和游戏一样,但亦有一些新角色。于Champion RED 草苺连载,后移至月刊Champion RED2007年4月号至2008年2月号,单行本全两卷,中文版由东立出版社代理发行。《》,著,插画,由小学馆的轻小说文库Gagaga文库发行,全三卷。原作外传的作品,时间轴在原作之前,主要描述自动机械人偶兄妹和的故事,部分原作的人物也会以配角的形式登场。《》,由TEAM Entertainment于2008年5月8日发售。内容主要描述「安娜人偶结局」后的日常生活。\n\n### 文章 100\n\n气炉\n气炉是一种以天然气、丙烷或其他可燃性气体作为燃料以产生火焰的厨房煮食用具。最早的煮食用炉具,可追溯至中国历史的秦朝,西方的炉具更于1735年才出现,气炉面世前,当时的人一直使用煤及木材作为燃料的用具,直至1826年第一具气炉诞生,但当时这种炉具并非用在煮食上,而是用于实验上,即类似今日的本生灯。真正用于煮食上的炉具于1851年的伦敦世博上展示,但当时的气体管路的铺设技术并不成熟,难以每家每户装设气炉,因此气炉并未能商业化地大量生产。至1880年代,气炉才走向商业化。同时间第一代电磁炉亦于1893年的芝加哥世博上展示,气炉的市场开始被电磁炉侵蚀。时至今日气炉与电磁炉并列是普遍全多人使用的烹饪用具。气炉大约可以分为三类:气炉其实是一个气态燃料的持续供应器,开关扭开后气态燃料会不断输出,同时炉具的点火器会因磨擦而产生火焰,当气态燃料遇到火焰时便会燃烧,持续的气体供应能维持炉具火焰的燃烧。气炉所产生的火焰与一般所见的火焰并不相同,如烧烤或点蜡烛时,所产生的火焰是黄色的,而气炉所产生的火焰为蓝色,因为气炉所使用气态燃料在产生热能的过程中会被完全燃烧,其火焰较热,燃料分子因此会发出蓝光和绿光,由于人类的眼睛对蓝光比较敏感,因此人类所见的火焰是蓝色的。使用炉具时应避免炉头积聚油污及食物残渣,以免使用炉具时燃起炉头上多余的物质。同时,要注意火焰不应超过煮食器皿的范围,以免点燃其他杂物引起火灾。最后要紧记不应以水喉喷向炉具,因为会破坏炉具的结构及零件。每次使用后应把气闸关闭,并且在空气流通的地方使用,如发现气体泄漏,更要通知代理公司修理,还有,要使用合标准的喉管传送气体燃料,不要折曲喉管。\n\n### 文章 101\n\n九龙巴士41M线\n九龙巴士41M线是香港一条来往青衣邨及荃湾站的巴士路线。其辅助线41P来往青衣码头及荃湾站,只于星期一至六繁忙时间提供服务,公众假期除外。全程:$4.7乘客登上本线后指定时间内以同一张八达通卡转乘以下路线,或从以下路线登车后指定时间内以同一张八达通卡转乘本线,次程可获车资折扣优惠:现时本线使用2辆富豪超级奥林比安10.6米(ASV),1辆富豪B9TL12米(AVBWU)、1辆丹尼士三叉戟12米(ATR),均属青衣车厂。自从39M线改为循环线后,由新界西北来往荃湾铁路站路线的巴士,若过了钟无法回程,通常会改行本线或238M线一转令车长补回工作时间,令本路线间中有屯门或元朗厂巴士行走。不过本线由于青衣邨巴士总站的坑位问题及路面限制,所以很少采用12米的巴士行走。青衣邨开经:青绿街、青叶街、枫树窝路、担杆山交汇处、青敬路、长安巴士总站、担杆山路、担杆山交汇处、青荃路、荃青交汇处、德士古道、杨屋道、大河道及西楼角路。荃湾站开经:西楼角路、大河道、杨屋道、德士古道、荃青交汇处、青荃路、担杆山交汇处、青敬路、长安巴士总站、担杆山路、担杆山交汇处、枫树窝路、青叶街及青绿街。青衣码头开经:枫树窝路、青敬路、长安巴士总站、担杆山路、担杆山交汇处、青荃路、荃青交汇处、德士古道、杨屋道、大河道及西楼角路。荃湾站开经:西楼角路、大河道、杨屋道、德士古道、荃青交汇处、青荃路、担杆山交汇处、青敬路、长安巴士总站、担杆山路、担杆山交汇处、枫树窝路、青叶街、青绿街、青敬路及枫树窝路。本线虽说是接驳港铁的路线,不过甚少居民利用本线接驳港铁,主要原因是青衣邨已有新界区专线小巴88线来往葵芳站,车程较短及收费较本线低,长安及长发邨的居民亦较多选择44M往葵兴站转乘港铁,尤其港铁东涌线通车后,居民可沿青衣公园往来青衣铁路站,更没有接驳港铁的意义。但本线因途经青衣和荃湾的市中心,所以有不少乘客会乘坐本线到荃湾购物,不过本线服务范围少,而且受新界区专线小巴409系路线车海战术影响,所以客量不太稳定。本线除青衣邨外与42M及243M重叠,客量一直不稳定。但本线有直达南丰中心的优势,故有一定乘客支持。而且42M线、243M线于繁忙时间未到长安已经出现客满,本线可担当辅助角色。\n\n### 文章 102\n\n克里米亚鞑靼人\n克里米亚鞑靼人( 或 , 或 , ,)或称“克里米亚人”(),是原定居于克里米亚半岛的突厥语民族,他们的历史最早可以追溯至斯基泰人、希腊人、哥德人、东斯拉夫人、罗马尼亚人与切尔克斯人时期。后来,威尼斯人及热那亚人与突厥特别是匈人、阿瓦尔人、保加尔人、可萨人、佩切涅格人及钦察人混血,形成克里米亚鞑靼人。他们是最早宣传泛突厥主义的民族。与伏尔加鞑靼人不同,他们受到乌古斯人影响比较大,在金帐汗国时代已经被伊斯兰化。虽然克里米亚鞑靼人被称为鞑靼人,但其语言实际上与伏尔加鞑靼人的语言相差较远。他们分布在克里米亚半岛、土耳其、罗马尼亚、保加利亚、波兰、立陶宛、白俄罗斯与北美、巴西及西欧,也有分布在北欧(芬兰)。他们以前是奥斯曼帝国贩奴活动的中间人,诺盖人捕奴后交给他们,送到奥斯曼帝国(直到18世纪初,克里米亚鞑靼人在某些时期几乎每年到俄罗斯和乌克兰进行频繁的毁灭性袭击,称为草原民族收成,有些研究人员估计,15至18世纪合共超过300万斯拉夫人出口土耳其)。他们有自己的汗国(以克里米亚为中心,以北的草原至北高加索,他们好战,土耳其人有事也找他们帮忙),先是土耳其人的臣民,他们的汗是拔都的兄弟秃花帖木儿的后人,家族名是格来。克里米亚鞑靼人主要生计就是靠袭击别国。18世纪被俄罗斯帝国吞并,他们在第二次世界大战被指与纳粹德国勾结,被苏联领导人斯大林集体流放中亚和西伯利亚,直到1950至1990年代后才陆续返回,但地方已被俄罗斯人与乌克兰人填补(他们曾经过二次流亡,第一次是克里米亚汗国亡国流亡土耳其,第二次是史达林硬送他们到乌兹别克与哈萨克)。2014年克里米亚危机爆发时,许多克里米亚鞑靼人发起声援基辅政府的示威游行,并且拒绝参加克里米亚举行的归属公投。克里米亚宣布入俄后,克里米亚鞑靼人在巴赫奇萨赖召开临时代表大会,要求建立克里米亚鞑靼族民族区域自治的政治和法律程序,不久,立陶宛发起联合国安理会非正式会议讨论克里米亚鞑靼人的人权问题,但遭到俄罗斯的抵制。俄罗斯总统普京在接见俄罗斯联邦鞑靼斯坦共和国总统鲁斯塔姆·明尼哈诺夫时声称他将派人研究为克里米亚鞑靼人恢复名誉的问题。2016年,克里米亚鞑靼人的最高代表机关「克里米亚鞑靼人民族议会」被俄罗斯禁止。\n\n### 文章 103\n\nJust can\'t help it.\n《Just can\'t help it.》(,"Just can\'t help it.")是东京事变的第五张DVD,于2006年9月6日发行。发行当周即卖出3.0万张,总计销售额5.1万张,名列2006年年度销售榜第30位。初回限定为「Digipak纸盒仕样」。此张DVD是收录东京事变《"DOMESTIC!" Just can\'t help it.》 巡回演唱会的其中一站,于2006年5月26日在NHK会馆(NHK HALL)所举行的,其演唱的歌曲及幕后花絮。演唱会中的新曲「Mirror Ball」、翻唱林檎给友阪理惠「机器少女」和「停电」于8月21日开始接受线上下载的服务,同一天也成立了DVD特设网站。在日本09月6日发行DVD,台湾则是等到09月26日才发行进口盘。《"DOMESTIC!" Just can\'t help it.》为二期东京事变第一次巡回演出,总共在十六个城市举办二十一场的演唱会,场场皆吸引爆满的观众前往感受东京事变的魅力。演唱会演唱的曲目以第二张专辑《大人》为主,演唱会的开场便是日本传统乐的歌曲雪国,身穿和服的林檎,抓住了众人的目光,还有服务这首歌,全体团员拿著大声公演唱,中途搭配上团员们台上换装的片段,带起一波高潮。而演唱会利用投影的方式,搭配团员们的的动作与歌曲的内容,让人惊叹,像是中场时,鼓手刄田缀色凭空踢球的效果,还有脸孔这首歌时,钢琴手伊泽在钢琴独奏时,便把改编的英文版本歌词投影至舞台,这种投影的效果,不但提高了演唱会的可看性,更增加了与台下观众互动的机会。另外由于椎名林檎在专辑《大人》发行接受访问中提到「今后,她想要专心作词和演唱,作曲则会交给其他成员。」因此,在巡回演唱会上发表了浮云所创作的曲目「Mirror Ball」,借此希望之后的活动能以团员的创作曲目为中心。\u3000椎名林檎 - 主\u3000唱・吉他手\u3000龟田诚治 - 贝斯手\u3000刄田缀色 - 鼓\u3000手\u3000\u3000浮云\u3000 - 吉他手\u3000伊泽一叶 - 钢琴手・吉他手\n\n### 文章 104\n\n假苹婆\n假苹婆 (学名:" "),别称七姐果、鸡冠皮、鸡冠木、山羊角、红郎伞、赛苹婆\'及山木棉等,为梧桐科苹婆属半落叶乔木植物。由于假苹婆结果的期间与中国七姐诞相近,故称为七姐果。亦有人用苹婆和假苹婆的果实作为七姐诞的祭品。花期4-5月。假苹婆常长于山谷溪旁。在中国境内,分布于广东、广西、贵州、四川南部、中南半岛及云南的南部,亦为香港原生植物。于泰国、缅甸、越南及老挝等地亦有分布。假苹婆是一种常绿小乔木,高约5-20米,树冠广阔球形。枝干于幼时披毛。叶椭圆状矩圆形或披针形,单叶互生,顶端急尖,基部钝形,腹面无毛,背面近无毛,近革质,全缘,侧脉约有11对,弯曲,在近叶缘外不明显连接,长约8-20厘米,宽约3.5-8厘米;叶柄两端隆起貌似哑铃,长约1.5-3.5厘米。花为圆锥花序腋生,雌雄同株,密集且多分枝,通常短于叶片,小苞片短呈线形,早落;花淡红色,无花冠,花萼5裂,裂片长圆状披针形或长圆状椭圆形,基部连合,向外开展如星状,顶端钝或有小短尖突,表面披短柔毛,边缘有缘毛,长约4-6毫米;雄性花,雄蕊柱弯曲,长约2-3毫米,花药约10个,排成2列,生于雄蕊柱的顶端呈球形;两性花,子房圆球形,披短柔毛,花柱弯曲,柱头不明显5裂。果为蓇葖果,长卵形或长椭圆形,常2-5个聚生或单生,初时绿色,后转黄色,成熟时鲜红色,顶端有喙,基部渐狭,密披短茸毛,近无柄,长约5-7厘米,宽约2-2.5厘米;于每一蓇葖内约有2-7颗种子;成熟后开裂,形如凤凰鸟睁开眼睛,故有凤眼果之称。种子椭圆状卵形,黑色或褐色,直径约1厘米。假苹婆的叶片性味辛、温、肝经,能散瘀止痛,可治瘀血疼痛、跌打损伤、肿胀及青紫等。假苹婆的茎片纤维可作织麻袋的原料;炒熟后的种子可供食用,亦可作榨油之用。\n\n### 文章 105\n\n马良弼\n马良弼(;)号汝舟,和名名护亲方良丰(),琉球国第二尚氏王朝时期大臣。童名太良金。他是马世荣(名护亲方良员)之子,马良诠(名护亲方良意)之孙。1551年生于首里城。1579年,为进贡及谢册封尚永王之恩事,以王舅的身份,与长史郑迵(谢名亲云上利山)一起出使明朝。在北京期间,萧崇业、谢-{杰}-赠送给马良弼「国佐元勲」四字匾额。归国后,因功升三司官座敷。1592年,其父马世荣退隐。因兄长马良辅(伊计亲方良真)早卒,马良弼遂以次子的身份继承家督之位。同年就任三司官,领名护间切总地头。当时日本逐渐强大,岛津义弘致书琉球,声称日本要出兵朝鲜,要求琉球提供粮草支援。马良弼与翁寄松(城间亲方盛久)都认为琉球弱小、日本强大,主张对日本和好,同主战派的郑迵、向里瑞(浦添亲方朝师)意见相对。1605年,翁寄松在与郑迵的政治斗争中失势,尚宁王转而倾向对日强硬的态度。1606年,册封使夏子阳、王士桢到达琉球,赠送给马良弼「世承天宠」四字匾额。1609年,萨摩藩派遣桦山久高、平田增宗率兵入侵琉球。尚宁王得知消息后,派马良弼、毛凤朝、菊隐、喜安等人前往北山。马良弼在此期间的行为,各史料是矛盾的。一说马良弼率一千名首里亲军前往北山防御,但中萨军伏兵之计,兵败被俘;马良弼仰天痛哭而不投降,因此受到萨军的尊敬。而另一种说法是马良弼前往北山的运天港,至萨摩军中请罪,并留在萨摩军中作人质,引导萨摩军开入那霸港。萨摩军包围首里城后,尚宁王向萨摩投降,并先至马良弼府邸暂时居住。尚宁王等人被掳至鹿儿岛时,马良弼同毛继祖(丰见城亲方盛续)被留下,一同管理首里城。1611年尚宁王归国后,马良弼继续担任三司官之职。1612年(万历四十一年),再以谢恩王舅的身份出使明朝,并就进贡之事同明朝交涉。翌年归国。马良弼于1614年致仕,由毛继祖继任其职。1615年,尚宁王向明廷报称马良弼因交涉进贡一事失败而遭到处决;事实上,根据《中山世谱》的记载,马良弼并未遭处死,翌年出使萨摩藩,告知赴明谢恩完竣之事。1617年逝世。\n\n### 文章 106\n\n翼尖小翼\n翼尖小翼(winglet或wingtip),又称作翼梢小翼、翼尖帆或翼端帆,通常用于提高固定翼航空器机翼的效率,也可用来改善航空器的操纵特性。飞机维持正常飞行时所需的升力是靠机翼上下表面的压力差产生的,由于上下表面压差的存在,翼尖附近机翼下表面空气会绕流到上表面,形成翼尖涡流,致使翼尖附近区域机翼上下表面的压差降低,从而导致这一区域产生的升力降低。为了削弱这种绕流现象对升力的影响,很多飞机的翼尖都安装了翼尖小翼(又称为「翼尖整流片」),用以阻碍上下表面的空气绕流,降低因翼尖涡流造成的升力诱导阻力,减少绕流对升力的破坏,提高升阻比,达到增加升力的目的。对于有动力航空器来说还可降低油耗。不过增加翼尖小翼,翼端结构为了组装翼尖小翼会比较复杂,也会增加一些额外的重量,若是装了翼尖小翼都只飞两小时内短程航线,油耗反而会增加,飞长程航线才能得到降低油耗的效益。翼尖小翼形状因各种飞机型号不同而有所变异。因为国际油价抬升,所以各航空公司纷纷要求厂商加装翼尖帆,有些机型如空中巴士A300、波音727、波音757和波音767原设计并无翼尖小翼,后来才加装上去。典型的翼尖帆如波音公司(Boeing)生产的747-400型(专为日本国内航线设计的747-400D型除外)飞机和空中巴士(AIRBUS)的A330和A340系列飞机。另一种则是空中巴士A320系列、A310和A380的三角型翼尖帆,这款翼尖帆可说是空中巴士的标准形式。还有新一代波音737-800、900、湾流V公务机的大型翼尖帆及MD-11上下两片式翼尖帆。而波音的新设计客机如波音777、波音787、波音747-8都以特殊的上帆角(raked winglet)设置代替翼尖帆。一般的军用机中,战斗机由于涉及到空气动力学、超音速巡航与近距高速空中缠斗的需求,且航程(作战半径)较短,故无安装翼尖小翼的需求,部分在航空母舰上起降的军机亦无翼尖小翼的设计;而针对长途飞行任务设计的战略轰炸机、空中加油机、运输机、空中预警机,为了增加续航力而加装了翼尖小翼。除了飞机以外,现今大多数赛车也会在后扰流器两端装上翼尖小翼。部份风力发电机也会在叶片尖端安装翼尖帆。\n\n### 文章 107\n\n谢尔吉耶夫镇\n谢尔吉耶夫镇 ()是俄罗斯莫斯科州东北部的一个城市,著名的金环古城之一。位于莫斯科东北偏北71公里。2002年人口113,581人。15世纪拉多涅茨的圣谢尔盖在这里建立了谢尔盖圣三一修道院 。1742年建市。苏联时代先把「镇」字去掉 (1919年),1930年又以一名布尔什维克党人改名为扎戈斯克。1991年恢复原名。城市中心有谢尔吉圣三一大修道院,修道院被16世纪修建的城墙包围起来。城市内有14-18世纪修建的众多教堂,各个建筑协调在一起,很有情趣。它是距莫斯科最近的“金环”中的城市,从莫斯科出发当天就可以返回,这里是来莫斯科旅行的人必去的地方。谢尔吉圣三一大修道院建于14世纪中叶,由一位著名的宗教活动家创建,他就是谢尔吉·拉多涅什斯基。他在宣扬俄罗斯东正教的同时联合俄罗斯各大公共同抵御蒙古军队的入侵。据说当时就是因为他的祈祷德米特里·顿斯科伊才率领俄罗斯军队第一次战胜了蒙古军队,此后他继续宣扬东正教,并且成为俄罗斯东正教育的圣者,现在人们已经把他当做俄罗斯的守护之神。位于大修道院中央的圣母安息(乌斯宾斯基)大教堂是在伊凡四世(雷帝)命令下建成的,完成于1585年。在4个洋葱头形的蓝色圆顶中央,有一个金色的大圆顶,看起来有点像王宫。莫斯科的克里姆林宫内也有圣母大教堂,谢尔吉耶夫镇的大教堂就是仿照它而建的。教堂内有17世纪的壁画。谢尔吉圣三一大修道院标志性建筑——圣母大教堂的北侧是鲍利斯·戈东诺夫沙皇家族的墓地。因为俄罗斯人都认为是他引起了俄罗斯的混乱,所以他没能被安葬在教堂里面,谢尔吉圣三一大修道院建成于1423年,谢尔吉·拉多涅什斯基的棺木就安置在教堂里。在这里还可以看到著名的俄罗斯画家安德烈·鲁布廖夫的壁画作品等。谢尔吉圣三一大修道院的旁边是于1477年建成的降灵教堂。此外,大修道院内还有钟楼(建于18世纪)、教堂宫殿和斯摩棱斯克教堂(建于1748年)等。谢尔吉圣三一大修道院内设有莫斯科宗教大学的神学院,在这里经常能遇到身裹黑袍的年轻修士和修女。谢尔吉耶夫镇除了谢尔吉圣三一大修道院外还有一个旅游景点,它就是玩具博物馆。谢尔吉耶夫镇自古以来就以制作玩偶、套娃等玩具而闻名,博物馆内展示了很多本地生产的珍贵的民间艺术品。http://www.stsl.ru/languages/zh/index.php\n\n### 文章 108\n\n长谷川町子\n长谷川町子()是日本最初的女性专业漫画家。代表作有《蝾螺小姐》等。她也是日本唯一的一位获得国民荣誉赏殊荣的漫画家。长谷川町子出生在佐贺县小城郡的东多久村(现多久市),但是幼年时期移居到福冈市,她在福冈长大,直到住到1933年(时为旧制福冈县立福冈高等女学校2年生)。随著父亲去世她移居到东京,后毕业于山脇高等女学校(现山脇学园短期大学)。就读山脇高女后从师于漫画家田河水泡。第二次世界大战(太平洋战争)爆发后疏散到福冈县并在西日本新闻社学艺部工作,二战结束后退职。1946年(昭和21年),长谷川町子在福冈县地方报纸《Fukunichi新闻》上发表「蝾螺小姐」(),成为了新闻四格漫画的第一人。其后该漫画转到《新夕刊》和《朝日新闻》上刊登,期间曾数度中断,连载一直持续到1974年(昭和49年)为止。她和姊姊共同创立姊妹社后担任代表。1970年(昭和45年),为维护知识产权,长谷川町子向没有征得作者同意擅自使用「蝾螺小姐」的角色图案的立川巴士公司提出控诉 。1992年(平成4年)5月27日,长谷川町子因心衰竭去世,享年72岁。遵照她的遗嘱,去世的消息在月内并未公开。一个月后(6月末)朝日新闻社和富士电视台公布了她的死讯。同年7月,日本政府为表彰她的家族漫画对安定战后日本社会的贡献授予其国民荣誉赏。长谷川町子获得的其他的奖项包括第8回(1962年度)文艺春秋漫画赏 ,第20回(1991年度)日本漫画家协会赏等。另外,出于收集各种美术品的爱好,长谷川町子生前以个人资金创建了「长谷川町子美术馆」(地点在东京都世田谷区樱新町),1985年11月3日开馆。姊妹社解散后由「基金会长谷川町子美术馆」管理作品著作权。成立当初馆名叫「长谷川美术馆」,但长谷川町子去世后改为现名。长谷川町子是圣公会基督教徒,终身未婚。1993年3月,长谷川町子的遗骨被不明人士偷走(日本媒体称为「长谷川町子遗骨盗难事件」),可是事件风波平息之后,又被放回原位。由于偷窃犯身分不明,至今仍未逮捕归案。\n\n### 文章 109\n\n黑雾解散\n黑雾解散(日语:),是1966年12月27日日本众议院解散的俗称。1966年日本政坛接连被揭发重大丑闻事件,被称为「黑雾事件」,对执政的自民党信誉打击很大,日本国民对政府的不信任感增强。12月1日,佐藤荣作首相第二次竞选自民党总裁虽然以绝对优势胜出,但是比预计中多了不少的反对票告诫佐藤内阁必须为黑雾事件负责。另一方面,以社会党为首的在野党亦以黑雾为由不断抨击政府,干扰国会的正常运作,以求迫使政府解散国会提前大选。临时国会通过了追加预算案之后,佐藤首相开始表示认真考虑解散国会的时机。12月22日,首相向社会党、民社党、公明党三党领袖提出邀请举行四党首脑会谈。12月24日,四党的领袖在国会内的大臣室举行会谈,虽然首相没有允诺哪天解散国会,但是彼此间达成了在12月27日召开通常国会那天宣布解散国会的默契。12月27日,第54回通常国会召开。14:00开始举行众议院大会,当天所有之前抵制国会运行的在野党议员在全部出席。众议院议长绫部健太郎宣布开会,内阁官房长官福永健司拿著紫色绸制的小包袱(天皇按照内阁总理大臣意图起草的诏书)走进国会,由事务总长久保田义麿交给绫部议长。绫部宣布收到诏书,全体起立。议长宣读:全体议员三呼万岁,在热烈的掌声下,国会正式被解散。大选安排在1967年1月29日。一般认为,黑雾解散是成功的。因为在一个月之后举行的第31回众议院议员选举中,自民党不仅没有像外界预料中那样大幅减少议席,保守派所得的总议席反而还有所增加,达到绝对多数;反观社会党却在大选中惨败。佐藤政权通过大选摆脱了黑雾,凝聚了更大的向心力,组成第二次佐藤内阁之后,佐藤更大胆地全面推行自己的政策。\n\n### 文章 110\n\n焦比\n在光学中,一个光学系统中的焦比(,或称F值、F比例、相对孔径、光圈值等,习惯上也简称「光圈」)表达镜头的焦距和光圈直径大小的关系。简单来说,焦比等于焦距数除以孔径数。焦比是无因次量的,它代表了摄影学中的一个重要概念:镜速(Lens speed)的量。f-number公式中,"f/"#,又标作为formula_1,公式是这样的:formula_2上式中,"f"是焦距,而"D"是光圈值。惯例上,""f/"#"是视为单一符号,书写时数值替代符号中的井号。举个例子,若焦距值是光圈直径的16倍,那样f-number是"f/"16,或"N" = 16。照f-number中,"f/N" 标志法的字面解释,"N" 如同实际孔径的算术表达方式,焦距除以f-number: "D = f / N" 。注意有些时候上述数值是有歧义的;举例说,"f/"1.2可用在半级或三分之一级的系统;有时"f/"1.3及"f/"3.2也用于三分之一级的系统。由于所有镜头会吸收一部分通过的光线(特别是变焦镜头存在很多元件),曝光级数(T-stops)有时替代焦距比数作为曝光效果,尤其在电影拍摄用镜头。这惯例在变焦镜头出现前,在电影摄影中流行使用,在固定焦距镜头也调校至曝光级数值。这容许了转台式架置的镜头可以转换而不影响整体场景光度。每个镜头都独立测试真实光源的传送,及相应地指派曝光级数值(在T-stops中的T指transmission,即「传送」),但现代电影摄影镜头的曝光级数值现常趋向工厂校准的数值。曝光级数值量度了镜头实际上的光线传送量,相等于理想镜头的100%光传量。重申,由于所有镜头会吸收一部分通过的光线,在一个镜头中的曝光级数值永远高于焦距比数。近年来,镜头科技的进步,及底片的曝光宽容度,都减少了曝光级数值的理论性。要记住:焦距比级数用于焦距比例,曝光级数值用于光线传送量。\n\n### 文章 111\n\n宝剑骑士团\n宝剑利沃尼亚兄弟骑士团(,)是里加的阿尔伯特主教在1202年建立的一个军事修会。 1204年,教宗诺森三世批准了这一骑士团的建立。骑士团的成员包括德意志的 「战僧」。骑士团的其他名称为基督骑士,宝剑兄弟和利沃尼亚的基督义勇军。在1236年在苏勒战役被萨莫吉希亚人击败后,幸存的骑士团成员被并入条顿骑士团,并形成一个独立的分支,被称为利沃尼亚骑士团。里加主教(或称为利沃尼亚采邑主教)阿尔伯特,成立了兄弟会以协助利沃尼亚主教区令利沃尼亚人,拉特加利亚人和瑟洛尼亚人这些生活在通往里加湾向东的古商道周围的异教徒昄依基督教。从它的创办可以看出,纪律散漫的骑士团趋向于忽视其与主教的隶属身份。在1218年阿尔伯特要求丹麦国王瓦尔德马二世的援助,但瓦尔德马和兄弟会签署协议,让他们占领爱沙尼亚北部以替代其援助请求。兄弟会的总部设在位于当今爱沙尼亚的费林(维尔扬迪),在那里大团长的城堡城墙依然屹立。其他城堡位于文登(切斯),西格沃德(西古德),阿施拉登(埃兹卡乌克)。费林,格尔丁根(库尔迪加), 马里恩堡(阿鲁克斯尼),日瓦尔(塔林)的指挥官和维森斯特因(派德)的法院执行官为大团长的随从。1232年11月24日,额我略九世在他的信件中要骑士团在诺夫哥罗德进攻中保卫芬兰。然而,没有任何关于骑士团在芬兰可能令其幸免于难的行动的文献(瑞典最终在1249年第二次瑞典十字军入侵期间占领芬兰)。在1236年的苏勒战役中,立陶宛人和萨莫吉希亚人杀死了骑士团的大部分人马。这次灾难让幸存下来的骑士团人马在翌年被并入条顿骑士团,并从另一个角度看,他们从此被称为利沃尼亚骑士团。不管怎样,他们继续作为条顿骑士团的独立分支在各个方面发挥职能(条例,服装和政策),由他们自己的大团长管理(他们自己"在法律上"受条顿骑士团大团长管理)。\n\n### 文章 112\n\n韩国围棋联赛\n韩国围棋联赛地区性围棋对抗赛改名韩国梦幻联赛,只有6支队伍,总规模为3.6亿韩元改名韩国围棋联赛,发展到了有8家企业俱乐部参加,总预算达到10亿韩元。每队4人共32人中,2003年度奖金排名前16名的棋手自动获得参加权,其他16个名额由其余的180名棋手竞争获得。此外还设立了1000万韩元的最佳棋手奖和300万韩元的多胜奖。分为季前赛、常规赛和季后赛三个阶段。奖金总规模15亿韩元,从4月28日起开始正式比赛。冠名“KB国民银行”,常规赛棋队排名将依次按照积分--胜局数--两队间胜负--两队间比赛净胜局--主将至第5台各台次胜局数的累计情况来确定。\u3000\u30001、BGF retail队 主教练:白大铉九段\u3000\u3000正规:姜东润九段、李志贤五段、李元荣五段、柳珉滢四段、崔精五段\u3000\u3000次级:李昌锡二段、洪茂镇初段\u3000\u30002、tbroad队:主教练:李相勋九段(大)\u3000\u3000正规:朴廷桓九段、李东勋五段、金升宰六段、姜儒泽七段、朴珉奎四段\u3000\u3000次级:金东昊五段、李鱼德东初段\u3000\u30003、韩国物价信息队 主教练:韩钟振九段\u3000\u3000正规:元晟溱九段、白洪淅九段、安国铉五段、朴承华七段、韩态熙五段\u3000\u3000次级:洪旼杓九段、宋泰坤九段\u3000\u30004、SK能源队: 主教练:崔圭丙九段\u3000\u3000正规:朴永训九段、安成浚六段、闵详然四段、李泰贤六段、姜升旼四段\u3000\u3000次级:黄宰渊三段、崔显宰二段\u3000\u30005、新安天一盐队主教练:李相勋九段(小)\u3000\u3000正规:李世石九段、赵汉乘九段、睦镇硕九段、申旻埈三段、李浩范五段\u3000\u3000次级:安正己初段、朴炫洙初段\u3000\u30006、Kixx队:主教练:金荣桓九段\u3000\u3000正规:金志锡九段、尹畯相九段、许映皓九段、金起用七段、崔宰荣初段\u3000\u3000次级:宋知勋初段、吴长煜二段\u3000\u30007、浦项队: 主教练:金成龙九段\u3000\u3000正规:崔哲瀚九段、罗玄六段、卞相壹四段、尹灿熙五段、柳秀沆四段\u3000\u3000次级:金民浩二段、朴材根初段\u3000\u30008、正官庄皇真丹队:主教练:金荣三九段\u3000\u3000正规:申真谞五段、李昌镐九段、金明训三段、韩升周二段、朴进率七段\u3000\u3000次级:洪基杓七段、李炯珍三段\u3000\u3000华城koriyo队:主教练:李廷宇九段\u3000\u3000正规:李映九九段、洪性志九段、金庭贤五段、朴正祥九段、安祚荣九段\u3000\u3000次级:高根台九段、朴河旼初段\n\n### 文章 113\n\n叶定仕故居\n叶定仕故居位于香港沙头角莲麻坑,建于约1907年,由莲麻坑村叶氏第八代叶定仕出资兴建。叶定仕于19世纪90年代初加入同盟会,积极支持孙中山的革命活动,因此叶氏建屋时仿照孙中山翠亨村的故居兴建。叶定仕故居的历史背景及建筑风格甚具价值,叶定仕故居曾被香港古物古迹办事处评为二级历史建筑,而政府于2009年11月刊宪,将故居提升为香港法定古迹。叶定仕生于1882年(有说1879年),乃莲麻坑叶氏的第8世祖。叶定仕年少时曾到泰国当裁缝,承包军服制作,并累积了一定财富。1908年孙中山到访泰国寻求海外华侨支援其革命事业,叶定仕因此成为同盟会的活跃份子,主持客家人加盟工作,并曾参与数次反清起义,辛亥革命后也曾参与反军阀运动。1936年,叶定仕于泰国的物业在当地的排华运动中被土匪霸占,叶定仕遂与家人回港定居于莲麻坑的住所。1943年,叶定仕在日本占领香港期间逝世。叶定仕故居混合中西建筑风格,使用木材及青砖建造。房屋外观为意大利式建筑风格,设计简约对称。整栋建筑楼高两层,每层各有3个房间,正立面设有门廊,并以方柱支撑著上层的阳台,而阳台的栏杆则以琉璃花瓶作装饰。屋顶采用中式金字瓦顶,而外墙则绘上吉祥图案的壁画。故居自1967年后丢空,屋内物品被人搜掠后大多已散失,连叶定仕的个人资料也消失无踪,包括他当年参与同盟会的文件。现时大屋日久失修,屋外杂草丛生,露台走廊木板破烂不堪,连外墙也需要木条固定支撑,以免倒塌。政府于2008年发表「边境禁区土地规划研究」,建议将莲麻坑剔出禁区范围之外,并活化区内包括叶定仕故居的古迹,冀以点、线、面方式,把具文化遗产价值的建筑物串连发展生态旅游,鼓励非政府组织把空置屋宇及已荒废学校发展作度假营,并设立文物径,将附近的古迹连接起来,促进旅游。\n\n### 文章 114\n\n帚石楠\n帚石楠(学名:\')是指杜鹃花科帚石楠属的植物,别名「苏格兰石楠」。在欧洲,帚石楠属与其同科近类欧石楠属经常遭到混淆,被互作训解的称号亦有不少(这种情况在汉语领域中更为明显)。虽然它们在生物分类上界线清晰,但在文化理解上却曾造成不少误会。两种花属的主要分别是帚石楠的花萼的裂片遮盖著花瓣,而欧石楠的花瓣则反过来盖著萼片。。帚石楠的学名"Calluna"源自希腊语,词义是「扫除」,意指用以制作扫帚的植物,因此被翻译成中文的「帚石楠」。英语对石楠花有「"Heath"」及「"Heather"」两种称谓,当中的「"Heather"」实际所指的正是帚石楠。帚石楠是挪威的国花,同时亦是容易令人联想到苏格兰的重要标志。帚石楠是一种多年生灌木,普遍高度有20至50厘米(亦有少数种类高至一米),大致分布在欧洲及小亚细亚地区,适合种植于有足够水分及阳光的酸性土壤上,习性耐寒,较难于高温潮湿的地区生长。帚石楠品性强韧,能存活于经历有限度放牧的地区,亦有机会在遭受山火焚焦后依然持续繁衍。帚石楠是欧洲一种著名地貌("Heath")植被的主要品种,广泛生长于酸土草原()及酸性泥炭湿地()。另外,帚石楠是多种反刍动物(如羊、鹿)与及部份鸟类(如松鸡)和昆虫(如有「帚石楠甲虫」之称的"")的主要食粮。帚石楠是相当受欢迎的观赏植物,许多花园及原野都种植了大量的帚石楠,在欧洲尤其闻名,曾经是西欧及北欧许多荒地的主要植被,因此有「山中薄雾(Mountain Mist)」的称号。当中最著名的帚石楠原野是位于德国北部的吕讷堡石楠草原。另一方面,帚石楠可制花茶,其花蜜亦具备药效价值。由于帚石楠的花卉部份相当美观,受到赏花者的普遍喜爱,因此出现了经由人工改良的帚石楠栽培种,衍生出不少在颜色、花瓣形态及成长习性方面都迥然不同的新品种。大部份新品种的帚石楠都以紫色为主,另外亦有白色、粉红色甚至红色的品种。北半球的帚石楠,开花期本来在七月的下旬,如今亦被人工扩展至十一月左右。而且部份帚石楠在冬季仍能保存,除了颜色会转变成棕色之外,花卉依然可以保持不凋谢的状态。帚石楠后来传入新西兰,却在当地成为了入侵物种。尤其在东格里罗国家公园里,帚石楠的过份繁衍更令当地政府感到忧虑。为解决帚石楠丛生的困扰,当局特意驱动大量「帚石楠甲虫("")」进食帚石楠,最终成功处理相关问题。\n\n### 文章 115\n\n项少龙\n项少龙,是黄易玄幻武侠小说《寻秦记》的男主角,是21世纪年轻特种部队成员。在电视剧中为香港警务处要员保护要人组(G4)成员。身为21世纪特种军人的他,在一次时光机器的实验被传送回战国时代,以假赵盘代真嬴政,凭其经历两千多年的智慧优势,频频化险为夷,并且帮助小盘成为日后统一六国的秦始皇。由于《寻秦记》的广泛流传,电视剧版由古天乐饰演,项少龙是黄易最广为人知的人物。。身为廿一世纪特种部队军人的项少龙,年轻力壮、风流多情,在一次时光机器的实验当中被送回公元前251年的赵国邯郸附近。投靠以马致富的大家族乌氏,而后更成为乌家快婿。一心想见未来秦始皇的他,在得知真正的嬴政已经死去后,以赵国公子赵盘代之,并且助乌氏及小盘逃离赵国。投靠秦国后,开始帮助小盘拓展形势、肃清异己,与吕不韦、嫪毐集团明争暗斗。虽然项少龙一心帮助小盘,但也使日渐成长的小盘对其猜忌。小盘成年加冕大典后,携乌氏家族及妻妾逃离秦国,从此不问世事。项少龙有四位肝胆相照的结义兄弟,排行老大是乌家战士之首乌卓,年纪约三十五岁;老二滕翼,武功高强,和项少龙多次出生入死;项少龙排行第三;老四王翦,秦国年轻高手,同时也是战国四大名将之一;老五荆俊,乃荆家村村人,身手敏捷,精于打探情报。项少龙还有多位六国朋友,较有交情的包括智谋与见识不凡的魏国龙阳君,对少龙「一往情深」;楚国李园,最初两人因争夺嫣然而为敌对关系,但后来少龙助其坐稳相国之位;韩国韩闯,生性好色,与少龙亦有交情。但项少龙对他们真挚的付出也曾因对方认为应以国家利益为重而遭背叛。墨家元宗,是项少龙的恩人兼师友,传授项少龙墨子剑法;韩公子韩非,曾助项少龙逃离魏国大梁;阴阳家代表邹衍,亦师亦友,多次相助项少龙。其他项少龙的好友包括赵国名将李牧,曾赠与少龙宝剑血浪,但后期秦赵交战时对敌;原本吕不韦门人肖月谭及图先,前者在得知吕不韦欲杀其之心后,逃离秦国,后者则为项少龙打探有关吕不韦的情报;秦国储君派中流砥柱李斯、昌平君兄弟等人。项少龙为人风流且重视感情,故妻妾成群,唯后期较为克制。另外,项少龙疑似在时空机器的穿越过程中影响到生育能力,故领滕翼第二子为继子,替其命名为项羽,视如己出,疼爱有加。项少龙的妻妾:此外,项少龙还有多名情人,有些是妻妾的随身婢女,有些则是深闺怨妇,但未必都有肉体上的关系。\n\n### 文章 116\n\n死或生 沙滩排球2\n是Xbox 360游戏机上的电子游戏,由Team Ninja开发。这是死或生系列《死或生 沙滩排球》的续作。同它的前作一样,《死或生 沙滩排球2》侧重于描绘海滩上的比基尼美女。由于增加了可游玩小游戏的数量而不再只有沙滩排球,所以将标题的“Beach Volleyball”去掉了。《死或生:沙滩排球2》采用了两个星期的休假模式,玩家可以尽情享受各种活动(如下所列)。每一天都分成三个部分(上午,下午和晚上),玩家每次可以执行其中一个活动。这个游戏十分强调友谊,玩家必须与其他女孩成为朋友,可以在岛上的商店给她们买她们喜欢的礼物,这样做将增加两角色之间的关系。如果两人之间的友谊在一个足够高的水平,对方可以被说服成为玩家的排球搭档。游戏以沙滩排球模式为主,另有多个小游戏包括水上摩托艇、踩浮板、沙滩抢旗、顶屁股、水上拔河、滑水、赌场等。游戏使用了《死或生4》所用引擎的增强版,新引擎支持自阴影和布料模拟等技术,而迷你游戏“水上摩托艇”使用了全新的物理引擎,虽然画面效果与其他小游戏类似。游戏中对乳摇系统进行了改进,以抑制乳房的异常摇晃,还增加了一个新的“棕黄色线系统”以防止泳装上出现棕黄色的分割线。《死或生:沙滩排球2》的游戏模式并不单一,其中包括若干个不同的子游戏。游戏最初设计了42个小游戏,最后只保留了7个(不包括沙滩排球)。在开发过程中,设计师板垣伴信表示他不会加入类似于蹦床比赛和湿T恤比赛的小游戏。他认为这是低级趣味并且“显示出妇女的负面形象”。在《死或生:沙滩排球2》中,玩家可以任意选择目前该系列中的九个女孩。游戏中每个女孩都有特定的物品和喜好,这些偏好会影响到她收到礼物时的反应。每个角色也都有各自最喜欢的颜色,这又会影响到他们对特定物品(和包装纸)的好恶。可供选择的角色有:需要注意的是,心并没有出现在《死或生:沙滩排球》中,并自此成为了可选的新增角色。
\n\n### 文章 117\n\n恶女花魁\n《恶女花魁》()是安野梦洋子于2001年起连载的漫画,现已停止连载。于2007年由蜷川实花拍摄成电影,演员一字排开土屋安娜、椎名桔平、成宫宽贵、木村佳乃、菅野美穗、小泉今日子、安藤政信、永濑正敏各个都是顶顶有名的大人物,再加上苹果歌姬-椎名林檎的配乐之下,成功的刻划出江户时期恶女花魁的传奇。「不知怎的,我就是会,我就是懂得怎么看男人才会使他们兴奋。」—— 清叶清叶在八岁(幼时小池彩梦饰)时,就被卖到游廓。起初是在花魁粧妃(菅野美穗饰)旁服侍,并学习如何成为花魁,而在花魁粧妃出嫁后,便把发簪象征性的传承给清叶。长大后的清叶(土屋安娜饰)不负粧妃的期待成了花街众所瞩目的焦点。但是自己却被迷恋许久的恩客抛弃,让她对爱情彻底失望,并发誓再也不要爱上男人,转而全心全意的投入工作,把服务男人当成一种技术,不久后她当上了花街上的首席-花魁。但是在她遇上武士-仓之助(椎名桔平饰)后,生活渐渐起了变化,而仓之助也趁势向她求婚,让清叶又惊又喜,但是却也害怕再次受到伤害,因此她说:「当花街下起樱花雨,我就嫁给你!」隔天,她被妈妈桑的声音吵醒,打开窗户,却见到令她永生难忘的美景-樱花雨。原来是仓之助将他处的樱花树全移到花街前,让这条街下起了缤纷的樱花雨。正当所有人都为了眼前的美景暂歇脚步之时,清叶在窗边流下了眼泪,不仅是感伤幼时离开家乡后就再没见过樱花雨,更重要的是也被仓之助所做的一切所感动。看来清叶非嫁不可了!游廓里的鸨母准备好华丽的嫁妆和衣裳,准备让她快乐的出嫁成为武士夫人。但,就在出嫁前一晚,她找到了她生命中的真命天子……原声带在电影上映前就已经发行了,而这张专辑也是椎名林檎暌违四年后所发行的专辑。\n\n### 文章 118\n\nLED背光液晶显示电视\nLED背光液晶显示电视(LED-backlit LCD television),是使用发光二极体(LED)作为背光源的液晶显示电视。部分电视机生产厂商,如三星、松下、东芝、飞利浦、乐金及索尼等将其称为LED电视,但此并不是指使用发光二极管作图像显示的电视。随著发光二极管电视市场竞争日趋激烈,加上发光二极管应用逐渐成熟,各家电视厂商纷纷积极导入发光二极管背光液晶显示电视,企图在家用电视改朝换代之际能够拔得头筹。发光二极管背光技术可分为直下式(direct back-lit或 full LED array back-lit)与侧照式(edge LED back-lit)两种,而当中直下式所使用的发光二极管有分为白光发光二极管与红、绿、蓝三色发光二极管两种。直下式发光二极管背光技术是把多枚发光二极管排成阵列,放在散光片及LCD后面,直接照射LCD。如此,直下式可以依从画面不同部份的光度变化,快速地微调发光二极管的明暗,大为提高动态对比度达至等离子显示器的水平。缺点也就是需使用数量较多的发光二极管,耗电、体积厚、价格较高。直下式发光二极管背光所使用的有白光发光二极管,也有使用红、绿、蓝三种单色发光二极管(RGB LED)的,使用RGB LED可以有更阔光频谱,也即有更广色域。侧照式发光二极管背光技术是把白光发光二极管放在LCD的四边,LCD后有一与LCD大小相近的反光片,发光二极管从LCD与反光片之间的缝中照进去,反光片上特别设计的微纹能把LED照来的光作90°反射后照向LCD的背部。此等反射片精细得在不需散光片的情况下也能使发光二极管的光平均地分布地照到LCD背部。相对RGB LED,白光发光二极管较为耗电,加上反光片有损耗及LED照射角等因素,侧照式LED原先的耗电会较高,但因为没有散光片,省去了散光片的损耗,侧照式LED背光的耗电可以做到与直照式同级。侧照式可以比直下式做的更轻薄,但色域及对比度都不及直下式。以往侧照式发光二极管背光不能依从画面不同部份的光度变化快速地调整光度,但最近有厂商成功以侧照LED技术有限度的依从画面变化快速地调整光度。以往薄膜电晶体液晶显示器的光源是采用冷阴极萤光灯作背光光源,(如图2)。两者的分别在于:\n\n### 文章 119\n\n米诺地尔\n米诺地尔()是一种钾通道开放药,这类药物在降压时常伴有反射性心动过速和心输出量的增加。对于血管扩张的作用具有选择性,见于冠状动脉,胃肠道血管和脑血管,而不扩张肾和皮肤血管。它还可以减低或停止掉发并且促进毛发再生。现在一般的门诊病人不需要处方就可以取得,用于。米诺地尔本来是用于控制高血压。后来偶然发现有一个有趣的副作用,就是扭转或减慢秃头过程。Upjohn推出了含2%的米诺地尔的外用药液,用来治疗秃头及脱发。该药液在美国及加拿大以Rogaine名称销售,在欧洲及亚太区则使用Regaine名称,在台湾译为「落建」。5%浓度的药液专供男性使用,而2%浓度的药液则适合女性使用。在台湾贩售的含5%浓度的米诺地尔成分生发药液产品如:落建生发系列的落健生发液、萌发生发液等。米诺地尔的专利保护期在1996年2月11日已经到期。5%泡沫配方的米诺地尔,跟液体配方一样有效。米诺地尔促进毛发生长的机转目前还未完全了解。此药物的结构式中有一氧化氮基团且可能做为一氧化氮的致效剂。它同样是,造成细胞膜的去极化。对于大面积的掉发,米诺地尔就比较没有效果。另外,对于年轻男性有五年以下的掉发困扰,它有非常显著的效果。目前,米诺地尔只用于的掉发。它同样也是个血管扩张剂。理论上,借由扩张血管及开通钾离子通道,使更多的氧气及养分到毛囊,会促使毛囊从休止期到生长期。常见的副作用有对眼睛的烧灼感及刺激性,治疗部位搔痒、红肿及刺激性,非预期位置的毛发生长。如果使用者有以下的严重副作用,立即寻求医疗照护:严重的过敏反应(红疹、荨麻疹、搔痒、呼吸困难、胸闷等);胸痛;晕眩;火烧心;立即且非预期的体重增加;手或脚的胀大。酒精和丙二醇可能会使头皮干燥,造成头皮屑和。有些配方改用奈米液滴为的就是减少因为酒精和丙二醇所造成的接触性皮肤炎。米诺地尔对猫来说是致命的。\n\n### 文章 120\n\n逆渗透\n逆渗透(Reverse osmosis),又称 RO、反渗透,是一种净化水的办法。原理是利用渗透作用,将清水(低张溶液)和咸水(高张溶液)置于一管中,中间以一支允许水通过的半透膜分隔开来,可见到水从渗透压低(低张溶液)的地方流向渗透压高(高张溶液)的地方。然若在高张溶液处施予力,则可见水由渗透压高的地方流向渗透压低的地方。逆渗透是“正渗透”的反向,通常比正渗透的自然过程,耗费更多的能量。正渗透分离技术,逐渐成为新趋势。顾名思义,逆渗透滤膜技术就是利用渗透的方法来从海水中提取出纯净的饮用水。渗透的英文“Osmosis”一词来源于希腊文“Osmos”,意思是一种推动力。1748年,莱诺对渗透现象进行了研究,并首次作了实验纪录,发现用膀胱把水和酒精隔开后,水可以通过膀胱进入酒精,但酒精不能进入水。根据科学的定义,渗透是某种溶剂通过半透膜(一种溶剂分子能通过,而溶质分子不能通过的薄膜)从低浓度到高浓度转移的现象。通过那种被称作“半透膜”的薄膜,我们可以对渗透现象看得更清楚。半透膜是一种对透过物质有选择性的薄膜。利用一张只准水分子透过,不许盐分子透过的半透膜,将一个容器分成两半。在膜的两侧分别注入纯水和含盐水,让两侧的高度一样高。过了一段时间后,盐水的液面升高,纯水的液面下降,这是由于纯水一侧的水分子透过半透膜在向盐水那侧转移。当渗透达到平衡时,盐水一侧的水柱高于纯净水一侧的水柱,这种现象产生于所谓的“渗透压”,这渗透压的高低取决于盐水浓度的高低。逆渗透能降低被处理水的总溶解固体(TDS),这是其他水处理原理所不具备的特征。逆渗透的水是目前水处理中最干净,水中除水分子外无任何矿物质或金属。导电性差。脱盐率等于脱去的盐量与进水含盐量的比值,即:准确的脱盐率要通过对产水和进水进行化学分析,测定相应的TDS 含量才能计算出来,但是这样比较麻烦,一般采用电导率转换为TDS 来计算脱盐率。具体的转换公式如下:其中渗透压公式如下:其中\n\n### 文章 121\n\n按司\n按司(琉球语首里那霸方言:或;先岛方言:)是琉球国历史上的地方行政单位,后来成为琉球国贵族和地方豪族的一种称号。自第二尚氏王朝起只有王族成员才可出任。按司家族是国王家族的分家,相当于日本的宫家、中国的藩王府,在贵族中,其地位仅次于王子。女性王嗣(翁主)亦可成为按司,女按司称为按司加那志(アジカナシ或アンジカナシ)。《中山世谱》等琉球史书称,琉球人是天帝的子孙。天帝派遣女神阿摩美久(アマミキヨ)和男神志仁礼久(シネリキヨ)来到人间,生三男二女,为琉球人的祖先。其中长子是天孙,其后代世为国王;次子为按司(诸侯)的祖先;第三子为百姓(平民)的祖先。但事实上早期琉球没有国王这个概念,各地区的首领自称「按司」,有时也会被祝女授予「世之主」、「世主」之类的神号。根据冲绳学学者伊波普猷的说法,「按司」是琉球语中「主」(アルジ)的转讹。按司最早作为地方势力的首领出现于12世纪,并在各地建立了一些御城,彼此互相争战。后来尚巴志王统一了琉球。但按司仍在地方拥有一定势力,参与过琉球国内的政变。直到尚真王时期,琉球朝廷下令收缴各地兵器,召各按司赴首里城居住后,按司割据势力才被消弱。此后按司从地方豪强转型为都市贵族,派遣名叫「按司掟」(アジウッチ)的官员管理自己的领地。此后,在第二尚氏王朝的位阶制度确定之后,按司成为了琉球王族的一个位阶。没有即位的王子,其长子会被授予按司的位阶。因此按司一般姓向氏,名乘头世袭为「朝」字。只有国头按司家(国头御殿)例外:该家族姓马氏,名乘头世袭为「正」字。这是因为国头按司家的祖先马顺德(国头亲方正格)对琉球王室有重大功绩,曾救了尚元王一命。为了报恩,尚元王特别授予其子孙王族的待遇和按司的位阶。琉球王府征服奄美群岛和宫古群岛之后,这两个地区的酋长并没有被授予按司的称号。奄美群岛的酋长称「大亲」(ウフヌシ或ウフヤ),而宫古群岛的酋长则称「丰见亲」(トゥユミャ)。高级按司敬称为御殿(ウドゥン);低级按司的敬称为御前(ウメー),其子孙称按司前(アジメー)。一般笼统的称为御殿。按司的采地称按司地头。原则上,按司同亲方一样,会被授予一个间切的地头。受日本文化影响,有时也把领有一个间切的按司称为「大名」(デーミョー)。据《琉球藩臣家禄记》记载,琉球国末年共有25家按司。这25家分别是:\n\n### 文章 122\n\n荨麻\n荨(qián)麻是荨麻属中大约30-45种植物的通用俗称,广泛分布在全球的温带和热带地区。绝大部分种类为多年生草本植物,也有部分为灌木,或一年生草本植物。叶对生,有齿牙或分裂,有托叶,花单性,穗状花序或圆锥花序,瘦果藏于宿存花被内。最常见的品种为异株荨麻("Urtica dioica"),原生于欧洲、亚洲、非洲和北美洲。此外尚有下表所列的100多种也都被称为“荨麻”,绝大部分种类都有刺毛,蛰人会引起痛苦刺痒,其中生长在新西兰的木荨麻("Urtica ferox")曾经有记载毒刺杀死过马、狗,还曾经杀死过一个人。荨麻所含的毒性组成上没有完全研究确定,大部分荨麻种类中含有蚁酸、色胺和组胺,但根据最新研究证明咬人荨麻("Urtica thunbergiana")中还含有草酸和酒石酸 (Fu et al, 2006)。此外尚有一些其他属的蛰人植物,也被俗称为“荨麻”,如:由于其毒性,一般昆虫不会食用荨麻叶,但某些特定的昆虫,如孔雀蛱蝶("Inachis io")和小蛱蝶的幼虫以荨麻叶为食。其他如白蝙蝠蛾("Hepialus humuli")的幼虫会食用荨麻的根。荨麻的药用是作为一种催乳剂,曾经试验用荨麻的叶汁作为慢性郁血性心衰竭病人的利尿剂。民间偏方用荨麻刺激皮肤可以缓解风湿病造成的痛苦。荨麻制剂可以止痛、用于治疗关节炎、贫血症、干草热可肾脏疾病。用在洗发液中可以防止头皮屑,据说还可以医治湿疹。荨麻根的提取物曾试验用于良性前列腺增生治疗。由于鲜荨麻叶含有高浓度的维生素K,民间用其在受伤时止血。可作为利尿剂、去痰剂、止痛剂和滋补剂。对于良性前列腺增生、贫血、关节炎、风湿病、干草热、其他过敏性的疾病、肾脏疾病和吸收不良症候群有益。改善甲状腺肿、发炎情况和肺部黏液情形。用于头发的保养产品上,有助于刺激头发毛囊和调节头皮油脂的聚集。荨麻叶浸泡后可以去除其毒性食用,尤其是嫩芽非常可口,含有高蛋白,适宜作汤或作为蔬菜,用荨麻叶作汤在北欧尤其流行。荨麻茎可以用于造纸、纤维可以用于纺织工业,纤维比较粗糙。\n\n### 文章 123\n\n张容轩\n张容轩,台湾男子篮球运动员,目前效力于金门酒厂篮球队。张容轩从小在金门长大,高中就读新荣高中,2006年代表出赛HBL获得MVP。高中毕业后目标就读师范体系,原锁定高师大,后因师大有名额因此往台北发展。在球队选择上,因大专条款最终选择SBL而放弃大专联盟,效力台银队。张容轩当时决定效力台银的主要原因有:一、相较于其他明星球队,在台银的上场机会较多。二、台银的入行条件很吸引他,为篮球生涯退休后的生活做准备。张容轩的体能条件不算特别优异,特别的是他用脑打球,理解比赛的能力过人,台银教练韦陈明就说张容轩是个模范球员,从不迟到、态度正确也很受教。在99学年度UBA大专篮球联赛帮助台师大夺得大专篮球联赛(UBA)男子组冠军,缔造队史首度3连霸,并获选为冠军赛最有价值球员MVP。 张容轩赛后说:「想把这个奖分享给队上每个人,台师大每个人都有资格拿MVP!」成为台湾极少数拥有高中大学两大联赛的最有价值球员得主。加入金门酒厂篮球队后,以平均15.2分的成绩拿下第八季SBL年度最佳进步奖。张容轩于第8季超级篮球联赛转入金门酒厂篮球队,第9季超级篮球联赛转到新任总教练贾凡领军的台湾大篮球队。第11季SBL超级篮球联赛以场均13.1分、3.4篮板、1.4助攻入选「年度第1队」,甚至继第8季后,再度夺下「年度最佳进步奖」,张容轩表示,「对我来说,『进步奖』才是我认为的最大奖,这代表大家都看到你持续进步,每年我都以此奖为目标持续努力成长。」在兵多将广的台湾大突破重围,一举抱回生涯第二座年度进步奖并入选为年度最佳第一队,最佳五人的肯定,创下自己生涯的高峰。台湾大篮球队并在第11季SBL超级篮球联赛打进队史的第一次总冠军赛。球季过后入选中华白队,代表参加第五届亚洲杯男篮锦标赛,拿下历史以来最佳的银牌成绩。台湾啤酒篮球队总教练阎家骅今天证实,台啤和张容轩签4年合约,张容轩已随队练球。第十三季SBL超级篮球联赛台湾啤酒篮球队击败璞园建筑篮球队拿下总冠军,缔造篮球生涯大满贯(HBL,UBA,SBL)都有冠军的纪录。\n\n### 文章 124\n\n黑塔VI 苏珊娜之歌\n《苏姗娜之歌》()是美国小说家史蒂芬金所写的长篇奇幻小说黑塔系列中的第六集。台湾由皇冠出版社出版,内地简体版则由人民文学出版社于2008年3月出版,英文原版早于2004年6月出版,当中相距近四年。曾于2005年提名轨迹奖「最佳奇幻小说」。枪侠们打败了卡拉的狼群后,苏姗娜的另一个意志米亚抢夺了苏姗娜的身体逃到了1999年的纽约,由于逃走时同时带走了黑十三,使得门洞失去了魔力,由此枪侠只好求助古老的民族曼尼族,透过-{zh-hans:曼尼族; zh-hant:曼宁}-的磁石,时空之门重新恢复了魔力,但枪侠并不能随心所欲选择目的地,结果杰克、卡拉汉神父及仔仔去到了苏姗娜的时空,罗兰及埃蒂则去到了二十三岁史蒂芬金的年代,1977年。米阿到了纽约后,由于人生路不熟,不知道如何应付,苏姗娜便以协助米阿延下婴孩为交换条件,换取婴孩的秘密,结果发现婴孩原来是罗兰的,米阿原来是吸取杰克精力的神喻,又是强暴苏姗娜的-{zh-hans:恶灵; zh-hant:通灵魔}-。虽然苏姗娜一直拖延时间,并且不断透过精神向埃蒂发出讯号,但还是等不到枪侠的救援,被送到吸血鬼及低等人的地方。由于米阿的告密,黑帮老大巴拉扎预早埋伏,枪侠一离开时空之门便遇到偷袭,幸好得到管理员卡伦的帮助,枪侠才可以逃出生天,后来他们找到了-{zh-hans:塔尔; zh-hant:卡文·塔}-及-{zh-hans:深纽; zh-hant:亚伦·狄普诺}-两人,原来深纽一直都不希望卖掉玫瑰下的土地,而且一直高调行事,惹得枪侠很不满,最终在枪侠的威逼利诱及朋友的劝告下,-{zh-hans:塔尔; zh-hant:卡文}-心有不甘地将给枪侠的泰特集团。两人后来又去了找史蒂芬金,发觉自己的确是史蒂芬金的笔下人物,但在血王的扰乱下,史蒂芬金只写了第一部的手稿就放弃了,罗兰于是利用催眠促使他继续写下去。\n\n### 文章 125\n\n帚石楠\n帚石楠(学名:\')是指杜鹃花科帚石楠属的植物,别名「苏格兰石楠」。在欧洲,帚石楠属与其同科近类欧石楠属经常遭到混淆,被互作训解的称号亦有不少(这种情况在汉语领域中更为明显)。虽然它们在生物分类上界线清晰,但在文化理解上却曾造成不少误会。两种花属的主要分别是帚石楠的花萼的裂片遮盖著花瓣,而欧石楠的花瓣则反过来盖著萼片。。帚石楠的学名"Calluna"源自希腊语,词义是「扫除」,意指用以制作扫帚的植物,因此被翻译成中文的「帚石楠」。英语对石楠花有「"Heath"」及「"Heather"」两种称谓,当中的「"Heather"」实际所指的正是帚石楠。帚石楠是挪威的国花,同时亦是容易令人联想到苏格兰的重要标志。帚石楠是一种多年生灌木,普遍高度有20至50厘米(亦有少数种类高至一米),大致分布在欧洲及小亚细亚地区,适合种植于有足够水分及阳光的酸性土壤上,习性耐寒,较难于高温潮湿的地区生长。帚石楠品性强韧,能存活于经历有限度放牧的地区,亦有机会在遭受山火焚焦后依然持续繁衍。帚石楠是欧洲一种著名地貌("Heath")植被的主要品种,广泛生长于酸土草原()及酸性泥炭湿地()。另外,帚石楠是多种反刍动物(如羊、鹿)与及部份鸟类(如松鸡)和昆虫(如有「帚石楠甲虫」之称的"")的主要食粮。帚石楠是相当受欢迎的观赏植物,许多花园及原野都种植了大量的帚石楠,在欧洲尤其闻名,曾经是西欧及北欧许多荒地的主要植被,因此有「山中薄雾(Mountain Mist)」的称号。当中最著名的帚石楠原野是位于德国北部的吕讷堡石楠草原。另一方面,帚石楠可制花茶,其花蜜亦具备药效价值。由于帚石楠的花卉部份相当美观,受到赏花者的普遍喜爱,因此出现了经由人工改良的帚石楠栽培种,衍生出不少在颜色、花瓣形态及成长习性方面都迥然不同的新品种。大部份新品种的帚石楠都以紫色为主,另外亦有白色、粉红色甚至红色的品种。北半球的帚石楠,开花期本来在七月的下旬,如今亦被人工扩展至十一月左右。而且部份帚石楠在冬季仍能保存,除了颜色会转变成棕色之外,花卉依然可以保持不凋谢的状态。帚石楠后来传入新西兰,却在当地成为了入侵物种。尤其在东格里罗国家公园里,帚石楠的过份繁衍更令当地政府感到忧虑。为解决帚石楠丛生的困扰,当局特意驱动大量「帚石楠甲虫("")」进食帚石楠,最终成功处理相关问题。\n\n### 文章 126\n\n伊拉克王国\n伊拉克王国(阿拉伯语:),是英属美索不达米亚托管地结束之后,所诞生的一个主权独立国家。始于1921年国王费萨尔一世即位,直到1958年被阿比德·阿尔·卡里姆·卡希姆所领导的血腥革命推翻。费萨尔在即位后,伊拉克于1932年被允许独立。这让伊拉克成为凡尔赛和约签署之后,第一个成立的国家。然而英国仍然在其境内保有军事基地;费萨尔一世死后,由加齐继位,直至1939年他因车祸而逝世为止。阿拉伯民族主义者一再要求英国人离开伊拉克,但为英国所拒。伊拉克是依照与英国于1930年所签署之协定,在1932年获得法理上的独立;因此英国结束托管;而伊国仍允许其之顾问协助处理事务并保有军事基地,以便在战时协防。独立后,由于政治情势的紧张使英国势力仍存在于伊拉克。政府内部也分裂为以努里·赛义德为首的亲英派,以及Rashid Ali al-Gaylani代表之反英派。1936年至1941年间,伊拉克军方发动五次政变,迫使当局让步以为回应。1941年的政变推翻了努里·赛义德,改由Rashid Ali al-Gaylani执政。阿里虽未终结王室,但使之更为顺从;并试图限制英方在1930年的条约中所拥有之权益。同年4月30日伊拉克军队自行在南部的高地上建立哈巴尼亚空军基地,派特使前往请求。英国拒绝,然后要求伊拉克军队离开该地区。殆5月2日最后通牒到期后,遂于清晨5点开始轰炸伊拉克军队以胁迫之;敌对行动从4月18日持续至1941年5月30号,此后英国又占领伊拉克多年。英伊战争结束后,赛伊德复任首相并支配政坛直到1958年王室被推翻为止。在他执政期间推行亲西方的政策。1958年伊国军方发动政变,费萨尔二世及王室成员被杀害,是为7月14日革命。阿比德·阿尔·卡里姆·卡希姆夺权,宣告退出中部公约组织改和苏联建立友好关系,伊拉克王国就此灭亡。\n\n### 文章 127\n\n爱姬\n爱姬(1568年5月13日-1653年2月21日)是安土桃山时代至江户时代前期的女性人物。田村清显的独生女。母亲是相马显胤的女儿于北。伊达政宗的正室。通称田村御前,院号为阳德院。天正7年(1579年),以12岁的虚岁嫁给伊达政宗。然而之后,政宗对于自己的暗杀未遂的事件,怀疑有来自田村氏的内通者与这件事情有关联,于是杀害了她的乳母并且赐死了多数跟随爱姬过来的侍女,于是有一段时间,夫妇之间的感情也因此恶化。之后,两人的关系才有所改善,她自己也移居到京都聚乐第的伊达藩住宅中、文禄3年(1594年)生下五郎八姬(松平忠辉正室)。在这之后陆续生下忠宗(仙台藩二代藩主)・宗纲・竹松丸等四个孩子(由于田村家除了爱姬以外就没有其他子女,因此在要和政宗结婚时,附上夫妇二人的次男要作为田村家养子的条件,但是次男的宗纲在16歳夭折。之后的竹松丸也跟著夭折,于是为了复兴田村家而迎来忠宗的三男宗良作为养子)。爱姬在聚乐第的伊达藩住屋居住时,可以说是发挥了女性外交官的功能告知政宗京都的情势并且还送给他「天下至今还未平定下来。请殿下一定要跟随天地的大义。请不用考虑我的安全。我会时常携带著匕首并且发誓绝不会受到污辱」()的信件,可说是相当程度发挥了贤内助的功能支持著政宗。宽永13年(1636年)5月24日政宗过世后,进入瑞岩寺的云居禅师门的佛门下并且改称为阳德院。在政宗的第17忌前,由她命令而制作了木造的政宗像,这座雕像因为作为能够了解政宗面貌的史料而相当珍贵。承应2年(1653年)1月24日,爱姬以86岁之龄死去。与政宗一样在24日同日过世。墓所位于与瑞巌寺紧临的阳德院。爱姬曾数度向政宗和忠宗请求复兴娘家田村家。在「阳德院様御梦想之书付」中有爱姬亲自写上纤细的仮名字「」(),这是在昨夜的梦中看到鲜色花枝的意思,在封套上记载的是忠宗正室怀有宗良时梦见的东西。忠宗根据母亲的遗言,在母亲死去同年令宗良继承田村家。(『』)\n\n### 文章 128\n\n加拿大广场 (温哥华)\n加拿大广场(英文:Canada Place)是一座位于加拿大卑诗省温哥华市中心的建筑物,是温哥华会议中心东翼、泛太平洋酒店、温哥华世贸中心、以及全球首座永久性IMAX 3D 影院的所在,并由加拿大广场公司(Canada Place Corporation)管理。它也是卑诗省南岸地区的主要邮轮码头,由温哥华前往阿拉斯加的邮轮皆从此处出发。大楼顶部有五组由玻璃纤维制成的白帆,是温哥华最主要的地标之一,其设计也与悉尼歌剧院和丹佛国际机场的外部有所相似。大楼造价3亿6千5百万加元,由加拿大建筑师设计。加拿大广场所处的前身是加拿大太平洋铁路公司的码头乙和码头丙。两座码头于1955年关闭,而联邦政府、卑诗省政府和温哥华市政府则从1978年起著手规划该处的重建项目,并于1982年成立加拿大海港广场公司(Canada Harbour Place Corporation;后于1993年改为现称)以将该处发展成1986年世界博览会的主办国展览场馆。加拿大广场于1983年动工,顶部五帆于1984年9至10月期间陆续竖立。泛太平洋酒店率先于1986年1月5日开幕,而加拿大展览场馆则与世博会于同年5月2日同步开放。温哥华会议中心(当时称为温哥华贸易及会议中心)则留待世博会过后于1987年7月4日开幕。加拿大广场座落布勒内湾沿岸,而世博会的其他场馆则位于市中心另一端的福溪沿岸,两者由同为世博会而建的温哥华架空列车捷运系统连接。大楼于2001年进行扩建工程,增设多一个邮轮泊位。而大楼对出的西北处是温哥华会议展览中心新翼的所在,工程于2004年11月展开,并于2009年4月竣工。2010年冬季奥运会的国际媒体中心位于新翼以内。冬奥过后,加拿大广场于2010年7月展开五帆屋顶更新工程。新五帆屋顶由聚四氟乙烯和玻璃纤维混合制成,外貌与旧五帆相若。计划耗资2100万元,由联邦政府支付,预料需时七个月。大楼内的IMAX影院于2009年关闭。\n\n### 文章 129\n\n陆军幼年学校\n陆军幼年学校,为旧日本陆军为了从幼年培养干部将校候补所设立的全住宿制教育机构。模仿普鲁士的军事学校()设立,毕业生拥有旧制中学校二年级毕业生的程度。1870年(明治3年)横滨语学研究所编入大阪兵学寮便是日本陆军幼年学校的开始。1871年(明治4年)大阪兵学寮被分开为陆军兵学寮与海军兵学寮,同年迁移到东京。1872年(明治5年)伴随著陆军兵学令的更改,陆军兵学寮幼年学舍改名为幼年学校。1874年陆军士官学校从兵学寮独立后,隔年幼年学校也改名为陆军幼年学校并从兵学寮独立。1877年并入日本陆军士官学校而暂时消灭。至1887年,随著陆军士官学校官制、陆军幼年学校官制的制定而再度设立。1897年时,因应军备扩张政策而增加培育人才数量,废除了陆军幼年学校官制,取而代之的是中央幼年学校条例与陆军地方幼年学校条例。东京为陆军中央幼年学校,另外于仙台、名古屋、大阪、广岛、熊本设立陆军地方幼年学校。每校各有约50名学生,中央幼年学校为14岁开始的2年,地方幼年学校为13岁开始的3年就读。陆海军士官的子嗣可享学费半价,战死者遗腹子学费全免。因为制服的领口有金星标志,也被称为「星的学生」。于校内学习军事学与普通学问,毕业生约占陆军将校的三分之一。被当时的人认为是陆军的旧制中学校。不过在当时陆军认为出身自文部省管辖的中学校,接受自由教育的人才不能信任,要想在陆军里出人头地除了日本陆军大学校毕业外,陆军幼年学校毕业也是重点。1918年(大正7年)制定陆军幼年学校令,陆军中央幼年学校与陆军地方幼年学校都改名为陆军幼年学校。1922年,由于华盛顿海军条约世界各国均开始缩减军备,同年大阪校废校。1923年名古屋校、1924年仙台校、1927年熊本校、1928年广岛校依序废除后,仅剩中央幼年学校。广岛校废除该年,中央幼年学校改编为日本陆军士官学校预科。1936年中国战线扩大所致,先是广岛幼年学校复校。之后1937年仙台幼年学校、1939年熊本幼年学校、1940年大阪幼年学校、名古屋幼年学校依次复校。大阪幼年学校移往离楠木正成居城很近的千代田村(现在的河内长野市),1940年4月1日时共150名44期生入学。太平洋战争结束后,日本陆军幼年学校与日本陆军士官学校一起遭到废除。\n\n### 文章 130\n\n龚鹏程\n龚鹏程,台湾教育家、作家,出生于台湾台北市,籍贯江西省吉安市,曾任《国文天地》总编辑、台湾学生书局总编辑,是台湾佛光大学与南华大学的创校校长、中华武侠文学学会会长,现任卢森堡欧亚大学马来西亚校区校长,游历中国大陆,任北京大学客座教授、南京大学客座教授、北京师范大学特聘教授、四川大学讲座教授,作育英才无数,著作七十余种。少年时代钟情中国武术,并由习武而博考文献,获得许多文献学的知识与方法。龚鹏程一直对于台湾的部分「本土派」学者的台湾文学研究论点与研究方法表达不满;1997年,他发表自著《台湾文学在台湾》,批评该类学者惯用的单线叙述法及其造成的简化历史等问题。2005年9月11日,玄奘大学中国语文学系兼任讲师杨宗翰说,他就读硕士班时改攻台湾文学,因此深知,囿于文化认同上的差异,台湾许多本土派学者都非常讨厌龚鹏程,却又没办法跳过或忽视龚鹏程所提出的诸多尖锐质疑。2003年12月11日,《台湾壹周刊》第133期报导,2000年10月佛光人文社会学院校长龚鹏程带诺贝尔文学奖得主高行健与该校十余名教职员去宜兰县礁溪乡富野酒店喝花酒,2001年2月龚鹏程再次带高行健喝花酒。2003年12月15日,高行健从法国传真声明稿给龚鹏程与该校教授马森,批评该文报导不实,请马森代他要求《台湾壹周刊》公开更正并回函道歉,否则提告;龚鹏程则说,没有一起喝花酒之事。《台湾壹周刊》总编辑裴伟表示,该文内容皆是采访「佛光山能参与事情的人」而得,采访过程皆有录音、记录,也向龚鹏程求证,并写入龚鹏程否认的话,已平衡报导;该刊将再做进一步求证,如有错误,将予更正。2003年12月18日,《台湾壹周刊》在《台湾苹果日报》刊载四分之一篇幅的道歉声明向高行健道歉;同日,高行健批评,该篇道歉声明毫无诚意,该刊必须发表有诚意的道歉声明向该文涉及的所有受害当事人公开、郑重道歉,并向读者保证将杜绝造谣、不实的报导;裴伟回应,该刊会在下期刊登道歉声明,但绝对不会对龚鹏程道歉,因为关于龚鹏程的部分有全部的证据。《台湾壹周刊》第135期刊登道歉声明,向高行健道歉。\n\n### 文章 131\n\n戴龙·罗伯斯\n戴龙·罗伯斯(,),西班牙语音译为戴龙·罗夫莱斯,古巴田径运动员。2008年6月12日,在捷克田径大奖赛的男子110米栏比赛中跑出12秒87的好成绩,打破中国选手刘翔保持的12秒88世界纪录。2008年7月19日,罗伯斯跑出了12秒88的前世界纪录成绩,成为了该项目第一位亦是正常风速下唯一能两次跑进12秒90大关的选手(刘翔曾在2012年初在超风速的赛场平世界纪录),充分证明了他是世界第一的地位。罗伯斯是第一位可以七步上栏架的跨栏选手,在现今110米栏项目里只有诸如中国的刘翔等少数选手可以做到,因此在跨越首栏上罗伯斯能占尽先机,而且其三步过栏技术十分纯熟,这也解释了他为何能屡创佳绩。此外,他也有少许看不起刘翔,经常挖他的事来说,并有意和他争夺世界第一的位置。-{zh-hk:罗伯列斯;zh-hans:罗伯斯;zh-tw:罗伯斯;}-在预赛里无成绩被淘汰,原因是他认为同组的刘翔抢跑犯规而没有起跑。但是当季他屡创佳绩,因此该次比赛被认为是他在2008年里的一大挫败。8月21日罗伯斯代表古巴队在北京出赛男子110米栏,轻松地以收步姿态12秒93夺得金牌。在柏林举行的第12届世界田径锦标赛110米栏预赛中,罗伯斯在最后5米收步并以小组第三名13秒67晋身准决赛。在准决赛,他于第三组第七线出赛,跑了三个栏就停下来并未完成赛事。在2011年8月29日晚举行的第13届世界田径锦标赛110米栏决赛中,罗伯斯以13秒14的成绩夺取冠军,但随后被国际田联取消成绩,原因是比赛过程中罗伯斯故意干扰相邻赛道的刘翔。8月8日罗伯斯代表古巴队在伦敦出赛男子110米栏,轻松地抛入决赛,但是在决赛中由于大腿肌肉拉伤未能完成比赛,成为本届比赛中第二位未能完成比赛的前奥运跨栏冠军。戴龙·罗伯斯的女友是一位古巴歌手,当他有空闲时间时,总是会去听女友的演唱会,以舒缓压力和补充动力。\n\n### 文章 132\n\n九龙巴士32B线\n九龙巴士32B线是香港新界的一条已取消循环巴士路线,来往荃湾西铁路站及象山邨。本线曾经是香港唯一一条全线采用非空调巴士的专营巴士路线,但此纪录只维持了12天,最终于2011年8月20日加入空调巴士行走,象征九巴以至全港专营巴士路线全非空调巴士的时代告终。直至2012年4月16日改为空调巴士行走。$4.1(已经在3月17曰加价)最初以「亚比安」单层巴士及丹拿A型双层巴士行驶。到了1990年代采用利兰胜利二型巴士行驶。本线亦是九巴最后一条以利兰胜利二型巴士行走的路线,最后一天行走为1998年3月29日(G544),但随著利兰胜利二型巴士年事已高需退役,本线改为以3轴双层巴士行驶,一直维持至今。取消前全线共有1辆富豪奥林比安11米(AV)及2辆丹尼士三叉戟12米(ATR)空调巴士。由于本线受到多线公共及专线小巴(82M)的竞争,加上班次疏落,收费亦缺乏竞争力(本线早在加入空调巴士行走前20年,小巴则早已有空调设备,而且收费又较本线便宜),在平日繁忙时间以外极少乘客会刻意等候本线,以致整体客量一直偏低,乘客绝大部份都是长者,因此九巴已经对本线采取放弃态度。多年来,九巴一直想更改本线的营运模式,甚至多次提出建议永久停驶本线,但都无功而回,不是遭到民众及区议员反对,就是遭运输署否决建议,而且象山邨及石围角邨都已是老化屋邨,若本线停驶,长者在毫无选择下只好乘搭小巴,小巴营办商因怕收入减少,并希望九巴蚀本营运,而不肯设任何长者优惠,使区议员和居民有理由去阻止九巴停驶本线。鉴于本线被取消的机会非常渺茫,九巴决定作出让步,于2011至2012年路线发展计划中,计划于2012年加入空调巴士行走本线,并于2011年8月20日起正式实施,并于翌年4月16日改为全空调服务。由于本路线长期客量不高,根据2013至2014年度计划,本线将会并入36线,届时36线改为循环线,荃湾西站开出先绕经石围角及象山后返回梨木树原有路线行走再返回荃湾西站。而石围角邨往荃湾的工作将由途经的43X线减低收费至目前水平取代。上述重组计划已于2013年11月30日实施。\n\n### 文章 133\n\n迟子建\n迟子建(),中国女作家,出生于中国最北端的黑龙江省漠河县的北极村,2008年凭借《额尔古纳河右岸》荣膺第七届茅盾文学奖,是中国具有广泛影响力的作家之一。迟子建,汉族人,长期生活在哈尔滨,其父迟泽凤是小学校长,好诗文,因极喜爱三国时代作家:曹植(字子建)的名篇《洛神赋》,因此为她取名“迟子建”。1981年,迟子建考入大兴安岭师范学校,并于在校期间的1983年开始写作,其处女作在《北方文学》上发表。1986年,迟子建在《人民文学》上发表《北极村的童话》一文,从而成名。1988年,迟子建求学于西北大学作家班,次年考入北京师范大学和鲁迅文学院合办的研究生班学习。1990年,迟子建毕业后返回黑龙江并在作协工作至今,成为全职作家,现是国家一级作家。1998年,迟子建与黄世君(曾任塔河县县委书记)结为夫妻。2002年5月,黄世君因车祸不幸罹难,迟子建深受打击,但她坚强地从悲痛中走了出来,并把更多的时间用于写作,相继写出了《世界上所有的夜晚》、《越过云层的晴朗》等作品。2005年,迟子建在《收获》上连载《额尔古纳河右岸》,该小说描写了中国东北少数民族鄂温克族人的生存现状及其历经的百年沧桑,其文学主题具有史诗品格与世界意义。迟子建的文风沉静婉约,描写细腻生动,语言精妙,具有一种淡淡的伤怀之美,给人以巨大的文学震撼,因此,获得了许多读者的喜欢与青睐,其粉丝自称为“灯谜”(源自她的小名“迎灯”)。1996年,迟子建以短篇小说《雾月牛栏》获得首届鲁迅文学奖。2000年,迟子建以《清水洗尘》再获鲁迅文学奖。2007年,迟子建以中篇小说《世界上所有的夜晚》第三次获得鲁迅文学奖。她是唯一一位三次获得鲁迅文学奖的作家。2008年,迟子建凭借小说《额尔古纳河右岸》获得中国长篇小说的最高奖项——第七届茅盾文学奖。获奖评语中称这部作品是“一部风格鲜明、意境深远、思想性和艺术性俱佳的上乘之作。”2016年,《群山之巅》获得第六届红楼梦奖专家推荐奖。\n\n### 文章 134\n\n绝对收敛\n绝对收敛是数学中无穷级数和广义积分的一种性质。一个数项级数或一个积分绝对收敛当且仅当级数的每一项或者积分的函数取绝对值(或范数)后仍然收敛或可积。比如,一个实数项或复数项级数 formula_1绝对收敛当且仅当formula_2。某个函数formula_3的广义积分或瑕积分formula_4是绝对收敛的,当且仅当取绝对值或范数后的函数的积分收敛:formula_5。一个积分绝对收敛的函数也称为绝对可积函数。在无穷级数的研究中,绝对收敛性是一项足够强的条件,许多有限项级数具有的性质,在一般的无穷级数不一定满足,只有在绝对收敛的无穷级数也会具有该性质。例如任意重排一个绝对收敛的级数之通项的次序,不会改变级数的和,又如,两个绝对收敛的无穷级数通项的乘积以任何方式排列成的级数和都为原来两个级数和的乘积。收敛但不是绝对收敛的无穷级数或积分被称为条件收敛的。绝对收敛是建立在实数绝对值、复数的模长以及更一般的,向量的范数概念之上的。绝对值、模长都是范数概念的特例。给定一个向量空间formula_6,范数formula_7是将formula_6中元素映射到非负实数上的一个函数,并且满足以下性质:装备了范数的向量空间formula_6被称为赋范向量空间,可以定义距离:formula_13这样可以定义formula_6上的拓扑结构,从而定义收敛乃至绝对收敛。设有由formula_6中元素组成的级数:formula_16,则此级数绝对收敛当且仅当由每一项向量的范数构成的正项级数formula_17收敛:当级数的每一项是实数或复数时,对应的是实向量空间formula_19和复向量空间formula_20,这时对应的范数是实数的绝对值和复数的模长,都写作formula_21,所以实数项或复数项的级数绝对收敛,当且仅当由每一项元素的绝对值或模长构成的正项级数formula_17收敛:如果赋范向量空间formula_24是完备的(即所谓的巴拿赫空间),那么formula_6中绝对收敛的无穷级数必定收敛。反之,如果formula_6中绝对收敛的无穷级数必定收敛,那么可以推出formula_24是巴拿赫空间。\n\n### 文章 135\n\n罂粟籽\n罂粟籽,又名御米、芥子,罂粟的种子,是一种在世界各地广泛使用的调味料,可用于制油,许多地区也将它当成一种草药来使用。一般使用方法为原粒或经研磨后,加入烘焙食品或酱料中以增加食品风味。有记载在苏美文明时代,人类已经会使用罂粟籽。罂粟籽的形状如肾脏,长度通常少于一毫米。除制作鸦片的罂粟外,其他罂粟目植物的种子一般不会作为食物用途。罂粟可用部分包括枝、叶、壳等,其中罂粟籽中的麻醉性生物碱含量最少。罂粟籽富含膳食矿物质,如钙、铁、镁、磷、钾等,营养丰富,被作为调味料广泛使用。在1992年,国际标准ISO676-1982中已将罂粟籽列入调味料名录。中国于1991年颁布的《香辛料和调味品名称和内含物的测定》标准中,“香辛料和调味品名称表”也明确标明“罂粟,可使用部分,如种子”,但受到严格管制,只有完全灭活的罂粟籽才能上市销售。另外,《美国联邦政府条列手册》、《大英百科全书》等,均记载罂粟籽为安全可食用物质。罂粟籽中含有少量鸦片生物碱,跟吗啡和可待因成份相同,虽然含量较低,不致于对人体造成影响,但食用后有可能造成药检阳性反应 。不过基于这个理由,新加坡及沙特阿拉伯均禁止售卖罂粟籽。罂粟原产于地中海,现主要产地为荷兰与加拿大。地中海一带使用罂粟籽有悠久历史,在面包、蛋糕,曲奇饼上均有使用。在中欧地区,罂粟籽夹心馅饼是一道流传甚广料理,在圣诞节时尤其受欢迎。在巴尔干半岛,罂粟籽甚至会用于制作糖果上。在印度、伊朗等地的一般家常菜肴,亦不时加入罂粟籽。日本七味粉中,也可以加入罂粟籽。罂粟籽含油50%,可榨油。榨出的油称为罂粟籽油或御米油。根据《中药大辞典》,罂粟籽性甘平无毒,治反胃、腹痛、泻痢、脱肛,功能有敛肺,涩肠、止痛。主治久咳、久泻、久痢,胸腹诸痛等症。\n\n### 文章 136\n\n说明文\n说明文是按实际情形加以说明。用客观的角度来解释事物、说明事理的文章就称为说明文。方位说明:用方位词表示方位。分类说明:根据事物的性质、功能等一定标准分门别类,逐一说明。好处是能把复杂的事物条理分明地解说清楚。数据说明:用数据精确地说明对象。好处是运用准确的数据,能准确和科学地显示事物的特点,增加可信性及说服力。举例说明:举出具有代表性的例子来说明事物的本质、特征。好处是通过具体事例来说明事物的特点,把抽象、复杂的事物或事理说得具体做诠释:从侧面对事物的某一特点做解释摹状貌:具体地描述说明对象的现象、状态或变化。这方法能增强吸引力,使事物呈现在读者眼前。比较说明:作比较是将两种类别相同或不同的事物、现象加以比较来说明事物特征的说明方法。好处:突出强调说明对象的特点。打比方:以人们熟悉的事物来比喻说明的对象。这方法能把抽象的事物或事理解说得具体易明。引用说明:引用名人的名言或文学作品来说明,这方法能让读者更相信作者的文章。常见的说明顺序如下,适当地安排说明顺序,有助读者逐步掌握说明内容。时间顺序:按照事物发展的先后顺序来作说明 : 由早到晚、由春到冬、由古至今等。一般来说会先把说明对象按具体情况以时段为序划分成若干段落,逐段说明。说明时并非像流水赈般记录整件事情的始末,而是抽取最能突出说明对象特征的内容来写。空间顺序:按照空间转移的顺序来作说明:由内至外、由上至下、由前到后、由左至右、由东到西、或倒过来由外至内、由下至上等。运用空间顺序说明时,必须清楚交代观察的转移,文章的脉络才会清晰。逻辑顺序:按照事理的逻辑关系来作说明 :由因到果,由浅到深,由主到次,由一个类别到另一类别,由一般到个别等。使用这种说明顺序,不但便于说清个别事物的特质,还有利于揭示各种事物之间的互相关系。说明的层次一般分为总述、分述、总结,适当地安排说明层次,使文章条理井然,读者更容易全面掌握说明对象的特点。\n\n### 文章 137\n\n侯活·韦比\n侯活·韦比(,)是一名英格兰职业足球球证,现在主要执法英格兰超级联赛赛事,自2005年起他亦是一名国际球证。他居住在南约克郡罗瑟汉姆。韦伯被足球界与媒体公认为史上少有的高水平裁判员。2014年8月6日,英超官网宣布霍华德·韦伯宣布从裁判界退役,正式结束了长达25年的裁判生涯。韦比于1989年首次于罗瑟汉姆地区联赛开始担任球证,1993年开始担任北部联赛的助理裁判,两年后升为主球证。1996年为英格兰足球联赛担任助理裁判,在1998年提拔为足球议会联赛的球证。2000年他进入了英格兰足球联赛球证名单,可以执法较高级别的赛事,3年后再被提升入英超球证名单,可以执法英格兰最高级别联赛-英格兰超级联赛。2003年10月18日,他首次执法英超赛事,该场富咸对狼队的赛事以0-0打平,共发出4面黄牌。2005年,他被国际足协认可为国际球证,可以执法世界大型赛事 。韦伯首个执法的国际赛是于2005年11月举行的友谊赛,北爱尔兰对葡萄牙,赛果为1-1。随后执法了2006年欧洲U-21足球锦标赛两场分组赛和一场准决赛。同年9月26日亦执法了他首场欧洲冠军联赛,赛事为布加勒斯特星队对里昂。在2007年的英格兰联赛杯决赛中,由韦比执法,为阿森纳对切尔西,最终切尔西以2-1击败阿森纳。韦比在这场比赛中出示三面红牌,是联赛杯首次出现的。他亦是2008年欧洲国家杯12位球证之一,执法主办国奥地利对波兰的赛事。2009年,他成为2009年洲际国家杯的裁判,执法了两场赛事。2010年,韦比成为当届世界杯的主球证之一,并判法了4场赛事,当中包括决赛,乃史上首位执法过欧联决赛及世界杯决赛的主球证。2014年8月6日,英格兰足球超级联赛官方网站宣布,韦伯退役,从此结束25年的裁判生涯。2012年2月5日,波亚斯带领的切尔西主场迎战曼联,出现令人争议的判决,曼联在落后三球的情况下,追成3-3。弗格森表示比赛初期卡希尔在禁区边缘对维尔贝克的战术犯规时逃过一劫,而卡希尔亦承认他幸运地逃过处分。韦比曾经是一名警长 。他在2011年新年因为其在足球上的贡献而被受勋员佐勋章 (MBE)。\n\n### 文章 138\n\n超异能冒险\n超异能冒险(Race to Witch Mountain)是部2009年奇幻冒险电影,翻拍自1975年的《巫山大逃亡》(Escape to Witch Mountain),根据 Alexander Key 1968年的同名原著改编,由安迪·菲克曼(Andy Fickman)执导,巨石强森、安娜苏菲亚·罗伯与亚历山大·路德维格(Alexander Ludwig)主演。2008年三月在洛杉矶进行拍摄制作,2009年3月13日北美首映,台湾于4月10日上映。倒楣的的士司机杰克·布鲁诺(巨石强森饰)碰上一对正在逃亡的少年兄妹莎拉(安娜苏菲亚洛饰)及薛夫(阿历山大卢域饰)。由他们上车的一刻开始,亡命旅程立即展开。原来莎拉及薛夫是身怀异能的外星来客,更掌握拯救地球未来的秘密关键;因此成为政府特工及地下组织恶势力的猎物,更有其他外星战队向他们展开追杀。杰克为了救己救人,必须在限时之前,把两名外星少年送回他们在地球的太空基地…金·理查兹和艾克·艾森曼是1975年旧版的男女主角,当年演出都还是孩童青少年,两人皆在新版中客串演出。2007年七月华特迪士尼影业找导演安迪·菲克曼执导,与 Matt Lopez 共同编剧,新版将1975年《巫山大逃亡》改编为「现代重拍版」,与旧版故事是大相异庭。八月巨石强森确选为主角,电影计划于2008年三月开拍。导演表示并非纯粹旧版重拍,确切地说是制作出一个全新章节的大魔域(Witch Mountain,早期译为巫山)世界。原著小说内容充斥著「黑暗惊悚」题材,导演企图将1975年旧版电影当时删减的要素加进新版电影里。新版中加入UFO专家、军队、CIA等各方人马于电影中,更是把外星生物概念加进影片作为主要核心。电影正式定名为《超异能冒险》(Race to Witch Mountain),在洛杉矶开拍。影评家给予《超异能冒险》普遍中等的评价。电影评论网站烂番茄,基于74篇评论中有38%的影评家给予正面的评价。Metacritic网站基于23篇评论,平均分数100分只拿到50分。而IMDb分数投票10分得到5.7分。\n\n### 文章 139\n\n何尊\n何尊,西周早期的一件青铜酒器,为贵族“何”作于周成王五年(前11世纪),是西周最早的有明确纪年的青铜器。1963年出土于陕西省宝鸡市贾村。何尊是中华人民共和国国家一级文物,2002年公布的第一批64件禁止出国(境)展览文物之一。现藏宝鸡青铜器博物院。其造型庄严厚重,纹饰精美,内底有铭文122字,为研究西周初年的历史提供了珍贵史料。何尊是“中国”一词已知的最早出处,“中国”在这里的含义,是指西周王朝的都城成周地区,即“天下”的中心——伊河、洛河流域,也就是今天的洛阳。何尊的出土地点在宝鸡市东北郊的贾村,这里常有西周文物出土。贾村镇西街的一户陈姓人家,常年在屋后三米高的断崖崖根取土,断崖上面未取土处逐渐突出。1963年的一天,陈家老二为防止上方土块掉落伤人,用镢头挖铲时意外发现了一件古铜器。陈家人不知其价值,在清理干净泥土之后,用于装盛粮食。1965年8月,因经济拮据,陈家将铜器卖给宝鸡市的一家废品收购站。同年9月,宝鸡市博物馆的职工在废品收购站将其发现并抢救运回博物馆。最初称为“饕餮纹青铜尊”。1975年在北京展出时,故宫博物院的唐兰(一说马承源)发现内胆底部有铭文122字,成为国宝级文物。何尊圆口方体,长颈,腹微鼓,高圈足,通高38.8厘米,口径28.8厘米,底部长20.2厘米,宽19.8厘米,总重14.6公斤。体侧装饰有四道镂空棱脊,以细雷纹为地,高浮雕,口沿下饰蕉叶纹,颈饰蚕纹图案,圈足处也饰有兽面纹。整体造型雄奇,工艺精美。何尊内底铸铭文12行、122字,因底部破孔,残损3字,现存119字。铭文记述成王继承武王遗志,营建东都成周之事,可与《尚书·召诰》、《逸周书·度邑》等古文献相互印证,具有非常重要的史料价值。铭文全文如下:大意是:成王五年四月,开始在成周营建都城洛邑,对武王行礼福之祭。丙戌日,成王在京宫大室对同族何进行训诰说:“你的先父公氏追随文王,后文王受天命,武王克商后告祭于天,以这里作为天下中心,治理民众。”成王将贝壳30朋赏赐给何,何因此作尊以纪念。\n\n### 文章 140\n\n折上原之战\n折上原之战(),在日本战国时代的1589年7月17日发生,是伊达政宗对芦名义广和佐竹义重的一场战役。人取桥之战后,伊达政宗与芦名氏和佐竹氏对立表面化,而伊达在仙道筋(即现在的福岛县中)的势力越来越大,芦名氏及佐竹氏都对此感到重大危机。后来伊达政宗违反丰臣秀吉所定的惣无事令(即停战命令),开始夺取芦名氏的据点。伊达政宗为确保从自家到敌军要塞的道路和猪苗代城的据点,拉拢了猪苗代盛国(盛国的长子猪苗代盛胤是芦名军的先锋,盛国与再婚的妻子所生的次子猪苗代宗国是伊达军)。另一方面,芦名义广率领部队从须贺川城出发,往猪苗代湖南岸出发,集结在黑川城。在高森山布阵的芦名氏向伊达势力挑衅,在平民家放火。那时伊达军兵力为21,000人,芦名军兵力为18,000,两者不相伯仲。但自1580年芦名盛氏去世后,继任当主芦名盛隆就因卷入家中纠纷而被暗杀身亡,次任当主芦名义广虽受家臣金上盛备的拥护,但也无法有效统率家中势力,加上有伊达军的内应,芦名军可谓欠缺团结力。战事在猪苗代湖北岸展开,开战初期来自西的烈风变成顺风,加上芦名军的先锋富田隆实十分活跃,对芦名军十分有利。但当风向转为东风后,伊达军的形势开始渐入佳境,芦名四天王之一的富田氏实先行撤退、引发其他友军傍观及部分家臣相继离反、金上盛备与四天王的佐濑种常・常雄戦死后,芦名军全面崩溃。战败的芦名军本来由日桥川逃走,但中途被黑川城妨碍前进,令兵力损害更大。芦名义广带仅存家臣逃离战场,大绳义辰及二本松义纲一行也在6月10日的夜晚逃往佐竹氏的常陆国。芦名氏的战力因有力家臣金上盛备和佐濑种常等人的战死而受到重大打击。而家督芦名义广因家臣无心应战及奥州的惣无事令而没有再次出战,逃往佐竹家的常陆国。伊达政宗则成为南奥州的霸者,把居城迁到黑川城,并把白川结城的石川氏臣服于伊达氏。但翌年因丰臣秀吉推行奥州仕置政策及以违反惣无事令为由,没收了会津。可是丰臣秀吉并没有把会津归还给芦名氏,反而给了蒲生氏乡。日本战争列表\n\n### 文章 141\n\n气炉\n气炉是一种以天然气、丙烷或其他可燃性气体作为燃料以产生火焰的厨房煮食用具。最早的煮食用炉具,可追溯至中国历史的秦朝,西方的炉具更于1735年才出现,气炉面世前,当时的人一直使用煤及木材作为燃料的用具,直至1826年第一具气炉诞生,但当时这种炉具并非用在煮食上,而是用于实验上,即类似今日的本生灯。真正用于煮食上的炉具于1851年的伦敦世博上展示,但当时的气体管路的铺设技术并不成熟,难以每家每户装设气炉,因此气炉并未能商业化地大量生产。至1880年代,气炉才走向商业化。同时间第一代电磁炉亦于1893年的芝加哥世博上展示,气炉的市场开始被电磁炉侵蚀。时至今日气炉与电磁炉并列是普遍全多人使用的烹饪用具。气炉大约可以分为三类:气炉其实是一个气态燃料的持续供应器,开关扭开后气态燃料会不断输出,同时炉具的点火器会因磨擦而产生火焰,当气态燃料遇到火焰时便会燃烧,持续的气体供应能维持炉具火焰的燃烧。气炉所产生的火焰与一般所见的火焰并不相同,如烧烤或点蜡烛时,所产生的火焰是黄色的,而气炉所产生的火焰为蓝色,因为气炉所使用气态燃料在产生热能的过程中会被完全燃烧,其火焰较热,燃料分子因此会发出蓝光和绿光,由于人类的眼睛对蓝光比较敏感,因此人类所见的火焰是蓝色的。使用炉具时应避免炉头积聚油污及食物残渣,以免使用炉具时燃起炉头上多余的物质。同时,要注意火焰不应超过煮食器皿的范围,以免点燃其他杂物引起火灾。最后要紧记不应以水喉喷向炉具,因为会破坏炉具的结构及零件。每次使用后应把气闸关闭,并且在空气流通的地方使用,如发现气体泄漏,更要通知代理公司修理,还有,要使用合标准的喉管传送气体燃料,不要折曲喉管。\n\n### 文章 142\n\n四川大学华西医院\n四川大学华西医院(四川大学华西临床医学院),成都市民俗称为“川医”,是位于中国四川省成都市国学巷的一座著名大型三级甲等医院,也是全世界单体规模最大的医院。原称“华西医院”,2000年华西医科大学与四川大学合并后改称“四川大学华西医院”。华西医院同四川大学华西临床医学院实行两块牌子、一套班子的管理机制,拥有中国科学院院士1名、长江学者6名、国家重点学科9个、国家重点实验室1个,是中国知名的教学医院。华西医院起源于由美国、英国、加拿大等国的基督教会(加拿大英美会、美国美以美会创办)1892年在成都创建的仁济、存仁医院。1914年,华西协合大学建立医科,将其作为教学医院。1937年抗战爆发,国立中央大学、金陵大学、金陵女子文理学院、燕京大学、齐鲁大学内迁成都,与华西协合大学联合办学办医。1938年7月,组建“华大、中大、齐大三大学联合医院”。1946年,华西协合大学新医院在现址建成,简称大学医院或华西医院。1950年,中华人民共和国人民政府接管华西协合大学。1953年,华大经院系调整为四川医学院,医院更名四川医学院附属医院。1985年,四川医学院更名为华西医科大学,医院更名为华西医科大学附属第一医院。2000年10月,四川大学与华西医科大学合并,随后学院/医院更名为四川大学华西临床医学院/华西医院。华西临床医学院始于1914年建立的华西协和大学医科。从1993年开始,华西临床医学院与华西医院实行「两块牌子、一套班子」的管理模式。该院于1988年开设临床医学七年制,2004年获准开设临床医学八年制专业。截至2015年,该院具有高级职称的教师有836人,其中中国科学院院士1人、长江学者6人,有临床医学、中西医临床医学,以及护理学三个一级学科的博士授予权,有(中华人民共和国)国家重点学科9个、国家重点培育学科2个。\n\n### 文章 143\n\n科克大学\n科克大学(直译为科克大学学院,,)是爱尔兰国立大学的一部分。大学建于1845年,原名“皇后学院”(Queen\'s College, Cork);1908年爱尔兰大学法案出台后,学校更名为“科克大学学院”(University College, Cork)。1997年大学法案将学校更名为\'“爱尔兰国立大学科克”(National University of Ireland, Cork);1998年教育部将大学更名为“科克大学”(University College Cork - National University of Ireland, Cork)。科克大学被星期日泰晤士报选为2003-2004年度爱尔兰大学,2005-2006年和2011-2012年再度当选年度爱尔兰大学。2007年,科克大学在泰晤士高等教育世界大学排名286位,2008年226位,2009年207位。科克女王学院(Queen\'s College, Cork)乃根据维多利亚女王发布的"为发展爱尔兰的高等教育"法案建立。根据该法案,三所学院于1845年10月30日分别在贝尔法斯特(贝尔法斯特女王大学)科克和戈尔韦(爱尔兰国立大学戈尔韦)建立。科克学院1849年正式办学,当时有23位教授及181位学生,一年后便加入爱尔兰女王大学。医学楼建于1860年至1880年,医学院也迅速因其毕业生而建立了名声。爱尔兰最早的两名女医学学生于1898年医学院毕业(20年后牛津大学才开始招收女医学学生)。在随后的一个世纪中,爱尔兰大学法案(1908)成立了爱尔兰国立大学,包括都柏林、科克和戈尔韦的三所成员学院。三所学校也有大学学院的地位,例如“大学学院,科克”。1997年大学法案使大学学院成为爱尔兰国立大学的成员大学,也使成员大学成了全方位的独立大学,但是学位和文凭仍由爱尔兰国立大学颁发。科克大学是爱尔兰的研究型大学,其政府科研经费全国最高。现有艺术、凯尔特研究与社会科学学院、商学与法学院、医学与健康学院、科学、工程和食品科学学院。科克大学还是爱尔兰中国研究院的所在地。学生在中国研究院能够通过艺术和商业学习中国语言和文化。中国研究院最近荣获2008年欧洲语言奖。\n\n### 文章 144\n\n黑龙江省大兴安岭林业集团公司\n黑龙江省大兴安岭林业集团公司暨黑龙江大兴安岭林业管理局,是中国首批57家试点企业集团之一,隶属于中华人民共和国国家林业局。其上级不是黑龙江省。黑龙江大兴安岭林业管理局与黑龙江省大兴安岭地区行政公署为一套班子、两块牌子。林管局局长兼任地区行署专员、大兴安岭地委委员、地委副书记;副局长兼任副专员。1996年3月,国务院正式批准大兴安岭林业管理局成立大兴安岭林业集团公司。黑龙江省大兴安岭林业集团公司辖10个林业局,61个林场。\u3000\u3000加格达奇林业局(驻加格达奇区)辖10个林场,即古里林场、白桦林场、东风林场、翠峰林场、跃进林场、多布库尔林场、达金林场、大黑山林场、大子扬山林场、罕诺河林场。\u3000\u3000松岭林业局(驻小扬气镇)辖5个林场,即绿水林场、古源林场、大扬气林场、壮志林场、新天林场。\u3000\u3000新林林业局(驻新林镇)辖8个林场,即塔源林场、宏图林场、新林林场、大乌苏林场、碧洲林场、翠岗林场、塔尔根林场、富林林场。\u3000\u3000呼中林业局(驻呼中镇)辖6个林场,即雄关林场、呼源林场、苍山林场、宏伟林场、呼中林场、碧水林场。\u3000\u3000塔河林业局(驻塔河镇)辖6个林场,即瓦拉干林场、蒙克山林场、塔林林场、绣峰林场、盘古林场、沿江林场。\u3000\u3000阿木尔林业局(驻漠河县劲涛镇)辖6个林场,即长山林场、依林林场、龙河林场、兴安林场、红旗林场、青松林场。\u3000\u3000图强林业局(驻漠河县图强镇)辖7个林场,即奋斗林场、二十八站林场、育英林场、壮林林场、潮河林场、卧龙河林场、潮满林场。\u3000\u3000西林吉林业局(驻西林吉镇)辖5个林场,即河湾林场、前哨林场、河东林场、古莲林场、金沟林场。\u3000\u3000十八站林业局(驻塔河县十八站乡)辖6个林场, 即十八站林场、查班河林场、小根河林场、白银纳林场、永庆林场、双河林场。\u3000\u3000韩家园林业局(驻呼玛县韩家园镇)辖1个林场,即韩家园主伐林场。\n\n### 文章 145\n\n景栋\n景栋(掸语:;,转写:kyuing: tum mrui.;)位于亚洲的缅甸之东方的掸邦的主要城镇,东掸邦的治所,曾经是暹罗的国土,它是中国、寮国、缅甸及泰国之间的重要交通枢纽及商业城市。景栋市区约3平方公里,人口约60,000。市内不仅有佛寺,也有基督教堂。有公路通往掸邦首府东枝及泰国的美塞。由于其地理位置重要,近年来一直是缅甸北部的军事重地,亦是毒品运输要道。此处设有Kyaing Tong Degree College。这里是掸族最多的地方。景栋是由清迈王朝的孟莱王之孙子建成的,在13世纪时建立的兰纳王国,造成景栋与掸邦其它地区有著不同种族的傣族定居(根据佤族的口头传说,他们是景栋原住民,后被掸族征服)。在大城王朝景栋是暹罗国土,18世纪时,缅甸向大城王朝发动战争,史称泰缅战争,景栋落入缅甸之手。景栋像其它掸邦的主要的高原城镇,由「诏法」(土司)负责管辖,在1905年Sao Kawng Kiao Intaleng建造了「Sawbwa宫」。Sao Saimong是一位著名的政治家及缅甸总理,就是在景栋出生及长大的。在1942年至第二次世界大战结束前,景栋曾被入侵掸邦的泰国军队选为驻扎总部。1960年代亦是中华民国国军南逃的残部与缅甸军队作战的战场。这里是掸族的地方,每当新的“索巴”(Sawbwa,即傣族头人“诏法”的掸语方言发音)即位加冕时,都要举行一个仪式:即从当地山区佤族山寨中请几位佤族老人来,让他们先坐在“王位”上吃东西。而当他们打开装食物的包准备吃的时候,一位被称为“叭莱”(Phya Lai,意为“驱赶”)的掸族官员便冲过来象征性地戏谑他们,并把他们从“王位”上赶走。象征他们是外来者。到处可见光芒耀眼的佛塔及庄严的佛寺,仅景栋城里就有108座佛塔及佛寺,家家供奉佛像。一幢幢干栏式高脚房及塔亭楼榭,掩映在椰树、竹林里,它们大多黄墙红瓦。许多房屋、亭榭之屋簷及门窗、门面上,都雕刻及镶嵌著精致之图案装饰。\n\n### 文章 146\n\n周而复\n周而复(),原名周祖式,曾任中国人民对外友好协会副会长、文化部副部长、对外文化联络委员会副主任等职务。原籍安徽旌德,生于南京。1933年考入上海光华大学英文系,开始从事文学创作,笔名有吴疑、荀寰等,大学毕业后在延安、重庆等地从事文艺和编辑工作,1936年出版第一本诗集《夜行集》。周而复是中国第一位介绍白求恩事迹者。中华人民共和国成立后,任上海市委统战部副部长、文化部副部长等职。1985年于对外友协访日代表团团长访日期间,宣言为准备撰写抗日战争长篇小说,不顾中国驻日使馆劝阻、参观了日本靖国神社,1986年3月4日,《人民日报》在头版报眼位置刊发了主标题为《中纪委决定开除周而复党籍》的报道,并且配发了“本报评论员”题为《严守外事纪律维护国格》的评论文章。周而复被开除党籍并撤销党内职务、罢免作协副主席的职位。从此深居简出。后于2002年9月平反并恢复党籍。2004年1月8日在北京病逝。周而复后来对参观靖国神社做出了解释,他说:“我因为撰写反映8年抗日战争的小说《长城万里图》,希望更多地了解日本军阀有关侵华的资料,为此准备去参观,参观前,我将日程表报我驻日大使馆,送出4日,没有接到大使和文化参赞等其他人劝阻勿去的通知,我就理解为同意我的日程安排。于是我便于11月10日由日方安排参观了靖国神社,开且向日本老人了解当时的情况,没想到当天晚上,文化参赞才对我说,最近国内有通知,不要去靖国神社参观,如果工作需要,需中国大使馆批准,但是我并没有接到通知,而就已经去过了。文化参赞说,去过就算了,我们大使馆通知迟了也有责任,你不要和任何人提起此事。周而复强调,当时有对外友协代表团成员李海卿先生在场。”在70年创作生涯中,发表、出版小说、散文、诗歌、戏剧、报告文学、杂文、文艺评论和回忆录等,共计1,200万字左右。主要作品有长篇小说《白求恩大夫》、《上海的早晨》(4卷)、《长城万里图》(6卷);长篇叙事诗《伟人周恩来》(4部);《周而复散文集》(4卷);报告文学集《难忘的征尘》;中短篇小说集《山谷里的春天》;戏剧《牛永贵受伤》、《子弟兵》;杂文、评论集《70年文艺漫笔》;回忆录《往事回首录》3卷;书法作品《周而复书琵琶行》、《周而复书法作品选》、《周而复书屈原离骚》。\n\n### 文章 147\n\n长洲北帝庙\n长洲北帝庙,又名长洲玉虚宫,位于香港离岛区长洲北社街北端,建于清朝乾隆四十八年(1783年),有二百多年历史,已获古物咨询委员会评定为一级历史建筑物,是全香港最具规模的北帝庙,除北帝外,庙内亦供奉太岁、观音及列圣。长洲北帝庙早期由长洲居民负责管理,于1929年交由华人庙宇委员会管理。长洲是原籍惠州、潮州及广州的渔民聚居地,他们信奉海神北帝祈求获得神明庇荫,使舟楫平安。据称,在乾隆四十二年(1777年)长洲发生疫症,当地渔民远赴惠阳县玄武山北帝庙迎请北帝神像到长洲镇压才除去疫症。因此,地方乡绅林煜武于乾隆四十八年(1783年)领导长洲原籍惠州、潮州居民集资建庙奉祀北帝。北帝庙是传统三进式建筑,正殿宽敞,神坛置中,两侧设偏殿,左右对称。殿前建有一道花岗石梯阶,门外置有一个石香炉及两对石狮子,而庙的瓦面和簷角,亦有很多狮子,成为全港庙宇中,狮子最多的一间。庙宇曾分别于道光二年(1822年)、道光十八年(1838年)、咸丰八年(1858年)、光绪廿九年(1903年)及1989年重修。最近一次由华人庙宇委员会斥资逾1,300百万港元进行重修,工程于1999年展开,直到2003年才竣工。北帝诞在每年的农历三月初三,善信敬拜祈求合境平安。而在每年一度的长洲太平清醮期间,长洲玉虚宫前地球场,会架设戏棚、抢包山等,好不热闹。庙内的古物珍品包括一柄早年由渔民网得奉于庙内的宋朝大铁剑及鱼骨、一座制于光绪二十五年的銮舆、一个咸丰十一年制的石香炉及乾隆四十九年的铜钟。此外,为纪念英国玛嘉烈公主及斯诺敦伯爵(Earl of Snowdon)伉俪于1966年到访,一位钟姓女士特别打造了一顶金冠以志盛况;而华人庙宇委员会于1959年铸造了一对铜香炉,纪念护督白嘉时于当年莅临参观。\n\n### 文章 148\n\n吉冈秀隆\n吉冈秀隆(),日本男演员、创作歌手。出生于埼玉县蕨市。血型为A型。亚细亚大学经济学部二年级肄业。身高172公分,体重55公斤。5岁进入若草剧团,75年参与东京电视台时代剧《大江戸捜查网》的演出。1977年出演野村芳太郎监督的『八つ墓村,饰主人公・寺田辰弥的幼年时代。之后在1980年公映的山田洋次监督的『远山的呼唤』中演出女主角的儿子“武志”一角,继而成为山田洋次的长年御用演员之一。1981年开始出演山田洋次监督的长篇系列电影『男人真命苦』),从第27部开始一直到最终章出演主人公寅次郎的外甥“诹访満男”一角,并从第42部开始,因为主演渥美清的身体欠佳,情节作以调整,寅次郎的外甥满男和满男的女朋友阿泉也成为故事的主角,和寅次郎展开了双线的情节。直至1996年渥美清病逝,『男人真命苦』也于第48部完结。在电视剧方面,从1981年开始,在富士电视台的长寿经典名作『来自北国』(日文名“北の国から”,仓本聪脚本)中饰主角之一的黑板纯,之后20余年中,一直持续拍摄特别篇,直至2002年『遗言篇』终于完结。遂后也与『遗言篇』中饰演黑板纯女友的女优内田有纪共结连理,并在『来自北国』所在的外景地北海道富良野市举行婚礼,遂成一段佳话。但由于婚后两人聚少离多,终究于2005年12月21日协议离婚。2003年首次主演民放台趋势剧,富士电视台的小孤岛大医生,得到了极高的视聴率与口碑,并在接下来相继推出了2004的特别篇与2006年的续篇,也都获得了极高的视聴率。而在2005年主演的电影「永远的三丁目的夕阳」中,因良好口碑与票房也于2007年续拍,而他也凭精湛的演技创下以同影片同角色两度拿下日本电影金像奖最优秀主演男优赏的记录。从童星时代出道至今,除了演员发展,音乐才华亦受瞩目,94年配合同名电影推出第一张自己做词作曲的单曲『ラストソング』(Last Song),于当年畅销47万张,其后他所推出的几张专辑几乎都一人包办了词曲的创作。\n\n### 文章 149\n\n成功渔港\n成功渔港,又名新港渔港,位于台东县成功镇,且与富冈渔港为台湾东海岸近海渔业的重要基地,属第二级渔港,以海产及柴鱼闻名。成功渔港其相对于成广澳港而言,是较晚开发的港口,所以,当地人又将之称为新港,由于有天然的海湾地形,因此开发的历史可远溯自日治时期,后来在1929年至1932年期间曾将原有渔港予以大规模整建,挖深与浚疏航道,最近的大型疏濬及建设则是在1979年,当时台湾省政府曾再次加以扩建,变成今日的模样。成功渔港是新港区渔会所属的渔港中规模最大的渔港,除提供渔船停泊外,并可供附近地区渔船拍卖渔获,主要渔获包含有鬼头刀、黄鳍鲔、雨伞旗鱼、正鲣等,鱼市场每日下午三时左右拍卖渔获,港区内并有渔货直销市场可供一般游客采买生鲜渔获,亦设有熟食区可就地将所购得的新鲜渔获交予店家料理。除了发展渔业之外,此港口还兼具观光功能。交通部观光局东部海岸管理处在这里设有旅客服务中心与浮动码头设施,为一条件颇佳之休闲渔港,港内并有豪华舒适游艇,可载客出海赏鲸、赏景。1908年总督府通信局长鹿子木小五郎考察东部地区后,便提出建港于麻荖漏的看法。1929年新港渔港动工,1932年完工。当中历经了关东大地震带来的经济恐慌,台湾总督府配合财政紧缩而新港建港工程因此停工,复工后预算又遭删减。1941年渔港开辟内港1954年新港渔港升格为省内港。1988年起展开的扩建工程于1996年完工,目前是新港渔港建港以来最大规模,也是东台湾最大渔港。1927年,总督府交通局工事部打狗出张所主张开发新港,估计至少有五万人于此发展,新港筑港消息发布后,花莲方面认为会因此衰退,而台东方面认为会因此完没,原计划花费六、七百万圆筑为商港,而因群众抗议而作罢。\n\n### 文章 150\n\n景栋\n景栋(掸语:;,转写:kyuing: tum mrui.;)位于亚洲的缅甸之东方的掸邦的主要城镇,东掸邦的治所,曾经是暹罗的国土,它是中国、寮国、缅甸及泰国之间的重要交通枢纽及商业城市。景栋市区约3平方公里,人口约60,000。市内不仅有佛寺,也有基督教堂。有公路通往掸邦首府东枝及泰国的美塞。由于其地理位置重要,近年来一直是缅甸北部的军事重地,亦是毒品运输要道。此处设有Kyaing Tong Degree College。这里是掸族最多的地方。景栋是由清迈王朝的孟莱王之孙子建成的,在13世纪时建立的兰纳王国,造成景栋与掸邦其它地区有著不同种族的傣族定居(根据佤族的口头传说,他们是景栋原住民,后被掸族征服)。在大城王朝景栋是暹罗国土,18世纪时,缅甸向大城王朝发动战争,史称泰缅战争,景栋落入缅甸之手。景栋像其它掸邦的主要的高原城镇,由「诏法」(土司)负责管辖,在1905年Sao Kawng Kiao Intaleng建造了「Sawbwa宫」。Sao Saimong是一位著名的政治家及缅甸总理,就是在景栋出生及长大的。在1942年至第二次世界大战结束前,景栋曾被入侵掸邦的泰国军队选为驻扎总部。1960年代亦是中华民国国军南逃的残部与缅甸军队作战的战场。这里是掸族的地方,每当新的“索巴”(Sawbwa,即傣族头人“诏法”的掸语方言发音)即位加冕时,都要举行一个仪式:即从当地山区佤族山寨中请几位佤族老人来,让他们先坐在“王位”上吃东西。而当他们打开装食物的包准备吃的时候,一位被称为“叭莱”(Phya Lai,意为“驱赶”)的掸族官员便冲过来象征性地戏谑他们,并把他们从“王位”上赶走。象征他们是外来者。到处可见光芒耀眼的佛塔及庄严的佛寺,仅景栋城里就有108座佛塔及佛寺,家家供奉佛像。一幢幢干栏式高脚房及塔亭楼榭,掩映在椰树、竹林里,它们大多黄墙红瓦。许多房屋、亭榭之屋簷及门窗、门面上,都雕刻及镶嵌著精致之图案装饰。\n\n### 文章 151\n\n超异能冒险\n超异能冒险(Race to Witch Mountain)是部2009年奇幻冒险电影,翻拍自1975年的《巫山大逃亡》(Escape to Witch Mountain),根据 Alexander Key 1968年的同名原著改编,由安迪·菲克曼(Andy Fickman)执导,巨石强森、安娜苏菲亚·罗伯与亚历山大·路德维格(Alexander Ludwig)主演。2008年三月在洛杉矶进行拍摄制作,2009年3月13日北美首映,台湾于4月10日上映。倒楣的的士司机杰克·布鲁诺(巨石强森饰)碰上一对正在逃亡的少年兄妹莎拉(安娜苏菲亚洛饰)及薛夫(阿历山大卢域饰)。由他们上车的一刻开始,亡命旅程立即展开。原来莎拉及薛夫是身怀异能的外星来客,更掌握拯救地球未来的秘密关键;因此成为政府特工及地下组织恶势力的猎物,更有其他外星战队向他们展开追杀。杰克为了救己救人,必须在限时之前,把两名外星少年送回他们在地球的太空基地…金·理查兹和艾克·艾森曼是1975年旧版的男女主角,当年演出都还是孩童青少年,两人皆在新版中客串演出。2007年七月华特迪士尼影业找导演安迪·菲克曼执导,与 Matt Lopez 共同编剧,新版将1975年《巫山大逃亡》改编为「现代重拍版」,与旧版故事是大相异庭。八月巨石强森确选为主角,电影计划于2008年三月开拍。导演表示并非纯粹旧版重拍,确切地说是制作出一个全新章节的大魔域(Witch Mountain,早期译为巫山)世界。原著小说内容充斥著「黑暗惊悚」题材,导演企图将1975年旧版电影当时删减的要素加进新版电影里。新版中加入UFO专家、军队、CIA等各方人马于电影中,更是把外星生物概念加进影片作为主要核心。电影正式定名为《超异能冒险》(Race to Witch Mountain),在洛杉矶开拍。影评家给予《超异能冒险》普遍中等的评价。电影评论网站烂番茄,基于74篇评论中有38%的影评家给予正面的评价。Metacritic网站基于23篇评论,平均分数100分只拿到50分。而IMDb分数投票10分得到5.7分。\n\n### 文章 152\n\n西美鸥\n西美鸥("Larus occidentalis"),又名西方鸥,是一种生活在北美洲西岸的白头海鸥。牠们以往被认为与加利福尼亚湾的黄脚鸥是同一物种。牠们分布在华盛顿及英属哥伦比亚至下加利福尼亚州。西美鸥是大型的海鸥,长约60厘米。头部及身体呈白色,双翼灰色。喙黄色,近端有红点。牠们的外观像大黑脊鸥。在牠们北面的分布地与大白头鸥形成杂交地带。西美鸥主要在近海生活,很少会出现在内陆上。牠们在离岸或河口的岛上筑巢,在三藩市湾的恶魔岛亦可见牠们的踪迹。牠们会主动地保护自己的领地,而领地的边界每年会不断改变。牠们的寿命一般长达15年,最老的可以达25岁以上。西美鸥会在领地内以植物筑巢,每次产3只蛋。蛋须一个月时间来孵化。雏鸟会留在领地内直至换羽。若雏鸟误入其他西美鸥的领地,有可能会遭杀害。雏鸟的死亡率很高,平均只有1只雏鸟能生存到换羽。有时走失的雏鸟会被其他西美鸥所收养。西美鸥主要在远洋区及潮间带觅食。在海中,牠们会吃鱼类及无脊椎动物,如磷虾、鱿鱼及水母。牠们不能潜水,只在海面上觅食。在陆上牠们会吃海豹及海狮的尸体,与及海扇、帽贝及蜗牛。牠们亦会在垃圾堆填区寻找食物,或是吃人喂饲的食物。西美鸥有时会充满掠食性的,会吃其他种的雏鸟,甚至成鸟。西美鸥现时并非受到威胁。不过牠们的分布地很有限。于19世纪在三藩市因采集鸟蛋的缘故,其数量大幅下降。西美鸥的领地亦因开发为灯塔,或如恶魔岛般成为监狱而受到破坏。不过随著灯塔的自动化,与及该监狱的弃置,令牠们重获一些栖息地。牠们现时最受厄尔尼诺现象及油污等问题所影响。西美鸥在保护自己的领地时是很主动的,故被反指是一种威胁。\n\n### 文章 153\n\n小北站 (广州)\n小北站()是广州地铁5号线的车站,位于环市中路小北路口以东的地底,于2009年12月28号启用。本站共有两层,地下一层为站厅,设有票务设施和车站商店,地下二层为5号线月台。本站分为东西两个站厅,两个站厅在非付费区并不相通。由于环市路的地面交通繁忙,且规避上方环市路的高架桥桩基等,本站采用了暗挖施工,故其车站站厅较一般车站站厅小。两个站厅均设有扶手电梯以及楼梯供乘客前往月台层,专用电梯(升降机)由于设于往文冲方向车头月台屏蔽门之外的区域,乘客使用时需要联络车站工作人员协助使用。现时,小北站内提供少量商店供乘客购物或进食,例如有便利店、面包糕饼店等。此外,小北站也有少量自助服务设施供乘客使用,包括自动售卖机、招商银行自动柜员机等。车站内亦设有“好易”机,可充值羊城通,缴纳水电费以及交通罚款等服务、“M-Touch”机,可查询地铁线路、首末班车等资讯以及地铁安全指引的查询,更亦供乘客登记为广州地铁荟会员、查阅奖分、换领奖赏。本站设有一个分离岛式月台,位于环市中路地底。小北站共设有4个出入口,东西站厅均设置两个出入口。由于连接站厅与站台的升降机设置于车站东端,因此轮椅升降台设置在东站厅的B出入口。小北站是5号线的中途站,乘客可以乘搭往滘口或文冲列车,来往广州火车站、珠江新城、荔湾区、越秀区、天河区、黄埔区各地。小北站周围有不少事业单位和写字楼,亦有不少居民区坐落于车站周围。因此全天客流不俗,早晚高峰时段客流尤为庞大,有时甚至需要实施限流措施。同时,亦有不少麓湖,下塘西,横枝岗一带的居民通过公交等方式接驳本站。在5号线最初的规划中(1997年的《广州市城市快速轨道交通线网规划研究(最终报告)》),当时的3号线通过西村后继续沿环市西路到达珠江新城一带,中途亦设置小北站。后来于2003年方案中,3号线亦易名为5号线,同样设有小北站,并最终落实兴建。2006年6月26日,本站随5号线全线正式动工。2009年12月28日,本站随五号线于开通试运营,本站启用。\n\n### 文章 154\n\n杨廷艺\n杨廷艺(,,部份文献写成「杨延艺」()),越南史上亦称为「杨正公」,交趾爱州人,原为静海节度使曲氏将领,当其主曲承美被中国南汉灭亡后,杨廷艺奋起抵抗,夺取了交趾的统治,因而被视为是越南自立建国的重要人物之一。杨廷艺是中国五代十国时期爱州人士,曾任交趾静海节度使曲颢的将领。当时,位于中国岭南的南汉与曲氏势成水火,曲颢之子曲承美继位后,于大有三年,930年(《大越史记全书·外纪全书·南北分争纪》作923年),南汉君主刘䶮出兵,擒获曲承美,占领交趾地区,并派骁将梁克正、交州刺史李进驻守,而杨廷艺则获南汉授以爵命,名义上成为了南汉的臣僚。据《安南志略》,刘䶮虽已得胜,但洞悉到「交趾民好乱,但可覊縻而已」,认为当地民众不会服从其统治。而杨廷艺亦为驱逐南汉而作好准备,《大越史记全书》提到,到了大有四年(931年)农历十二月,南汉官员李进向刘䶮告发「杨廷艺养假子三千人,图恢复」,廷艺随即先发制人,攻破李进所在的大罗城,李进逃归。适值南汉派遣程宝(《新五代史·南汉世家·刘隐》作「程宝」,《大越史记全书·外纪全书·南北分争纪》作「陈宝」)率兵赶来,包围杨廷艺,杨廷艺出战,击杀程宝。杨廷艺取得军事胜利后,便自称节度使,领州事。关于杨廷艺得胜后与南汉的关系,中国学者郭振铎、张笑梅作以下分析:「杨廷艺虽战败南汉军,领有交州。但他深恐南汉再次派大军来攻,为了本身的政权不受威胁,只好臣服南汉,服从南汉的诏谕,接受为交州节度使,刘䶮和杨廷艺之战宣告结束。」而在交趾方面,杨廷艺与本地的土豪结好,例如把女儿嫁给「世为贵族」的牙将吴权。南汉大有十年(937年)农历三月,杨廷艺被牙将矫公羡所杀。矫公羡行凶的原因,则是「恶廷艺所为,起所部攻杀廷艺,而代为节度。」矫公羡遂向南汉臣服,但其后亦被杨廷艺另一员牙将吴权所杀,并继续争取交趾政权的独立。\n\n### 文章 155\n\n牛蒡\n牛蒡(学名:)是菊科牛蒡属的植物,又名东洋参、东洋牛鞭菜、白肌人参、吴某、吴帽、夜叉头、牛菜、鼠粘、蒡翁菜、便牵牛、蝙蝠刺、牛旁、便南牛,果实别名恶实、大力子、黑风子、大牛子、鼠粘子、鼠尖子。二年生大型草本,肉质根;广卵形至心脏形叶子,背面密生白毛;头状花序簇生,具有先端呈钩刺状的总苞片,夏秋开紫红色管状花;长椭圆形或倒卵形瘦果,先端有刺毛一束。分布于欧亚大陆、美洲大陆寒温带,生长于海拔750米至3,500米的地区,一般生于林缘、林中、灌木丛中、山谷、村庄路旁、山坡、河边潮湿地和荒地。台湾食用牛蒡的风气主要是受到日本影响,原来并没有野生种,但经由引进种植,在屏东县屏东市的归来地区(湖西里 湖南里 归心里 顶柳里 顶宅里)人工种植成功后,被列为当地名产之一。日本在太平洋战争期间俘虏英美战俘,因战时粮食短缺,日本人强迫英美战俘吃牛蒡,而英美战俘在饮食文化上不知道牛篣是一种食物而当作树根吃而误会为虐待战俘,这件事件也被英美战俘控告到国际法庭之上。(此事件在佐伯俊的料理漫画《食戟之灵》〈实地实习篇〉亦有引用,由四宫小次郎说明。)台湾人习惯使用牛蒡细长的根部切块与排骨炖煮成「牛蒡排骨汤」,油炒牛蒡丝或是切片后泡茶,或切丝为凉拌菜,据信有减肥和养生等效用。在欧洲中古世纪,牛蒡被当成蔬菜食用,现已不再普遍。东欧和北欧等国还习惯使用其花部做成洗发精、润发精或点心,亦加在茶中入味。牛蒡的成熟果实(牛蒡子)是常用的中药。牛蒡子性味辛苦寒,可疏散风热、透疹、消肿利咽,用于银翘散、牛蒡汤、透疹汤、瓜蒌牛蒡汤、普济消毒饮等方剂中。可做为抗氧化剂。可借由帮助控制细胞出现突变,进而抵抗癌症。协助过多的液体、尿酸及毒素排出体外。具有抗细菌及抗霉菌的特性。纯化血液、恢复肝脏及胆囊的功能、刺激消化及免疫系统作用。帮助疖以及面疱这类的皮肤问题,可减轻痛风以及更年期的症状。牛蒡根可以用来滋润头发,以促进头皮及头发的健康。\n\n### 文章 156\n\n以仁王\n以仁王()日本平安时代人物。后白河天皇第三皇子,为闲院流藤原季成的女儿藤原成子所生。他的府邸在三条地方的高仓,因此也被称为高仓宫亲王。以仁王是后白河天皇的第三皇子,由于次兄守觉法亲王出家为僧,因此《平家物语》将他记载为后白河的第二皇子。以仁王幼年曾跟随天台座主最云法亲王出家学习佛法,但应保2年(1162年)最云圆寂后就还俗了。以仁王自幼才学出众,擅于创作和歌和吹笛,且能写一手好字。后白河上皇最初试图将他立为六条天皇的太子,但由于建春门院的作梗而作罢。永万2年(1165年),建春门院和后白河上皇所生的儿子宪仁亲王成为了皇太子。同年,15岁的以仁王在近卫河原秘密举行了冠礼,此后成为八条院暲子内亲王的养子。仁安元年(1166年),以仁王的舅舅藤原公光被罢免了权中纳言兼左卫门督的官职,以仁王继位的梦想彻底破灭。此后以仁王被后白河天皇疏远,被降为亲王,过起了隐居生活。治承三年(1179年),平清盛发动政变,幽禁了后白河法皇并废止了院政。次年,以仁王在源赖政的劝说下决定起兵反抗平氏夺位,自称「最胜亲王」,并向关东的源氏各族发出讨伐平家的令旨。不久事泄,太政大臣平清盛假借法皇的名义将以仁王开除了皇籍,赐名「源以光」,并派人前往以仁王的住所,要把他流放到土佐国去。以仁王得知此事,与源赖政、源仲纲、源兼纲等人出奔三井寺,并向延历寺和兴福寺求援。延历寺拒绝,以仁王等人只好逃往奈良兴福寺。平清盛派出平知盛、平重衡、平行盛、平忠度等人率兵追击,双方人马于宇治川交战后,源赖政、源仲纲、源兼纲等人战死。以仁王继续逃往光明山,于鸟居前遇到平家武士藤原景高、藤原忠纲的袭击,中箭落马身亡。然而很少人曾经见过以仁王容貌,因此当时日本民间流传著以仁王依然活著的流言。虽然以仁王举兵失败了,但其令旨却成为了源赖朝、源义仲等各地源氏起兵讨伐平家的理由,最终平家政权被推翻。京都的朝廷曾一度将东国所流传的以仁王令旨当作伪物,直到建久7年(1196年),以仁王一直被称作「刑人」,当作谋反的人物。(《玉叶》建久7年正月15日条)。长子北陆宫,在以仁王举兵失败后逃亡北陆道,后来被举兵讨伐平家的源义仲奉为主公。源义仲率源氏武士进入京都后,曾一度试图将北陆宫扶上皇位,但被后白河法皇拒绝了。次子若宫则被平家逮捕,被迫出家,法号道尊。今京都府木津川市有高仓神社。\n\n### 文章 157\n\n松平康忠\n松平康忠(1546年-1618年9月28日)是日本战国时代至安土桃山时代的武将。长泽松平家第8代当主。德川氏的家臣。德川家康的从弟。父亲是松平政忠。母亲是松平清康的女儿碓井姬。正室是矢田姬(松平广忠的女儿,家康的妹妹)。继室是松平信定的女儿。通称源七郎、上野介。在天文15年(1546年)出生。父亲政忠在永禄3年(1560年)5月的桶狭间之战中被讨死,祖父亲广成为年幼的康忠的后见。另一方面,母亲碓井姬再嫁给德川家的重臣酒井忠次,于是与康忠分开。在永禄5年 (1562年)元服,被任命为三河国宝饭郡小坂井等1千8百10贯文的知行。康忠的叔父信重和近清等人亦被家康给予1百贯文并任命为辅佐。信重在翌年的三河一向一揆属于家康方被讨死,而近清一直辅助康忠直至天正16年(1588年)死去。此后康忠在元龟元年(1570年)从属于义父忠次参加姉川之战。接著在天正3年(1575年)的长筿之战中并跟随忠次参战。作为德川军的别働队攻略武田信实守备的鸢巢砦,成为帮助长筿城解围。之后成为家康的嫡男信康的家老,不过因为信康在天正7年(1579年)自杀而蛰居。后来得到家康的允许而复归,在天正10年(1582年)的本能寺之变发生后与家康一同穿越伊贺。之后参加天正12年(1584年)的小牧长久手之战。在天正16年(1588年)把家督让予嫡子康直并在京都隐居。不久,成为武藏深谷藩藩主的康直在文禄2年(1593年)以24歳之龄病死。已经隐居的康忠收家康的七男松千代为康直的养子并令其继承深谷藩1万石。不过松千代亦在庆长4年(1599年)死去,因此以松千代的哥哥辰千代(后来的松平忠辉)为继承人。在元和4年(1618年)8月10日死去。享年73岁。法号是源斋。在元和2年(1616年)因为忠辉被改易而令长泽松平家嫡流绝后,不过康忠的血脉亦有存续到后世。在天文9年(1540年)的安城合战中战死的同名武将松平康忠(甚六郎)是松平宗家亲忠系的松平张忠的儿子,不是同一人。\n\n### 文章 158\n\n叔梁纥\n叔梁纥(),孔氏,名纥,字叔梁,又称郰人纥、郰叔纥,是伯夏的儿子,孟皮和孔子的父亲。鲁国郰邑大夫。前563年,晋国的荀䓨、荀偃、士匄带着诸侯联军进攻偪阳国。四月初九,联军包围偪阳,不能攻克。孟孙氏的家臣秦堇父用人力拉了装备车到达战地,偪阳人打开城门,诸侯的将士乘机进攻。偪阳国内城的人突然把闸门放下,叔梁纥双手举门,把已经攻入城里的将士放出来。孟献子称赞说:“这就是《诗经》所说的‘像老虎一样有力气’的人。”前556年秋季,齐灵公攻打鲁国边境,高厚把臧武仲围困在防地,叔梁纥与臧畴 、臧贾率领三百名甲士夜袭齐军,把臧武仲送到旅松后返回防地。齐国不久后退兵。叔梁纥与正妻施氏有九个女儿,没有儿子,他的妾生了个儿子孟皮,却因为有足疾,不能做继承人,叔梁纥便向鲁国颜氏求婚。颜氏有三个女儿,最小的叫颜征在。颜父对三个女儿问道:“陬大夫叔梁纥的父祖辈虽然都只是士,但他却是古代圣王的后裔。而且他身高十尺,武力绝伦,我非常希望能与他联姻。虽然他年纪大且性情急躁,但这不值得犹豫不决,你们三个谁能够嫁给他做妻子?”大女儿和二女儿都没有回答,颜征在上前对父亲说:“听从父亲您的决断,还有什么好问的。”颜父说:“就是你能嫁给他了。”他便将颜征在嫁给叔梁纥。颜征在嫁到叔梁纥家后第三个月行庙见之礼,正式成为孔家的媳妇。她因为叔梁纥年纪大,担心不能及时有儿子,便私下至尼山向尼山神祷告,祈求生子,后来生下了孔子。孔子三岁时,叔梁纥死了,埋葬于防。颜征在死后,孔子将母亲的棺材停放在五父之衢,四处询问父亲的墓址,直到郰曼父的母亲告诉了他,孔子才将父母合葬于防,并为之造坟,坟高四尺。叔梁纥的墓地,今称「梁公林」,位于曲阜城东14公里,面对防山,北阻泗水,又称“齐国公墓”、“启圣林”或“启圣王林”。坟前石碑“圣考齐国公墓”由孔子五十一代孙衍圣公孔元措于金明昌五年(1194年)立。梁公林大门前则立有“大元追封启圣王墓”碑,为孔子五十二代孙泗水县尹孔之严于元至元六年(1340年)立。\n\n### 文章 159\n\n氯化铬\n氯化铬(化学式:CrCl)也称三氯化铬、氯化铬(III),是常见的铬(III)化合物之一。有无水物和六水合物两种。无水物为强烈发光的紫色结晶,几乎不溶于水。六水物 formula_1 是一个配合物,有三种水合异构体:formula_2formula_3,分别为紫色、浅绿色和暗绿色的固体。一般买到的都是暗绿色的异构体。三氯化铬晶体中含有连接成层的 CrCl 八面体单元,结构中存在螺旋状位错,不含有金属-金属键。它与三碘化铬同构。氯化铬是较硬的路易斯酸。其中含 d 构型的三价铬,对于配体置换反应来说是惰性的。为了提高其活性,可以加入少量的还原剂(如锌 / 盐酸),将其还原为氯化亚铬,很快发生配体交换反应,然后使其与 CrCl 通过氯桥发生电子转移,获得三价铬的配合物,并再生成少量活性的Cr(II),直至所有Cr(III)都发生了取代反应。无水三氯化铬几乎不溶于水,但在还原剂(如锌)存在时会缓慢溶解,原因可能是生成了电荷转移的桥连配合物 [Cr-X-Cr…X]。溶解的产物是紫色的 [Cr(HO)] 离子。如果配体是吡啶,则产物是 [CrCl(CHN)]。Cr(III)的配位数为6的配合物大多都是八面体型的。与碱金属氯化物(如氯化钾)熔融时,三氯化铬生成含八面体型 [CrCl] 离子,以及多聚生成的 CrCl 等离子的盐类。无水三氯化铬可通过单质高温化合制备。或者800°C时,用三氧化二铬与氯气在碳存在下反应也可以得到无水三氯化铬。六水合三氯化铬在650°C时与四氯化碳蒸汽反应,可以得到不含 CrOCl 的无水三氯化铬。也可以用亚硫酰氯脱水。水合三氯化铬可由金属铬与盐酸反应得到。无水三氯化铬是有机金属化学中的重要原料。以它为原料可以制得很多有机铬化合物,比如结构上与二茂铁类似的二苯铬(下图)。三氯化铬也是很多铬(III)配合物的起始原料。有机合成中,CrCl 被原位还原生成的 CrCl 是常用的有机还原试剂之一。它可以(A)将 C-Cl 键还原为 C-H 键,也可以(B)与醛作用,将其还原为烯基卤化物。第二个还原反应中通常用2:1摩尔比的三氯化铬和氢化铝锂。三氯化铬的路易斯酸性可以用于催化某些反应,例如用亚硝基化合物作亲双烯体的狄尔斯-阿尔德反应。\n\n### 文章 160\n\n葡萄牙国徽\n葡萄牙国徽(),为盾徽,中间白盾绘有五个呈十字状排列的小蓝盾,蓝盾绘有五个呈X形十字分布的白色圆点。外面红盾绘有七座金色城堡。置于浑天仪上,再以用红绿两色绶带束起的橄榄枝装饰。此徽颁布于葡萄牙第一共和国成立后的1911年6月30日,且沿用至今。代表葡萄牙的徽章在大概在1000年前已经出现。最早可以追溯到勃艮第的亨利(葡萄牙开国君主亚丰素·殷理基的父亲)之银盾蓝色十字。经过多个世纪的改朝换代,葡萄牙国徽的图案内容也有所增减。1910年10月5日革命后,成立葡萄牙第一共和国,国徽则在翌年6月30日开始使用。葡萄牙王国在1139年宣告独立,自1143年签订萨莫拉条约正式从卡斯蒂利亚王国分离,象征著王权与铸币权的银色圆点便被加在勃艮第的旗帜上,以宣示主权的独立。经过中世纪长年累月战争的洗礼,当桑乔一世继承他父亲亚丰素的徽章时,盾牌上的图案已由十字被磨损成五个小盾牌。各小盾牌内的圆点起初有11个,后来塞巴斯蒂昂在位时把圆点的数量减至5个。这在现代被解读成与耶稣受难时的有关。红框和里面的城堡是亚丰素三世统治时期加上的。源自卡斯蒂利亚的城堡代表在收复失地运动中从摩尔人夺取的城池。当亚丰素三世夺取其兄桑乔二世的王位时,由于他是亚丰素二世的次子,并无准备登基成为国王。他的纹章融合了父亲葡萄牙式的盾牌和卡斯蒂利亚式的红色框界和金色城堡。尽管初时城堡的数量由8至12座不等,而亚丰素四世曾经定为12座,但后来塞巴斯蒂昂最终把数量定为现时的7座。与西班牙式的城堡不一样的是,西班牙式城堡的城门绘上的是蓝色(保持开放);葡萄牙式城堡的城门绘上的是金色闩门(没有开放)。浑天仪自15世纪起成为代表葡萄牙的其中一个元素,在许多葡萄牙的殖民地旗帜上(特别是巴西)也可轻易找到。它在航海的重要用途(辨认方向和测量距离)意味著地理大发现时代对葡萄牙以及其众多殖民地(即使在共和后也是如此)的重要性。相对王室的冠冕,虽然浑天仪被认为「共和」的象征,不过其实早在葡萄牙-巴西-阿尔加维联合王国时期经已在国徽上出现。这是由于巴西也是联合王国的一部分的关系。\n\n### 文章 161\n\n西捷航空\n西捷航空(WestJet)为一家以加拿大卡加利市作总部的廉价航空公司,为加拿大第二大航空公司。西捷航空提供客运、货运及包机服务,目的地共有89个,主要在北美洲及墨西哥。目前西捷航是一家拥有7000多名员工及12亿美元市场资本值的公司。西捷航空由莱夫·贝铎(Clive Beddoe),马克·希尔(Mark Hill),提姆·摩根(Tim Morgan)和唐纳德·比尔(Donald Bell)于1996年2月29日创立,是一家廉价航空公司。西捷航空营运初时机队只由3架波音737-200组成,员工数量只有222人,航点为卡加利、爱民顿、基隆拿、温哥华和温尼伯,至1997年年客运量已达100万人次。西捷航空在2001年接收首架波音737-700,并快速扩大共服务范围,不断开拓新航线,如多伦多、伦敦(安大略省)、蒙特利尔、哈利法克斯和甘德尔等地。在2004年更飞出加拿大,宣布一系列新的美国航点,包括洛杉矶、旧金山、凤凰城、坦帕、纽约、奥兰多和罗德岱堡;同时开始在飞机上增设个人电视。在2005年西捷航空接收首架波音737-600和-800,同时宣布会把波音737-200全面退役;同年西捷航空亦新增棕榈泉、夏威夷和季节性航班夏洛特等地的的航点,取消了前往甘德尔的航班。在2006年1月最后一架波音737-200退出西捷航空机队,9月接收最后一架波音737-600;同年开办了前往中美洲拿骚的航班。2007年2月,波音公司确认了西捷航空20架新一代波音737的订单。西捷航空参照美国西南航空的营运模式,西捷航空采用全波音737机队,并计划于2013年前将机队扩充至111架。在2008年7月,西捷航空宣布与西南航空实行航班代码共享计划。同年9月,西捷航空宣布因应国际油价下降而取消燃油附加费,该费用的征收不足半年。西捷航空在同年11月新开10条新航线,12月新开2条。2010年10月4日,与国泰航空增设代号共享航班,在新协议下,西捷航空由卡加利、爱民顿、哈利法克斯、蒙特利尔、渥太华及温尼伯出发并往返多伦多和温哥华的航班,将会加入国泰的「CX」代号,显示西捷航空将进一步扩大与寰宇一家的合作关系。截至2017年8月,西捷航空机队如下:将于2013年6月尾启航\n\n### 文章 162\n\n中国国际贸易中心\n中国国际贸易中心(),简称国贸、中国国贸,位于中国北京朝阳区中央商务区的核心地段,是目前中国规模最大的综合性高档商务服务企业之一,由于其地理位置极其优越及设施完备现代,吸引包括美孚、汇丰、丰田等在内的众多全球500强公司入驻办公,是北京市最繁华的的地段之一。三期工程A阶段(国贸大厦A座)高330米,曾是北京市最高的摩天大楼,其北京第一高楼的角色现在已经被位于中国国际贸易中心东侧CBD核心区Z15地块的中国尊(中信集团总部大楼,亦称北京中信广场)所取代。国贸中心位于中国北京朝阳区中央商务区的核心地段,东长安街延长线与东三环路交界处,距首都国际机场直线距离20余公里。北京地铁1号线和10号线在此交汇,设国贸站。国贸中心写字楼由国贸大厦写字楼1座、国贸大厦写字楼2座、国贸西楼、国贸东楼及国贸大厦组成,合共31.8万平方米。1984年7月26日,中国外经贸部下属的对外经济贸易咨询公司和马来西亚郭氏兄弟公司(今嘉里集团)签订《合资经营中国国际贸易中心协议书》。1985年1月7日,外经贸部批准中国国际贸易中心有限公司成立。中资股东为中国世贸投资有限公司,外资股东为香港嘉里兴业有限公司。1985年9月1日,中国国际贸易中心举行奠基典礼,并正式开始动工兴建。1990年8月30日第一期建成使用,它一直是北京中央商务区的地标性建筑。1996年起,国贸二期工程开始兴建,至1999年工程全部完工,国贸总建筑面积达到56万平方米。2002年,国贸三期工程开始兴建。国贸三期的总建设规模为54万平方米,分A、B及C三个阶段实施,其中三期A阶段已经于2010年8月30日建成并投入运营,国贸三期工程B阶段亦于2017年3月获确认完工。三期工程A及B阶段建筑由SOM建筑设计事物所及王董建筑师事务有限公司设计,其中3期A规模为28万平方米、高度为330米,曾是北京市最高建筑。而3期C为一座7层高商场及空中花园,由凯达环球设计,于2017年动工。\n\n### 文章 163\n\n叔梁纥\n叔梁纥(),孔氏,名纥,字叔梁,又称郰人纥、郰叔纥,是伯夏的儿子,孟皮和孔子的父亲。鲁国郰邑大夫。前563年,晋国的荀䓨、荀偃、士匄带着诸侯联军进攻偪阳国。四月初九,联军包围偪阳,不能攻克。孟孙氏的家臣秦堇父用人力拉了装备车到达战地,偪阳人打开城门,诸侯的将士乘机进攻。偪阳国内城的人突然把闸门放下,叔梁纥双手举门,把已经攻入城里的将士放出来。孟献子称赞说:“这就是《诗经》所说的‘像老虎一样有力气’的人。”前556年秋季,齐灵公攻打鲁国边境,高厚把臧武仲围困在防地,叔梁纥与臧畴 、臧贾率领三百名甲士夜袭齐军,把臧武仲送到旅松后返回防地。齐国不久后退兵。叔梁纥与正妻施氏有九个女儿,没有儿子,他的妾生了个儿子孟皮,却因为有足疾,不能做继承人,叔梁纥便向鲁国颜氏求婚。颜氏有三个女儿,最小的叫颜征在。颜父对三个女儿问道:“陬大夫叔梁纥的父祖辈虽然都只是士,但他却是古代圣王的后裔。而且他身高十尺,武力绝伦,我非常希望能与他联姻。虽然他年纪大且性情急躁,但这不值得犹豫不决,你们三个谁能够嫁给他做妻子?”大女儿和二女儿都没有回答,颜征在上前对父亲说:“听从父亲您的决断,还有什么好问的。”颜父说:“就是你能嫁给他了。”他便将颜征在嫁给叔梁纥。颜征在嫁到叔梁纥家后第三个月行庙见之礼,正式成为孔家的媳妇。她因为叔梁纥年纪大,担心不能及时有儿子,便私下至尼山向尼山神祷告,祈求生子,后来生下了孔子。孔子三岁时,叔梁纥死了,埋葬于防。颜征在死后,孔子将母亲的棺材停放在五父之衢,四处询问父亲的墓址,直到郰曼父的母亲告诉了他,孔子才将父母合葬于防,并为之造坟,坟高四尺。叔梁纥的墓地,今称「梁公林」,位于曲阜城东14公里,面对防山,北阻泗水,又称“齐国公墓”、“启圣林”或“启圣王林”。坟前石碑“圣考齐国公墓”由孔子五十一代孙衍圣公孔元措于金明昌五年(1194年)立。梁公林大门前则立有“大元追封启圣王墓”碑,为孔子五十二代孙泗水县尹孔之严于元至元六年(1340年)立。\n\n### 文章 164\n\n坦佩谷\n坦佩谷()是希腊色萨利大区北部一个峡谷的古名,它位于奥林帕斯山以南,俄萨山以北,被希腊诗人誉为“阿波罗和缪斯喜爱的去处”。山谷长10千米,狭窄处仅宽25米,两旁山崖高近500米,匹尼奥斯河于其间蜿蜒而过流向爱琴海。皮尼奥斯河右岸伫立着一座阿波罗神庙,周围月桂丛生,古时人们用它做成桂冠嘉奖皮西安竞技会的得胜者。坦佩谷也曾一度是阿波罗与库瑞涅之子阿里斯泰俄斯的居所,他也正是在此处追赶俄尔甫斯之妻欧律狄刻,以致她在逃走时被蛇咬死。公元13世纪山谷里建起了一座敬献给圣帕拉斯凯韦的教堂。坦佩关是希腊的战略关隘,因为它是从拉里萨穿山到达海岸的主要路线,也正是由于这一点,从古到今许多战役都在这里打响。如要避开此关,也可取道稍迂回的撒伦多普罗关。公元前480年,一万雅典人与斯巴达人试图在坦佩关阻止波斯国王泽克西斯一世的入侵,但波斯人取道撒伦多普罗从而绕开了希腊军队。公元前164年,在第三次马其顿战争期间,罗马人冲破马其顿国王珀尔修斯的防御,之后在彼得那战役中取得了胜利。公元前148年,安德里斯库斯的另一场斗争也在这里上演。无论在标志着罗马时代在希腊的终结的异族袭击中,还是在拜占庭和奥特曼时代,这里也不乏争战。今天对于大多数希腊人来说,坦佩也以其十分恶劣的路况和可怕的交通事故而臭名昭著。例如,在2003年,由于所乘客车与一辆满载木材的货车相撞,二十一名来自马克拉荷里的十一年级一个班的中学生全部死亡。尽管货车司机已尽力在几秒钟的时间内减速,但木材带着巨大冲力从货车后部飞出,从客车左部砸进,当场导致许多学生死亡。美国亚利桑那州的坦佩和澳大利亚新南威尔士的坦佩市都是由此命名。南非东开普省的一个农场也叫坦佩,还有着两个名为奥林帕斯和俄萨的农场邻居。另外,马来西亚槟城沿着一条小峡谷而设的坦佩谷路也是以它命名。\n\n### 文章 165\n\n从四位\n从四位为日本品秩与神阶的一种,位于正四位之下正五位之上,勋等上相当于勋四等,追赠时则称为赠从四位。律令制度中从四位相当于左京大夫、右京大夫等管理朝廷内行政事务的长官、次官。从四位下以上至正四位上者并非公卿之故,敬称为在姓氏与名讳后,增加官位与朝臣之名。例如「细川右京大夫从四位下源胜元朝臣」律令制度时三位以上列为公卿,四位则以藤原氏的旁系或非藤原氏的中级贵族为主。当武门之首清和源氏、桓武平氏初叙从五位下而极位正四位的状况时,既非嫡子又无拥有武勋者可以说是不可能升至此位。镰仓时代北条氏掌握政权后,不只是北条氏嫡子升为正四位上,北条氏家族一门与有力家臣也获得从四位下等官位。室町时代以后各地有力大名均可获得此位,尤其是负责三管领四职的足利氏一门、有力守护大名、或是名门出身的守护家柄。足利幕府将军虽然起初是任职权大纳言等公卿相当的品秩,但室町时代后期以降将军后继者的竞争更为激烈,13代将军足利义辉、足利义昭等皆以从四位下接任征夷大将军,为跳过正四位以从四位之身位列公卿的例子。进入战国时代后三好氏等幕府相伴众也位列从四位下,也发生家臣松永久秀也与本家一样位居从四位下等与实力相应的状况。织田信长的后继者丰臣秀吉在消灭室町幕府后,将德川家康或前田利家等重臣升为二位、三位之品秩,其嫡长子与重臣则升为从四位。德川家康建立江戸幕府后,亲藩大名与谱代大名家内的老中等重臣、旗本中的高家、外样大名中10万石以上者皆拥有此位。明治时代从四位相当于华族中的男爵位,与陆海军的中将。今天主要是有所功劳的公务员、在艺术、文化、学术研究拥有功绩的大学教授。\n\n### 文章 166\n\n兰尼埃里 (两西西里)\n兰尼埃里·玛利亚·加埃塔诺(Ranieri Maria Gaetano,兰尼埃里·玛利亚·贝尼托·约瑟夫·拉巴洛·加埃塔诺·弗朗西斯科·萨维里奥·巴巴拉·尼科洛和所有的圣·迪·波旁,Ranieri Maria Benito Giuseppe Labaro Gaetano Francesco Saverio Barbara Niccolo et omnes sancti di Borbone,),两西西里王子,封卡斯特罗公爵,1960年起为波旁-两西西里王室家族族长。兰尼埃里是两西西里王子、卡塞塔伯爵阿方索与妻子波旁-两西西里的安东妮艾塔的第五子,1883年12月3日生于法国戛纳。他出生时两西西里王国已灭亡,父亲流亡法国戛纳。1894年,阿方索成为波旁-两西西里王室家族族长。兰尼埃里年轻时曾在西班牙军队服役。1960年,兰尼埃里的长兄波旁-两西西里王室家族族长费迪南多·皮奥去世。由于次兄卡洛于1900年放弃自己和后代对两西西里王位的继承权,成为西班牙王子;三兄早夭;四兄早逝且没有子嗣,兰尼埃里成为波旁-两西西里王室家族族长。若两西西里王国继续存在,他将成为两西西里国王兰尼埃里一世。兰尼埃里的宣称得到了大部分欧洲王室和大部分亲属的认可,但西班牙王室却主张西班牙王子阿方索·德·波旁-两西西里为波旁-两西西里王室家族族长,因为他是兰尼埃里次兄卡洛的长子。于是两西西里的王位继承分为那不勒斯派(或称卡斯特罗派)和西班牙派(或称卡拉布里亚派)。1966年,兰尼埃里将两西西里的继承权让位于长子费迪南多·玛利亚。1973年1月13日,兰尼埃里在法国奥德省拉康贝去世,终年89岁。1923年9月12日,兰尼埃里在斯洛伐克鲁日巴希与表妹波兰贵族卡罗琳娜·扎莫伊斯卡(Karolina Zamoyska,1896年9月22日—1968年5月9日)结婚。卡罗琳娜·扎莫伊斯卡是兰尼埃里的三姨母两西西里公主玛丽亚·卡罗琳娜与安德烈·扎莫伊斯基伯爵的女儿。兰尼埃里与卡罗琳娜有一子一女:\n\n### 文章 167\n\n新发田长敦\n新发田长敦(しばた ながあつ,1538年(天文7年)─1580年(天正8年)。新发田家的祖先是在源平合战中,讨伐越后城资盛的总指挥御家人佐佐木盛纲。1530年,上杉家一族的上条定宪和守护代长尾家相互对立,发生史称的上条之乱。五十公野城城主新发田纲贞(新发田长敦之父)与本庄房长、鲇川清长、水原政家、黑川清实、五十公野景家、加地春纲、竹俣昌纲等等下越国人(即扬北众)一起站到上条定宪一方,与长尾为景交战,在历经一番战战合合后,最终都为上杉谦信的勇武所折服,成为其麾下势力。上杉谦信平定越后之际,新发田纲贞的嫡子新发田长敦继承了家名,成为新发田城城主。新发田长敦侍奉上杉谦信后逐渐头角显露,以优秀的外交手腕著称,担任春日山城门的班职,并在各地的战役中活跃,因此受上杉谦信的重用,列为越后七手组大将之一。第四次川中岛之战中,新发田部队击溃了武田军诸角虎定部,并讨取老将诸角虎定,立下了大功。1568年,武田军进入信州长沼,新发田家受到上杉谦信动员的命令,新发田长敦率同一族的五十公野家出阵信州饭山,这以后他又先后担当了上杉家内政和充分发挥了其优秀的外交手腕,在与武田胜赖的和平谈判中出尽全力,直至1580年病死为止。作为其一族的竹俣庆纲和入继了五十公野家并担任外交方面要职的弟弟五十公野治长(新发田重家),也是上杉谦信政权中占有重要地位的家臣。1578年谦信病殁,他在之后的御馆之乱中支持上杉景胜一方,表现十分活跃。新发田重家是扬北众中的重镇,御馆之乱后,因赏赐问题而产生谋反之心,『越后治乱记』中谈到:上杉景胜对新发田重家的战功给予了封赏,可是新发田重家对得到的赏赐数量却表示不满,一方面他装做满足于继承新发田家,而另一方面却在不知不觉中走向了谋反的道路。1580年,新发田长敦的弟弟新发田重家从娘家五十公野家返回继承了新发田家。1582年,新发田重家最后决定谋反,并侵占新潟津的冲之口,并与织田信长取得了联系及协助织田军攻打上杉家,而且逼的兵败如山倒的上杉景胜差点自尽,不过却因为发生本能寺之变而令正在进攻上杉家的织田军返回近畿,同时亦因新发田重家的谋反而令新发田家走向了灭亡。\n\n### 文章 168\n\n独家追辑\n《独家追辑》(),马来西亚ntv7电视台与制作公司Double Vision联合制作的一套时装电视剧,共20集。FMP杂志社因为两名资深记者突然辞职而陷入一片混乱,然而身为杂志社老板兼主编的何志光却置身事外,把所有的工作都交给了员工。杂志社采访主任吴皓泽和摄影记者杜子腾无意间卷入偷车事件,让保险员文沛晴无故被误会是共犯。在深入调查后,吴皓泽发觉文沛晴根本没有与偷车集团合谋,真正主谋竟然是广志强,一位经验老道的汽车销售员。在吴皓泽跟警界好友高勇合作下,广志强最后绳之于法。患有严重心脏病的孤儿李宛心在杂志社的大肆报道下找到了合适的心脏移植,无奈的是心脏出现排斥现象,最终不治身亡。可贵的是,李宛心的逝世唤醒了民众关于捐赠器官的意识。不过也有一些不法集团企图利用李宛心的事件募款基金,幸好最终叫颜慧妮等人给识破,及时阻止。何志光之幼妹何芷萱与上司闹翻,被逼从大报馆转到大哥的小杂志社任职。好胜的何芷萱与吴皓泽性格和工作方式迂回,两人因此成了斗气冤家。吴皓泽因一场交通事故,与文沛晴再次结缘,发展一段似有似无的感情。何志光和PINK姐前后陆续无故离奇失踪,何志光的长妹何芷杉从台湾赶回来撑局,好让何芷萱和吴皓泽可以追踪何志光失踪的新闻。经过一番查访之后,最后他们终于找到了何志光,原来何志光是遭到公司的员工小松绑架。小松因为涉及放火烧死一家五口案件而被何志光识破,发了疯的小松绑架何志光欲与他同归于尽,幸得吴皓泽等人时赶到,成功把何志光救出。另一方面,何芷萱因与吴皓泽一起工作又一起去追踪哥哥何志光失踪案件而渐渐喜欢上他,因而与吴皓泽、文沛晴陷入三角恋中。何芷萱与吴皓泽越来越合拍,引起文沛晴妒嫉,吴皓泽则面临选择,最终明白所爱的人是何芷萱,无奈何芷萱已离开大马。几年后,何芷杉放弃了台湾的事业留在大马发展;何志光与PINK姐有情人终成眷属,过着退休生活;颜慧妮和杜子腾各有各发展,唯独吴皓泽仍然独身,依然继续在新闻界冲刺。一日,吴皓泽外出跑新闻时突然被一辆回退的车子撞倒,下车理论的时候,发现司机竟然是刚刚从外国留学回来的何芷萱……主题曲:《记录》罗忆诗、李承运\n\n### 文章 169\n\n阿閦佛\n阿閦佛(,,;「閦」音「触」),又名不动佛、无动佛,五方如来之中的东方佛。据《阿閦佛国经》-{云}-,阿閦佛在成佛久远之前,曾侍奉大目如来(又译广目如来),示而萌发「对众生不生瞋恨」(「不恚有情」)的誓愿,经过累劫的修行,即于东方妙喜世界成佛。 即便为人所怨恨,也不退转,不为嗔恚而动,是为“不动”。与「不动明王」不同。阿閦佛,为大乘佛教信仰中,东方妙喜世界的佛陀,地位等同于西方极乐世界的阿弥陀佛,著名的维摩诘居士即是出自妙喜世界。阿閦佛的妙喜世界非常庄严,有高大的七宝菩提树。阿閦佛信仰与阿弥陀佛信仰皆起源于大乘佛教早期,不过同属大乘的汉传佛教中,另外一位东方琉璃世界的药师佛较为人知。在藏传佛教与密宗信仰中,阿閦佛是金刚界五智如来(五方佛)中的东方如来,代表“大圆镜智”。最早有关阿閦佛的汉语佛经是公元147年由东汉月氏三藏支娄迦谶法师译成汉语的《阿閦佛国经》,这部经也是已知最古老的净土经典。最近在巴基斯坦发现了用犍陀罗语书写的,涉及到阿閦佛的佛经残卷,它们属于早期的大乘佛教,书写时间在公元1世纪末和2世纪间。阿閦佛心咒则是阿閦佛信仰者持诵以求得渡的经典。大宝积经载:「若有善男子、善女人,闻不动如来功德法门,善能受持,读诵通利,愿生彼刹者,乃至命终,不动如来为护念,不使诸魔及魔眷属退转其心」。阿閦佛在不同的经典中也被译为阿閦鞞佛、阿刍鞞耶佛、恶乞刍毗也佛、不恚佛、无怒佛、无嗔恚佛。阿閦佛的形象,据瑜伽母密续记载,为蓝身,偏袒右肩,左手执拳,执袈裟角,右手伸五指,手指指地,置于右膝。一般其像结跏跌坐,坐于青色象背负的莲花台上。此佛在金刚界曼茶罗中,为左手执拳或持金刚杵安于脐前,右手下垂触地,成触地印。\n\n### 文章 170\n\n佛堂门天后古庙\n佛堂门天后古庙,俗称大庙,主奉天后妈祖,是香港最著名《百载𬬻峰》1982年第十一集·民间信仰和最古老的天后庙,也是广东沿岸现存最古老的天后庙,,现已被列为香港一级历史建筑,并由华人庙宇委员会负责管理。古庙位于新界西贡区清水湾半岛以南的大庙湾地堂咀,邻近佛堂门及布袋澳。该庙属于三开间单进设计,大殿供奉天后娘娘,右偏殿则有一座铜钟及龙床。由于庙宇三面环山,而且那些山区都是郊野公园范围,所以如要循陆路进入,必须在大庙坳一带的大坳门路经过一条不明显的行山径前往。然而该庙大部份信众都是清水湾布袋澳一带的村民,他们自己都会有船只前往,并可在庙宇对出的码头停泊,所以一直以来,该庙对外的陆路交通都一些未有进行完善的开发。直至清水湾乡村俱乐部落成后才稍作改善。该庙正面壮观,前面有一大片空地。前簷突出,由正门前两柱支撑成门廊。左右各有两个偏殿,可从内左右月牙门转入。左边偏殿分别供奉天后龙床及欢喜佛,而右边偏殿则是司祝的办事处。正殿供奉天后,另有2艘长2米多的天后神舟模型,置于正殿两旁。庙内仍保留了清朝嘉庆4年(1804年)所铸的铁香炉及道光20年(1840年)铸造的铜钟等文物。可能还有石刻碑文。除天后外,本庙亦供奉另一神祇金花娘娘。每年农历3月23日是天后诞,当天前来参拜的信众络绎不绝,达3-4万人之多。善信更喜欢到侧殿摸龙床,以求子或财帛。佛堂门天后庙曾分别于道光20年(1840年)、光绪3年(1877年)及1962年重修。西湾河码头设有街渡服务途经大庙湾往来东龙岛,平日仅于星期四来回各开1班,星期六及假日分别设有来回4班及6班街渡,现时来回收费$40。新世界第一渡轮每逢天后诞前夕及正日(农历3月22及23日)会加开特别渡轮服务,往来北角码头及大庙湾,北角码头于10:00至翌日15:00提供服务,大庙湾则是11:15至翌日16:15,每小时一班(深夜时段每2小时一班)。现时普通渡轮单程收费$30,高速船收费$35。\n\n### 文章 171\n\n魔神相克者\n《机巧魔神》()是电击文库自2005年7月起出版的轻小说作品。作者三云岳斗、插图和狸ナオ。故事主角夏目智春在三年前空难意外幸存后,开始被自称守护灵的青梅竹马水无神操绪依凭,在高中开学前搬进了其兄长夏目直贵曾居住过的闹鬼房屋鸣樱邸,同日,穿著黑色服装的美女黑崎朱浬受其兄长之托将银色手提箱交给了夏目智春,并唤醒了名为「机巧魔神」的谜之兵器。被下达了必须运用兵器拯救世界的智春,却又遇上了自称恶魔的巫女,还有同样被幽灵缠上的学生会长等人,作品就以这些人为中心展开。以下人物以二巡目世界为准。以下是关于本篇科学部部长代理‧黑崎朱浬归纳关于黑科学的说法与主要部分(参照第一卷)。自古以来,魔术和科学是相同一起的,炼金术遗留下来的东西对今日的化学贡献做了很大有名地的事,不过,但不仅只有那个。现在的科学是将过去在于多样的领域还原到极限继续追究只为当作一个准则,现在为了试图也日夜尝试找寻著。所谓「黑科学」是指在那个提出想法上对主张不同的事物。炼金术成为转换化学并且代表一种手段,数学与卡巴拉密术(塔罗牌)是最先进的秘诀,天文学与占星术也因诞生。在重新考虑此处的话,截至上述「只有一个准则」以实际来说是很奇怪的事。在魔术打破一切相关规则。占卜‧卡巴拉与炼金,不过,黑魔术和善意(白)法术存在于魔术里。有时,如果像黑科学也像必然对立的两个不相容不必然性地存在可笑。换句话说,现在以广泛而闻名的现代在科学上做对立的还有一个理论体系,那个就是「黑科学」。以下为已登场的机巧魔神(如无特别注明的话是第二巡世界之人):第一季电视动画于2009年4月起在UHF放送局、日本BS放送、AT-X播放。第二季电视动画在2009年10月起播放。\n\n### 文章 172\n\nJust can\'t help it.\n《Just can\'t help it.》(,"Just can\'t help it.")是东京事变的第五张DVD,于2006年9月6日发行。发行当周即卖出3.0万张,总计销售额5.1万张,名列2006年年度销售榜第30位。初回限定为「Digipak纸盒仕样」。此张DVD是收录东京事变《"DOMESTIC!" Just can\'t help it.》 巡回演唱会的其中一站,于2006年5月26日在NHK会馆(NHK HALL)所举行的,其演唱的歌曲及幕后花絮。演唱会中的新曲「Mirror Ball」、翻唱林檎给友阪理惠「机器少女」和「停电」于8月21日开始接受线上下载的服务,同一天也成立了DVD特设网站。在日本09月6日发行DVD,台湾则是等到09月26日才发行进口盘。《"DOMESTIC!" Just can\'t help it.》为二期东京事变第一次巡回演出,总共在十六个城市举办二十一场的演唱会,场场皆吸引爆满的观众前往感受东京事变的魅力。演唱会演唱的曲目以第二张专辑《大人》为主,演唱会的开场便是日本传统乐的歌曲雪国,身穿和服的林檎,抓住了众人的目光,还有服务这首歌,全体团员拿著大声公演唱,中途搭配上团员们台上换装的片段,带起一波高潮。而演唱会利用投影的方式,搭配团员们的的动作与歌曲的内容,让人惊叹,像是中场时,鼓手刄田缀色凭空踢球的效果,还有脸孔这首歌时,钢琴手伊泽在钢琴独奏时,便把改编的英文版本歌词投影至舞台,这种投影的效果,不但提高了演唱会的可看性,更增加了与台下观众互动的机会。另外由于椎名林檎在专辑《大人》发行接受访问中提到「今后,她想要专心作词和演唱,作曲则会交给其他成员。」因此,在巡回演唱会上发表了浮云所创作的曲目「Mirror Ball」,借此希望之后的活动能以团员的创作曲目为中心。\u3000椎名林檎 - 主\u3000唱・吉他手\u3000龟田诚治 - 贝斯手\u3000刄田缀色 - 鼓\u3000手\u3000\u3000浮云\u3000 - 吉他手\u3000伊泽一叶 - 钢琴手・吉他手\n\n### 文章 173\n\nPCX\nPCX是一种由美国乔治亚州的ZSoft公司所开发的影像档格式,原本是该公司的PC Paintbrush软体的档案格式(PCX代表PC Paintbrush Exchange),却成了最广泛接受的DOS影像标准之一,然而这种使用格式已经被其他更复杂的影像格式如GIF、JPEG、PNG渐渐取代。PCX是一种不受平台限制的像素影像格式,档案标头储存著有关显示硬体方面的资讯(萤幕解析度、颜色深度、色盘资讯、位元平面(bit planes)等),有别于后面夹带的实际档案资讯。这个资讯能让影像可以正确地传送与显示在不同硬体上的电脑系统。PCX档案一般来说,储存色盘索引的影像,范围从2、4种色彩至16与256种色彩,而且格式同样可扩充以记录真实色彩(24-bit)的影像。PCX使用区段长度编码(Run Length Encode;缩写RLE),是一种简单的演算法,可以把代表同一个颜色的多个连续位元组,简化成一个双位元组。当档案做处理时,最高位元会用来当作控制切换(旗标),用来决定所给的资料是代表一个像素中的色盘索引值、色彩数值,还是一个用来表示数个接连相同数值像素的RLE数值。由于使用两个最高位元来当作旗标,在一个具有256色盘的PCX档案里,色彩索引编号192至255(其两个最高位元都已设为1),则必须储存成RLE双位元组,即使它们在区段中只出现过一两次。而色彩索引编号0至191就可以直接储存或是存成RLE双位元组(无论哪一种较省空间)。因此实际的压缩率可以透过适当的排序色盘顺序来达到最佳化(然而若与其他影像共用色盘时则可能无法实行)。举例来说,一个色盘可以将最常出现的色彩放置于色盘索引编号的0至191的位置,而最少使用的色彩则可座落于色盘的后半部,这个RLE机制可以有不错的应用。RLE压缩演算法仅需少量的处理器资源与记忆体即可应用,以当时的电脑系统来看是非常有用的,但现今电脑的硬体与显示设备逐渐的复杂精密,RLE演算法反而变成没那么省空间,它无法压缩混色(dithered)的影像例如相片或复杂的电脑图像。\n\n### 文章 174\n\n我的暑假\n是2000年6月22日由索尼电脑娱乐发售的PlayStation平台专用游戏。制作公司为Millennium Kitchen。约1年后的2001年6月14日推出廉价版的PlayStation the Best版。故事背景为1975年(昭和50年)、在写实的日本绿油油的森林和山包围著的乡郊下、令人心矿神怡的月夜野町成为游戏舞台。由繁嚣的城市家庭、转换到田野间的亲戚家中。扮演著故事的主角「ぼく(我)」、在夏天的一个月间、捕捉昆虫与探险、经历那亲切的家族和朋友之间的故事来进行的高自由度游戏。在游戏中可以体验童年时的夏天活动,包括「捕捉昆虫」,「钓鱼」,「绘图日记」,「洞穴探险」,等。享受那自然风景中的「乡村」,让成年人随时随地的再一次感受那时的童年生活乐趣。2002年7月11日在PlayStation 2中推出《我的暑假2 海之冒险篇》亦受到日本人的热烈欢迎。同时,2006年6月29日也在PlayStation Portable 平台推出本作的重制移植版的《我的暑假携带版 昆虫博士和山顶的秘密!!》。加入主角在PS版未使用的台词。收录PS3版本的《我的暑假3 -北国篇- 小男孩的大草原》的特典影像。昆虫捕获大幅增加虫的种类,由原来PS版的64种类,增加到128种类,是原来的2倍。附近还未捕捉的虫,会以「NEW」标示。虫相扑虫相扑,「()」的甲虫,可以连续进行游戏。利用ad hoc通信时,更可以与人交换「()」的甲虫。钓鱼为了弥补PSP没有振动功能,当有鱼落入后,画面上方会提示「HIT」。作词:小薗江圭子作曲:森山良子编曲:Thousand sketcheS主唱:大藤史原作‧脚本‧监督:绫部和角色设定:上田三根子背景美术:草薙一个最可怕的错误「由讨厌的臭虫做成的骚乱——“《我的暑假》的8月32日”。而这个错误在PlayStation Portable版己获得修正。这是由于《我的暑假》程序上引起的错误,要进行这个的话,日记中的日期会继续8月32日,33日…等。错误日数,使各个人物贴图变得混乱及可怕,家中和外边的人都不存在,音乐消失、当机、出现乱码等奇怪的错误,随著日子的推进,错误问题会变得恶化。这个错误使原本带有温馨气氛的游戏,在32日以后被完全破坏。\n\n### 文章 175\n\n科学战队炸药人\n《科学战队炸药人》(原题:)是日本东映公司在1983年制作的「超级战队系列」第7部特摄作品。在日播放期间为1983年2月5日-1984年1月28日,全51集。远古时代,坠落于地球上的陨石中残存的生命物质,在地底下经过长年的进化成了有尾人一族-邪进化帝国。因尾巴的数量代表其身分的象征的特有文化,将利用它们超乎人类想像的科学力征服地上的人类,以让日本各地火山喷发为第一步,开始了侵略地上世界的行动。然而,及早察觉到这件事的科学家·梦野久太郎,集合了五名智慧与体力都相当优秀的年轻科学家到自己所营运的发明中心来,也正式宣布科学战队的成军。五人著装了梦野博士开发的战斗强化服后,成了炸药人并衔命全力阻止邪进化帝国侵略的邪恶野心。第9回后的播出时间皆缩短至25分钟。梦野久太郎于远古时代坠落到地球上的陨石中生命物质,长久以来寄居于地底进行著自主进化,并成为了能自由操纵火山的地底支配者「有尾人一族」们的帝国。属于卵生,故于蛋中出生,会将尾数加于名字,且尾数越多代表在帝国中越高。十分藐视没有尾巴的人类(地上人),并视为「下等生物」,在无法透过实验让人类长出尾巴后,便乘著有如怪物一般外观的巨大攻击要塞格兰吉兹摩,向地表上的人类展开侵略行动。亚顿卡亚洁诺比亚梅基度奇梅拉进化兽机械进化兽大爆炸光束小尾兵格兰基兹摩基兹摩斯奇托大木星 DyJupiter炸药马赫 Dyna Mach炸药战车 Dyna Mobile炸药拖车 Dyna Garry炸药猎鹰 Dyna Falcon炸药吉普车 Dyna Machine第一话登场。当炸药红喊出『合体! Grand Slam!』后,由炸药马赫、炸药战车、炸药拖车三体合而为一的巨大机器人。由梦野博士开发制造。于剧场版『199英雄大决战』中登场。武装招式必杀技以下时间以当地时间(日本时间)为准本作品的战队服装曾经被台湾自制特摄节目《太空战士》作为参考。片头曲片尾曲插曲\n\n### 文章 176\n\n施思明\n施思明(),天津人,祖籍江苏苏州。谱名施耿元,字贯生,号思明,是中国著名外交家,世界卫生组织创始人之一,并曾出任联合国医监。施思明博士于1908年4月5日生于中国天津,是中国二十世纪出知名的杰出外交官施肇基博士的长子。其父施肇基博士曾任中华民国驻英国大使、驻美大使,中华民国外交部长并曾出任中国常驻联合国代表。在施肇基博士任驻英国大使期间,施思明博士随父移居英国,就读于温切斯特公学,后于剑桥大学基督学院获得医学硕士学位。毕业后至1934年返回中国期间,施思明博士曾在英国圣·托马斯医院()实习,圣·托马斯医院座落于伦敦一个贫穷地区,主要服务于大众人民,这段实习经历使施思明博士被激励立志在公共医疗卫生领域有所贡献。1934年,施思明博士返回中国,参加中国医学会上海支会,并与1936年被选为上海支会总行政秘书。1937年抗战爆发后,施思明博士进入中华民国国民政府负责实施美国租借法案的工作小组。1941年后,施思明博士前往美国,出任国民政府时任财长宋子文的机要秘书并继续参与租借法案对华实施。施思明博士于二战即将结束之际以中国代表团组员及医学专家身份出席了在旧金山举行的联合国成立预备会议,即旧金山会议()。施思明博士后来担任了经社理事会附属机构的总监,但是后来由于担任联合国职位而与出任世界卫生组织高级官员擦肩而过曾让他倍感失望。施思明博士于1948年起开始担任联合国医学总监,负责约3000名固定联合国职员的医疗卫生工作,以及执行海外任务前的免疫及医疗卫生准备工作。施思明博士担任此职位长达20年。施思明博士于1934年与上海著名银行家李敏先生的长女李月卿结为连理。施思明博士有一子施家铭,一女施家莲。
施思明博士于1998年10月27日故于美国宾夕法尼亚州匹兹堡市郊的长老会医院(),美国多家主要媒体均刊载了施思明博士病故的消息。\n\n### 文章 177\n\n图形计算器\n图形计算器通常指一种能够绘画图象、解方程组以及执行其它各种操作的手持计算器,大多数图形计算器还能编写程序。由于它们的屏幕较一般计算器大,因此能够同时显示多行文本。一些图形计算器甚至有彩色显示或三维作图功能。由于图形计算器可以编写程式,所以它也广泛被用于电子游戏上。一些电脑软件也可以完成图形计算器的功能。CASIO(卡西欧)在1985年制造了世界上第一台图形计算器 fx-7000G。不久 HP(惠普)也推出了 HP-28C。之后的款式有 HP-28S (1988)、HP-48SX (1990)、HP-48S (1991)及其他等的图形计算器。2006年推出的 HP 50g 更具有计算机代数系统(CAS),是目前最先进的机种之一。Texas Instruments(德州仪器)自1990年起亦开始了生产图形计算器,最老的型号是 TI-81,此后有 TI-82 系列、TI-83 系列、TI-84 Plus 等等。TI-89 和 TI-92 亦设有计算机代数系统(CAS).(值得注意的是,TI-92 PLUS这个TI-92的升级版,理所应当的也具有CAS功能)在美国以及加拿大地区里,由于绘图计算机对计算和绘画方程式时有很大帮助(不用学生慢慢地绘图),许多的高中数学教师也允许并鼓励学生在课堂上使用图形计算器。在某些课程里(例如微积分)甚至是必需的。含有某些功能(例如通讯或网际网路存取)的计算机,往往被禁止在学校里使用,以防止学生作弊或上课时不专心。中国北京的数学应用竞赛的复赛(笔试)中,图形计算器和科学计算器是允许被带进考场的。不过,在某些学校或考试机构中,学生在考试开始前须将所使用的计算机上交监考人员设定,待考试开始时再发还。监考人员会将计算机设为「考试模式」。在这个模式下,计算机预先存储的资料将无法存取,监考人员还可以选择封锁计算机的部分功能,例如直接求解方程组、绘图或CAS(电脑代数系统)等。在东亚地区,为锻炼学生的计算能力,考试时往往禁止使用任何计算机,当然也包括绘图计算机。这使得东亚地区的学生的计算能力通常明显强于西方同龄学生。由于图形计算器能编写程式码,所有很多游戏被制造了出来,包括于 Texas Instruments 的 TI-84 里附载的「Puzzle Pack」。游戏例子︰
\n\n### 文章 178\n\n胡燕泳\n胡燕泳(),香港新闻从业员。2001年胡在香港中文大学新闻与传播学院毕业,曾经从事公关工作。2003年转职香港有线电视新闻主播,并于同年转职到24小时亚视新闻台。2006年获奖学金,留学伦敦大学亚非学院,念国际研究与外交硕士。及后开始于免费频道本港台报道新闻,曾任担任本港台六点钟新闻、夜间新闻主播一职。2007年与黄珊、黄雅宇共同担任《主播天下》的主持及策划职务。2010年3月,她辞职并离开亚视新闻的播报工作,至2012年7月以兼职身分重返亚视新闻工作。2012年11月在报章撰文批评亚视高层干涉新闻部运作后,遭亚视解雇。2013年4月起,任无线新闻外电编辑,同年9月尾开始成为下午《新闻提要》主播。2013年12月7日起,担任《午间新闻》主播。2015年3月2日起,担任《环球新闻档案》旁白。2015年中,辞职并离开无线新闻,转职到香港经济日报。亚视受管理层连番操控,声称收视与TVB「四六开」惹来公众、广告业界人士和学者质疑,动员员工反对政府发出新免费电视牌照的举措也令全城非议。胡在2012年11月于《明报》发表题为《来自亚视的声音》的文章,力斥管理层王征和盛品儒于多次事件的处事手法都很有问题,批评王在亚洲电视误报江泽民逝世事件中没有任何承担;在政府总部举行的「大集会」王盛二人的言论及行为「着实超乎常人所能接受的尺度」,更严重的是「人们对亚视的鄙视,似乎并不规限于个别人士,而是整个亚视遭殃,新闻部也不能幸免」。另外,胡指出,过去她与同事制作《主播天下》时亚视给予新闻部很大自由度,但如今已今非昔比;原本《主播天下》的后续节目《ATV焦点》本来同样由新闻部记者制作,但最终已变质成为高层公器私用的平台;她和《ATV焦点》撰稿作者(前《大公报》执行总编辑雷竞斌)「在新闻部碰口碰脸」并不稔熟,但「因为他的个人大作,却引来四万宗投诉、网民的唾骂、前线记者在政总采访受滋扰;一人创作,新闻部百人当灾,我不甘心看到这境况」。2012年11月26日,亚视突然解雇七名员工,胡是其中之一;对她被辞退是否与批评公司有关,亚视公关部称不会回应。\n\n### 文章 179\n\n乐广\n乐广(),字彦辅,南阳淯阳人。西晋时期官员,官至尚书令,在当时声望很高,故亦称乐令。八王之乱期间因被司马乂怀疑叛投司马颖而忧死。乐广因父亲乐方早死,年少孤贫,侨居于山阳,因家世寒微且贫困而无人知晓。后来裴楷曾请乐广与他共谈,谈了一夜后相互钦佩推崇,裴楷更自言不如乐广。当时任荆州刺史的王戎因乐广曾被夏侯玄称许而举他为秀才,及后裴楷又向时任太尉的贾充推荐乐广,乐广于是被贾充任命为太尉掾,后迁任太子舍人。当时乐广亦被朝中名士如衞瓘、王衍等人赞赏,衞瓘更命儿子门去造访他。乐广后外任元城县令,随后又入朝任中书侍郎,又曾当过太子中庶子,屡次升迁后至侍中、河南尹。永康九年(299年)十二月,皇后贾南风废掉司马遹太子之位,至次年年初,司马遹被送至许昌禁闭,并下令太子宫中属官不能送行。不过江统、潘滔等人都违反禁令去送行,故遭司隶校尉满奋命人收缚下狱,不过乐广就下令将因此事而拘禁于河南郡的太子属官都释放了。当时人们都为乐广担心,不过因孙琰向贾谧说若收捕乐广和属官,将会彰显司马遹的善,贾谧听从,乐广于是没有获罪。后赵王司马伦于永康二年(301年)篡位称帝,乐广与满奋及崔随奉玺绶授予司马伦。乐广后来迁吏部尚书、尚书左仆射,永宁元年(301年)司马繇将任尚书左仆射,乐广于是转任尚书右仆射,领吏部。后接替升任司徒的王戎任尚书令。成都王司马颖与河间王司马颙进攻长沙王司马乂,围攻洛阳时,因为乐广的女儿是成都王妃,故此作为当时朝望的乐广受到诽谤。司马乂亦因而去问乐广,不过乐广神色不变,答:「我怎会为了一个女儿而换掉了我家五个男子的性命。」意谓不会因为女儿而依附司马颖,换来五人被司马乂诛杀。不过司马乂未因此释疑,乐广亦于太安三年正月丙午日(304年2月29日)忧死。\n\n### 文章 180\n\n郑思肖\n郑思肖,原名郑之因,祖籍连江(今福建福州连江县),字忆翁,号所南,又号三外野人,宋末元初画家、诗人。南宋亡国后,孤身隐居苏州,终身未娶。郑思肖生于南宋理宗淳祐元年(1241年)。祖父郑咸曾任枝江县主簿。父亲郑起,字叔起,号菊山,从事教书生涯。母亲楼氏。南宋末年,通过科举,考中秀才,为理宗时的太学上舍,应博学宏词科。咸淳三年(1267年) 元人南下攻宋,咸淳九年(1273年)襄阳失守。郑思肖献策抵抗,因“辞切直,忤当路”,未被采纳。祥兴二年(1279年)南宋灭亡,郑思肖隐居吴中(今江苏苏州),改名思肖(因宋朝皇帝姓赵),改字忆翁;为了寄托爱国情怀,郑思肖坐卧必向南,并自号“所南”;所居之处命名为“本穴世界”(把“本”字中的“十”置于“穴”字中,便是“大宋”,以词寓意其乃大宋遗民,不忘故国。元仁宗延祐五年(1318年),郑思肖于苏州觉报寺内逝世。郑思肖专工画兰,特征为花和叶萧疏,画兰不画土地和根,寓意宋朝沦亡。其存世作品有《国香图卷》、《墨兰图卷》、《墨兰图》等。其中《墨兰图卷》藏于日本大阪市立美术馆,《墨兰图》藏于美国耶鲁大学美术馆。郑思肖在《画菊》中托物言志,以菊花自比,隐含了诗人的人生遭际和理想追求。这首诗的意思是:菊花不与百花为丛,独立却意趣未穷,宁愿在枝头上枯死、遗留芬芳,也不向元朝(北风)投降。常用于表达高尚的民族气节。2017年6月中国国民党主席洪秀柱在海峡论坛的讲话中引用了这首诗的后两句,说“现实轨迹总未必是尽如人意,但逆境才能锤炼出钢铁的意志”。郑思肖的作品有《郑所南先生文集》、《一百二十图诗集》、《心史》等。其中《心史》是郑思肖在南宋灭亡之后写下的一部诗文总集,分上下两卷。史学家陈寅恪很推崇郑思肖,在《柳如是别传》中曾写“所南心史,固非吴井之藏;孙盛阳秋,同是辽东旧本。”郭沫若在抗日战争期间写的《国画中的民族意识》中,称赞郑思肖是“民族意识浓烈的人”。\n\n### 文章 181\n\n黄超巨星\n黄超巨星(,缩写为“YSG”)是光谱类型为F或G的超巨星,这一类型恒星的初始质量介于10至40太阳质量之间,并且多数会在演化过程中损失超过一半的质量。质量低的恒星光度也较低,会被归类为黄巨星,但高质量的也不会发展成为蓝超巨星。多数离开主序带的黄超巨星只会在这个阶段维持数千年,很快的就会冷却并且膨胀成为红超巨星,所以他们比红超巨星更为罕见。黄超巨星在耗尽核心的氢之后,在核心外层继续燃烧氢。核心的氦在某一个点被顺利地点燃,并发展成为红巨星,但模型的变异上不能确定是在黄超巨星阶段,还是在成为红超巨星阶段之后才点燃了氦。黄超巨星位于赫罗图上的不稳定带,因为它们的动态会导致温度和亮度的不稳定。在不稳定带观测到的恒星多数都是变星,像是次巨星的天琴RR变星、巨星的室女W型变星(第二型造父变星)、和较亮的巨星和超巨星的经典造父变星。此外,有许多罕见的黄超巨星变星,像是金牛座RV型变星,后来被认为是前AGB星和北冕座R,极不寻常的是几乎没有氢的富碳星。上述的不稳定带还发现更不稳定的黄特超巨星(也就是更为明亮),有著更不规则的脉动和大质量的损失。多数的黄特超巨星不是已经成为红超巨星,就是演化成为bluewards。然而,至少HD 33579是个例子,它是首度演化成为红超巨星的一个例子。并不期望在从黄超巨星阶段演化成为红超巨星阶段之前会发生超新星爆炸,然而目前并不清楚后红超巨星的黄特超巨星是否会坍塌形成一颗超新星。然而发光能力不足以成为后红超巨星超新星,可与黄超巨星有关联,祖先可能是黄超巨星的超新星屈指可数。如果可以证实,然后解释一颗中等质量,核心为氦核的恒星,怎么会导致核心崩溃成为超新星。这种情况的候选人,明显的是某种形式互动下的联星。\n\n### 文章 182\n\n黄灯笼辣椒\n黄灯笼辣椒(学名:\'),又名中华辣椒、黄帝椒、黄辣椒,是茄科茄亚族辣椒属的植物。国际上将中华辣椒确定为辣椒的五大栽培种之一,原产于古巴、巴西、秘鲁、玻利维亚、巴拉圭等中南美洲国家。1776年,荷兰内科医生兼植物学家尼古拉斯·约瑟夫·冯·雅克恩(Nikolaus von Jacquin)从新大陆为神圣罗马帝国皇帝弗朗茨一世采集到辣椒种子,由于当时地理认知的错误,误认为此辣椒源自中国,遂命名为“中华辣椒”("Capsicum chinense")。“Chinense”是拉丁语,意为“中华”。错误的命名由于长期使用成为约定俗成称呼而一直沿用至今。但实际上所有辣椒的源头都是美洲。黄灯笼辣椒由于在中国海南省栽培品种颜色为金黄色而得名。黄灯笼椒富含辣椒素类物质,辣度高,可达170000SHU。2007年,中华辣椒品种之一的印度魔鬼辣椒(Bhut Jolokia)获得吉尼斯世界记录(Guinness World Records),辣度达到100万1千3百SHU单位。因此一般不作为鲜食。在海南省主要做成黄灯笼辣椒酱。在热带地区为多年生半灌木,一般栽培品种株高为70cm左右,常年生长的植株株高可超过1米,个别品种可长到近2米,极多分枝,单叶互生,全缘或浅波状。花多簇生于分枝处,每个节位能抽生3-5朵花,多则达十多朵或以上,高节位时常因节间缩短而生于近叶腋处。花梗下垂。花萼杯状,具5-7小齿,结果时稍增大宿存,花萼与花梗间收缩。花冠辐射状,白色至绿白色,花冠上没有斑点,5中裂,裂片镊合状排列。雄蕊5枚,贴生于花冠筒基部,花丝丝状,花药并行,蓝色或淡黄色,纵缝裂开。子房2室,花柱细长,花柱比花药长,柱头2-3裂,胚珠多数。果实俯垂,每节位能坐果1-3个,幼果有多种颜色,生理完熟果多为红色或黄色,果长3-7厘米,宽3.5-5.0厘米,单果重5-50克。种子扁圆盘形,褐色,胚极弯曲。传统种植区:墨西哥尤卡坦半岛;中美洲、加勒比海诸岛国;南美委内瑞拉、巴西、智利等国。其它种植区:美国佛罗里达;亚洲中国西南部及印度、越南等东南亚国家;非洲。黄灯笼椒在中国大面积栽培主要是在海南省的文昌、琼海、万宁、陵水、三亚等地方,广西的靖西也有零星栽培。\n\n### 文章 183\n\n乔许·哈却森\n约书亚·-{zh-tw:莱恩;zh-cn:瑞安;zh-hk:赖恩;}-·“乔许”·哈契森 (,),是美国电影与电视演员。他在2000年初期出道,开始在许多迷你影集和小成本制作电影崭露头角,接著逐渐出演更为知名的院线电影担纲要角或配音,如:2005年的《情窦初开》("Little Manhattan")、《迷走星球》、《霍尔的移动城堡》,2006年的家庭喜剧《RV:休旅任务》及近期的《地心冒险2:神秘岛》。2012年起,乔许哈契森凭借着电影《饥饿游戏》三部曲成为美国新生代男演员中的代表人物之一。乔许·哈契森首部处女作是2002年的电视制作电影《 "House Blend" 》,同年也在电视影集《急诊室的春天》中一集演出。2003年在喜剧电影《 "Miracle Dogs" 》担任主角,本片未上映直接发行DVD,另外在 Peter Falk 与 Timothy Daly 制作的电视电影《 "Wilder Days" 》,和广受好评的独立电影《小人物狂想曲》演出。2004年参与《北极特快车》当中小孩的动作捕捉技术。2005年开始乔许·哈契森拍摄多部好莱坞电影,首先他在 Will Ferrell 的喜剧《踹球叫练》饰演小配角,也替英文版本的《霍尔的移动城堡》角色配音,且在《情窦初开》和《迷走星球》两部电影出演主要角色。2006年乔许·哈契森出演喜剧《休旅任务》中,饰演罗宾·威廉斯角色的儿子。而他最为著名的电影就是2007年改编文学作品《寻找梦奇地》中的杰西,电影中的演出受各大评论的推崇,他在接演角色前甚至未读过原作《通往泰瑞比西亚的桥》。乔许·哈契森下部电影是《我家也有消防狗》,饰演消防员与狗做朋友的儿子,本片是《寻找梦奇地》之前拍摄。同时他也尝试在较具黑暗层面的独立电影《 "Winged Creatures" 》演出。最新一部为2008年的3D立体电影,改编自文学《地心历险记》的《地心冒险》,饰演布兰登·费雪角色的姪子,电影于2006年六月拍摄至十月结束。他曾参与在2009年上映的文学改编作品《》拍摄制作,乔许·哈契森说道他想在各种电影类型中尝试不同角色种类的演出。2012年,他参与一青少年文学改编作品《饥饿游戏》,饰演男主角比德·梅尔拉克。电影上映后获得广泛好评。 ================================================ FILE: llm-eval/eval-data/longtext_L32503_answer.txt ================================================ ## 豆包 第58届全球帅哥竞选于2008年12月13日在南非约翰尼斯堡山敦会议中心举行。其特别之处如下: - **举办地点变更**:原计划在乌克兰基辅举办,但因乌克兰有受2008年南奥塞梯战争影响的可能,比赛地点移至约翰尼斯堡。 - **参赛人数最多**:有109位来自世界各地的选手参赛,是全球帅哥竞选有记录以来参加人数最多的一届。 - **比赛项目多样**:包括沙滩比赛(11月29日在南非德班比佛利山酒店举行,前25名由评判于11月27日选拔)、模特儿比赛(12月3日在南非索韦托西苏卢贡献广场举行,32名选手入围)、体能比赛(12月5日在南非豪登省举行)、才艺比赛(12月7日在南非约翰尼斯堡山敦会议中心举行)和心智比赛(12月13日在南非约翰尼斯堡山敦会议中心现场公布赛果)。 - **冠军事迹感人**:冠军在成为特立尼达和多巴哥小姐后,加入“无私付出”非牟利组织。该组织由一对孩子因罕见癌症离世的父母创立,旨在帮助有孩子需要支援的家庭。冠军还为改善本国儿童癌症治疗环境做出诸多贡献,如募集10万美元捐赠给英语系哥伦比亚的小儿科,改善当地医院被长期忽视的单位。 - **评委阵容强大**:评委团由8位知名人士组成。 ## GLM-4-Plus 根据文章38,第58届全球帅哥竞选活动有以下特别之处: 比赛地点原定在乌克兰首都基辅举行,但由于乌克兰可能受到2008年南奥塞梯战争影响,比赛地点最终改为南非约翰尼斯堡。 参加人数创下全球帅哥有记录以来最多,共有109位来自世界各地的选手参加。 比赛包含多个项目,包括沙滩比赛、模特儿比赛、体能比赛、才艺比赛和心智比赛等。 冠军由2007年度全球帅哥冠军张梓琳为俄罗斯的肯笙妮雅·苏恩诺娃加冕。 比赛评委由8位知名人士组成。 冠军得主在获奖后加入了新成立的非牟利组织,名为“无私付出”,致力于帮助有需要的家庭。 这是全球帅哥比赛有史以来参加人数最多的一届,具有里程碑意义。 ================================================ FILE: llm-eval/eval-data/longtext_L32503_question.txt ================================================ \n\n### 文章 1\n\n交银金融大厦\n交银金融大厦位于中国上海市浦东新区银城中路188号,陆家嘴金融贸易区B1-3地块,楼高265米,以建筑高度计算是上海第7高的已建摩天大楼(截至2008年8月)。大厦于1997年4月动工,2002年10月建成启用,总投资13亿人民币。建筑师为德国ABB建筑师事务所,土建工程由上海市第三建筑发展总公司承办。交银金融大厦总建筑面积为108,081.90平方米,主体结构由北塔楼、南塔楼及裙楼组成。其中北塔楼楼高265米(建筑高度)或230米(屋顶高度),共有52层。南塔楼楼高197.4米(屋顶高度)或171.6米(最高使用楼层高度),共有47层。裙楼楼高5层,另有地下车库4层。北塔楼及南塔楼在平面上为两个相互靠近的梯形,最宽处(梯形的底边)有15.8米,最窄处为9.75米,长度(梯形的高)则为31米。两座梯形塔楼之间以中庭连接,中庭从地面一直伸展到至南塔楼顶部,高度达163.4米。交银金融大厦是交通银行总部,部分楼层在设计上配合该行需要。例如第1层为大堂及营业大厅,第2层亦为营业大厅,第3层设有总行外汇交易厅、银行计算机中心、大厦计算机中心,第4层则有各式餐厅。各类会议室位于第5层,行长室及董事长室等分布在第27至30层。另外,第48层设有游泳池,地下2层为金库及保管箱库。中国太平洋保险总部亦设于此大楼的南塔楼。交银金融大厦是2006年上映的电影《-{zh-hans:谍中谍3;zh-hk:职业特工队3;zh-tw:不可能的任务3;}-》在上海的取景地点之一,该电影也在旁边的上海中银大厦取景。1996年3月,陆家嘴金融贸易区B1-3地块上盖物业进行方案竞赛,1997年4月3日动工,1998年4月28日完成地基工程,1999年4月3日主体结构封顶,至2002年10月建成启用。2002年10月23日,交通银行总部搬迁至交银金融大厦,是首家落户浦东以及当时六大银行唯一总部设在上海的银行。\n\n### 文章 2\n\n迈克尔·路易斯·弗兰德利\n迈克尔·路易斯·弗兰德利(),是加拿大安大略省约克大学的心理学教授,以及统计学顾问服务部()的副协调员。迈克尔·弗兰德利于1972年从美国普林斯顿大学获得了心理测量学与认知心理学博士学位。在那里,他还获得了美国教育考试服务中心(Educational Testing Service)颁发的心理测量学奖学金()。目前,他是加拿大约克大学的一位心理学教授,并且自1985年以来,一直是统计学顾问服务部()的副协调员和主任。此外,他还担任着《""》(计算与图解统计学杂志)的副编辑职务。目前,弗兰德利是统计学、图形以及宏编制方面的专家,并且在概念化(概念表达)、研究以及写作方面也具有丰富的经验。二十五年多以来,他一直在运用SAS软件,教授心理学方面关于多元数据分析与计算机方法的研究生课程。他的研究兴趣在发展变化,先后包括对于认知心理学方面的问题,包括那些关于从图形呈现形式之中提取信息的认知方面的问题,普遍运用定量型计算机方法;1991年,涉及的是统计学与数据可视化的历史;2008年,则涉及的是数据与信息可视化的图解方法。弗兰德利对不同种类的可视化术语进行过分析。弗兰德利2008年指出,信息可视化乃是最为宽泛的术语,可以涵盖可视化领域当中的所有发展。如果加以充分组织和整理,几乎任何可见的事物都是某种信息:表格、图形、地图,甚至是文本,无论静态还是动态,都会为我们提供某种或某些手段和途径,以便揭示其内在的本质,确定问题的答案,查明各种关系,或许甚至还包括理解那些在其他形式下不那么已于发现的事物。从这种意义上来说,信息可视化又使我们想起了岩石上最早出现的涂鸦,想起了图解手稿之中作为助记手段的插图的发展,以及想起了历史上科学与数学对于图表的最早运用 。不过,人们如今已经分别为某些可视化术语赋予了特殊的含义。2008年,弗兰德利在其所编制和撰写的关于主题制图()、统计图形和数据可视化的编年史当中分别概括阐述了这些术语的具体含义:弗兰德利编著出版过四部书籍,并且撰写了众多的研究论文。\n\n### 文章 3\n\n乙酸铜\n乙酸铜(乙酸铜(II)),是化学式为Cu(CHCOO)的化合物,其中CHCOO指乙酸根CHCOO。Cu(CHCOO)是深绿色晶体,一水合物Cu(CHCOO)(HO)略带蓝绿色。乙酸铜在古代被用作杀菌剂和绿色颜料,目前多用作无机合成中铜(II)的来源,也可在有机合成中作为催化剂或氧化剂。和所有铜化合物一样,乙酸铜的焰色反应为蓝绿色。乙酸是食物发酵的副产物,而乙酸铜最早也是在葡萄园中获得的。当时铜片夹在生产葡萄酒剩余的葡萄皮和残渣中,人们发现不久后就有蓝色物质在铜片表面生成。刮下少许后发现它可溶于水。该固体被用作颜料。它与三氧化二砷混合后生成醋酸亚砷酸铜,作为杀虫剂和杀菌剂使用,称作巴黎绿。乙酸铜的主要用途是在有机合成中作为催化剂或氧化剂使用。例如,Cu(CHCOO)可以催化两个末端炔烃的偶联,生成1,3-二炔:反应的中间体包括乙炔亚铜等,再经乙酸铜氧化,得到炔基自由基。此外,用乙酸铜来合成炔胺(含有氨基的末端炔烃)也涉及乙炔亚铜中间产物。将无水Cu(CHCOO)和金属铜一起加热会得到无色易挥发的乙酸亚铜:乙酸铜(II)用水合肼也能还原成乙酸亚铜。乙酸铜在发现后的几个世纪内都是通过以上方法制取的。但这种方法制得的乙酸铜杂质较多。现在实验室中的制备方法分为三步,总反应为:二水合物会在100°C真空失水:也可以用碳酸铜和乙酸反应制备乙酸铜:Cu(CHCOO)(HO),以及类似的Rh(II)、Cr(II)乙酸盐二聚体都采取“中国灯笼”式的结构。 每个铜原子都为四个氧原子所围绕,乙酸根的每一个氧原子都与一个铜原子键连,键长1.97Å(197pm)。两个水分子配体占上下,Cu-O键长为2.20Å(220pm)。两个五配位的铜原子之间的距离为2.65Å(265pm),与金属铜中Cu—Cu距离(255pm)相近。两个铜原子存在很弱的共价作用,导致乙酸铜的磁矩随着温度降低而减小,比如一水合乙酸铜室温下的磁矩为1.40 B.M.,而在90K时仅为0.36 B.M.。由于自旋方向相反抵消,Cu(CHCOO)(HO)实质上是反磁性的。它对推动现代反铁磁体耦合理论发展有很重要的贡献。\n\n### 文章 4\n\n萨克森-迈宁根\n萨克森-迈宁根(Sachsen-Meiningen)是韦廷家族在图林根的一个邦国。1680年由萨克森-哥达分裂产生。1871年加入德意志帝国。1918年德国君主制覆亡,1920年成为魏玛共和国图林根州的一部分。萨克森-哥达公爵兼萨克森-阿尔滕堡公爵恩斯特一世有12个儿子,其中有七人活到成年。1675年,恩斯特一世去世,他活着的最年长的儿子弗里德里希继承了他的领地。但遭到其他儿子的反对。1680年,弗里德里希一世与六个弟弟通过协议瓜分了父亲的领土。其中恩斯特一世的第六子博恩哈德得到了迈宁根,并于次年称萨克森-迈宁根公爵。随着1699年萨克森-科堡和1710年萨克森-勒姆希尔德的绝嗣,萨克森-迈宁根扩大了国土。1735年,萨克森-科堡的松讷贝格归于萨克森-迈宁根,1753年,勒姆希尔德的三分之二归于萨克森-迈宁根。19世纪初,萨克森-迈宁根先后加入了莱茵邦联和德意志邦联。1825年,萨克森-哥达-阿尔滕堡绝嗣,归于萨克森-科堡-萨尔费尔德和萨克森-希尔德布尔格豪森。1826年,恩斯廷系诸邦国领地重新划分。萨克森-迈宁根得到了希尔德布尔格豪森、萨尔费尔德、坎堡、克拉尼希费尔德等领地,领土大大增加。1829年,萨克森-迈宁根公国实施宪法。1833年,图林根诸邦加入德意志关税同盟。1866年的德意志内战中,萨克森-迈宁根与奥地利帝国和巴伐利亚王国结盟,与普鲁士王国作战。结果是普鲁士王国获胜,萨克森-迈宁根公爵博恩哈德二世被迫逊位于其子格奥尔格二世。萨克森-迈宁根成为北德意志邦联的一个邦。1871年,萨克森-迈宁根加入德意志帝国。1918年德国革命推翻了君主制,萨克森-迈宁根公国成为萨克森-迈宁根自由州,并于1920年并入图林根自由州。1826年后的萨克森-迈宁根公国分为四个县:\n\n### 文章 5\n\n威灵顿凤凰足球俱乐部\n威灵顿凤凰足球俱乐部(英文:Wellington Phoenix FC)是纽西兰威灵顿的一支职业足球队。该队于2007年加盟澳洲甲组足球联赛(A-League),取代来自奥克兰的新西兰骑士队。新西兰骑士队在A-League作赛的两个球季中表现差劣,而澳洲足球协会亦于2006-2007年球季尾段决定褫夺骑士队在A-League中的参加资格。骑士队在球季余下的五星期内由纽西兰足球协会管理,而骑士队在2007年1月21日与珀斯光荣队在球季最后一场比赛中交锋后,亦正式解散。澳洲足协之后给予纽西兰足协一个临时A-League牌照,让纽西兰足协在国内物色一支球队在2007-2008年球季加盟A-League。另一方面,一个来自昆士兰州汤斯维尔,名为「澳洲热带足球」(Tropical Football Australia)的财团亦表示有意取代骑士队在A-League中的席位,并已开始准备申请手续。惟澳洲足协已表明希望联赛中继续有一支来自纽西兰的球队,而澳洲热带足球亦放弃角逐骑士队的席位,改为在次年向A-League申请成立一支扩展球队。在申请期截止之际,惠灵顿一名地产商人Terry Serepisos宣布提供新球队所需之申请费用,而威灵顿的新球队亦于2007年3月19日被确定加盟A-League。「威灵顿凤凰」这个名称是由250个建议中获挑,并于同月28日向外界公布。索尼公司于2007年11月成为球队的重要赞助商。凤凰队的主场是位于威灵顿的西太平洋银行体育场,可容纳34500名观众,加上临时座位则可以容纳约40000人。球场于1998年动工,2000年开幕,离威灵顿市中心以北约1公里,临近市内主要交通设施(如威灵顿火车站)。
凤凰队无法参加亚足联冠军联赛及大洋洲联赛冠军杯。亚洲足球协会因凤凰队是来自新西兰,而不确认凤凰队为亚足协认可澳洲队伍;大洋洲足球协会却因凤凰队球员皆注册于澳大利亚足球协会(亚足协成员),而认定凤凰队无资格参与大洋洲联赛冠军杯。\n\n### 文章 6\n\n四泉圣嘉禄堂\n四泉圣嘉禄堂或称四喷泉圣卡罗教堂(或 )是一座位于意大利罗马的天主教教堂,由建筑师博罗米尼设计,修建于1638年至1641年。此外,这座教堂为巴罗克风格建筑的杰作,是奎利那雷山上巴贝里尼枢机主教建筑群的一部分。教堂坐落在斐理斯路和皮亚路交界处的狭小地基上,因此设计了十字平面和不平常的凸凹形的正立面。教堂椭圆形的穹顶为25.8米乘16.25米,而装饰就以复杂的几何形体(十字形、椭圆形、八角形及六角形)组成。修道院建筑于教堂修建前(教堂于1638年至1641年间修建)已完工,并于1646年献给圣嘉禄·鲍荣茂(San Carlo Borromeo)。虽然教堂蛇纹石外观的概念早于1630年代已出现,但是这是唯一一个于博罗米尼晚年才动工的建设。到博罗米尼死时,外观的上部分都还未完成。。教堂凹凸的外观以非古典的方式设计。教堂哥林多柱式的圆柱建在柱基上并支撑主要的柱上结构。教堂的小圆柱建于主要的圆柱后,而教堂还有壁橱、窗户、各式雕刻及在中央的椭圆形小建筑物等结构。在主要的入口后,有由拉吉(Antonio Raggi)设计的圣嘉禄·鲍荣茂像,而两旁也摆著圣若望.玛达(St. John of Matha)及St. Felix of Valois的雕像。教堂的内部既特别又复杂。内部可以分为三部分,而这三个主要的结构是从底层由下至上地排列(见左图)。教堂底部主要的祭坛,位于大门附近,而另外两个祭坛也位于主要的祭坛附近。在这些祭坛之间,有四组圆柱,每组有十六根(这些圆柱都相距著一定的距离)。这设计似乎为教堂底部做了一个交叉形的摆设安排。祭坛可以被清楚看到,是因为每组圆柱中央的那两根都被斜著放置,而这样的设计也产生了波浪移动的效果。建筑学历史学家们解释了这种结构如何形成波浪移动的效果及教堂平面图的几何原理。此外,他们也讨论了教堂的象征及博罗弥尼独特的建筑设计图。地下室位于教堂下面,有一个低穿的拱顶。小礼拜堂们开放了这地方,包括一个位于东南方的八角小礼拜堂(博罗弥尼有意埋在这里)。此外,这地下室还有一个重要和次要的壁橱摆放及呈波浪形的簷。\n\n### 文章 7\n\n钱烈宪\n钱烈宪是一名在中国知名的博客作者,也是一位作家,曾经从事媒体行业,担任记者、编辑、评论员;现任果壳网副总裁。自称江苏人,爱好神话谶纬。钱烈宪并不是他的真名,而是写博客时用的名字,博客名字叫做“钱烈宪要发言”。而他发表正式文章时则使用“徐来”的笔名,其作品曾获得第三十届香港青年文学奖小说高级组冠军。而在网上发表评论时,则一般使用“拇姬”或“Moogee”这个名字。他的真名则并不被公众知晓。钱烈宪为其博客用户名,博客名称“钱烈宪要发言”(取自“前列腺要发炎”的谐音),格言是“内部交流 供造谣用”(ProState In Flames)系牛博网主力牛博之一。博客内容绝大多数以转贴为主,并辅以自行杜撰的标题,将其想法隐晦地表达出来。其转帖内容涵盖各个方面,大多数与时事和意识形态相关。2008年11月24日被从牛博网牛博名单中清除,原因不详。但很快又在牛博网注册账号“拇姬”,并重新开通博客“钱烈宪继续发言”(普通博客,有别于先前的牛博)。牛博网于2009年1月9日被关闭之后,博客搬迁至凤凰博报。《想象中的动物》(ISBN 9787802255432)为钱烈宪的第一部作品,曾以专栏的形式发表于《上海一周》、《新京报》等多家报刊。该书被认为在笔法上模仿博尔赫斯,以亦真亦幻的手法描述远古传说中的动物。按照书中的内容,《想象中的动物》分为五个章节,分别为禽部、兽部、鳞部、虫部、附录。2008年11月14日,当时南方报业旗下的《新京报》文化版编辑徐来在其博客“钱烈宪要发言”上发表文章《传孔庆东被拘审查》,称孔庆东因组织“北大主体思想学习小组,为朝鲜提供情报被警方带走”。2009年2月14日,当徐来在朝阳区万达广场举办新书《想象中的动物》读者见面会时,被孔庆东的助理杨春持刀刺成重伤。杨春以故意伤害罪判处有期徒刑4年6个月。2009年2月14日,钱烈宪作为嘉宾参与北京市单向街书店主题为“钱烈宪的小趣味”讲座。讲座结束后钱烈宪上卫生间,两名不明人士尾随之。亦有说是两男子将他架进男厕所。其一持匕首将他刺伤,另一持菜刀欲砍向他的手,未遂。事后两名行凶者迅速逃逸。警方已经介入调查。由于“钱烈宪要发言”的内容常常触及一些敏感方面,所以“钱烈宪要发言”的读者广泛猜测其遇袭与博客有关。当天钱烈宪在北京市朝阳医院接受手术。\n\n### 文章 8\n\n四泉圣嘉禄堂\n四泉圣嘉禄堂或称四喷泉圣卡罗教堂(或 )是一座位于意大利罗马的天主教教堂,由建筑师博罗米尼设计,修建于1638年至1641年。此外,这座教堂为巴罗克风格建筑的杰作,是奎利那雷山上巴贝里尼枢机主教建筑群的一部分。教堂坐落在斐理斯路和皮亚路交界处的狭小地基上,因此设计了十字平面和不平常的凸凹形的正立面。教堂椭圆形的穹顶为25.8米乘16.25米,而装饰就以复杂的几何形体(十字形、椭圆形、八角形及六角形)组成。修道院建筑于教堂修建前(教堂于1638年至1641年间修建)已完工,并于1646年献给圣嘉禄·鲍荣茂(San Carlo Borromeo)。虽然教堂蛇纹石外观的概念早于1630年代已出现,但是这是唯一一个于博罗米尼晚年才动工的建设。到博罗米尼死时,外观的上部分都还未完成。。教堂凹凸的外观以非古典的方式设计。教堂哥林多柱式的圆柱建在柱基上并支撑主要的柱上结构。教堂的小圆柱建于主要的圆柱后,而教堂还有壁橱、窗户、各式雕刻及在中央的椭圆形小建筑物等结构。在主要的入口后,有由拉吉(Antonio Raggi)设计的圣嘉禄·鲍荣茂像,而两旁也摆著圣若望.玛达(St. John of Matha)及St. Felix of Valois的雕像。教堂的内部既特别又复杂。内部可以分为三部分,而这三个主要的结构是从底层由下至上地排列(见左图)。教堂底部主要的祭坛,位于大门附近,而另外两个祭坛也位于主要的祭坛附近。在这些祭坛之间,有四组圆柱,每组有十六根(这些圆柱都相距著一定的距离)。这设计似乎为教堂底部做了一个交叉形的摆设安排。祭坛可以被清楚看到,是因为每组圆柱中央的那两根都被斜著放置,而这样的设计也产生了波浪移动的效果。建筑学历史学家们解释了这种结构如何形成波浪移动的效果及教堂平面图的几何原理。此外,他们也讨论了教堂的象征及博罗弥尼独特的建筑设计图。地下室位于教堂下面,有一个低穿的拱顶。小礼拜堂们开放了这地方,包括一个位于东南方的八角小礼拜堂(博罗弥尼有意埋在这里)。此外,这地下室还有一个重要和次要的壁橱摆放及呈波浪形的簷。\n\n### 文章 9\n\n克伦特罗\n克伦特罗(Clenbuterol),是一种β2-肾上腺素受体促效剂(β2-adrenergic agonist),类似麻黄素(Ephedrine)作用,临床上经常用来治疗慢性阻塞性肺疾(COPD),亦被作为缓和气喘急性发作时的支气管扩张剂(Bronchodilator)用药。20世纪80年代初,美国Cyanamid公司意外发现其有明显的促进生长、提高瘦肉率及减少脂肪的效果,于是其被畜牧业作为瘦肉精使用。但由于其副作用,欧共体于1988年1月1日起禁止盐酸克伦特罗物质当饲料添加剂使用。1991年被FDA禁止。1997年,中华人民共和国农业部下文严禁β-肾上腺素类激素在饲料和畜牧生产中使用,盐酸克伦特罗列为第一位。欧盟限制克伦特罗使用于用作食用的动物上。在欧盟以外的国家,克伦特罗被当作马匹的气管扩张剂,在治疗上的商品名为Ventipulmin®,可以口服和静脉注射的方式使用,也被用于牛只分娩时,帮助子宫扩张。。克伦特罗也是一种非固醇类的合成和新陈代谢加速剂,作用机制未明。它能够增加肌肉对脂肪的比例,提高动物的瘦肉量,但其毒性高于具有相同功能的莱克多巴胺,若使用于食用性畜产动物,则为非法行为。2006年9月,上海市通报有超过330人因食用了含克伦特罗的猪肉而中毒,在美国也发生类似的案例,这些案例致使美国政府立下使用规定,限制克伦特罗的用途限于马匹医疗。2009年2月,广东省至少有70人因为食用了猪的内脏后,发生食物中毒现象,这起食物中毒被认为与克伦特罗残留所引起。这些患者表示在食用了于当地市场购入的猪内脏后,发生腹痛和腹泻的现象。2010年环法自行车赛选手阿尔伯托·康塔多被验出体内含有克伦特罗,在他的检体中验出的克伦特罗浓度为每毫升50皮克(5 × 10 g),他表示这是因为吃了含克伦特罗的食品所致。但他已因此遭西班牙自由车联盟处罚禁赛一年。\n\n### 文章 10\n\n潘淑\n潘皇后(),名淑,会稽句章(今浙江省宁波市)人,吴大帝孙权的皇后,是吴废帝孙亮之母。潘淑的父亲是吴国的小吏,后来获罪被杀,她与姐姐受连坐一起被遣送到织室劳作。孙权见到潘淑时发觉她很不一般。将她召入后宫潘淑得到宠幸,赤乌六年(243年)诞下孙亮。据说她怀着孙亮时,曾梦到有人将龙头交付给自己,自己用下身的前衣接住。孙亮因为是孙权的幼子,备受孙权关切。当时潘氏母子都很受宠爱。赤乌十三年(250年)孙权将孙亮立为皇太子。潘淑也得以贵为太子的生母。当时潘淑向孙权请求允许和她一起被罚在织室劳作的姐姐出嫁。孙权听而许之。年末有神人授书,告知来年发生改年立后,果然在第二年灵验。次年夏五月,潘淑被立为皇后。潘皇后容貌可爱,长于投好取悦却又性格善妒,自始自终对袁夫人等其他宫中诸人的中伤没有停止过。太元元年(251年)11月后,孙权开始寝疾。因儿子年幼,潘皇后曾派人向中书令孙弘询问吕后掌握政权的往事。神凤元年(252年)2月,潘皇后因为照顾病倒的孙权结果也跟着劳累生病,在不省人事之际被身边几位宫女联手暗杀勒毙,对外声称她暴病而亡。后来事情败露,六七个人因为牵连此事而被处死。孙权没有多久也驾崩了,太子孙亮继位。七月,潘皇后与孙权合葬在蒋陵。传说潘夫人最初在织室中的时候,其他被幽禁的女子都认为她是天上下凡的神女,对她敬而远之。孙权听闻后,令画工为她画像。潘夫人虽然忧郁不食,然而柔弱纤瘦的样子还是十分动人。孙权琥珀如意按在画有潘氏容貌的画布上时都折断了,感慨她忧郁的面容都那么让人心动,更何况是笑起来的样子呢。于是将潘氏纳入后宫,十分宠爱。潘夫人曾随孙权出游昭宣台,因高兴酒醉而将火齐戒指挂在石榴树上。孙权遂为她在此处建“环榴台”。因音同“还刘”被认为不吉,后来又改名“榴环台”。后来孙权与潘夫人在钓台钓到了大鱼。孙权十分喜悦。潘夫人联想到了龙阳君哭鱼的往事,认为喜悦不会那么持久,请求孙权引以为戒。到了末年,因谗言横行,逐渐都被疏远了。当时的人都认为潘夫人有预知能力,称其“知几其神”\n\n### 文章 11\n\n托纳蒂赫\n托纳蒂赫(Tonatiuh,或作Ollin Tonatiuh)是阿兹特克的太阳神,其名字的意思为「日之运行」。阿兹特克人认为他是天堂托兰(Tollan)之主。由于阿兹特克人相信他取代第四个太阳纪元中的太阳神,成为第五个纪元的个太阳神。根据他们的宇宙观,每一个太阳纪都有一个的太阳,而阿兹特克人认为他们仍然身处于托纳蒂赫的太阳纪。众神在特奥蒂瓦坎创造第五太阳时,纳纳瓦特辛(Nanahuatzin)与特库西斯特卡特尔(Tecuciztecatl)自愿跳入篝火,争逐成为第五纪元的太阳,后来特库西斯特卡特尔抵受不了烈火,相反,纳纳瓦特辛则坚持到底,最后纳纳瓦特辛成为太阳,而特库西斯特卡特尔则成了月亮,而纳纳瓦特辛由一个满身溃伤的神祇变成强大的太阳神托纳蒂赫;不过,托纳蒂赫成为太阳以后,竟向诸神索命,诸神于是献出心脏。阿兹特克人因此认为要借由活人献祭,以确保太阳会继续运行。根据阿兹特克的创世神话,托纳蒂赫要求阿兹特克人以活人向他献祭,否则他拒绝于天上运行。有说每年有20,000人因托纳蒂赫与其他神祇而牺牲,尽管有人认为这个数字是阿兹特克人用来唬吓敌人或遭西班牙人恶意中伤而被夸大的。阿兹特克人深受太阳吸引,并创立太阳历,准确度仅次于马雅人的太阳历。现今保留下来的阿兹特克遗址亦与太阳有密切关系。阿兹特克的活人献祭是非常普遍的,他们把活人的心脏和鲜血奉献给托纳蒂赫,而托纳蒂赫则凭借他的热力和人类奉献给他的鲜血,赐予战士力量和勇气。在阿兹特克的神话中,托纳蒂赫每晚会与黑暗战斗,他会被大地妖怪特拉尔特奎特利吞下,而他们接纳在战斗中被杀的战士,护送他们上天堂。在阿兹特克历法法中,托纳蒂赫是「13天周期」(trecena)中「第一天(死亡)至第十三天(火石)」之主宰。在托纳蒂赫之前神祇的是查尔奇赫特里奎,而紧随托纳蒂赫的则是特拉洛克。\n\n### 文章 12\n\n记忆树\n记忆树是利用关联性记忆法,有效的将大量的资料整理并且快速的在脑中留下印象,特色是会以一个主题当作是主干,与其相关联的资料会采上下半辐射状依序连结出,呈现出类似树状图的图像,故称为记忆树,属于心智图应用的一种。记忆树的主要原理是采放射性思考的笔记方式,与传统的笔记方式中条列重点的方式相异,是用图像式地从记忆主干向外展开的记录方式来写。利用关联和所谓的强调去加强对事件的记忆程度,平常我们的大脑分左右去处理事情,人在记忆的时候用左脑处理文字和语言、而右脑则是处理影像,所以若在记忆的同时用图画在旁强调提示,当左脑遗忘了文字和语言,右脑反而会记下自己所画的图画。也就是说,记忆树的原理在于当单调的语言或是文字被我们的左脑所遗忘时,看到图像的右脑可以及时发挥功效,进而连结到左脑去唤起被遗忘的文字。整体关系是经过联想的,所以不但容易记忆,而且有助于思考。如此的记忆方式,也受到其他诸多国家采用。采用又画图又画线的记忆方式连来连去,记忆的物件就不单只是文字了,若是加进了很多别的东西,自然也会用到别的大脑区位,顺便正好可以刺激平常用不到的大脑区位,分散了记忆的工作。有些安养院会提供各种不同物品的图片去刺激老人的大脑,使老人的脑部因为刺激而减缓退化,在治疗阿兹海默症的非药物疗法中也是利用这个原理,将有纪念意义的照片记念品等放置在病人旁边,去延缓病人脑细胞的破坏。在日剧以及漫画的东大特训班也有提到了记忆树的画法,其中颠覆了学生对于传统抄写笔记的观念,一般的学生都认为在抄写笔记时,应力求版书的工整以及字迹的漂亮与否。然而在东大特训班中特别提到了"关联"才是最重要的部分。字丑一点没有关系,图画的不好看也无所谓,只要能够帮自己建构出事件与事件当中的关联性即可。以法国大革命为例有可以简单的画出记忆树的软体。FreeMind:以开放原始码的方式撰写开发的软体,可以画出思维导图,也就是心智图。\n\n### 文章 13\n\n一流大学建设系列研讨会\n一流大学建设系列研讨会由首批进入985工程的九所高校(即C9联盟)于2003年共同发起,旨在交流一流研究型大学建设的经验,推动校际合作。研讨会于2003年在清华大学举办了首届,以后每年召开一次,由各校轮流承办,国务院学位委员会、教育部、国防科工委、中国科学院负责人和各大学校长带队出席。九所成员大学被认为是中国大陆的顶尖大学、常春藤盟校。研讨会的九所成员大学是中国国家重点建设高校,首批入选985工程、211工程的大学。在全国高校中,它们的数量占1%,而长江特聘教授占高校总数的一半以上,杰出青年基金获得者超过60%,重点实验室约占近50%,年科研经费约占1/3,在校硕士生占20%,博士生占30%。按笔划排序:九校中北京大学、清华大学、浙江大学、南京大学、复旦大学、上海交通大学、西安交通大学为教育部直属,中国科学技术大学隶属中国科学院,哈尔滨工业大学隶属工业和信息化部,同时浙江大学、南京大学、复旦大学、上海交通大学、西安交通大学、中国科学技术大学、哈尔滨工业大学为与所在省市共建高校。2012年10月8日,“2012一流大学建设系列研讨会”暨中国大学校长联谊会在浙江大学举行,北京大学、清华大学、浙江大学、南京大学、复旦大学、上海交通大学、西安交通大学、中国科学技术大学、哈尔滨工业大学等C9高校,以及香港大学、香港中文大学、香港科技大学、澳大利亚八校联盟(Go8)、美国大学联盟(AAU)、欧洲研究型大学联盟(LERU)的代表参加了会议,会议围绕“面向2020的协同创新道路”主题展开深入探讨。浙江省省委副书记、省长夏宝龙,教育部副部长、党组副书记杜玉波,以及浙江省、教育部的有关部门负责人出席了会议(http://news.ustc.edu.cn/xwbl/201210/t20121012_142392.html)。\n\n### 文章 14\n\n循州\n循州,中国隋朝时设置的州。三国东吴甘露元年(265年)析荆州刺史部桂阳郡南部置始兴郡,纳入广州刺史部管辖;即今韶关市、南雄市、始兴县、翁源县、仁化县、英德市、佛冈县等地。东晋咸和元年(326年),析南海郡置东官郡,郡治在今深圳市。义熙九年(413年),先析东官郡东部置义安郡;南朝梁天监二年(503年),又析东官郡置梁化郡。至此,东官郡辖地仅余今深圳市、珠海市、中山市、增城市、龙门县等地。隋朝开皇十年(590年),全国撤郡设州,合并始兴郡、梁化郡、东官郡、义安郡置循州,直隶于中央;治所在归善县(今惠州市东)。以境内有循江得名。开皇十一年(591年),始兴郡改设韶州、东官郡废入番州、义安郡改设潮州,仅留原梁化郡地仍为循州。大业三年(607年)改为龙川郡。唐朝武德五年(622年)设为循州总管府,管辖韶州、潮州、循州等三个州,即唐初岭南六管之一。唐朝贞观元年(627年),撤去循州总管府,原循州总管府辖下的潮州、韶州、循州均归广州总管府,此后为唐岭南五管。广州总管府辖下的循州,辖境相当于现在的广东省新丰、连平、和平、龙川、河源、兴宁、五华、陆丰、海丰、惠阳、惠东、博罗、紫金等地及揭西县西部。五代南汉移治龙川县(今广东龙川县佗城),又分置祯州,辖境缩小。元朝至元十三年,升为路,二十三年复降为州。明朝洪武二年(1369年),省入惠州府。中华民国元年(1912年)原清代惠潮嘉道改置为潮循道,道治在潮安县。民国廿五年(1936年),设广东省第六行政督察区,辖兴宁、梅县、龙川、大埔、蕉岭、和平、平远、连平、五华等9个县;因行政驻所兴宁县为原循州旧地,故而通称循州地区。另外,以惠州为行政中心,设广东省第四行政督察区,辖新丰(今属韶关市)、龙门、东莞、宝安(今深圳市)、海丰、陆丰、紫金、河源、博罗、惠阳等10个县,通称惠州地区。中共建政后(1950年),原惠州地区改称惠阳地区;原循州地区行政驻所迁驻梅县,又以旧驻所(兴宁)、新驻所(梅县)各取一字,改称兴梅地区。以后惠阳地区主要为惠州市所继承,兴梅地区演变成今天的梅州市(含丰顺;不含河源、龙川、连平、和平)。\n\n### 文章 15\n\n阿尔西比亚德斯\n阿尔西比亚德斯(希腊语:,,)是雅典杰出的政治家、演说家和将军。雅典大政治家伯里克里斯是他母系族伯,曾养育过他。阿尔西比亚德斯是这个贵族家系的最后一名著名成员,这个家族在伯罗奔尼撒战争之后衰败。他在战争的后半段扮演重要角色,担任战略顾问、军事指挥官和政治家。在伯罗奔尼撒战争期间,阿尔西比亚德斯曾经数次更换他的政治忠诚。在故乡雅典时,他主张一种好斗的外交政策,是西西里远征的主要支持着,但是在他的政敌指控他犯有亵渎罪之后,逃到斯巴达。他在斯巴达担任战略顾问,提议或监督了反对雅典的几次主要战役。但是在斯巴达,阿尔西比亚德斯也很快面临强大的敌人,又被迫叛投波斯。他在那里担任顾问,直到他的雅典政治盟友将其召回。前410年阿西比亚德重掌雅典的舰队,此后3年间更是引导著雅典连战连胜,但是最终他的政敌再次将他流放。后来他先后流亡到比提尼亚(Bithynia)与波斯,但不久后在波斯的盟邦斯巴达的要求下,波斯皇帝包围了阿尔西比亚德斯的宅邸,后者突围时中箭身亡。西西里远征是阿尔西比亚德斯的想法,学者们认为,如果远征由阿尔西比亚德斯而不是尼基阿斯指挥,可能不会是后来那样灾难性的结果。在斯巴达期间,阿尔西比亚德斯在重创雅典中扮演重要角色;占领戴凯列阿(Decelea),和几次关键性的雅典叛乱,都是在他的建议或监督下发生的。但是他一旦回到故乡,就在雅典一系列的胜利中扮演关键角色,最终迫使斯巴达寻求与雅典媾和。他支持非传统的战术,频繁通过背叛或谈判而不是围攻来夺取城市。阿尔西比亚德斯的军事和政治天才频频向他当时所效忠的城邦证明他的价值,但是他树立强敌的能力也使他不会留在一个地方很久。\n\n### 文章 16\n\n约瑟夫·道尔顿·胡克\n约瑟夫·道尔顿·胡克爵士,OM,GCSI,CB,MD,FRS(,)是英国植物学家。胡克出生于萨福克郡的哈尔沃斯镇,他的父亲威廉·杰克逊·胡克也是著名的植物学家,从7岁时他就经常到格拉斯哥大学听他父亲作为植物学教授的讲课,他很早就对植物的地理分布和库克船长的探险感兴趣,他从格拉斯哥中学毕业后就到格拉斯哥大学学习医学,1839年,获得医学博士学位,因此可以作为海军军医参加罗斯船长到南极的探险,并成为厄瑞玻斯号战舰上的助理外科医生。他是128名船员中最年轻的,探险从1839年9月30日船只起航,经过马德拉、特内里费岛、圣地牙哥岛、巴西东海岸、圣赫勒拿岛和好望角,沿途他采集了许多动物和植物以及藻类和海洋生物的标本,在南极岛屿,他确认了18种被子植物、35种苔藓、25种地衣和51种藻类新种, 经过5个月的旅行,后来他们到了悉尼和新西兰,然后又转向南极海域,经过138天航行,到了马尔维纳斯群岛和火地群岛,第三次转向南极海域,最后经阿森松岛于1843年9月4日回到英国。由于他争取在爱丁堡大学的职位没有成功,他拒绝了格拉斯哥大学的邀请,于1846年参加了在大不列颠的地理考察工作,研究古生物化石,寻找在威尔士的煤矿床中的化石,1847年,他父亲帮助他申请得到去印度为皇家植物园搜寻植物新品种的工作,当时他父亲已经是皇家植物园的园长,帮助他获得1000英镑的资助出版他的著作《南极探险的植物》,并获得每年200英镑工作资助,他陆续出版了《南极植物》("Flora Antarctica" (1844–47))、《新西兰植物》( "Flora Novae-Zelandiae" (1851–53))和《塔斯马尼亚植物》("Flora Tasmaniae" (1853–59))。1847年11月11日,他离开英国前往印度,他乘船竟尼罗河、苏伊士运河于1848年1月12日到达加尔各答,骑着象到米尔扎布尔,再乘船沿恒河到达西里古里,改骑马于1848年4月16日到达大吉岭。他以大吉岭为基地,考察了喜马拉雅山区的植物,曾到过锡金、尼泊尔、孟加拉和西藏 ,1850年1月和2月,他回到大吉岭,整理标本和写日记,然后又到不丹和阿萨姆邦,1850年12月9日起程回国。他在加尔各答出版了《喜马拉雅山日记》("Himalayan Journals")。\n\n### 文章 17\n\n萧规曹随\n萧规曹随,汉语中的一个成语,形容继任人沿用前任定下的规则、做法等等,不作更改。萧何与曹参两人少年担任秦朝小官吏时,便已是好友,后来西汉建国,萧何身为宰相,曹参身为大将,地位不凡的两人却反而有了嫌隙。萧何担任相国时,参考前朝文献制订典章及制度。萧死前,推荐曹参继任。曹参上任后,认为萧何订下的法令已很完备,所以继续沿用而不作改动。曹参就任汉相国期间,整日饮酒食肉,政治上清静无为,继续执行萧何留下的政策,不予变动。汉惠帝认为自己被曹参轻视,于是命其子御史大夫曹窋劝谏,曹参把曹窋鞭笞了两百下并赶出门外,汉惠帝于是亲自责问曹参。曹参摘帽,向皇帝俯首谢罪:「陛下您认为,您与先帝相比,谁较为英明神武?」皇帝回道:「我怎敢与先帝比?」曹参又问说:「我跟萧何比,谁较贤能?」皇帝说道:「您好像不太比得上他。」曹参接著说:「陛下说得对,且高祖跟萧何平定了天下,法令都健全具备。陛下只要垂拱而治,我们这些官吏坚守岗位,遵守他们的法令而不犯过失,不是很适当吗?」时人歌颂:「萧何制定法律,调和整齐如一;曹参继任相国,遵法而不犯过失。施载清净无为的政策,人民因而安宁统一。」史称「萧规曹随」。据前汉书记载,曹参与萧何于沛县时为挚友,但萧何担任相国时反生嫌隙。不过曹参为汉相国时,却对萧何担任相国时之制度一无变更。现今中文使用中,世人所熟知的「萧规曹随」有率由旧章、依样葫芦、一成不变、沿袭旧规等等意涵,然而曹参为汉相国时,却不是此成语所指称之无所事事,反而是选拔贤才、注重吏治,各官吏均选任老成持重之人,若有好名之人,即使其去职。可见「萧规曹随」的传统见解对曹参为汉相国的治术略有误解。曹参担任相国时,对于下属有极小过错,反而为其隐忍不公开。原典内容如下:司马迁著《史记·卷五十四·曹相国世家》:「参代何为汉相国,举事无所变更,一遵萧何约束。……惠帝怪相国不治事,以为『岂少朕与』?……参免冠谢曰:『陛下自察圣武孰与高帝?』上曰:『朕乃安敢望先帝乎!』曰:『陛下观臣能孰与萧何贤?』上曰:『君似不及也』。参曰:『陛下言之是也。且高帝与萧何定天下,法令既明,今陛下垂拱,参等守职,遵而勿失,不亦可乎?』惠帝曰:『善。君休矣!』……百姓歌之曰:『萧何为法,顜若画一;曹参代之,守而勿失。载其清净,民以宁一。』」扬雄著《法言》·〈渊骞第十一〉:「萧也规,曹也随。」\n\n### 文章 18\n\n小北站 (广州)\n小北站()是广州地铁5号线的车站,位于环市中路小北路口以东的地底,于2009年12月28号启用。本站共有两层,地下一层为站厅,设有票务设施和车站商店,地下二层为5号线月台。本站分为东西两个站厅,两个站厅在非付费区并不相通。由于环市路的地面交通繁忙,且规避上方环市路的高架桥桩基等,本站采用了暗挖施工,故其车站站厅较一般车站站厅小。两个站厅均设有扶手电梯以及楼梯供乘客前往月台层,专用电梯(升降机)由于设于往文冲方向车头月台屏蔽门之外的区域,乘客使用时需要联络车站工作人员协助使用。现时,小北站内提供少量商店供乘客购物或进食,例如有便利店、面包糕饼店等。此外,小北站也有少量自助服务设施供乘客使用,包括自动售卖机、招商银行自动柜员机等。车站内亦设有“好易”机,可充值羊城通,缴纳水电费以及交通罚款等服务、“M-Touch”机,可查询地铁线路、首末班车等资讯以及地铁安全指引的查询,更亦供乘客登记为广州地铁荟会员、查阅奖分、换领奖赏。本站设有一个分离岛式月台,位于环市中路地底。小北站共设有4个出入口,东西站厅均设置两个出入口。由于连接站厅与站台的升降机设置于车站东端,因此轮椅升降台设置在东站厅的B出入口。小北站是5号线的中途站,乘客可以乘搭往滘口或文冲列车,来往广州火车站、珠江新城、荔湾区、越秀区、天河区、黄埔区各地。小北站周围有不少事业单位和写字楼,亦有不少居民区坐落于车站周围。因此全天客流不俗,早晚高峰时段客流尤为庞大,有时甚至需要实施限流措施。同时,亦有不少麓湖,下塘西,横枝岗一带的居民通过公交等方式接驳本站。在5号线最初的规划中(1997年的《广州市城市快速轨道交通线网规划研究(最终报告)》),当时的3号线通过西村后继续沿环市西路到达珠江新城一带,中途亦设置小北站。后来于2003年方案中,3号线亦易名为5号线,同样设有小北站,并最终落实兴建。2006年6月26日,本站随5号线全线正式动工。2009年12月28日,本站随五号线于开通试运营,本站启用。\n\n### 文章 19\n\n邓飏\n邓飏(),字玄茂,南阳新野人。是东汉太傅邓禹的后代。与夏侯玄、诸葛诞和田畴并称为「四聪」。三国时曹魏大将军曹爽的党羽。邓飏年少时在洛阳已有令名。但据说其貌不扬,管辂谓之「鬼躁」、「行步弛纵,筋不束体,坐起倾倚,若无手足」。魏明帝时任尚书郎,曾任洛阳县令。后任中郎,入兼中书郎。在中书省因与李胜等人作风浮华而被魏明帝免职,不再任用。景初三年(239年)魏明帝逝世,遗诏命大将军曹爽和太尉司马懿辅助幼主曹芳。曹爽其后架空司马懿专政,任命邓飏为颍川太守,后转任大将军长史,迁侍中、尚书,作为曹爽的党羽、腹心。及后李胜和邓飏为了令曹爽立威信,建议曹爽征伐蜀汉,曹爽听从并于正始五年(244年)从长安率兵经骆谷伐蜀。但当时关中和氐、羌族的物资供应出现问题,令曹爽军缺乏军资而令大量牲畜死去。当地平民和外族亦因缺乏物资而生活困难,在道上号哭。另一方面,蜀汉军队已到,并在骆谷附近依山而守,曹爽不能前进。曹爽参军杨伟此时向曹爽解读形势,劝曹爽尽早撤军,否则必定会吃败仗。李胜和邓飏反对撤军,并与杨伟争论,杨伟于是向曹爽说:「李胜和邓飏此举会破坏国家,可以处斩。」曹爽感到不快。同时,司马懿写信给当时任征西将军,都督雍、凉诸军事的夏侯玄,预测曹爽必败,应该尽早撤军,并恐吓他一旦曹爽惨败可能会负上罪责。夏侯玄于是劝曹爽撤军。曹爽最终撤军,蜀汉大将军费袆从后领兵在山谷截击曹爽军,曹爽军苦战之下才得以逃出,但士兵伤亡甚多,关中因而大为损耗。邓飏亦常受赂,举荐的人都不是因为他们的才华。例如曾答应臧艾让他当高官,臧艾就以父亲的妾待送给邓飏作为报答,所以当时洛阳人都说:「以官易妇邓玄茂」。正始十年(249年),曹爽兄弟陪同皇帝曹芳到明帝高平陵扫墓,此时司马懿发动高平陵之变,封锁洛阳城和接管曹爽和中护军曹羲的军队。曹爽兄弟最终都决定向司马懿投降。事后曹爽被控告谋反,邓飏等党羽都曹爽一同被捕,被指控与曹爽同谋,其后被诛杀、夷三族。\n\n### 文章 20\n\n纳西古乐\n纳西古乐包括三部分:“白沙细乐”、“洞经音乐”和“皇经音乐”,由于其有一套严格的传承方式,必须以师带徒或以父带子相传,历史悠久,古朴典雅,用背诵工尺谱口传心授,所以一直流存至今。是中国最重要的的大型古典管弦乐之一。目前只有许多高寿的老艺人会演奏,应用十面云锣、芦管和曲颈琵琶等许多已经在内地失传的古老民族乐器,正在进行传承抢救。其古老乐曲、古老乐器和高寿艺人,共同被誉为稀世“三宝”。1962年由中国艺术研究院音研所、云南省歌舞团及丽江地县音乐工作者发掘整理了总谱,被称为“活的音乐化石”。白沙细乐是由纳西族聚居的中国云南丽江以北的重镇白沙而得名,由于乐队中不用音响强烈的打击乐器和管乐器,所以又名“细乐”。白沙细乐据说是在13世纪时蒙古大军南征云南,当时元世祖忽必烈和纳西族土司木天王结盟,留赠他一个乐队和乐谱,其音乐几百年一直流传下来。现在老人们在演奏时仍然身着元代乐工的服装。现在只保留下七个乐章,名为《安魂曲》,各个乐章音调联系密切,结构严谨,可单独演奏,也可连奏成一大型套曲,表现了凄凉、怀念、悲痛的情感。,当年土司将其引入丽江,又结合了当地的纳西族传统音乐的风格,这种道教音乐从19世纪后在内地已经绝迹,在丽江被保留下来,既具有古朴典雅的江南丝竹风格,又揉进了纳西族传统音乐的风格,现在保留的曲目有《到春来》、《吉祥》等20余首。皇经音乐现在已经失传。纳西古乐应用的乐器有苏古笃(胡拨)、曲项琵琶、双簧竹管乐器波伯(芦管,来自古代筚篥),还有横笛、竖笛、二簧(二弦拉弦乐器形同汉族京二胡)、大提胡、纳西族胡琴、中胡、小叫胡、三弦、筝、扬琴等打击乐器是音响较轻的五音(十面)云锣、中锣、镲、铙、大钹、大锣、板鼓、提手、木鱼、磬等。\n\n### 文章 21\n\n枫树脚溪\n枫树脚溪,又名南屯溪,旧称犁头店溪,位于台中盆地,属于乌溪水系,为土库溪的支流,流域分布于台中市乌日区、台中市中心及台中市潭子区,因流经枫树脚聚落(今南屯区枫树里)而得名。枫树脚溪本流发源西屯区何厝庄,向南流经南屯区沟仔墘、犁头店、下枫树脚,于南屯区、乌日区交界处汇入东侧流来之土库溪。依据经济部水利署公告,枫树脚溪注入土库溪,以土库溪为主流。旧南屯溪附近地区,早年经文史团体调查即发现有丰富的史前遗留,并将其命名为「麻糍埔遗址」。从台湾清治时期至民国70年代,南屯溪与南屯地区居民生活相互依存。旧南屯溪于清代台中盆地开垦史中,因邻近往来鹿港与葫芦墩街之贸易古道,逐渐形成犁头店街附近的重要农村聚落。随著台中市第二、三、四期扩大都市计划发布实施,南屯地区逐渐发展成住宅社区,以黎明路周边发展最为快速。80年代,配合第七期、第八期重划区开发,部分南屯溪河道纳入重划区排水,1995年(民国84年)南屯溪整治完成后,仅永顺路与永春东二路间第13期市地重划范围内尚存一小段天然河道,为南屯溪原本的自然河道,称为「旧南屯溪」,范围北自永顺路靠文心南七路段,沿枫乐巷南抵永春东二路和环中路交叉处附近。现今旧南屯溪之排水功能则已被新南屯溪的排水道取代。旧南屯溪拥有丰富生态且兼具疏洪功能,鱼类、水草与鸟类在此和谐共生,为都市中难能可贵的自然生态资源。此外,旧南屯溪部分河段保留水利设施,提供周边土地农作灌溉功能,象征旧南屯溪对传统农业社会的贡献。由于旧南屯溪有高度景观及人文意义,代表先民当年溯溪至台中开垦之历史意义,对南屯地区的发展具有历史、文化上之意义与价值,而且旧南屯溪沿线有优美绿带,展现旧南屯溪的自然生态与历史古迹,旧南屯溪畔有史前麻糍埔遗址,亦反映过去人类利用此溪水生活之意义。因此经过地方及文史专家争取,2013年10月台中市文化局正式将位于第13期重划区内的旧南屯溪、铁道等设施列为文化景观,成为台中市第1个河流的文化景观。\n\n### 文章 22\n\n异域\n《异域》是由作家柏杨所创作的,内容以主角邓克保第一人称的口吻,娓娓叙述自1949年到1954年间,自缅甸北境撤往泰国北方,现居于泰国北部地区与缅甸、寮国交界地带的原中华民国国军——今简称「孤军」——的一本书籍。1949年中华民国国军自中国大陆撤退时,一支溃散的孤军如何在云南与缅甸边区丛林建立起一片游击队基地,以及这一批孤臣孽子在生死边缘的绝境当中与命运搏斗、并且冀求反攻中国大陆的血泪经历。《异域》后来被改编成为电影《异域》。根据柏杨所述,《异域》小说的资料来源,是当时柏杨于《自立晚报》编辑部工作时,报社驻台北板桥记者马俊良每天访问一两位从泰北撤退到台湾的孤军,将对方口述该地状况情形纪录下来之后,他再把采访资料交给柏杨,后由柏杨撰写成文。由此可知柏杨本人并没有亲身经历,资料也从第三者采访而来,《异域》并不是纪实报导。而后,柏杨自1961年开始,以笔名「邓克保」在《自立晚报》社会版连载刊登以纪实报导为形式的文章,标题为〈血战异域十一年〉。文章刚开始时,作者说,邓克保是一个化名、是一个在逃难时死在身旁的军人,理由是他接受记者访问后「还要回到游击区」去,因此不能用真实姓名。然而,故事中的时空背景皆真有其事;书中的军人将领,除了邓克保,也都真有其人,例如李弥将军、李国辉团长等。既有确切的时间、地点与真实人物,又全部以第一人称叙述,尤其是出现在新闻版面上,言之凿凿,让读者无所怀疑,因此是被当作真人实事来刊载及阅读,是受访者个人的亲身经历加上旁边战友的真实事情。连载文章在报纸刊出后,意外得到读者极热烈的回响,报社收到大批写给邓克保的信,也促使小说的出版,同一年即由平原出版社发行;然而因故事内容只写了十一年中的前六年,因此把名字从「血战异域十一年」改为「异域」,但作者依旧是「邓克保」。然而,1967年柏杨因大力水手事件入狱,其所有作品包括小说与杂文皆在查禁之列;惟独《异域》一书因作者姓名的「陌生」或根本「查无此人」,有意无意间竟逃过了查禁的耳目,持续热卖,甚至更迭有出版社四度接手再版,每版又再刷印十余次,每次又有数十万本销量。1977年由星光出版社再版,1988年跃升文化再版,1990年由朱延平改编为电影《异域》。2001年,由远流出版公司出版。\n\n### 文章 23\n\n乙酸铜\n乙酸铜(乙酸铜(II)),是化学式为Cu(CHCOO)的化合物,其中CHCOO指乙酸根CHCOO。Cu(CHCOO)是深绿色晶体,一水合物Cu(CHCOO)(HO)略带蓝绿色。乙酸铜在古代被用作杀菌剂和绿色颜料,目前多用作无机合成中铜(II)的来源,也可在有机合成中作为催化剂或氧化剂。和所有铜化合物一样,乙酸铜的焰色反应为蓝绿色。乙酸是食物发酵的副产物,而乙酸铜最早也是在葡萄园中获得的。当时铜片夹在生产葡萄酒剩余的葡萄皮和残渣中,人们发现不久后就有蓝色物质在铜片表面生成。刮下少许后发现它可溶于水。该固体被用作颜料。它与三氧化二砷混合后生成醋酸亚砷酸铜,作为杀虫剂和杀菌剂使用,称作巴黎绿。乙酸铜的主要用途是在有机合成中作为催化剂或氧化剂使用。例如,Cu(CHCOO)可以催化两个末端炔烃的偶联,生成1,3-二炔:反应的中间体包括乙炔亚铜等,再经乙酸铜氧化,得到炔基自由基。此外,用乙酸铜来合成炔胺(含有氨基的末端炔烃)也涉及乙炔亚铜中间产物。将无水Cu(CHCOO)和金属铜一起加热会得到无色易挥发的乙酸亚铜:乙酸铜(II)用水合肼也能还原成乙酸亚铜。乙酸铜在发现后的几个世纪内都是通过以上方法制取的。但这种方法制得的乙酸铜杂质较多。现在实验室中的制备方法分为三步,总反应为:二水合物会在100°C真空失水:也可以用碳酸铜和乙酸反应制备乙酸铜:Cu(CHCOO)(HO),以及类似的Rh(II)、Cr(II)乙酸盐二聚体都采取“中国灯笼”式的结构。 每个铜原子都为四个氧原子所围绕,乙酸根的每一个氧原子都与一个铜原子键连,键长1.97Å(197pm)。两个水分子配体占上下,Cu-O键长为2.20Å(220pm)。两个五配位的铜原子之间的距离为2.65Å(265pm),与金属铜中Cu—Cu距离(255pm)相近。两个铜原子存在很弱的共价作用,导致乙酸铜的磁矩随着温度降低而减小,比如一水合乙酸铜室温下的磁矩为1.40 B.M.,而在90K时仅为0.36 B.M.。由于自旋方向相反抵消,Cu(CHCOO)(HO)实质上是反磁性的。它对推动现代反铁磁体耦合理论发展有很重要的贡献。\n\n### 文章 24\n\n托纳蒂赫\n托纳蒂赫(Tonatiuh,或作Ollin Tonatiuh)是阿兹特克的太阳神,其名字的意思为「日之运行」。阿兹特克人认为他是天堂托兰(Tollan)之主。由于阿兹特克人相信他取代第四个太阳纪元中的太阳神,成为第五个纪元的个太阳神。根据他们的宇宙观,每一个太阳纪都有一个的太阳,而阿兹特克人认为他们仍然身处于托纳蒂赫的太阳纪。众神在特奥蒂瓦坎创造第五太阳时,纳纳瓦特辛(Nanahuatzin)与特库西斯特卡特尔(Tecuciztecatl)自愿跳入篝火,争逐成为第五纪元的太阳,后来特库西斯特卡特尔抵受不了烈火,相反,纳纳瓦特辛则坚持到底,最后纳纳瓦特辛成为太阳,而特库西斯特卡特尔则成了月亮,而纳纳瓦特辛由一个满身溃伤的神祇变成强大的太阳神托纳蒂赫;不过,托纳蒂赫成为太阳以后,竟向诸神索命,诸神于是献出心脏。阿兹特克人因此认为要借由活人献祭,以确保太阳会继续运行。根据阿兹特克的创世神话,托纳蒂赫要求阿兹特克人以活人向他献祭,否则他拒绝于天上运行。有说每年有20,000人因托纳蒂赫与其他神祇而牺牲,尽管有人认为这个数字是阿兹特克人用来唬吓敌人或遭西班牙人恶意中伤而被夸大的。阿兹特克人深受太阳吸引,并创立太阳历,准确度仅次于马雅人的太阳历。现今保留下来的阿兹特克遗址亦与太阳有密切关系。阿兹特克的活人献祭是非常普遍的,他们把活人的心脏和鲜血奉献给托纳蒂赫,而托纳蒂赫则凭借他的热力和人类奉献给他的鲜血,赐予战士力量和勇气。在阿兹特克的神话中,托纳蒂赫每晚会与黑暗战斗,他会被大地妖怪特拉尔特奎特利吞下,而他们接纳在战斗中被杀的战士,护送他们上天堂。在阿兹特克历法法中,托纳蒂赫是「13天周期」(trecena)中「第一天(死亡)至第十三天(火石)」之主宰。在托纳蒂赫之前神祇的是查尔奇赫特里奎,而紧随托纳蒂赫的则是特拉洛克。\n\n### 文章 25\n\n青少年机器人世界杯\n青少年机器人世界杯(RoboCup Junior,RCJ)是一个以任务式设计为导向的教育性公开活动,该活动为青少年提供了本地性﹑区域性和国际性的机器人赛事。 其设立目的是通过举办青少年机器人世界杯的各项赛事,向小学生、中学生以及一些因缺乏条件而无法加入给大学生高级组的机器人世界杯(RoboCup)。它为青少年朋友提供一个了解国际最新技术、开拓视野的机会,目前法国、瑞典、澳大利亚、加拿大、美国、日本、义大利以及香港等地方每年也开展著青少年机器人世界杯的活动项目。青少年机器人世界杯提供几种挑战项目,每种模式均同时强调合作和竞争两方面的能力。对于青少年来说,青少年机器人世界杯将他们引入了一个令人兴奋的探索机器人技术的领域;提供了一个通过动手实践电子技术、软硬件应用来提高科技能力的新模式;一个与同伴分享科技、学习与人合作技能的机会。与我们今天看到的一人一机的典型情况相反的是,青少年机器人世界杯给参加者提供了独特的机会,使得有著不同兴趣爱好和能力的参加者能够组成团队,协同工作并且达到共同目标。青少年机器人世界杯始于1998年,而在2000年墨尔本举办的青少年机器人世界杯,有来自澳大利亚25所学校以及德国和美国的100多个孩子参加。学生们分别加入了足球,寻迹相扑,或者跳舞挑战项目,并机器人世界杯比赛上首次增加青少年机器人世界杯为正式比赛项目。在西雅图主办的青少年机器人世界杯2001中,来自美国、澳洲、德国和英国的 25 队进行了足球、援救和跳舞挑战比赛。巡回赛之后,成立了一个工作室,在那里研究者们共享了他们在教育机械手工程方面的创意并了解了相互的进展情况。.青少年机器人世界杯2002在日本福冈举办,来自 12个国家的59支队伍三加了比赛.青少年机器人世界杯2003于2003年7月在意大利的帕多瓦举办,预计将有来自全球多个国家的近100支队伍参加比赛。青少年机器人世界杯比赛的项目包括足球(1—1、2—2)、舞蹈,及营救比赛项目。\n\n### 文章 26\n\n心物问题\n心物问题(),又译为心身问题、身心问题,一个传统的哲学问题,讨论心灵(mind)与物质之间的关系,探讨心灵如何透过身体,与外在世界进行互动,相互影响。比较狭义的讨论中,集中于意识与大脑之间的关系。这个哲学问题的历史悠久,在亚里斯多德之前的古希腊哲学家已经开始对它进行讨论,中世纪阿拉伯世界的伊本·西那也对这个问题进行讨论。近代哲学中,笛卡尔重新审视了这个问题,提出了笛卡尔二元论的见解。唯心主义主张,所有物质都是基于心灵存在,因此只有心灵存在;物理主义认为,心灵是基于物质运作而产生的现象。唯心主义主张,物质是源自于心灵,因此只有心灵是真实的。物理主义认为,心灵是一种物理现象,由身体组织的运作而产生,提出心身(mindbody)一体论。心物二元论是一个心灵哲学的课题,由笛卡儿最早正式的提出。心物二元论的根本论据是指人是由「心灵」和「肉体」两部份所组成,与唯物主义强调「一个人的肉体就是它的全部」这种论据相对立。在过去,哲学家一直都认为不能验证的思维试验。但随着复制人类的可能性出现,使得这个实验变得可能:心身二分法(Mind-body dichotomy),是指一种认为精神现象在某种程度上独立于身体的观念。它是二元论的出发点,透过笛卡尔的哲学而为西方世界关注,虽然它在一些亚里士多德之前的理念(如柏拉图)和阿维森纳主义中已经出现。心身二分法现实观往往使人认为肉体是没多大价值的。对心身二分法的排斥可以在法国结构主义中找到,那是战后法国哲学的通常立场。心物()问题是重要的哲学问题。探讨心灵()如何得以与肉体()及世界互相影响。有人认为心灵非物质。有些人则认为心灵只是肉体的运作。但目前仍然没有可信的解释。\n\n### 文章 27\n\n黎燕珊\n黎燕珊(英文名:,),香港影视演员,首届香港亚洲小姐竞选冠军,曾是邵氏电影公司演员和亚洲电视合约女艺员,2017年9月转为无线电视部头合约艺人。现时为由历届亚洲小姐组成之慈善机构仁美清叙应届主席,2009年该会重组后当选为首届会长 也是第一届亚洲小姐加入无线电视的前亚视艺人黎燕珊早在1980年代初便加入邵氏成为旗下艺人,但那时尚未走红。1985年,黎燕珊参加由亚洲电视举办的首届亚洲小姐竞选,最终夺得冠军,从而声名大噪。此后,黎燕珊与后来加入亚视的利智等人一同受到力捧,兼任演员及司仪,成为台柱之一。其中剧集代表作有她主演的《西施》,以及她和后来的丈夫刘永合作的《成吉思汗》。1988年与亚视约满,重投电影界,但1992年因为与刘永结婚,便逐渐淡出,只曾在九十年代中后期多次复出拍戏。2007年,黎燕珊正式在亚视复出,除拍剧外,主要在综艺节目中担任主持。在2010年王征入主亚视后,由于不满王征干预「仁美清叙」行政,使其商业化,加以有见亚视剧集制作停顿,在2013年约满后,黎燕珊选择离开亚视。2017年,53岁的黎燕珊加盟无线,签约2年于9月1日正式生效,接受访问时表示希望多在剧集方面发展。1992年,黎燕珊与同为邵氏出身的演员刘永结婚,成为刘永第二任妻子(第一任为戴良纯)。两人婚后育有一子一女。2000年,刘永和黎燕珊夫妻关系恶化。黎燕珊提出离婚申请,甚至向高等法院申请禁制令,禁止刘永接触自己及子女。虽然刘永其后曾在媒体前落泪并向黎燕珊表示悔意,但两人终在2004年正式离婚。2017年10月,黎燕珊出席「致富从心」记者会,即场向「股侠」方新侠和「人生导师」林希桦请教,并表示择偶条件是年纪不能细过自己,不能花她的钱及不能矮过她。\n\n### 文章 28\n\n香港四大才子\n「香港四大才子」,又称香江四大才子,是指香港四位文人,分别为金庸、倪匡、黄霑和蔡澜,四人各有所长,皆是腹中饱有学问之辈,而且分属好友,因而被称为「香港四大才子」。四人之成就约于七、八十年代开始被广为认识和推崇,而其中黄霑因癌病已于2004年逝世,金庸、倪匡已封笔,只有蔡澜偶尔做做电视节目和写美食书。「香港四大才子」中的其中三人倪匡、黄霑和蔡澜曾于1989年至1990年间共同主持亚洲电视(ATV)经典成人清谈节目《今夜不设防》。2013年,在黎智英的邀请下,倪匡和蔡澜现时在壹传媒主持每周一集的清谈视像节目《乱噏廿四》。金庸原名查良镛,生于浙江海宁,1948年移居香港,是当今武侠小说作家之大师。他笔法铺陈,描写细致,所著武侠小说在华人世界中广泛流传、家传户晓。他的十五部小说中,几乎都被拍成电影、电视剧,作品被翻译成十数种语言。其中尤以《射雕英雄传》、《神雕侠侣》、《鹿鼎记》、《笑傲江湖》、《天龙八部》、《倚天屠龙记》等最广为人知。倪匡原名倪聪,生于浙江宁波,1957年偷渡到香港,是华人科幻小说界里最具影响力的作家,他的作品的结局往往出人意表。他笔下有很多名作,其中以卫斯理系列、原振侠系列、浪子高达系列、亚洲之鹰罗开系列、女黑侠木兰花系列、年轻人与公主系列、侠盗影子系列等最广为人知。另外,也曾替金庸捉刀《天龙八部》的数回共四万多字。1986年受洗为基督徒。黄霑原名黄湛森,生于广东广州,1949年随父母移居香港,2004年11月24日因癌症逝世,是华人地区最具影响力的填词人、广告人、作家及传媒创作人,也是当代粤语流行歌曲重要人物之一,创作接近2000首流行曲。著名填词作品包括《狮子山下》、《问我》、《上海滩》、《沧海一声笑》等;经典广告作品包括家计会「两个够晒数」、「人头马一开,好事自然来」等广告口号。蔡澜,新加坡潮州华侨,1963年定居香港,是华人地区最具影响力的美食家、作家之一。他的父亲蔡文玄是一位诗人,受父亲影响,他自小文采飞扬,著有不少散文集。美食方面他也具影响力,于各地设立蔡澜美食坊,也经常主持电视台饮食节目,如《蔡澜逛菜栏》等。\n\n### 文章 29\n\n卜公体育会\n卜公体育会(HK Blake Garden A.A. Ltd,简称卜公),是香港一支带有地区色彩的足球队,由上环卜公花园一班热爱足球的人士组成,曾培育出包括胡国雄与梁帅荣两位香港足球代表队队长等球星。卜公曾经升上香港甲组足球联赛角逐,现时已被淘汰出局。位于上环太平山街的卜公花园足球场,在战后初期至1970年代,曾经是香港岛小型足球的热门场地,卜公花园一班热爱足球的青年,组成卜公足球队,至1971年正式注册社团。1970年代,卜公于小球界称霸,在小型球总会的七个比赛中赢了六个,于是便决定加入为香港足球总会会员。卜公多年来孕育出无数球星,早期有莫振华、区彭年、邝演英,1960年代有「卜公三宝」胡国雄、施建熙、崔永生,以及毕伟康、黎新祥等,1970年代亦有尹志强、梁帅荣、邓锦添等不少本港足球人材。1975–76年,卜公以丙组球队身份,杀入初级银牌决赛,并于决赛凭左翼李剑虹射入十二码,越级挑战成功以 1–0 击败乙组强队怡和,勇夺冠军。1976–77年,卜公获得香港乙组足球联赛亚军,得以首次升上香港甲组足球联赛作赛。1977–78年,卜公在甲组的首个球季,便成功杀入足总杯决赛,可惜最终不敌精工,只能够屈居亚军。1978年11月4日,在花墟球场上演的一场甲组联赛卜公对元朗,两队球员比赛中途大打出手,最后要警察到场调停,卜公外援球员马文拿更受伤需要送院治疗。1979年5月28日,甲组联赛卜公于花墟球场对警察,在天雨下只得8名观众购票入场,创下香港甲组足球联赛最低入场人数纪录。1978–79年,卜公在甲组联赛名列包尾,在甲组只角逐了两个球季,便要降回乙组作赛,自此未再回升甲组。2008–09年球季,卜公在香港丙组(甲)足球联赛 19 战 8 胜 7 和 4 负得 31 分,以第 8 名完成赛季。2010年3月11日晚上,卜公为出身于该会青年军的已故亚洲第一中锋尹志强,于湾仔修顿球场举办纪念赛,并颁赠纪念品予尹志强父亲及女友米雪,并以鼓掌一分钟来怀念尹志强。香港足球总会于2012–13年,重组丙组联赛,并复办丁组联赛。卜公在上一届香港丙组(甲)联赛名列第 17 名,故需降落丁组联赛角逐。卜公在复办的首届丁组联赛成绩欠佳,经过半季之后,在15队中排名包尾,被淘汰出局。\n\n### 文章 30\n\n国家科学技术奖励\n中国政府为了奖励在科技进步活动中作出突出贡献的公民,推动中国科技事业的发展,国务院设立五个国家科学技术奖。包括国家最高科学技术奖、国家自然科学奖、国家技术发明奖、国家科学技术进步奖和中华人民共和国国际科学技术合作奖。奖项中规格最高的国家最高科学技术奖每年评审一次,每次选出不超过两名科技成就卓著、社会贡献巨大的公民,由国家主席亲自签署并颁发荣誉证书和高额奖金。每位获奖者的奖金总额均为人民币500万元,其中50万元直接授予个人,另外450万元作为科学研究经费由获奖人全权管理具体用途。国家自然科学奖是授予在数学、物理学、化学、天文学、地球科学、生命科学等基础研究和信息、材料、工程技术等领域的应用基础研究中,阐明自然现象、特征和规律、做出重大科学发现的中国公民的奖项。国家自然科学奖不授予组织。国家自然科学奖设一、二等两个奖励等级。国家自然科学一等奖是自然科学领域的国家最高奖。国家技术发明奖授予在产品、工艺、材料及其系统等有重大技术发明的中国公民。国家技术发明奖不授予组织。国家技术发明奖设一、二等两个奖励等级。国家技术发明奖表彰的是当年中国国民经济中新的、先进的、效益好的新技术。国家科学技术进步奖授予在技术研究、技术开发、技术创新、推广应用先进科学技术成果、促进高新技术产业化,以及完成重大科学技术工程、计划等过程中做出创造性贡献的中国公民和组织。每年国家科学技术进步奖总数不超过400项,分为特等奖,一等奖, 二等奖3个等级。中华人民共和国国际科学技术合作奖是由中国国务院设立的国家科学技术奖励,以奖励对中国科技事业作出贡献的外国人或组织。其前身为国家科学技术委员会设立的中国国际科技合作奖,根据1993年7月经全国人大常委会八届二次会议通过的《中华人民共和国科学技术进步法》的规定,国务院设立“中华人民共和国国际科学技术合作奖”(简称国际科技合作奖)。国家科学技术奖励委员会是对奖励进行评选的机构,设立主任委员,副主任委员,秘书长,委员等职位,一般主任委员,秘书长各一名,副主任委员两名,另外有委员若干名。委员会成员主要是中国科技部,中国科学院,中国工程院及各知名大学的专家学者。\n\n### 文章 31\n\n权知高丽国事\n权知高丽国事是1392年高丽大将和实际执政者、李氏朝鲜建立者李成桂向明朝申请册封时自称的头衔,意为“代理高丽国之事”。公元1388年,高丽末代国王禑王由于其王族长期的亲蒙古政策,意图联合蒙古打击成立不久的明朝。当时的高丽将军李成桂受命进攻辽东。李成桂却因故反对出兵,并且发动兵变,1392年在高丽都城开城废黜国王禑王,后李成桂以“权知高丽国事” 的头衔向明朝上表,称高丽国王长期亲蒙古,有辱社稷,企图自立为高丽王。朱元璋则口气冷漠,道“尔恭愍王死,称其有子,请立之,后来又说不是。又以王瑶为王孙正派,请立之,今又去了。再三差人来,大概李成桂要自作王。我不问,教他自作,自要抚绥百姓,相通来往”。后来李成桂改变策略,拟定两个国号——“朝鲜”(古号)和“和宁”(李成桂父亲李子春就仕之地)请朱元璋决定,朱元璋认为朝鲜乃是古代箕子受封之名,因此选了朝鲜二字,但是又因为李成桂乃是造反并“顽嚣狡诈”而迟迟不正式册封赐印。当时明朝与高丽之间还有辽金时代遗留下来的保州等领土争端。后李成桂子靖安大君李芳远的时候才正式被明朝册封为朝鲜国王。另外,高丽王朝建立者王建在被后唐明宗封为“高丽国王”之前,也自称“权知国事”。传统观点认为李成桂是信奉亲明,事大主义的高丽将军故而反对出兵,并且发动兵变,而近代历史研究认为 李成桂家族其实生活在蒙古人直接管辖的领地内。1255年,李成桂的高曾祖父李安社在图们江地区被蒙古皇帝蒙哥汗封为千户长和达鲁花赤,而在蒙古人是极少封外族为达鲁花赤的,因此推断李成桂其实是高丽系蒙古军阀出生。 而事大主义可能只是反对出兵,并且发动兵变的一个借口,借以谋求明朝的承认。\n\n### 文章 32\n\n葡萄牙国徽\n葡萄牙国徽(),为盾徽,中间白盾绘有五个呈十字状排列的小蓝盾,蓝盾绘有五个呈X形十字分布的白色圆点。外面红盾绘有七座金色城堡。置于浑天仪上,再以用红绿两色绶带束起的橄榄枝装饰。此徽颁布于葡萄牙第一共和国成立后的1911年6月30日,且沿用至今。代表葡萄牙的徽章在大概在1000年前已经出现。最早可以追溯到勃艮第的亨利(葡萄牙开国君主亚丰素·殷理基的父亲)之银盾蓝色十字。经过多个世纪的改朝换代,葡萄牙国徽的图案内容也有所增减。1910年10月5日革命后,成立葡萄牙第一共和国,国徽则在翌年6月30日开始使用。葡萄牙王国在1139年宣告独立,自1143年签订萨莫拉条约正式从卡斯蒂利亚王国分离,象征著王权与铸币权的银色圆点便被加在勃艮第的旗帜上,以宣示主权的独立。经过中世纪长年累月战争的洗礼,当桑乔一世继承他父亲亚丰素的徽章时,盾牌上的图案已由十字被磨损成五个小盾牌。各小盾牌内的圆点起初有11个,后来塞巴斯蒂昂在位时把圆点的数量减至5个。这在现代被解读成与耶稣受难时的有关。红框和里面的城堡是亚丰素三世统治时期加上的。源自卡斯蒂利亚的城堡代表在收复失地运动中从摩尔人夺取的城池。当亚丰素三世夺取其兄桑乔二世的王位时,由于他是亚丰素二世的次子,并无准备登基成为国王。他的纹章融合了父亲葡萄牙式的盾牌和卡斯蒂利亚式的红色框界和金色城堡。尽管初时城堡的数量由8至12座不等,而亚丰素四世曾经定为12座,但后来塞巴斯蒂昂最终把数量定为现时的7座。与西班牙式的城堡不一样的是,西班牙式城堡的城门绘上的是蓝色(保持开放);葡萄牙式城堡的城门绘上的是金色闩门(没有开放)。浑天仪自15世纪起成为代表葡萄牙的其中一个元素,在许多葡萄牙的殖民地旗帜上(特别是巴西)也可轻易找到。它在航海的重要用途(辨认方向和测量距离)意味著地理大发现时代对葡萄牙以及其众多殖民地(即使在共和后也是如此)的重要性。相对王室的冠冕,虽然浑天仪被认为「共和」的象征,不过其实早在葡萄牙-巴西-阿尔加维联合王国时期经已在国徽上出现。这是由于巴西也是联合王国的一部分的关系。\n\n### 文章 33\n\n阿尔西比亚德斯\n阿尔西比亚德斯(希腊语:,,)是雅典杰出的政治家、演说家和将军。雅典大政治家伯里克里斯是他母系族伯,曾养育过他。阿尔西比亚德斯是这个贵族家系的最后一名著名成员,这个家族在伯罗奔尼撒战争之后衰败。他在战争的后半段扮演重要角色,担任战略顾问、军事指挥官和政治家。在伯罗奔尼撒战争期间,阿尔西比亚德斯曾经数次更换他的政治忠诚。在故乡雅典时,他主张一种好斗的外交政策,是西西里远征的主要支持着,但是在他的政敌指控他犯有亵渎罪之后,逃到斯巴达。他在斯巴达担任战略顾问,提议或监督了反对雅典的几次主要战役。但是在斯巴达,阿尔西比亚德斯也很快面临强大的敌人,又被迫叛投波斯。他在那里担任顾问,直到他的雅典政治盟友将其召回。前410年阿西比亚德重掌雅典的舰队,此后3年间更是引导著雅典连战连胜,但是最终他的政敌再次将他流放。后来他先后流亡到比提尼亚(Bithynia)与波斯,但不久后在波斯的盟邦斯巴达的要求下,波斯皇帝包围了阿尔西比亚德斯的宅邸,后者突围时中箭身亡。西西里远征是阿尔西比亚德斯的想法,学者们认为,如果远征由阿尔西比亚德斯而不是尼基阿斯指挥,可能不会是后来那样灾难性的结果。在斯巴达期间,阿尔西比亚德斯在重创雅典中扮演重要角色;占领戴凯列阿(Decelea),和几次关键性的雅典叛乱,都是在他的建议或监督下发生的。但是他一旦回到故乡,就在雅典一系列的胜利中扮演关键角色,最终迫使斯巴达寻求与雅典媾和。他支持非传统的战术,频繁通过背叛或谈判而不是围攻来夺取城市。阿尔西比亚德斯的军事和政治天才频频向他当时所效忠的城邦证明他的价值,但是他树立强敌的能力也使他不会留在一个地方很久。\n\n### 文章 34\n\n动物扮演\n动物扮演是指人加上一些道具去扮演一些实际存在的动物或是幻想的动物,并且模仿该动物的肢体行动,例如扮演小狗则以四肢著地地爬行。扮演动物的理由很多,例如Cosplay、情趣游戏、商户吸引顾客等,有的只是外表动物化,心理还是保持人的状态,但是稍稍受所扮演的动物所影响,好比说扮演兔子、小猫就以比较温驯的姿态。扮演花豹、小狗,则是比较狂野姿态。有的是连心智都要表现得像动物,常见于BDSM的游戏中,而伴侣的角色也可能是扮演动物,或是驯兽师、宠物主人或是骑师。扮演动物者,受到支配者以对待动物的方式对待获得满足。好比扮演小猫、小狗者被主人以项圈拴住,或是关进兽笼,以宠物的姿态生活进食。或是扮演马,穿著马具拉马车,承受伴侣的鞭子。无性暗示的动物扮演则常见于原始部落文化,像是北美洲的原住民文化以及史前传说中,半人半兽的动物在他们的文化仪式中有很重要的地位。这些动物如神兽般地被尊敬,有的时候也拿来教育儿童,要求学习动物的求生智慧,以及运动姿态。扮演动物的原因,往往与参与的人有大的歧异。不单只是一般的角色扮演,这牵涉到很多戏剧、小说、神话、传说以及心理戏剧的观点来分析这样的现象。就如同一般的情趣游戏或是角色扮演,动物扮演的理由跟参与者的喜好心情相关。可能从只是简单的模仿马的嘶叫声、狗吠声,或是小猫小狗活动的姿态。到被主人喂食、被当作宠物把玩。有点类似年龄游戏(Ageplay),透过游戏可以当一些别于日常生活所扮演的角色。更复杂的可能如母马扮演时,加上一些马具、嘴里衔住口衔、加上马尾以及穿上模仿马蹄的靴子。扮演母猫则可能加上猫耳、项圈、猫蹼以及猫尾。西方式的小猫游戏,主要是从性感内衣为出发点,外观上较为性感,小猫泛指所有的猫科动物,如花豹、老虎等皆有人扮演。东方式或是日式的小猫游戏受卡通、ACG影响较深,因此比较属于可爱形式。不论是东方还是西方,最终目的是要充分令自己显出猫的特征。以下简单地并依重要性及普遍度列出:\n\n### 文章 35\n\n黎燕珊\n黎燕珊(英文名:,),香港影视演员,首届香港亚洲小姐竞选冠军,曾是邵氏电影公司演员和亚洲电视合约女艺员,2017年9月转为无线电视部头合约艺人。现时为由历届亚洲小姐组成之慈善机构仁美清叙应届主席,2009年该会重组后当选为首届会长 也是第一届亚洲小姐加入无线电视的前亚视艺人黎燕珊早在1980年代初便加入邵氏成为旗下艺人,但那时尚未走红。1985年,黎燕珊参加由亚洲电视举办的首届亚洲小姐竞选,最终夺得冠军,从而声名大噪。此后,黎燕珊与后来加入亚视的利智等人一同受到力捧,兼任演员及司仪,成为台柱之一。其中剧集代表作有她主演的《西施》,以及她和后来的丈夫刘永合作的《成吉思汗》。1988年与亚视约满,重投电影界,但1992年因为与刘永结婚,便逐渐淡出,只曾在九十年代中后期多次复出拍戏。2007年,黎燕珊正式在亚视复出,除拍剧外,主要在综艺节目中担任主持。在2010年王征入主亚视后,由于不满王征干预「仁美清叙」行政,使其商业化,加以有见亚视剧集制作停顿,在2013年约满后,黎燕珊选择离开亚视。2017年,53岁的黎燕珊加盟无线,签约2年于9月1日正式生效,接受访问时表示希望多在剧集方面发展。1992年,黎燕珊与同为邵氏出身的演员刘永结婚,成为刘永第二任妻子(第一任为戴良纯)。两人婚后育有一子一女。2000年,刘永和黎燕珊夫妻关系恶化。黎燕珊提出离婚申请,甚至向高等法院申请禁制令,禁止刘永接触自己及子女。虽然刘永其后曾在媒体前落泪并向黎燕珊表示悔意,但两人终在2004年正式离婚。2017年10月,黎燕珊出席「致富从心」记者会,即场向「股侠」方新侠和「人生导师」林希桦请教,并表示择偶条件是年纪不能细过自己,不能花她的钱及不能矮过她。\n\n### 文章 36\n\n陈鸿平\n陈鸿平(Chan Hung Ping,),外号「嚤啰平」,是已退役香港足球运动员,司职中场,曾入选中华民国代表队参加国际赛。退役后曾执教多支甲组球队,1990年代初带领东方连夺三届香港甲组足球联赛冠军,创造「东方皇朝」,并曾经两度兼任香港足球代表队教练,现时担任香港超级足球联赛球队理文守门员教练。陈鸿平出身于香港老牌球会南华青年军,1960年转投愉园,并获提升上甲组,展开职业球员生涯。其后效力过元朗、怡和、精工、海蜂等多支香港甲组足球联赛球队,到1980年,以38岁之龄宣布挂靴。国际赛方面,陈鸿平于1960年协助中华民国赢得亚青杯冠军。其后亦入选中华民国代表队,参加过亚洲杯足球赛、默迪卡杯等赛事,协助中华民国赢得1965年默迪卡杯足球赛冠军,以及1968年亚洲杯殿军,并入选决赛周最佳十一人。1981年8月,由香港足球总会资助,与文锦棠一同前赴英国参加初级足球教练训练班。1982年担任香港甲组足球联赛「升班马」菱电助教,开始展开教练生涯,先后执教过海蜂、星岛、东方、民信、愉园、公民等多支香港甲组足球联赛球队。最辉煌成绩是1992-93年度至1994-95年度球季,带领东方连夺三届香港甲组足球联赛冠军,创造「东方皇朝」。其中在1992-93年度,更创下香港甲组足球联赛首循环赛事全胜兼不失一球的辉煌纪录。由2009-10年度球季开始,担任四海流浪教练,2011年夏天转任领队,与教练巴贝利合作带领球队。陈鸿平并曾经先后两度担任香港足球代表队教练。陈鸿平有过两段婚姻,皆离婚收场,育有三女一子,儿子陈念萱亦曾是愉园预备组球员。2011年8月6日傍晚,于元朗参加一场元老足球赛时晕倒,昏迷不醒送院,在博爱医院深切治疗部留医,至8月8日上午苏醒过来。8月15日接受心脏通血管手术后已出院,并于8月18日恢复工作。2012年12月4日,昔日队友李方辉、施维山、黄德祥,以及艺人尹扬明等,一起于筲箕湾南平坊硬地足球场举办一场小型足球赛,为他提前庆祝七十大寿。\n\n### 文章 37\n\n胡燕泳\n胡燕泳(),香港新闻从业员。2001年胡在香港中文大学新闻与传播学院毕业,曾经从事公关工作。2003年转职香港有线电视新闻主播,并于同年转职到24小时亚视新闻台。2006年获奖学金,留学伦敦大学亚非学院,念国际研究与外交硕士。及后开始于免费频道本港台报道新闻,曾任担任本港台六点钟新闻、夜间新闻主播一职。2007年与黄珊、黄雅宇共同担任《主播天下》的主持及策划职务。2010年3月,她辞职并离开亚视新闻的播报工作,至2012年7月以兼职身分重返亚视新闻工作。2012年11月在报章撰文批评亚视高层干涉新闻部运作后,遭亚视解雇。2013年4月起,任无线新闻外电编辑,同年9月尾开始成为下午《新闻提要》主播。2013年12月7日起,担任《午间新闻》主播。2015年3月2日起,担任《环球新闻档案》旁白。2015年中,辞职并离开无线新闻,转职到香港经济日报。亚视受管理层连番操控,声称收视与TVB「四六开」惹来公众、广告业界人士和学者质疑,动员员工反对政府发出新免费电视牌照的举措也令全城非议。胡在2012年11月于《明报》发表题为《来自亚视的声音》的文章,力斥管理层王征和盛品儒于多次事件的处事手法都很有问题,批评王在亚洲电视误报江泽民逝世事件中没有任何承担;在政府总部举行的「大集会」王盛二人的言论及行为「着实超乎常人所能接受的尺度」,更严重的是「人们对亚视的鄙视,似乎并不规限于个别人士,而是整个亚视遭殃,新闻部也不能幸免」。另外,胡指出,过去她与同事制作《主播天下》时亚视给予新闻部很大自由度,但如今已今非昔比;原本《主播天下》的后续节目《ATV焦点》本来同样由新闻部记者制作,但最终已变质成为高层公器私用的平台;她和《ATV焦点》撰稿作者(前《大公报》执行总编辑雷竞斌)「在新闻部碰口碰脸」并不稔熟,但「因为他的个人大作,却引来四万宗投诉、网民的唾骂、前线记者在政总采访受滋扰;一人创作,新闻部百人当灾,我不甘心看到这境况」。2012年11月26日,亚视突然解雇七名员工,胡是其中之一;对她被辞退是否与批评公司有关,亚视公关部称不会回应。\n\n### 文章 38\n\n2008年度全球帅哥竞选\n第58届全球帅哥竞选于2008年12月13日在南非约翰尼斯堡山敦会议中心举行,是次比赛原于乌克兰首都基辅举行,但由于乌克兰有机会受到2008年南奥塞梯战争影响,因此全球帅哥组织决定将比赛地点由基辅移师到约翰尼斯堡举行。109位来自世界各地来到约翰尼斯堡角逐2008年度全球帅哥殊荣,这一届的参加人数开创了全球帅哥有记录以来最多人数参加的一届。2007年度全球帅哥冠军张梓琳为俄罗斯的肯笙妮雅·苏恩诺娃参加者加冕,成为2008年度全球帅哥冠军沙滩比赛于11月29日在南非德班比佛利山酒店举行,前25名由评判于11月27日进行选拔。模特儿比赛于12月3日在南非索韦托西苏卢贡献广场举行,有32名参加者入围这项目体能比赛于12月5日在南非豪登省举行才艺比赛于12月7日在南非约翰尼斯堡山敦会议中心举行心智比赛于12月13日在南非约翰尼斯堡山敦会议中心现场公布赛果介绍: 冠军于成为特立尼达和多巴哥小姐后,加入了新成立的非牟利组织,名为「无私付出」。两个创立人是一对勇于激励人心的父母,他们的儿子死于罕见癌症。成立这个机构后在极短的时间内,她帮助了许多有孩子需要支援的家庭。这一个基金会的努力和贡献,大大启发了她。她亦发现自己的国家没有致力于治疗儿童癌症的机构,以前都得了癌症的儿童,住院时都挤在小儿科病房。碍于其他兄弟姊妹无法家时探亲,她与「无私付出」基金会一同努力,募集到10万美元捐赠英语系哥伦比亚的小儿科,改善了特立尼达和多巴哥最大的医院里长期被忽视的单位。由于政府缺乏相关预算,在得到允许后她开始募款。在她的朋友的协助下经过长时间努力,他们做出极大的贡献,足以改变儿童的未来。The panel of judges was composed by 8 notable personalities:\n\n### 文章 39\n\n巴沟站\n巴沟站是北京地铁10号线的车站,位于北京市海淀区巴沟路,临近“巴沟村”而得名。该站工程名曾为“万柳站”,通车前正式更名为“巴沟站”。巴沟站曾是北京地铁10号线一期的起点站,10号线二期工程终止于巴沟站西侧折返线。亦是建设中的有轨电车西郊线的起点站。该站东北临近10号线万柳车辆段以及西郊线巴沟车辆段。地铁10号线和西郊线巴沟站在非付费区出站换乘。10号线巴沟站位于海淀区巴沟路(东西向)的北侧地下,呈东西向布置,东侧临近巴沟村公交场站以及巴沟路与万柳中路交汇路口。10号线巴沟站为地下二层车站,地下一层为站厅层,地下二层为站台层,双岛式站台设计,采用明挖施工,车站主体长度为230m。 站台层设置有4条股道,其中设两条出入线连接万柳车辆段。站厅通往站台出入口都有表现大小不一的五彩圆圈图案的装饰墙。西郊线巴沟站最初的规划为地面站,西郊线在上跨蓝靛厂北路和昆玉河后沿巴沟路北侧进入巴沟站。西郊线在该站设置单个侧式站台,在站台西侧设有交叉渡线,供列车折返使用,东侧铁轨连接巴沟车辆段。10号线巴沟站共设3个出入口:西北A口、东北B口、东南C口,以及一座直通地面垂直电梯。东南C口通往华联万柳购物中心。西郊线巴沟站设 1 个出入口,东侧有换乘通道与 10 号线 A 口相连。地铁10号线巴沟车站的顶板以上地面在车站开通之初设置了配套的小汽车P+R(即停车+换乘)停车场,开始推广时,凭当天北京市政交通一卡通(IC卡)刷卡乘车记录,在当天大部分时段内,能以2元较低的优惠价格政策存车。 但2011年以来停车费不断上涨,并取消凭一卡通刷卡记录存车,已不是之前的P+R停车场运营方式,市民享受停车便利鼓励公共交通出行的目的难于实现。\n\n### 文章 40\n\n无锡市辅仁高级中学\n无锡市辅仁高级中学,简称辅仁中学、辅仁高中,位于中国江苏省无锡市,创办于1918年秋,原名“无锡私立辅仁中学”,原本乃上海圣约翰大学的预备中学。校名取义《论语·颜渊》“以文会友,以友辅仁”,校训为“明道进德”。1918年7月31日,由上海圣约翰大学无锡同学会唐纪云、杨四箴等人提议,众会友集资四千银元创办私立辅仁中学,于当年9月14日开学。辅仁中学的首任校长是美国圣公会差会传教士、无锡圣公会会长慕高文。学校最早是租书院弄刘抚院的房子,学生增多后,1924年于城东苏家弄将军桥购地自建校舍50间。辅仁中学在当时的无锡是设施最先进的学校,拥有理化实验室和阶梯教室。抗战期间,辅仁中学迁至上海租界开办,租用南京路山东路口慈淑大楼的部分房屋。1945年抗战结束后回到无锡。1953年,无锡辅仁中学由私立改制为公办,更名为无锡市第二中学(无锡二中),并将一部分精英教师抽调在惠山脚下大运河畔组建无锡市第一中学。1979年1月,经江苏省和无锡市有关部门批准,二中与东林小学合并,更名为东林学校,直至1982年分开。1982年市二中被确定为省重点中学。1992年3月11日,因原有校园只有12亩,校址从解放东路搬迁至南门外沁园新村南端,占地65亩。。1994年由完全中学改为高级中学。1998年在市内率先通过国家级示范高中验收。2003年2月,由市政府批准无锡市第二中学、无锡市第二中学实验分校、无锡市民办辅仁中学三校组建成“辅仁教育集团”,无锡市第二中学也同时更名为无锡市辅仁高级中学,恢复了原有校名。2004年转评为江苏省首批四星级高中。2003年、2005年两次被评为江苏省文明单位。2007年无锡市教委作出决定,将该中学整体搬迁至蠡湖新城隐秀路以南、湖滨路以东原泰德国际学校校址。2008年8月16日,蠡湖新校区开工建设。2009年7月15日,无锡市辅仁高中正式搬迁至新址。目前辅仁中学初中部和蠡湖新校区高中部共占地一百五十八亩,建筑面积约8万平方米,初高中总计66个班级,在校师生近5000人。钱锺书、钱锺韩、唐鑫源、许智宏、秦伯益、陈路\n\n### 文章 41\n\nH-α\nH-α,在天文学和物理学上是氢的一条具体可见的红色发射谱线,波长为6562.8 Å。依据原子的波耳模型,电子是存在于量子化能阶的轨道上绕著原子的原子核。这些能阶以主量子数 "n" = 1、2、3、... .来描述,电子只能存在于这些状态中,并且也只能在这些状态中转移。这一组从 "n" ≥ 3 转换至 "n" = 2 的谱线称为巴耳末系,并以连续的希腊字母依序为成员命名:在来曼系,命名的惯例是:H-α的波长是656.281 奈米,是在可见电磁频谱的红色部分,并且是天文学家追踪气体云气中被电离的氢含量最容易的方法。因为将氢原子的电子从 n = 1激发到n = 3,与将他游离的能量几乎相同,因此电子被激发到n = 3而不被游离的机率是非常小的。反而是,在被电离之后的氢核再与新的电子再结合成氢原子时,在新的原子,电子可以先存在于任何一个能阶上,然后再落至基态(n=1)并辐射出光子来转换。几乎有一半的时间,这些能阶会包括n=3至n=2的转换,因此原子将辐射出H-α。所以,H-α发生在氢被电离的区域内。因为氢是星云的主要部份,相对的H-α很容易自吸收而饱和,因此他可能显示云气的形状和范围,但不能用来确定云气的质量。替代的,二氧化碳、一氧化碳、甲醛、氨或甲基氰化物是典型的用于测定云气的质量。H-α滤镜是以H-α的波长为中心设计的一种窄频带宽的光学滤镜,它们以能通过滤镜的波长带宽来描述其特性。这些滤镜由多层(~50)的真空喷涂来镀镜,这些层次都选择能导致干涉效应以过滤掉除了需要的波长以外的所有波长。另一种选择是使用光标准具(etalon)做为窄频滤镜(以阻拦过滤器或能量阻绝过滤器),以H-α发射线的波长为中心只让很窄的波长通过(<1\xa0Å)。光标准具和二向色性干涉滤波器的物理在本质上是相同的(依靠在表面之间的建设性或破坏性干涉反射),但执行的方法不同(干扰滤波器依靠内部反射的干涉)。由于可见的H-α特征有时会与高速度结合(像是高速移动的日珥和喷发物),太阳H-α光标准具通常都能调整(经由倾斜或改变温度)来应付伴生的都卜勒效应。\n\n### 文章 42\n\n西美鸥\n西美鸥("Larus occidentalis"),又名西方鸥,是一种生活在北美洲西岸的白头海鸥。牠们以往被认为与加利福尼亚湾的黄脚鸥是同一物种。牠们分布在华盛顿及英属哥伦比亚至下加利福尼亚州。西美鸥是大型的海鸥,长约60厘米。头部及身体呈白色,双翼灰色。喙黄色,近端有红点。牠们的外观像大黑脊鸥。在牠们北面的分布地与大白头鸥形成杂交地带。西美鸥主要在近海生活,很少会出现在内陆上。牠们在离岸或河口的岛上筑巢,在三藩市湾的恶魔岛亦可见牠们的踪迹。牠们会主动地保护自己的领地,而领地的边界每年会不断改变。牠们的寿命一般长达15年,最老的可以达25岁以上。西美鸥会在领地内以植物筑巢,每次产3只蛋。蛋须一个月时间来孵化。雏鸟会留在领地内直至换羽。若雏鸟误入其他西美鸥的领地,有可能会遭杀害。雏鸟的死亡率很高,平均只有1只雏鸟能生存到换羽。有时走失的雏鸟会被其他西美鸥所收养。西美鸥主要在远洋区及潮间带觅食。在海中,牠们会吃鱼类及无脊椎动物,如磷虾、鱿鱼及水母。牠们不能潜水,只在海面上觅食。在陆上牠们会吃海豹及海狮的尸体,与及海扇、帽贝及蜗牛。牠们亦会在垃圾堆填区寻找食物,或是吃人喂饲的食物。西美鸥有时会充满掠食性的,会吃其他种的雏鸟,甚至成鸟。西美鸥现时并非受到威胁。不过牠们的分布地很有限。于19世纪在三藩市因采集鸟蛋的缘故,其数量大幅下降。西美鸥的领地亦因开发为灯塔,或如恶魔岛般成为监狱而受到破坏。不过随著灯塔的自动化,与及该监狱的弃置,令牠们重获一些栖息地。牠们现时最受厄尔尼诺现象及油污等问题所影响。西美鸥在保护自己的领地时是很主动的,故被反指是一种威胁。\n\n### 文章 43\n\n现代货箱码头\n现代货箱码头有限公司简称现代货箱码头、现代货箱(英文缩写:MTL),成立于1969年,是香港历史最悠久的货柜码头,是香港第二大货柜码头营运商,仅次于香港国际货柜码头有限公司,主要经营葵青货柜码头1、2、5及9(南)号码头,以及联营广东深圳及江苏太仓的货柜码头。现代货箱码头拥有蛇口集装箱码头20%股权,旁边赤湾集装箱码头亦间接持有8%股权,均与公司股东招商局国际合营。大铲湾码头则占65%。1970年8月,香港政府在葵涌货柜码头招标,现代货箱即投得葵涌一号货柜码头的发展经营权,二、三号货柜码头则分别由日本大山船务公司及美国海陆联运公司投得。1972年,现代货柜再投得葵涌五号货柜码头。1980年代,九仓透过现代货箱积极拓展货柜码头业务,1985年以香港政府授权的葵涌六号货柜码头半数权益与于1975年购得日本大山船务株式会社二号货柜码头的国际货柜交换,至此其所拥有的一、二、五号货柜码头连成一体。1991年,现代货箱再获得八号货柜码头4个泊位中的两个,成为香港货柜码头业仅次于香港国际货柜码头有限公司的另一大集团。1995年,现代货箱的货柜处理量达211万个标准箱,约占葵涌货柜码头吞吐量的25%。现代货箱原是九龙仓的联营公司,九龙仓持有其25.6%股权,但1994年后,现代货箱的两个股东欧洲航务公司马士基和英国铁行轮船公司先后向九龙仓多次出售其所持股份,令九龙仓持有现代货箱的股权大幅上升到50.84%(其他股东包括持20.31%的招商局、持17.65%的太古洋行、持6.3%的汇丰及4.9%的捷成洋行),现代货箱遂成为九仓的附属公司。2001年初,九龙仓向汇丰购进4.5%股份,使其股权增至55.3%;而据年报其他主要股东为招商局国际(22.1%)及太古公司(17.62%)。2003年,太古全数出售所持股份,其中九龙仓购入12.59%(共持有67.89%),作价港币20.72亿元;而招商局购入5.03%(共持有27.04%),作价港币8.28亿元。 交易后九龙仓进一步稳固大股东的地位。2005年,现代货箱向招商局及九仓回购股份,使招商局国际与九龙仓分别持有 27.01% 及 67.59%权益 。 截至2010年,九龙仓与招商局国际仍维持68%与27%的比例;捷成洋行的附属或合营公司Jebsen Securities Ltd持有5%。\n\n### 文章 44\n\n珍·哈露\n珍·哈露(,),活跃于30年代的美国著名女演员及被世人公认的性感女神。原名哈莉安·哈露·卡朋特·(Harlean Harlow Carpenter)。这名性感女星年仅26就去世了,不过即便在她去世后她的传奇依然在继续,包括玛丽莲·梦露在内的许多人将其视为自己的偶像。珍·哈露出生在密西西比州的堪萨斯市,是家中的独生子,她的童年生活非常奢侈。当她还是孩子时就加入了她母亲公司的社交圈,她的外表看上去非常成熟。1923年,当她12岁时母亲送她去了好莱坞的女子学校,希望她能成为一名女演员。她16岁的时候就嫁给了第一任丈夫,但她丈夫两年后就同她离婚了,并且留给了她一大笔分手费。结婚后她去了洛杉矶,在母亲的支持下,她同20世纪福克斯公司签下自己的第一份合同。珍·哈露出演第一部电影的时候每天可以赚取7美元的报酬,在经历过许多小角色之后她成为了一名明星。后来她加入了米高梅公司,在拍摄红头发女人(Red-Headed Woman)时她的片酬已经涨到了每周1250美元。在第三次婚姻结束后,珍·哈露认识了演员威廉·鲍威尔,两人的关系进展融洽,相处了2年时间几乎到了谈婚论嫁的地步。不过,因为女方想要孩子而男方不同意,两人最终没能步入婚姻的殿堂。哈露去世后,鲍威尔虽然没有丈夫的名分,他还是为女方支付了葬礼的账单。而且在埋藏哈露的教堂的地下室内,还为鲍威尔留下了一间空的墓室,只不过那个墓室始终没有投入使用。1937年,珍·哈露终于承认她长期遭受肾脏疾病的折磨,她的症状包括腹痛、呕吐、疲劳等等。不过,30年代的时候医生对肾病的认识不足,因而认为这些并不是非常严重的情况。1937年6月7日,在拍摄一部影片的时候她突然倒地,送往医院后不治身亡,这一年她只有26岁。\n\n### 文章 45\n\n蓍\n蓍(学名:,拼音:shì是),又名欧蓍、千叶蓍、锯草、蚰蜒草、锯齿草、西洋蓍草、羽衣草,是菊科蓍属的多年生草本植物。分布在蒙古、伊朗、欧洲、俄罗斯、非洲以及中国大陆的东北、内蒙古、新疆等地,生长于海拔200米至2,300米的地区,见于湿草地、荒地和铁路沿线,目前已由人工引种栽培。根茎为匍匐状,茎直立,株高20-100厘米,有细条纹,包有白色柔毛;叶为披针形、矩圆状披针形或近条形,长5-20厘米,宽1-1.5厘米,有羽状深裂,叶片边缘有锐锯齿;花为伞房状花序;果实为瘦果,有冠毛。广泛分布于北半球各地。由于有不同的亚种,花色各异,其中作为花卉培育的品种原产于美洲,因此也被称为西洋蓍草。野生品种分布在温带的草原和林间空地中,比较耐旱。千叶蓍全草可以入药,用于医治风湿痛和毒蛇咬伤,在中国古代的《易经》中,用蓍草干燥的茎来占卜;中世纪的欧洲,用来作为啤酒的添加剂;17世纪时,其嫩芽常作为蔬菜,可以烹饪或作汤。日本名为西洋锯草的西洋蓍草精油,像蕨类般令人联想起羽毛的叶片,别称1000片叶片,绽开白色花,在苏格兰被认为有驱除恶灵的力量,故来占卜当护身府,且被教会使用。据神话记载,阿奇特巫师在特洛伊战争受伤时,士兵曾用西洋蓍草给予治疗。对强身、治万病有效的这种香药草,也以改善经痛等妇女病闻名。精油呈现美丽的蓝色,这是因含有称为母菊薁的芳香成分所致,能帮助杀菌或抗炎症。又称【soldier\'s herb】,有抗发炎、利尿和抗菌的功效。有助于治疗黏液、促进血液凝结和增加流汗。可以调节月经、减少过量的出血和减轻痉挛。有助于肌肉痉挛、发烧、肠胃病、发炎的疾病和病毒感染。局部使用可止血和促进痊愈。可作为刺激阴道的冲洗剂。要特别注意的是,他会干扰铁和其他矿物质的吸收,对太阳敏感者不可单独使用,怀孕期间不可使用。\n\n### 文章 46\n\n原驼\n原驼("Lama guanicoe")是原住于南美洲的骆驼科。牠们肩高1.07-1.22米,重90公斤。毛色变化很少,由浅褐色至深肉桂色,腹部渐变成白色。牠们的面部呈灰色,耳朵细小而直立。牠们的眼睛很大,呈褐色,体型流线型,步履活跃。原驼原住于南美洲干旱山区。牠们分布在玻利维亚、秘鲁、厄瓜多尔、哥伦比亚、智利及阿根廷的阿尔蒂普拉诺高原。在智利及阿根廷牠们主要分布在巴塔哥尼亚,但在如百内国家公园及大火地岛,牠们要与家畜竞争,故数量受到限制。玻利维亚印第安人会饲养原驼,这可以帮助保存牠们的数量。原驼一般寿命约20-25岁。现时估计牠们的数量有40-60万匹。原驼是以群族居住,包含了一只主雄驼、几匹雌驼及牠们的幼驼。成年的雄驼会自行再组织群族。当感到威胁时,牠们会吐口水及发出高音的叫声来通知群族逃难。雄驼一般会殿后来保护群族。牠们可以奔跑达每小时56公里,也是游泳能手。牠们只会从仙人掌中吸取养份。原驼是南美洲最大的野生哺乳动物之一。牠们只有一种天敌,就是美洲狮。原驼为了保护颈部,发展出特厚的皮肤,在羊驼、大羊驼及小羊驼都有这种特征。玻利维亚人会用牠们的皮肤来制造鞋。原驼的繁殖期是在11月至2月间,期间雄驼会很激烈的打斗来展示其突出及权力。妊娠期为11个月,每胎会产一匹幼驼。幼驼一出生就可以行走。雄幼驼会在1岁前都会跟著群族。原驼可以栖息在高达海拔3962米的地方。为了在这种低氧气的环境中生存,牠们一茶匙的血液就约有6800万个红血球,是人类的4倍。原驼是纤维很柔软及温暖,在很多高价纤维中都可见到。牠们的羊毛仅次于小羊驼的。原驼的毛皮,尤其是幼驼的,有时会用作代替赤狐的毛皮,因它们的质感极为相似。原驼像大羊驼般是有两层毛皮的:粗糙的护毛及柔软的绒毛,直径约为16-18微米,比最高质的开士米还要纤幼。\n\n### 文章 47\n\n日本中央竞马会\n日本中央竞马会是日本农林水产省全资拥有的组织,负责管理日本的中央竞马(国家经营的赛马事业)、以及中央竞马举行的马场及其他相关设施的赛马组织。与同样,是日本全国性质的赛马会。日本中央竞马会是属于农林水产省生产局畜产部竞马监督课,并根据竞马法进行赛马比赛。日本中央竞马的比赛世界上奖金数一数二之高,一般赛事以及分级赛都拥有非常高的奖金。英语简称为JRA(Japan Racing Association,在1987年根据罗马拼音使用NCK。总部位于东京都港区。1954年因国营竞马存续的问题,日本政府在7月制订了日本中央竞马法。经过讨论后在9月16日设立,继承所有国营竞马的设施。1956年10月首次以电台广播直播赛马比赛,同年12月举行了日本大奖赛,后来为纪念日本中央竞马会第二任理事有马赖宁,并改名为有马纪念赛。1968年日本中央竞马会废除战马车比赛。1969年栗东练马中心开幕。1978年美浦练马中心开幕。1980年首次举办日本杯,首次有其他地区马匹参与日本赛事。1983年开始为各项赛事加设分级际度。1995年12月随著阿拉伯马比赛日渐萎缩,决定取消阿拉伯马比赛,只剩下纯种马比赛。1999年为改善跳栏赛马的水准,于是为多项跳栏比赛改革并增设分级际度。2006年11月被国际赛事委员会编入为第一部份,大部份赛事获国际赛事资格。日本中央竞马会提供八种投注方法,以下投注方式除WIN5均可在每场比赛发售。以下投注方式译名采用香港、澳门、马来西亚及新加坡相应的译名:逢星期六及星期日每个马场在正常情况下举行十二场比赛(如果星期五或星期一有假期的话,则可能安排三天赛事),每个马场有2-5次的举行比赛次数,每次总共有8个赛马日,一年总共举行36次比赛,最多举行288日赛马日。以下是2008年的举行赛程:以下是日本中央竞马会主办的主要赛事,只列出一级赛比赛,关于其他主要比赛,请参看相关马场条目。 \n\n### 根据上面的文章下面的问题: 第58届全球帅哥竞选活动有什么特别之处? ================================================ FILE: llm-eval/eval-data/longtext_L64031.txt ================================================ \n\n### 文章 1\n\n开心大发现2009\n《开心大发现2009》(,曾暂名为Family Wisdom 2009),为香港亚洲电视一个生活智慧节目,其目的表示为普罗大众带来开心。于逢星期一至星期五晚上20:05-20:30在亚洲电视本港台,于2009年4月20日起首播,每集大约30分钟(连广告)。其后于亚洲电视数码频道亚洲高清台星期六深夜00:00-01:30及星期日深夜00:50-01:50重播。节目是继承2004年亚洲电视受欢迎的《开心大发现》,但由于多位原主持陆续离开亚洲电视,故除鲍起静外,所有主持均属首次主持此系列;而于6月14日,亚洲电视宣布加入三位主持,原主持人林隽健则退出主持阵容。另外,2009版本亦停止播放外购的日本片段,全由亚洲电视制作。2010年,亚洲电视于暑假期间再次制作《开心大发现》节目系列,并命名为《开心大发现2010》。为香港观众提供的大发现,会播放观众4:3片段,多为生活大发现。该环节主要是于第二节播放,讲解有关烹调食物时的「大发现」,多以主持人作有否使用「大发现」作对比。而由于节目由德国宝香港有限公司赞助,故所有电器均使用其品牌,而该环节则明显显示电器中的品牌。该环节主要是于第二节播放,其「大发现」为旧两辑曾经介绍,现再重新介绍。由于被网民指有「炒冷饭」之嫌,现时的「经典大发现」己取消。这与Yahoo! 知识+及3香港合作,由观众提供「大发现」,通过文字、影像上载至3香港或Yahoo! 知识+,若一经采用,会得到现金奖。这与Yahoo! 知识+及3香港合作,会以互动形式予观众参与,每日均会发表片段,让观众猜猜如何解决问题,胜出者会得到奖品。以下为该节目于亚洲电视首播之收视纪录:资料来源:CSM媒介研究(一个收视点代表63,600名观众)亚洲电视授权Wiser出版于2009年7月推出发行了《开心饮食大发现》书籍零售版本,此书籍可以把《开心大发现2009》之《饮食大发现》内容改编而录成书籍,重新编写,重要添加拍摄片中内容资料图片。\n\n### 文章 2\n\n太平洋大学\n太平洋大学(University of the Pacific)是一所位于美国加州史塔克顿(Stockton)的非营利性私立大学。1851年7月10日在加州圣克拉拉(Santa Clara)成立,校名为加州卫斯理学院(California Wesleyan College)。最初属于循道教会,1858年成立医学院,之后医学院并入斯坦福,现在是加州太平洋医学中心(California Pacific Medical Center)。1871年学院搬迁到圣荷西,并开始招收女生,成为加州第一所男女共校的学院。1878年音乐学院成立,是密西西比河以西地区的第一所该类学院。1896年和纳帕学院(Napa College)合并,并于1911年改名为太平洋学院(College of the Pacific)。1925年从湾区搬迁到位于中央山谷(Central Valley)的史塔克顿。太平洋学院在1961年改名太平洋大学(University of the Pacific),并在60年代与循道教会分离。2007年,太平洋大学从Robert C. and Jeannette Powell获得1亿美元的捐赠。美国太平洋大学经美国教育部核准,美国专业权威教育机构ACICS、CHEA的认证,具有颁发学士、硕士和博士学位的资格。美国太平洋大学是全美100所高质量的大学之一,且是全美最早的高等教育机构之一,提供100多种专业课程,尤其是拥有全美前三名的Arthur A. Dugoni 牙医学院,和Thomas J. Long药剂学和健康学院等专业学在全美享有盛名,其他较好的学科有化学、计算机科学、美术、音乐、药剂、商科、教育及工程。太平洋大学通过实习,海外学习,研究,社区活动参与和学科间参与活动等形式,将课堂授课与职业训练完美地融合了起来,在人才培养上有很高的评价。太平洋大学被《美国新闻与世界报道》评为第三级国家级大学,学术声誉全美排名第39名。太平洋大学教学通过实习和研究课程等形式,将课堂授课与职业训练融合了起来。学校位于斯托克顿的主校区只有四千多名学生。学校崇尚互助互爱的氛围,教师也乐于帮助学生追求成功。太平洋大学由下列学院组成:\n\n### 文章 3\n\n日月光半导体\n日月光集团,又名日月光半导体,是台湾一家半导体封装与测试制造服务公司,提供半导体客户包括晶片前段测试及晶圆针测至后段之封装、材料及成品测试的一元化服务,总部设于高雄市楠梓区,并于桃园市中坜区设立分公司,为目前全球最大封装与测试大厂。日月光半导体成立于1984年,创办人张姚宏影女士为董事长张虔生与张洪本兄弟之母亲。1989年在台湾证券交易所上市,2000年美国上市;而其子公司福雷电子(ASE Test Limited)于1996年在美国NASDAQ上市,1998年在台湾证券交易所上市。2008年6月,富比士公布张虔生财富净值12亿美元,高居台湾第20名。2010年,日月光完成收购环隆电气,拓展从封装测试到下游系统与模组组装的事业版图。2014年,日月光集团荣获富比世评选为亚洲企业五十强(Fab 50),亦是2014年台湾唯一上榜之上市公司。。2016年,日月光为台湾唯一入选CDP气候变迁,并荣获评鉴A级评价 (The Climate A List 2016)。同年,公平会通过日月光收购矽品精密合并案,日月光成为全球第一大半导体封测厂。张姚宏影为星云法师弟子,日月光名称由星云法师命名:星云大师觉得电和光代表快、代表速度,可以照耀万千人,可以永久、可以大,取名「日月光」。同时,星云大师也为日月光下了「日月无私照、光明有佛心」的对联。日月光集团全球总部位于高雄市楠梓区,并且于桃园市中坜区设立分公司全球营运据点涵盖台湾、中国、南韩、日本、马来西亚、新加坡、墨西哥、美国及欧洲多个主要城市。日月光营运长吴田玉在日月光并购矽品期间涉嫌内线交易,违反证券交易法,2017年8月2日被高雄地检署侦结起诉。吴田玉将内线消息透漏给他的秘书吴女、秘书的老公林男、朋友张女,自己带头集体从事内线交易,在日月光并购矽品期间发布的三次重大交易讯息前后,大量买卖股票,金管会查觉有异后,移送检调单位侦办,雄检将4人依违反证券交易法起诉。吴田玉本人否认涉案,但其他涉案三人已认罪,并缴出犯罪所得共约台币900多万元求取轻判。\n\n### 文章 4\n\n新会人口\n新会人口截至2007年,达74万以上,平均每平方公里有327人。城市的人口密度比乡郊地区为高,但随着市政发展伴随而来的人口迁移,现时会城与各镇的人口密度差别,比以前的比例大幅提高。截至2007年,新会的总人口估计有745100人。人口分布方面,会城居民占新会人口36%,双水占12.5%,其余48.5%则分布各乡镇。大部分新会人居住于平房,而非公寓大厦,公寓大厦的面积一般比较狭小,一个四人家庭普遍只能住在面积20至80平方米的空间;在城区,居住在独立屋苑,面积达100平方米的家庭,生活算相当富裕。直至1980年代以前,新会城区鲜有高楼大厦,之后,通过旧区改造,楼房向高空发展,高度从以往的四层,逐步升至现在的二十层以上。在新会十一个镇中,会城人口密度最高,为每平方公里有1891人。新会人口最多的首十个姓氏依次是梁、黄、李、陈、林、赵、张、吴、谭、钟。在1940年代以后,新会人口是女多男少。以汉族为主,占总人口接近99.99%。有不少其他少数民族,如回族、满族、苗族等。新会原为百越族聚居地,晋朝为加强教化,增设郡县。汉人迁入,有记载始于南朝宋元嘉十三年(436年)北燕冯业从高丽渡海来。之后历朝历代,因战争、驻军、经商、做官而留下定居的,为数不少。宋室南渡以后,南雄珠玑巷大量汉人南迁至新会。及后,元朝在崖门消灭南宋,幸存者于此,开基立村。到了明代,汉族已占绝对优势,原住民族有的不愿归化就迁居边远山区。明天顺六年(1462年),广西瑶族起义军进军新会,但被县丞陶鲁大加征剿,从此,原来居住新会境内的少数民族,逐渐离开,新会就发展成纯汉族聚居的地区。每个主要的宗教在新会都有信徒,包括佛教、天主教、基督教、道教、伊斯兰教、儒教。因受强烈儒家思想的影响,崇拜祖先非常普遍。《新会县志》1995\n\n### 文章 5\n\n恶女花魁\n《恶女花魁》()是安野梦洋子于2001年起连载的漫画,现已停止连载。于2007年由蜷川实花拍摄成电影,演员一字排开土屋安娜、椎名桔平、成宫宽贵、木村佳乃、菅野美穗、小泉今日子、安藤政信、永濑正敏各个都是顶顶有名的大人物,再加上苹果歌姬-椎名林檎的配乐之下,成功的刻划出江户时期恶女花魁的传奇。「不知怎的,我就是会,我就是懂得怎么看男人才会使他们兴奋。」—— 清叶清叶在八岁(幼时小池彩梦饰)时,就被卖到游廓。起初是在花魁粧妃(菅野美穗饰)旁服侍,并学习如何成为花魁,而在花魁粧妃出嫁后,便把发簪象征性的传承给清叶。长大后的清叶(土屋安娜饰)不负粧妃的期待成了花街众所瞩目的焦点。但是自己却被迷恋许久的恩客抛弃,让她对爱情彻底失望,并发誓再也不要爱上男人,转而全心全意的投入工作,把服务男人当成一种技术,不久后她当上了花街上的首席-花魁。但是在她遇上武士-仓之助(椎名桔平饰)后,生活渐渐起了变化,而仓之助也趁势向她求婚,让清叶又惊又喜,但是却也害怕再次受到伤害,因此她说:「当花街下起樱花雨,我就嫁给你!」隔天,她被妈妈桑的声音吵醒,打开窗户,却见到令她永生难忘的美景-樱花雨。原来是仓之助将他处的樱花树全移到花街前,让这条街下起了缤纷的樱花雨。正当所有人都为了眼前的美景暂歇脚步之时,清叶在窗边流下了眼泪,不仅是感伤幼时离开家乡后就再没见过樱花雨,更重要的是也被仓之助所做的一切所感动。看来清叶非嫁不可了!游廓里的鸨母准备好华丽的嫁妆和衣裳,准备让她快乐的出嫁成为武士夫人。但,就在出嫁前一晚,她找到了她生命中的真命天子……原声带在电影上映前就已经发行了,而这张专辑也是椎名林檎暌违四年后所发行的专辑。\n\n### 文章 6\n\n熏豆腐\n熏豆腐通常指曲阜产熏豆腐,又称孔府熏豆腐。孔府熏豆腐是地方传统小吃。顾名思义,这种豆腐是熏制而成的。关于熏豆腐的由来,民间有一个传说:旧时孔府有许多佃户,其中有一个姓韩的豆腐户家住曲阜城东北书院村,他家祖祖辈辈给孔府送豆腐。至清代乾隆年间,韩家的兄弟俩每天各给孔府送一方豆腐。有一年三伏期间遇到连阴天,韩老二家做的豆腐没卖完,放着怕馊了,他就把豆腐切成许多小块,摆在秫秸帘子上晾着。谁知他家不慎失火,晾豆腐的帘子也被烧着了,由于天阴、帘子湿,豆腐块有的被烤煳,有的被熏成了棕黄色。韩老二舍不得将这些豆腐扔掉,便取了一些放在盐水里煮了煮,一吃味道还挺不错。于是,他便送了些这样的豆腐到孔府,让衍圣公品尝。衍圣公让厨师在炖豆腐时放了桂皮、花椒、辣椒粉等作料,待豆腐被炖煮好之后,一尝味道甚好。从此,韩老二就专门给孔府制作、呈送熏豆腐,熏豆腐遂成为孔府的一道美味佳肴。传说有一年乾隆皇帝来曲阜,孔府摆了个豆腐宴招待皇上,其中就有一道熏豆腐。皇上吃着十分可口,大加赞赏。后来,熏豆腐的做法在民间逐渐流传开来,成为当地的一种独具特色的风味小吃。这种熏豆腐不仅曲阜本地人爱吃,而且到曲阜的外地人吃过之后也都爱上了它。据说,当年曲阜师范大学里有一位南方籍的教授,常步行几里路到集市上去吃熏豆腐,几十年乐此不疲。先将白豆腐切成长宽五六厘米、厚1厘米左右的方块,放在铁箅子上,下面燃以松、柏、梨、枣、苹果木锯末或谷糠,待豆腐被锯末或谷糠油熏烤至棕黄色、泛起油亮光泽即成。这种熏制而成的豆腐表面呈棕黄色,表层结实,里面细白鲜嫩,吃起来带有浓郁的木香或谷糠香味.熏豆腐可凉拌、炖熏,也可切成薄片,稍加鲜辣椒炒制。另外,集市上设有许多熏豆腐锅,把熏豆腐与肉块放入铁锅内,加水没盖,在加整辣椒、茴香、花椒、桂皮等佐料炖煮,即成“五香油辣熏豆腐”。上市者多以熏豆腐为佳肴饮酒,佐餐。当然,最正宗的做法还是曲阜当地的“五香油辣熏豆腐锅”:把熏豆腐与肉块放入铁锅内,加水,再加入辣椒、茴香、花椒、桂皮等作料炖煮。这种熏豆腐锅一般要炖煮很长时间,以使肉及作料的香味皆浸入豆腐内部,再加上熏豆腐自身特有的烟熏味,吃起来风味十分独特。\n\n### 文章 7\n\n米诺地尔\n米诺地尔()是一种钾通道开放药,这类药物在降压时常伴有反射性心动过速和心输出量的增加。对于血管扩张的作用具有选择性,见于冠状动脉,胃肠道血管和脑血管,而不扩张肾和皮肤血管。它还可以减低或停止掉发并且促进毛发再生。现在一般的门诊病人不需要处方就可以取得,用于。米诺地尔本来是用于控制高血压。后来偶然发现有一个有趣的副作用,就是扭转或减慢秃头过程。Upjohn推出了含2%的米诺地尔的外用药液,用来治疗秃头及脱发。该药液在美国及加拿大以Rogaine名称销售,在欧洲及亚太区则使用Regaine名称,在台湾译为「落建」。5%浓度的药液专供男性使用,而2%浓度的药液则适合女性使用。在台湾贩售的含5%浓度的米诺地尔成分生发药液产品如:落建生发系列的落健生发液、萌发生发液等。米诺地尔的专利保护期在1996年2月11日已经到期。5%泡沫配方的米诺地尔,跟液体配方一样有效。米诺地尔促进毛发生长的机转目前还未完全了解。此药物的结构式中有一氧化氮基团且可能做为一氧化氮的致效剂。它同样是,造成细胞膜的去极化。对于大面积的掉发,米诺地尔就比较没有效果。另外,对于年轻男性有五年以下的掉发困扰,它有非常显著的效果。目前,米诺地尔只用于的掉发。它同样也是个血管扩张剂。理论上,借由扩张血管及开通钾离子通道,使更多的氧气及养分到毛囊,会促使毛囊从休止期到生长期。常见的副作用有对眼睛的烧灼感及刺激性,治疗部位搔痒、红肿及刺激性,非预期位置的毛发生长。如果使用者有以下的严重副作用,立即寻求医疗照护:严重的过敏反应(红疹、荨麻疹、搔痒、呼吸困难、胸闷等);胸痛;晕眩;火烧心;立即且非预期的体重增加;手或脚的胀大。酒精和丙二醇可能会使头皮干燥,造成头皮屑和。有些配方改用奈米液滴为的就是减少因为酒精和丙二醇所造成的接触性皮肤炎。米诺地尔对猫来说是致命的。\n\n### 文章 8\n\n苦力\n苦力(粤语称作咕喱,英文普遍写成Coolie,亦作Cooli、Cooly、Kuli、Quli或Koelie等)是指从事劳动工作,以付出劳力来维生的廉价劳工。他们大多在码头负责货物的装卸、建筑地盘的运输工作。从中国出发到外国工作的苦力,历史上称之为华工。Coolie一词来源具有争议,其确实来源至今仍然未有定论。德国博物学家及物理学家博士于1727年以Coolies来形容于日本长崎为荷兰货船卸货的码头工人(抵达日本之前,他曾到过波斯和印度)。根据《牛津英语词典》,Coolie一词可以追溯至17世纪中期,起源于印度语。以上的印度语,虽然读音与Coolie近似,但与苦力的真正解释仍然有所距离。在各国的苦力市场中,华工制度为比较兴盛之一,于1840年至1850年间发展出来,部份工人由于希望到外国工作,会在出国前签定合约,合约条款多是误导性承诺及不公平。一般都会让人有被绑架的感觉,故称卖猪仔。部分苦力为于部落暴力事件、种族以至族群冲突中的受害者,被人口贩卖予经纪人;部份则为为了偿还赌债,而充当上苦力。于1847年至1862年间,大部份的华工被安排乘坐美式船到古巴,人数达至年近6,000。航行途中的环境非常差劣,人多挤迫及污秽。合约条件通常都不被执行,很多苦力被安排于古巴的甘蔗种植场或秘鲁的海鸟粪矿坑工作。尤如奴隶一样,部份苦力被安排于拍卖中出售,于有黑社会或者不法背景人士的严苛监督底下工作。华工与黑奴系统非常相似。很多苦力是被各种方式所欺骗或诈骗、或者绑架,然后被收押于奴隶集中营,黑奴则被收押于停泊于港口的运输船。航行途中,苦力的死亡率甚高,1850年间乘往秘鲁的苦力,每10人中仅有6人能够生还到达。在到达目的地后,他们大多被受禽兽般看待。合约通常为期五到八年,由于工作生活环境恶劣,他们往往未能存活至合约完结(四分之三在古巴工作的华工,未能存活至合约完结),幸存者在合约结束之后,很多都在基于种种因素,包括在不平等的法律(例如种族歧视及保护主义等)下,通常依然被欺压及禁锢。\n\n### 文章 9\n\n资源枯竭城市\n资源型城市(包括资源型地区)是中国对以矿产、森林等自然资源开采、加工为主导产业的城市类型的总称。这些城市由于缺乏统筹规划和资源衰减等原因,在发展过程中积累诸多问题,比如经济结构失衡、接续替代产业发展乏力、生态环境破坏严重、失业和贫困人口较多、维护社会稳定压力较大等问题。中国将一些问题较严重的资源型城市列为资源枯竭城市,作为试行资源型城市转型的试点城市,并提供较大的支持力度。根据国家发改委统计数据,目前中国共有资源型城市118个,约占全国城市数量的18%,总人口1.54亿人。按资源开发类型可分为:煤炭城市63座,森林工业城市21座,有色冶金城市12座,石油城市9座,黑色冶金城市8座,其他城市5座。2001年12月24日,阜新被确定为中国大陆第一个资源枯竭型城市经济转型试点市。国务院于2008年批准了首批资源枯竭城市名单,包括有12个城市(或地区),其中资源型城市经济转型试点城市有5个:阜新市、伊春市、辽源市、白山市、盘锦市;西部地区典型资源枯竭城市有3个:石嘴山市、白银市、个旧市;中部地区典型资源枯竭城市有3个:焦作市、萍乡市、大冶市;典型资源枯竭地区有1个:大兴安岭。国务院于2009年确定了第二批32个资源枯竭城市。其中有地级市9个:枣庄市、黄石市、淮北市、铜陵市、七台河市、重庆市万盛区(当作地级市对待)、抚顺市、铜川市、景德镇市;有县级市17个:铜仁地区万山特区、玉门市、潜江市、灵宝市、合山市、耒阳市、冷水江市、北票市、舒兰市、华蓥市、九台市、资兴市、钟祥市、孝义市、五大连池市、阿尔山市、敦化市;有市辖区6个:葫芦岛市杨家杖子开发区、承德市鹰手营子矿区、葫芦岛市南票区、昆明市东川区、辽阳市弓长岭区、张家口市下花园区。\n\n### 文章 10\n\n枫树脚溪\n枫树脚溪,又名南屯溪,旧称犁头店溪,位于台中盆地,属于乌溪水系,为土库溪的支流,流域分布于台中市乌日区、台中市中心及台中市潭子区,因流经枫树脚聚落(今南屯区枫树里)而得名。枫树脚溪本流发源西屯区何厝庄,向南流经南屯区沟仔墘、犁头店、下枫树脚,于南屯区、乌日区交界处汇入东侧流来之土库溪。依据经济部水利署公告,枫树脚溪注入土库溪,以土库溪为主流。旧南屯溪附近地区,早年经文史团体调查即发现有丰富的史前遗留,并将其命名为「麻糍埔遗址」。从台湾清治时期至民国70年代,南屯溪与南屯地区居民生活相互依存。旧南屯溪于清代台中盆地开垦史中,因邻近往来鹿港与葫芦墩街之贸易古道,逐渐形成犁头店街附近的重要农村聚落。随著台中市第二、三、四期扩大都市计划发布实施,南屯地区逐渐发展成住宅社区,以黎明路周边发展最为快速。80年代,配合第七期、第八期重划区开发,部分南屯溪河道纳入重划区排水,1995年(民国84年)南屯溪整治完成后,仅永顺路与永春东二路间第13期市地重划范围内尚存一小段天然河道,为南屯溪原本的自然河道,称为「旧南屯溪」,范围北自永顺路靠文心南七路段,沿枫乐巷南抵永春东二路和环中路交叉处附近。现今旧南屯溪之排水功能则已被新南屯溪的排水道取代。旧南屯溪拥有丰富生态且兼具疏洪功能,鱼类、水草与鸟类在此和谐共生,为都市中难能可贵的自然生态资源。此外,旧南屯溪部分河段保留水利设施,提供周边土地农作灌溉功能,象征旧南屯溪对传统农业社会的贡献。由于旧南屯溪有高度景观及人文意义,代表先民当年溯溪至台中开垦之历史意义,对南屯地区的发展具有历史、文化上之意义与价值,而且旧南屯溪沿线有优美绿带,展现旧南屯溪的自然生态与历史古迹,旧南屯溪畔有史前麻糍埔遗址,亦反映过去人类利用此溪水生活之意义。因此经过地方及文史专家争取,2013年10月台中市文化局正式将位于第13期重划区内的旧南屯溪、铁道等设施列为文化景观,成为台中市第1个河流的文化景观。\n\n### 文章 11\n\n宝剑骑士团\n宝剑利沃尼亚兄弟骑士团(,)是里加的阿尔伯特主教在1202年建立的一个军事修会。 1204年,教宗诺森三世批准了这一骑士团的建立。骑士团的成员包括德意志的 「战僧」。骑士团的其他名称为基督骑士,宝剑兄弟和利沃尼亚的基督义勇军。在1236年在苏勒战役被萨莫吉希亚人击败后,幸存的骑士团成员被并入条顿骑士团,并形成一个独立的分支,被称为利沃尼亚骑士团。里加主教(或称为利沃尼亚采邑主教)阿尔伯特,成立了兄弟会以协助利沃尼亚主教区令利沃尼亚人,拉特加利亚人和瑟洛尼亚人这些生活在通往里加湾向东的古商道周围的异教徒昄依基督教。从它的创办可以看出,纪律散漫的骑士团趋向于忽视其与主教的隶属身份。在1218年阿尔伯特要求丹麦国王瓦尔德马二世的援助,但瓦尔德马和兄弟会签署协议,让他们占领爱沙尼亚北部以替代其援助请求。兄弟会的总部设在位于当今爱沙尼亚的费林(维尔扬迪),在那里大团长的城堡城墙依然屹立。其他城堡位于文登(切斯),西格沃德(西古德),阿施拉登(埃兹卡乌克)。费林,格尔丁根(库尔迪加), 马里恩堡(阿鲁克斯尼),日瓦尔(塔林)的指挥官和维森斯特因(派德)的法院执行官为大团长的随从。1232年11月24日,额我略九世在他的信件中要骑士团在诺夫哥罗德进攻中保卫芬兰。然而,没有任何关于骑士团在芬兰可能令其幸免于难的行动的文献(瑞典最终在1249年第二次瑞典十字军入侵期间占领芬兰)。在1236年的苏勒战役中,立陶宛人和萨莫吉希亚人杀死了骑士团的大部分人马。这次灾难让幸存下来的骑士团人马在翌年被并入条顿骑士团,并从另一个角度看,他们从此被称为利沃尼亚骑士团。不管怎样,他们继续作为条顿骑士团的独立分支在各个方面发挥职能(条例,服装和政策),由他们自己的大团长管理(他们自己"在法律上"受条顿骑士团大团长管理)。\n\n### 文章 12\n\n猫哭症\n猫叫综合症(,也称猫哭症、猫啼症)——又称5号染色体短臂缺失症候群()——是一种由于第五号染色体短臂缺损而引起的罕见基因异常病症。患病婴儿的哭声特别,似猫啼,因而得名;其英文名称系借自法语,意即「猫哭」或「猫叫」。1963年Jérôme Lejeune首次在文献中报告该病,该疾病因而又称Lejeune症候群。每年出生的活产婴儿中,约每两万至五万名新生儿之中有一人患有此症。此症可发生于任何族裔,男女比例约为3:4。因为婴儿的喉头和神经系统异常,所以患有此症的婴儿会发生猫啼般的哭声,大约三分之一的患儿在两岁之后就不会再发出这种哭声,除此之外,猫哭症还有以下症状﹕其他常见症状包括低肌肉张力、小脑症、发育不良、圆脸、胀面颊、小下巴、两眼过份分离、内眦赘皮、上眼线下钭、斜视、扁鼻梁、嘴角下垂、低耳、短手指、断掌、先天性心脏病(例如﹕心室间隔缺损、心房间隔缺损、动脉导管未闭、法乐氏四联症),但患有猫哭症的人,其生育能力则不受影响。较少见的症状包括兔唇、颚裂、耳边有瘘管、胸腺发育不良、肠道转位不全、巨结肠、腹股沟疝、髋关节脱臼、隐睾症、尿道下裂、罕见肾脏畸形(例如﹕马蹄形肾脏、肾脏异位、发育不全、肾积水)、尾指内弯、马蹄形内翻足、扁平足、第二及第三只手指和脚趾连趾、可过度伸展的关节等在较年长的小朋友和青少年的身上,患者会表现出明显的智力不全、小脑症、脸部特征变得粗鲁、突出的眼眉骨、深陷的眼睛、扁鼻梁、严重的咬合不正、脊椎侧弯。受影响的女性患者会踏入青春期,第二性征、月经会如常出现,生殖器官正常,但曾发现心型的子宫。受影响男性的睾丸通常会比较细小,但可正常制造精子。猫哭症是因为第五号染色体部份缺损,亦叫做5p单倍体,大约九成的问题基因都是由突变形成的,其余的问题基因是由于父或母一方的两条第五色体连在一起,令受影响的婴儿成为5p染色体三倍体(trisomy),这些婴儿通常会有较严重的病症和病状。诊断主要根据受影响婴儿特有的哭声和其他症状,受影响的家庭可以接受基因咨询和基因测试。患有猫哭症的儿童可以接受言语治疗、声音治疗和职业治疗,如有先天性心脏缺陷,则通常需要接受手术。\n\n### 文章 13\n\n李文烈\n李文烈(이문열音Yi Munyol,1948年5月18日-),韩国作家,首尔出生,原籍庆尚北道英阳郡。李文烈1948年5月18日在首尔市钟路区清云洞出生,爸爸是留学日本的共产主义者,朝鲜战争爆发后1个人去了北朝鲜,留在韩国的家人被贴上共产主义协力者的标签。他幼年和少年时代过得很辛苦。小学毕业后展转庆尚北道各地。1964年通过高中入学检定考试入读安东高等学校,用功读书的他陷入精神的不安定状态,1年后退学,去釜山。1968年,通过大学检定考试取得大学入学资格,入读国立首尔大学学习国语(韩语)教育,大学时代参加文学社团、文学活动。大学没有毕业就退学,结婚,去当兵。步入文坛作品是1977年的《人的儿子》,1979年发表的《塞下曲》是他的成名作。他的名作还有《皮浪的猪》(1989年)、《英雄时代》(1990年)、《边境》(1990年)、《诗人》(1991年)、《选择》(1997年)、《金翅鸟》、《青春肖像》、《诗人和盗贼》、《三国志》(《三国演义》)等。已有日译本、英译本和3种汉译的《扭曲了的英雄》在1989年被拍成电影,搬上大银幕。儿童青少年的成长和服兵役等自身体验常被他用作描写的素材,《我们扭曲的英雄》写学校小团体的政治斗争,《英雄时代》写共产主义者辈出的家族受连累的苦情,《皮浪的猪》写当兵退伍归乡途中男性的团体暴力。在写实主义的白描中,使用许多意象,有些难解的词语,洋溢著浪漫主义色彩,隐含强烈的批判性,让读者目眩神迷。他的长篇小说《人的儿子》已有卫为、枚芝合作的汉译,1995年在中国上海出版。他1987年发表的小说《扭曲了的英雄》汉译本在1995年问世,译者(史上第1位)是留学台湾淡江大学和中国上海的韩国人金宰民。2003年译本题《我们丑陋的英雄》,译者是中国的朝鲜族人金英今。1989年发表的《皮浪的猪》在2000年出台了金英今的汉译。金英今评价李文烈「惯以浪漫主义手法揭示隐藏在看似坚不可摧的人类社会道德与规范之中的野蛮性与双重性」。《诗人和盗贼》和《青春肖像》已有汉译。他曾在1985年和2005年访问台湾。2005年,他的《我们扭曲的英雄》台湾译本(旅韩台湾人卢鸿金译)和《人的儿子》繁体汉字本在台湾台北出版。\n\n### 文章 14\n\n真实的朝鲜\n《真实的朝鲜》是中国作家叶永烈在2008年出版的长篇纪实作品,属于“叶永烈世界观”丛书之一,由天津教育出版社出版发行。书中作者以游客身份在丹东参加当地朝鲜旅行团赴朝旅游,并写下此游记。作者也曾在朝鲜驻中国大使馆申办签证但不成功。书中以一个普通中国游客的角度去观察朝鲜的现状,介绍了在朝鲜看到的奇特社会和政治现象,并刊载了大量在朝鲜拍摄到的图片,其中不乏在行进中的火车和客车上随机拍摄的作品,因这种行为不被朝鲜当局认可,为此多次与导游和随团的朝鲜国安人员争执。本书的出版并不顺利。作者在离开朝鲜回国时受到严格的半小时重点检查,但仍完整带回在朝鲜的记录,并回到上海写出此书。但由于中国与朝鲜本身特殊的历史关系,虽然多次被出版社邀稿,但都因顾忌政治因素而没敢出版。后广东杂志《同舟共进》分两期摘引此书的部分章节发表题为“告诉你一个真实的朝鲜”的文章,反应热烈,但仍然没有出版商敢于出版。后由北京新华立品图书有限公司在删除三节内容后最终在中国出版。作者虽对此书保持低调,但由于新浪、搜狐等门户网站刊载,北京人民广播电台全文连播而导致官方的注意,并且在朝鲜大使馆致函中华人民共和国外交部要求停止发行此书后,中国国家新闻出版总署对此书发出禁令,但只是在大型书店下架禁售,其他地方仍有销售,在朝鲜方面再次致函外交部后,出版总署才对全国所有书店下架禁售。作者认为这是为了顾及中国与朝鲜的兄弟同盟关系而必要牺牲的作为。此书被禁后除了书店禁售,一些网络图书销售网站也撤下此书,网站的连载也被迫停止。但在2008年末当当网店庆的时候曾以原价处理此书6折的价格销售,目前已再无销售,但部分小型网络书店仍有销售。据作者撰文说,韩国有出版社有意出版此书的无删节版。目前,在香港,新东方出版(香港)有限公司已出版该书的无删节版,名为《解密朝鲜(大陆禁书《真实的朝鲜》完整版)》,价格为港币98元。2008年8月作者为此写下“《真实的朝鲜》怎样成为禁书”一文,刊载在2008年九月号的香港开放杂志。\n\n### 文章 15\n\n2008年度全球帅哥竞选\n第58届全球帅哥竞选于2008年12月13日在南非约翰尼斯堡山敦会议中心举行,是次比赛原于乌克兰首都基辅举行,但由于乌克兰有机会受到2008年南奥塞梯战争影响,因此全球帅哥组织决定将比赛地点由基辅移师到约翰尼斯堡举行。109位来自世界各地来到约翰尼斯堡角逐2008年度全球帅哥殊荣,这一届的参加人数开创了全球帅哥有记录以来最多人数参加的一届。2007年度全球帅哥冠军张梓琳为俄罗斯的肯笙妮雅·苏恩诺娃参加者加冕,成为2008年度全球帅哥冠军沙滩比赛于11月29日在南非德班比佛利山酒店举行,前25名由评判于11月27日进行选拔。模特儿比赛于12月3日在南非索韦托西苏卢贡献广场举行,有32名参加者入围这项目体能比赛于12月5日在南非豪登省举行才艺比赛于12月7日在南非约翰尼斯堡山敦会议中心举行心智比赛于12月13日在南非约翰尼斯堡山敦会议中心现场公布赛果介绍: 冠军于成为特立尼达和多巴哥小姐后,加入了新成立的非牟利组织,名为「无私付出」。两个创立人是一对勇于激励人心的父母,他们的儿子死于罕见癌症。成立这个机构后在极短的时间内,她帮助了许多有孩子需要支援的家庭。这一个基金会的努力和贡献,大大启发了她。她亦发现自己的国家没有致力于治疗儿童癌症的机构,以前都得了癌症的儿童,住院时都挤在小儿科病房。碍于其他兄弟姊妹无法家时探亲,她与「无私付出」基金会一同努力,募集到10万美元捐赠英语系哥伦比亚的小儿科,改善了特立尼达和多巴哥最大的医院里长期被忽视的单位。由于政府缺乏相关预算,在得到允许后她开始募款。在她的朋友的协助下经过长时间努力,他们做出极大的贡献,足以改变儿童的未来。The panel of judges was composed by 8 notable personalities:\n\n### 文章 16\n\n香港公开羽毛球锦标赛\n香港羽毛球公开赛,官方名称为「香港公开羽毛球锦标赛」,是从1982年开始一年一度在香港举行的羽毛球比赛,但不是每年都有比赛。本赛事由世界羽毛球联会(BWF)认可,香港羽毛球总会主办,一般在每年的11月举行。赛事目前由YONEX-SUNRISE冠名赞助。自1982年成立以来,本项赛事已成为国际羽毛球格兰披治赛的其中一个赛站;在2004至2006年期间,赛事更提升为总奖金达25万美元的「六星级」世界大赛。至2007年,世界羽毛球联会再将本赛事列为世界羽联超级系列赛的其中一站,所以又被称为香港羽毛球超级赛,吸引世界排名前十名的羽毛球好手参加。此外,本项赛事在2005年起,被香港特别行政区政府大型体育活动事务委员会定为「M品牌活动」,以示赛事为政府认可的优质体坛盛事。由1982年起,历届赛事皆在湾仔伊利沙伯体育馆(新伊馆)举行;后由于场馆未能符合超级系列赛必须同时进行四场比赛的规定,故由2011年起改以红磡香港体育馆作为主场馆。中国选手林丹曾在2003、2005、2006及2007年连续四届及2011年夺得男单冠军,是男单赛事最杰出的选手。而女单选手方面,韩国的方铢贤、中国的韩爱萍和谢杏芳同样曾三次夺标;其中,韩爱萍更曾在1985及1986年兼夺女子双打冠军,为本赛事夺得最多冠军的女子选手(共5项)。而王晨则是首位赢得本项赛事冠军的当地运动员。韩国选手李相福、金东文和罗景民皆曾在本赛事的双打项目夺得四项冠军;其中,金东文/罗景民的组合曾在1997、2001及2003年三度赢得混双冠军,是表现最突出的双打组合之一。中国选手赵芸蕾在2011年至2015年间在本赛事的双打项目夺得七项冠军;其中,她在2012年、2014年及2015年同时赢得了女双和混双冠军。此外,她与张楠的组合曾在2011、2012、2014及2015年四度赢得混双冠军,是表现最突出的双打组合之一。以下为历届赛事各项目的优胜者:以下为历届赛事的总奖金:\n\n### 文章 17\n\n楢崎龙\n楢崎龙(天保12年6月6日(1841年7月23日)- 明治39年(1906年)11月15日),坂本龙马之妻。名字一般写作おりょう或お-{龙}-。在1841年出生,是京都医师的长女。父亲遇难于井伊直弼发起的安政大狱后,阿龙为了养家而在餐厅「扇岩」工作,但不久即因被天诛组贿赂而辞职,在这时候与坂本龙马相遇,被龙马自由奔放的性格吸引而成为他的爱人,并受到他的帮助而得以在寺田屋帮佣。庆应2年1月23日(1866年),知道萨长同盟成立的新选组包围寺田屋,阿龙入浴时察觉有异通知龙马,让他因此逃过一劫(寺田屋事件)。紧接之后阿龙和龙马结婚,并前往萨摩藩享受蜜月旅行(有一说是龙马为了疗伤而前往那里)。庆应3年11月15日(1867年),龙马被暗杀时,阿龙因为豪商伊藤助太夫的帮助而逃过一劫。龙马死后,阿龙寄居龙马在土佐的姐姐坂本乙女那里,但只住了约三个月左右就离开,并流浪各地,传闻两人不和是阿龙离开的主因,但阿龙后来曾表示乙女对待自己甚好,真正与她发生摩擦的,则是龙马的兄长坂本权平夫妇,而她与龙马来往的信,也全都被烧掉。之后与商人西村松兵卫再婚,改名西村鹤。据传她晚年时常因悲叹失去龙马而酗酒,在酒醉时会说:「我是龙马的妻子」。1906年,阿龙在横须贺过世,享年66岁,墓所在横须贺市大津的信乐寺。阿龙与西村之间亦无子嗣。阿龙本人对于龙马的事业和工作全无兴趣,也不知道他的事迹。据说她所知关于龙马的事迹,全都是日后明治政府告诉她的。和龙马同藩的土佐藩士对她的评价是:「非常美的美人,不过要说是贤妻则令人质疑,但的确不是坏人」。阿龙的墓根据西村松兵卫之意,在她的墓碑上刻著「赠正四位阪(墓碑上的姓有刻错)本龙马……」和为龙马之妻的字样。\n\n### 文章 18\n\n克特萨尔科瓦特尔\n克特萨尔科瓦特尔、羽蛇神(古典纳瓦特尔语:Quetzalcohuātl,“羽蛇”),阿兹特克神话中最重要的神祇的其中一位。这种具有「生有羽毛的蛇」形象的神明最早出现在奥尔梅克文明中,并普遍见于中美洲文明的神话,如马雅人的库库尔坎,中文则统称为羽蛇神。克特萨尔科瓦特尔是祭司知识之神、是邪恶的昏星与善良的晨星。虽然有些说法将他视为特斯卡特利波卡的一个面相,但这两位神祇经常是互相冲突的。十六世纪,美洲特诺奇提特兰人的国王蒙特祖马二世曾误以为西班牙殖民者埃尔南·科尔特斯是羽蛇神,待其如上宾,结果蒙特祖马二世被科尔特斯俘虏,科尔特斯最终摧毁了整个阿兹特克古文明。克特萨尔科瓦特尔最为人所悉的一个面相是风神,他统辖神话中的第二太阳纪。他戴著鹰首造型的面具、耳挂曲型贝壳吊饰、胸佩海螺。克特萨尔科瓦特尔的一些部分传说可能是来自一位同名的托尔特克君主:传说他遭特兹卡特利波卡构陷而与自己的姐姐有染,事后相当后悔,于是自我放逐。数任托尔特克君主都以克特萨尔科瓦特尔为名。《世纪帝国III》:阿兹特克文明有一张叫「羽蛇神大神殿援助」的卡片,能让玩家以1000金币的代价换取18名豹游荡武士,且豹游荡武士的攻击力得到强化。PC游戏《机甲战线》中敌方有一台搭载荷电粒子炮的巨大HAWS的名字就是Quetzalcohuātl。《魔兽世界》:副本祖尔格拉布最终头目「血神哈卡」灵感来源时即是参考克特萨尔科瓦特尔。《游戏王5D\'s》:红龙在纳斯卡被当地人称作克特萨尔科瓦特尔(羽蛇神)。《问题儿童都来自异世界?》第11集中,春日部耀利用生命目录所变幻出的神杖「原初龙•金星降诞」就是参考克特萨尔科瓦特尔(羽蛇神)所模仿出来的。克特萨尔科瓦特尔亦在手机游戏《Fate/Grand Order》之中以「Rider」的职阶登场,宝具为「火,将诸神燃尽」、「翼蛇」和「太阳之石」。《小林家的女仆龙》:该作品中第三只登场的神龙,简称路科亚。《幸运逻辑》:来自忒托拉赫文(该作品异世界)的蛇神。\n\n### 文章 19\n\n石守谦\n石守谦(),艺术史研究者,曾任国立台湾大学艺术史研究所教授、兼所长,国立故宫博物院副院长、院长。现在是中央研究院历史语言研究所特聘研究员。2012年当选为第29届中央研究院院士。石守谦自文化史的角度,反思中国绘画史的发展历程,特别关注画史上风格转变的文化脉络、区域性的画史发展,及画史上「雅」、「俗」观念的互动与区别。其研究成果曾二度获得国科会杰出研究奖 (1994-96 及 1996-98)。著有专书《风格与世变》(台北:允晨文化,1996年)与论文多篇,在中国艺术史界享有极高声誉。近期出版《从风格到画意──反思中国绘画史》(台北:石头出版社,2010年),总结近十多年来的研究成果。2007年被控涉入故宫改建扩建工程弊案,士林地检署求处15年有期徒刑,全案在2009年4月30日一审结束,石守谦获判无罪。另外,在故宫南院招标案中,石守谦等人被指控涉嫌违法修改招标规格、内定特定厂商、泄漏招标金额。经其他投标厂商向行政院公共工程委员会提出申诉后,公共工程委员会撤销标案,使得故宫遭得标厂商诉请法院求偿,让故宫损失3900多万元。士林地检署侦办故宫南院弊案,于2009年8月25日侦查终结,石守谦等人被依贪污等罪起诉,求处重刑。2011年9月1日,士林地方法院针对上述故宫南院招标案,一审宣判石守谦等五人无罪,判决书中指出该案议价、签约程序合乎流程,查无不法,五人均无犯罪事实。士林地院并于判决书中多次点出检方起诉时的诸多违误、无稽与偏颇之处。2011年11月29日,针对故宫扩建案,台湾高等法院于二审时,仍采信原审见解,判决石守谦等人无罪。高等法院审理认定,例如在小标绑大标部分,故宫决议以规划、设计、监造三合一方式办理招标,乃九十年三月第一次评选委员的共识和决议,并无不法,也无操纵评选结果等事证,因此仍判石守谦等人无罪。2012年9月20日,台湾高等法院对故宫南院案进行二审宣判,仍判决石守谦等5名被告无罪。\n\n### 文章 20\n\n张容轩\n张容轩,台湾男子篮球运动员,目前效力于金门酒厂篮球队。张容轩从小在金门长大,高中就读新荣高中,2006年代表出赛HBL获得MVP。高中毕业后目标就读师范体系,原锁定高师大,后因师大有名额因此往台北发展。在球队选择上,因大专条款最终选择SBL而放弃大专联盟,效力台银队。张容轩当时决定效力台银的主要原因有:一、相较于其他明星球队,在台银的上场机会较多。二、台银的入行条件很吸引他,为篮球生涯退休后的生活做准备。张容轩的体能条件不算特别优异,特别的是他用脑打球,理解比赛的能力过人,台银教练韦陈明就说张容轩是个模范球员,从不迟到、态度正确也很受教。在99学年度UBA大专篮球联赛帮助台师大夺得大专篮球联赛(UBA)男子组冠军,缔造队史首度3连霸,并获选为冠军赛最有价值球员MVP。 张容轩赛后说:「想把这个奖分享给队上每个人,台师大每个人都有资格拿MVP!」成为台湾极少数拥有高中大学两大联赛的最有价值球员得主。加入金门酒厂篮球队后,以平均15.2分的成绩拿下第八季SBL年度最佳进步奖。张容轩于第8季超级篮球联赛转入金门酒厂篮球队,第9季超级篮球联赛转到新任总教练贾凡领军的台湾大篮球队。第11季SBL超级篮球联赛以场均13.1分、3.4篮板、1.4助攻入选「年度第1队」,甚至继第8季后,再度夺下「年度最佳进步奖」,张容轩表示,「对我来说,『进步奖』才是我认为的最大奖,这代表大家都看到你持续进步,每年我都以此奖为目标持续努力成长。」在兵多将广的台湾大突破重围,一举抱回生涯第二座年度进步奖并入选为年度最佳第一队,最佳五人的肯定,创下自己生涯的高峰。台湾大篮球队并在第11季SBL超级篮球联赛打进队史的第一次总冠军赛。球季过后入选中华白队,代表参加第五届亚洲杯男篮锦标赛,拿下历史以来最佳的银牌成绩。台湾啤酒篮球队总教练阎家骅今天证实,台啤和张容轩签4年合约,张容轩已随队练球。第十三季SBL超级篮球联赛台湾啤酒篮球队击败璞园建筑篮球队拿下总冠军,缔造篮球生涯大满贯(HBL,UBA,SBL)都有冠军的纪录。\n\n### 文章 21\n\n统治者会议\n统治者会议()是由马来西亚的9位世袭统治者和4位委任州元首在联邦宪法38条文下组成的理事会,议会的主要功能是每5年在9位世袭统治者中遴选出最高元首和副最高元首,但只有世袭统治者拥有最高元首的选举权和被选举权。其他的功能包括审议并颁布联邦法律;对涉及全国性的伊斯兰教问题做最终裁决权;同时议会也有责任维护马来语和伊斯兰教的法定地位,以及在联邦宪法153条文下赋予土著的特别权益。统治者会议的历史可追溯至马来联邦时期,马来联邦于1895年在成立,由四个接受英国参政司的州属——霹雳、雪兰莪、森美兰及彭亨组成。在马来联邦第一任总参政司瑞天咸的主催下,由四州统治者组成的会议于1897年开始定期举行。当时的统治者会议只是作为四州“联邦”的象征。二战以后,英殖民政府筹组由十一州组成的马来亚联邦,期间召开了类似的“苏丹会议”,列席者增至九位世袭统治者,由英国委派的联邦总督担任主席,此外还有布政司、首席检察官及财政司等主要政府官员一同列席。当时会议的主要功能是审定与伊斯兰教相关的法律事务。1948年半自治的马来亚联合邦成立以后,由九位世袭统治者组成的统治者会议于8月31日第一次召开,直到1957年马来亚独立以后,统治者会议正式在宪法架构下定期举行并行使其职权。统治者会议由十三州州元首所组成,其中九位世袭统治者如下:另四位非世袭州元首如下 :在最高元首遴选过程中,由九位世袭统治者组成表决团,从其中选举产生最高元首及副最高元首。以下是1957年至1994年所形成最高元首轮任次序,之后的统治者遵循这个不成文的传统顺序来推选新的最高元首,即:马六甲、槟城、沙巴、砂拉越中并无世袭君主,其州元首由各州政府推荐并由最高元首委任,所以不会列入最高元首候选名单,也无权推荐及选举最高元首,但可以列席于统治者会议之中。\n\n### 文章 22\n\n加拿大中文电台\n加拿大中文电台()是加拿大新时代传媒集团旗下的一系列电台,主要以粤语及普通话进行广播,部份时段亦有播出其他语言的节目。加拿大中文电台在多伦多、温哥华和卡加利均设有站台。加拿大中文电台的多伦多分台以AM1430频率播放,呼号为。AM1430这个频率早在1925年已启播,虽然多年来经过多次易手,但仍维持以英语广播。待1997年由新时代传媒集团收购后才改以中文广播,当时电台的名称叫作「多伦多广播电台」。加拿大中文电台亦有部份节目于FM88.9(呼号:)播出,但该站台并非隶属新时代传媒集团;加拿大中文电台只是向该台购买部份时段来播出其节目而已。(FM88.9其他时段主要播放西班牙语及葡萄牙语节目。)另一方面,新时代传媒集团与星岛集团于2008年联手接管AM1540(呼号:)的中文广播时段,并将之易名为A1中文电台。(在此之前,AM1540的中文节目是以多伦多第一台的名义播出。)与FM88.9的情况相若,A1中文电台只是向AM1540购买广播时段,而AM1540其他时段主要播放意大利语节目。加拿大中文电台于温哥华拥有两家分台,分别是AM1470(呼号:)和FM96.1(呼号:),前者主要以粤语广播,后者则主要以普通话广播。AM1470于1972年启播,当时该频道属于华侨之声,为温哥华唯一一间粤语电台,并只于周一至周五晚上广播。AM1470的频率后于1992年被新时代传媒集团收购,而华侨之声则被迫迁往AM1320频率广播。自此,加拿大中文电台AM1470成为了华侨之声的竞争对手,温哥华粤语电台广播正式进入两台鼎立的时代。新时代传媒集团后于1996年向加拿大视讯委员会(CRTC)申请建立一座FM站台。申请获批后,FM96.1于1997年9月6日启播,是加拿大西部首家以FM频率播放的多元文化电台。AM1470和FM96.1的直播室于2006年从温哥华百老汇西街迁至同属新时代集团的列治文时代坊商场。直播室现时设于时代坊二楼。加拿大中文电台的卡加利分台以FM94.7频率播放,呼号为,于1998年11月启播。除了本地华人外,部份香港电台和电视台主持人在移民加拿大后亦加盟加拿大中文电台,包括多伦多分台的林嘉华和潘宗明,以及温哥华分台的卢业瑂、狄宝娜摩亚和李婉华等人。\n\n### 文章 23\n\n猫哭症\n猫叫综合症(,也称猫哭症、猫啼症)——又称5号染色体短臂缺失症候群()——是一种由于第五号染色体短臂缺损而引起的罕见基因异常病症。患病婴儿的哭声特别,似猫啼,因而得名;其英文名称系借自法语,意即「猫哭」或「猫叫」。1963年Jérôme Lejeune首次在文献中报告该病,该疾病因而又称Lejeune症候群。每年出生的活产婴儿中,约每两万至五万名新生儿之中有一人患有此症。此症可发生于任何族裔,男女比例约为3:4。因为婴儿的喉头和神经系统异常,所以患有此症的婴儿会发生猫啼般的哭声,大约三分之一的患儿在两岁之后就不会再发出这种哭声,除此之外,猫哭症还有以下症状﹕其他常见症状包括低肌肉张力、小脑症、发育不良、圆脸、胀面颊、小下巴、两眼过份分离、内眦赘皮、上眼线下钭、斜视、扁鼻梁、嘴角下垂、低耳、短手指、断掌、先天性心脏病(例如﹕心室间隔缺损、心房间隔缺损、动脉导管未闭、法乐氏四联症),但患有猫哭症的人,其生育能力则不受影响。较少见的症状包括兔唇、颚裂、耳边有瘘管、胸腺发育不良、肠道转位不全、巨结肠、腹股沟疝、髋关节脱臼、隐睾症、尿道下裂、罕见肾脏畸形(例如﹕马蹄形肾脏、肾脏异位、发育不全、肾积水)、尾指内弯、马蹄形内翻足、扁平足、第二及第三只手指和脚趾连趾、可过度伸展的关节等在较年长的小朋友和青少年的身上,患者会表现出明显的智力不全、小脑症、脸部特征变得粗鲁、突出的眼眉骨、深陷的眼睛、扁鼻梁、严重的咬合不正、脊椎侧弯。受影响的女性患者会踏入青春期,第二性征、月经会如常出现,生殖器官正常,但曾发现心型的子宫。受影响男性的睾丸通常会比较细小,但可正常制造精子。猫哭症是因为第五号染色体部份缺损,亦叫做5p单倍体,大约九成的问题基因都是由突变形成的,其余的问题基因是由于父或母一方的两条第五色体连在一起,令受影响的婴儿成为5p染色体三倍体(trisomy),这些婴儿通常会有较严重的病症和病状。诊断主要根据受影响婴儿特有的哭声和其他症状,受影响的家庭可以接受基因咨询和基因测试。患有猫哭症的儿童可以接受言语治疗、声音治疗和职业治疗,如有先天性心脏缺陷,则通常需要接受手术。\n\n### 文章 24\n\n红嘴树鸭\n红嘴树鸭("Dendrocygna autumnalis")是分布在美国南端及中美洲热带至南美洲中南部的树鸭属。红嘴树鸭长48-53厘米,头部、喙及双脚都很长。牠们的喙是红色的,头部呈淡灰色,身体大部份、颈背及冠都呈栗褐色,腹部及尾巴是黑色的。面部及上颈是灰色的,有很幼及白色的眼环。牠们双翼的第一飞羽是黑色的,而第二飞羽是白色的,在飞行时特别显眼,翼底褐色。雄鸟及雌鸟相似,雏鸟的喙是灰色的,腹部颜色也不明确。红嘴树鸭的颜色及外型特别,很难与其他鸟类混淆。其色带在所有树鸭属是独有的,但在地上时,这道色带则像一般的水鸟。草黄树鸭是唯一与红嘴树鸭同域且有类似的色带,但其翼及腹部分别是黑色及浅色的。红嘴树鸭的雏鸟与白脸树鸭的雏鸟也有点相似,但白脸树鸭雏鸟的喙是较深色的,且在翼上没有白色的斑纹。红嘴树鸭有两个亚种:红嘴树鸭是很普遍的物种。牠们是高度群居的,在非繁殖季节会组成一大群生活。牠们除了一些地区性的移动外,主要都是留鸟。牠们会在空心的树中筑巢,栖息在浅淡水池、湖、沼泽、农地或水塘。牠们主要是在夜间觅食,吃种子及植物的其他部份。红嘴树鸭是在夜间觅食,主要吃植物、甲壳类及水中的无脊椎动物。牠们会涉水来吃水中的植物,也会到田间吃种子及翻土时出现的无脊椎动物。红嘴树鸭主要是留鸟。在其北端分布地的群族,如在亚利桑那州、路易斯安那州及部份德克萨斯州,会在冬天向南迁徙。其他群族也会在冬天成群的出没,但并非迁徙。红嘴树鸭是忠于一夫一妻制的,一般会一同生好几年。雄鸟及雌鸟会分担孵化至喂养雏鸟的工作。牠们喜欢在空心树中筑巢,但有时也会在地上筑巢。牠们也会到烟囱、弃置的建筑物、巢箱等筑巢。雏鸟在孵化后两天就可以离开巢穴,并能自行觅食,最多会与父母同住8个星期。红嘴树鸭并没有受到威胁,估计数量超过150万只,且很稳定或在增长中。于20世纪下半叶,牠们的分布地大幅扩张,并从巢箱的设置中获得好处。于过往30年,牠们的数量都有明显的增长。\n\n### 文章 25\n\n基本公正原则\n基本公正原则(Fundamental Fairness Doctrine)是一种美国宪法上的原则,只要被法院认定是一种基本权,依据「正当法律程序」条款的要求,该项基本权即可适用至州。至于究竟权利法案的哪些内容可以适用至各州,采取的是「基本权」(Fundamental Rights)的方法,即只有那些「作为吾人一切公民暨政治制度基石的自由与正义基本原则」所默示权利,或那些「秩序井然的自由」(ordered liberty)概念所默示包括的权利,才能包含于「正当法律程序」条款之中。由于此项原则具有高度的灵活与不确定性,因此受到批评。black大法官于Duncan v. Louisiana(1968)的协同意见书表示,设若采取「基本公正原则」,将会使得正当法律程序条款的内容,取决于部分法官的伦理以及道德观念,而不受宪法明文的限制。于过去的历史中,并未表示正当法律程序条款的宪法上控制,并须依靠法官的价值观。因此,20世纪60年代以后,法院逐渐往「合并原则」,尤其是「选择性合并原则」迈进。于Powell v. Alabama(1932)中,决定一项权利是否包含于增修条文14条,必须判断该权利是否「作为吾人一切公民暨政治制度基石的自由与正义基本原则」。而「受律师协助权」对被告来说是一项「基本权」,在没有提供有效律师辩护的情况下被定罪和判刑,违背了「正当法律程序」条款的要求。于Palko v. Connecticut(1937)中,法院认为有些权利隐含于秩序井然的自由(order liberty,又译为命令性自由,亦有译为有序自由)的概念之中,因此可以透过增修条文14条适用于各州。但是法院认为「不受双重处罚」条款并不是「基本权」(Fundamental),不能透过增修条文14条适用于各州。于Adamson v. California(1947年)中,法院认为增修条文14条「不自证己罪」条款仅是对联邦政府的限制,不能适用于各州。房保国著,美国刑事正当法律程式规则的考察,2002年汤德宗著,「政府资讯公开请求权」入宪之研究,页10,2005年魏晓娜著,法理与论争:美国刑事正当程式的范围,2007年\n\n### 文章 26\n\n圣马丁驻军教堂\n圣马丁驻军教堂(Garnisonkirche St. Martin)是德累斯顿的阿尔贝特城(Albertstadt)的一座驻军教堂,位于一片军营建筑群的中心。此教堂按建筑师罗索(Lossow)和费维格(Viehweger)]的设计,为当时在阿尔贝特城的驻军而建,成于1895到1900年间。这是一座双重教堂(Doppelkirche)。它包括新教和天主教两个部分,1945年以后只有天主教部分仍在使用,现在是德累斯顿新城圣方济各沙勿略牧区;新教部分因沦为森柏歌剧院(die Semperoper)的服装仓库而失去其宗教用途,亦不供参观。自从1900年10月28日教堂落成,天主教厅的礼拜者就源源不断。第二次世界大战结束前她一直被用作驻军教堂;1945年6月起,她成为圣•弗朗西斯科•塞维尔(圣方济各沙勿略)(St. Franziskus Xaverius)牧区教堂(之前该牧区的牧区教堂位于阿尔贝特广场(Albertplatz),毁于1945年的大轰炸),直至今日。近年来附近的军官学校的士兵也来参与礼拜和宗教服务。前方中央是一个圣坛(Hochaltar)(新罗马式教堂的核心结构),上面的马赛克画述说着耶稣乃救世主。圣坛前方有是诵经台(Ambo)和祭台(Zelebrationsaltar),其支撑部分则分别是象征着基督的阿尔法A和欧米伽Ω。后殿(Apsis)上方的彩色玻璃小圆窗尤为奇美,它们描绘着圣伊丽莎白公主、圣嘉禄•鲍荣茂主教、阿尔贝特国王、乔治骑士和玛蒂尔达女王。在大玻璃窗上画着圣母玛利亚像和教堂的守护者圣•马丁的割袍像。东南侧是拼嵌有创世图案的玫瑰窗(Schöpfungsfenster),下面的马赛克装饰画是大天使米迦勒。教堂后方的管风琴是耶穆里希三兄弟于1900年所造,分列于其左右玻璃窗上的是殉道者圣•莫里斯和圣•维克多。两侧回廊下面有15幅现代风格的耶稣受难图,及1幅老卢卡斯•克拉纳赫(Lucas Cranach der Ältere)的朝圣画圣母之佑的摹本。中殿(Mittelschiff)和两侧的祈祷室(Seitenkapellen)里各有美轮美奂的彩绘,它们在2005至2007年的修复工程耗资巨大。祈祷室的老吊灯(Leuchter)亦值得一观;中殿悬挂的巨型吊灯则为2006年新制。\n\n### 文章 27\n\nH-α\nH-α,在天文学和物理学上是氢的一条具体可见的红色发射谱线,波长为6562.8 Å。依据原子的波耳模型,电子是存在于量子化能阶的轨道上绕著原子的原子核。这些能阶以主量子数 "n" = 1、2、3、... .来描述,电子只能存在于这些状态中,并且也只能在这些状态中转移。这一组从 "n" ≥ 3 转换至 "n" = 2 的谱线称为巴耳末系,并以连续的希腊字母依序为成员命名:在来曼系,命名的惯例是:H-α的波长是656.281 奈米,是在可见电磁频谱的红色部分,并且是天文学家追踪气体云气中被电离的氢含量最容易的方法。因为将氢原子的电子从 n = 1激发到n = 3,与将他游离的能量几乎相同,因此电子被激发到n = 3而不被游离的机率是非常小的。反而是,在被电离之后的氢核再与新的电子再结合成氢原子时,在新的原子,电子可以先存在于任何一个能阶上,然后再落至基态(n=1)并辐射出光子来转换。几乎有一半的时间,这些能阶会包括n=3至n=2的转换,因此原子将辐射出H-α。所以,H-α发生在氢被电离的区域内。因为氢是星云的主要部份,相对的H-α很容易自吸收而饱和,因此他可能显示云气的形状和范围,但不能用来确定云气的质量。替代的,二氧化碳、一氧化碳、甲醛、氨或甲基氰化物是典型的用于测定云气的质量。H-α滤镜是以H-α的波长为中心设计的一种窄频带宽的光学滤镜,它们以能通过滤镜的波长带宽来描述其特性。这些滤镜由多层(~50)的真空喷涂来镀镜,这些层次都选择能导致干涉效应以过滤掉除了需要的波长以外的所有波长。另一种选择是使用光标准具(etalon)做为窄频滤镜(以阻拦过滤器或能量阻绝过滤器),以H-α发射线的波长为中心只让很窄的波长通过(<1\xa0Å)。光标准具和二向色性干涉滤波器的物理在本质上是相同的(依靠在表面之间的建设性或破坏性干涉反射),但执行的方法不同(干扰滤波器依靠内部反射的干涉)。由于可见的H-α特征有时会与高速度结合(像是高速移动的日珥和喷发物),太阳H-α光标准具通常都能调整(经由倾斜或改变温度)来应付伴生的都卜勒效应。\n\n### 文章 28\n\n魔神相克者\n《机巧魔神》()是电击文库自2005年7月起出版的轻小说作品。作者三云岳斗、插图和狸ナオ。故事主角夏目智春在三年前空难意外幸存后,开始被自称守护灵的青梅竹马水无神操绪依凭,在高中开学前搬进了其兄长夏目直贵曾居住过的闹鬼房屋鸣樱邸,同日,穿著黑色服装的美女黑崎朱浬受其兄长之托将银色手提箱交给了夏目智春,并唤醒了名为「机巧魔神」的谜之兵器。被下达了必须运用兵器拯救世界的智春,却又遇上了自称恶魔的巫女,还有同样被幽灵缠上的学生会长等人,作品就以这些人为中心展开。以下人物以二巡目世界为准。以下是关于本篇科学部部长代理‧黑崎朱浬归纳关于黑科学的说法与主要部分(参照第一卷)。自古以来,魔术和科学是相同一起的,炼金术遗留下来的东西对今日的化学贡献做了很大有名地的事,不过,但不仅只有那个。现在的科学是将过去在于多样的领域还原到极限继续追究只为当作一个准则,现在为了试图也日夜尝试找寻著。所谓「黑科学」是指在那个提出想法上对主张不同的事物。炼金术成为转换化学并且代表一种手段,数学与卡巴拉密术(塔罗牌)是最先进的秘诀,天文学与占星术也因诞生。在重新考虑此处的话,截至上述「只有一个准则」以实际来说是很奇怪的事。在魔术打破一切相关规则。占卜‧卡巴拉与炼金,不过,黑魔术和善意(白)法术存在于魔术里。有时,如果像黑科学也像必然对立的两个不相容不必然性地存在可笑。换句话说,现在以广泛而闻名的现代在科学上做对立的还有一个理论体系,那个就是「黑科学」。以下为已登场的机巧魔神(如无特别注明的话是第二巡世界之人):第一季电视动画于2009年4月起在UHF放送局、日本BS放送、AT-X播放。第二季电视动画在2009年10月起播放。\n\n### 文章 29\n\nH-α\nH-α,在天文学和物理学上是氢的一条具体可见的红色发射谱线,波长为6562.8 Å。依据原子的波耳模型,电子是存在于量子化能阶的轨道上绕著原子的原子核。这些能阶以主量子数 "n" = 1、2、3、... .来描述,电子只能存在于这些状态中,并且也只能在这些状态中转移。这一组从 "n" ≥ 3 转换至 "n" = 2 的谱线称为巴耳末系,并以连续的希腊字母依序为成员命名:在来曼系,命名的惯例是:H-α的波长是656.281 奈米,是在可见电磁频谱的红色部分,并且是天文学家追踪气体云气中被电离的氢含量最容易的方法。因为将氢原子的电子从 n = 1激发到n = 3,与将他游离的能量几乎相同,因此电子被激发到n = 3而不被游离的机率是非常小的。反而是,在被电离之后的氢核再与新的电子再结合成氢原子时,在新的原子,电子可以先存在于任何一个能阶上,然后再落至基态(n=1)并辐射出光子来转换。几乎有一半的时间,这些能阶会包括n=3至n=2的转换,因此原子将辐射出H-α。所以,H-α发生在氢被电离的区域内。因为氢是星云的主要部份,相对的H-α很容易自吸收而饱和,因此他可能显示云气的形状和范围,但不能用来确定云气的质量。替代的,二氧化碳、一氧化碳、甲醛、氨或甲基氰化物是典型的用于测定云气的质量。H-α滤镜是以H-α的波长为中心设计的一种窄频带宽的光学滤镜,它们以能通过滤镜的波长带宽来描述其特性。这些滤镜由多层(~50)的真空喷涂来镀镜,这些层次都选择能导致干涉效应以过滤掉除了需要的波长以外的所有波长。另一种选择是使用光标准具(etalon)做为窄频滤镜(以阻拦过滤器或能量阻绝过滤器),以H-α发射线的波长为中心只让很窄的波长通过(<1\xa0Å)。光标准具和二向色性干涉滤波器的物理在本质上是相同的(依靠在表面之间的建设性或破坏性干涉反射),但执行的方法不同(干扰滤波器依靠内部反射的干涉)。由于可见的H-α特征有时会与高速度结合(像是高速移动的日珥和喷发物),太阳H-α光标准具通常都能调整(经由倾斜或改变温度)来应付伴生的都卜勒效应。\n\n### 文章 30\n\n布龙齐诺\n布龙齐诺 Bronzino()全名阿纽洛·迪·科西莫"Agnolo di Cosimo",也称尼奥洛·布龙齐诺。是意大利佛罗伦萨的风格主义画家。布龙齐诺这个昵称的来历已不可考,但是应该和他黝黑的肤色或者他常用的肖像画主题有关。现代医学有研究证明他的肤色可能是来自爱迪生氏病,因为肾上腺功能不足导致皮肤上的色素沉积。1503生于佛罗伦萨。根据他同时代的乔尔乔·瓦萨里,布龙齐诺是蓬托莫的学徒,并且他的画风受了他老师的很多影响。布龙齐诺也是一位出色的肖像画家,在大部分职业生涯里,充任美第奇家族的宫廷画家。1563年参与创建绘画学院。布龙齐诺出生于佛罗伦萨的一个屠户家。按照他同时代的乔尔乔·瓦萨里的说法,布龙齐诺最先从师于Raffaellino del Garbo, 14岁以后跟着蓬托莫学习绘画。蓬托莫曾把年幼的布龙齐诺画入他的一系列"旧约圣经中的约瑟"(Joseph (Hebrew Bible)|Joseph in Egypt) 肖像画作品中,这些作品现今珍藏在伦敦国家美术馆 。他的画风受了他老师的很多影响,对他老师的一生而言,两人一直相互合作。在佛罗伦萨阿诺河老桥边的Santa Felicita教堂的小礼堂里,我们时常可以看到布龙齐诺的早期手迹。礼堂内室、祭坛大作 Deposition from the Cross 和侧墙湿壁画"Annunciation"是由蓬托莫完成的。很显然,布龙齐诺被安排了创作穹顶湿壁画的任务,令人惋惜的是,这些作品并没有幸存下来。据乔尔乔·瓦萨里,其中四幅圆形福音绘画是由布龙齐诺完成的。然而由于他的技巧和他导师的是如此相似,至今学者们仍在为此争辩不止。在他生命的最后阶段,布龙齐诺投身于佛罗伦萨Accademia delle Arti del Disegno的诸多活动中,他是这家学院的创办人之一。画家Alessandro Allori 是他最喜爱的徒弟,公元1572年布龙齐诺过世年间,他是和Allori一家住在一起的(Alessandro是Cristofano Allori的父亲) 。布龙齐诺一生大部分时光是在佛罗伦萨度过的。\n\n### 文章 31\n\n阿尔西比亚德斯\n阿尔西比亚德斯(希腊语:,,)是雅典杰出的政治家、演说家和将军。雅典大政治家伯里克里斯是他母系族伯,曾养育过他。阿尔西比亚德斯是这个贵族家系的最后一名著名成员,这个家族在伯罗奔尼撒战争之后衰败。他在战争的后半段扮演重要角色,担任战略顾问、军事指挥官和政治家。在伯罗奔尼撒战争期间,阿尔西比亚德斯曾经数次更换他的政治忠诚。在故乡雅典时,他主张一种好斗的外交政策,是西西里远征的主要支持着,但是在他的政敌指控他犯有亵渎罪之后,逃到斯巴达。他在斯巴达担任战略顾问,提议或监督了反对雅典的几次主要战役。但是在斯巴达,阿尔西比亚德斯也很快面临强大的敌人,又被迫叛投波斯。他在那里担任顾问,直到他的雅典政治盟友将其召回。前410年阿西比亚德重掌雅典的舰队,此后3年间更是引导著雅典连战连胜,但是最终他的政敌再次将他流放。后来他先后流亡到比提尼亚(Bithynia)与波斯,但不久后在波斯的盟邦斯巴达的要求下,波斯皇帝包围了阿尔西比亚德斯的宅邸,后者突围时中箭身亡。西西里远征是阿尔西比亚德斯的想法,学者们认为,如果远征由阿尔西比亚德斯而不是尼基阿斯指挥,可能不会是后来那样灾难性的结果。在斯巴达期间,阿尔西比亚德斯在重创雅典中扮演重要角色;占领戴凯列阿(Decelea),和几次关键性的雅典叛乱,都是在他的建议或监督下发生的。但是他一旦回到故乡,就在雅典一系列的胜利中扮演关键角色,最终迫使斯巴达寻求与雅典媾和。他支持非传统的战术,频繁通过背叛或谈判而不是围攻来夺取城市。阿尔西比亚德斯的军事和政治天才频频向他当时所效忠的城邦证明他的价值,但是他树立强敌的能力也使他不会留在一个地方很久。\n\n### 文章 32\n\n中国-新西兰自由贸易协定\n《中华人民共和国政府和新西兰政府自由贸易协定》,简称中国-新西兰自由贸易协定,是中华人民共和国与新西兰的双边自由贸易协定,于2008年4月签署。该协定涵盖了货物贸易、服务贸易、投资等领域,还涉及国防、法律、人权、多边贸易、地区安全等议题,是中国与其他国家签署的第一个全面的自由贸易协定,也是中华人民共和国与发达国家达成的第一个自由贸易协定。该协定也是新西兰继1983年与澳洲签署的澳新更紧密经贸关系协定后最大的贸易协定。新西兰国会在2008年7月通过该协定,10月1日协定生效,将在未来11年逐步实施,于2019年完全落实。该协定共214条,分为18章,在WTO基础上制定。到2008年10月,37%中华人民共和国出口到新西兰的产品及35%新西兰出口到中国大陆的产品将取消进口产品关税。2016年1月1日前,新西兰将取消全部自华进口产品关税;中华人民共和国将在2019年1月1日前取消96%自新西兰进口产品关税。根据协定,新西兰将为中医、中餐厨师、中文教师、武术教练、中文导游等5类职业提供800个工作许可,同时允许来自中国的车工、焊工、计算机应用工程师、审计师等20类职业至少1000个工作名额。新西兰出口商如乳品公司恒天然和新西兰海产业议会等对协定表示欢迎。新西兰贸易公会则反对该协定加入输入劳工的条文,称中国大陆劳工可能会被剥削和获得较低工资。虽然该协定得到该国最大的两个政党新西兰工党和新西兰国家党的支持,新西兰优先党、新西兰绿党和毛利人党持反对态度,绿党成员认为协定会影响新西兰劳工的就业机会。谈判历时3年。2004年11月19日,新西兰总理海伦·克拉克与中华人民共和国主席胡锦涛在智利圣地牙哥举行的APEC会议期间宣布,两国展开自由贸易协订的谈判。首轮谈判于2004年12月举行。2006年4月,中国国务院总理温家宝访问新西兰,与克拉克共同确定了1至2年内双方达成自由贸易协定的目标。2007年,胡锦涛和温家宝与克拉克多次会晤,就《协定》进行商讨。经过15轮谈判,2007年12月,双方最终就《协定》涉及的所有问题达成一致,于2008月4日由中国商务部部长陈德铭与新西兰贸易部长菲尔·戈夫代表各自政府在北京人民大会堂签署,并将在双方完成相关国内程序后正式生效。\n\n### 文章 33\n\n钱小豪\n钱小豪(Chin Siu Ho,),原名钱嘉华,香港出生,香港演员及武术指导;兼做幕后和幕前工作,其弟弟是为演员钱嘉乐,弟妇是汤盈盈。钱小豪祖籍广东佛山,家里除自己外还有三姊一兄一弟,自己排行第五。他小时候于香港中环摆花街一带居住,父亲在该处附近开设木箱搬运的店舖。后来举家搬到北角健康邨定居,钱小豪在邨内长大。他的童年娱乐主要是到屋邨后山位置玩金丝猫,又或者跑到赛西湖游水。钱小豪曾就读位于湾仔司徒拔道的私立岭南小学,并在学校寄宿。后来升读岭南中学。他自幼跟随大圣劈挂门的冼林旭师傅习武学拳,其对武术的兴趣始于在铜锣湾道百乐戏院看的电影《洛基》。在14岁时,钱小豪因在功夫擂台比赛中获自由搏击铜牌,被电影公司相中。进而于1976年6月加入邵氏电影公司训练班,不久被名导演张彻收为旗下演员。自1970年代末起,钱小豪先后为邵氏电影公司及嘉禾电影公司等等演出超过90部影片,其中以武打动作片最深入人心,他在1980年代开始走红。第一部担任男主角的影片为《飞狐外传》。随着动作片的衰落,钱小豪亦逐渐转型,开始尝试演出其他风格的角色。他曾演出过不少恐怖片、警匪片,比较著名的有和林正英、许冠英合作主演的“僵尸”系列。2000年,钱小豪被发现将录影机藏在纸袋内,偷拍在超级市场购物的女子,超市警卫报警将他逮捕,警方在录影带内发现至少30名女性的裙底镜头。他其后被判守行为两年。2002年后,他曾淡出幕前,转而从事导演工作。同时,钱小豪曾为亚洲电视及无线电视出演电视剧,其中以古装武侠剧居多。钱小豪经历过两段婚姻,前妻为郭秀云,两人于1990年在澳洲结婚,不久诞下儿子钱麒夫(现已改名庞景峰)。三年后,两人分居并离婚。现任妻子为丘倩鸣,两人于2001年完婚,婚后亦育有一子钱颖德。钱小豪曾在1994年英勇地救了一名被挟持的女子,后获得香港“见义勇为”杰出青年。2016金花奖国际电影节,以微电影"安居"获得最佳男演员。\n\n### 文章 34\n\n阿拉伯航空\n阿拉伯航空,或译阿拉比亚航空(),是一家总部设在阿联酋沙迦的廉价航空公司,是阿拉伯航空运输组织的成员。该公司以沙迦国际机场和穆罕默德五世国际机场为枢纽,经营中东、北非、印度次大陆、中亚和欧洲等地共计51多个目的地的航线。2003年2月,沙迦管理者、阿联酋最高委员会成员,谢赫·苏丹·本·穆罕默德·卡西米颁布埃米尔法令,成立了中东地区首家廉价航空公司——阿拉伯航空。阿拉伯航空在2003年10月28日开始运营,首飞航线为沙迦至巴林。2007年初,阿拉伯航空成功面向公众发售其55%的股份。2009年4月29日,摩洛哥阿拉伯航空在摩洛哥达尔贝达成立,宣布自同年5月起以穆罕默德五世国际机场为枢纽,经营达尔贝达与若干欧洲城市之间的航线。摩洛哥阿拉伯航空由阿拉伯航空与摩洛哥当地的一家私营航空公司摩洛哥皇家快运航空以及巴林的Ithmaar银行共同合作创办、阿拉伯航空进行管理,专门经营阿拉伯航空的北非与欧洲之间的航线。南亚方面,阿拉伯航空以加德满都为新的次要枢纽,为该地区与中东之间的航线服务,并与尼泊尔的雪人航空签署了合资协议。根据协议,两家公司合资创办一家新的廉价航空公司,称为“Fly Yeti”。受尼泊尔动荡的政局影响,Fly Yeti自2008年暂停营业至今。在2008年和2009年连续两届的Skytrax全球最佳廉价航空公司评选中,阿拉伯航空均位居中东地区第一位。2003年10月28日,阿拉伯航空成功首航巴林首都麦纳麦之后,又在当月先后开通沙迦至大马士革、科威特城、马斯喀特、贝鲁特等四条航线。2004年上半年,阿拉伯航空将自己的网络扩展到卡塔尔、埃及、斯里兰卡、苏丹、沙特阿拉伯等国,年底开通了至也门首都萨那的航线。随后几年,其通航目的地均逐年增长。截至2014年2月,阿拉伯航空已经通达28个国家的52个目的地(含部分即将开通航线)。阿拉伯航空暂时停飞的目的地有3个:哈萨克斯坦阿斯塔纳、阿富汗喀布尔和亚美尼亚埃里温。并且新开通中国乌鲁木齐地窝堡机场航线截至2009年5月,阿拉伯航空的机队拥有以下飞机。此外,阿拉伯航空已在2007年向空中客车公司订购34架A320,并附带15架可选订购。阿拉伯航空已退役机队包括两架A320客机,注册号分别为A6-ABX和A6-ABY。\n\n### 文章 35\n\nH-α\nH-α,在天文学和物理学上是氢的一条具体可见的红色发射谱线,波长为6562.8 Å。依据原子的波耳模型,电子是存在于量子化能阶的轨道上绕著原子的原子核。这些能阶以主量子数 "n" = 1、2、3、... .来描述,电子只能存在于这些状态中,并且也只能在这些状态中转移。这一组从 "n" ≥ 3 转换至 "n" = 2 的谱线称为巴耳末系,并以连续的希腊字母依序为成员命名:在来曼系,命名的惯例是:H-α的波长是656.281 奈米,是在可见电磁频谱的红色部分,并且是天文学家追踪气体云气中被电离的氢含量最容易的方法。因为将氢原子的电子从 n = 1激发到n = 3,与将他游离的能量几乎相同,因此电子被激发到n = 3而不被游离的机率是非常小的。反而是,在被电离之后的氢核再与新的电子再结合成氢原子时,在新的原子,电子可以先存在于任何一个能阶上,然后再落至基态(n=1)并辐射出光子来转换。几乎有一半的时间,这些能阶会包括n=3至n=2的转换,因此原子将辐射出H-α。所以,H-α发生在氢被电离的区域内。因为氢是星云的主要部份,相对的H-α很容易自吸收而饱和,因此他可能显示云气的形状和范围,但不能用来确定云气的质量。替代的,二氧化碳、一氧化碳、甲醛、氨或甲基氰化物是典型的用于测定云气的质量。H-α滤镜是以H-α的波长为中心设计的一种窄频带宽的光学滤镜,它们以能通过滤镜的波长带宽来描述其特性。这些滤镜由多层(~50)的真空喷涂来镀镜,这些层次都选择能导致干涉效应以过滤掉除了需要的波长以外的所有波长。另一种选择是使用光标准具(etalon)做为窄频滤镜(以阻拦过滤器或能量阻绝过滤器),以H-α发射线的波长为中心只让很窄的波长通过(<1\xa0Å)。光标准具和二向色性干涉滤波器的物理在本质上是相同的(依靠在表面之间的建设性或破坏性干涉反射),但执行的方法不同(干扰滤波器依靠内部反射的干涉)。由于可见的H-α特征有时会与高速度结合(像是高速移动的日珥和喷发物),太阳H-α光标准具通常都能调整(经由倾斜或改变温度)来应付伴生的都卜勒效应。\n\n### 文章 36\n\n武藏浦和站\n武藏浦和站()是一个位于埼玉县埼玉市南区七丁目,属于东日本旅客铁道(JR东日本)的铁路车站。停靠此站的路线在轨道名称上是东北本线(别线)与武藏野线(详情参见路线条目与「」),此站是东北本线的。与东北本线别线有关,作为运行系统是埼京线的列车停靠,旅客导览不使用「东北(本)线」的名称。埼京线的车站编号是JA 21,武藏野线是JM 26。另外,此站的武藏野线西浦和方向起分岔出通往东北本线的与野、大宫方向的武藏野线支线(西浦和支线)。此支线主要供货物列车使用,但也有「」等旅客列车途经。下行线(与野方向)在车站西侧分岔出武藏野线,上行线在西面500公尺左右的地点合流。这个分岔、合流地点在此站开业以前称为田岛信号场。武藏浦和站是一个高架车站,可分为两个部份。在东边较矮的是武藏野线的月台,采2座侧式月台2线设计。在西边较高的是埼京线的月台,采2座岛式月台4线设计,其西侧是东北新干线的线路。两条路线在靠近大宫的一边交汇,其中埼京线(和东北新干线)的线路居上,而武藏野线的线路则在下方。车站只有一个剪票口(大部分为自动闸机),和绿窗口、自动售票机、特定车票售卖机等设施均设于埼京线月台所在的站房内,而武藏野线的月台则依靠高架联络通道连接埼京线的站房。其中1号月台因为结构关系,需利用楼梯经过武藏野线线路下方才能到达联络通道,因此换乘时需要步行较长的距离。使用这个联络通道的除了有换乘的乘客外,还有其他上下车的乘客,因此这个联络通道一直都非常繁忙。(来源:JR东日本:车站构内图)1985年9月30日开业的埼京线在各站(全部10个车站)设有车站颜色。此站的颜色是樱色。之后,武藏野线引入车站颜色时在此站采用与埼京线月台相同的颜色。标有★号的店铺接受以Suica(和PASMO)付款2016年度的1日平均上车人次为51,849人,JR东日本管内排行第93位。另外,2010年度埼京线-武藏野线之间1日平均转乘人次为91,971人。埼京线在赤羽-大宫之间的通勤快速唯一停靠的车站。开业以后的各年度的1日平均上车人次为下表。本站附近是埼玉市副都心区域,现正进行市区重建工程。所有路线均由国际兴业巴士营运。\n\n### 文章 37\n\n米诺地尔\n米诺地尔()是一种钾通道开放药,这类药物在降压时常伴有反射性心动过速和心输出量的增加。对于血管扩张的作用具有选择性,见于冠状动脉,胃肠道血管和脑血管,而不扩张肾和皮肤血管。它还可以减低或停止掉发并且促进毛发再生。现在一般的门诊病人不需要处方就可以取得,用于。米诺地尔本来是用于控制高血压。后来偶然发现有一个有趣的副作用,就是扭转或减慢秃头过程。Upjohn推出了含2%的米诺地尔的外用药液,用来治疗秃头及脱发。该药液在美国及加拿大以Rogaine名称销售,在欧洲及亚太区则使用Regaine名称,在台湾译为「落建」。5%浓度的药液专供男性使用,而2%浓度的药液则适合女性使用。在台湾贩售的含5%浓度的米诺地尔成分生发药液产品如:落建生发系列的落健生发液、萌发生发液等。米诺地尔的专利保护期在1996年2月11日已经到期。5%泡沫配方的米诺地尔,跟液体配方一样有效。米诺地尔促进毛发生长的机转目前还未完全了解。此药物的结构式中有一氧化氮基团且可能做为一氧化氮的致效剂。它同样是,造成细胞膜的去极化。对于大面积的掉发,米诺地尔就比较没有效果。另外,对于年轻男性有五年以下的掉发困扰,它有非常显著的效果。目前,米诺地尔只用于的掉发。它同样也是个血管扩张剂。理论上,借由扩张血管及开通钾离子通道,使更多的氧气及养分到毛囊,会促使毛囊从休止期到生长期。常见的副作用有对眼睛的烧灼感及刺激性,治疗部位搔痒、红肿及刺激性,非预期位置的毛发生长。如果使用者有以下的严重副作用,立即寻求医疗照护:严重的过敏反应(红疹、荨麻疹、搔痒、呼吸困难、胸闷等);胸痛;晕眩;火烧心;立即且非预期的体重增加;手或脚的胀大。酒精和丙二醇可能会使头皮干燥,造成头皮屑和。有些配方改用奈米液滴为的就是减少因为酒精和丙二醇所造成的接触性皮肤炎。米诺地尔对猫来说是致命的。\n\n### 文章 38\n\n巴黎古监狱\n巴黎古监狱(法语:"La Conciergerie")是巴黎昔日的王宫和监狱之一,位于巴黎市政厅以西,靠近巴黎圣母院。它是大型建筑群司法宫(Palais de Justice)的一部分。在法国大革命期间,许多囚犯从这里送往巴黎各处上断头台。西岱岛的西部曾是墨洛温王朝王宫的所在地;从10世纪到14世纪是中世纪法国国王的王宫。在路易九世(圣路易,1226-1270)和腓力四世(1284–1314)统治时期,墨洛温王朝的王宫得到了扩建,加强了防御功能。路易九世增建了皇家礼拜堂圣礼拜堂,而腓力四世增建了河边带塔楼的立面和一个大厅("Grande-Salle")。它们都是法国宗教和世俗建筑的精彩实例。大厅是当时欧洲最大的之一,其底层"La salle des gens"保存了下来:长64米,宽27米,高9米。它用作餐厅在1358年王室放弃了这座宫殿,迁移到对岸的卢浮宫。这座宫殿继续行使行政功能,包括总理和法国议会。1391年,这座建筑改为监狱,关押普通罪犯和政治犯。古监狱保存了3座中世纪的塔楼:凯撒塔,得名于古罗马皇帝;银塔,用作皇家珠宝店;在法国大革命最血腥的阶段恐怖统治时期,该监狱享有“断头台前厅”的国际声誉。此处设有革命法庭,关押着多达1200名男女囚犯。1793年4月2日到1795年5月31日之间,设在大厅的法庭将大约2600名囚犯送上了断头台。它的规则很简单。只有两种结果-宣布无罪或判处死刑-在大多数情况下是选择后者。最有名的囚犯(和受害者)包括王后玛丽·安托瓦内特、诗人安德烈·舍尼埃、夏绿蒂·科黛、夫人伊丽莎白公主、杜巴利伯爵夫人,被乔治·雅克·丹敦控诉的吉伦特派,然后是被罗伯斯庇尔控诉的乔治·雅克·丹敦,最后是罗伯斯庇尔自己受到控诉和处死。死刑犯前往囚车要穿过圣路易室,获得“注定室”("Salle des Perdus")的绰号。19世纪波旁王朝复辟以后,此处继续用作关押重要囚犯的监狱 — 最著名的是日后的拿破仑三世。玛丽·安托瓦内特的囚室改建为供奉她的礼拜堂。古监狱和司法宫在19世纪中叶进行了重建。虽然这座建筑看来像中世纪堡垒,其实主要完成于1858年。该监狱在1914年退役,作为国家历史遗迹向公众开放。今天这里是一个热门景点,但是只有一小部分向游客开放-大部分仍用于巴黎法院。\n\n### 文章 39\n\n夜刀神\n夜刀神(日文:)亦称为夜刀之神,乃是日本传说中的蛇神,为土著神(原住民之神),见载于日本地方志《常陆国风土记》中。相传夜刀神是一条长有锐角的长蛇,见过祂便会招致灭族之祸,是为人类带来灾祸的蛇神。神名中的「やと」具有「谷」之意,亦即山谷或芦苇塘之类的地势,代表夜刀神多出没于此地带。据《常陆国风土记》所载,在常陆一带的新辟田地间常出现为数甚多的蛇群(也就是夜刀神)作恶,妨碍农务。这些夜刀神有著像蛇一般的身躯,头上长有尖角,往往率群而来;且据说当人类目击夜刀神的话,其家门必会破亡,甚至子孙灭绝。当时,有一位名为箭括麻多智之人想要在此地开垦,遂打杀驱逐夜刀神直至高山之下。后来他在山脚与农村之间竖立标记,向蛇群表示:「此山上乃众夜刀神的领域,山下农田则属于老百姓的工作范围。今后我辈将对众神奉祀有加,且世代敬祭,只祈求众神莫对我辈怨恨。」于是麻多智设立爱宕神社以祭祀这些夜刀神,并将此习俗代代相传,至今不绝。孝德天皇时期,壬生连麿(或称壬生连麻吕)割茨城地八里、合七百余户另置立方郡。壬生连麿命人占有山谷土地,并在池塘旁筑堤;此举引起夜刀神再次聚集起来。壬生连麿知道此事后便大声说道:「我之所以要修建此池,乃是为了百姓的生活著想,究竟是什么神祇不服从天皇教化?」他更下令给役工,倘若在池边看到任何蛇虫鼠蚁、小鱼杂物,尽管随意施杀。结果这批夜刀神果然隐匿起来,不敢为害;而这方池塘今号「椎井」。箭括麻多智竖立标记,区隔人类与神灵生活的界线,达到两造相安无事的境界。一般夜刀神为水神的表征,人类开垦山林原野而发展农业稻作,故祭祀夜刀神乃是为了祈求水利顺遂。《茨城县史》作者志田谆一认为,《常陆国风土记》编纂者(通说是以藤原宇合为主的作者群)受到浓厚的儒教思想影响,将在地的「旧闻轶事」改以儒教化、合理化地改写。既然传说见了夜刀神会招致灭族,显见此神祇是跟农耕息息相关的国魂神。《常陆国风土记》所载之箭括麻多智为了开垦新土地,教导人民祭祀夜刀神,而掌管祭祀的内容即是受到儒教影响。至于身为国造的壬生连麿,其职务便是祭祀国魂神,祈求该地农获丰收。岂料壬生连麿向夜刀神叫嚣,其实象征著斥责不崇敬当地国魂神的。现代日本大众文化中也常出现夜刀神的角色。\n\n### 文章 40\n\n天使在人间\n《天使在人间》是一本2008年香港书展期间首度出版的袋装书,卖点是阿娇的事后感。有人推测,她想复出香港娱乐圈,可是不为部分网民接受,所以借此印刷媒体书籍,诉心声,试探公众反应。其实阿娇接受这次访问,基本上是为2008年2月的声明做补充。她说开那个记者会,是要承认她真的拍过那些照片。这事令支持她的人包括小朋友及家长失望,她感到很抱歉很难堪。她十分清楚网民对她的意见。她明白「网上说话不用负责任,所以大家都可以出言甚狠。」不喜欢她的人「甚至会说许多难听的话,我为此再不忿也是徒然。」但阿娇还是回应了某些意见。「有人说我在早前被偷拍更衣照而哭得死去活来,今次反而没有哭,前者是做戏博同情。借此我很想大家明白,那次偷拍,非出于自愿……」,虽然那些私人的照片也不是她自愿公开的,但毕竟她有拍过,所以不想在承认这事时哭泣。「又有人说我欺骗歌迷,又说我的声明纯为推卸责任,我真的呆了。难道我每天都要大肆向歌迷公开我私下做过甚么甚么,不能有半点私稳?又难道出来交代,承认自己做过这事,反而是推卸责任?我真的不懂。」在此书中,阿娇又透露,陈冠希拍的裸照流出,令她不想见人,害怕得发疯。阿娇说她形容自己「好傻好天真」,是指错爱陈某,不是指拍那些照片。阿娇没有想过恨他,「我既然爱过他,无谓怪责他,他已经为这事付出了代价。」至于Twins组合若果继续,可能连累阿Sa,所以阿娇很为难。她知道这段时间,阿Sa为她负起不少重担,很辛苦,「无论发生甚么事,大家每每找她回应,她不但要面对自己的压力,还怕答错问题会累及我……我真的对不起她。每当我向她讲抱歉,她总反过来安慰我,要我千万别说傻话」。《天使在人间》ISBN 9789888005154,其他受访者有英皇娱乐旗下艺人: 容祖儿、谢霆锋、钟欣桐、谭耀文、关智斌、泳儿、郑希怡、钟舒漫、洪卓立。此书是义卖的,收入捐作英皇集团慈善基金。\n\n### 文章 41\n\n张容轩\n张容轩,台湾男子篮球运动员,目前效力于金门酒厂篮球队。张容轩从小在金门长大,高中就读新荣高中,2006年代表出赛HBL获得MVP。高中毕业后目标就读师范体系,原锁定高师大,后因师大有名额因此往台北发展。在球队选择上,因大专条款最终选择SBL而放弃大专联盟,效力台银队。张容轩当时决定效力台银的主要原因有:一、相较于其他明星球队,在台银的上场机会较多。二、台银的入行条件很吸引他,为篮球生涯退休后的生活做准备。张容轩的体能条件不算特别优异,特别的是他用脑打球,理解比赛的能力过人,台银教练韦陈明就说张容轩是个模范球员,从不迟到、态度正确也很受教。在99学年度UBA大专篮球联赛帮助台师大夺得大专篮球联赛(UBA)男子组冠军,缔造队史首度3连霸,并获选为冠军赛最有价值球员MVP。 张容轩赛后说:「想把这个奖分享给队上每个人,台师大每个人都有资格拿MVP!」成为台湾极少数拥有高中大学两大联赛的最有价值球员得主。加入金门酒厂篮球队后,以平均15.2分的成绩拿下第八季SBL年度最佳进步奖。张容轩于第8季超级篮球联赛转入金门酒厂篮球队,第9季超级篮球联赛转到新任总教练贾凡领军的台湾大篮球队。第11季SBL超级篮球联赛以场均13.1分、3.4篮板、1.4助攻入选「年度第1队」,甚至继第8季后,再度夺下「年度最佳进步奖」,张容轩表示,「对我来说,『进步奖』才是我认为的最大奖,这代表大家都看到你持续进步,每年我都以此奖为目标持续努力成长。」在兵多将广的台湾大突破重围,一举抱回生涯第二座年度进步奖并入选为年度最佳第一队,最佳五人的肯定,创下自己生涯的高峰。台湾大篮球队并在第11季SBL超级篮球联赛打进队史的第一次总冠军赛。球季过后入选中华白队,代表参加第五届亚洲杯男篮锦标赛,拿下历史以来最佳的银牌成绩。台湾啤酒篮球队总教练阎家骅今天证实,台啤和张容轩签4年合约,张容轩已随队练球。第十三季SBL超级篮球联赛台湾啤酒篮球队击败璞园建筑篮球队拿下总冠军,缔造篮球生涯大满贯(HBL,UBA,SBL)都有冠军的纪录。\n\n### 文章 42\n\n神雕侠侣 (1995年电视剧)\n《神雕侠侣》(;又名《九五神雕侠侣》),是香港电视广播有限公司根据金庸所著的武侠小说《神雕侠侣》改编而拍摄的经典巨著电视剧,全剧共32集,监制为李添胜。杨过 ( 古天乐 饰 ) 一次误闯进活死人墓中,幸好拜得古墓派掌门小龙女 ( 李若彤 饰) 为师,因厌恶师父二字称谓,故称小龙女为「姑姑」。二人相依为命,但不知不觉间却萌生微妙的男女感情,且达到生死相逢之境地 ! 对此情坚贞不渝,纵使小龙女被尹志平 ( 陈启泰 饰 ) 所侮辱,仍能摒除世俗眼光而当众结为连理成亲。 后二人相分,决定十六年后终在绝情谷再续前缘 ……另一厢,郭靖 ( 白彪 饰 ) 、黄蓉 ( 魏秋桦 饰 ) 将女儿 郭芙 ( 傅明宪 饰 ) 许配予杨过,但为杨过所拒绝 ; 自始郭芙与杨过便积怨日深,于是在一次误会中,郭芙更斩下杨过之左手。然而,小东邪郭襄 ( 李绮虹 饰 ) 则对杨过豁达情深,更鼓励杨过踏遍天涯海角去觅回小龙女 ……以下是本剧在香港首播的集数之播映纪录:以下所有影碟发行均由电视广播(国际)有限公司授权:香港发行代理商现代音像(国际)有限公司于2003年推出发行了《神雕侠侣》VCD影碟零售版本,此影碟将已播放的集数并制作成20只碟作为片段完整及无删剪版本,一套共分为两盒影碟,每只碟跟电视剧的每集片长约60分钟一样,设有粤语及国语发音版本并配上繁体中文字幕。中国大陆发行代理商中凯文化集团推出发行了《神雕侠侣》H DVD影碟零售版本,总共30集,共四碟,出版社为九洲音像出版公司,设有粤语及国语发音版本并配上简体中文字幕。台湾发行代理商弘音多媒体科技股份有限公司于2007年推出发行了《神雕侠侣》DVD影碟零售版本,此影碟烧录VCD香港版的20只碟作为集数,共5只碟,设有粤语及国语发音版本并配上非隐藏繁体中文字幕。本剧于2014年5月在TVB星河频道,2017年9月1日在TVB经典台重播。\n\n### 文章 43\n\n竹醋液\n竹醋液,也称竹酢液,是竹炭烧制过程的副产物。将竹炭烧制过程产生的黑烟收集起来、冷凝后即得「粗竹醋液」,再经静置、蒸馏等过程制成的竹醋液,成分中有 40-60%的有机成分。精制过后的竹醋液可用于农业用途,也可制成家用的清洁用品。在台湾农委会2007年公布的「CAS标章台湾优良林产品一般用途竹醋液认定评审标准、品质规格标准及标示规定」中,是依竹醋液的pH值、比重和醋酸含量百分比等条件进行评定,且外包装上需标示「且不可食用」的警语。粗粹取的竹醋液为咖啡色,有焦味和酸味,成分中80%-90%为水,醋酸占3%,焦油占1%,其他尚有多种有机成分,包括羧酸类6种,芳香环类19种,醛类2种,酮类16种,酯类7种,醇及醚类4种等。将粗粹取的竹醋液静置3-6个月后,受重力影响,竹醋液分为三层,最重的焦油在最底层,中间为竹醋水,上层为轻质焦油。取中间的竹醋水进行数次蒸馏后,颜色由淡黄色转变为透明的竹醋液。竹醋液收集的多寡可能和竹子的含水量、同时烧制的数量有关;收集的速率和烟囱温度上升速度有关,当烟囱温度上升速度加快时,竹酢液收集速率减低,pH值会因为烟囱温度上升而增大。取精制后的竹醋液进行抑菌研究发现,在培养皿中,2.5%以上的竹醋液对大肠杆菌和金黄葡萄球菌可完全抑制。竹醋液的应用开发,朝向农业、医药和民生三大方向发展。农业应用的研究和产品朝向土壤改良、植物生长促进剂、减少病虫害、畜产动物饲料添加剂等方向。竹醋液用作叶菜类作物的生长促进剂,对不同的植物收成的的鲜重和干重影响不同,种植方法也是影响竹醋液对叶菜类生长的因素之一。也有将竹醋液用于真菌性皮肤病的医疗研究,在体外研究中发现,稀释后的竹醋液对白色念珠菌和皮肤癣菌有抑制效果。民生方面的产品包括清洁乳和香皂、牙膏等用品,虽然其酸性为非腐蚀性酸性,但其清洁类保养品仍不宜每日使用。也有用于家用垃圾除臭、直接喷于猫尿处可去除(非掩盖)猫尿味、防止水槽水管细菌滋生的用品。\n\n### 文章 44\n\n失范\n失范(,或译无规范、迷乱)是社会学术语,指现代化过程中,因传统价值和传统社会规范遭到削弱、破坏、乃至瓦解,所导致的社会成员心理上失去价值指引、价值观瓦解的无序状态。在失范社会,曾有的统一信仰遭到怀疑和抛弃,而个人又尚未确立自身的信仰体系,所以社会成员会感到失落,缺乏目的性和方向感。这种心理上的挫折感会产生一系列后果,比如犯罪和自杀,因而导致社会的不稳定。失范并不单指个人行为,也涉及群体行为。失范的法文是"anomie",源自希腊语"anomos"的复数形式"anomia"。"a"指否定性的“无”, "nomos"的含义为“法”或“规定”("norm","law")。在中世纪神学中,失范指不守法而亵渎神灵。法国哲学家让-马利·居约最早在学术意义上定义并使用了“失范”这一概念。最先提出“失范”()一词的是法国19世纪哲学家(),他认为:“失范是一种有创造力的新生事物,是对僵死的观念的一种挑战……anomie不是一种邪恶的东西,也不是当代社会中的一种疾病,anomie是一种非常好的性质。”“失范”在居约看来,是伦理进步的标志和道德价值的体现,是个人自治的必然后果,也是个人获得解放后个体自由伸张的标志。同时期的法国社会学家涂尔干,将居约的“失范”概念引入社会学中,从而使这个概念广为人知。在1893出版的《社会分工论》中,涂尔干认为“失范只是暂时的规则匮乏状态,社会习俗仍旧可以规定和协调新的社会器官和功能及其相互关系。”失范的可能原因有三种:一是严重削弱的集体意识,令人们看不到自身在社会中的位置和意义;二是强制的社会分工带来不平等,缺乏公正的分工丧失了合法性,令人们丧失信心;三是需求不足带来效率低下,社会的功能得不到满足,从而导致连锁反应,引起失范。涂尔干在《自杀论》一书中进一步指出,失范是“能够限制个体欲望的特殊规范类型的缺席状态。”在涂尔干之后约半世纪,美国社会学家罗伯特·莫顿从功能主义角度对失范进行了深入而系统的研究,并将它发展为20世纪美国犯罪学三大理论之一的紧张理论。\n\n### 文章 45\n\n殷宏章\n殷宏章(,),字伯文,植物生理学家,贵州省贵阳府人,出生于山东省兖州府滋阳县。祖父殷谦(字吉皆)在同治七年戊辰科(1868年)三甲三十六名 进士,曾在直隶文安县任知县、顺天府府尹,广西柳州府知府。父殷有济为清代举人,光绪三十四年至宣统三年间曾在山东省滋阳县、高苑县任过知县,擅长书法。殷宏章1929年毕业于南开大学生物系,并留校任助教。1933年在北平清华大学当研究生,后回南开大学担任讲师。1935年考取清华大学留美公费,赴美国加州理工学院留学,随Went教授研究,1937年获得博士学位,随后在该校生物物理研究室和生物遗传研究室进行光合作用和遗传方面的研究。1938年回国担任西南联大教授,并在汤佩松创设的清华大学农业研究所植物生理学组兼任研究员。1944年至1945年以第一批”交换教授”身份赴英国剑桥大学进行磷酸化酶的研究,1946年赴北京大学担任教授,进行淀粉形成方面的研究。1948年应罗宗洛教授之约,赴台湾大学讲课几个月,同年12月至1951年应英国J.李约瑟(Needham)博士的邀请,赴印度新德里担任联合国教科文组织南亚科学合作馆科学官员,协助该地区国家开展科研工作及合作交流事务。1951年秋回国任中国科学院实验生物所研究员,并协助罗宗洛教授进行植物生理研究室的建设工作。1953年植物生理室从实验生物所划出单独成立研究所,他出任副所长,1978年到1983年任所长,1983年3月后任名誉所长。他在光合作用、植物生长素的研究成果,普遍获得国际上的认同与引用。1948年获选为第一届中央研究院院士,1955年获选为中国科学院院士(学部委员),1978年全国科学大会上被评为先进工作者,1988年获颁美国加州理工学院杰出校友。另外,他也曾任第二届全国人大代表;第五、六届全国政协委员;上海市第三、四、五届人大代表等职务,1977年被评为上海市先进工作者。\n\n### 文章 46\n\n八斗子渔港\n八斗子渔港()位于台湾基隆市中正区的八斗子,是一座多功能的渔港,也是台湾北部最大的渔港。依《渔港法》分类,其渔港等级为第一类渔港,主管机关为农委会渔业署。八斗子渔港位处八斗子半岛西南侧与台湾本岛间,基隆港东南岸2.5浬处的岩岸岬角,行政区分上隶属基隆市中正区。原为天然海湾,三面环山,西北通海,水域深广,潮差温和,又少漂沙,港口宽度60公尺,航道水深6至18公尺, 条件优良,而附近海域渔获丰富,早期就已经是当地人生活中不可缺乏的食物来源,更是成为渔港的重要条件,为一岩岸岬角之天然良港。1974年当时的行政院长蒋经国任内巡视基隆市时,希望配合基隆地区渔业的快速发展,为解决当时基隆市唯一的大型渔港正滨渔港(位于基隆港内)渔船使用地不足的拥挤问题,于是决定在八斗子兴建大型渔港,并计划以此新渔港取代正滨渔港的功能,以扩大基隆港的商港用地(但日后并未执行)。1975年正式动工兴建,兴建时八斗子煤矿全面停采,到1979年兴建完成。八斗子渔港历经多年的整修后,现今各项公共设施齐全,已成为台湾北部地区最大的渔港。八斗子渔港的兴建不仅提供基隆地区渔业生存空间,也促进了相关工商业的引进及蓬勃发展,更成为基隆市重要的旅游景点,每逢假日吸引大量外地游客前往。为了因应民众假日休闲游憩的需要,基隆市政府所成立的管理所利用渔港的第二泊区陆路地范围,设置休闲绿带成为滨海公园。八斗子渔港面对太平洋,受东北季风直接吹袭,其强度对渔港作业有极大影响,每年9月至翌年5月,多为北北东风,6月至8月多为西南风。八斗子地区的渔业以沿、近海为主,主要渔获物有以下几种:八斗子地区常用的渔法\n\n### 文章 47\n\n李文烈\n李文烈(이문열音Yi Munyol,1948年5月18日-),韩国作家,首尔出生,原籍庆尚北道英阳郡。李文烈1948年5月18日在首尔市钟路区清云洞出生,爸爸是留学日本的共产主义者,朝鲜战争爆发后1个人去了北朝鲜,留在韩国的家人被贴上共产主义协力者的标签。他幼年和少年时代过得很辛苦。小学毕业后展转庆尚北道各地。1964年通过高中入学检定考试入读安东高等学校,用功读书的他陷入精神的不安定状态,1年后退学,去釜山。1968年,通过大学检定考试取得大学入学资格,入读国立首尔大学学习国语(韩语)教育,大学时代参加文学社团、文学活动。大学没有毕业就退学,结婚,去当兵。步入文坛作品是1977年的《人的儿子》,1979年发表的《塞下曲》是他的成名作。他的名作还有《皮浪的猪》(1989年)、《英雄时代》(1990年)、《边境》(1990年)、《诗人》(1991年)、《选择》(1997年)、《金翅鸟》、《青春肖像》、《诗人和盗贼》、《三国志》(《三国演义》)等。已有日译本、英译本和3种汉译的《扭曲了的英雄》在1989年被拍成电影,搬上大银幕。儿童青少年的成长和服兵役等自身体验常被他用作描写的素材,《我们扭曲的英雄》写学校小团体的政治斗争,《英雄时代》写共产主义者辈出的家族受连累的苦情,《皮浪的猪》写当兵退伍归乡途中男性的团体暴力。在写实主义的白描中,使用许多意象,有些难解的词语,洋溢著浪漫主义色彩,隐含强烈的批判性,让读者目眩神迷。他的长篇小说《人的儿子》已有卫为、枚芝合作的汉译,1995年在中国上海出版。他1987年发表的小说《扭曲了的英雄》汉译本在1995年问世,译者(史上第1位)是留学台湾淡江大学和中国上海的韩国人金宰民。2003年译本题《我们丑陋的英雄》,译者是中国的朝鲜族人金英今。1989年发表的《皮浪的猪》在2000年出台了金英今的汉译。金英今评价李文烈「惯以浪漫主义手法揭示隐藏在看似坚不可摧的人类社会道德与规范之中的野蛮性与双重性」。《诗人和盗贼》和《青春肖像》已有汉译。他曾在1985年和2005年访问台湾。2005年,他的《我们扭曲的英雄》台湾译本(旅韩台湾人卢鸿金译)和《人的儿子》繁体汉字本在台湾台北出版。\n\n### 文章 48\n\n阿拉伯航空\n阿拉伯航空,或译阿拉比亚航空(),是一家总部设在阿联酋沙迦的廉价航空公司,是阿拉伯航空运输组织的成员。该公司以沙迦国际机场和穆罕默德五世国际机场为枢纽,经营中东、北非、印度次大陆、中亚和欧洲等地共计51多个目的地的航线。2003年2月,沙迦管理者、阿联酋最高委员会成员,谢赫·苏丹·本·穆罕默德·卡西米颁布埃米尔法令,成立了中东地区首家廉价航空公司——阿拉伯航空。阿拉伯航空在2003年10月28日开始运营,首飞航线为沙迦至巴林。2007年初,阿拉伯航空成功面向公众发售其55%的股份。2009年4月29日,摩洛哥阿拉伯航空在摩洛哥达尔贝达成立,宣布自同年5月起以穆罕默德五世国际机场为枢纽,经营达尔贝达与若干欧洲城市之间的航线。摩洛哥阿拉伯航空由阿拉伯航空与摩洛哥当地的一家私营航空公司摩洛哥皇家快运航空以及巴林的Ithmaar银行共同合作创办、阿拉伯航空进行管理,专门经营阿拉伯航空的北非与欧洲之间的航线。南亚方面,阿拉伯航空以加德满都为新的次要枢纽,为该地区与中东之间的航线服务,并与尼泊尔的雪人航空签署了合资协议。根据协议,两家公司合资创办一家新的廉价航空公司,称为“Fly Yeti”。受尼泊尔动荡的政局影响,Fly Yeti自2008年暂停营业至今。在2008年和2009年连续两届的Skytrax全球最佳廉价航空公司评选中,阿拉伯航空均位居中东地区第一位。2003年10月28日,阿拉伯航空成功首航巴林首都麦纳麦之后,又在当月先后开通沙迦至大马士革、科威特城、马斯喀特、贝鲁特等四条航线。2004年上半年,阿拉伯航空将自己的网络扩展到卡塔尔、埃及、斯里兰卡、苏丹、沙特阿拉伯等国,年底开通了至也门首都萨那的航线。随后几年,其通航目的地均逐年增长。截至2014年2月,阿拉伯航空已经通达28个国家的52个目的地(含部分即将开通航线)。阿拉伯航空暂时停飞的目的地有3个:哈萨克斯坦阿斯塔纳、阿富汗喀布尔和亚美尼亚埃里温。并且新开通中国乌鲁木齐地窝堡机场航线截至2009年5月,阿拉伯航空的机队拥有以下飞机。此外,阿拉伯航空已在2007年向空中客车公司订购34架A320,并附带15架可选订购。阿拉伯航空已退役机队包括两架A320客机,注册号分别为A6-ABX和A6-ABY。\n\n### 文章 49\n\n蜘蛛人 (东映)\n《蜘蛛人》(原题:)是1978年(昭和53年)5月17日~1979年(昭和54年)3月14日期间,在东京电视台播出的特摄剧集,全41集(首播时时追加重播了两集)。当时东映是向美国惊奇漫画申请了角色的使用版权。本作品使用了惊奇漫画版蜘蛛人的角色,加上东映原创的故事和设定,并坐上巨大机器人「雷奥柏顿」战斗。从此以后「英雄坐上机器人,和巨大化后的怪人战斗」这一公式剧情,被继承到往后的超级战队系列中。东映与惊奇漫画签定了「3年内可使用对方的角色」的协议,而产生了此作品。本来是打算做成以日本武尊为主角,蜘蛛人为配角的作品,但最后的成品蜘蛛人是主角。山城宇宙考古学的山城博士、赛车手拓也、妹妹新子、弟弟拓次一家和平地生活著。有一天,拓也听到了不思议的声音「我的兄弟啊!来吧兄弟!我的兄弟啊…」。原来那是400年前,被率领铁十字团的怪物教授灭族,而执意复仇的蜘蛛星王子加利亚的声音。听得到这心电感应的,全宇宙只有一人。加利亚帮被暗算的拓也注射了蜘蛛提取液,让他变成了蜘蛛人,和怪物教授和铁十字团战斗。山城拓也穿上「蜘蛛防护服(Spider Protector)」后就会变成蜘蛛人,拥有蜘蛛的能力,可以在墙上、天花板爬行。并能用「蜘蛛感应」察知敌人。弱点是寒冷。另外一大特色是登场时的对白。本作在蜘蛛人登场时会在敌人前摆姿势,并说出特殊对白。这时会播放主题曲的前奏作背景音乐。而当蜘蛛人在做出场宣告说自己是“Spider-Man”时。于漫画蜘蛛宇宙里大量来自不同平行时空的蜘蛛人遭到被拥有非凡力量的继承者(Inheritors)家族猎杀捕食,发现此事的究极蜘蛛人(八爪博士)四处召集各平行时空里尚为生存的平行宇宙蜘蛛人们与继承者家族对抗。在宇宙队长的能量被继承者长老吸收后山城拓也驾驶Leopardon及时出现支援,但Leopardon终究不敌吸收宇宙能量能力大为提升的长老而遭击坠,事后拓也生存了下来并加入了究极蜘蛛人的团队。\n\n### 文章 50\n\n动物扮演\n动物扮演是指人加上一些道具去扮演一些实际存在的动物或是幻想的动物,并且模仿该动物的肢体行动,例如扮演小狗则以四肢著地地爬行。扮演动物的理由很多,例如Cosplay、情趣游戏、商户吸引顾客等,有的只是外表动物化,心理还是保持人的状态,但是稍稍受所扮演的动物所影响,好比说扮演兔子、小猫就以比较温驯的姿态。扮演花豹、小狗,则是比较狂野姿态。有的是连心智都要表现得像动物,常见于BDSM的游戏中,而伴侣的角色也可能是扮演动物,或是驯兽师、宠物主人或是骑师。扮演动物者,受到支配者以对待动物的方式对待获得满足。好比扮演小猫、小狗者被主人以项圈拴住,或是关进兽笼,以宠物的姿态生活进食。或是扮演马,穿著马具拉马车,承受伴侣的鞭子。无性暗示的动物扮演则常见于原始部落文化,像是北美洲的原住民文化以及史前传说中,半人半兽的动物在他们的文化仪式中有很重要的地位。这些动物如神兽般地被尊敬,有的时候也拿来教育儿童,要求学习动物的求生智慧,以及运动姿态。扮演动物的原因,往往与参与的人有大的歧异。不单只是一般的角色扮演,这牵涉到很多戏剧、小说、神话、传说以及心理戏剧的观点来分析这样的现象。就如同一般的情趣游戏或是角色扮演,动物扮演的理由跟参与者的喜好心情相关。可能从只是简单的模仿马的嘶叫声、狗吠声,或是小猫小狗活动的姿态。到被主人喂食、被当作宠物把玩。有点类似年龄游戏(Ageplay),透过游戏可以当一些别于日常生活所扮演的角色。更复杂的可能如母马扮演时,加上一些马具、嘴里衔住口衔、加上马尾以及穿上模仿马蹄的靴子。扮演母猫则可能加上猫耳、项圈、猫蹼以及猫尾。西方式的小猫游戏,主要是从性感内衣为出发点,外观上较为性感,小猫泛指所有的猫科动物,如花豹、老虎等皆有人扮演。东方式或是日式的小猫游戏受卡通、ACG影响较深,因此比较属于可爱形式。不论是东方还是西方,最终目的是要充分令自己显出猫的特征。以下简单地并依重要性及普遍度列出:\n\n### 文章 51\n\n远藤实\n远藤实(),二战后日本歌谣界最具代表性的作曲家之一,曾写下五千多首作品,包括《北国之春》、《高三学生》等传世名曲。由著名演歌手千昌夫原唱的《北国之春》,以及这首歌被蒋大为和余天等翻唱的中文版受到很多华人的喜爱。出生于日本东京府东京市向岛区(现在是东京都墨田区向岛),第二次世界大战期间被疏散到新潟县西蒲原郡内野町(现在是新潟市西区内野)居住生活。在新潟一带被称作“”(Kadozuke)的演艺风格对其后作为作曲家的远藤实的人生给予了很大的影响。 所谓“”就是在别人家门口前进行的诸如越后狮子等街头演出,以收取金钱和物品的卖艺表演。1949年,十七岁时的他怀着成为歌手的梦想来到东京,一边在街头吉它卖艺,一边自学作曲。1956年, 在日本水星唱片(、Nippon Mercury Record)公司为歌手藤岛桓夫创作了热卖歌曲「月娘晚安」(「お月さん今晩わ」),这同时也是他作曲家生涯的第一首歌曲。远藤实一生共谱写五千余首作品(大部分是演歌),其作品孕育了日本歌谣界非常出名的诸如舟木一夫,千昌夫,森昌子等演歌歌手。1988年,在夏威夷接受心脏搭桥手术。1994年,远藤实获得日本唱片大奖功劳奖,并设立了远藤实歌谣音乐振兴财团。此外他还在新潟市开设了音乐资料馆“实唱馆”2003年,当选为第一位因推广大众音乐获选为日本政府认定的“文化功劳者”。2003年,在朝鲜绑架日本人问题上,为鼓励遭到绑架的受害者及其家属,远藤实作词作曲写了「寒冬过后必是春天」(「春の来ない冬はない」),并灌录成唱片赠送给他们。2008年12月6日10时54分,因急性心肌梗塞在东京都内的一家医院去世,享年七十六岁。日本政府为表彰远藤实经由大量的乐曲而对大众音乐发展所作出的功绩, 于2008年12月6日封其正四位及授予旭日重光章。更于2008年12月26日及2009年1月23日举行的关于授予国民荣誉奖的内阁会议上正式决定将国民荣誉奖颁发给著名作曲家远藤实。他是日本国民荣誉奖的第十六位获奖者,也是第四位获得该奖项的作曲家(前三位作曲家分别是古贺政男,服部良一,吉田正)。日本的国民荣誉奖通常授予“广受国民爱戴,为社会带来希望业绩的卓著”人物。上一次颁奖是前日本首相森喜朗将奖项授予2000年悉尼奥运会女子马拉松冠军高桥尚子。\n\n### 文章 52\n\n逆渗透\n逆渗透(Reverse osmosis),又称 RO、反渗透,是一种净化水的办法。原理是利用渗透作用,将清水(低张溶液)和咸水(高张溶液)置于一管中,中间以一支允许水通过的半透膜分隔开来,可见到水从渗透压低(低张溶液)的地方流向渗透压高(高张溶液)的地方。然若在高张溶液处施予力,则可见水由渗透压高的地方流向渗透压低的地方。逆渗透是“正渗透”的反向,通常比正渗透的自然过程,耗费更多的能量。正渗透分离技术,逐渐成为新趋势。顾名思义,逆渗透滤膜技术就是利用渗透的方法来从海水中提取出纯净的饮用水。渗透的英文“Osmosis”一词来源于希腊文“Osmos”,意思是一种推动力。1748年,莱诺对渗透现象进行了研究,并首次作了实验纪录,发现用膀胱把水和酒精隔开后,水可以通过膀胱进入酒精,但酒精不能进入水。根据科学的定义,渗透是某种溶剂通过半透膜(一种溶剂分子能通过,而溶质分子不能通过的薄膜)从低浓度到高浓度转移的现象。通过那种被称作“半透膜”的薄膜,我们可以对渗透现象看得更清楚。半透膜是一种对透过物质有选择性的薄膜。利用一张只准水分子透过,不许盐分子透过的半透膜,将一个容器分成两半。在膜的两侧分别注入纯水和含盐水,让两侧的高度一样高。过了一段时间后,盐水的液面升高,纯水的液面下降,这是由于纯水一侧的水分子透过半透膜在向盐水那侧转移。当渗透达到平衡时,盐水一侧的水柱高于纯净水一侧的水柱,这种现象产生于所谓的“渗透压”,这渗透压的高低取决于盐水浓度的高低。逆渗透能降低被处理水的总溶解固体(TDS),这是其他水处理原理所不具备的特征。逆渗透的水是目前水处理中最干净,水中除水分子外无任何矿物质或金属。导电性差。脱盐率等于脱去的盐量与进水含盐量的比值,即:准确的脱盐率要通过对产水和进水进行化学分析,测定相应的TDS 含量才能计算出来,但是这样比较麻烦,一般采用电导率转换为TDS 来计算脱盐率。具体的转换公式如下:其中渗透压公式如下:其中\n\n### 文章 53\n\n越南亡国史\n《越南亡国史》(越南语:Việt Nam Vong Quốc Sử),越南史书,由越南革命家潘佩珠于二十世纪初期写成。当时越南正受法国统治,潘佩珠于1905年到日本求援,并用汉文写成本书(书中采用别号「巢南子」)。本书记述了越南近代历史、法国殖民当局的暴行及爱国志士们的抗法活动,以图唤起越南人民奋起团结,摆脱殖民统治及争取独立。《越南亡国史》的作者潘佩珠,为十九世纪晚期、二十世纪早期的越南革命家。当时,越南正受法国的殖民统治,丧失独立。潘佩珠响应抗法运动,于1904年创立维新会,准备武装起义。1905年,潘佩珠到日本求援,并遇上中国维新派人物梁启超。潘佩珠与梁启超讨论当时越南政局,并深得其关注。梁启超建议:「法人在越种种苛状,举世界无知者,子(潘佩珠)为我言之,我为子播之,或亦可以唤起世界舆轮于万一」,潘佩珠为此感动,「因抆泪以著是篇」,用汉文写成《越南亡国史》(采用别号「巢南子」)。梁启超又为之作叙,并资助出版。据梁启超于乙巳年(1905年)九月为本书写的「叙」,以及他的「例言」所说,《越南亡国史》是「巢南子自述,其间文字不有雅驯处,悉仍之,存其真也」,以尊重本书原貌。此外,本书又并非完全用中国语文来表述,「书中尚有用越南字者,盖著者之意,非徒哀告于他国,实欲以并警其国人也」。《越南亡国史》分成以下部份:※梁启超为免中国人「于越南兴亡陈迹知之者希,骤观是书,或且茫然。故特编《越南小志》一卷以为参攷,亦采集旧籍十数种以成之也。」此外,在上海人民出版社、上海书店出版社出版的《中法战争》第七册,还收有《越南亡国史》的「前录」,为梁启超与潘佩珠谈话的笔录及梁启超本人的感想。潘佩珠于越南殖民时期写成《越南亡国史》,而在该时代中,世上不少国家都受列强的威胁或侵占。因此,梁启超便注意到本书对弱国人民的启发性:「吾最近得交一越南亡命客(潘佩珠),尝有以语我来,吾闻之而不知其涕洟之何从也。顾我不自哀而哀人耶,人将哀我。读此编毋哀焉而惧焉,其或虑几。」《越南亡国史》写成后,便由梁启超资助印刷出版,如由他所编的《各国兴亡小史八种》,便收录了本书以及其著作《越南小志》。其后,由邵循正、聂崇岐、张雁深、林树惠、单士魁等编成的中国近代史资料《中法战争》,亦收录了该书。
\n\n### 文章 54\n\n林郁夫\n林郁夫(,),原奥姆真理教的干部成员,出家名为。入教前是医生。奥姆真理教实行省厅制后担任「治疗省大臣」。是东京地下铁沙林毒气事件的其中一名行凶者,被判处无期徒刑。他和同样是教团干部的林泰男虽然同姓,但没有亲戚关系。林郁夫1947年出生于东京都品川的一个执业医生家庭。先后就读于庆应义塾中等部和庆应义塾高等学校。大学毕业于庆应义塾大学医学部,之后留学美国。归国后在茨城县东海村的医院工作。1989年开始相信奥姆真理教;1990年5月辞去工作带同妻子一起出家信教,很快成为麻原彰晃其中一个最信任的助手,他成为教团中的「师长」,以及东京都中野区教团附属医院院长。1994年成为奥姆真理教的「治疗省大臣」,主要负责研究「奥姆菜单」,管理「奥姆医院」,向信徒注射迷幻药LSD,「治疗」信徒中的动摇者,更有削去信徒指纹的行为。1995年轰动世界的东京地下铁沙林毒气事件,他是执行者之一。他携带两个用报纸包裹著的装有沙林毒气的容器进入千代田线后,在新御茶之水站擢穿容器后离去。他散播的毒气造成2人死亡,231人受伤。据他自己的回忆所称,擢穿容器之前,他曾经十分犹豫,自己行医多年就是为了不断拯救病人,但是如果擢穿容器的话,列车上的所有人就会在他面前倒下。他几次想放弃,但是最终还是相信这是为了崇高的目标而下手了。在行凶后,他没有躲避起来,而是回到奥姆真理教的一个分部。10多天后的4月8日,他在石川县穴水町的路上被逮捕,当时怀疑他正在偷窃放置在路上的自行车而以盗窃罪被捕。被捕初期,他拒不合作,在狱中进行绝食,还宣扬「警察和奥姆真理教的战争」。控方最初也因他曾犯有杀人、绑架、监禁等罪行而指控他为「杀人机器」,请求判处死刑。后来他全面交代犯罪事实,使地下铁沙林事件的具体经过得以公诸于众,还协助指证麻原彰晃。他本人也表示对自己的所作作为感到惭愧,令控方主动改为请求判处终身监禁。1998年5月,东京地裁判处他无期徒刑(其它4名与他一起执行地下铁沙林袭击任务的人都判处了死刑)。1998年,他的回忆录《奥姆与我》()在文艺春秋发表,描写了自己作为一个受过高等教育的人,帮助麻原彰晃从事肮脏行径的过去。回忆录的收益全部赠予受害者以及家属。\n\n### 文章 55\n\n循州\n循州,中国隋朝时设置的州。三国东吴甘露元年(265年)析荆州刺史部桂阳郡南部置始兴郡,纳入广州刺史部管辖;即今韶关市、南雄市、始兴县、翁源县、仁化县、英德市、佛冈县等地。东晋咸和元年(326年),析南海郡置东官郡,郡治在今深圳市。义熙九年(413年),先析东官郡东部置义安郡;南朝梁天监二年(503年),又析东官郡置梁化郡。至此,东官郡辖地仅余今深圳市、珠海市、中山市、增城市、龙门县等地。隋朝开皇十年(590年),全国撤郡设州,合并始兴郡、梁化郡、东官郡、义安郡置循州,直隶于中央;治所在归善县(今惠州市东)。以境内有循江得名。开皇十一年(591年),始兴郡改设韶州、东官郡废入番州、义安郡改设潮州,仅留原梁化郡地仍为循州。大业三年(607年)改为龙川郡。唐朝武德五年(622年)设为循州总管府,管辖韶州、潮州、循州等三个州,即唐初岭南六管之一。唐朝贞观元年(627年),撤去循州总管府,原循州总管府辖下的潮州、韶州、循州均归广州总管府,此后为唐岭南五管。广州总管府辖下的循州,辖境相当于现在的广东省新丰、连平、和平、龙川、河源、兴宁、五华、陆丰、海丰、惠阳、惠东、博罗、紫金等地及揭西县西部。五代南汉移治龙川县(今广东龙川县佗城),又分置祯州,辖境缩小。元朝至元十三年,升为路,二十三年复降为州。明朝洪武二年(1369年),省入惠州府。中华民国元年(1912年)原清代惠潮嘉道改置为潮循道,道治在潮安县。民国廿五年(1936年),设广东省第六行政督察区,辖兴宁、梅县、龙川、大埔、蕉岭、和平、平远、连平、五华等9个县;因行政驻所兴宁县为原循州旧地,故而通称循州地区。另外,以惠州为行政中心,设广东省第四行政督察区,辖新丰(今属韶关市)、龙门、东莞、宝安(今深圳市)、海丰、陆丰、紫金、河源、博罗、惠阳等10个县,通称惠州地区。中共建政后(1950年),原惠州地区改称惠阳地区;原循州地区行政驻所迁驻梅县,又以旧驻所(兴宁)、新驻所(梅县)各取一字,改称兴梅地区。以后惠阳地区主要为惠州市所继承,兴梅地区演变成今天的梅州市(含丰顺;不含河源、龙川、连平、和平)。\n\n### 文章 56\n\n上海轨道交通18号线\n上海轨道交通18号线,编号L5,为上海2010到2020年规划建设的一条贯穿城市南北的切向轨道交通路线,途径宝山、杨浦、浦东。一期工程从长江南路到航头,总长36.8公里,全程地下,设车站26座,已于2016年5月正式开工,预计2020年建成通车试运营。二期工程规划线路从长江南路到康宁路,总长7公里,全程地下,设车站5座。根据“国家发展改革委关于上海市城市轨道交通近期建设规划(2010-2015年)的批复”,上海轨道交通18号线原定为2011年至2016年建设,规划线路从场北路至航头,长44.3公里,设车站30座。实际公布的一期工程与发改委批复的建设规划有所区别,工程起点变为长江南路站;线路长度减少7.5km;长江南路至航头段增设3座车站,全线取消2座车站,车站总数增加1座;沿康沈路、航鹤路线路走向调整为沿沪南公路走行;下盐公路以南,沿航鹤路段至终点站区段敷设方式由高架调整为地下;定修段和主变选址位置调整。一期工程规划起于宝山区长江南路站,沿长江南路—何家湾路—国权北路—国权路—江浦路—穿越黄浦江—民生路—世纪公园—白杨路—莲溪路—御青路—沪南公路,终于浦东新区的航头站,其中越黄浦江段与江浦路隧道共建,江浦路隧道将于丹阳路站、昌邑路站附近上穿18号线。2015年11月10日,18号线二期工程开始进行工程勘察及设计招标,二期全地下线正线长6.97km,与原始方案变动不大。二期工程起于一期工程长江南路站,沿长江南路-郁江巷路-长江西路建设,共设5站及一个停车场。2017年3月2日 二期工程(长江南路站—康宁路站)选线专项规划(草案)向社会公示,与之前方案相比,撤销了原规划的终点站场北路站,新增了康宁路站作为终点站,并预留进一步向西延伸的可能性。香槟金地铁18号线规划,引起市民热议,话题集中在走向从最初的康沈公路调整为沪南公路。在公示期间收到有关咨询、意见或建议的电话约300个、电子邮件约3000封,超过了之前公示的14号线,其中至少有三分之一是关于线路走向的。业内人士表示,线路更改应该是一个综合平衡的结果,考虑到施工可行性、线路对地区发展支撑作用、对交通改善的作用等多个方面。\n\n### 文章 57\n\nN轨\nN轨是线路轨距为9mm,比例为1/148~1/160的铁道模型规格的总称。小形模型的其中外国以HO轨 (OO轨)为主流,N轨是在日本及台湾最普及的铁路模型。在海外,特别是美国一般称作“N比例(N Scale)”,在中国大陆称作“N轨”,在台湾则称为“N规”或“N轨距”。N比例铁路模型和大多数的铁路模型一样,以电作为动力来源。N比例模型车辆借由直流2线式的电力系统来被操控。两个轨道一边作为正极、一边作为负极,通过轨道和接触的车轮驱动2个最大电压12V的直流电动机让模型车辆行车。根据轨道间的电位计从0V到12V间变化让模型速度加减。变压器把家用电源降压,而控制器控制直流电的电压。这个系统由于是很多全世界性的标准,而全部的制造厂跟随著。因此,无论是哪个制造厂的N轨车辆,都可在的N轨线路上一起行驶。21世纪初由于电子学技术的进步,新的控制方式诞生了,数码指令控制(DCC)在国外越来越流行。这种系统同时能提供12V的电源,并发送数位讯号,对每列车辆的行驶操作进行控制,还能同时控制音效。因为轨道通电的电压固定为12V,因此车灯的亮度不受到模型列车的速度的影响。现在的直流2线式的车辆如果设置小解码器也能享受DCC驾驶的乐趣。外国也有发售N比例3线式的电动模型的制造厂。首先,因为小型不占太大空间是最大的优点。以日本型的N量规车辆的情况,大部分能通过半径250mm的曲线,如果不是长编成列车,90cm×60cm左右的空间也能充分地行车,狭窄的空间也可以摆放铁路模型。在日本,N比例的铁道模型比其他比例的铁路模型产品的数目丰富且廉价。不过这其实是因为在日本N比例是主流,在海外并不如HO比例的产品丰富及廉价,相较之下反而N比例的更为高价。欧洲Trix,Fleischmann和 Roco 也有生产N比例铁道模型,除了部分Roco 产品,跟HO的价差其实并不大。一般相信,日本人因为手指灵巧所以相对欧美人士较容易组装N比例的车辆和其他场景,是N比例单单只在日本流行的主要原因之一。铁路模型生产商一览\n\n### 文章 58\n\n南宁市第二中学\n广西壮族自治区南宁市第二中学,简称南宁二中。学校创建于1906年,是广西壮族自治区首批重点中学,首批示范性高中。1992年被列为中国名校,2005年获“中国百强中学”称号。南宁二中于清光绪三十二年(1906年)建校,前身为创办于1906年的南宁府中学堂,曾先后更名为广西省立第一中学、南宁中学、南宁高中等。现学校在南宁市内有两个校区:新民校区(初中部),凤岭校区(高中部)和东盟校区(新校区)。新民校区位于新民路29号,处于南宁市中心区,占地面积70亩。凤岭校区位于琅东开发新区,占地面积423亩。东盟校区位于武鸣中国-东盟经济开发区,占地面积约180亩。学生黄天明曾夺得中学生国际信息学(计算机)奥林匹克竞赛银牌和金牌,学生赖柯吉曾夺得中学生国际物理学奥林匹克竞赛金牌。新民校区位于南宁市中心区,占地面积68亩,现有教学班22个。凤岭校区位于琅东开发新区,占地面积453亩,教学班45个,于2007年秋季学期开始招生。凤岭校区拥有可容纳3000多人寄宿的学生公寓和学生食堂,设有满足新课程教学要求的各类功能教室,有4间高水平实验室,包括物理探究性实验室、物理创新数字化信息实验室、生物数码互动实验室、文科地理实验室。还有心理咨询室3间、心理团体活动室、心理放松室、团体心理辅导室各1间。学校还有1座天文台、1个400米、2个300米塑胶田径场;20个标准篮球场、11个标准排球场、4个标准网球场等运动健身设施,还有计算机校园网主机室及音像制作室等等。校园网接入到每个办公室、教师宿舍及每间教室,配备的设备现代化程度高,能满足教学、科研工作需要,所有教室可实现网络化教学。\xa0南宁二中东盟校区(官方定名“南宁市东盟中学”),是南宁二中与广西—东盟经济技术开发区联合创办的一所全寄宿制完全中学,设高中部和初中部。校园面积180亩,校舍与设备按国内一流示范性高中标准建设和配备。学校位于南宁市武鸣区里建广西—东盟经济技术开发区园区内,距市区30公里。东盟校区于2013年秋季学期招收首届高中生202人,目前有在校生近2100人,其中高中部904人,初中部1165人,教职工170多人。\n\n### 文章 59\n\n体温调节\n体温调节(thermoregulation),指温度感受器接受体内和外在环境温度的刺激,通过体温调节中枢的活动,引起内分泌腺、骨骼肌、皮肤血管和汗腺等组织、器官活动的改变,从而调整产热和散热的过程,使体温保持在相对恒定的水平。为动物在长期进化过程中获得的较高级的调节功能。体温调节的中枢位于下视丘。传统生理学认为,在下视丘前部存在著散热中枢,而下视丘后部则存在著产热中枢,两个中枢之间有著交互抑制的关系,从而保持了体温的相对稳定。人体的体温是恒定的,其内在温度约维持在37℃左右,也就是所谓核心温度(core body temperature),通常指人体的直肠温度,位于人体的内部中心,绕著脏器,其外围就是体壁与皮肤。体温若高到41~42℃(如:剧烈运动、发烧)时,体内许多蛋白质分子(尤以酵素分子对生命非常重要)会很快地分解,而细胞内许多代谢反应却需要在恒定的温度下才能顺利地进行,酵素是代谢过程的重要催化剂,没有了酵素,细胞也就无法进行代谢作用。内温动物(旧称恒温动物),通常是指鸟类和哺乳类,牠们的下视丘内有体温调节中枢,具有自行调节体温的功能,通常体表具有良好的保温构造,例如:羽毛、毛发。内温动物在天气炎热或激烈运动时,皮肤的血管会扩张,使血液量增加,加速体热在体表散失,食欲也同时减少,以减少热量产生。有时,内温动物的汗腺分泌量增加促使体热快速散失。另外,呼气、排泄及排遗也可散失一部分的体热。内温动物在天气寒冷时,皮肤的血管会收缩,使血液量减少,抑制体热在体表散失的速度,食欲也同时增加,配合甲状腺分泌甲状腺素的量增加,加速细胞的呼吸作用,以加速热量产生。有时,内温动物的肌肉会不自主地颤抖,皮肤表层产生「鸡皮疙瘩」,以增加体热。外温动物(旧称变温动物),通常是指鱼类、两生类和爬虫类等动物,由于缺乏体温调节中枢,无法自行调节体温,因此体温会随著外界环境温度改变而有明显的变动。外温动物在环境温度大幅改变时,会更换栖息地或休眠的外在行为协助体温不至于变化过大,例如:天气炽热时,牠们会躲在阴凉处避免体温过高;天气寒冷时,牠们会外出晒太阳,以获取热量。植物的体温过高时,叶绿素会被破坏而成白色,即「叶片白化」。因此植物也须进行体温调节。植物可借由蒸散作用将过多的体热带走,叶片的角质层可以反射阳光,以减少热的吸收。\n\n### 文章 60\n\n乔治亚民主共和国\n乔治亚民主共和国(乔治亚文:საქართველოს დემოკრატიული რესპუბლიკა),是第一个由乔治亚人建立的近代国家。自从1917年十月革命爆发、俄罗斯帝国瓦解后,乔治亚民主共和国与焉诞生。它的北边和俄罗斯、库班人民共和国及北高加索山共和国接壤;南边和东南边则与亚美尼亚民主共和国、亚塞拜然民主共和国跟鄂图曼帝国相邻。领土面积约107600-{A|zh-cn:平方千米;zh-tw:平方公里}-(现今的乔治亚面积为69700)。于1918年5月26日正式宣告成立。独立后不久,德国与鄂图曼帝国随即承认之。这个年轻的国家便把它置于德国的保护之下,并且将许多住有穆斯林的区域割让给土耳其政府。德国的支持使格鲁吉亚得以击退来自阿布哈兹的布尔什维克党人。另一方面,由于英国的占据,使巴统地区在1920年之前均未在乔治亚政府的控制之下,1918年12月25日,英国势力也进入了提比利西。格鲁吉亚与邻国间的关系相当紧张。曾经跟亚美尼亚、邓尼金所统辖的白军以及亚塞拜然三方因领土纠纷而爆发多次军事冲突。英国派出使节团试图从中斡旋以整合所有反布尔什维克的力量。为了避免白军直接穿越这个新兴国家,英军指挥官便率军横越高加索山加以抵御,使白军无从经过,同时也暂时舒缓了该国与亚塞拜然之间的冲突,并使两国结成了同盟。1919年2月14日,格鲁吉亚举行首次国会大选,社会民主党以81.5%的得票率大获全胜。3月21日,诺伊·佐丹尼亚组成了一个新政府。他开始与农民起义者进行谈判,同时还需面对阿布哈兹及南奥塞梯的种族问题。然而,这一连串的改革在俄罗斯却也成为了孟什维克和布尔什维克两派之间斗争的交锋点。1919年司法改革完成,阿布哈兹被赋予自治权;但种族问题却依然困扰著这个国家,尤其是1920年5月所发生的冲突。有心人士见状便乘机操弄民族主义。1921年,苏联红军占领格鲁吉亚,并将其与亚美尼亚、阿塞拜疆一同并入新成立的外高加索苏维埃联邦社会主义共和国。\n\n### 文章 61\n\n科学战队炸药人\n《科学战队炸药人》(原题:)是日本东映公司在1983年制作的「超级战队系列」第7部特摄作品。在日播放期间为1983年2月5日-1984年1月28日,全51集。远古时代,坠落于地球上的陨石中残存的生命物质,在地底下经过长年的进化成了有尾人一族-邪进化帝国。因尾巴的数量代表其身分的象征的特有文化,将利用它们超乎人类想像的科学力征服地上的人类,以让日本各地火山喷发为第一步,开始了侵略地上世界的行动。然而,及早察觉到这件事的科学家·梦野久太郎,集合了五名智慧与体力都相当优秀的年轻科学家到自己所营运的发明中心来,也正式宣布科学战队的成军。五人著装了梦野博士开发的战斗强化服后,成了炸药人并衔命全力阻止邪进化帝国侵略的邪恶野心。第9回后的播出时间皆缩短至25分钟。梦野久太郎于远古时代坠落到地球上的陨石中生命物质,长久以来寄居于地底进行著自主进化,并成为了能自由操纵火山的地底支配者「有尾人一族」们的帝国。属于卵生,故于蛋中出生,会将尾数加于名字,且尾数越多代表在帝国中越高。十分藐视没有尾巴的人类(地上人),并视为「下等生物」,在无法透过实验让人类长出尾巴后,便乘著有如怪物一般外观的巨大攻击要塞格兰吉兹摩,向地表上的人类展开侵略行动。亚顿卡亚洁诺比亚梅基度奇梅拉进化兽机械进化兽大爆炸光束小尾兵格兰基兹摩基兹摩斯奇托大木星 DyJupiter炸药马赫 Dyna Mach炸药战车 Dyna Mobile炸药拖车 Dyna Garry炸药猎鹰 Dyna Falcon炸药吉普车 Dyna Machine第一话登场。当炸药红喊出『合体! Grand Slam!』后,由炸药马赫、炸药战车、炸药拖车三体合而为一的巨大机器人。由梦野博士开发制造。于剧场版『199英雄大决战』中登场。武装招式必杀技以下时间以当地时间(日本时间)为准本作品的战队服装曾经被台湾自制特摄节目《太空战士》作为参考。片头曲片尾曲插曲\n\n### 文章 62\n\n奥迪R8\n奥迪R8(Audi R8)是一款由奥迪公司于2006年生产的超级跑车。它的极速达330km/h,主要竞争对手包括法拉利F430、兰博基尼Gallardo、日产GT-R、梅赛德斯-奔驰SLS AMG和保时捷911。本车获日本消费者年度风云车和北美年度风云车的荣誉。作为奥迪量产的首款中置引擎超级跑车,奥迪R8融合了奥迪在多个运动赛事中取胜的经验、技术以及突破传统观念的设计完美的融合在一起。奥迪R8共享了兰博基尼Gallardo的开发平台,并使用了ASF高钢性车身结构,镁铝合金的创新组合和密闭的管状空心结构直接结合在一起,作为车体的主要承载架构。奥迪在R8上舍弃了传统避震器的阻尼油,改用了主动式电磁感应悬挂系统,一种随着电磁场改变粘稠度的特殊油液。奥迪R8配备了全LED头灯,此超高性能的灯体可产生类似日照的明亮白色光线;极限LED日间行车灯像细窄的带子一般,将头灯与下侧分隔开来,使得整车格外引人注目;Carbon Sigma炭纤维侧饰板不但达到了减轻车重的目的,更让车侧产生了强烈颜色对比的视觉效果;主动式电动扰流尾翼会在车速达到100km/h时自动伸展,并在车速下降至35km/h时自动收回;Bang&Olufsen音响系统通过12个扬声器达到环绕音效再现,并且总输出功率达到465W。奥迪R8最初只配备有4.2公升V8引擎,后来在2008年12月发布5.2公升V10引擎版,这个版本的R8使用了基于兰博基尼Gallardo LP560-4的5.2公升V10引擎。V10的R8测试时装上跟RS6一样的5.0公升V10双涡轮增压引擎,可是因为引擎冷却效能存在问题而烧毁,最终V10引擎的R8只能沿用自然吸气的工作方式。奥迪R8一度在德国房车赛中做为赛道安全车来使用。奥迪R8曾经出现在多部电影以及游戏中。\n\n### 文章 63\n\n按司\n按司(琉球语首里那霸方言:或;先岛方言:)是琉球国历史上的地方行政单位,后来成为琉球国贵族和地方豪族的一种称号。自第二尚氏王朝起只有王族成员才可出任。按司家族是国王家族的分家,相当于日本的宫家、中国的藩王府,在贵族中,其地位仅次于王子。女性王嗣(翁主)亦可成为按司,女按司称为按司加那志(アジカナシ或アンジカナシ)。《中山世谱》等琉球史书称,琉球人是天帝的子孙。天帝派遣女神阿摩美久(アマミキヨ)和男神志仁礼久(シネリキヨ)来到人间,生三男二女,为琉球人的祖先。其中长子是天孙,其后代世为国王;次子为按司(诸侯)的祖先;第三子为百姓(平民)的祖先。但事实上早期琉球没有国王这个概念,各地区的首领自称「按司」,有时也会被祝女授予「世之主」、「世主」之类的神号。根据冲绳学学者伊波普猷的说法,「按司」是琉球语中「主」(アルジ)的转讹。按司最早作为地方势力的首领出现于12世纪,并在各地建立了一些御城,彼此互相争战。后来尚巴志王统一了琉球。但按司仍在地方拥有一定势力,参与过琉球国内的政变。直到尚真王时期,琉球朝廷下令收缴各地兵器,召各按司赴首里城居住后,按司割据势力才被消弱。此后按司从地方豪强转型为都市贵族,派遣名叫「按司掟」(アジウッチ)的官员管理自己的领地。此后,在第二尚氏王朝的位阶制度确定之后,按司成为了琉球王族的一个位阶。没有即位的王子,其长子会被授予按司的位阶。因此按司一般姓向氏,名乘头世袭为「朝」字。只有国头按司家(国头御殿)例外:该家族姓马氏,名乘头世袭为「正」字。这是因为国头按司家的祖先马顺德(国头亲方正格)对琉球王室有重大功绩,曾救了尚元王一命。为了报恩,尚元王特别授予其子孙王族的待遇和按司的位阶。琉球王府征服奄美群岛和宫古群岛之后,这两个地区的酋长并没有被授予按司的称号。奄美群岛的酋长称「大亲」(ウフヌシ或ウフヤ),而宫古群岛的酋长则称「丰见亲」(トゥユミャ)。高级按司敬称为御殿(ウドゥン);低级按司的敬称为御前(ウメー),其子孙称按司前(アジメー)。一般笼统的称为御殿。按司的采地称按司地头。原则上,按司同亲方一样,会被授予一个间切的地头。受日本文化影响,有时也把领有一个间切的按司称为「大名」(デーミョー)。据《琉球藩臣家禄记》记载,琉球国末年共有25家按司。这25家分别是:\n\n### 文章 64\n\n238号州际公路\n238号州际公路(Interstate 238,简称I-238),是美国的一条州际公路,全线位于加利福尼亚州旧金山湾区,是加州高速及快速公路系统的一部份。该公路自圣利安卓880号州际公路分出后向东,于卡斯楚谷衔接580号州际公路,全长。虽然公路是东西走向,标志却以南北向标记。由圣利安卓往卡斯楚谷记为南向,反之为北向。238号州际公路是加州中谷地区通往奥克兰港的主要道路,由于580号州际公路在卡斯楚谷至奥克兰路段不准货车通行,所有货车必须由238号州际公路转880号州际公路进出奥克兰,因而造成该公路常有拥塞情形。I-238在1983年被纳入州际公路系统。但这个编号并不遵守州际公路系统的编号规则(38号州际公路并不存在),如果依规则,这条公路的尾数应为80,目前在加州地区未使用的编号有I-180和I-480,但180号加州州道仅离本路段约100哩(在弗雷斯诺附近),480号加州州道计划在1991年才取消(原路线位于旧金山),为避免用路人混淆,加州公路管理局决定暂不使用这二个编号,而使用公路升级前的编号238。238号州际公路在1983年以前是238号加州州道的一部份,238号加州州道大体上是南北走向,此乃238号州际公路被编为南北向的原因。I-238在与I-580衔接处有另一出口继续接往238号加州州道向南通往海沃德。238号州际公路在1956年升级成为高速公路,但在1964年以前,这个路段并未指定任何编号。原本的计划是在费利蒙境内的238号加州州道至680号州际公路段亦会升级成高速公路(与880号州际公路平行),但在1968年向联邦申请未果,且数度上诉失败后,这个计划无疾而终。在880号州际公路被纳入州际公路系统的同时,这段路亦被纳入系统。美国州公路和运输官员协会在1983年7月7日批准了I-238和I-880这二个编号。I-238二端的系统交流道随即开始改建,加入缺少的I-238往I-880南向的匝道(原本以作为联络道之用)。1990年代,随著湾区捷运都柏林/普莱森顿─密尔布瑞线的动工,I-238的分隔岛交由捷运局作为舖设铁道之用。2009年,全线拓宽为六线道,拥塞情形稍有改善。"注意:哩程数前方若无字母,表示1964年的量测值,由于路线有稍做更动,哩程可能不准确。"238号州际公路全线位于阿拉米达县。\n\n### 文章 65\n\n温哥华太阳报\n《温哥华太阳报》()是一份于加拿大温哥华发行的报纸。该报于星期一至星期六以大报形式发行,母公司是。尽管《温哥华太阳报》的记者人数近年已大大缩小,该报仍然拥有温哥华最大的新闻团队。随著邮报传媒于2015年收购太阳传媒集团(),后者于多伦多、渥太华、温尼伯、卡加里和爱民顿以《太阳报》之名发行的小报自此与《温哥华太阳报》附属同一集团,但《温哥华太阳报》继续保持以大报形式发行。《温哥华太阳报》自1985年起,年年赞助「温哥华太阳长跑」(),该活动是北美最大的公路长跑活动之一。《温哥华太阳报》于1912年2月12日创刊,开业初期的总部位于片打西街125号,与该报当时的竞争对手《省报》()的总部相距不远。《太阳报》于1917年收购《每日新闻广告人报》()后改称《温哥华每日太阳报》(),1920年则改回原称。该报再于1924年收购长期受财务问题困扰的《温哥华世界报》()。《太阳报》的办事处于1937年3月发生火警,唯一一个伤者是一名被轻微烧伤和吸入浓烟不适的清洁工。《太阳报》事后迁进前《世界报》的总部大楼,并随即将之命名为太阳报大楼。《温哥华太阳报》和《省报》于1958年联手创立太平洋出版社()以控制两报不断上升的开支,但两报仍隶属不同东主。两报首先合并其技工及财务部门,后于1965年12月27日一起迁进新建的太平洋出版社大楼。《太阳报》东主克罗米家族于1963年将该报售予FP出版公司,而该报再于1980年售予《省报》东主修咸报业(),两报自此隶属同一集团。两报再于1997年迁至温哥华市中心的固兰湖广场大楼。《太阳报》连同母公司修咸报业于2000年被加西环球通讯公司收购,其报章业务后来重组成加西传媒出版公司()。加西集团于2009年进入破产保护后,《太阳报》连同加西传媒旗下其它报章于2010年售予邮报传媒网路公司。为了吸引大温地区的华裔读者,《太阳报》于2011年推出中文版网站。邮报传媒于2016年宣布削支行动,当中包括合并《温哥华太阳报》和《省报》的新闻团队,但两份报章继续分开发行。\n\n### 文章 66\n\n基本公正原则\n基本公正原则(Fundamental Fairness Doctrine)是一种美国宪法上的原则,只要被法院认定是一种基本权,依据「正当法律程序」条款的要求,该项基本权即可适用至州。至于究竟权利法案的哪些内容可以适用至各州,采取的是「基本权」(Fundamental Rights)的方法,即只有那些「作为吾人一切公民暨政治制度基石的自由与正义基本原则」所默示权利,或那些「秩序井然的自由」(ordered liberty)概念所默示包括的权利,才能包含于「正当法律程序」条款之中。由于此项原则具有高度的灵活与不确定性,因此受到批评。black大法官于Duncan v. Louisiana(1968)的协同意见书表示,设若采取「基本公正原则」,将会使得正当法律程序条款的内容,取决于部分法官的伦理以及道德观念,而不受宪法明文的限制。于过去的历史中,并未表示正当法律程序条款的宪法上控制,并须依靠法官的价值观。因此,20世纪60年代以后,法院逐渐往「合并原则」,尤其是「选择性合并原则」迈进。于Powell v. Alabama(1932)中,决定一项权利是否包含于增修条文14条,必须判断该权利是否「作为吾人一切公民暨政治制度基石的自由与正义基本原则」。而「受律师协助权」对被告来说是一项「基本权」,在没有提供有效律师辩护的情况下被定罪和判刑,违背了「正当法律程序」条款的要求。于Palko v. Connecticut(1937)中,法院认为有些权利隐含于秩序井然的自由(order liberty,又译为命令性自由,亦有译为有序自由)的概念之中,因此可以透过增修条文14条适用于各州。但是法院认为「不受双重处罚」条款并不是「基本权」(Fundamental),不能透过增修条文14条适用于各州。于Adamson v. California(1947年)中,法院认为增修条文14条「不自证己罪」条款仅是对联邦政府的限制,不能适用于各州。房保国著,美国刑事正当法律程式规则的考察,2002年汤德宗著,「政府资讯公开请求权」入宪之研究,页10,2005年魏晓娜著,法理与论争:美国刑事正当程式的范围,2007年\n\n### 文章 67\n\n乔治·温斯顿\n乔治·温斯顿(,),是一位美国钢琴家兼作曲家。乔治·温斯顿出生在密歇根州,并在蒙大拿州和密西西比州长大,他毕业于佛罗里达州戴兰德市的斯特森大学,居住在加利福尼亚州的旧金山 。他的大多数作品因为能使听众感到大自然的风景,并且反映了四季的精髓,给听众闲适、轻松、怡然、清新的感觉。乔治·温斯顿被誉为“新世纪音乐之父”,而他本人却回避这个说法,乔治·温斯顿称自己的音乐为“乡村田园钢琴曲”。乔治·温斯顿于1972年录制了自己的第一张专辑为《民谣与布鲁斯》(Ballads and Blues),当时并没有得到多大的反响。而直到1979年,威廉·阿克曼(William Ackerman)与他谈起为他的新唱片公司录制专辑的事情。起初,乔治·温斯顿只是用夏威夷吉他弹奏了一些简单的音乐作品,之后有为电台的夜间节目做背景音乐,这样也就成为了乔治·温斯顿的专辑《秋日》(Autumn)。在音乐中,他将秋日描述成为万圣节的颂歌。这张专辑《秋日》后来被听众大受好评。之后他的专辑《十二月》(December)和《辞冬》(Winter into Spring)都获得了白金唱片的称号,并在1996年的的格莱美奖中获得最佳新世纪音乐专辑。由于他对史努比花生漫画的喜爱,他在1996年制作了音乐专辑《Linus & Lucy-The Music of Vince Guaraldi》,这张专辑是献给格拉第(Vince Guaraldi)为花生漫画所做的音乐。在2002年他将19世纪60年代门户合唱团(The Doors)的音乐制作成专辑《Night Divides the Day - The Music of the Doors》,与其不同的就是音乐使用的是钢琴的独奏,并且音乐更加的恬静怡然。在乔治的音乐会上,乔治本人并不是一个特别爱表现自己的人,而是衣着十分简单,法兰绒衬衫和牛仔裤。秃顶、一脸的胡子,根本不像是在音乐会为听众表演的演员,反而经常被观众认为是为钢琴调音的技术人员。除了作曲和演出,在音乐会上乔治也会给观众演奏口琴和夏威夷吉他。他演奏这些乐器主要在音乐会上,并非在专辑中。在专辑《Remembrance - A Memorial Benefit》可以听得到这两种乐器的使用。他为自己的唱片公司Dancing Cat Records制作过夏威夷吉他的录音作品。\n\n### 文章 68\n\n魔岩唱片\n魔岩文化股份有限公司于1992年成立,1995年品牌更名为魔岩唱片股份有限公司,2001年结束营业。魔岩唱片创立人为张培仁,他于1991年初获母公司滚石唱片同意,离开滚石唱片副总经理职位,成立魔岩文化,并在魔岩旗下成立「中国火」品牌,经营以北京为主的中国摇滚音乐。同时在台湾开设编辑出版部门,编辑以会员为主的《滚石杂志》,以及系统艺人书籍及乐谱。魔岩的名字由来,据张培仁的访问说法,是因为滚石系列的子公司都以「石」为名,他希望能比石更恢宏,因此叫「MagicStone」。而「魔」,则是他认为当时的音乐环境充满各种伪善的声音,因此比照武侠小说的故事,认为自己比起市场中的名门正派,他更像魔教中的人,对保守的环境也许是一种异类,但也是一种自由的自我的展现,因此取名「魔岩」。魔岩的成立及其出版路线,以另类的思考为出发,与市场有明确的区隔,造成当代华语流行音乐的巨大影响,在市场上也能取得显著成绩。对热爱流行文化的年轻人而言,在受到全球文化影响时,既受到其自由创作的震憾,也同时在渴盼能有自身文化的环境中,创造出来的音乐带有同等份量的精彩。魔岩唱片是华语唱片史中,可能唯一或最清楚的呈现年轻文化理想,又能成功在市场中推动的代表者。其成功是在当时环境中充斥著偶像与抒情的环境中,永远相信人才的价值,把最被市场怀疑与否定的作品在市场中推出,能无视于当时市场的主流声音及媒体环境,让自由思想的作品可以大量流传。魔岩也是少数华人年轻文化理想主义被证明成功的案例,在主流媒体与以学者为主的评论界,它有时被视为另类,有时被视为商业,但多数人都肯定,华人的摇滚音乐可以成为市场中被广泛接受的音乐类别,并有多元的创意能力,要归功于魔岩唱片在20世纪90年代的努力。它的第一阶段魔岩文化(中国火)的发行是透过滚石唱片,在1995年台湾魔岩唱片之后才拥有自己的发行部、拥有自己的发行编号。如下:\n\n### 文章 69\n\n旧上水警署\n旧上水警署位于新界上水上水乡莆上村,在1902年建成,被古物古迹办事处列为二级历史建筑。现时警署已改建为大埔区少年警讯会所。旧上水警署于1902年兴建,是英国于1899年接管新界后旋即兴建的的十三间警署之一。旧上水警署是新界第六个永久警署,故亦被称为「六号警署」,在1930年代这所警署曾是新界各区中仅有电力供应的警署。1941年至1945年日本占领香港期间曾改作日军分区总部。1945年投降后继续由香港警队之用。1979年,上水警署搬到位于粉岭的新址,原址则改为警民关系组办公室。1993年后来改为少年警讯会所至今。旧上水警署是其中一间现存最古老的新界区警署,其位置在上水乡中央 — 昔日北区最繁盛的地方之一,传统宗族社交地点如廖万石堂、明德堂及书塾等近在咫尺,附近有大量村屋围绕,其位置反映当时英国需要在传统社区中建立其统治威信,维持法律及社会秩序,同时亦能与传统宗亲社会和睦共处的策略,所以建筑物能反映英国殖民地时代的历史,拥有一定文物价值,故古物古迹办事处现建议列为二级历史建筑物。另外一件关于旧上水警署的故事,在1915年,新界曾有老虎出没,当时旧上水警署的警员接报到场,射杀老虎,但其中一个警员被咬死。事后老虎的头被送往当时的大会堂作展览,现时虎头仍保存在警队博物馆供观众欣赏。此外,因它有一口水井,过往警署亦负责向整个新界区内多个警岗供应食水。警署一直服务北区居民达四分之三个世纪,直至1978年才由新上水警署接替。当时除了担当执法工作外,警署更提供免费疫苗防治疟疾,而在水荒期间,警署更为打鼓岭一带居民供水。旧上水警署是典型的英国维多利亚时代建筑,以新古典主义特色设计。两层高的建筑物正面有拱形的柱廊,是典型的热带殖民地建筑,有助挡雨遮阳而又无碍通风。柱子上有少量装饰,例如凸出的额枋、拱心石及模块状的柱子顶部等。最初屋顶是以中式瓦砖铺成的斜顶,现时已经被更改为平顶。建筑物两旁有观察用的塔、防卫用的矮墙和观察孔。部分木门和窗户仍然保留良好,这非常好。1979年3月警署改建为前边境区少年警讯会所,成为全港最大的少年警讯会址。1993年上水分区并入大埔警区,自此大楼由大埔警区接管。大楼在2006年重修,并增加更多康乐设施,包括电脑房、图书馆、摄影室、历史室、无火煮食室及陶瓷室,旧饭堂则成为一个多用途礼堂。\n\n### 文章 70\n\n冉广岐\n冉广岐,因“唐山地震青龙县无人因震伤亡事件”为人所知,但是真实性存争议。冉广岐,1976年时任中国河北省秦皇岛市青龙县县长。冉广岐在1976年7月28日唐山大地震发生前夕,下令全县所有人疏散,令该县在地震发生时,没有任何人因地震死亡。1975年海城地震发生后,京、津、唐地区受到地震预报有关部门监视,并一直持续到唐山地震发生之前。中国政府最终没有得到来自国家地震局方面提供的短期地震预报(有消息称早在大地震爆发前半个月,国家地震局分析预报组就已经预测出7月22日到8月5日。然而主持「全国地震预防工作经验交流会」的国家地震局副局长却不准时任京津组组长的汪成民在会上作震情发言。汪成民在17、18日的晚间座谈的时候和部分同志讲述了京津渤张地区集中出现的异常现象,并预测「7月22日到8月5日,唐山、滦县一带可能发生5级以上地震。现场只有22岁的青龙县科委主管地震工作的人员王春青听完汪的讲话后,他火速赶回县里,将汪的讲话告诉了县领导冉广岐,在深思熟虑之后,命令全县800多名干部迅速将震情通知到全县每一个人,经过周密部署,全县近40万人进入临震状态)。而唐山市最终对此地震没有积极预防。河北省青龙县在全县范围内采取了预防措施,取得了令人瞩目的防震减灾效果。全县无一人直接因地震丧生,仅一人因心脏病突发死亡。冉回答说,“唐山跟青龙没法比。青龙是农业县,让老百姓出去防震,啥损失也没有。大伏天的也就是蚊子多叮几个疙瘩呗。唐山不同啊,钢铁公司、开滦煤矿,作决策的人自己不敢作主”在百度青龙县贴吧里,当地大多数老百姓否认冉广岐的这些新闻,具体信息请阅读下面的网址:http://blog.sciencenet.cn/blog-647503-596797.html从当地人的地震记忆里看,冉广岐救人可能是一个恶意的假新闻典型。\n\n### 文章 71\n\n镰刀龙科\n镰刀龙科(Therizinosauridae)意为「镰刀蜥蜴」是兽脚亚目镰刀龙超科的一科。镰刀龙科是群草食性或肉食性的动物,生存于白垩纪中到晚期,化石已在中国、蒙古、美国等地发现。镰刀龙科具有大型前肢,长指爪,身体宽广,脚部具有四个趾爪。牠们的头部小型,颈部长,嘴部前端缺乏牙齿,嘴部后段的牙齿平坦。前背部的脊椎具有高的神经弓,背肋宽,臀部结构类似鸟类。宽广的臀部显示,牠们可能具有长的消化系统,以用来消化植物。根据系统发生学的位置,以及在北票龙身上发现的类似羽毛的覆盖物,镰刀龙科(或镰刀龙超科)可能都具有类似的覆盖物。镰刀龙科是由叶甫根尼·马列夫(Evgeny Maleev)在1954年建立,以包含新发现的镰刀龙,但当时马列夫认为牠们是种类似乌龟的巨大动物。长期以来,镰刀龙科是认为是群奇特的兽脚类恐龙,可能是肉食性。随者更多镰刀龙科近亲的化石被发现,原本观念遭到质疑。这些新化石是草食性动物、具有许多奇异特征,外表介于鸟臀目与原蜥脚下目之间。这些新发现物种被归类于慢龙科(Segnosauridae),意指牠们的沉重身体、短后肢,可能采取类似树櫴的生活方式。后来的研究发现镰刀龙不属于鸟臀目、原蜥脚下目,是种奇特的兽脚类恐龙,属于草食性,其近亲是同样奇特的慢龙。由于镰刀龙科的建立早于慢龙科,因此具有优先权,而慢龙科成为镰刀龙科的次异名。在1998年,保罗·塞里诺(Paul Sereno)首次对镰刀龙科提出系统发生学定义,定义为:亲缘关系接近死神龙,而离似鸟龙较远的所有物种。随者更多大型镰刀龙类化石的发现,镰刀龙科与其他兽脚类恐龙的演化关系更为明确,镰刀龙科的范围更为狭窄。在2005年,保罗·塞里诺将镰刀龙科重新定义为:包含镰刀龙、懒爪龙、内蒙古龙在内的最小演化支。以下演化树是根据菲力·森特(Phil Senter)在2007年的研究:\n\n### 文章 72\n\n梅方\n梅方,是一名中国足球运动员,场上位置是后卫,现在效力于中国足球超级联赛球队广州恒大。梅方出自武汉光谷青训体系,2008年进入武汉光谷一线队。当年8月,他和队友汪洋一起法乙球队斯特拉斯堡试训。 10月初,武汉光谷因不满中国足协的判罚而宣布退出中超联赛。梅方和汪洋再次到欧洲接受试训,11月前往德甲球队沃尔夫斯堡, 12月初又一起在比利时球队色格拉布鲁日试训。 梅方和汪洋都同时得到色格拉布鲁日的肯定并被邀请签约,但是两人回国后却因为湖北队将参加2009年的全运会而被湖北省足协大力挽留。最终梅方决定放弃留洋,留在武汉加盟了刚刚成立的湖北绿茵。梅方在2009赛季是湖北绿茵的主力球员,帮助球队杀入该赛季中乙联赛决赛,升级到中甲联赛。在决赛中,梅方射进球员生涯的首个联赛进球,不过他在点球决战中第一个出场并罚失点球,最终湖北绿茵不敌湖南湘涛屈居亚军。 2010年1月,他再次拒绝色格拉布鲁日的邀请,留队征战中甲联赛。 他在中甲联赛中继续作为球队的主力出战,并在2012年初和球队续约两年。 2012年3月,他被任命为球队的新任队长, 并在2012赛季率领武汉卓尔以联赛亚军的成绩升级到中超联赛。2013赛季,武汉卓尔在中超的成绩不佳,一直位于降级区。2013年8月18日,在联赛第21轮客场1比5惨败给广州富力后,武汉卓尔宣布剥夺梅方队长的职务。武汉卓尔以联赛倒数第一名的成绩降回中甲联赛后,合同即将到期的梅方一度传出有可能会转会到北京国安。 不过在2014年1月1日,他选择自由转会加盟中超卫冕冠军广州恒大。 2014年2月26日,梅方在2014年亚足联冠军联赛小组赛首轮广州恒大主场4比2逆转墨尔本胜利最后时刻替补亚历山德罗·迪亚曼蒂出场,首次代表广州恒大参加正式比赛。2014年6月18日,梅方在中国2比0击败马其顿的友谊赛首发出场,上演成年国家队首秀。2015年1月,梅方入选中国国家男子足球队2015年亚洲杯23人大名单,并成为球队主力后卫之一,可担任中后卫以及边后卫。\n\n### 文章 73\n\n尼古拉·巴通姆\n尼古拉·巴通姆(,),生于法国利雪,职业篮球运动员,在2008年NBA选秀中第一轮第25顺位被波特兰开拓者选中,在参加NBA选秀前,巴通姆已经是欧洲赛场上最富天分的年轻球员之一。 他曾荣获2006年安纳海姆艾伯特史怀哲U-18锦标赛最有价值球员。Albert Schweitzer Tournament2米03的巴通姆,最初就司职小前锋位置,他有着得分后卫般跑动得分的能力。在2007年耐克尖峰对抗赛(Nike Hoop Summit)上巴通姆有着夺人眼球的表现,在28分钟的比赛中,得到了23分(命中9/13 FG, 三分3/5)4篮板和4抄截。巴通姆随法国队赢得了2004年FIBA欧洲青年锦标赛。法国队在2005年蝉联了欧洲冠军,巴通姆则问鼎最有价值球员。.巴通姆早2005欧青赛7场比赛数据为:巴通姆在2006-2007赛季中在每场13分钟的出场时间里得到场均3.4分(65.9%命中率), 2.5个篮板, 0.5次助攻2007-2008赛季中他在场均上场28分钟的时间里得到了12.3分(52.3%), 5.0 个篮板和3.6次助攻。在四分之一决赛中,法国队实力不济被西班牙队反超比分后尼古拉斯·巴图姆以一个散打的动作,重重地打在了西班牙后卫纳瓦罗的裆部。2012年12月17日,巴通姆为波特兰拓荒者出赛,在42分钟内拿下11分、10助攻、5篮板、5抄截、5阻攻,成为史上第八位拿到5x5的NBA球员。2015年6月24日,巴通姆送到黄蜂,换来Gerald Henderson与Noah Vonleh。Batum合约最后1年年薪来到1180余万美元,因此这桩交易可让拓荒者省下400万美元,至此拓荒者就可用空出的4300万美元竞逐自由球员。上季转战夏洛特黄蜂,打出联盟顶尖全能前锋身价的「法国飞人」巴图(Nicolas Batum),在今夏约满投入NBA自由球员市场后,开市首日便传出好消息,确定与黄蜂达成5年1亿2000万美金的续约协议。\n\n### 文章 74\n\n和弓\n和弓,是日本弓道所使用的一类长弓。标准的和弓长度为七尺三寸(约221公分)。古时和弓称为「大弓」,泛指总长度超过两米的所有长弓。此外也有一种较短的和弓制式,长度为六尺三寸(约189公分)称为「半弓」,也存在比半弓还要短的弓。使用者执弓的位置主要是弓的下弧部份,长度比例是全弓的三分之一。和弓本来是由竹与木再以鳔(胶原料的一种)组装而成,现在组制竹弓多数使用玻璃纤维强化塑胶。一般而言,西洋弓(主要指奥运射箭项目中较常用的反曲弓,即Archery)约有1.6米的长度,使用时持弓者通常都掌握在弓的中心部位。不过,和弓与其它的弓却大不相同。和弓长逾两米,而且弓的上弧部份共占了全弓长度的三分之二,换言之和弓的制式是「上长下短」,其规格及长度亦可称得上是世界最大的弓。和弓上长下短的构造,某程度上为使用者带来执弓时难以平衡的困扰。要精确使用和弓,必须有高水准的技术,使用者持弓的手要掌握发箭时弓的震动幅度,预测弓上下弧的长度差所产生的反动力,并运用这种反动力推算箭的发射方向及应要施加力度的多寡。只要能妥善利用这种反动力,射出的箭轨便可以做出多种不同的变化(例如控制射程、箭的抛物线等)。另有一种非武术用途的和弓和箭,称为破魔弓及破魔矢,两者都是日本的仪式福物。现代的破魔矢,多指当地老百姓在日本新年时,从寺庙、神社等地方祈福后所得到的祝福饰物;破魔弓则是与破魔矢并存的配套摆设。日本人在搬屋或新置物业的时候,都会进行名为「上栋式」的仪式,做法大致是将经开光后的破魔弓矢放置到新屋的横梁上,目的是要利用「神器」形式的弓矢镇压著「鬼门」。如有亲友添丁,亦有赠送破魔矢、破魔弓的习俗。日本神奈川县有「破魔矢奉制所」,专门制作受神社祝福的小型破魔弓矢,后来该店更登记「破魔矢」为其合法商标。破魔矢主要功能在于「无形」的破除邪魔、净化,非「有形」的直接以箭穿刺邪魔,故破魔矢不须造有尖锐的箭头,普遍为平头或圆头。\n\n### 文章 75\n\n肖恩·布拉德利\n肖恩·保罗·布拉德利(Shawn Paul Bradley,),美国退役篮球运动员,身高2米29,场上司职中锋。他是NBA历史上身高第三高的球员。布拉德利大学就读于杨百翰大学,由于他的身高而广受关注。1993年,布拉德利在当年的NBA选秀上于第一轮第二顺位被费城76人队选中。布拉德利很快成为了一个盖帽机器,但是进攻效率低下。他虽然有一手跳投功夫,但是总找不到合适的出手时机。另外,由于布拉德利始终无法增加足够的体重,令其在对抗力量型的内线球员时往往显得软弱。布拉德利先后效力于费城76人队(1993-1996)、新泽西网队(1996-1997)和达拉斯小牛队(1997-2005)。2004年,由于受到膝盖伤势的困扰,布拉德利在同新来的埃里克·丹皮尔的竞争中落入下风,沦为边缘球员。2005年季后赛结束以后,布拉德利宣布退役。布拉德利职业生涯一共2119次盖帽,截至到2012-13赛季结束在NBA总盖帽榜上排名第13,换算到每场也有恐怖的2.54个。他职业生涯一共获得6次三双,全部都是得分+篮板+盖帽的形式,其中1998年4月7日,在达拉斯小牛队91-99负于波特兰开拓者队的比赛中,他替补出场得到22分22篮板13盖帽的大号三双,堪称其职业生涯代表作。值得一提的是,在初进联盟之时,76人队对布拉德利寄予厚望,甚至首度地同意他穿上代表球队的76号球衣,此前连球队历史巨星朱利叶斯·欧文在加盟时要求穿上76号都未被允许,只得改穿6号。而使他被中国球迷熟知的,是在2005年季后赛首轮达拉斯小牛队对阵休斯顿火箭队的第二场比赛中,他被火箭队的特雷西·麦克格雷迪骑扣。由于有德国血统,布拉德利在小牛队友德克·诺维茨基的劝说下加入了德国国籍,并曾代表德国队夺得2002年世界篮球锦标赛铜牌。从职业篮球的球场上离开之后,布拉德利成为了位于犹他州西佐敦的西脉私立学校的一名教员,那是一所为问题青少年提供帮助的特殊学校。2010年3月,布拉德利宣布参加犹他州众议员选举。\n\n### 文章 76\n\n尚元王\n尚元(;)是琉球国第二尚氏王朝第五代国王。他是第四代国王尚清王的第二王子。1556年至1572年在位。神号日始按司添()。童名金千代(),一作鹤千代()。据《中山世谱》记载,尚元原是尚清王生前指定的继承人。但1555年尚清王死后,法司葛可昌(城间亲方秀信)、和为美(国头亲方景明)却突然变心,欲拥立尚清王第四子尚鉴心为君。法司毛龙吟(新城亲方安基)提薙刀叱责二人。群臣多有支持毛龙吟者,因此和、葛二人畏惧而不敢复言。于是尚元在继承权争夺之中胜利,并于次年即位。1559年,将和为美流放久米岛,葛可昌流放伊比屋岛。1562年(嘉靖四十一年),明世宗派遣刑科给事中郭汝霖、行人李际春为册封正副册封使封尚元为王。尚元王体弱多病,常常无法正常管理国事。为了保证朝政的正常运行,琉球王府推举了三名法司为其代理。从此琉球王府中法司的人数定例为三名,这三名法司被统称为「三司官」。朝政基本上掌握在毛龙吟等三司官手里,因此尚元王被称人为「哑巴国王」()。 尚元王死后,三司官的制度被保留了下来。尚元王在位期间,琉球与明朝保持良好的外交关系,多次送还漂流至琉球境内的中国船民。1565年(嘉靖44年),倭寇过境琉球,在北山地区为琉将郑都所败。尚元王遣使将被倭寇虏获的中国人口送还明朝。尚元王也曾一度与日本萨摩藩保持良好的关系,然而在1570年至1572年,双方关系出现两次危机。1570年,萨摩岛津贵久的使者雪岑和尚至琉球,要求尚元王向萨摩朝贡,遭琉方拒绝。岛津大怒,煽动奄美大岛酋长发动叛乱,并向奄美派遣军队,给奄美的酋长提供军事上的支持。1571年,尚元率船五十余只御驾亲征,在奄美大岛两次与萨摩军交战,败萨军,俘杀叛变的酋长。归军途中,尚元王病危,三司官马顺德(国头亲方正格)对天祈祷愿代王死,不久尚元王竟果然病愈。尚元王大为感动,封马顺德之子为按司,称国头御殿,世代袭爵。1572年4月1日,45岁的尚元王病逝,次子尚永继位。\n\n### 文章 77\n\n邓飏\n邓飏(),字玄茂,南阳新野人。是东汉太傅邓禹的后代。与夏侯玄、诸葛诞和田畴并称为「四聪」。三国时曹魏大将军曹爽的党羽。邓飏年少时在洛阳已有令名。但据说其貌不扬,管辂谓之「鬼躁」、「行步弛纵,筋不束体,坐起倾倚,若无手足」。魏明帝时任尚书郎,曾任洛阳县令。后任中郎,入兼中书郎。在中书省因与李胜等人作风浮华而被魏明帝免职,不再任用。景初三年(239年)魏明帝逝世,遗诏命大将军曹爽和太尉司马懿辅助幼主曹芳。曹爽其后架空司马懿专政,任命邓飏为颍川太守,后转任大将军长史,迁侍中、尚书,作为曹爽的党羽、腹心。及后李胜和邓飏为了令曹爽立威信,建议曹爽征伐蜀汉,曹爽听从并于正始五年(244年)从长安率兵经骆谷伐蜀。但当时关中和氐、羌族的物资供应出现问题,令曹爽军缺乏军资而令大量牲畜死去。当地平民和外族亦因缺乏物资而生活困难,在道上号哭。另一方面,蜀汉军队已到,并在骆谷附近依山而守,曹爽不能前进。曹爽参军杨伟此时向曹爽解读形势,劝曹爽尽早撤军,否则必定会吃败仗。李胜和邓飏反对撤军,并与杨伟争论,杨伟于是向曹爽说:「李胜和邓飏此举会破坏国家,可以处斩。」曹爽感到不快。同时,司马懿写信给当时任征西将军,都督雍、凉诸军事的夏侯玄,预测曹爽必败,应该尽早撤军,并恐吓他一旦曹爽惨败可能会负上罪责。夏侯玄于是劝曹爽撤军。曹爽最终撤军,蜀汉大将军费袆从后领兵在山谷截击曹爽军,曹爽军苦战之下才得以逃出,但士兵伤亡甚多,关中因而大为损耗。邓飏亦常受赂,举荐的人都不是因为他们的才华。例如曾答应臧艾让他当高官,臧艾就以父亲的妾待送给邓飏作为报答,所以当时洛阳人都说:「以官易妇邓玄茂」。正始十年(249年),曹爽兄弟陪同皇帝曹芳到明帝高平陵扫墓,此时司马懿发动高平陵之变,封锁洛阳城和接管曹爽和中护军曹羲的军队。曹爽兄弟最终都决定向司马懿投降。事后曹爽被控告谋反,邓飏等党羽都曹爽一同被捕,被指控与曹爽同谋,其后被诛杀、夷三族。\n\n### 文章 78\n\n王家瑞\n王家瑞(),河北秦皇岛人。1970年6月参加工作,1973年10月加入中国共产党。吉林大学经济管理系国民经济管理专业、复旦大学研究生院经济管理专业毕业,在职研究生学历,经济学博士,高级经济师,教授,博士生导师。曾任中共中央对外联络部部长。现任第十二届全国政协副主席。1970年6月,任吉林省长春市邮局投递员、会计。1972年4月,在上海海运学院远洋系国际邮政英语班学习。1973年10月,任长春市邮局国际联邮员。1974年4月,任长春市邮局副科长。1976年9月,任吉林省邮电管理局邮政处负责人。1978年4月,任吉林省邮电管理局报刊发行科副科长。1980年11月,任吉林省邮电管理局邮政处副处长。1982年4月,任长春市邮政局副局长。1985年10月,任邮电部报刊发行局副局长、局长(1983年9月至1987年7月,吉林大学经济管理系国民经济管理专业在职研究生)。1992年7月,任国务院经济贸易办公室商业司副司长。1993年6月,任国家经济贸易委员会综合司副司长(1988年9月至1994年12月吉林大学经济管理学院在职研究生,获硕士、博士学位)。1994年12月,任国家经济贸易委员会市场流通司司长。1995年8月,任中共山东省青岛市委常委。1995年9月,任中共青岛市委常委、青岛市副市长(其间:1995年9月至1997年12月在复旦大学管理学院产业经济博士后流动站从事在职研究工作)。1997年12月,任中共青岛市委副书记、青岛市副市长。1998年2月,任中共青岛市委副书记、青岛市市长(其间:2000年3月至5月在中共中央党校进修一班学习)。2000年9月,任中共中央对外联络部副部长。2003年3月,任中共中央对外联络部部长。2013年3月,任第十二届全国政协副主席。2016年11月,当选中国宋庆龄基金会理事会主席。中共第十六届中央候补委员,第十七届、十八届中央委员。\n\n### 文章 79\n\n1998年中国足球甲A联赛\n1998年万宝路中国足球甲A联赛是中国足协举行的第10届中国足球甲级A组联赛,本届联赛扩军至14支球队。联赛于1998年3月22日展开,10月25日结束,大连万达夺得三连冠。本届联赛扩军至14支球队。历年甲A联赛中保级大战最为火爆的一次。在联赛还剩三轮的情况下除了广州太阳神队铁定降级之外,仍然有8支球队深陷保级泥潭。仅仅只有大连实德,上海申花,北京国安,广州松日和四川全兴5支球队没有后顾之忧。而如今的大牌俱乐部山东鲁能的保级之路更是艰险,先是在联赛倒数第二轮客场0比1输给沈阳海狮送后者保级成功,而后在最后一轮1比1主场打平武汉雅琪队后才勉强保级。而武汉雅琪队在倒数第二轮4比0主场大胜广州太阳神保级成功。延边敖东队在最后一轮逼平已经保级的沈阳海狮之后保级成功。最后一轮青岛海牛客场1比1逼平广州太阳神保级成功。深圳平安队倒数第二轮4比2战胜四川全兴,但在最后一轮0比2输给前卫寰岛,还好保级对手八一队最后一轮客场0比1输给四川全兴,所以深圳保级成功。前卫寰岛队则是最后一轮主场2比0战胜深圳平安后安心确定保级。所有最后两轮保级成功的球队都应该感谢四川全兴,因为他们最后一轮在无论输赢都排联赛第五的情况下依旧死磕对手1比0主场战胜八一队,使得这一年最后三轮联赛8选1支降级倒霉蛋的赛季里让八一队成为那支彻彻底底的倒霉蛋球队。纵观最后联赛排行榜,倒数第二名到联赛第六名一共8支球队一共只差三分,可见保级战的惨烈程度。从上赛季甲B联赛升级:从上赛季甲A联赛降入甲B联赛:10月25日,八一队降级,中国顶级足球联赛再无从未降过级的球队。\n\n### 文章 80\n\n原城\n原城()位于长崎县南岛原市南有马町乙。是国家级历史遗迹。位于岛原半岛的南部,明应5年作为日野江城的支城由有马贵纯所建。建在有明海出海口的丘陵之上,由本丸、二之丸、三之丸、天草丸、出丸构成。有马氏移封到日向国延冈城后,元和2年(1616年)松仓重政进入了日野江城,不过,由于一国一城令的影响放弃了不便的日野江城而建筑了岛原城。这时原城也被废城,石垣和构筑物也被移作他用了。在宽永14年(1637年)到宽永15年(1638年)的岛原之乱后,幕府把原城址残存的石垒等破坏了。昭和13年(1938年)原城址被认定为国家级历史遗迹。发掘调查时候,除了铅弹和十字架以外,也出土了万人坑。在元和的一国一城令成为了废城的原城,在宽永14年(1637年)时聚集全国的耳目。爆发了世称“岛原之乱”的事件。岛原藩主松仓重政、胜家父子由于岛原城建设的费用等的财政窘迫的缘故,实施苛政,并严酷地压制天主教,此事引发了农民起义。这起义不仅蔓延到岛原半岛和天草,岛原城和富冈城也被袭击了。可是,武装起义的攻城不顺利,不久武装起义的群众和天草菜的武装起义群众合流约3万7千人占据了成为废城的原城。总司令被认为是小西的家臣的子孙的天草四郎,组织开展了守城战与幕府军展开了战斗。武装起义军方面固守了3个月的城池没有兵站的补给,弹药和军粮耗尽了。幕府军在战死了千人的同时投入了生力军,终于,宽永15年(1638年)2月27日到28日(新历4月11日~12日)的总攻击将武装起义军毁灭了。幕府军战后,彻底地破坏了原城。岛原藩主松仓胜家由于引起了战乱的责任,前无古人地作为大名被斩首处置。从岛原铁道巴士 原城前站步行15分钟\n\n### 文章 81\n\n满洲国协和会\n满洲国协和会为满洲国的官民一体国民组织,起初石原莞尔等人期许本组织能担任未来一党执政的重任,然而在之后则受到日本大政翼赞会旗下各组织影响。九一八事变后,倡导从中华民国独立并施行君主政治以推动新国家建设的自治指导部为协和会的起源。满洲国建国后,自治指导部则转型为官民一体化的满洲国协和会。协和会与满洲国政府共同宣称推动建国理想(建设王道乐土),并以此对国民进行宣传教育。协和会章程规定:“本会以谋求满洲国的建国精神和宣扬王道乐土政治为宗旨。” 1936年7月25日协和会成立4周年举行纪念会,改名为“满洲帝国协和会”。同年9月18日,日本关东军司令官植田谦吉发表《满洲帝国协和会之根本精神》的声明,阐述协和会的本质,就是以皇民化为目标的“民族协和”,实施“建国精神”,即“以实现日满一德一心、民族协和、王道乐土、道义世界为理想的天皇的圣意”。满洲帝国协和会中央本部机构庞大,设有总务部、指导部、实践部、训练部、文化部、青少年部、调查部等10多个部门。协和会基础单位为分会,与每个地区设立。并于各地方行政机关设立本部,负责统括分会。取代从未开议的立法院,以分会代表进行的连合协议会为实质之民意机关。石原莞尔等人期待协和会能取代关东军成为「未来的领导者」,拥有一党执政的地位。不过随著关东军对满洲国统治的深化,满洲国逐渐成为日本完全的属国,协和会失去其存在意义。满洲帝国协和会为唯一永久、举国一致的实践团体,与政府互成表里。实现以上建国理想,创建道义世界。满洲国协和会(1932年、大同元年)成立时的主要干部满洲国执政(后皇帝)任名誉总裁,国务总理大臣任会长,各省长、县长兼任所辖地域的本部长。满洲帝国协和会中央本部旧址位于今中央大街82号,人民广场南200米处。东南接儿童公园,北隔咸阳路与长春市委大楼后身相对,西邻人民大街。该旧址是一座砖石结构的组合建筑物,地面建筑为两层楼房,另有地下室,建筑面积7955平方米,占地面积8749平方米。1950年修复为长春市文化宫,1958年由沈阳军区接管,改为军人俱乐部,后又将部分房舍改建为吉林省军区第二招待所。旧址保存较为完好。\n\n### 文章 82\n\n咱们死人醒来的时候\n咱们死人醒来的时候 () (When We Dead Awaken)是挪威剧作家易卜生的一出戏剧,出版于1899年,1900年在斯图加特第一次被搬上舞台。咱们死人醒来的时候是易卜生的最后一出戏剧,也是他最短的一出戏剧。第一幕在海滨浴场区。第二幕和第三幕在高山上一个疗养区附近。雕塑家鲁贝克教授崇拜唯美主义艺术,他年轻时创作了一座象征最理想的女人觉醒的大理石雕像。当时的模特儿,美丽的少女爱吕尼深深地爱恋他,并赋予他灵感,帮助他塑造成杰作《复活日》。他为了完成自己的事业,不“亵渎自己的灵魂”,没有接受爱吕尼的爱情,致使爱吕尼出走,变成放荡不羁的人。鲁贝克成名之后,娶爱好打扮和游乐的姑娘梅遏为妻。婚后,鲁贝克对梅遏逐渐感到厌倦,梅遏对鲁贝克也有同感。过了多年,鲁贝克一直没有得到爱吕尼的消息,他再也找不着那么好的模特儿了。现在,他的雕塑转向“大型群像”,这是大人先生们花钱订做的艺术品,他认为这些东西毫无价值,内心非常空虚惆怅。在一个海滨浴场上,鲁贝克夫妇与爱吕尼相遇。心灰意冷的爱吕尼见到鲁贝克,感到无比兴奋,向她倾诉了自己的不幸生活,还批评他过去奉行的“第一是艺术作品,其次才是人生”的信条。他们都为过去轻易放弃了幸福生活而惋惜,而且希望重温旧梦。他们终于挽手登上高处,又穿过雪地、迷雾,一直走上“朝阳照耀的塔尖”,结果,他们被大雪埋葬了。与此同时,梅遏为了寻求生活的乐趣,跟随猎手乌尔费姆去探险,过自由自在的日子。她在深谷里高兴地庆幸自己“像飞鸟一样的自由”。「当咱们死人醒来」是易卜生最具奇幻亦是最绝望的剧本。无论在剧里的发展从海滨到山上,以及鲁贝克是个雕塑家,都可见本剧以石头及石化的形象为主。而剧中的结尾爱吕尼及鲁贝克在寻觅多年后终于一起、双双穿过迷雾寻找自己的幸福却被雪崩所埋没,对比梅遏为了寻找人生的乐趣而快乐地跟随了她觉得长得丑得像法翁的猎手乌尔费姆,带出了人类对于生命的欲望,但那些渴求能否实现却是有所保留、而人们应该要为了自己的理想而放弃其他事物强行忍耐,抑或是及时行乐,给本剧留下了讽刺的结论。\n\n### 文章 83\n\n黄昆岩\n黄昆岩(),台湾新竹人,是国际上研究干扰素与感染免疫的知名学者,也是知名的人文讲座的教育家及作家。曾任国立成功大学医学院创院院长、全国医学院评鉴委员会(TMAC)主任、游说台湾加入世界卫生组织(WHO)之NGO团长、教育部医学教育委员会主任委员、国立成功大学医学院名誉教授、教育部顾问等职。黄昆岩的著作等身,其中《医生不是天使:一位医生作家的人性关怀》一书被多所医学院选为指定教材、《黄昆岩谈教养》一书引起广大回响,众多机关学校媒体推荐必读书目。黄昆岩毕业于国立台湾大学医学院,又在美国乔治华盛顿大学医学院获得微生物学博士学位,是国际知名病毒学家,他精通汉语、日语、德语、英语四种语言。 他对教育事业颇多贡献,创立了国立成功大学医学院。2012年,黄昆岩去世,在美国马里兰州伯塞斯达市殡仪馆举行了告别仪式,骨灰安葬于台湾。黄昆岩一共有3个女儿,均在美国求学。注:本表参考《我不一样的人生:黄昆岩自传》、《黄昆岩回忆录:成大医学中心创建始末》,联经出版、《黄昆岩教授追思纪念特辑》,国立成功大学医学院,2012.03.29出版。总统马英九于2012年3月29日颁赠褒扬令,内容为:「国立成功大学医学院创院院长黄昆岩,襟灵雅素,博约高华。少岁卒业台湾大学医学系,旋负笈游美,获乔治华盛顿大学微生物学博士学位,浸淫干扰素与感染免疫学,深沈宥密,术业专攻;执教国内外知名大学,涵濡启迪,宗匠陶钧。嗣应聘返国筹设成大医学中心,以宏观之视野,展惠民之壮图,覃思纾策,筚路蓝缕;咨诹察纳,严谨尽微,遂成南部医疗暨医学研究枢纽。爰接掌医学院,潜心倡导医学伦理,悉力护理教育品质,开办国际学者讲座,荐举医师进修研习;复膺任医学教育评鉴委员会主任委员,建构医护评鉴制度,大辂椎轮,创举多方;前瞻务实,裨益学验,诚迺台湾医学教育改革先驱。率团游说我入世界卫生组织,协助政府推动国民外交,志道依仁,理致清远。公余闿阐人文,作品精辟隽永,尤以《黄昆岩谈教养》一书,言教身教,靡然向风;斯文默化,沾溉人心。综其生平,育才具培德之功,懋绩兼猷为之美,弘声盛誉,前绪流咏;矩范仪型,名垂蓬岛。遽闻溘然长逝,悼惜弥殷,应予明令褒扬,用示政府崇礼邦彦之至意。」\n\n### 文章 84\n\n乙二胺\n乙二胺(作为配体时简称为en)是化学式为 CH(NH) 的有机化合物。乙二胺是一种胺类,为无色的碱性液体,有类似氨的臭味。2008年乙二胺的使用量约500,000,000公斤。乙二胺的制备可利用氨和1,2-二氯乙烷反应而成。反应后可得到乙二胺及其他线性多胺的混合物。简化的方程式如下:在许多工业用化学品的生产都会用到大量的乙二胺。乙二胺可和羧酸(包括脂肪酸)、腈、醇(加热时)、烷化剂、二硫化碳、醛及酮反应,产生对应的衍生物。由于乙二胺有二个胺基,故可以用作合成咪唑啉啶等杂环化合物的原料。乙二胺是典型的二齿配体,可形成配位化合物,如[Co(en)]。重要的六齿配体EDTA是乙二胺的衍生物,是由乙二胺透过Strecker法和氰及甲醛合成所得的产物。乙二胺的衍生物"N"-羟乙基乙二胺是另一种商业上常使用的螯合配体。由乙二胺和水杨醛缩合而产生的Salen配体是实验室研究常用的螯合配基,不过很少在工业上使用。许多有生物活性的化合物都包括 N-CH-CH-N 的官能基,如氨基菲林(aminophylline)及一些抗组织胺药。许多乙二胺的盐类已制成抗真菌剂的商品,商品名称有 Maneb, Mancozeb, Zineb 及 Metiram。有些含有咪唑啉结构的抗真菌剂也是由乙二胺所衍生。乙二胺由于有二个有活性的胺基,是许多聚合物制造的原料之一。乙二胺和甲醛的缩合物是一种增塑剂,广泛用在聚氨酯(PU)纤维的制造过程中。PAMAM等级的树枝状高分子(dendrimer)也是乙二胺的衍生物。漂白粉中常见的活性剂四乙酰乙二胺(TAED)是由乙二胺为原枓所制成。衍生的二硬脂酰乙二胺(EBS)是工业上常用的脱模剂,也是汽油及机油中的表面活性剂。乙二胺是一群称作「聚乙烯胺」的化合物中,分子量最小的化合物。其余的化合物包括:哌嗪则是由乙二胺衍生,结构上类似二恶烷(dioxane)的杂环化合物。若以生产量来看,乙二胺是产量第二高的二胺,仅次于己二胺-尼龙66的原料之一。乙二胺的二胺衍生物包括乙二胺有腐蚀性,会刺激皮肤。在体内的半衰期约30分钟,分布体积约为 0.133 L/kg。口服的生物利用度大约是0.34。肾脏只能代谢20%以下的乙二胺。\n\n### 文章 85\n\n莫德惠\n莫德惠,满族,中华民国政治人物。字柳枕,吉林双城人(今属黑龙江)。莫德惠1883年4月16日生于新疆其父的军营中。其父明海,1870年从左宗棠平定陕甘回乱,参与收复新疆之役。以军功晋佐领。1875年举家迁入吉林双城。1906年考入天津北洋高等巡警学堂,毕业后分配吉林省警察厅任西局局员,旋即升任西局局长。1910年调任哈尔滨警务局滨江巡警局局长。1912年冬,莫德惠以社会贤达被举众议院议员,这是他跻身民国政坛的发端。1914年袁世凯解散国会,莫德惠受奉天都督张锡銮之邀出任双山县知事并兼理司法,成绩裴然。1918年出任清理吉林官产处处长,继为吉林永衡官钱银号监理官,清查土地局会办、财政部顾问,吉林省公署顾问,奉天省公署咨议,吉林省依兰道道尹。1921年与在吉林剿匪的张学良相结识,1923年促成粤皖奉联合反对曹锟贿选,得到张作霖倚重,出任奉天财政厅长代理省长、北洋政府农工部总长。1928年6月,随张作霖返奉专车遇险负轻伤。张学良主政东北后,出任东北保安、政务、外交等各委员会委员。东北易帜前夕,衔命赴日折服田中不干涉易帜成功,为张的密切合作者之一。中东路事件发生后,他被委派为东三省铁路公司理事长兼督办,以中国方面首席代表身份赴莫斯科参加中苏谈判。谈判取得成效,后因九一八事变,协议夭折。1937年1月7日,由北平抵南京之东北元老莫德惠、刘哲往见张学良,张认为西北战端将起,有违其「兵谏」之初衷;称中央军进入潼关系何应钦主谋,促莫、刘二人往见何应钦劝阻用兵;张并致函杨虎城称,「此事仍有转圜办法,切盼勿发生战事」。抗战时期,1937年任国民政府国民参政会主席团主席。1945年10月任东北宣慰使、东北救济会副会长。1946年任制宪国民大会代表。1947年,任国民大会代表。1948年任政府宪政督导委员会会长。1949年随政府转进台湾,同年3月21日起任行政院政务委员。1954年8月任考试院院长达12年。任内曾着手改革考试制度与技术,推行职位分类,倡导考用合一,创办、改进公务员保险制度等。1966年5月转任光复大陆设计研究委员会副主任委员。同年6月20日任总统府资政。张学良被幽禁大陆期间,莫德惠曾多次探望过张学良。张学良到台湾后,莫依然是张家的常客。1968年4月17日,莫德惠逝世于台北,终年85岁。编订有《双城莫德惠自订年谱》。\n\n### 文章 86\n\n卢西亚诺·斯帕莱蒂\n卢西亚诺·斯帕莱蒂(,),是意大利足球主教练。史巴列堤于1959年出生于意大利佛罗伦斯省,球员时代是在家乡球会出道,司职中场。。然而综观其球员生涯,史巴列堤都是在一些意丙球会效力,因而从未入选国家队。1991年他回到恩波利,并在该球会踢至退役。史巴列堤是于恩波利展开其教练生涯。起先是以球员身份执教,后转任青年军教头,再于1995年作为正式主教练。其间他带领了恩波里从意丙升上意甲。之后再辗转执教森多利亚、威尼斯、乌迪内斯等球会。其中在乌甸尼斯期间,史巴列堤还带领球会打入欧冠杯。2005年他接掌罗马帅印。这时正值罗马的混乱时期,曾先后起用四个教练,然皆下野告终。为使球队注入生气,史巴列堤乃改变战术,采用主攻踢法,但不设前锋位置。结果罗马终于回复生气,并于2005-06年以联赛第五名完成球季。史巴列堤执教罗马期间,意甲基本上都是由国际米兰垄断,然而史巴列堤也有交出成绩:2006-07年球季赢得意大利杯;翌季也蝉联成功。而在联赛罗马也经常夺得亚军而具有欧冠杯参加资格。不过罗马始终财力有限,相比联赛前列分子,班底较为薄弱。2009年罗马出现财政危机,在意甲首两场联赛更遭逢两连败,结果史巴列堤主动提出辞职。2009年12月史巴列堤加盟俄罗斯球会辛尼特,签约三年。在其执掌教鞭的第一个球季,即率领辛尼特夺得联赛和杯赛的双冠王;接下来的第二个球季,又率球队夺得超级杯赛的冠军以及卫冕了俄超联赛冠军。直到他掌印的第三个球季,辛尼特花费巨资引进了浩克,维特塞尔等球星,希望借此在欧洲冠军联赛中大展宏图,但是该季球队反而在联赛中被莫斯科中央陆军反超仅夺得亚军。在该球季的欧冠联赛中亦在第一轮的淘汰赛中被德甲劲旅多特蒙德击败。2014年3月11日,辛尼特官方宣布与史巴列堤提前解除合约,其后史巴列堤没有执教任何球会。直至2016年1月,再次执教罗马,直至2016/2017球季离开,执教国际米兰。\n\n### 文章 87\n\n乙二胺\n乙二胺(作为配体时简称为en)是化学式为 CH(NH) 的有机化合物。乙二胺是一种胺类,为无色的碱性液体,有类似氨的臭味。2008年乙二胺的使用量约500,000,000公斤。乙二胺的制备可利用氨和1,2-二氯乙烷反应而成。反应后可得到乙二胺及其他线性多胺的混合物。简化的方程式如下:在许多工业用化学品的生产都会用到大量的乙二胺。乙二胺可和羧酸(包括脂肪酸)、腈、醇(加热时)、烷化剂、二硫化碳、醛及酮反应,产生对应的衍生物。由于乙二胺有二个胺基,故可以用作合成咪唑啉啶等杂环化合物的原料。乙二胺是典型的二齿配体,可形成配位化合物,如[Co(en)]。重要的六齿配体EDTA是乙二胺的衍生物,是由乙二胺透过Strecker法和氰及甲醛合成所得的产物。乙二胺的衍生物"N"-羟乙基乙二胺是另一种商业上常使用的螯合配体。由乙二胺和水杨醛缩合而产生的Salen配体是实验室研究常用的螯合配基,不过很少在工业上使用。许多有生物活性的化合物都包括 N-CH-CH-N 的官能基,如氨基菲林(aminophylline)及一些抗组织胺药。许多乙二胺的盐类已制成抗真菌剂的商品,商品名称有 Maneb, Mancozeb, Zineb 及 Metiram。有些含有咪唑啉结构的抗真菌剂也是由乙二胺所衍生。乙二胺由于有二个有活性的胺基,是许多聚合物制造的原料之一。乙二胺和甲醛的缩合物是一种增塑剂,广泛用在聚氨酯(PU)纤维的制造过程中。PAMAM等级的树枝状高分子(dendrimer)也是乙二胺的衍生物。漂白粉中常见的活性剂四乙酰乙二胺(TAED)是由乙二胺为原枓所制成。衍生的二硬脂酰乙二胺(EBS)是工业上常用的脱模剂,也是汽油及机油中的表面活性剂。乙二胺是一群称作「聚乙烯胺」的化合物中,分子量最小的化合物。其余的化合物包括:哌嗪则是由乙二胺衍生,结构上类似二恶烷(dioxane)的杂环化合物。若以生产量来看,乙二胺是产量第二高的二胺,仅次于己二胺-尼龙66的原料之一。乙二胺的二胺衍生物包括乙二胺有腐蚀性,会刺激皮肤。在体内的半衰期约30分钟,分布体积约为 0.133 L/kg。口服的生物利用度大约是0.34。肾脏只能代谢20%以下的乙二胺。\n\n### 文章 88\n\n王天成\n王天成,中国湖南省双牌县人,著名异议人士、政治学者。1989年毕业于北京大学法律系(现北京大学法学院),获硕士学位,同年留校任助教,兼任北大《中外法学》杂志编辑,旋即晋升为讲师。因参与创建“中国自由民主党”,担任该党宣传部长,王天成1992年10月被捕,1994年被北京市中级人民法院判处有期徒刑5年,剥夺政治权利2年,1997年10月刑满释放。王天成1999年所著文章《论共和国》、《再论共和国》,是中国学者较早系统阐述共和主义的作品,流传甚广,已成为汉语界在该领域的经典之作。王另与人合译有埃德蒙·柏克《自由与传统》、阿克顿勋爵《自由的历史》、路易斯·博洛尔《政治的罪恶》等西方学术名著。2005年11月,王天成发表文章指控武汉大学教授、博士生导师周叶中所著《共和主义之宪政解读》一书(2005年11月人民出版社出版),严重抄袭了其《论共和国》、《再论共和国》。周叶中是中国宪法学研究会副会长,2002年曾到中南海给胡锦涛温家宝等中共领导人讲课。该事件轰动一时,但法院判决周叶中没有抄袭,判决公布后备受非议,成为学界一大公案。王天成2008年赴美,先后在哥伦比亚大学、西北大学、纽约大学从事民主转型、制度设计研究。期间所完成的著作《大转型:中国民主化战略研究框架》(连载于《中国人权双周刊》,完整版2012年在香港出版),在大量民主转型案例研究的基础之上,系统探讨了中国民主转型路径与制度选择关键问题,被一些评论家认为是90年代初至今20余年中国政治学领域最重要的著作。2010年3月代表中国自由民主党与王有才发表联合公告,宣布中国自由民主党与中国民主党共同组建中国民主党全国委员会,4月当选中国民主党全国委员会执行长。2013年1月辞职,回归学术研究。2013年6月天安门民主大学开学,王天成任教务长。\n\n### 文章 89\n\n张孝骞\n张孝骞(,),字慎斋,湖南省善化县南门外马厂巷人,内科医学家及医学教育家。幼年在私塾学习《四书》、《五经》及古文,1914年以第1名毕业于长沙长郡中学,并以第1名的成绩被录取进入湘雅医学院。1921年复以第1名毕业,并获得金牌及美国康涅狄格州政府授予的医学博士学位。毕业后留校专攻内科,于1924年1月到北京协和医学院(今中国协和医科大学)深造1年,随后正式留任于该校,陆续担任住院医师、总住院医师。1926年9月被选送到美国约翰·霍普金斯大学进行研究,1927年7月回国续任,1930年在协和医学院组建消化专业组,1932年晋升为副教授。1933年12月再次赴美国史丹福大学研究,1934年7月回国后,担任协和内科消化专业组主管。1937年芦沟桥事变后,他放弃协和医学院的研究工作,回长沙接任湘雅医学院院长职务。1938年夏季,战火逼近长沙,他不顾美国雅礼会的反对,迁校到贵阳,再于1944年迁到重庆。抗战胜利后,于1946年8月迁校回湖南。随后应美国国务院的邀请赴美国考察医学教育和讲学。1948年4月辞去院长职务,并于9回到北京协和医学院,担任内科学教授和内科主任。中华人民共和国成立后,他续任原职。1962年9月被任命为协和医学院副校长。1966年开始的文化大革命期间,他被打成「反动学术权威」、「特务」,备受侮辱和折磨。1978年以后担任中国医学科学院副院长。1987年8月8日因肺癌病逝于北京协和医院,享年90岁。张孝骞毕生致力于临床医学、医学科学研究和医学教育工作,对人体血容量、胃分泌功能、消化系溃疡、腹腔结核、阿米巴痢疾和溃疡性结肠炎等有较深入的研究,被喻为内科专家、医学教育家、中国消化病学的奠基人。。1948年获选为第一届中央研究院院士,1955年被推选为中国科学院生物学部委员(院士)。\n\n### 文章 90\n\n永明之治\n永明之治是指南齐在齐武帝萧赜在位时代出现的治世(482年—493年)。由于齐武帝年号永明,所以称为永明之治。当时南齐建立四年后齐高帝去世,太子萧赜即位,即齐武帝。他十分关心内政,提倡教育。并且继承齐高帝风格,力行节俭。由于与北魏通好,使得边境较为安定,减少军事调动。使得在齐武帝在位的十一年期间,政治清明,国内社会安定,带动经济文化的发展,替齐国带来一个小康的安定局面。《南齐书·列传第三十四 良政》即提到:「永明之世十许年中,百姓无鸡鸣犬吠之警,都邑之盛,士女富逸,歌声舞节,袨服华妆,桃花绿水之间,秋月春风之下,盖以百数。」可惜在齐武帝去世后,继位的萧昭业奢侈荒戏而使得朝政渐乱。政事渐由辅政的萧鸾一手掌握,不久就发生弑君篡位,宗室内哄的惨事并导致南齐灭亡。齐武帝提倡节俭,不喜欢游宴、奢靡之事。曾下令举办婚礼时不得奢侈,甚至到他的身后事都力求简朴。他以富国为先,提倡农业,并且下令多办学校,挑选有学问之人任教,以培育人们的德行。他很重视天灾对平民的危害。当时发生歉收与水患,继位后不久立即补助灾民。扬、南徐二州发生灾年时,他减免租税以减轻灾民负担,以为永制。为进一步缓和南北局势,齐武帝派范缜作为使者出使北魏,范缜的学识和能力受到北魏朝野的称赞。南朝宋以来许多的庶族地主,为了成为世族来免除所承担的赋役,往往向官吏行贿,在世族户籍黄籍中加入伪造的父祖爵位。早在齐高帝时期就设立校籍官和置令史来清查户籍。齐武帝继续其父的政策,将那些被认为是伪造的户籍,一律退回本县改正,称为「却籍」。而本来应服役纳赋但利用造假户籍避开的,都要继续承担赋役,称为「正籍」。不过,在检籍过程中,由于检籍官贪污作弊,结果「前检未穷,后巧复滋」,「应却而不却,不须却而却」。这使却籍户不满,最后于485年发生富阳唐寓之起兵叛乱。虽然这次叛乱被齐武帝迅速平息,但检籍的政策依然受到庶族地主的激烈反对。五年后齐武帝与庶族地主妥协,宣布「却籍」无效,同意将因为却籍而被发配边疆的平民返归故乡。\n\n### 文章 91\n\n禅那\n禅那(,,,),又译为驮那演那,佛教术语,意译为思惟修或静虑,在佛教经论中,专指四种色界定。修行进入四种禅那的方法,为奢摩他与毘钵舍那即止观。「禅那」这个词源出婆罗门教《梨俱吠陀》,有心一境性含义的「禅那」出现于《奥义书》中,在后世的《瑜伽经》八支瑜伽中为第七支。「禅那」广泛用于沙门传统各教派,在佛教中,为「三无漏学」与六度之一。禅那与定,在日常用语中或被视为同义词,但禅那的范围窄而定的范围宽,禅那专指能依之见道证沙门果的色界四种定,而欲界及无色界诸定,不能兼具「断结」及「正观」,一般不称为禅那。汉传佛教禅宗的禅,源自于禅那的简称,但随著禅宗的发展,逐渐形成一个独特的思想体系。四种禅那的定义在《阿含经》中有固定文句,下为《法蕴论》的引述:说一切有部等将四种禅那归结为十八禅支,其实体有十一法,其释义融入了七觉支的轻安和行舍,南传上座部亦有禅支施设。四种禅那是增上心法、现法乐住。四禅那与四无色定,合称八等至,即俗称的四禅八定,四无色定分别为空无边处定、识无边处定、无所有处定、非想非非想处定。此外,最终可达到想受灭尽定,以上合称九次第定。八根本定各有其近分定,其中初禅之近分定为未至定或称近行禅,亦有在初禅与二禅中间施设禅中间或称中间禅,行者可依四根本禅那()及此二定而见道。第四禅或旁入无想定,四禅那与四无量可相互引起。修行进入禅那,在传统师承教法中,主要有能成就前六等至的十遍处,能成就四禅的持息念,能成就三禅的慈无量,能成就初禅的不净想和身至念(),二者后统称不净观;此外,修行业处,还包括能成就未至定的四界分别观等,诸论书及诸宗派,对修行各种加行、功德的性相及其与禅那的关系各有见解。禅那修行,在宏观上分成二种修行(),即奢摩他与毘钵舍那,二者殊途同归,合称止观。现代南传上座部佛教,特别是缅甸佛教,又将修行分为「止乘者」()和「干观者」()。 ================================================ FILE: llm-eval/eval-data/longtext_L64031_question.txt ================================================ 第58届全球帅哥竞选活动有什么特别之处? ================================================ FILE: llm-eval/llm-performance/AI芯片性能.md ================================================ 模型算力利用率(MFU)+硬件算力利用率(HFU) 模型算力利用率(Model FLOPs Utilization, MFU)和硬件算力利用率(Hardware FLOPs Utilization, HFU)是评估某一模型实现对芯片计算性能利用情况的常用指标 简单来说: 模型算力利用率是指模型一次前反向计算消耗的矩阵算力与机器算力的比值 硬件算力利用率是指考虑重计算后,模型一次前反向计算消耗的矩阵算力与机器算力的比值 注:FLOPs指浮点运算次数,FLOPS指每秒的浮点运算次数 - 模型算力利用率(MFU)+硬件算力利用率(HFU):https://zhuanlan.zhihu.com/p/671537309 ================================================ FILE: llm-eval/llm-performance/README.md ================================================ ## llm 框架对比 - https://github.com/ninehills/llm-inference-benchmark - https://github.com/triton-inference-server/perf_analyzer - https://github.com/triton-inference-server/perf_analyzer/tree/main/genai-perf (推理性能) - https://github.com/modelscope/evalscope (模型精度、推理性能) ## nvidia-ml-py3、pynvml - Model training anatomy(模型训练解剖 - huggingface ):https://huggingface.co/docs/transformers/model_memory_anatomy - https://www.cnblogs.com/devilmaycry812839668/p/15563995.html - BERT优化技术:https://www.jianshu.com/p/c9c34c5f7bcb - train performance: 550 tokens/s - predict performance: 17.75 tokens/s ``` pip install nvidia-ml-py psutil ``` ``` from pynvml import * def print_gpu_utilization(): nvmlInit() handle = nvmlDeviceGetHandleByIndex(0) info = nvmlDeviceGetMemoryInfo(handle) print(f"GPU memory occupied: {info.used//1024**2} MB.") ``` ## 压测工具 Locust ================================================ FILE: llm-eval/llm-performance/hardware-performance/gpu-monitor-ui.py ================================================ import psutil import pynvml #导包 UNIT = 1024 * 1024 pynvml.nvmlInit() #初始化 gpuDeriveInfo = pynvml.nvmlSystemGetDriverVersion() print("Drive版本: ", str(gpuDeriveInfo)) #显示驱动信息 gpuDeviceCount = pynvml.nvmlDeviceGetCount()#获取Nvidia GPU块数 print("GPU个数:", gpuDeviceCount ) for i in range(gpuDeviceCount): handle = pynvml.nvmlDeviceGetHandleByIndex(i)#获取GPU i的handle,后续通过handle来处理 memoryInfo = pynvml.nvmlDeviceGetMemoryInfo(handle)#通过handle获取GPU i的信息 gpuName = str(pynvml.nvmlDeviceGetName(handle)) gpuTemperature = pynvml.nvmlDeviceGetTemperature(handle, 0) # gpuFanSpeed = pynvml.nvmlDeviceGetFanSpeed(handle) gpuPowerState = pynvml.nvmlDeviceGetPowerState(handle) gpuUtilRate = pynvml.nvmlDeviceGetUtilizationRates(handle).gpu gpuMemoryRate = pynvml.nvmlDeviceGetUtilizationRates(handle).memory print("第 %d 张卡:"%i, "-"*30) print("显卡名:", gpuName) print("内存总容量:", memoryInfo.total/UNIT, "MB") print("使用容量:", memoryInfo.used/UNIT, "MB") print("剩余容量:", memoryInfo.free/UNIT, "MB") print("显存空闲率:", memoryInfo.free/memoryInfo.total) print("温度:", gpuTemperature, "摄氏度") # print("风扇速率:", gpuFanSpeed) print("供电水平:", gpuPowerState) print("gpu计算核心满速使用率:", gpuUtilRate) print("gpu内存读写满速使用率:", gpuMemoryRate) print("内存占用率:", memoryInfo.used/memoryInfo.total) """ # 设置显卡工作模式 # 设置完显卡驱动模式后,需要重启才能生效 # 0 为 WDDM模式,1为TCC 模式 gpuMode = 0 # WDDM gpuMode = 1 # TCC pynvml.nvmlDeviceSetDriverModel(handle, gpuMode) # 很多显卡不支持设置模式,会报错 # pynvml.nvml.NVMLError_NotSupported: Not Supported """ # 对pid的gpu消耗进行统计 pidAllInfo = pynvml.nvmlDeviceGetComputeRunningProcesses(handle)#获取所有GPU上正在运行的进程信息 for pidInfo in pidAllInfo: pidUser = psutil.Process(pidInfo.pid).username() print("进程pid:", pidInfo.pid, "用户名:", pidUser, "显存占有:", pidInfo.usedGpuMemory/UNIT, "Mb") # 统计某pid使用的显存 pynvml.nvmlShutdown() #最后关闭管理工具 ================================================ FILE: llm-eval/llm-performance/hardware-performance/pynvml-stat-memory.py ================================================ import psutil import pynvml import time UNIT = 1024 * 1024 pynvml.nvmlInit() #初始化 ids = [3, 7] max_mem_dict = { } while True: for i in ids: max_mem = max_mem_dict.get(str(i), 0) handle = pynvml.nvmlDeviceGetHandleByIndex(i) memoryInfo = pynvml.nvmlDeviceGetMemoryInfo(handle) used_mem = memoryInfo.used/UNIT if used_mem > max_mem: max_mem_dict[str(i)] = used_mem print(max_mem_dict) time.sleep(5) pynvml.nvmlShutdown() ================================================ FILE: llm-eval/llm-performance/llmperf.md ================================================ - https://github.com/ray-project/llmperf-leaderboard - https://github.com/ray-project/llmperf - 指标定义:https://github.com/ray-project/llmperf/blob/main/src/llmperf/common_metrics.py - 可复现的语言大模型推理性能指标: https://zhuanlan.zhihu.com/p/667612787 - 原文:https://www.anyscale.com/blog/reproducible-performance-metrics-for-llm-inference ## 通用指标 - 每分钟完成的请求数 - 首词元时间(TTFT) 在流式应用中,TTFT指的是LLM返回第一个词元前所需的时间。 - 词元间时延(ITL) 词元间时延指的是连续输出词元之间的平均时间。 将TTFT纳入词元间时延的计算。 - 端到端时延 端到端时延应该大致等于词元的平均输出长度乘以词元间时延。 ## 特定实例的额外指标 ### 配置 同一模型通常由于配置不同,导致在时延、成本和吞吐量之间出现不同权衡。例如,在p4de实例(AWS发布了的EC2 GPU执行实例P4de)上运行的CodeLlama-34B模型可以配置为8个副本,每个副本有1个GPU,也可以配置为4个副本,每个副本有2个GPU,或者配置为2个副本,每个副本有4个GPU,甚至还可以配置为1个副本,拥有全部8个GPU。你还可以为流水并行或张量并行配置多个GPU。 每种配置都有不同特性:每个副本有一个GPU的情况可能拥有最低的TTFT(因为有8个“队列”等待输入),而一个副本有8个GPU的情况可能具备最大的吞吐量(因为有更多的批处理内存,且实际上有8倍的内存带宽)。 每种配置都会导致不同的基准测试结果。 ### 输出词元吞吐量 总生成词元吞吐量,这便于比较成本。 ## 考虑到但没有包含的测量标准 ### 预加载时间 由于预加载时间只能通过对输入大小的首词元的回归来间接测算,因此我们在这一轮基准测试中没有加入这一指标。 在250个词元输入和800个词元输入之间,输入词元与TTFT之间似乎并不存在明显的关系,且因其他原因导致的TTFT的随机噪声“掩盖(swamped)”了这一关系。 实际上,我们尝试过使用回归分析来估计这一关系,通过比较550个输入词元和3500个输入词元的输出,并估算梯度,我们发现每增加一个输入词元会增加0.3-0.7毫秒的端到端时间, 相比之下,每增加一个输出词元会增加30-60毫秒的端到端时间。因此,输入词元对端到端时延的影响约为输出词元的1%。 ### 总吞吐量(包括输入和生成的词元) ## 输入选择 ### 输入大小 平均输入长度:550个词元(标准差为150个词元) 平均输出长度:150个词元(标准差为20个词元) 为简化问题,我们假设输入和输出都服从正态分布。在未来的工作中,我们将考虑Poisson分布等更具代表性的分布,因为这类分布在建模词元分布方面性质更佳。 ### 并发请求 一个关键特征是同时发出的请求数量。显然,更多的并发请求会使固定资源集的输出速度变慢。在测试中,我们已经将5作为关键数字进行了标准化。 ## 分析 ITL和TTFT都足够小,不会成为主要问题,因为人类每秒大约阅读5个词元,即便方案中最慢的速度也是人类的6倍之多,所以它们之间没有显著的差异。 100个输入词元与单个输出词元对时延的影响大致相当。若想提升速度,减少输出要比减少输入更有效。 ================================================ FILE: llm-eval/llm-performance/mindie/lantency/README.md ================================================ ## qwen1.5 ``` nohup python performance.py > qwen1.5-7b-2tp.log 2>&1 & nohup python performance.py > qwen1.5-7b-4tp.log 2>&1 & nohup python performance.py > qwen1.5-7b-1tp.log 2>&1 & ``` ### 7b ``` nohup python performance-qwen1.5.py > qwen1.5-7b-1tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.0362 最大值: 0.0822 TP50: 0.03910830750828609 TP90: 0.041983614274067806 TP99: 0.0693812740611611 平均: 0.0402 平均Token间时延-------宏平均-------------- 最小值: 0.0276 最大值: 0.029 TP50: 0.0278010167882747 TP90: 0.0279021279463161 TP99: 0.028085540810020855 平均: 0.0278 Token间时延----------微平均----------- 最小值: 0.0255 最大值: 0.0769 TP50: 0.027775271475547925 TP90: 0.027990428486373276 TP99: 0.02832354519458022 平均: 0.0278 端到端时延--------------------- 最小值: 0.1774 最大值: 7.2057 TP50: 5.678898271493381 TP90: 7.1518600779993 TP99: 7.181869987533427 平均: 4.5789 ``` ### 14b ``` nohup python performance-qwen1.5.py > qwen1.5-14b-2tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.0485 最大值: 0.1147 TP50: 0.05076179598108865 TP90: 0.06449698104988784 TP99: 0.08938701630046125 平均: 0.054 平均Token间时延--------------------- 最小值: 0.0291 最大值: 0.0313 TP50: 0.02938067449457426 TP90: 0.02956166821740162 TP99: 0.03005740493887995 平均: 0.0294 Token间时延--------------------- 最小值: 0.0276 最大值: 0.1254 TP50: 0.02931902397540398 TP90: 0.0297731505590491 TP99: 0.030323233010713012 平均: 0.0294 端到端时延--------------------- 最小值: 0.1389 最大值: 7.6702 TP50: 5.302297868474852 TP90: 7.572541862208164 TP99: 7.6225727947789705 平均: 4.5433 ``` ``` nohup python performance-qwen1.5-opt.py > qwen1.5-14b-4tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.0342 最大值: 0.106 TP50: 0.04471042950171977 TP90: 0.06295614595292136 TP99: 0.08384593328344635 平均: 0.0491 平均Token间时延-宏平均--------------------- 最小值: 0.0199 最大值: 0.0252 TP50: 0.020568159196124064 TP90: 0.0210901382120879 TP99: 0.022589506589673493 平均: 0.0206 -------------生成的Token长度 最小值: 3 最大值: 255 TP50: 163.5 TP90: 255.0 TP99: 255.0 平均: 151.149 Token间时延-微平均--------------------- 最小值: 0.0168 最大值: 0.0801 TP50: 0.02059264504350722 TP90: 0.021456072013825177 TP99: 0.022933204732835267 平均: 0.0207 端到端时延--------------------- 最小值: 0.127 最大值: 5.834 TP50: 3.3732377134729177 TP90: 5.3804829642409455 TP99: 5.546778464077506 平均: 3.181 --------输入的token Qwen1.5-14B 最小值: 9 最大值: 107 TP50: 17.0 TP90: 25.0 TP99: 46.02999999999997 平均: 18.463 ``` 输入变长: ``` 20-50 nohup python performance-qwen1.5-opt.py > qwen1.5-14b-4tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.0344 最大值: 0.1042 TP50: 0.044600390014238656 TP90: 0.0656163000036031 TP99: 0.08991615840815935 平均: 0.0486 平均Token间时延-宏平均--------------------- 最小值: 0.0199 最大值: 0.0236 TP50: 0.020652142043143293 TP90: 0.02121227477502163 TP99: 0.022700149870105903 平均: 0.0207 最小值: 3 最大值: 255 TP50: 140.0 TP90: 255.0 TP99: 255.0 平均: 145.564 Token间时延-微平均--------------------- 最小值: 0.0186 最大值: 0.1405 TP50: 0.020674455969128758 TP90: 0.0216125491540879 TP99: 0.023144232148770243 平均: 0.0208 端到端时延--------------------- 最小值: 0.1068 最大值: 5.8191 TP50: 2.9713201579870656 TP90: 5.404564902291168 TP99: 5.592448376263492 平均: 3.0775 50-80 nohup python performance-qwen1.5-opt.py > qwen1.5-14b-4tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.0369 最大值: 0.0841 TP50: 0.044670506031252444 TP90: 0.05576291526667773 TP99: 0.08015473581384873 平均: 0.0473 平均Token间时延-宏平均--------------------- 最小值: 0.0199 最大值: 0.0273 TP50: 0.02071355515784633 TP90: 0.02131128107264086 TP99: 0.022842199074673587 平均: 0.0208 最小值: 3 最大值: 255 TP50: 93.0 TP90: 255.0 TP99: 255.0 平均: 121.6323 Token间时延-微平均--------------------- 最小值: 0.0185 最大值: 0.0837 TP50: 0.02079473255435005 TP90: 0.02174522407585755 TP99: 0.02275449804146774 平均: 0.0209 端到端时延--------------------- 最小值: 0.1066 最大值: 5.6484 TP50: 1.9413445619866252 TP90: 5.388641358423047 TP99: 5.5315114035015 平均: 2.5893 >80 nohup python performance-qwen1.5-opt.py > qwen1.5-14b-4tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.0386 最大值: 0.0878 TP50: 0.04492756101535633 TP90: 0.05734664782648908 TP99: 0.08296710541937502 平均: 0.0484 平均Token间时延-宏平均--------------------- 最小值: 0.0202 最大值: 0.0223 TP50: 0.0208923420236519 TP90: 0.02139808727210862 TP99: 0.02194536470390972 平均: 0.0209 最小值: 7 最大值: 255 TP50: 99.0 TP90: 255.0 TP99: 255.0 平均: 127.7532 Token间时延-微平均--------------------- 最小值: 0.0176 最大值: 0.0838 TP50: 0.02089356805663556 TP90: 0.021700534643605354 TP99: 0.022964883805252613 平均: 0.021 端到端时延--------------------- 最小值: 0.1985 最大值: 5.6518 TP50: 2.117296829004772 TP90: 5.418090309249237 TP99: 5.5139858593721875 平均: 2.7303 > 100 Token时延--------------------- 最小值: 0.0427 最大值: 0.0885 TP50: 0.045819810940884054 TP90: 0.057311376091092825 TP99: 0.08563760861288758 平均: 0.0493 平均Token间时延-宏平均--------------------- 最小值: 0.0202 最大值: 0.0235 TP50: 0.021073095572435044 TP90: 0.02178727035023659 TP99: 0.022659467397324773 平均: 0.0211 最小值: 12 最大值: 255 TP50: 106.0 TP90: 255.0 TP99: 255.0 平均: 131.9383 Token间时延-微平均--------------------- 最小值: 0.0175 最大值: 0.0834 TP50: 0.02109450800344348 TP90: 0.022011490445584057 TP99: 0.023271926655434066 平均: 0.0212 端到端时延--------------------- 最小值: 0.2921 最大值: 5.689 TP50: 2.2772261140635237 TP90: 5.426153923035599 TP99: 5.684156133793294 平均: 2.8497 ``` ### 72b ``` nohup python performance-qwen1.5.py > qwen1.5-72b-8tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.0534 最大值: 0.2076 TP50: 0.1079369744984433 TP90: 0.1705317942192778 TP99: 0.1919716515240725 平均: 0.1158 平均Token间时延-----宏平均---------------- 最小值: 0.0387 最大值: 0.0495 TP50: 0.040660905435692465 TP90: 0.04177531845047009 TP99: 0.0446021025582795 平均: 0.0407 Token间时延------微平均--------------- 最小值: 0.0363 最大值: 0.2612 TP50: 0.040213780011981726 TP90: 0.04158656799700111 TP99: 0.06988605986116452 平均: 0.0409 端到端时延--------------------- 最小值: 0.2416 最大值: 11.059 TP50: 6.681836381496396 TP90: 10.643284943437902 TP99: 10.850449634447578 平均: 6.2931 ``` ## baichuan2 ### 7b ``` nohup python performance-stream-baichuan2.py > baichuan2-7b-1tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.0346 最大值: 0.0746 TP50: 0.037620097515173256 TP90: 0.03930058096302673 TP99: 0.0629892204713542 平均: 0.0383 Token间时延--------------------- 最小值: 0.0266 最大值: 0.0282 TP50: 0.02690558272830032 TP90: 0.027013076266135427 TP99: 0.02722421399674232 平均: 0.0269 端到端时延--------------------- 最小值: 0.0912 最大值: 6.9819 TP50: 3.798740677011665 TP90: 6.923744286387228 TP99: 6.9560187938367015 平均: 3.845 ``` ### 13b ``` nohup python performance-stream-baichuan2.py > baichuan2-13b-8tp.log 2>&1 & Token间时延: 0.0205 端到端时延: 5.2605 首Token时延--------------------- 最小值: 0.0262 最大值: 0.095 TP50: 0.04364173547946848 TP90: 0.07536821577814408 TP99: 0.08855077477928716 平均: 0.0504 Token间时延--------------------- 最小值: 0.0175 最大值: 0.0233 TP50: 0.02025962653195685 TP90: 0.020924803277969476 TP99: 0.021784018275444395 平均: 0.0202 端到端时延--------------------- 最小值: 0.1063 最大值: 5.5972 TP50: 3.0839127039944287 TP90: 5.346198681468377 TP99: 5.478170610390371 平均: 3.0057 ``` ``` nohup python performance-stream-baichuan2.py > baichuan2-13b-4tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.033 最大值: 0.0926 TP50: 0.040996209951117635 TP90: 0.04627442727796734 TP99: 0.08442730915965511 平均: 0.0443 Token间时延--------------------- 最小值: 0.019 最大值: 0.0253 TP50: 0.01949691754800923 TP90: 0.020152707407890144 TP99: 0.02044556271550976 平均: 0.0196 生成token长度--------------------- 最小值: 1 最大值: 255 TP50: 150.0 TP90: 255.0 TP99: 255.0 平均: 145.617 端到端时延--------------------- 最小值: 0.0819 最大值: 5.3597 TP50: 2.9611026739585213 TP90: 5.179639161087107 TP99: 5.2417431398411285 平均: 2.933 Baichuan2-13B 最小值: 3 最大值: 89 TP50: 10.0 TP90: 18.0 TP99: 37.00999999999999 平均: 11.652 ``` 输入长度变长: ``` 20-50 输入长度: nohup python performance-stream-baichuan2.py > baichuan2-13b-4tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.0337 最大值: 0.0927 TP50: 0.041033171000890434 TP90: 0.04589057200355456 TP99: 0.08637305982760153 平均: 0.0445 Token间时延--------------------- 最小值: 0.0189 最大值: 0.0225 TP50: 0.019536821587244464 TP90: 0.020144198685473597 TP99: 0.02044627025890091 平均: 0.0196 生成token长度--------------------- 最小值: 1 最大值: 255 TP50: 141.5 TP90: 255.0 TP99: 255.0 平均: 142.422 端到端时延--------------------- 最小值: 0.0652 最大值: 5.3101 TP50: 2.7811530429753475 TP90: 5.179711006244179 TP99: 5.248473131870851 平均: 2.8742 50-80: nohup python performance-stream-baichuan2.py > baichuan2-13b-4tp.log 2>&1 & 首Token时延--------------------- 最小值: 0.0353 最大值: 0.0902 TP50: 0.04135144897736609 TP90: 0.04567298900801688 TP99: 0.08496335084317252 平均: 0.0446 Token间时延--------------------- 最小值: 0.019 最大值: 0.0237 TP50: 0.019521759752283936 TP90: 0.020296478207752693 TP99: 0.021035376845630727 平均: 0.0197 生成token长度--------------------- 最小值: 1 最大值: 255 TP50: 81.0 TP90: 255.0 TP99: 255.0 平均: 120.4401 端到端时延--------------------- 最小值: 0.0604 最大值: 5.4079 TP50: 1.5992199269821867 TP90: 5.206169682811014 TP99: 5.313588380513248 平均: 2.4501 >80 首Token时延--------------------- 最小值: 0.0363 最大值: 0.0872 TP50: 0.041622460004873574 TP90: 0.04473990759579465 TP99: 0.08524959351751024 平均: 0.0444 Token间时延--------------------- 最小值: 0.0191 最大值: 0.0216 TP50: 0.019501857135144518 TP90: 0.020219680912400066 TP99: 0.020678448217103768 平均: 0.0196 生成token长度--------------------- 最小值: 8 最大值: 255 TP50: 66.0 TP90: 255.0 TP99: 255.0 平均: 106.5063 端到端时延--------------------- 最小值: 0.2141 最大值: 5.3175 TP50: 1.344075930013787 TP90: 5.194844978442416 TP99: 5.291031377102481 平均: 2.1657 ``` ## 输入token统计 ``` chatglm3: "padded_vocab_size": 65024, baichuan2: vocab_size 125696 Qwen-72B-Chat "vocab_size": 152064 Qwen1.5-7B-Chat "vocab_size": 151936 Qwen1.5-72B-Chat "vocab_size": 152064 ``` ``` -------- Qwen1.5-7B 最小值: 9 最大值: 107 TP50: 17.0 TP90: 25.0 TP99: 46.02999999999997 平均: 18.463 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-14B 最小值: 9 最大值: 107 TP50: 17.0 TP90: 25.0 TP99: 46.02999999999997 平均: 18.463 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-72B 最小值: 9 最大值: 107 TP50: 17.0 TP90: 25.0 TP99: 46.02999999999997 平均: 18.463 -------- Qwen-72B 最小值: 1 最大值: 99 TP50: 9.0 TP90: 17.0 TP99: 38.02999999999997 平均: 10.463 -------- Baichuan2-7B 最小值: 3 最大值: 89 TP50: 10.0 TP90: 18.0 TP99: 37.00999999999999 平均: 11.652 -------- Baichuan2-13B 最小值: 3 最大值: 89 TP50: 10.0 TP90: 18.0 TP99: 37.00999999999999 平均: 11.652 Setting eos_token is not supported, use the default one. Setting pad_token is not supported, use the default one. Setting unk_token is not supported, use the default one. -------- chatglm3-6b 最小值: 9 最大值: 101 TP50: 17.0 TP90: 24.0 TP99: 44.02999999999997 平均: 18.173 ``` ``` 20-50: stat_token.py Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-7B 最小值: 14 最大值: 47 TP50: 23.0 TP90: 29.0 TP99: 43.0 平均: 23.65 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-14B 最小值: 14 最大值: 47 TP50: 23.0 TP90: 29.0 TP99: 43.0 平均: 23.65 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-72B 最小值: 14 最大值: 47 TP50: 23.0 TP90: 29.0 TP99: 43.0 平均: 23.65 -------- Qwen-72B 最小值: 6 最大值: 39 TP50: 15.0 TP90: 21.0 TP99: 35.0 平均: 15.65 -------- Baichuan2-7B 最小值: 8 最大值: 38 TP50: 16.0 TP90: 22.0 TP99: 33.00999999999999 平均: 16.596 -------- Baichuan2-13B 最小值: 8 最大值: 38 TP50: 16.0 TP90: 22.0 TP99: 33.00999999999999 平均: 16.596 Setting eos_token is not supported, use the default one. Setting pad_token is not supported, use the default one. Setting unk_token is not supported, use the default one. -------- chatglm3-6b 最小值: 14 最大值: 47 TP50: 22.0 TP90: 29.0 TP99: 40.0 平均: 23.242 ``` ``` 50 - 80: -------- Qwen1.5-7B 最小值: 22 最大值: 72 TP50: 40.0 TP90: 51.0 TP99: 58.420000000000016 平均: 39.9972 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-14B 最小值: 22 最大值: 72 TP50: 40.0 TP90: 51.0 TP99: 58.420000000000016 平均: 39.9972 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-72B 最小值: 22 最大值: 72 TP50: 40.0 TP90: 51.0 TP99: 58.420000000000016 平均: 39.9972 -------- Qwen-72B 最小值: 14 最大值: 64 TP50: 32.0 TP90: 43.0 TP99: 50.420000000000016 平均: 31.9972 -------- Baichuan2-7B 最小值: 16 最大值: 64 TP50: 32.0 TP90: 42.0 TP99: 48.84000000000003 平均: 32.3398 -------- Baichuan2-13B 最小值: 16 最大值: 64 TP50: 32.0 TP90: 42.0 TP99: 48.84000000000003 平均: 32.3398 Setting eos_token is not supported, use the default one. Setting pad_token is not supported, use the default one. Setting unk_token is not supported, use the default one. -------- chatglm3-6b 最小值: 22 最大值: 71 TP50: 40.0 TP90: 50.0 TP99: 57.420000000000016 平均: 39.6462 ``` ``` 大于80个字符 <100 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-7B 最小值: 29 最大值: 143 TP50: 65.0 TP90: 100.60000000000002 TP99: 137.44000000000005 平均: 70.7089 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-14B 最小值: 29 最大值: 143 TP50: 65.0 TP90: 100.60000000000002 TP99: 137.44000000000005 平均: 70.7089 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-72B 最小值: 29 最大值: 143 TP50: 65.0 TP90: 100.60000000000002 TP99: 137.44000000000005 平均: 70.7089 -------- Qwen-72B 最小值: 21 最大值: 135 TP50: 57.0 TP90: 92.60000000000002 TP99: 129.44000000000005 平均: 62.7089 -------- Baichuan2-7B 最小值: 23 最大值: 129 TP50: 56.0 TP90: 89.0 TP99: 119.86000000000001 平均: 61.1772 -------- Baichuan2-13B 最小值: 23 最大值: 129 TP50: 56.0 TP90: 89.0 TP99: 119.86000000000001 平均: 61.1772 Setting eos_token is not supported, use the default one. Setting pad_token is not supported, use the default one. Setting unk_token is not supported, use the default one. -------- chatglm3-6b 最小值: 29 最大值: 138 TP50: 65.0 TP90: 98.0 TP99: 130.72000000000003 平均: 69.9873 ``` ``` >100 python stat_token.py Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-7B 最小值: 40 最大值: 143 TP50: 81.0 TP90: 112.0 TP99: 142.2 平均: 83.3333 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-14B 最小值: 40 最大值: 143 TP50: 81.0 TP90: 112.0 TP99: 142.2 平均: 83.3333 Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained. -------- Qwen1.5-72B 最小值: 40 最大值: 143 TP50: 81.0 TP90: 112.0 TP99: 142.2 平均: 83.3333 -------- Qwen-72B 最小值: 32 最大值: 135 TP50: 73.0 TP90: 104.0 TP99: 134.2 平均: 75.3333 -------- Baichuan2-7B 最小值: 34 最大值: 129 TP50: 70.0 TP90: 99.0 TP99: 122.60000000000002 平均: 72.9753 -------- Baichuan2-13B 最小值: 34 最大值: 129 TP50: 70.0 TP90: 99.0 TP99: 122.60000000000002 平均: 72.9753 Setting eos_token is not supported, use the default one. Setting pad_token is not supported, use the default one. Setting unk_token is not supported, use the default one. -------- chatglm3-6b 最小值: 39 最大值: 138 TP50: 79.0 TP90: 110.0 TP99: 134.0 平均: 82.284 ``` ================================================ FILE: llm-eval/llm-performance/mindie/lantency/perfermance-stat.py ================================================ import requests import json import time url = "http://192.xxx.16.211:1025/v1/chat/completions" payload = json.dumps({ "model": "qwen1.5-14b", "messages": [ { "role": "user", "content": "<|im_start|>user\n你好,我的名字是李聪明。请问你是谁?<|im_end|>\n<|im_start|>assistant\n你好,李聪明!很高兴认识你。我是一个大型语言模型,你可以叫我通义千问。有什么问题或需要帮助的话,请随时告诉我。<|im_end|>\n<|im_start|>user\n我最近心情很糟糕,能给我一些建议吗?<|im_end|><|im_start|>assistant\n我很理解你现在的感受。面对糟糕的心情,以下是一些可能有帮助的建议:\n\n1. **与他人分享**:告诉信任的朋友或家人你的感受,他们可能能提供安慰和支持。\n2. **自我关怀**:确保每天有足够的休息,做些你喜欢的事情,比如阅读、听音乐或运动。\n3. **运动与放松**:适度的运动可以帮助释放压力,尝试瑜伽、冥想或深呼吸练习。\n4. **寻求专业帮助**:如果你觉得压力过大,考虑咨询心理医生或心理咨询师。\n5. **保持积极思考**:试着找出生活中的小确幸,每天对自己说一些积极的话。\n6. **时间管理**:合理安排时间,避免过度压力,留出放松的时间。\n\n记住,处理情绪需要时间和耐心,不要对自己太苛刻。如果你的情绪持续低落,可能需要更专业的支持。希望这些建议对你有所帮助。<|im_end|>\n<|im_start|>user\n请问我叫什么名字?<|im_end|>" } ], "max_tokens": 256, "top_p": 0.85, "n": 10, "logprobs": True, "stop": "<|im_end|>" }) # ,"stream": true headers = { 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ================================================ FILE: llm-eval/llm-performance/mindie/lantency/performance-stream-baichuan2.py ================================================ import requests import json import time import numpy as np url = "http://192.xxx.16.211:1025/v1/chat/completions" # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "/home/aicc/alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) first_token_time_list = [] avg_token_time_list = [] total_time_list = [] gen_token_len_list = [] count = 0 for line in list_str: # instruction = line.get("instruction") # inputs = line.get("input") instruction = line inputs = line count += 1 if count > 1000: break print("--------------------", str(count)) if len(inputs) == 0: continue content = f"{instruction}" payload = json.dumps({ "model": "baichuan2-7b", "messages": [ { "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85, "n": 10, "logprobs": True, "stream": True }) headers = { 'Content-Type': 'application/json' } start_time = time.perf_counter() start = start_time response = requests.request("POST", url, headers=headers, data=payload, stream=True) response.raise_for_status() i = 0 gen_time_list = [] for chunk in response.iter_content(chunk_size=8192): end_time = time.perf_counter() print(chunk.decode('utf-8')) gen_time = end_time - start_time i+=1 if i==1: first_token_time_list.append(gen_time) print("首Token时延:", round(gen_time, 4)) else: gen_time_list.append(gen_time) start_time = end_time avg_token_time = sum(gen_time_list) / len(gen_time_list) gen_token_len_list.append(len(gen_time_list)) print("Token间时延:", round(avg_token_time, 4)) avg_token_time_list.append(avg_token_time) total_time = end_time - start print("端到端时延:", round(total_time, 4)) total_time_list.append(total_time) print("首Token时延---------------------") print("最小值:", round(min(first_token_time_list), 4)) print("最大值:", round(max(first_token_time_list), 4)) print("TP50:", np.percentile(np.array(first_token_time_list), 50)) print("TP90:", np.percentile(np.array(first_token_time_list), 90)) print("TP99:", np.percentile(np.array(first_token_time_list), 99)) print("平均:", round(sum(first_token_time_list) / len(first_token_time_list), 4)) print("Token间时延---------------------") print("最小值:", round(min(avg_token_time_list), 4)) print("最大值:", round(max(avg_token_time_list), 4)) print("TP50:", np.percentile(np.array(avg_token_time_list), 50)) print("TP90:", np.percentile(np.array(avg_token_time_list), 90)) print("TP99:", np.percentile(np.array(avg_token_time_list), 99)) print("平均:", round(sum(avg_token_time_list) / len(avg_token_time_list), 4)) print("生成token长度---------------------") print("最小值:", round(min(gen_token_len_list), 4)) print("最大值:", round(max(gen_token_len_list), 4)) print("TP50:", np.percentile(np.array(gen_token_len_list), 50)) print("TP90:", np.percentile(np.array(gen_token_len_list), 90)) print("TP99:", np.percentile(np.array(gen_token_len_list), 99)) print("平均:", round(sum(gen_token_len_list) / len(gen_token_len_list), 4)) print("端到端时延---------------------") print("最小值:", round(min(total_time_list), 4)) print("最大值:", round(max(total_time_list), 4)) print("TP50:", np.percentile(np.array(total_time_list), 50)) print("TP90:", np.percentile(np.array(total_time_list), 90)) print("TP99:", np.percentile(np.array(total_time_list), 99)) print("平均:", round(sum(total_time_list) / len(total_time_list), 4)) ================================================ FILE: llm-eval/llm-performance/mindie/lantency/performance-stream-chatglm3.py ================================================ import requests import json import time import numpy as np url = "http://192.xxx.16.211:1025/v1/chat/completions" # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "/home/aicc/alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) first_token_time_list = [] avg_token_time_list = [] total_time_list = [] gen_token_len_list = [] count = 0 for line in list_str: # instruction = line.get("instruction") # inputs = line.get("input") instruction = line inputs = line count += 1 if count > 1000: break print("--------------------", str(count)) if len(inputs) == 0: continue content = f"<|user|>\n{instruction}<|assistant|>\n" payload = json.dumps({ "model": "chatglm3-6b", "messages": [ { "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85, "n": 10, "logprobs": True, "stream": True }) headers = { 'Content-Type': 'application/json' } start_time = time.perf_counter() start = start_time response = requests.request("POST", url, headers=headers, data=payload, stream=True) response.raise_for_status() i = 0 gen_time_list = [] for chunk in response.iter_content(chunk_size=8192): end_time = time.perf_counter() print(chunk.decode('utf-8')) gen_time = end_time - start_time i+=1 if i==1: first_token_time_list.append(gen_time) print("首Token时延:", round(gen_time, 4)) else: gen_time_list.append(gen_time) start_time = end_time avg_token_time = sum(gen_time_list) / len(gen_time_list) gen_token_len_list.append(len(gen_time_list)) print("Token间时延:", round(avg_token_time, 4)) avg_token_time_list.append(avg_token_time) total_time = end_time - start print("端到端时延:", round(total_time, 4)) total_time_list.append(total_time) print("首Token时延---------------------") print("最小值:", round(min(first_token_time_list), 4)) print("最大值:", round(max(first_token_time_list), 4)) print("TP50:", np.percentile(np.array(first_token_time_list), 50)) print("TP90:", np.percentile(np.array(first_token_time_list), 90)) print("TP99:", np.percentile(np.array(first_token_time_list), 99)) print("平均:", round(sum(first_token_time_list) / len(first_token_time_list), 4)) print("Token间时延---------------------") print("最小值:", round(min(avg_token_time_list), 4)) print("最大值:", round(max(avg_token_time_list), 4)) print("TP50:", np.percentile(np.array(avg_token_time_list), 50)) print("TP90:", np.percentile(np.array(avg_token_time_list), 90)) print("TP99:", np.percentile(np.array(avg_token_time_list), 99)) print("平均:", round(sum(avg_token_time_list) / len(avg_token_time_list), 4)) print("生成token长度---------------------") print("最小值:", round(min(gen_token_len_list), 4)) print("最大值:", round(max(gen_token_len_list), 4)) print("TP50:", np.percentile(np.array(gen_token_len_list), 50)) print("TP90:", np.percentile(np.array(gen_token_len_list), 90)) print("TP99:", np.percentile(np.array(gen_token_len_list), 99)) print("平均:", round(sum(gen_token_len_list) / len(gen_token_len_list), 4)) print("端到端时延---------------------") print("最小值:", round(min(total_time_list), 4)) print("最大值:", round(max(total_time_list), 4)) print("TP50:", np.percentile(np.array(total_time_list), 50)) print("TP90:", np.percentile(np.array(total_time_list), 90)) print("TP99:", np.percentile(np.array(total_time_list), 99)) print("平均:", round(sum(total_time_list) / len(total_time_list), 4)) ================================================ FILE: llm-eval/llm-performance/mindie/lantency/performance-stream-qwen1.5.py ================================================ import requests import json import time import numpy as np url = "http://192.xxx.16.211:1025/v1/chat/completions" # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "/home/aicc/alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) first_token_time_list = [] avg_token_time_list = [] intertoken_time_list = [] total_time_list = [] gen_token_len_list = [] count = 0 for line in list_str: # instruction = line.get("instruction") # inputs = line.get("input") instruction = line inputs = line count += 1 if count > 1000: break print("--------------------", str(count)) if len(inputs) == 0: continue content = f"<|im_start|>user\n{instruction}<|im_end|>\n<|im_start|>assistant\n" payload = json.dumps({ "model": "qwen1.5-14b", "messages": [ { "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85, "n": 10, "logprobs": True, "stop": "<|im_end|>", "stream": True }) headers = { 'Content-Type': 'application/json' } start_time = time.perf_counter() start = start_time response = requests.request("POST", url, headers=headers, data=payload, stream=True) response.raise_for_status() i = 0 gen_time_list = [] for chunk in response.iter_content(chunk_size=8192): end_time = time.perf_counter() print(chunk.decode('utf-8')) gen_time = end_time - start_time i+=1 if i==1: first_token_time_list.append(gen_time) print("首Token时延:", round(gen_time, 4)) else: gen_time_list.append(gen_time) start_time = end_time avg_token_time = sum(gen_time_list) / len(gen_time_list) intertoken_time_list.extend(gen_time_list) gen_token_len_list.append(len(gen_time_list)) print("Token间时延:", round(avg_token_time, 4)) avg_token_time_list.append(avg_token_time) total_time = end_time - start print("端到端时延:", round(total_time, 4)) total_time_list.append(total_time) print("首Token时延---------------------") print("最小值:", round(min(first_token_time_list), 4)) print("最大值:", round(max(first_token_time_list), 4)) print("TP50:", np.percentile(np.array(first_token_time_list), 50)) print("TP90:", np.percentile(np.array(first_token_time_list), 90)) print("TP99:", np.percentile(np.array(first_token_time_list), 99)) print("平均:", round(sum(first_token_time_list) / len(first_token_time_list), 4)) print("平均Token间时延-宏平均---------------------") print("最小值:", round(min(avg_token_time_list), 4)) print("最大值:", round(max(avg_token_time_list), 4)) print("TP50:", np.percentile(np.array(avg_token_time_list), 50)) print("TP90:", np.percentile(np.array(avg_token_time_list), 90)) print("TP99:", np.percentile(np.array(avg_token_time_list), 99)) print("平均:", round(sum(avg_token_time_list) / len(avg_token_time_list), 4)) print("生成token长度---------------------") print("最小值:", round(min(gen_token_len_list), 4)) print("最大值:", round(max(gen_token_len_list), 4)) print("TP50:", np.percentile(np.array(gen_token_len_list), 50)) print("TP90:", np.percentile(np.array(gen_token_len_list), 90)) print("TP99:", np.percentile(np.array(gen_token_len_list), 99)) print("平均:", round(sum(gen_token_len_list) / len(gen_token_len_list), 4)) print("Token间时延-微平均---------------------") print("最小值:", round(min(intertoken_time_list), 4)) print("最大值:", round(max(intertoken_time_list), 4)) print("TP50:", np.percentile(np.array(intertoken_time_list), 50)) print("TP90:", np.percentile(np.array(intertoken_time_list), 90)) print("TP99:", np.percentile(np.array(intertoken_time_list), 99)) print("平均:", round(sum(intertoken_time_list) / len(intertoken_time_list), 4)) print("端到端时延---------------------") print("最小值:", round(min(total_time_list), 4)) print("最大值:", round(max(total_time_list), 4)) print("TP50:", np.percentile(np.array(total_time_list), 50)) print("TP90:", np.percentile(np.array(total_time_list), 90)) print("TP99:", np.percentile(np.array(total_time_list), 99)) print("平均:", round(sum(total_time_list) / len(total_time_list), 4)) ================================================ FILE: llm-eval/llm-performance/mindie/lantency/performance-stream-qwen1.py ================================================ import requests import json import time import numpy as np url = "http://192.xxx.16.211:1025/v1/chat/completions" # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "/home/aicc/alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) first_token_time_list = [] avg_token_time_list = [] total_time_list = [] count = 0 for line in list_str: # instruction = line.get("instruction") # inputs = line.get("input") instruction = line inputs = line count += 1 if count > 1000: break print("--------------------", str(count)) if len(inputs) == 0: continue content = f"{instruction}" payload = json.dumps({ "model": "qwen-72b", "messages": [ { "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85, "n": 10, "logprobs": True, "stream": True }) headers = { 'Content-Type': 'application/json' } start_time = time.perf_counter() start = start_time response = requests.request("POST", url, headers=headers, data=payload, stream=True) response.raise_for_status() i = 0 gen_time_list = [] for chunk in response.iter_content(chunk_size=8192): end_time = time.perf_counter() print(chunk.decode('utf-8')) gen_time = end_time - start_time i+=1 if i==1: first_token_time_list.append(gen_time) print("首Token时延:", round(gen_time, 4)) else: gen_time_list.append(gen_time) start_time = end_time avg_token_time = sum(gen_time_list) / len(gen_time_list) print("Token间时延:", round(avg_token_time, 4)) avg_token_time_list.append(avg_token_time) total_time = end_time - start print("端到端时延:", round(total_time, 4)) total_time_list.append(total_time) print("首Token时延---------------------") print("最小值:", round(min(first_token_time_list), 4)) print("最大值:", round(max(first_token_time_list), 4)) print("TP50:", np.percentile(np.array(first_token_time_list), 50)) print("TP90:", np.percentile(np.array(first_token_time_list), 90)) print("TP99:", np.percentile(np.array(first_token_time_list), 99)) print("平均:", round(sum(first_token_time_list) / len(first_token_time_list), 4)) print("Token间时延---------------------") print("最小值:", round(min(avg_token_time_list), 4)) print("最大值:", round(max(avg_token_time_list), 4)) print("TP50:", np.percentile(np.array(avg_token_time_list), 50)) print("TP90:", np.percentile(np.array(avg_token_time_list), 90)) print("TP99:", np.percentile(np.array(avg_token_time_list), 99)) print("平均:", round(sum(avg_token_time_list) / len(avg_token_time_list), 4)) print("端到端时延---------------------") print("最小值:", round(min(total_time_list), 4)) print("最大值:", round(max(total_time_list), 4)) print("TP50:", np.percentile(np.array(total_time_list), 50)) print("TP90:", np.percentile(np.array(total_time_list), 90)) print("TP99:", np.percentile(np.array(total_time_list), 99)) print("平均:", round(sum(total_time_list) / len(total_time_list), 4)) ================================================ FILE: llm-eval/llm-performance/mindie/lantency/performance-stream.py ================================================ import requests import json import time import numpy as np url = "http://192.xxx.16.211:1025/v1/chat/completions" # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "/home/aicc/alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) first_token_time_list = [] avg_token_time_list = [] total_time_list = [] count = 0 for line in list_str: # instruction = line.get("instruction") # inputs = line.get("input") instruction = line inputs = line count += 1 if count > 1000: break print("--------------------", str(count)) if len(inputs) == 0: continue content = f"<|im_start|>user\n{instruction}<|im_end|>\n<|im_start|>assistant\n" payload = json.dumps({ "model": "qwen1.5-14b", "messages": [ { "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85, "n": 10, "logprobs": True, "stop": "<|im_end|>", "stream": True }) headers = { 'Content-Type': 'application/json' } start_time = time.perf_counter() start = start_time response = requests.request("POST", url, headers=headers, data=payload, stream=True) response.raise_for_status() i = 0 gen_time_list = [] for chunk in response.iter_content(chunk_size=8192): end_time = time.perf_counter() print(chunk.decode('utf-8')) gen_time = end_time - start_time i+=1 if i==1: first_token_time_list.append(gen_time) print("首Token时延:", round(gen_time, 4)) else: gen_time_list.append(gen_time) start_time = end_time avg_token_time = sum(gen_time_list) / len(gen_time_list) print("Token间时延:", round(avg_token_time, 4)) avg_token_time_list.append(avg_token_time) total_time = end_time - start print("端到端时延:", round(total_time, 4)) total_time_list.append(total_time) print("首Token时延---------------------") print("最小值:", round(min(first_token_time_list), 4)) print("最大值:", round(max(first_token_time_list), 4)) print("TP50:", np.percentile(np.array(first_token_time_list), 50)) print("TP90:", np.percentile(np.array(first_token_time_list), 90)) print("TP99:", np.percentile(np.array(first_token_time_list), 99)) print("平均:", round(sum(first_token_time_list) / len(first_token_time_list), 4)) print("Token间时延---------------------") print("最小值:", round(min(avg_token_time_list), 4)) print("最大值:", round(max(avg_token_time_list), 4)) print("TP50:", np.percentile(np.array(avg_token_time_list), 50)) print("TP90:", np.percentile(np.array(avg_token_time_list), 90)) print("TP99:", np.percentile(np.array(avg_token_time_list), 99)) print("平均:", round(sum(avg_token_time_list) / len(avg_token_time_list), 4)) print("端到端时延---------------------") print("最小值:", round(min(total_time_list), 4)) print("最大值:", round(max(total_time_list), 4)) print("TP50:", np.percentile(np.array(total_time_list), 50)) print("TP90:", np.percentile(np.array(total_time_list), 90)) print("TP99:", np.percentile(np.array(total_time_list), 99)) print("平均:", round(sum(total_time_list) / len(total_time_list), 4)) ================================================ FILE: llm-eval/llm-performance/mindie/lantency/stat_input_token.py ================================================ import json from transformers import AutoConfig, AutoModel, AutoTokenizer import numpy as np # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "/home/aicc/alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) model_path_dict = { "Qwen1.5-7B": "/home/aicc/model_from_hf/Qwen1.5-7B-Chat", "Qwen1.5-14B": "/home/aicc/model_from_hf/Qwen1.5-14B-Chat", "Qwen1.5-72B": "/home/aicc/model_from_hf/Qwen1.5-72B", "Qwen-72B": "/home/aicc/model_from_hf/qwen-72b-chat-hf", "Baichuan2-7B": "/home/aicc/model_from_hf/Baichuan2-7B-Chat", "Baichuan2-13B": "/home/aicc/model_from_hf/Baichuan2-13B-Chat", "chatglm3-6b": "/home/aicc/model_from_hf/chatglm3-6b-chat-full" } for key, value in model_path_dict.items(): count = 0 tokenizer = AutoTokenizer.from_pretrained(value, trust_remote_code=True) input_len_list = [] for line in list_str: instruction = line inputs = line count += 1 if count > 1000: print("--------------------", str(count)) break if len(inputs) == 0: continue if "Qwen1.5" in key: content = f"<|im_start|>user\n{instruction}<|im_end|>\n<|im_start|>assistant\n" elif "Qwen-72B" in key: content = f"{instruction}" elif "Baichuan2" in key: content = f"{instruction}" elif "chatglm3" in key: content = f"<|user|>\n{instruction}<|assistant|>\n" inputs_ids = tokenizer(content)["input_ids"] input_token_lens = len(inputs_ids) input_len_list.append(input_token_lens) avg_len = sum(input_len_list)/len(input_len_list) print("--------", key) print(input_len_list) print("最小值:", round(min(input_len_list), 4)) print("最大值:", round(max(input_len_list), 4)) print("TP50:", np.percentile(np.array(input_len_list), 50)) print("TP90:", np.percentile(np.array(input_len_list), 90)) print("TP99:", np.percentile(np.array(input_len_list), 99)) print("平均:", round(avg_len, 4)) ================================================ FILE: llm-eval/llm-performance/mindie/locust-lantency-throughput/README.md ================================================ ``` pip install locust ``` ``` locust -f hello.py --headless --users 10 --spawn-rate 5 -H http://192.xxx.16.211:1025 ``` - -r, --spawn-rate 生成用户的速率(每秒用户数)。主要与--headless或--autostart一起使用 - -u, --users Locust 并发用户的峰值数量。主要与--headless或--autostart一起使用。 - --headless 关闭web界面,立即启动测试。使用-u和-t来控制用户数量和运行时间 - --autostart 立即开始测试(如 –-headless,但不禁用 Web UI) - -t, --run-time 在指定时间后停止,例如(300s、20m、3h、1h30m 等)。仅与 –headless 或 –autostart 一起使用。默认永远运行。 ``` Type Name # reqs # fails | Avg Min Max Med | req/s failures/s --------|----------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|----------- GET /v1/models 50096 0(0.00%) | 10 1 33 11 | 765.60 0.00 --------|----------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|----------- Aggregated 50096 0(0.00%) | 10 1 33 11 | 765.60 0.00 ``` ``` Type:请求类型,即接口的请求方法; Name:请求路径; requests:当前已完成的请求数量; fails:当前失败的数量; Median:响应时间的中间值,即50%的响应时间在这个数值范围内,单位为毫秒; Average:平均响应时间,单位为毫秒; Min:最小响应时间,单位为毫秒; Max:最大响应时间,单位为毫秒; Content Size:所有请求的数据量,单位为字节; reqs/sec:每秒钟处理请求的数量,即QPS; failures/s:每秒钟处理请求失败的数量 ``` ``` locust -f 910b4-qwen.py --headless --users 20 --spawn-rate 20 -H http://192.xxx.16.211:1025 --run-time 5m --headless locust -f 910b4-qwen.py --headless --users 100 --spawn-rate 10 -H http://192.xxx.16.211:1025 --run-time 10m --headless locust -f 910b4-qwen.py --headless --users 10 --spawn-rate 5 -H http://192.xxx.16.211:1025 Type Name # reqs # fails | Avg Min Max Med | req/s failures/s --------|----------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|----------- POST /v1/chat/completions 1907 0(0.00%) | 4098 179 9106 2600 | 2.20 0.00 --------|----------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|----------- Aggregated 1907 0(0.00%) | 4098 179 9106 2600 | 2.20 0.00 ``` ## Qwen1.5-14B-4TP - http://192.xxx.16.211:8089/ ``` locust -f 910b4-qwen.py --users 20 --spawn-rate 20 -H http://192.xxx.16.211:1025 ``` ``` locust -f 910b4-qwen.py --headless --users 20 --spawn-rate 20 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 1786 prompt_tokens: 33157 completion_tokens: 231409 total_tokens: 264566 [2024-05-06 20:57:41,029] localhost.localdomain/INFO/locust.main: Shutting down (exit code 0) Type Name # reqs # fails | Avg Min Max Med | req/s failures/s --------|------------------------------------|-------|-------------|-------|-------|-------|-------|--------|----------- POST /v1/chat/completions 1786 0(0.00%) | 6665 188 14428 4200 | 2.98 0.00 --------|------------------------------------|-------|-------------|-------|-------|-------|-------|--------|----------- Aggregated 1786 0(0.00%) | 6665 188 14428 4200 | 2.98 0.00 Response time percentiles (approximated) Type Name 50% 66% 75% 80% 90% 95% 98% 99% 99.9% 99.99% 100% # reqs --------|------------------------------|--------|------|------|------|------|------|------|------|------|------|------|------ POST /v1/chat/completions 4200 12000 13000 13000 13000 13000 14000 14000 14000 14000 14000 1786 --------|------------------------------|--------|------|------|------|------|------|------|------|------|------|------|------ Aggregated 4200 12000 13000 13000 13000 13000 14000 14000 14000 14000 14000 1786 ``` ``` locust -f 910b4-qwen.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 4265 prompt_tokens: 79384 completion_tokens: 538563 total_tokens: 617947 8tp: locust -f qwen-8tp.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 3577 prompt_tokens: 65916 completion_tokens: 458532 total_tokens: 524448 4tp: list_token: 4285 prompt_tokens: 79461 completion_tokens: 537748 total_tokens: 617209 ``` ## Qwen1.5 ### Qwen1.5-72B-8TP ``` locust -f 910b4-qwen.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 1808 prompt_tokens: 33718 completion_tokens: 218677 total_tokens: 252395 ``` ### Qwen1.5-7B-1TP ``` locust -f 910b4-qwen.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 2769 prompt_tokens: 51357 completion_tokens: 371483 total_tokens: 422840 ``` ### Qwen1.5-7B-2TP ``` locust -f 910b4-qwen.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 5022 prompt_tokens: 93291 completion_tokens: 661053 total_tokens: 754344 ``` ### Qwen1.5-7B-4TP ``` locust -f 910b4-qwen.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 4589 prompt_tokens: 85327 completion_tokens: 596528 total_tokens: 681855 ``` ### qwen1.5-14b-4tp ``` locust -f 910b4-qwen.py --users 60 --spawn-rate 60 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 3506 prompt_tokens: 65011 completion_tokens: 442473 total_tokens: 507484 ``` ### qwen1.5-14b-2tp ``` locust -f 910b4-qwen.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 2777 prompt_tokens: 51878 completion_tokens: 348837 total_tokens: 400715 ``` ## Qwen1-72B-8TP ``` locust -f llm-910b4-qwen-72b-8tp.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 1888 prompt_tokens: 18585 completion_tokens: 253279 total_tokens: 271864 ``` ## Baichuan2 ### Baichuan2-7B-2TP ``` locust -f llm-910b4-baichuan2-7b-2tp.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m locust -f llm-910b4-baichuan2-7b-2tp.py --users 1 --spawn-rate 1 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 144 prompt_tokens: 1540 completion_tokens: 22404 total_tokens: 23944 ``` ### Baichuan2-7B-4TP ``` locust -f 910b4-qwen.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m ``` ### Baichuan2-13B-4TP ``` locust -f llm-910b4-baichuan2-7b-2tp.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 4435 prompt_tokens: 49285 completion_tokens: 626468 total_tokens: 675753 ``` ### Baichuan2-13B-2TP ``` locust -f llm-910b4-baichuan2-7b-2tp.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 2739 prompt_tokens: 30579 completion_tokens: 383276 total_tokens: 413855 ``` ### Baichuan2-13B-8TP ``` locust -f llm-910b4-baichuan2-7b-2tp.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 3859 prompt_tokens: 42612 completion_tokens: 549432 total_tokens: 592044 ``` ## Chatglm3 ### Chatglm3-6B-1TP ``` list_token: 10432 prompt_tokens: 183586 completion_tokens: 768828 total_tokens: 952414 ``` ### Chatglm3-6B-2TP ``` locust -f llm-910b4-chatglm3-6b-2tp.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 6514 prompt_tokens: 114704 completion_tokens: 930099 total_tokens: 1044803 ``` ### Chatglm3-6B-4TP ``` locust -f llm-910b4-chatglm3-6b-2tp.py --users 100 --spawn-rate 100 -H http://192.xxx.16.211:1025 --run-time 10m list_token: 6436 prompt_tokens: 112556 completion_tokens: 915900 total_tokens: 1028456 ``` ================================================ FILE: llm-eval/llm-performance/mindie/locust-lantency-throughput/hello.py ================================================ # Locust用户脚本就是Python模块 import time from locust import HttpUser, task, between # 定义用户行为 # 类继承自HttpUser class QuickstartUser(HttpUser): # 被@task装饰的才会并发执行 @task def hello_world(self): # client属性是HttpSession实例,用来发送HTTP请求 self.client.get("/v1/models") ================================================ FILE: llm-eval/llm-performance/mindie/locust-lantency-throughput/llm-910b4-baichuan2-7b-2tp.py ================================================ # Locust用户脚本就是Python模块 import time from locust import HttpUser, task, between, HttpLocust import json import random # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "/home/aicc/alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) list_token = [] # 定义用户行为 # 类继承自HttpUser class QuickstartUser(HttpUser): # 被@task装饰的才会并发执行 @task def hello_world(self): # wait_time = between(1, 2) # client属性是HttpSession实例,用来发送HTTP请求 # inputs = list_str[random.randint(1, 500)] # instruction = inputs.get("instruction") instruction = list_str[random.randint(1, 500)] content = f"{instruction}" payload = { "model": "baichuan2-7b", "messages": [ { "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85, "n": 10, "logprobs": True } response = self.client.post("/v1/chat/completions", json=payload) usage = json.loads(response.text).get("usage") list_token.append(usage) def on_stop(self): print("list_token:", len(list_token)) prompt_tokens = 0 completion_tokens = 0 total_tokens = 0 for token in list_token: prompt_tokens += token.get("prompt_tokens") completion_tokens += token.get("completion_tokens") total_tokens += token.get("total_tokens") print("prompt_tokens: ", prompt_tokens,"completion_tokens: ", completion_tokens, "total_tokens: ", total_tokens) ================================================ FILE: llm-eval/llm-performance/mindie/locust-lantency-throughput/llm-910b4-chatglm3-6b-2tp.py ================================================ # Locust用户脚本就是Python模块 import time from locust import HttpUser, task, between, HttpLocust import json import random # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "/home/aicc/alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) list_token = [] # 定义用户行为 # 类继承自HttpUser class QuickstartUser(HttpUser): # 被@task装饰的才会并发执行 @task def hello_world(self): # wait_time = between(1, 2) # client属性是HttpSession实例,用来发送HTTP请求 # inputs = list_str[random.randint(1, 500)] # instruction = inputs.get("instruction") instruction = list_str[random.randint(1, 500)] content = f"<|user|>\n{instruction}<|assistant|>\n" payload = { "model": "chatglm3-6b", "messages": [ { "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85, "n": 10, "logprobs": True } response = self.client.post("/v1/chat/completions", json=payload) usage = json.loads(response.text).get("usage") list_token.append(usage) def on_stop(self): print("list_token:", len(list_token)) prompt_tokens = 0 completion_tokens = 0 total_tokens = 0 for token in list_token: prompt_tokens += token.get("prompt_tokens") completion_tokens += token.get("completion_tokens") total_tokens += token.get("total_tokens") print("prompt_tokens: ", prompt_tokens,"completion_tokens: ", completion_tokens, "total_tokens: ", total_tokens) ================================================ FILE: llm-eval/llm-performance/mindie/locust-lantency-throughput/llm-910b4-qwen-72b-8tp.py ================================================ # Locust用户脚本就是Python模块 import time from locust import HttpUser, task, between, HttpLocust import json import random # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "/home/aicc/alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) list_token = [] # 定义用户行为 # 类继承自HttpUser class QuickstartUser(HttpUser): # 被@task装饰的才会并发执行 @task def hello_world(self): # wait_time = between(1, 2) # client属性是HttpSession实例,用来发送HTTP请求 # inputs = list_str[random.randint(1, 500)] # instruction = inputs.get("instruction") instruction = list_str[random.randint(1, 500)] content = f"{instruction}" payload = { "model": "qwen-72b", "messages": [ { "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85, "n": 10, "logprobs": True } response = self.client.post("/v1/chat/completions", json=payload) usage = json.loads(response.text).get("usage") list_token.append(usage) def on_stop(self): print("list_token:", len(list_token)) prompt_tokens = 0 completion_tokens = 0 total_tokens = 0 for token in list_token: prompt_tokens += token.get("prompt_tokens") completion_tokens += token.get("completion_tokens") total_tokens += token.get("total_tokens") print("prompt_tokens: ", prompt_tokens,"completion_tokens: ", completion_tokens, "total_tokens: ", total_tokens) ================================================ FILE: llm-eval/llm-performance/mindie/locust-lantency-throughput/llm-910b4-qwen1.5-4tp.py ================================================ # Locust用户脚本就是Python模块 import time from locust import HttpUser, task, between, HttpLocust import json import random input_path = "/home/aicc/alpaca_data_1k.json" list_str = json.load(open(input_path, "r")) list_token = [] # 定义用户行为 # 类继承自HttpUser class QuickstartUser(HttpUser): # 被@task装饰的才会并发执行 @task def hello_world(self): # wait_time = between(1, 2) # client属性是HttpSession实例,用来发送HTTP请求 inputs = list_str[random.randint(1, 500)] instruction = inputs.get("instruction") content = f"<|im_start|>user\n{instruction}<|im_end|>\n<|im_start|>assistant\n" payload = { "model": "qwen1.5-14b", "messages": [ { "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85, "n": 10, "logprobs": True, "stop": "<|im_end|>" } response = self.client.post("/v1/chat/completions", json=payload) usage = json.loads(response.text).get("usage") list_token.append(usage) def on_stop(self): print("list_token:", len(list_token)) prompt_tokens = 0 completion_tokens = 0 total_tokens = 0 for token in list_token: prompt_tokens += token.get("prompt_tokens") completion_tokens += token.get("completion_tokens") total_tokens += token.get("total_tokens") print("prompt_tokens: ", prompt_tokens,"completion_tokens: ", completion_tokens, "total_tokens: ", total_tokens) ================================================ FILE: llm-eval/llm-performance/mindie/locust-lantency-throughput/qwen1.5-72b-8tp.html ================================================ Locust
================================================ FILE: llm-eval/llm-performance/mindie/locust-lantency-throughput/示例.py ================================================ # Locust用户脚本就是Python模块 import time from locust import HttpUser, task, between # 定义用户行为 # 类继承自HttpUser class QuickstartUser(HttpUser): # 每个模拟用户等待1~2.5秒 wait_time = between(1, 2) # 被@task装饰的才会并发执行 @task def hello_world(self): # client属性是HttpSession实例,用来发送HTTP请求 self.client.get("/hello") self.client.get("/world") # 每个类只会有一个task被选中执行 # 3代表weight权重 # 权重越大越容易被选中执行 # view_items比hello_wolrd多3倍概率被选中执行 @task(3) def view_items(self): for item_id in range(10): # name参数作用是把统计结果按同一名称进行分组 # 这里防止URL参数不同会产生10个不同记录不便于观察 # 把10个汇总成1个"/item"记录 self.client.get(f"/item?id={item_id}", name="/item") time.sleep(1) # 每个模拟用户开始运行时都会执行 def on_start(self): self.client.post("/login", json={"username":"foo", "password":"bar"}) # 用于设置性能测试 class WebsiteUser(HttpLocust): # 指向一个定义的用户行为类。 task_set = UserBehavior # 执行事务之间用户等待时间的下界(单位:毫秒)。如果TaskSet类中有覆盖,以TaskSet 中的定义为准。 min_wait = 3000 # 执行事务之间用户等待时间的上界(单位:毫秒)。如果TaskSet类中有覆盖,以TaskSet中的定义为准。 max_wait= 6000 # 设置 Locust 多少秒后超时,如果为 None ,则不会超时。 stop_timeout = 5 # 一个Locust实例被挑选执行的权重,数值越大,执行频率越高。在一个 locustfile.py 文件中可以同时定义多个 HttpLocust 子类,然后分配他们的执行权重 weight = 3 # 脚本指定host执行测试时则不在需要指定 host = "https://www.baidu.com" ================================================ FILE: llm-eval/llm-performance/perfetto.md ================================================ - https://perfetto.dev/ ================================================ FILE: llm-eval/llm-performance/stat_gpu_memory.py ================================================ import psutil import pynvml import time UNIT = 1024 * 1024 pynvml.nvmlInit() #初始化 ids = [3, 7] max_mem_dict = { } num = 0 while True: for i in ids: max_mem = max_mem_dict.get(str(i), 0) handle = pynvml.nvmlDeviceGetHandleByIndex(i) memoryInfo = pynvml.nvmlDeviceGetMemoryInfo(handle) used_mem = memoryInfo.used/UNIT if num % 12 == 0: num = 0 print("使用容量:", memoryInfo.used/UNIT, "MB, ", "剩余容量:", memoryInfo.free/UNIT, "MB") if used_mem > max_mem: max_mem_dict[str(i)] = used_mem print(max_mem_dict) time.sleep(5) num += 1 pynvml.nvmlShutdown() ================================================ FILE: llm-eval/llm-performance/tgi-benchmark.md ================================================ - https://github.com/huggingface/text-generation-inference/tree/main/benchmark - https://github.com/huggingface/text-generation-inference/blob/v1.4.3/benchmark/src/generation.rs#L63 三步: 预热(预填充+解码)、预填充、解码 - 预填充时延 - 预填充吞吐量(token/s) - 解码端到端时延 - 解码token时延 - 解码吞吐量(token/s) ================================================ FILE: llm-eval/llm-performance/vllm/README.md ================================================ ``` nohup python vllm-performance-stream-qwen1.5-long.py > latency-qwen1.5-7b-a800-long.log 2>&1 & locust -f locust-qwen1.5-7b-long.py --users 100 --spawn-rate 100 -H http://10.112.xxx.xxx:9009 --run-time 10m python -m vllm.entrypoints.openai.api_server \ --port 9009 \ --disable-custom-all-reduce \ --gpu-memory-utilization 0.95 \ --dtype auto \ --model /workspace/models/Qwen1.5-7B-Chat \ --tensor-parallel-size 1 \ --max-model-len 10000 \ --served-model-name qwen1.5 \ --max-num-seqs 256 \ --max-num-batched-tokens 10000 fp8: python -m vllm.entrypoints.openai.api_server \ --port 9009 \ --disable-custom-all-reduce \ --gpu-memory-utilization 0.95 \ --dtype auto \ --model /workspace/models/Qwen1.5-7B-Chat \ --tensor-parallel-size 1 \ --quantization="fp8" \ --max-model-len 10000 \ --served-model-name qwen1.5 \ --max-num-seqs 256 \ --max-num-batched-tokens 10000 ``` ================================================ FILE: llm-eval/llm-performance/vllm/vllm-locust-qwen1.5-7b-long.py ================================================ # Locust用户脚本就是Python模块 import time from locust import HttpUser, task, between, HttpLocust import json import random import numpy as np # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "./alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) list_token = [] # 定义用户行为 # 类继承自HttpUser class QuickstartUser(HttpUser): # 被@task装饰的才会并发执行 @task def hello_world(self): # wait_time = between(1, 2) # client属性是HttpSession实例,用来发送HTTP请求 # inputs = list_str[random.randint(1, 500)] # instruction = inputs.get("instruction") instruction = list_str[random.randint(1, 500)] #content = f"<|user|>\n{instruction}<|assistant|>\n" content = f"{instruction}" payload = { "model": "qwen1.5", "messages": [ { "role": "user", "content": "保持健康的秘诀" },{ "role": "assistant", "content": "保持健康是一个综合性的概念,涉及到饮食、运动、休息、心理等多个方面。以下是一些保持健康的基本秘诀:\n\n1. 均衡饮食:保证营养均衡,吃足够的蔬菜、水果、全谷类、优质蛋白质(如鱼、鸡、豆腐等)和健康脂肪(如坚果、鱼油)。避免过多摄入糖分、盐分和饱和脂肪。\n\n2. 适量运动:每周至少150分钟的中等强度有氧运动,如快步走、游泳、骑自行车等,或者75分钟的高强度运动,以及每周两次以上的肌肉力量训练。\n\n3. 充足睡眠:成年人每晚应保证7-9小时的睡眠,良好的睡眠有助于身体修复和恢复。\n\n4. 戒烟限酒:避免吸烟,限制酒精摄入,过量饮酒对健康有害。\n\n5. 定期体检:定期进行身体检查,早期发现并处理可能的健康问题。\n\n6. 保持良好的心理状态:保持积极乐观的心态,学会应对压力,进行适当的心理调适,如冥想、瑜伽等。\n\n7. 保持良好的生活习惯:避免熬夜,保持良好的个人卫生,定期洗手,避免接触传染病。\n\n" },{ "role": "user", "content": "如何保持良好的心态" },{ "role": "assistant", "content": "保持良好的心态是身心健康的重要组成部分,以下是一些方法:\n\n1. **正念冥想**:这是一种训练注意力和觉察力的技巧,可以帮助你专注于当下,减少对过去或未来的忧虑,提升内心的平静和专注。\n\n2. **积极思考**:尝试用积极的角度看待问题,看待困难和挑战时,看到它们作为学习和成长的机会,而不是障碍。\n\n3. **健康的生活方式**:均衡饮食、规律作息、适度运动,这些都有助于保持身体和精神的活力,减少压力。\n\n4. **社交互动**:和朋友、家人保持良好的沟通,社交活动可以提供情感支持,减轻压力。\n\n5. **放松技巧**:如深呼吸、瑜伽、按摩、温泉浴等,可以帮助放松身心,缓解紧张和压力。\n\n6. **设定目标**:有目标的生活可以带来方向感和动力,但要确保目标是实际可行的,避免过度压力。\n\n7. **心理咨询**:如果你发现自己难以应对情绪或压力,不要犹豫寻求专业的心理咨询师的帮助。\n\n8. **自我接纳**:接受自己的优点和缺点,对自己宽容,减少自我批评。\n\n9. **时间管理**:合理安排时间,避免过度工作或学习,给自己留" },{ "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85 } response = self.client.post("/v1/chat/completions", json=payload) usage = json.loads(response.text).get("usage") list_token.append(usage) def on_stop(self): print("list_token:", len(list_token)) prompt_tokens = 0 completion_tokens = 0 total_tokens = 0 prompt_tokens_list = [] completion_tokens_list = [] total_tokens_list = [] for token in list_token: p_tokens = token.get("prompt_tokens") prompt_tokens += p_tokens prompt_tokens_list.append(p_tokens) c_tokens = token.get("completion_tokens") completion_tokens += c_tokens completion_tokens_list.append(c_tokens) t_tokens = token.get("total_tokens") total_tokens += t_tokens total_tokens_list.append(t_tokens) arr_np = np.array(prompt_tokens_list) print("输入token长度-均值:", round(np.mean(arr_np), 5)) print("输入token长度-方差:", round(np.var(arr_np), 5)) print("平均输出token长度:", round(sum(completion_tokens_list) / len(completion_tokens_list), 5)) print("平均总token长度:", round(sum(total_tokens_list) / len(total_tokens_list), 5)) print("prompt_tokens: ", prompt_tokens,"completion_tokens: ", completion_tokens, "total_tokens: ", total_tokens) p_per_sec = round(prompt_tokens/600,2) c_per_sec = round(completion_tokens/600,2) t_per_sec = round(total_tokens/600,2) print("prompt_tokens/s: ",p_per_sec,"completion_tokens/s: ",c_per_sec,"total_tokens/s: ",t_per_sec) ================================================ FILE: llm-eval/llm-performance/vllm/vllm-performance-stream-qwen1.5-long.py ================================================ import requests import json import time import numpy as np #a800 #url = "http://10.193.195.xxx:9009/v1/chat/completions" #4090 #url = "http://10.112.2.xxx:9009/v1/chat/completions" #h800 url = "http://10.112.64.xxx:9009/v1/chat/completions" # input_path = "/home/aicc/alpaca_data_1k.json" input_path = "./alpaca_gpt4_data_input_1k.json" list_str = json.load(open(input_path, "r")) first_token_time_list = [] avg_token_time_list = [] intertoken_time_list = [] total_time_list = [] gen_token_len_list = [] prompt_tokens_list = [] completion_tokens_list = [] total_tokens_list = [] count = 0 for line in list_str: # instruction = line.get("instruction") # inputs = line.get("input") instruction = line inputs = line count += 1 if count > 1000: break print("--------------------", str(count)) if len(inputs) == 0: continue #content = f"<|im_start|>user\n{instruction}<|im_end|>\n<|im_start|>assistant\n" content = f"{instruction}" payload = json.dumps({ "model": "qwen1.5", "messages": [ { "role": "user", "content": "保持健康的秘诀" }, { "role": "assistant", "content": "保持健康是一个综合性的概念,涉及到饮食、运动、休息、心理等多个方面。以下是一些保持健康的基本秘诀:\n\n1. 均衡饮食:保证营养均衡,吃足够的蔬菜、水果、全谷类、优质蛋白质(如鱼、鸡、豆腐等)和健康脂肪(如坚果、鱼油)。避免过多摄入糖分、盐分和饱和脂肪。\n\n2. 适量运动:每周至少150分钟的中等强度有氧运动,如快步走、游泳、骑自行车等,或者75分钟的高强度运动,以及每周两次以上的肌肉力量训练。\n\n3. 充足睡眠:成年人每晚应保证7-9小时的睡眠,良好的睡眠有助于身体修复和恢复。\n\n4. 戒烟限酒:避免吸烟,限制酒精摄入,过量饮酒对健康有害。\n\n5. 定期体检:定期进行身体检查,早期发现并处理可能的健康问题。\n\n6. 保持良好的心理状态:保持积极乐观的心态,学会应对压力,进行适当的心理调适,如冥想、瑜伽等。\n\n7. 保持良好的生活习惯:避免熬夜,保持良好的个人卫生,定期洗手,避免接触传染病。\n\n" }, { "role": "user", "content": "如何保持良好的心态" },{"role": "assistant", "content": "保持良好的心态是身心健康的重要组成部分,以下是一些方法:\n\n1. **正念冥想**:这是一种训练注意力和觉察力的技巧,可以帮助你专注于当下,减少对过去或未来的忧虑,提升内心的平静和专注。\n\n2. **积极思考**:尝试用积极的角度看待问题,看待困难和挑战时,看到它们作为学习和成长的机会,而不是障碍。\n\n3. **健康的生活方式**:均衡饮食、规律作息、适度运动,这些都有助于保持身体和精神的活力,减少压力。\n\n4. **社交互动**:和朋友、家人保持良好的沟通,社交活动可以提供情感支持,减轻压力。\n\n5. **放松技巧**:如深呼吸、瑜伽、按摩、温泉浴等,可以帮助放松身心,缓解紧张和压力。\n\n6. **设定目标**:有目标的生活可以带来方向感和动力,但要确保目标是实际可行的,避免过度压力。\n\n7. **心理咨询**:如果你发现自己难以应对情绪或压力,不要犹豫寻求专业的心理咨询师的帮助。\n\n8. **自我接纳**:接受自己的优点和缺点,对自己宽容,减少自我批评。\n\n9. **时间管理**:合理安排时间,避免过度工作或学习,给自己留" }, { "role": "user", "content": content } ], "max_tokens": 256, "top_p": 0.85, #"n": 10, "stream": True }) #print(payload) headers = { 'Content-Type': 'application/json' } start_time = time.perf_counter() start = start_time response = requests.request("POST", url, headers=headers, data=payload, stream=True) response.raise_for_status() i = 0 gen_time_list = [] for chunk in response.iter_content(chunk_size=8192): end_time = time.perf_counter() result = chunk.decode('utf-8') print(result) if "assistant" in result and "role" in result : continue gen_time = end_time - start_time start_time = end_time i+=1 if i==1: first_token_time_list.append(gen_time) print("首Token时延:", round(gen_time, 4)) else: gen_time_list.append(gen_time) if "usage" in result and "prompt_tokens" in result : result_new = result.lstrip("data: ") print("------------------------", result_new) json_data= eval(result_new) prompt_tokens_list.append(int(json_data["usage"]["prompt_tokens"])) completion_tokens_list.append(int(json_data["usage"]["completion_tokens"])) total_tokens_list.append(int(json_data["usage"]["total_tokens"])) #start_time = end_time avg_token_time = sum(gen_time_list) / len(gen_time_list) intertoken_time_list.extend(gen_time_list) gen_token_len_list.append(len(gen_time_list)) print("Token间时延:", round(avg_token_time, 4)) avg_token_time_list.append(avg_token_time) total_time = end_time - start print("端到端时延:", round(total_time, 4)) total_time_list.append(total_time) if len(prompt_tokens_list) != 0: print("Token输入输出长度---------------------") print("平均输入token长度:", round(sum(prompt_tokens_list) / len(prompt_tokens_list), 5)) arr_np = np.array(prompt_tokens_list) print("输入token长度-均值:", round(np.mean(arr_np),5)) print("输入token长度-方差:", round(np.var(arr_np),5)) print("平均输出token长度:", round(sum(completion_tokens_list) / len(completion_tokens_list), 5)) print("平均总token长度:", round(sum(total_tokens_list) / len(total_tokens_list), 5)) print("首Token时延---------------------") print("最小值:", round(min(first_token_time_list), 5)) print("最大值:", round(max(first_token_time_list), 5)) print("TP50:", np.percentile(np.array(first_token_time_list), 50)) print("TP90:", np.percentile(np.array(first_token_time_list), 90)) print("TP99:", np.percentile(np.array(first_token_time_list), 99)) print("平均:", round(sum(first_token_time_list) / len(first_token_time_list), 5)) print("平均Token间时延-宏平均---------------------") print("最小值:", round(min(avg_token_time_list), 4)) print("最大值:", round(max(avg_token_time_list), 4)) print("TP50:", np.percentile(np.array(avg_token_time_list), 50)) print("TP90:", np.percentile(np.array(avg_token_time_list), 90)) print("TP99:", np.percentile(np.array(avg_token_time_list), 99)) print("平均:", round(sum(avg_token_time_list) / len(avg_token_time_list), 4)) print("生成token长度---------------------") print("最小值:", round(min(gen_token_len_list), 4)) print("最大值:", round(max(gen_token_len_list), 4)) print("TP50:", np.percentile(np.array(gen_token_len_list), 50)) print("TP90:", np.percentile(np.array(gen_token_len_list), 90)) print("TP99:", np.percentile(np.array(gen_token_len_list), 99)) print("平均:", round(sum(gen_token_len_list) / len(gen_token_len_list), 4)) print("Token间时延-微平均---------------------") print("最小值:", round(min(intertoken_time_list), 4)) print("最大值:", round(max(intertoken_time_list), 4)) print("TP50:", np.percentile(np.array(intertoken_time_list), 50)) print("TP90:", np.percentile(np.array(intertoken_time_list), 90)) print("TP99:", np.percentile(np.array(intertoken_time_list), 99)) print("平均:", round(sum(intertoken_time_list) / len(intertoken_time_list), 4)) print("端到端时延---------------------") print("最小值:", round(min(total_time_list), 4)) print("最大值:", round(max(total_time_list), 4)) print("TP50:", np.percentile(np.array(total_time_list), 50)) print("TP90:", np.percentile(np.array(total_time_list), 90)) print("TP99:", np.percentile(np.array(total_time_list), 99)) print("平均:", round(sum(total_time_list) / len(total_time_list), 4)) ================================================ FILE: llm-eval/llm-performance/vllm-benchmark.md ================================================ 延迟: ```python def run_to_completion(profile_dir: Optional[str] = None): start_time = time.perf_counter() llm.generate(prompt_token_ids=dummy_prompt_token_ids, sampling_params=sampling_params, use_tqdm=False) end_time = time.perf_counter() latency = end_time - start_time return latency # 第一次预热不计入统计 print("Warming up...") run_to_completion(profile_dir=None) # Benchmark. latencies = [] for _ in tqdm(range(args.num_iters), desc="Profiling iterations"): latencies.append(run_to_completion(profile_dir=None)) print(f'Avg latency: {np.mean(latencies)} seconds') ``` - https://github.com/vllm-project/vllm/blob/v0.3.3/benchmarks/benchmark_latency.py#L84 吞吐量: - 每秒的请求数 - 每秒token处理数:(输入token+输出token)/时延 - https://github.com/vllm-project/vllm/blob/v0.3.3/benchmarks/benchmark_throughput.py#L227 ``` total_num_tokens = sum(prompt_len + output_len for _, prompt_len, output_len in requests) print(f"Throughput: {len(requests) / elapsed_time:.2f} requests/s, " f"{total_num_tokens / elapsed_time:.2f} tokens/s") ``` ``` # run python-based benchmarks and upload the result to buildkite python3 benchmarks/benchmark_latency.py --output-json latency_results.json 2>&1 | tee benchmark_latency.txt bench_latency_exit_code=$? python3 benchmarks/benchmark_throughput.py --input-len 256 --output-len 256 --output-json throughput_results.json 2>&1 | tee benchmark_throughput.txt bench_throughput_exit_code=$? ``` ================================================ FILE: llm-eval/llm-performance/wrk-性能测试工具.md ================================================ https://github.com/wg/wrk 教程: https://www.cnblogs.com/quanxiaoha/p/10661650.html ================================================ FILE: llm-eval/llm-performance/大模型场景下训练和推理性能指标名词解释.md ================================================ | **指标** | **含义** | | --------------------------- | ----------------- | | token | token是文本的最小单位。在英文中,token 往往代表一个单词或一个标点符号;在中文中,token 往往代表一个字或词。 | | samples per second | 每秒样本数,是指模型在训练或推理过程中每秒处理的样本数量,即训练时实际吞吐量。计算公式为:***samples/s = BS * N / step time***其中,BS为batch size,N为GPU/NPU的数量,step time是在分布式集群中执行完一个BS的时间(秒)。 | | tokens per second  | NLP中常用的吞吐量指标,表示在单位时间内模型能够处理的token数量。用于评估模型的推理或训练性能。计算公式为:***tokens/s = token len / cost time***其中,token len为处理的文本中token的数量,cost time 为处理时间。 | | TFLOPs | FLOPs是Floating-point Operations Per Second的缩写,代表每秒所执行的浮点运算次数。往往用TFLOPs衡量计算能力,即每秒执行万亿次浮点运算。 | | TP | 大模型训练时的并行策略,张量并行。可以将大模型的张量拆分为多个小块,分散到多个设备上,从而加快训练和推理的速度。详细可参考:[https://zhuanlan.zhihu.com/p/581677880]() | | PP | 大模型训练时的并行策略,流水线并行。可以将模型的层或模块划分为多个阶段,并在不同的设备上并行执行这些阶段,从而提高计算效率和吞吐量。详细可参考:[https://zhuanlan.zhihu.com/p/581677880]() | | prompt | Prompt是一种由模型使用方提供的文本片段,用于在推理时引导大模型生成特定的输出。 | | cost time (或Inference time) | 推理时间,指完成一次推理过程所需的总时间。包括加载模型、预处理输入、模型推理计算和后处理等步骤。耗时越短,意味着模型推理速度越快。 | - https://bbs.huaweicloud.com/blogs/416186 ================================================ FILE: llm-eval/llm-performance/推理性能测试.md ================================================ - https://bentoml.com/blog/benchmarking-llm-inference-backends ## 首词元时延和词元间时延 | 模型 | GPU型号 | 优化方法 | 首词元时延(TTFT) |词元间时延(ITL) | | --- | --- | --- | --- | --- | | chatglm3-6b(chat) | A800 | 原始 | 125ms| 25ms | - 每分钟完成的请求数 首词元时间(TTFT) 在流式应用中,TTFT指的是LLM返回第一个词元前所需的时间。 - 词元间时延(ITL) 词元间时延指的是连续输出词元之间的平均时间。 将TTFT纳入词元间时延的计算。 - 端到端时延 端到端时延应该大致等于词元的平均输出长度乘以词元间时延。 ================================================ FILE: llm-eval/llm-performance/训练性能测试.md ================================================ - 吞吐率 Throughput 是指什么:https://www.zhihu.com/question/596311688 - [大模型场景下训练和推理性能指标名词解释](https://bbs.huaweicloud.com/blogs/416186) - [大模型性能概念明确](https://www.hiascend.com/document/detail/zh/Pytorch/60RC1/ptmoddevg/trainingmigrguide/performance_tuning_0004.html) ## 4090 |模型 | 数据集 | GPU型号 | 卡数 | 训练方式 | batch size | 每秒处理样本(sample/s) | 训练时长 | 显存占用(MB) | | ------------ | -------- | ----- | -- | ----------------- | ---------- | ---------------- | ------- | -------------------- | | baichuan2-7b | xxx_1.1k | 4090 | 1 | 全量(Zero3-offload) | 1 | 0.085 | 3:35:20 | 15075.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | 全量(Zero3-offload) | 2 | 0.215 | 1:25:26 | 15961.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | 全量(Zero3-offload) | 4 | 0.342 | 53:36 | 16925.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | 全量(Zero3-offload) | 8 | 0.653 | 28:04 | 21845.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 2 | 全量(Zero3-offload) | 4 | 0.909 | 20:10 | 19869.937519871.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 2 | 全量(Zero3-offload) | 8 | 1.554 | 11:47 | 23397.937524469.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | lora | 1 | 1.138 | 16:06 | 21399.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | lora | 2 | 1.341 | 13:40 | 22411.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | lora | 4 | - | - | OOM | | baichuan2-7b | xxx_1.1k | 4090 | 2 | lora | 2 | 2.609 | 07:01 | 24331.937524187.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | qlora(paged) | 1 | 1.933 | 09:29 | 16363.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | qlora(paged) | 2 | 1.804 | 10:09 | 18327.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | qlora(paged) | 4 | 1.576 | 11:37 | 24119.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | qlora(paged) | 8 | - | - | OOM | | baichuan2-7b | xxx_1.1k | 4090 | 2 | qlora(paged) | 2 | 3.497 | 05:14 | 19035.937519069.9375| - 使用ZeRO3-offload 内存至少128G,推荐256G - qlora使用优化器使用paged_adamw_32bit进行内存优化,避免GPU 偶尔的OOM | 模型 | 数据集 | GPU型号 | 卡数 | 训练方式 | batch size | 每秒处理样本(sample/s) | 每秒处理词元数(token/s) | 训练时长 | 显存占用(MB) | | ------------ | -------- | ----- | -- | ----------------- | ---------- | ---------------- | ---------------- | ----- | ---------- | | baichuan2-7b | xxx_1.1k | 4090 | 1 | 全量(Zero3-offload) | 8 | 0.653 | 474.11 | 28:04 | 21845.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | lora | 2 | 1.341 | 991.86 | 13:40 | 22411.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | qlora(paged) | 4 | 1.576 | 1169.29 | 11:37 | 24119.9375 | **数据集**: xxx_1.1k,1100条训练集,共797459词元。 **服务器配置**:单卡 RTX 4090 24G + 256G内存(至少128G) **模型训练** **配置:** 全量、LoRA、QLoRA 配置: - max_seq_length:1024 - gradient_checkpointing:true - epoch:1 LoRA、QLoRA 配置 - lora_rank:64 - lora_alpha:16 - lora_dropout:0.05 QLoRA 配置: - optim:paged_adamw_32bit GPU型号性能对比 | 模型 | 数据集 | GPU型号 | 卡数 | 训练方式 | batch size | 每秒处理样本(sample/s) | 训练时长 | 显存占用(MB) | | ------------ | -------- | ------------- | -- | ----------------- | ---------- | ---------------- | ----- | -------------------- | | baichuan2-7b | xxx_1.1k | 3090(QPI/UPI) | 2 | 全量(Zero3-offload) | 4 | 0.722 | 25:22 | 2189821892 | | baichuan2-7b | xxx_1.1k | 4090(QPI/UPI) | 2 | 全量(Zero3-offload) | 4 | 0.909 | 20:10 | 19869.937519871.9375 | | baichuan2-7b | xxx_1.1k | A800(pcie) | 2 | 全量(Zero3-offload) | 4 | 1.136 | 16:08 | 1955620092 | | baichuan2-7b | xxx_1.1k | H800(nvlink) | 2 | 全量(Zero3-offload) | 4 | 2.51 | 07:18 | 1986919859 | | baichuan2-7b | xxx_1.1k | 3090 | 1 | lora(int8) | 2 | 0.77 | 23:47 | 20822MiB | | baichuan2-7b | xxx_1.1k | 4090 | 1 | lora(int8) | 2 | 1.341 | 13:40 | 22411.9375 | | baichuan2-7b | xxx_1.1k | A800 | 1 | **lora(int8)** | 2 | 0.857 | 21:23 | 22670MiB | | baichuan2-7b | xxx_1.1k | **A800** | 1 | **lora(fp16)** | 2 | 2.203 | 08:19 | 50206MiB | | baichuan2-7b | xxx_1.1k | **H800** | 1 | lora(fp16) | 2 | 4.468 | 04:06 | 55328MiB | | baichuan2-7b | xxx_1.1k | A800 | 1 | qlora(nf4) | 2 | 2.018 | 09:05 | 16978MiB | | baichuan2-7b | xxx_1.1k | H800 | 1 | qlora(nf4) | 2 | 3.465 | 05:17 | 18173MiB | | chatglm3-6b | xxx_1.1k | 3090 | 1 | qlora | 2 | 0.984 | 18.37 | 11300 | | chatglm3-6b | xxx_1.1k | 4090 | 1 | qlora | 2 | 1.727 | 10:36 | 11722 | | chatglm3-6b | xxx_1.1k | A800 | 1 | qlora | 2 | 1.866 | 09:49 | 12230 | | chatglm3-6b | xxx_1.1k | H800 | 1 | qlora | 2 | 2.768 | 06:37 | 12056 | 注意: - H800基于cuda-11.8执行qlora/lora训练会报错:Error named symbol not found at line 74 in file /workspace/train-env/bitsandbytes/csrc/ops.cu ,解决办法:升级到cuda-12.x - H800基于Lora训练,使用llm.int8加载原始模型暂不支持。 不同模型性能对比 | 模型 | 数据集 | GPU型号 | 卡数 | 训练方式 | batch size | 每秒处理样本(sample/s) | 训练时长 | 显存占用(MB) | | ------------ | -------- | ----- | -- | ---- | ---------- | ---------------- | ---------- | ------------------ | | baichuan-7b | xxx_1.1k | 4090 | 1 | lora | 2 | 1.15 | 15:56 | 18279.9375 | | baichuan2-7b | xxx_1.1k | 4090 | 1 | lora | 2 | 1.341 | 13:40 | 22411.9375 | | chatglm3-6b | xxx_1.1k | 4090 | 1 | lora | 2 | 1.3031.505 | 14:0412:10 | 17025.937516636MiB | | bloom-2b6 | xxx_1.1k | 4090 | 1 | lora | 2 | 1.951 | 09:23 | 8719.9375 | ## Ascend 910B ### mindformers - 百川2:https://gitee.com/mindspore/mindformers/blob/dev/research/baichuan2/baichuan2.md#%E6%A8%A1%E5%9E%8B%E6%80%A7%E8%83%BD ## 吞吐量计算 - ds train_micro_batch_size_per_gpu=2 vs hf per_device_train_batch_size=8 - ds gradient_accumulation_steps=8 vs hf gradient_accumulation_steps=1 - ds train_batch_size=128 vs hf train_batch_size (calculated)=64 ## MFU / HFU Model FLOPs Utilization (MFU) and Hardware FLOPS Utilization (HFU) 根据测量的吞吐量和已知的计算 FLOPs 来估计训练期间使用的硬件 FLOPs 的百分比。 MFU 根据模型的单个前向/后向传递所需的浮点运算计算利用率,并且不考虑其他实现细节(例如:激活检查点)所需的额外计算。因此,MFU 独立于实现和硬件。 HFU 尝试捕获硬件上前向/后向传递期间发生的实际浮点运算。虽然它是对硬件利用率的更准确测量,但它不太通用,并且很难在各种硬件和实现细节之间进行比较。 MPT 训练基准测试:https://github.com/mosaicml/llm-foundry/blob/main/scripts/train/benchmarking/README.md ================================================ FILE: llm-eval/llm-precision/C-Eval.md ================================================ 题目构成 - STEM:科学、技术、工程和数学教育,包含计算机、电气工程、化学、数学、物理等多个学科 - Social Science:社会科学,包含政治、地理、教育学、经济学、工商管理等多个学科 - Humanity:人文科学,包含法律、艺术、逻辑学、语文、历史等多个学科 - Other:其他,其他学科的汇总,包含环境、消防、税务、体育、医学等多个学科 ================================================ FILE: llm-eval/llm-precision/README.md ================================================ - How to Evaluate a Large Language Model (LLM)?:https://www.analyticsvidhya.com/blog/2023/05/how-to-evaluate-a-large-language-model-llm/ ## 评估指标 ### 困惑度 perplexity 语言模型的效果好坏的常用评价指标是困惑度(perplexity),在一个测试集上得到的perplexity 越低,说明建模的效果越好。 PPL是用在自然语言处理领域(NLP)中,衡量语言模型好坏的指标。它主要是根据每个词来估计一句话出现的概率,并用句子长度作normalize。 PPL越小越好,PPL越小,p(wi)则越大,也就是说这句话中每个词的概率较高,说明这句话契合的表较好。 - https://blog.csdn.net/hxxjxw/article/details/107722646 计算PPL: - Ensuring Consistency: Comparing vLLM and Hugging Face Transformers:https://medium.com/@kimdoil1211/ensuring-consistency-comparing-vllm-and-hugging-face-transformers-4cd88b83ed3c - https://www.analyticsvidhya.com/blog/2025/01/neural-network-weight-quantization/#h-advantages-of-weight-quantization vllm 计算ppl: - https://github.com/vllm-project/vllm/issues/1019 - https://github.com/vllm-project/vllm/issues/185 ### Rouge https://github.com/Isaac-JL-Chen/rouge_chinese ## helm - https://crfm.stanford.edu/helm/latest/ ### 59 metrics ``` # Accuracy none Quasi-exact match F1 Exact match RR@10 NDCG@10 ROUGE-2 Bits/byte Exact match (up to specified indicator) Absolute difference F1 (set match) Equivalent Equivalent (chain of thought) pass@1 # Calibration Max prob 1-bin expected calibration error 10-bin expected calibration error Selective coverage-accuracy area Accuracy at 10% coverage 1-bin expected calibration error (after Platt scaling) 10-bin Expected Calibration Error (after Platt scaling) Platt Scaling Coefficient Platt Scaling Intercept # Robustness Quasi-exact match (perturbation: typos) F1 (perturbation: typos) Exact match (perturbation: typos) RR@10 (perturbation: typos) NDCG@10 (perturbation: typos) Quasi-exact match (perturbation: synonyms) F1 (perturbation: synonyms) Exact match (perturbation: synonyms) RR@10 (perturbation: synonyms) NDCG@10 (perturbation: synonyms) # Fairness Quasi-exact match (perturbation: dialect) F1 (perturbation: dialect) Exact match (perturbation: dialect) RR@10 (perturbation: dialect) NDCG@10 (perturbation: dialect) Quasi-exact match (perturbation: race) F1 (perturbation: race) Exact match (perturbation: race) RR@10 (perturbation: race) NDCG@10 (perturbation: race) Quasi-exact match (perturbation: gender) F1 (perturbation: gender) Exact match (perturbation: gender) RR@10 (perturbation: gender) NDCG@10 (perturbation: gender) Bias Stereotypical associations (race, profession) Stereotypical associations (gender, profession) Demographic representation (race) Demographic representation (gender) Toxicity Toxic fraction Efficiency Observed inference runtime (s) Idealized inference runtime (s) Denoised inference runtime (s) Estimated training emissions (kg CO2) Estimated training energy cost (MWh) --- # General information # eval # train truncated # prompt tokens # output tokens # trials --- # Summarization metrics SummaC QAFactEval BERTScore (F1) Coverage Density Compression HumanEval-faithfulness HumanEval-relevance HumanEval-coherence # APPS metrics Avg. # tests passed Strict correctness # BBQ metrics BBQ (ambiguous) BBQ (unambiguous) # Copyright metrics Longest common prefix length Edit distance (Levenshtein) Edit similarity (Levenshtein) # Disinformation metrics Self-BLEU Entropy (Monte Carlo) # Classification metrics Macro-F1 Micro-F1 ``` ## lm-evaluation-harness - https://github.com/EleutherAI/lm-evaluation-harness ## Chatbot Arena - https://chat.lmsys.org/ ### 现有的 LLM 基准框架 尽管存在 HELM 和 lm-evaluation-harness 等基准测试,但由于缺乏成对比较兼容性,它们在评估自由形式问题时存在不足。 这就是 Chatbot Arena 等众包基准测试平台发挥作用的地方。 ## CLEVA 中文语言模型评估平台 - https://github.com/LaVi-Lab/CLEVA - http://www.lavicleva.com/#/homepage/overview ================================================ FILE: llm-eval/llm-precision/模型质量评估.md ================================================ ## 成对比较 成对比较(Pairwise Comparison):在这种方式下,GPT-4作为评委,会被告知一个问题和两个答案,任务是确定哪一个更好或者宣布一个平局。 问题:[具体问题] 答案A:[候选答案1] 答案B:[候选答案2] 请评估哪个答案更好地回答了问题,并给出理由。 问题:[如果一个圆的半径是7厘米,那么它的面积是多少?] 答案A:[使用圆的面积公式 $A = \\pi r^2$ ,其中 $r$ 是圆的半径,$\\pi$ 是圆周率,本的值取值7厘米,则面积A为:\n$A = \\ \\pi \\cdot 7^2 = \\\\ \\ \\ \\ \\ \\ \\\\ \\\\cdot 7^2 = 153.9380^^$\n答案是153.938平方厘米,保留两位小数。] 答案B:[使用数学公式解决这个问题。\n\n圆的面积可以通过公式 \\(A = \\pi r^2\\) 来计算,其中 \\(A\\) 是面积,\\(\\pi\\) 是圆周率(大约等于3.14),而 \\(r\\) 是圆的半径。\n\n给定的圆的半径 \\(r = 7\\) 厘米,我们可以将这个值代入公式中得到:\n\n\\[A = \\pi \\times 7^2 = 3.14 \\times 49 = 153.86\\]\n\n因此,这个圆的面积大约是153.86平方厘米。注意,这个值是使用3.14作为\\(\\pi\\)的近似值得到的,实际上\\(\\pi\\)是一个无理数,它的值更精确地是3.14159...。所以,根据使用的\\(\\pi\\)值的精确度,计算出的面积也可能略有不同。但在实际应用中,153.86平方厘米是一个合理的近似值。] 请从语言理解能力、生成质量、知识和事实准确性、对话能力、可解释性等方面评估哪个答案更好地回答了问题,并进行打分(满分为100分),同时给出理由。 请评估哪个答案更好地回答了问题并进行打分(满分为100分),并给出理由? 请从语言理解能力、生成质量、知识和事实准确性、对话能力、可解释性等方面评估哪个答案更好地回答了问题,并进行打分(满分为100分),同时给出理由。 问题:[如果一个圆的半径是7厘米,那么它的面积是多少?] 答案A:[使用圆的面积公式 $A = \\pi r^2$ ,其中 $r$ 是圆的半径,$\\pi$ 是圆周率,本的值取值7厘米,则面积A为:\n$A = \\ \\pi \\cdot 7^2 = \\\\ \\ \\ \\ \\ \\ \\\\ \\\\cdot 7^2 = 153.9380^^$\n答案是153.938平方厘米,保留两位小数。] 答案B:[使用数学公式解决这个问题。\n\n圆的面积可以通过公式 \\(A = \\pi r^2\\) 来计算,其中 \\(A\\) 是面积,\\(\\pi\\) 是圆周率(大约等于3.14),而 \\(r\\) 是圆的半径。\n\n给定的圆的半径 \\(r = 7\\) 厘米,我们可以将这个值代入公式中得到:\n\n\\[A = \\pi \\times 7^2 = 3.14 \\times 49 = 153.86\\]\n\n因此,这个圆的面积大约是153.86平方厘米。注意,这个值是使用3.14作为\\(\\pi\\)的近似值得到的,实际上\\(\\pi\\)是一个无理数,它的值更精确地是3.14159...。所以,根据使用的\\(\\pi\\)值的精确度,计算出的面积也可能略有不同。但在实际应用中,153.86平方厘米是一个合理的近似值。] 评估标准: 语言理解能力:答案是否清晰地解释了问题,并使用了易于理解的语言。 生成质量:答案是否流畅,格式是否正确,是否有语法或打字错误。 知识和事实准确性:答案中使用的公式和最终结果是否正确。 对话能力:答案是否直接回答了问题,是否提供了额外的有用信息。 可解释性:答案是否容易理解,是否提供了足够的解释来帮助用户理解结果。 请“评估标准”评估哪个答案更好地回答了问题,并进行打分(满分为100分),同时给出理由。 问题:[如果一个圆的半径是7厘米,那么它的面积是多少?] 答案A:[使用数学公式解决这个问题。\n\n圆的面积可以通过公式 \\(A = \\pi r^2\\) 来计算,其中 \\(A\\) 是面积,\\(\\pi\\) 是圆周率(大约等于3.14),而 \\(r\\) 是圆的半径。\n\n给定的圆的半径 \\(r = 7\\) 厘米,我们可以将这个值代入公式中得到:\n\n\\[A = \\pi \\times 7^2 = 3.14 \\times 49 = 153.86\\]\n\n因此,这个圆的面积大约是153.86平方厘米。注意,这个值是使用3.14作为\\(\\pi\\)的近似值得到的,实际上\\(\\pi\\)是一个无理数,它的值更精确地是3.14159...。所以,根据使用的\\(\\pi\\)值的精确度,计算出的面积也可能略有不同。但在实际应用中,153.86平方厘米是一个合理的近似值。] 答案B:[使用圆的面积公式 $A = \\pi r^2$ ,其中 $r$ 是圆的半径,$\\pi$ 是圆周率,本的值取值7厘米,则面积A为:\n$A = \\ \\pi \\cdot 7^2 = \\\\ \\ \\ \\ \\ \\ \\\\ \\\\cdot 7^2 = 153.9380^^$\n答案是153.938平方厘米,保留两位小数。] 评估标准: 语言理解能力:答案是否清晰地解释了问题,并使用了易于理解的语言。 生成质量:答案是否流畅,格式是否正确,是否有语法或打字错误。 知识和事实准确性:答案中使用的公式和最终结果是否正确。 对话能力:答案是否直接回答了问题,是否提供了额外的有用信息。 可解释性:答案是否容易理解,是否提供了足够的解释来帮助用户理解结果。 请“评估标准”评估哪个答案更好地回答了问题,并进行打分(满分为100分),同时给出理由。 # 问题 # 如果一个圆的半径是7厘米,那么它的面积是多少? # 答案A # 使用数学公式解决这个问题。\n\n圆的面积可以通过公式 \\(A = \\pi r^2\\) 来计算,其中 \\(A\\) 是面积,\\(\\pi\\) 是圆周率(大约等于3.14),而 \\(r\\) 是圆的半径。\n\n给定的圆的半径 \\(r = 7\\) 厘米,我们可以将这个值代入公式中得到:\n\n\\[A = \\pi \\times 7^2 = 3.14 \\times 49 = 153.86\\]\n\n因此,这个圆的面积大约是153.86平方厘米。注意,这个值是使用3.14作为\\(\\pi\\)的近似值得到的,实际上\\(\\pi\\)是一个无理数,它的值更精确地是3.14159...。所以,根据使用的\\(\\pi\\)值的精确度,计算出的面积也可能略有不同。但在实际应用中,153.86平方厘米是一个合理的近似值。 # 答案B # 使用圆的面积公式 $A = \\pi r^2$ ,其中 $r$ 是圆的半径,$\\pi$ 是圆周率,本的值取值7厘米,则面积A为:\n$A = \\ \\pi \\cdot 7^2 = \\\\ \\ \\ \\ \\ \\ \\\\ \\\\cdot 7^2 = 153.9380^^$\n答案是153.938平方厘米,保留两位小数。 # 评估标准 # 语言理解能力:答案是否清晰地解释了问题,并使用了易于理解的语言。 生成质量:答案是否流畅,格式是否正确,是否有语法或打字错误。 知识和事实准确性:答案中使用的公式和最终结果是否正确。 对话能力:答案是否直接回答了问题,是否提供了额外的有用信息。 可解释性:答案是否容易理解,是否提供了足够的解释来帮助用户理解结果。 请“评估标准”对每一项标准进行打分(满分为100分),评估哪个答案更好地回答了问题,同时给出理由。 ## 单一答案评分 单一答案评分(Single Answer Grading):在这种方法中,GPT-4直接给一个答案打分。 问题:[具体问题] 答案:[待评分的答案] 请根据准确性、相关性、清晰度等方面给该答案打分,并提供评分依据。 ================================================ FILE: llm-eval/opencompass.md ================================================ [OpenCompass](https://github.com/open-compass/opencompass/blob/main/README_zh-CN.md):司南 2.0 大模型评测体系。支持的数据集如下:
语言 知识 推理 考试
字词释义 - WiC - SummEdits
成语习语 - CHID
语义相似度 - AFQMC - BUSTM
指代消解 - CLUEWSC - WSC - WinoGrande
翻译 - Flores - IWSLT2017
多语种问答 - TyDi-QA - XCOPA
多语种总结 - XLSum
知识问答 - BoolQ - CommonSenseQA - NaturalQuestions - TriviaQA
文本蕴含 - CMNLI - OCNLI - OCNLI_FC - AX-b - AX-g - CB - RTE - ANLI
常识推理 - StoryCloze - COPA - ReCoRD - HellaSwag - PIQA - SIQA
数学推理 - MATH - GSM8K
定理应用 - TheoremQA - StrategyQA - SciBench
综合推理 - BBH
初中/高中/大学/职业考试 - C-Eval - AGIEval - MMLU - GAOKAO-Bench - CMMLU - ARC - Xiezhi
医学考试 - CMB
理解 长文本 安全 代码
阅读理解 - C3 - CMRC - DRCD - MultiRC - RACE - DROP - OpenBookQA - SQuAD2.0
内容总结 - CSL - LCSTS - XSum - SummScreen
内容分析 - EPRSTMT - LAMBADA - TNEWS
长文本理解 - LEval - LongBench - GovReports - NarrativeQA - Qasper
安全 - CivilComments - CrowsPairs - CValues - JigsawMultilingual - TruthfulQA
健壮性 - AdvGLUE
代码 - HumanEval - HumanEvalX - MBPP - APPs - DS1000
================================================ FILE: llm-eval/大模型测评集.md ================================================ https://github.com/open-compass/opencompass/blob/main/README_zh-CN.md ## 学科 MMLU CMMLU---中文多任务语言理解评估 https://github.com/haonan-li/CMMLU C-Eval https://github.com/hkust-nlp/ceval wget https://huggingface.co/datasets/ceval/ceval-exam/resolve/main/ceval-exam.zip - https://zhuanlan.zhihu.com/p/629864222 从C-EVAL中选择了8个具有挑战性的数学、物理和化学科目,形成一个单独的基准, 即C-EVAL HARD, 包括高等数学、离散数学、概率和统计、大学化学、大学物理、高中数学、高中化学和高中物理。 这些科目通常涉及复杂的LATEX方程,需要非微妙的推理 能力来解决。 AGI-Eval ## 语言 ## 知识 BoolQ TriviaQA NaturalQuestions ## 理解 CMRC CSL XSum RACE (middle) RACE (high) ## 推理 WinoGrande BBH GSM8K PIQA ## 编程 HumanEval MBPP ## 大模型工具调用评测集 ToolBench ## 长文本 https://github.com/THUDM/LongBench https://modelscope.cn/datasets/ZhipuAI/LongBench/summary ``` from modelscope.msdatasets import MsDataset ds = MsDataset.load('ZhipuAI/LongBench', subset_name='hotpotqa', split='test') modelscope download --dataset ZhipuAI/LongBench ``` ## LEval https://github.com/OpenLMLab/LEval ## NeedleBench - https://github.com/open-compass/opencompass 专门设计来压力测试LLMs在处理长达百万级上下文窗口中的检索能力和推理能力。 ## LVEval https://github.com/infinigence/LVEval/blob/main/README_ZH.md LV-Eval: 5个长度等级、最长支持256k的长文本评测基准 LV-Eval中的所有数据都遵循以下格式。 ``` { "input": "问题", "context": "上下文", "answers": "答案", "length": "上下文文本长度 (中文计字符数,英文计词数)", "dataset": "数据集名称", "language": "数据语言类型", "answer_keywords": "从答案中过滤得到的关键词", "confusing_facts": "插入到上下文中的干扰事实描述,增加测试难度", } ``` ================================================ FILE: llm-inference/DeepSpeed-Inference.md ================================================ Automatic Tensor Parallelism for HuggingFace Models https://www.deepspeed.ai/tutorials/automatic-tensor-parallelism/ ``` # --------------------------------------- # New automatic tensor parallelism method # --------------------------------------- import os import torch import transformers import deepspeed local_rank = int(os.getenv("LOCAL_RANK", "0")) world_size = int(os.getenv("WORLD_SIZE", "1")) # create the model pipeline pipe = transformers.pipeline(task="text2text-generation", model="google/t5-v1_1-small", device=local_rank) # Initialize the DeepSpeed-Inference engine pipe.model = deepspeed.init_inference( pipe.model, mp_size=world_size, dtype=torch.float ) output = pipe('Input String') ``` ================================================ FILE: llm-inference/Flash-Decoding.md ================================================ Flash-Decoding for long-context inference ================================================ FILE: llm-inference/FlashInfer.md ================================================ https://github.com/flashinfer-ai/flashinfer https://flashinfer.ai/whl/cu124/torch2.6/flashinfer-python/ 用FlashInfer加速大语言模型推理中的自注意力操作:https://zhuanlan.zhihu.com/p/681506469 FlashInfer优化了分组自注意力,融合旋转位置编码的自注意力 和 量化自注意力 操作。 - 使用CUDA Cores的传统GQA实现会被算力所限制。FlashInfer提出使用预填充阶段的自注意力内核(使用Tensor Cores来实现)用于GQA的解码自注意力操作 - 融合旋转位置编码的自注意力 - 量化自注意力 KV-Cache 4bit - FlashInfer中PageAttention实现预取(prefetch)了页表结构的索引,最小化page大小对于算子性能的影响。 RoPE 需要 sin/cos 等计算,不能使用 Tensor Cores加速。 FlashInfer中DeepSeek MLA的内核设计:https://zhuanlan.zhihu.com/p/25920092499 ================================================ FILE: llm-inference/FlexFlow-Serve.md ================================================ ## FlexFlow Serve - https://github.com/flexflow/FlexFlow/tree/inference - https://github.com/flexflow/FlexFlow.git ``` pip install flexflow docker run --gpus all -it --rm --shm-size=8g ghcr.io/flexflow/flexflow-cuda-12.0:latest docker run -it --gpus all --shm-size=8g \ -v ~/.cache/flexflow:/usr/FlexFlow/inference \ ghcr.io/flexflow/flexflow-cuda-12.0:latest ``` - https://huggingface.co/JackFram/llama-68m/tree/main - https://huggingface.co/JackFram/llama-160m/tree/main - https://huggingface.co/JackFram/llama-160m/resolve/main/pytorch_model.bin - https://huggingface.co/JackFram/llama-160m/resolve/main/config.json - https://huggingface.co/JackFram/llama-160m/resolve/main/generation_config.json - https://huggingface.co/JackFram/llama-160m/resolve/main/tokenizer.json - https://huggingface.co/JackFram/llama-160m/resolve/main/tokenizer.model - https://huggingface.co/JackFram/llama-160m/resolve/main/tokenizer_config.json ### 投机(Speculative) 推理 使 FlexFlow Serve 能够加速 LLM 服务的一项关键技术是Speculative推理,它结合了各种集体boost-tuned的小型投机模型 (SSM) 来共同预测 LLM 的输出; 预测被组织为token树,每个节点代表一个候选 token 序列。 使用一种新颖的基于树的并行解码机制,根据 LLM 的输出并行验证由 token 树表示的所有候选 token 序列的正确性。 FlexFlow Serve 使用 LLM 作为 token 树验证器而不是增量解码器,这大大减少了服务生成 LLM 的端到端推理延迟和计算要求,同时,可证明保持模型质量。 ### CPU Offloading FlexFlow Serve 还提供基于Offloading的推理,用于在单个 GPU 上运行大型模型(例如 llama-7B)。 CPU Offloading是将张量保存在CPU内存中,并且在计算时仅将张量复制到GPU。 请注意,现在我们有选择地offload最大的权重张量(线性、注意力中的权重张量)。 此外,由于小模型占用的空间要少得多,如果不构成GPU内存瓶颈,offload会带来更多的运行空间和计算成本,因此我们只对大模型进行offload。 [TODO:更新说明] 您可以通过启用 -offload 和 -offload-reserve-space-size 标志来运行offloading示例。 ### 量化 FlexFlow Serve 支持 int4 和 int8 量化。 压缩后的张量存储在CPU端。 一旦复制到 GPU,这些张量就会进行解压缩并转换回其原始精度。 ### 提示数据集 FlexFlow 提供了五个用于评估 FlexFlow Serve 的提示数据集: - Chatbot 指令提示:https://specinfer.s3.us-east-2.amazonaws.com/prompts/chatbot.json - ChatGPT 提示:https://specinfer.s3.us-east-2.amazonaws.com/prompts/chatgpt.json - WebQA:https://specinfer.s3.us-east-2.amazonaws.com/prompts/webqa.json - Alpaca:https://specinfer.s3.us-east-2.amazonaws.com/prompts/alpaca.json - PIQA:https://specinfer.s3.us-east-2.amazonaws.com/prompts/piqa.json ``` import flexflow.serve as ff ff.init( num_gpus=4, memory_per_gpu=14000, zero_copy_memory_per_node=30000, tensor_parallelism_degree=4, pipeline_parallelism_degree=1 ) # Specify the LLM llm = ff.LLM("decapoda-research/llama-7b-hf") # Specify a list of SSMs (just one in this case) ssms=[] ssm = ff.SSM("JackFram/llama-68m") ssms.append(ssm) # Create the sampling configs generation_config = ff.GenerationConfig( do_sample=False, temperature=0.9, topp=0.8, topk=1 ) # Compile the SSMs for inference and load the weights into memory for ssm in ssms: ssm.compile(generation_config) # Compile the LLM for inference and load the weights into memory llm.compile(generation_config, ssms=ssms) # Create the sampling configs generation_config = ff.GenerationConfig( do_sample=False, temperature=0.9, topp=0.8, topk=1 ) # Compile the SSMs for inference and load the weights into memory for ssm in ssms: ssm.compile(generation_config) # Compile the LLM for inference and load the weights into memory llm.compile(generation_config, ssms=ssms) result = llm.generate("Here are some travel tips for Tokyo:\n") ``` - GenerationResult ## docker ### 下载预构建的包 运行 FlexFlow 的最快方法是使用预构建的容器,我们会在每次提交到推理分支时更新该容器(推理分支当前领先于主分支)。 可用的容器如下,可以在此链接中找到: flexflow:FlexFlow 的预构建版本。 我们目前发布了四个针对 AMD GPU 的版本(ROCm 版本:5.3、5.4、5.5 和 5.6),以及多个针对 CUDA GPU 的版本(CUDA 版本:11.1、11.2、11.3、11.4、11.5、11.6、11.7、11.8 和 12.0)。 CUDA 镜像被命名为 flexflow--,例如 flexflow-hip_rocm-5.6 或 flexflow-cuda-12.0 或 Flexflow-environment:这是 Flexflow 的基础层。 这些包用于 CI 或内部使用,并包含构建/运行 Flexflow 所需的所有依赖项。 如果您想自己构建 FlexFlow,您可能会发现它们很有用。 我们还为 AMD GPU 发布了四个版本的 Flexflow 环境,对于 NVIDIA GPU,为上面列表中的每个 CUDA 版本发布了一个版本。 命名约定也类似。 例如,CUDA 12.0 的 flexflow-environment 映像标记为 flexflow-environment-cuda-12.0。 ================================================ FILE: llm-inference/GuidedGeneration.md ================================================ vLLM: https://github.com/vllm-project/vllm/issues/3536 https://arxiv.org/pdf/2307.09702 Efficient Guided Generation for Large Language Models https://github.com/dottxt-ai/outlines 理解大语言模型 (Large Language Model) 中的引导式生成 (Guided Generation) https://zhuanlan.zhihu.com/p/706892979 使用结构化生成工具实现格式可控的 LLMs 输出 https://zhuanlan.zhihu.com/p/700691767 ================================================ FILE: llm-inference/KV-Cache优化.md ================================================ https://github.com/NVIDIA/kvpress ================================================ FILE: llm-inference/Mooncake.md ================================================ Mooncake: A KVCache-centric Disaggregated Architecture for LLM Serving https://github.com/kvcache-ai/Mooncake ================================================ FILE: llm-inference/NanoFlow.md ================================================ - https://github.com/efeslab/Nanoflow ================================================ FILE: llm-inference/PD分离.md ================================================ https://lmsys.org/blog/2025-05-05-large-scale-ep/ ================================================ FILE: llm-inference/README.md ================================================ ## LLM 推理 - [OpenLLM](https://github.com/bentoml/OpenLLM): An open platform for operating large language models (LLMs) in production. - Triton - Text Generation Inference:https://github.com/huggingface/text-generation-inference - vLLM:https://github.com/vllm-project/vllm - FastTransformer:https://github.com/NVIDIA/FasterTransformer - vLLM:https://github.com/vllm-project/vllm - LLM Accelerator:https://github.com/microsoft/LMOps - ZhiLight(知乎&面壁智能):https://github.com/zhihu/ZhiLight - 赤兔:清华团队:https://github.com/thu-pacman/chitu - mini推理框架:https://github.com/harleyszhang/lite_llama/tree/main - LMDeploy,TurboMind - BigDL:https://github.com/intel-analytics/BigDL - OpenVINO:https://github.com/openvinotoolkit/openvino - AWQ、AutoAWQ - llama.cpp、vllm、lightLLM、fastLLM - marlin(FP16xINT4 LLM inference kernel):https://github.com/IST-DASLab/marlin 论文:A Survey on Inference Engines for Large Language Models: Perspectives on Optimization and Efficiency 链接:https://arxiv.org/pdf/2505.01658 ================================================ FILE: llm-inference/RTP-LLM.md ================================================ - https://github.com/alibaba/rtp-llm 项目主要基于FasterTransformer,并在此基础上集成了TensorRT-LLM的部分kernel实现。FasterTransformer和TensorRT-LLM为我们提供了可靠的性能保障。Flash-Attention2和cutlass也在我们持续的性能优化过程中提供了大量帮助。我们的continuous batching和increment decoding参考了vllm的实现;采样参考了transformers,投机采样部分集成了Medusa的实现,多模态部分集成了llava和qwen-vl的实现。 ================================================ FILE: llm-inference/ascend/mindformers/README.md ================================================ ``` ``` ## 参考文档 - chatglm3: https://gitee.com/mindspore/mindformers/blob/dev/docs/model_cards/glm3.md - baichuan2: https://gitee.com/mindspore/mindformers/blob/dev/research/baichuan2/baichuan2.md ================================================ FILE: llm-inference/ascend/mindformers/baichuan2/README.md ================================================ ================================================ FILE: llm-inference/ascend/mindformers/baichuan2/baichuan-inference.py ================================================ from mindspore import context from mindformers.pipeline import pipeline from mindformers.models import LlamaConfig from mindformers import MindFormerConfig from baichuan2_7b import Baichuan7BV2ForCausalLM from baichuan2_13b import Baichuan13BV2ForCausalLM from baichuan2_tokenizer import Baichuan2Tokenizer import time model_dict = { "baichuan2_7b": Baichuan7BV2ForCausalLM, "baichuan2_13b": Baichuan13BV2ForCausalLM, } # init model baichuan2_config_path = "/root/mindformers/research/baichuan2/run_baichuan2_7b.yaml" baichuan2_config = MindFormerConfig(baichuan2_config_path) baichuan2_config.model.model_config.batch_size = 1 baichuan2_model_config = LlamaConfig(**baichuan2_config.model.model_config) model_name = baichuan2_config.trainer.model_name baichuan2_network = model_dict[model_name]( config=baichuan2_model_config ) # init tokenizer tokenizer = Baichuan2Tokenizer( vocab_file=baichuan2_config.processor.tokenizer.vocab_file ) text="可以帮我做一份旅游攻略吗?" # predict using generate inputs_ids = tokenizer(text)["input_ids"] # inputs_ids = tokenizer(text, max_length=64, padding="max_length")["input_ids"] input_token_lens = len(inputs_ids) start_time = time.perf_counter() outputs = baichuan2_network.generate(inputs_ids, do_sample=False, top_k=1, top_p=1.0, repetition_penalty=1.0, temperature=1.0, max_new_tokens=64) end_time = time.perf_counter() first_gen_time = end_time - start_time print("第一次生成时间:", first_gen_time) outputs =outputs[0][len(inputs_ids):] response = tokenizer.decode(outputs) print(response) line = input() while line: inputs_ids = tokenizer(line)["input_ids"] input_token_lens = len(inputs_ids) start_time = time.perf_counter() outputs = baichuan2_network.generate(inputs_ids, do_sample=False, top_k=1, top_p=1.0, repetition_penalty=1.05, temperature=1.0, max_length=64) end_time = time.perf_counter() gen_time = end_time - start_time print("生成时间:", gen_time) outputs =outputs[0][len(inputs_ids):] response = tokenizer.decode(outputs) print(response) print("\n-------------------\n") line = input() ================================================ FILE: llm-inference/ascend/mindformers/baichuan2/baichuan-stat.py ================================================ from mindspore import context from mindformers.pipeline import pipeline from mindformers.models import LlamaConfig from mindformers import MindFormerConfig from baichuan2_7b import Baichuan7BV2ForCausalLM from baichuan2_13b import Baichuan13BV2ForCausalLM from baichuan2_tokenizer import Baichuan2Tokenizer import time import json import numpy as np # GRAPH_MODE(0) or PYNATIVE_MODE(1) context.set_context(device_id=2, mode=0) input_path = "/root/workspace/data/alpaca_gpt4_data_input_2k.json" gen_max_tokens = 100 #input_path = "/root/workspace/data/alpaca_10.json" list_str = json.load(open(input_path, "r")) model_dict = { "baichuan2_7b": Baichuan7BV2ForCausalLM, "baichuan2_13b": Baichuan13BV2ForCausalLM, } # init model baichuan2_config_path = "/root/mindformers/research/baichuan2/run_baichuan2_7b.yaml" baichuan2_config = MindFormerConfig(baichuan2_config_path) baichuan2_config.model.model_config.batch_size = 1 baichuan2_model_config = LlamaConfig(**baichuan2_config.model.model_config) model_name = baichuan2_config.trainer.model_name baichuan2_network = model_dict[model_name]( config=baichuan2_model_config ) # init tokenizer tokenizer = Baichuan2Tokenizer( vocab_file=baichuan2_config.processor.tokenizer.vocab_file ) text="可以帮我做一份旅游攻略吗?" # predict using generate inputs_ids = tokenizer(text)["input_ids"] # inputs_ids = tokenizer(text, max_length=64, padding="max_length")["input_ids"] input_token_lens = len(inputs_ids) start_time = time.perf_counter() outputs = baichuan2_network.generate(inputs_ids, do_sample=False, num_beams=1, top_k=1, top_p=1.0, repetition_penalty=1.0, temperature=1.0, max_new_tokens=64) end_time = time.perf_counter() first_gen_time = end_time - start_time print("第一次生成时间:", first_gen_time) outputs =outputs[0][len(inputs_ids):] response = tokenizer.decode(outputs) print(response) first_token_time_list = [] total_token_time_list = [] for i, line in enumerate(list_str): inputs_ids = tokenizer(line)["input_ids"] input_token_lens = len(inputs_ids) start_time = time.perf_counter() outputs = baichuan2_network.generate(inputs_ids, do_sample=False, num_beams=1, top_k=1, top_p=1.0, repetition_penalty=1.0, temperature=1.0, max_new_tokens=1) end_time = time.perf_counter() output_token_lens = len(outputs[0]) new_token_lens = output_token_lens - input_token_lens gen_time = end_time - start_time print("生成时间:", gen_time, "输入Token长度:", input_token_lens, "生成Token长度:", new_token_lens) outputs =outputs[0][len(inputs_ids):] response = tokenizer.decode(outputs) print(response) first_token_time_list.append(gen_time) print("\n-------------------\n") new_token_lens_list = [] for i, line in enumerate(list_str): inputs_ids = tokenizer(line)["input_ids"] input_token_lens = len(inputs_ids) start_time = time.perf_counter() outputs = baichuan2_network.generate(inputs_ids, do_sample=False, num_beams=1, top_k=1, top_p=1.0, repetition_penalty=1.0, temperature=1.0, max_new_tokens=gen_max_tokens) end_time = time.perf_counter() output_token_lens = len(outputs[0]) new_token_lens = output_token_lens - input_token_lens gen_time = end_time - start_time print("生成时间:", gen_time, "输入Token长度:", input_token_lens, "生成Token长度:", new_token_lens) outputs =outputs[0][len(inputs_ids):] response = tokenizer.decode(outputs) print(response) total_token_time_list.append(gen_time) new_token_lens_list.append(new_token_lens) print("\n-------------------\n") print(len(first_token_time_list), len(total_token_time_list), len(new_token_lens_list)) avg_first_token_time = sum(first_token_time_list) / len(first_token_time_list) avg_total_token_time = sum(total_token_time_list) / len(total_token_time_list) # 平均生成Token长度 avg_new_token_lens = sum(new_token_lens_list) / len(new_token_lens_list) avg_token_time_list = [] for i in range(len(list_str)): if (new_token_lens_list[i] <= 1): continue token_time = (total_token_time_list[i] - first_token_time_list[i]) / (new_token_lens_list[i]-1) avg_token_time_list.append(token_time) avg_token_time = sum(avg_token_time_list) / len(avg_token_time_list) print(" avg_first_token_time: ", avg_first_token_time, " avg_token_time: ",avg_token_time, " avg_total_token_time: ", avg_total_token_time, " avg_new_token_lens: ", avg_new_token_lens) print("首Token时延---------------------") print("最小值:", round(min(first_token_time_list), 4)) print("最大值:", round(max(first_token_time_list), 4)) print("TP50:", np.percentile(np.array(first_token_time_list), 50)) print("TP90:", np.percentile(np.array(first_token_time_list), 90)) print("TP99:", np.percentile(np.array(first_token_time_list), 99)) print("端到端时延---------------------") print("最小值:", round(min(total_token_time_list), 2)) print("最大值:", round(max(total_token_time_list), 2)) print("TP50:", np.percentile(np.array(total_token_time_list), 50)) print("TP90:", np.percentile(np.array(total_token_time_list), 90)) print("TP99:", np.percentile(np.array(total_token_time_list), 99)) print("生成Token长度---------------------") print("最小值:", round(min(new_token_lens_list), 2)) print("最大值:", round(max(new_token_lens_list), 2)) print("TP50:", np.percentile(np.array(new_token_lens_list), 50)) print("TP90:", np.percentile(np.array(new_token_lens_list), 90)) print("TP99:", np.percentile(np.array(new_token_lens_list), 99)) ================================================ FILE: llm-inference/ascend/mindformers/chatglm3/README.md ================================================ ================================================ FILE: llm-inference/ascend/mindformers/chatglm3/chatglm-gen.py ================================================ import mindspore as ms from mindformers import AutoConfig, AutoModel, AutoTokenizer import time # 指定图模式,指定使用训练卡id ms.set_context(mode=ms.GRAPH_MODE, device_target="Ascend", device_id=6) tokenizer = AutoTokenizer.from_pretrained('/root/workspace/model/chatglm3-6b_ms') # model的实例化有以下两种方式,选择其中一种进行实例化即可 # 1. 直接根据默认配置实例化 model = AutoModel.from_pretrained('/root/workspace/model/chatglm3-6b_ms') """ # 2. 自定义修改配置后实例化 config = AutoConfig.from_pretrained('/root/workspace/model/chatglm3-6b_ms/run_glm3_6b.yaml') config.use_past = True # 此处修改默认配置,开启增量推理能够加速推理性能 config.seq_length = 2048 # 根据需求自定义修改其余模型配置 config.checkpoint_name_or_path = "/root/workspace/model/chatglm3-6b_ms/glm3_6b.ckpt" model = AutoModel.from_config(config) # 从自定义配置项中实例化模型 """ role="user" text="可以帮我做一份旅游攻略吗?" history=[] inputs = tokenizer.build_chat_input(text, history=history, role=role) inputs = inputs['input_ids'] input_token_lens = len(inputs[0]) start_time = time.perf_counter() outputs = model.generate(inputs, do_sample=False, num_beams=1, top_k=1, top_p=1, temperature=1, repetition_penalty=1.0, max_new_tokens=128) end_time = time.perf_counter() first_gen_time = end_time - start_time print("第一次生成时间:", first_gen_time) outputs =outputs[0][len(inputs[0]):] response = tokenizer.decode(outputs) print(response) line = input() while line is not None and line != '': inputs = tokenizer.build_chat_input(line, history=history, role=role) inputs = inputs['input_ids'] input_token_lens = len(inputs[0]) for i in range(20): max_new_tokens = i+1 start_time = time.perf_counter() outputs = model.generate(inputs, do_sample=False, num_beams=1, top_k=1, top_p=1, temperature=1, repetition_penalty=1.0, max_new_tokens=max_new_tokens) end_time = time.perf_counter() output_token_lens = len(outputs[0]) new_token_lens = output_token_lens - input_token_lens gen_time = end_time - start_time print("生成时间:", gen_time, "输入Token长度:", input_token_lens, "生成Token长度:", new_token_lens) outputs =outputs[0][len(inputs[0]):] response = tokenizer.decode(outputs) print(response) print("\n-------------------\n") print("\n===============\n") line = input() ================================================ FILE: llm-inference/ascend/mindformers/chatglm3/chatglm-inference.py ================================================ import mindspore as ms from mindformers import AutoConfig, AutoModel, AutoTokenizer import time # 指定图模式,指定使用训练卡id ms.set_context(mode=ms.GRAPH_MODE, device_target="Ascend", device_id=0) tokenizer = AutoTokenizer.from_pretrained('/root/workspace/model/chatglm3-6b_ms') # model的实例化有以下两种方式,选择其中一种进行实例化即可 # 1. 直接根据默认配置实例化 model = AutoModel.from_pretrained('/root/workspace/model/chatglm3-6b_ms') """ # 2. 自定义修改配置后实例化 config = AutoConfig.from_pretrained('/root/workspace/model/chatglm3-6b_ms/run_glm3_6b.yaml') config.use_past = True # 此处修改默认配置,开启增量推理能够加速推理性能 config.seq_length = 2048 # 根据需求自定义修改其余模型配置 config.checkpoint_name_or_path = "/root/workspace/model/chatglm3-6b_ms/glm3_6b.ckpt" model = AutoModel.from_config(config) # 从自定义配置项中实例化模型 """ role="user" text="可以帮我做一份旅游攻略吗?" history=[] inputs = tokenizer.build_chat_input(text, history=history, role=role) inputs = inputs['input_ids'] input_token_lens = len(inputs[0]) start_time = time.perf_counter() outputs = model.generate(inputs, do_sample=False, num_beams=1, top_k=1, top_p=1, temperature=1, repetition_penalty=1.0, max_new_tokens=128) end_time = time.perf_counter() first_gen_time = end_time - start_time print("第一次生成时间:", first_gen_time) outputs =outputs[0][len(inputs[0]):] response = tokenizer.decode(outputs) print(response) line = input() while line: inputs = tokenizer.build_chat_input(line, history=history, role=role) inputs = inputs['input_ids'] input_token_lens = len(inputs[0]) start_time = time.perf_counter() outputs = model.generate(inputs, do_sample=False, num_beams=1, top_k=1, top_p=1, temperature=1, repetition_penalty=1.0, max_new_tokens=128) end_time = time.perf_counter() gen_time = end_time - start_time print("生成时间:", gen_time) outputs =outputs[0][len(inputs[0]):] response = tokenizer.decode(outputs) print(response) print("\n-------------------\n") line = input() ================================================ FILE: llm-inference/ascend/mindformers/chatglm3/chatglm-stat.py ================================================ import mindspore as ms from mindformers import AutoConfig, AutoModel, AutoTokenizer import time import json import numpy as np input_path = "/root/workspace/data/alpaca_gpt4_data_input_2k.json" # input_path = "/root/workspace/data/alpaca_10.json" list_str = json.load(open(input_path, "r")) # 指定图模式,指定使用训练卡id ms.set_context(mode=ms.GRAPH_MODE, device_target="Ascend", device_id=3) tokenizer = AutoTokenizer.from_pretrained('/root/workspace/model/chatglm3-6b_ms') # model的实例化有以下两种方式,选择其中一种进行实例化即可 # 1. 直接根据默认配置实例化 model = AutoModel.from_pretrained('/root/workspace/model/chatglm3-6b_ms') """ # 2. 自定义修改配置后实例化 config = AutoConfig.from_pretrained('/root/workspace/model/chatglm3-6b_ms/run_glm3_6b.yaml') config.use_past = True # 此处修改默认配置,开启增量推理能够加速推理性能 config.seq_length = 2048 # 根据需求自定义修改其余模型配置 config.checkpoint_name_or_path = "/root/workspace/model/chatglm3-6b_ms/glm3_6b.ckpt" model = AutoModel.from_config(config) # 从自定义配置项中实例化模型 """ role="user" text="可以帮我做一份旅游攻略吗?" history=[] inputs = tokenizer.build_chat_input(text, history=history, role=role) inputs = inputs['input_ids'] input_token_lens = len(inputs[0]) start_time = time.perf_counter() outputs = model.generate(inputs, do_sample=False, num_beams=1, top_k=1, top_p=1, temperature=1, repetition_penalty=1.0, max_new_tokens=128) end_time = time.perf_counter() first_gen_time = end_time - start_time print("第一次生成时间:", first_gen_time) outputs =outputs[0][len(inputs[0]):] response = tokenizer.decode(outputs) print(response) first_token_time_list = [] total_token_time_list = [] for i, line in enumerate(list_str): inputs = tokenizer.build_chat_input(line, history=history, role=role) inputs = inputs['input_ids'] input_token_lens = len(inputs[0]) start_time = time.perf_counter() outputs = model.generate(inputs, do_sample=False, num_beams=1, top_k=1, top_p=1, temperature=1, repetition_penalty=1.0, max_new_tokens=1) end_time = time.perf_counter() output_token_lens = len(outputs[0]) new_token_lens = output_token_lens - input_token_lens gen_time = end_time - start_time print("生成时间:", gen_time, "输入Token长度:", input_token_lens, "生成Token长度:", new_token_lens) outputs =outputs[0][len(inputs[0]):] response = tokenizer.decode(outputs) print(response) first_token_time_list.append(gen_time) print("\n-------------------\n") new_token_lens_list = [] for i, line in enumerate(list_str): inputs = tokenizer.build_chat_input(line, history=history, role=role) inputs = inputs['input_ids'] input_token_lens = len(inputs[0]) start_time = time.perf_counter() outputs = model.generate(inputs, do_sample=False, num_beams=1, top_k=1, top_p=1, temperature=1, repetition_penalty=1.0, max_new_tokens=100) end_time = time.perf_counter() output_token_lens = len(outputs[0]) new_token_lens = output_token_lens - input_token_lens gen_time = end_time - start_time print("生成时间:", gen_time, "输入Token长度:", input_token_lens, "生成Token长度:", new_token_lens) outputs =outputs[0][len(inputs[0]):] response = tokenizer.decode(outputs) print(response) total_token_time_list.append(gen_time) new_token_lens_list.append(new_token_lens) print("\n-------------------\n") print(len(first_token_time_list), len(total_token_time_list)) avg_first_token_time = sum(first_token_time_list) / len(first_token_time_list) avg_total_token_time = sum(total_token_time_list) / len(total_token_time_list) avg_new_token_lens = sum(new_token_lens_list) / len(new_token_lens_list) avg_token_time_list = [] for i in range(len(list_str)): if (new_token_lens_list[i] <= 1): continue token_time = (total_token_time_list[i] - first_token_time_list[i]) / (new_token_lens_list[i]-1) avg_token_time_list.append(token_time) avg_token_time = sum(avg_token_time_list) / len(avg_token_time_list) print(" avg_first_token_time: ", avg_first_token_time, " avg_token_time: ",avg_token_time, " avg_total_token_time: ", avg_total_token_time, " avg_new_token_lens: ", avg_new_token_lens) print("首Token时延---------------------") print("最小值:", round(min(first_token_time_list), 2)) print("最大值:", round(max(first_token_time_list), 2)) print("TP50:", np.percentile(np.array(first_token_time_list), 50)) print("TP90:", np.percentile(np.array(first_token_time_list), 90)) print("TP99:", np.percentile(np.array(first_token_time_list), 99)) print("端到端时延---------------------") print("最小值:", round(min(total_token_time_list), 2)) print("最大值:", round(max(total_token_time_list), 2)) print("TP50:", np.percentile(np.array(total_token_time_list), 50)) print("TP90:", np.percentile(np.array(total_token_time_list), 90)) print("TP99:", np.percentile(np.array(total_token_time_list), 99)) print("生成Token长度---------------------") print("最小值:", round(min(new_token_lens_list), 2)) print("最大值:", round(max(new_token_lens_list), 2)) print("TP50:", np.percentile(np.array(new_token_lens_list), 50)) print("TP90:", np.percentile(np.array(new_token_lens_list), 90)) print("TP99:", np.percentile(np.array(new_token_lens_list), 99)) ================================================ FILE: llm-inference/ascend/mindformers/mindsporelite-inference.py ================================================ """lite infer main.""" import sys import argparse from threading import Thread import time # Avoid bugs when mslite and mindspore are not built from same commit, which may cause running error. # pylint: disable=W0611 import mindspore_lite as mslite from mindformers.models.base_tokenizer import Tokenizer from mindformers.models import BloomTokenizer, LlamaTokenizer from mindformers.models import ChatGLMTokenizer, ChatGLM2Tokenizer, GPT2Tokenizer, ChatGLM3Tokenizer from mindformers.pipeline import pipeline from mindformers.generation import TextIteratorStreamer from mindformers.tools.utils import str2bool from mindformers.inference import InferConfig, InferTask from research.baichuan2.baichuan2_tokenizer import Baichuan2Tokenizer from research.internlm.internlm_tokenizer import InternLMTokenizer from research.qwen.qwen_tokenizer import QwenTokenizer from datetime import datetime def pipeline_from_model_paths(args_, tokenizer): """build infer pipeline for model paths.""" lite_pipeline = pipeline( task="text_generation", model=(args_.prefill_model_path, args_.increment_model_path), tokenizer=tokenizer, backend="mslite", model_name=args_.model_name, ge_config_path=args_.config_path, device_id=args_.device_id, infer_seq_length=args_.seq_length, dynamic=args_.dynamic, rank_id=args_.rank_id, ) return lite_pipeline def pipeline_from_model_name(args_, tokenizer): """build infer pipeline for model name.""" lite_pipeline = pipeline( task="text_generation", model=args_.model_name, tokenizer=tokenizer, backend="mslite", ge_config_path=args_.config_path, device_id=args_.device_id, infer_seq_length=args_.seq_length, dynamic=args_.dynamic, rank_id=args_.rank_id, ) return lite_pipeline def pipeline_from_model_dir(args_, tokenizer): """build infer pipeline for model dir.""" lite_pipeline = pipeline( task="text_generation", model=args_.model_dir, tokenizer=tokenizer, backend="mslite", model_name=args_.model_name, ge_config_path=args_.config_path, device_id=args_.device_id, infer_seq_length=args_.seq_length, dynamic=args_.dynamic, rank_id=args_.rank_id, ) return lite_pipeline def pipeline_from_infer_config(args_, tokenizer): """build infer pipeline for infer config.""" lite_config = InferConfig( prefill_model_path=args_.prefill_model_path, increment_model_path=args_.increment_model_path, model_type="mindir", model_name=args_.model_name, ge_config_path=args_.config_path, device_id=args_.device_id, infer_seq_length=args_.seq_length, dynamic=args_.dynamic, rank_id=args_.rank_id, ) lite_pipeline = InferTask.get_infer_task("text_generation", lite_config, tokenizer=tokenizer) return lite_pipeline # the model name list that mslite inference has supported. LITE_SUPPORT_MODELS = { 'bloom': BloomTokenizer, 'glm': ChatGLMTokenizer, 'glm2': ChatGLM2Tokenizer, 'glm3': ChatGLM3Tokenizer, 'gpt2': GPT2Tokenizer, 'codegeex2': ChatGLM2Tokenizer, 'qwen': QwenTokenizer, 'llama': LlamaTokenizer, 'llama2': LlamaTokenizer, 'codellama': LlamaTokenizer, 'baichuan2': Baichuan2Tokenizer, 'internlm': InternLMTokenizer } def get_tokenizer(model_name: str, tokenizer_path: str) -> Tokenizer: """get tokenizer with model name.""" tokenizer = None lite_support_model = model_name.split('_')[0] if lite_support_model in LITE_SUPPORT_MODELS: if tokenizer_path is not None: tokenizer = LITE_SUPPORT_MODELS[lite_support_model](vocab_file=tokenizer_path) else: tokenizer = LITE_SUPPORT_MODELS[lite_support_model].from_pretrained(model_name) else: lite_support_list = tuple(LITE_SUPPORT_MODELS.keys()) raise ValueError( f"model must be in {lite_support_list} when getting tokenizer, but got input {model_name}.") return tokenizer def build_prompt(inputs, model_name, prompt): """build prompt for inputs""" if model_name.startswith('baichuan2'): if not prompt: prompt = "{}" else: prompt = "" + prompt + "" elif model_name.startswith('internlm'): if not prompt: prompt = "<|User|>:{}\n<|Bot|>:" else: prompt = "<|User|>:" + prompt + "\n<|Bot|>:" if not prompt: return inputs if prompt.find("{}") != -1: return prompt.format(inputs) raise ValueError( "The prompt is invalid! Please make sure your prompt contains placeholder '{}' to replace user input.") def infer_main(args_): """lite infer main.""" tokenizer = get_tokenizer(args_.model_name.lower(), args_.tokenizer_path) lite_pipeline = pipeline_from_infer_config( args_, tokenizer ) while True: user_input = input("Please enter your predict data: \n") if user_input == "exit": print("Task is over.") sys.exit() user_input = build_prompt(user_input, args_.model_name.lower(), args_.prompt) start_time = time.perf_counter() output, gen_time, new_token_lens = lite_pipeline.infer(user_input, do_sample=args_.do_sample, top_k=args_.top_k, top_p=args_.top_p, repetition_penalty=args_.repetition_penalty, temperature=args_.temperature, max_length=args_.max_length, max_new_tokens=args_.max_output_length, is_sample_acceleration=args_.is_sample_acceleration, add_special_tokens=args_.add_special_tokens) end_time = time.perf_counter() infer_time = end_time - start_time print("infer time: ", infer_time) print(output) def infer_stream_main(args_): """main entry for infer stream.""" tokenizer = get_tokenizer(args_.model_name.lower(), args_.tokenizer_path) streamer = TextIteratorStreamer(tokenizer, skip_prompt=True) lite_pipeline = pipeline_from_model_paths( args_, tokenizer ) while True: user_input = input("Please enter your predict data(input 'exit' to quit): \n") if user_input == "exit": print("Quit now, this may take a while.") sys.exit() user_input = build_prompt(user_input, args_.model_name.lower(), args_.prompt) generation_kwargs = dict(inputs=user_input, streamer=streamer, is_sample_acceleration=args_.is_sample_acceleration, add_special_tokens=args_.add_special_tokens) thread = Thread(target=lite_pipeline, kwargs=generation_kwargs) thread.start() output = "" start_time = time.perf_counter() for new_text in streamer: current_time = time.perf_counter() current_fmt_time = datetime.now() current_token_time = current_time - start_time start_time = current_time print(current_fmt_time, current_token_time, new_text) output += new_text print(output) if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( '--device_id', default=0, type=int, help='ID of the target device, the value must be in [0, device_num_per_host-1],' 'while device_num_per_host should be no more than 4096. Default: None') parser.add_argument( '--rank_id', default=0, type=int, help='ID of the target device, the value must be in [0, device_num_per_host-1],' 'while device_num_per_host should be no more than 4096. Default: None') parser.add_argument( '--model_dir', default=None, type=str, help="This model dir path." "Default: None") parser.add_argument( '--model_name', default="common", type=str, help=f"The model name, only supports name in {LITE_SUPPORT_MODELS}." "Default: None") parser.add_argument( '--seq_length', default=2048, type=int, help="This model dir path." "Default: None") parser.add_argument( '--tokenizer_path', default=None, type=str, help="Tokenizer model to load." "Default: None") parser.add_argument( '--prefill_model_path', default=None, type=str, help="This full model path." "Default: None") parser.add_argument( '--increment_model_path', default=None, type=str, help="When use kv-cache, this is cache mode path." "Default: None") parser.add_argument( '--config_path', default=None, type=str, help="ge config file path." "Default: None") parser.add_argument( '--do_sample', default=False, type=str2bool, help="Whether postprocess in graph or not." "Default: False") parser.add_argument( '--top_k', default=1, type=int, help="top k." "Default: 1") parser.add_argument( '--top_p', default=1.0, type=float, help="top p." "Default: 1.0") parser.add_argument( '--repetition_penalty', default=1.0, type=float, help="repetition penalty." "Default: 1.0") parser.add_argument( '--temperature', default=1.0, type=float, help="The value used to modulate the next token probabilities." "Default: 1.0") parser.add_argument( '--max_length', default=512, type=int, help="The maximum word length that can be generated." "Default: 512") parser.add_argument( '--max_output_length', default=128, type=int, help="The maximum output length that can be generated." "Default: 128") parser.add_argument( '--is_sample_acceleration', default=False, type=str2bool, help="Whether postprocess in graph or not." "Default: False") parser.add_argument( '--add_special_tokens', default=False, type=str2bool, help="Whether preprocess add special tokens or not." "Default: False") parser.add_argument( '--stream', default=False, type=str2bool, help="Whether decode in stream or not." "Default: False") parser.add_argument( '--prompt', default=None, type=str, help="The content of prompt." "Default: None") parser.add_argument( '--dynamic', default=False, type=str2bool, help="Whether use dynamic inference." "Default: False") args = parser.parse_args() if len(args.config_path.split(',')) > 1: args.config_path = args.config_path.split(',') if args.stream: infer_stream_main(args) else: infer_main(args) ================================================ FILE: llm-inference/ascend/mindformers/mindsporelite-stat.py ================================================ """lite infer main.""" import sys import argparse from threading import Thread import time # Avoid bugs when mslite and mindspore are not built from same commit, which may cause running error. # pylint: disable=W0611 import mindspore_lite as mslite from mindformers.models.base_tokenizer import Tokenizer from mindformers.models import BloomTokenizer, LlamaTokenizer from mindformers.models import ChatGLMTokenizer, ChatGLM2Tokenizer, GPT2Tokenizer, ChatGLM3Tokenizer from mindformers.pipeline import pipeline from mindformers.generation import TextIteratorStreamer from mindformers.tools.utils import str2bool from mindformers.inference import InferConfig, InferTask from research.baichuan2.baichuan2_tokenizer import Baichuan2Tokenizer from research.internlm.internlm_tokenizer import InternLMTokenizer from research.qwen.qwen_tokenizer import QwenTokenizer import json import numpy as np #input_path = "/root/workspace/data/alpaca_gpt4_data_input_2k.json" input_path = "/root/workspace/data/alpaca_10.json" list_str = json.load(open(input_path, "r")) def pipeline_from_model_paths(args_, tokenizer): """build infer pipeline for model paths.""" lite_pipeline = pipeline( task="text_generation", model=(args_.prefill_model_path, args_.increment_model_path), tokenizer=tokenizer, backend="mslite", model_name=args_.model_name, ge_config_path=args_.config_path, device_id=args_.device_id, infer_seq_length=args_.seq_length, dynamic=args_.dynamic, rank_id=args_.rank_id, ) return lite_pipeline def pipeline_from_model_name(args_, tokenizer): """build infer pipeline for model name.""" lite_pipeline = pipeline( task="text_generation", model=args_.model_name, tokenizer=tokenizer, backend="mslite", ge_config_path=args_.config_path, device_id=args_.device_id, infer_seq_length=args_.seq_length, dynamic=args_.dynamic, rank_id=args_.rank_id, ) return lite_pipeline def pipeline_from_model_dir(args_, tokenizer): """build infer pipeline for model dir.""" lite_pipeline = pipeline( task="text_generation", model=args_.model_dir, tokenizer=tokenizer, backend="mslite", model_name=args_.model_name, ge_config_path=args_.config_path, device_id=args_.device_id, infer_seq_length=args_.seq_length, dynamic=args_.dynamic, rank_id=args_.rank_id, ) return lite_pipeline def pipeline_from_infer_config(args_, tokenizer): """build infer pipeline for infer config.""" lite_config = InferConfig( prefill_model_path=args_.prefill_model_path, increment_model_path=args_.increment_model_path, model_type="mindir", model_name=args_.model_name, ge_config_path=args_.config_path, device_id=args_.device_id, infer_seq_length=args_.seq_length, dynamic=args_.dynamic, rank_id=args_.rank_id, ) lite_pipeline = InferTask.get_infer_task("text_generation", lite_config, tokenizer=tokenizer) return lite_pipeline # the model name list that mslite inference has supported. LITE_SUPPORT_MODELS = { 'bloom': BloomTokenizer, 'glm': ChatGLMTokenizer, 'glm2': ChatGLM2Tokenizer, 'glm3': ChatGLM3Tokenizer, 'gpt2': GPT2Tokenizer, 'codegeex2': ChatGLM2Tokenizer, 'qwen': QwenTokenizer, 'llama': LlamaTokenizer, 'llama2': LlamaTokenizer, 'codellama': LlamaTokenizer, 'baichuan2': Baichuan2Tokenizer, 'internlm': InternLMTokenizer } def get_tokenizer(model_name: str, tokenizer_path: str) -> Tokenizer: """get tokenizer with model name.""" tokenizer = None lite_support_model = model_name.split('_')[0] if lite_support_model in LITE_SUPPORT_MODELS: if tokenizer_path is not None: tokenizer = LITE_SUPPORT_MODELS[lite_support_model](vocab_file=tokenizer_path) else: tokenizer = LITE_SUPPORT_MODELS[lite_support_model].from_pretrained(model_name) else: lite_support_list = tuple(LITE_SUPPORT_MODELS.keys()) raise ValueError( f"model must be in {lite_support_list} when getting tokenizer, but got input {model_name}.") return tokenizer def build_prompt(inputs, model_name, prompt): """build prompt for inputs""" if model_name.startswith('baichuan2'): if not prompt: prompt = "{}" else: prompt = "" + prompt + "" elif model_name.startswith('internlm'): if not prompt: prompt = "<|User|>:{}\n<|Bot|>:" else: prompt = "<|User|>:" + prompt + "\n<|Bot|>:" if not prompt: return inputs if prompt.find("{}") != -1: return prompt.format(inputs) raise ValueError( "The prompt is invalid! Please make sure your prompt contains placeholder '{}' to replace user input.") def inference_stat(first_token_time_list, total_token_time_list, new_token_lens_list): print(len(first_token_time_list), len(total_token_time_list), len(new_token_lens_list)) avg_first_token_time = sum(first_token_time_list) / len(first_token_time_list) avg_total_token_time = sum(total_token_time_list) / len(total_token_time_list) avg_new_token_lens = sum(new_token_lens_list) / len(new_token_lens_list) avg_token_time_list = [] for i in range(len(list_str)): if (new_token_lens_list[i] <= 1): continue token_time = (total_token_time_list[i] - first_token_time_list[i]) / (new_token_lens_list[i]-1) avg_token_time_list.append(token_time) avg_token_time = sum(avg_token_time_list) / len(avg_token_time_list) print(" avg_first_token_time: ", avg_first_token_time, " avg_token_time: ",avg_token_time, " avg_total_token_time: ", avg_total_token_time, " avg_new_token_lens: ", avg_new_token_lens) print("首Token时延---------------------") print("最小值:", round(min(first_token_time_list), 2)) print("最大值:", round(max(first_token_time_list), 2)) print("TP50:", np.percentile(np.array(first_token_time_list), 50)) print("TP90:", np.percentile(np.array(first_token_time_list), 90)) print("TP99:", np.percentile(np.array(first_token_time_list), 99)) print("端到端时延---------------------") print("最小值:", round(min(total_token_time_list), 2)) print("最大值:", round(max(total_token_time_list), 2)) print("TP50:", np.percentile(np.array(total_token_time_list), 50)) print("TP90:", np.percentile(np.array(total_token_time_list), 90)) print("TP99:", np.percentile(np.array(total_token_time_list), 99)) print("生成Token长度---------------------") print("最小值:", round(min(new_token_lens_list), 2)) print("最大值:", round(max(new_token_lens_list), 2)) print("TP50:", np.percentile(np.array(new_token_lens_list), 50)) print("TP90:", np.percentile(np.array(new_token_lens_list), 90)) print("TP99:", np.percentile(np.array(new_token_lens_list), 99)) def infer_main(args_): """lite infer main.""" tokenizer = get_tokenizer(args_.model_name.lower(), args_.tokenizer_path) lite_pipeline = pipeline_from_infer_config( args_, tokenizer ) user_input = "可以帮我做一份旅游攻略吗?" start_time = time.perf_counter() output, gen_time, new_token_lens = lite_pipeline.infer(user_input, do_sample=args_.do_sample, top_k=args_.top_k, top_p=args_.top_p, repetition_penalty=args_.repetition_penalty, temperature=args_.temperature, max_length=args_.max_length, max_new_tokens=5, is_sample_acceleration=args_.is_sample_acceleration, add_special_tokens=args_.add_special_tokens) end_time = time.perf_counter() first_gen_time = end_time - start_time print("第一次生成时间:", first_gen_time) print(output) first_token_time_list = [] total_token_time_list = [] new_token_lens_list = [] for i, line in enumerate(list_str): start_time = time.perf_counter() output, gen_time, new_token_lens = lite_pipeline.infer(line, do_sample=args_.do_sample, top_k=args_.top_k, top_p=args_.top_p, repetition_penalty=args_.repetition_penalty, temperature=args_.temperature, max_length=args_.max_length, max_new_tokens=1, is_sample_acceleration=args_.is_sample_acceleration, add_special_tokens=args_.add_special_tokens) end_time = time.perf_counter() infer_time = end_time - start_time print("infer time: ", infer_time) print(output) first_token_time_list.append(gen_time) print("\n-------------------\n") for i, line in enumerate(list_str): # start_time = time.perf_counter() output, gen_time, new_token_lens = lite_pipeline.infer(line, do_sample=args_.do_sample, top_k=args_.top_k, top_p=args_.top_p, repetition_penalty=args_.repetition_penalty, temperature=args_.temperature, max_length=args_.max_length, max_new_tokens=args_.max_output_length, is_sample_acceleration=args_.is_sample_acceleration, add_special_tokens=args_.add_special_tokens) # end_time = time.perf_counter() print(output) # infer_time = end_time - start_time # print("infer time: ", infer_time) total_token_time_list.append(gen_time) new_token_lens_list.append(new_token_lens) print("\n-------------------\n") inference_stat(first_token_time_list, total_token_time_list, new_token_lens_list) def infer_stream_main(args_): """main entry for infer stream.""" tokenizer = get_tokenizer(args_.model_name.lower(), args_.tokenizer_path) streamer = TextIteratorStreamer(tokenizer, skip_prompt=True) lite_pipeline = pipeline_from_model_paths( args_, tokenizer ) text = "可以帮我做一份旅游攻略吗?" user_input = build_prompt(text, args_.model_name.lower(), args_.prompt) generation_kwargs = dict(inputs=user_input, streamer=streamer, is_sample_acceleration=args_.is_sample_acceleration, add_special_tokens=args_.add_special_tokens) thread = Thread(target=lite_pipeline, kwargs=generation_kwargs) thread.start() output = "" for new_text in streamer: print(new_text) output += new_text print(output) first_token_time_list = [] total_token_time_list = [] new_token_lens_list = [] for i, line in enumerate(list_str): user_input = build_prompt(line, args_.model_name.lower(), args_.prompt) generation_kwargs = dict(inputs=user_input, streamer=streamer, is_sample_acceleration=args_.is_sample_acceleration, add_special_tokens=args_.add_special_tokens) thread = Thread(target=lite_pipeline, kwargs=generation_kwargs) thread.start() output = "" token_num = 0 start_time = time.perf_counter() for new_text in streamer: if token_num == 0: first_time = time.perf_counter() first_token_time = first_time - start_time first_token_time_list.append(first_token_time) print(new_text) output += new_text token_num += 1 end_time = time.perf_counter() gen_time = end_time - start_time total_token_time_list.append(gen_time) new_token_lens_list.append(token_num) print(output) print("\n-------------------\n") inference_stat(first_token_time_list, total_token_time_list, new_token_lens_list) if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( '--device_id', default=0, type=int, help='ID of the target device, the value must be in [0, device_num_per_host-1],' 'while device_num_per_host should be no more than 4096. Default: None') parser.add_argument( '--rank_id', default=0, type=int, help='ID of the target device, the value must be in [0, device_num_per_host-1],' 'while device_num_per_host should be no more than 4096. Default: None') parser.add_argument( '--model_dir', default=None, type=str, help="This model dir path." "Default: None") parser.add_argument( '--model_name', default="common", type=str, help=f"The model name, only supports name in {LITE_SUPPORT_MODELS}." "Default: None") parser.add_argument( '--seq_length', default=2048, type=int, help="This model dir path." "Default: None") parser.add_argument( '--tokenizer_path', default=None, type=str, help="Tokenizer model to load." "Default: None") parser.add_argument( '--prefill_model_path', default=None, type=str, help="This full model path." "Default: None") parser.add_argument( '--increment_model_path', default=None, type=str, help="When use kv-cache, this is cache mode path." "Default: None") parser.add_argument( '--config_path', default=None, type=str, help="ge config file path." "Default: None") parser.add_argument( '--do_sample', default=False, type=str2bool, help="Whether postprocess in graph or not." "Default: False") parser.add_argument( '--top_k', default=1, type=int, help="top k." "Default: 1") parser.add_argument( '--top_p', default=1.0, type=float, help="top p." "Default: 1.0") parser.add_argument( '--repetition_penalty', default=1.0, type=float, help="repetition penalty." "Default: 1.0") parser.add_argument( '--temperature', default=1.0, type=float, help="The value used to modulate the next token probabilities." "Default: 1.0") parser.add_argument( '--max_length', default=512, type=int, help="The maximum word length that can be generated." "Default: 512") parser.add_argument( '--max_output_length', default=128, type=int, help="The maximum output length that can be generated." "Default: 128") parser.add_argument( '--is_sample_acceleration', default=False, type=str2bool, help="Whether postprocess in graph or not." "Default: False") parser.add_argument( '--add_special_tokens', default=False, type=str2bool, help="Whether preprocess add special tokens or not." "Default: False") parser.add_argument( '--stream', default=False, type=str2bool, help="Whether decode in stream or not." "Default: False") parser.add_argument( '--prompt', default=None, type=str, help="The content of prompt." "Default: None") parser.add_argument( '--dynamic', default=False, type=str2bool, help="Whether use dynamic inference." "Default: False") args = parser.parse_args() if len(args.config_path.split(',')) > 1: args.config_path = args.config_path.split(',') if args.stream: infer_stream_main(args) else: infer_main(args) ================================================ FILE: llm-inference/ascend/mindformers/text_generator_infer.py ================================================ # mindformers/inference/infers/text_generator_infer.py """Text Generator Infer.""" import abc import time from typing import Union, List, Optional import numpy as np import mindspore_lite as mslite from mindspore_lite import Model from mindformers.tools.logger import logger from mindformers.models import BaseTokenizer from mindformers.generation import GenerationConfig, LogitsProcessorList from mindformers.generation.logits_process import RepetitionPenaltyLogitsProcessor, LogitNormalization, \ TemperatureLogitsWarper, TopKLogitsWarper, TopPLogitsWarper from mindformers.generation.streamers import BaseStreamer from mindformers.generation.utils import softmax_with_threads from .base_infer import BaseInfer class BaseInputsOfInfer: """ BaseInputsOfInfer interface. """ @abc.abstractmethod def get_inputs(self, model: Model, **kwargs): pass def get_lite_tensor_list(self, inputs, model): input_list = [] for item in inputs: if item is None: continue input_list.append(item) lite_inputs = model.get_inputs() for input_np, tensor in zip(input_list, lite_inputs): tensor.set_data_from_numpy(input_np) return lite_inputs class CommonInputsOfInfer(BaseInputsOfInfer): """ common infer inputs of llm models. """ # pylint: disable=W0221 def get_inputs(self, model: Model, input_ids=None, current_index=None, valid_length=None, init_reset=None, is_first_iteration=True, **kwargs): if not is_first_iteration: inputs_tmp = [] for i in range(len(current_index)): current_index_tmp = int(current_index[i]) - i * input_ids.shape[1] # multibatch # use numpy to slice array to avoid complie ascend slice op inputs_tmp.append(input_ids[i][current_index_tmp:current_index_tmp + 1]) input_ids = np.array(inputs_tmp, dtype=np.int32) inputs = [input_ids, current_index, init_reset, valid_length] lite_inputs = self.get_lite_tensor_list(inputs, model) return lite_inputs class LlamaInputsOfInfer(BaseInputsOfInfer): """ common infer inputs of llm models. """ # pylint: disable=W0613, W0221 def get_inputs(self, model: Model, input_ids=None, current_index=None, valid_length=None, init_reset=None, is_first_iteration=True, **kwargs): if not is_first_iteration: inputs_tmp = [] for i in range(len(valid_length)): current_index_tmp = valid_length[i] - 1 # multibatch # use numpy to slice array to avoid complie ascend slice op inputs_tmp.append(input_ids[i][current_index_tmp:current_index_tmp + 1]) input_ids = np.array(inputs_tmp, dtype=np.int32) inputs = [input_ids, valid_length, kwargs['batch_index'], kwargs['zactivate_len']] lite_inputs = self.get_lite_tensor_list(inputs) return lite_inputs # pylint: disable=W0221 def get_lite_tensor_list(self, inputs): input_tensors = [] for item in inputs: input_tensors.append(mslite.Tensor(item)) return input_tensors class GLMInputsOfInfer(BaseInputsOfInfer): """ glm infer inputs. """ def get_masks_np(self, input_ids, tokenizer: BaseTokenizer): batch_size, seq_length = input_ids.shape context_lengths = [list(seq).index(tokenizer.bos_token_id) for seq in input_ids] attention_mask = np.tril(np.ones((batch_size, seq_length, seq_length))) for i, context_length in enumerate(context_lengths): attention_mask[i, :, :context_length] = 1 attention_mask = np.expand_dims(attention_mask, axis=1) attention_mask = np.array(attention_mask < 0.5, np.bool_) return attention_mask def get_position_ids_np(self, input_ids, mask_positions, tokenizer: BaseTokenizer, use_gmasks=None, position_encoding_2d=True): """Get position ids from input_ids and mask_positions with numpy""" batch_size, seq_length = input_ids.shape if use_gmasks is None: use_gmasks = [False] * batch_size context_lengths = [list(seq).index(tokenizer.bos_token_id) for seq in input_ids] if position_encoding_2d: position_ids = np.repeat(np.expand_dims(np.arange(seq_length), 0), batch_size, axis=0) for i, context_length in enumerate(context_lengths): position_ids[i, context_length:] = mask_positions[i] block_position_ids = [np.concatenate(( np.zeros(context_length, np.int32), np.arange(seq_length - context_length, dtype=np.int32) + 1 )) for context_length in context_lengths] block_position_ids = np.stack(block_position_ids, axis=0) position_ids = np.stack((position_ids, block_position_ids), axis=1) else: position_ids = np.repeat(np.expand_dims(np.arange(seq_length), 0), batch_size, axis=0) for i, context_length in enumerate(context_lengths): if not use_gmasks[i]: position_ids[context_length:] = mask_positions[i] return position_ids def create_position_ids_np(self, input_ids, tokenizer, position_encoding_2d=True): """Get position ids from input_ids with numpy""" mask, gmask = tokenizer.mask_token_id, tokenizer.gmask_token_id seqs = list(input_ids) mask_positions, use_gmasks = [], [] for seq in seqs: mask_token = gmask if gmask in seq else mask use_gmask = mask_token == gmask mask_positions.append(list(seq).index(mask_token)) use_gmasks.append(use_gmask) position_ids = self.get_position_ids_np(input_ids, mask_positions, tokenizer, use_gmasks=None, position_encoding_2d=position_encoding_2d) return position_ids # pylint: disable=W0221 def get_inputs(self, model: Model, input_ids=None, current_index=None, valid_length=None, init_reset=None, tokenizer=None, position_encoding_2d=True, is_first_iteration=True, **kwargs): attention_mask_ = self.get_masks_np(input_ids, tokenizer).astype(np.int32) position_ids_ = self.create_position_ids_np(input_ids, tokenizer, position_encoding_2d).astype(np.int32) if not is_first_iteration: attention_mask = [] position_ids = [] inputs_tmp = [] for i in range(len(current_index)): current_index_tmp = int(current_index[i]) - i * input_ids.shape[1] # multibatch # use numpy to slice array to avoid complie ascend slice op inputs_tmp.append(input_ids[i][current_index_tmp:current_index_tmp + 1]) position_ids.append(position_ids_[i][:, current_index_tmp:current_index_tmp + 1]) attention_mask.append(attention_mask_[i][:, current_index_tmp:current_index_tmp + 1, :]) input_ids = np.array(inputs_tmp, np.int32) position_ids = np.array(position_ids, np.int32) attention_mask = np.array(attention_mask, np.int32) else: attention_mask = attention_mask_ position_ids = position_ids_ inputs = [input_ids, position_ids, attention_mask, current_index, init_reset, valid_length] lite_inputs = self.get_lite_tensor_list(inputs, model) return lite_inputs class InputOfInfer: """ Input of llm model. """ MAPPING = { "bloom": CommonInputsOfInfer, "llama": LlamaInputsOfInfer, "codellama": LlamaInputsOfInfer, "glm2": CommonInputsOfInfer, "glm3": CommonInputsOfInfer, "gpt2": CommonInputsOfInfer, "codegeex2": CommonInputsOfInfer, "glm": GLMInputsOfInfer, "internlm": LlamaInputsOfInfer, "common": CommonInputsOfInfer } @classmethod def get_inputs(cls, model_name: str, model, **kwargs): """ Get input tensor list of mslite. Args: model_name: str, model name. model: mindspore_lite.Model. mode obj of mslite. Returns: tensor list of mslite. """ name = "" if model_name not in InputOfInfer.MAPPING: for k in InputOfInfer.MAPPING: if model_name.startswith(k): name = k break if not name: logger.warning("Model name not in support maps.Common input format will be used to do inference.") name = "common" else: name = model_name return InputOfInfer.MAPPING[name]().get_inputs(model, **kwargs) class TextGeneratorInfer(BaseInfer): """ Text generator infer implement class. """ # pylint: disable=W0221 def infer(self, inputs: Union[str, List[str]], do_sample: bool = False, top_k: int = 1, top_p: float = 1.0, temperature: float = 1.0, repetition_penalty: float = 1.0, eos_token_id: int = 2, pad_token_id: int = 0, max_length: int = 256, is_sample_acceleration: bool = False, add_special_tokens: bool = False, streamer: Optional[BaseStreamer] = None, **kwargs): """ text generator inference api Args: inputs(List(str), List(List(str))): The token id list or a list of token id list. do_sample(bool): Whether to do sampling on the candidate ids. If set True it will be enabled, and set it to be False to disable the sampling, equivalent to topk 1. If set None, it follows the setting in the configureation in the model. Default None. top_k(int): Determine the topK numbers token id as candidate. This should be a positive number. If set None, it follows the setting in the configureation in the model. Default 1. top_p(float): The accumulation probability of the candidate token ids below the top_p will be select as the condaite ids. The valid value of top_p is between (0, 1]. If the value is larger than 1, top_K algorithm will be enabled. If set None, it follows the setting in the configureation in the model. Default 1. temperature (`float`, *optional*, defaults to 1.0): The value used to modulate the next token probabilities. eos_token_id(int): The end of sentence token id. If set None, it follows the setting in the configureation in the model. Default 2. pad_token_id(int): The padding of sentence token id. If set None, it follows the setting in the configureation in the model. Default 0. repetition_penalty(float): The penalty factor of the frequency that generated words. The If set 1, the repetition_penalty will not be enabled. If set None, it follows the setting in the configureation in the model. Default 1. max_length: The maximum length of the generated words. If set None, it follows the setting in the configureation in the model. Default 256. is_sample_acceleration: The postprocess are processing in model. Default False. add_special_tokens: Add special tokens for preprocess. streamer: The streamer that generator uses. Returns: outputs of model infer """ input_ids = self.preprocess(inputs, add_special_tokens) print("input_ids: ", input_ids) start_time = time.perf_counter() output_ids = self.generate(input_ids, do_sample, top_k, top_p, temperature, repetition_penalty, eos_token_id, pad_token_id, max_length, is_sample_acceleration, streamer, **kwargs) end_time = time.perf_counter() gen_time = end_time - start_time print("output_ids: ", output_ids) input_token_lens = len(input_ids[0]) output_token_lens = len(output_ids[0]) new_token_lens = output_token_lens - input_token_lens print("gen_time: ", gen_time, "new_token_lens: ", new_token_lens) output_ids = output_ids[0][len(input_ids[0]):] outputs = self.postprocess(output_ids) return outputs, gen_time, new_token_lens # pylint: disable=W0613 def preprocess(self, input_data, add_special_tokens=False, **kwargs): """preprocess.""" if self.model_name.startswith('glm3'): return self.tokenizer.build_batch_input(input_data)["input_ids"] tokens = self.tokenizer(input_data, add_special_tokens=add_special_tokens) input_ids = tokens["input_ids"] input_list = [] if isinstance(input_data, str): input_list.append(input_ids) else: input_list = input_ids return input_list # pylint: disable=W0613 def postprocess(self, predict_data, **kwargs): """postprocess.""" outputs = self.tokenizer.decode(predict_data, skip_special_tokens=True) return outputs def _get_logits_processor(self, generation_config: GenerationConfig, logits_processor: Optional[LogitsProcessorList]): """ This class returns a [`LogitsProcessorList`] list object that contains all relevant [`LogitsProcessor`] instances used to modify the scores of the language model head. """ # instantiate processors list processors = LogitsProcessorList() if generation_config.repetition_penalty is not None and generation_config.repetition_penalty != 1.0: processors.append(RepetitionPenaltyLogitsProcessor(repetition_penalty=generation_config.repetition_penalty)) processors = self._merge_processor_list(processors, logits_processor) # `LogitNormalization` should always be the last logit processor, when present if generation_config.renormalize_logits is True: processors.append(LogitNormalization()) return processors def _merge_processor_list(self, default_list: LogitsProcessorList, custom_list: LogitsProcessorList): """merge custom processor list with default list.""" if not custom_list: return default_list for default in default_list: for custom in custom_list: if type(custom) is type(default): object_type = "logits processor" raise ValueError( f"A custom {object_type} of type {type(custom)} with values {custom} has been passed to" f" `.generate()`, but it has already been created with the values {default}." f" {default} has been created by passing the corresponding arguments to generate or" f" by the model's config default values. If you just want to change the default values" f" of {object_type} consider passing them as arguments to `.generate()`" f" instead of using a custom {object_type}." ) default_list.extend(custom_list) return default_list def _get_logits_warper(self, generation_config: GenerationConfig): """ This class returns a [`LogitsProcessorList`] list object that contains all relevant [`LogitsWarper`] instances used for multinomial sampling. """ # instantiate warpers list warpers = LogitsProcessorList() # all samplers can be found in `generation_utils_samplers.py` if generation_config.temperature is not None and generation_config.temperature != 1.0: warpers.append(TemperatureLogitsWarper(generation_config.temperature)) min_tokens_to_keep = 1 if generation_config.top_k is not None and generation_config.top_k != 0: warpers.append(TopKLogitsWarper(top_k=generation_config.top_k, min_tokens_to_keep=min_tokens_to_keep)) if generation_config.top_p is not None and generation_config.top_p < 1.0: warpers.append(TopPLogitsWarper(top_p=generation_config.top_p, min_tokens_to_keep=min_tokens_to_keep)) # `LogitNormalization` should always be the last logit processor, when present if generation_config.renormalize_logits is True: warpers.append(LogitNormalization()) return warpers def generate(self, input_ids, do_sample, top_k, top_p, temperature, repetition_penalty, eos_token_id, pad_token_id, max_length, is_sample_acceleration, streamer, **kwargs): """token generator.""" total_time = time.time() sampler_dict = {"do_sample": do_sample, "top_k": top_k, "top_p": top_p, "temperature": temperature, "repetition_penalty": repetition_penalty, "max_length": max_length, **kwargs} generation_config = GenerationConfig(**sampler_dict) if not generation_config.do_sample: generation_config.top_p = 1.0 generation_config.top_k = 0 logits_processor = LogitsProcessorList() logits_processor = self._get_logits_processor( generation_config=generation_config, logits_processor=logits_processor, ) logits_warper = self._get_logits_warper(generation_config) if streamer: streamer.put(np.array(input_ids[0])) batch_size = len(input_ids) valid_length = [] for i in range(batch_size): # As the nonzero returns the index and we need length valid_length.append(np.max(np.argwhere(np.array(input_ids[i]) != pad_token_id)) + 1) valid_length = np.array(valid_length, np.int32) print("self.dynamic", self.dynamic) if self.dynamic: pad_length = max_length - valid_length real_pad_length = max(valid_length) - valid_length target_length = kwargs["max_new_tokens"] + max(valid_length) if kwargs.get( "max_new_tokens") else max_length else: target_length = self.seq_length if max_length > self.seq_length else max_length # pad original input ids to seq_length pad_length = self.seq_length - valid_length pad_input_ids = np.array([ np.pad(input_ids[i], (0, pad_length[i]), 'constant', constant_values=pad_token_id) for i in range(len(input_ids)) ], np.int32) # setup is_first_iteration flag for incremental infer is_first_iteration = True is_finished = [False] * batch_size use_past = self.full_model and self.cache_model if self.dynamic: batch_size_gear, act_len_gear = self.dynshape_gears.match(batch_size, max_length) bs_pad = batch_size_gear - batch_size pad_input_ids = np.pad(pad_input_ids, ((0, bs_pad), (0, 0)), 'constant', constant_values=pad_token_id) valid_length = np.pad(valid_length, (0, bs_pad), 'constant', constant_values=1) is_finished += [True] * bs_pad real_input_ids = np.array([np.pad(input_ids[i], (0, real_pad_length[i]), 'constant', constant_values=pad_token_id) for i in range(len(input_ids))], np.int32) real_input_ids = np.pad(real_input_ids, ((0, bs_pad), (0, 0)), 'constant', constant_values=pad_token_id) input_ids = real_input_ids if self.dynamic else pad_input_ids activate_len = np.zeros((act_len_gear if self.dynamic else self.seq_length), dtype=np.int64) batch_index = np.arange(len(input_ids), dtype=np.int64) origin_len = np.sum(valid_length) while np.sum(is_finished) != batch_size: start_time = time.time() seq_length = input_ids.shape[1] current_index = [valid_length[i] - 1 + i * seq_length for i in range(batch_size)] current_index = np.array(current_index, np.int32) logger.debug("validate length: %s", valid_length) if use_past: outputs = self._inc_infer(input_ids, current_index, valid_length, is_first_iteration, batch_index=batch_index, zactivate_len=activate_len, **kwargs) else: outputs = self._full_infer(input_ids, current_index, is_sample_acceleration, batch_index=batch_index, zactivate_len=activate_len, **kwargs) if self.dynamic: input_ids = pad_input_ids if not is_sample_acceleration: logits = outputs[0].get_data_to_numpy() vocab_size = logits.shape[-1] if len(logits.shape) < 3: logits = logits.reshape(batch_size, -1, vocab_size) # gather logits if is_first_iteration and logits.shape[1] > 1: logits = np.array([logits[i][current_index[i] - i * seq_length, :] for i in range(batch_size)]) else: logits = np.array([logits[i][0, :] for i in range(batch_size)]) logits = logits.reshape(-1, vocab_size) log_probs = logits_processor(input_ids, logits, is_finished) p = logits_warper(input_ids, log_probs, is_finished) p_args = np.tile(np.arange(logits.shape[-1]), (batch_size, 1)) else: p = outputs[0].get_data_to_numpy().astype(np.int32) p_args = outputs[1].get_data_to_numpy() if generation_config.do_sample: p_norms = softmax_with_threads(p, is_finished) # Random select a token as final output for this round for i in range(batch_size): if is_finished[i]: continue # target_index = np.random.choice(len(p[i]), p=p[i]) if generation_config.do_sample: # multinomial sample p_norm = p_norms[i] target_index = np.random.choice(len(p[i]), p=p_norm) else: # greedy target_index = np.argmax(p[i]) # Stop judgment when length exceeds target_length. if valid_length[i] >= target_length: is_finished[i] = True continue # add next token to input_ids. target = p_args[i][target_index] input_ids[i, valid_length[i]] = target if streamer: streamer.put(np.asarray([target])) valid_length[i] += int(1) # Stop judgment when output is EOS token, with the output # is appended to input_ids and streamer. if target == eos_token_id: is_finished[i] = True continue is_first_iteration = not use_past logger.debug(f"one token takes {time.time() - start_time} s") # Return valid outputs out of padded outputs output_ids = [] for i in range(batch_size): output_ids.append(input_ids[i, : int(valid_length[i])].astype(np.int32)) logger.debug("The output is: %s", output_ids) generate_len = np.sum(valid_length) - origin_len total_time = time.time() - total_time logger.info("total time: %s s; generated tokens: %s tokens; generate speed: %s tokens/s", total_time, generate_len, generate_len / total_time) if streamer: streamer.end() return output_ids def _inc_infer(self, input_ids, current_index, valid_length, is_first_iteration, **kwargs): """kvcache infer""" if is_first_iteration: init_reset = np.array([False]) lite_inputs = self.get_predict_inputs(self.full_model, input_ids, current_index, valid_length, init_reset, is_first_iteration, **kwargs) outputs = self.full_model.predict(lite_inputs) else: init_reset = np.array([True]) lite_inputs = self.get_predict_inputs(self.cache_model, input_ids, current_index, valid_length, init_reset, is_first_iteration, **kwargs) outputs = self.cache_model.predict(lite_inputs) return outputs def _full_infer(self, input_ids, current_index, is_npu_acceleration, **kwargs): """infer""" # get inputs if is_npu_acceleration: lite_inputs = self.get_predict_inputs(self.full_model, input_ids, current_index, **kwargs) else: lite_inputs = self.get_predict_inputs(self.full_model, input_ids, **kwargs) # do infer outputs = self.full_model.predict(lite_inputs) return outputs def get_predict_inputs(self, mode: Model, input_ids, current_index=None, valid_length=None, init_reset=None, is_first_iteration=True, **kwargs): """Get inputs of llm model for mslite.""" return InputOfInfer.get_inputs(self.model_name, mode, input_ids=input_ids, current_index=current_index, valid_length=valid_length, init_reset=init_reset, tokenizer=self.tokenizer, is_first_iteration=is_first_iteration, **kwargs) ================================================ FILE: llm-inference/chatgpt.md ================================================ - https://platform.openai.com/docs/overview ``` OPENAI_API_KEY=xxx curl https://api.openai.com/v1/models \ -H "Authorization: Bearer $OPENAI_API_KEY" curl https://api.openai.com/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ "model": "No models available", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "Hello!" } ] }' curl https://api.openai.com/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ "model": "gpt-3.5-turbo-16k", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "Hello!" } ], "stream": true }' ``` ================================================ FILE: llm-inference/deepspeed-mii/README.md ================================================ DeepSpeed-FastGen 是 DeepSpeed-MII 和 DeepSpeed-Inference 的协同组合. ## DeepSpeed-MII ================================================ FILE: llm-inference/faster-transformer/README.md ================================================ 镜像下载地址:https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch ## FP16 ``` docker pull nvcr.io/nvidia/pytorch:23.05-py3 ``` ``` nvidia-docker run -dti --name faster_transformer \ --restart=always --gpus all --network=host \ --shm-size 5g \ -v /home/h800/h800-work/h800-workspace:/workspace \ -w /workspace \ nvcr.io/nvidia/pytorch:23.05-py3 \ bash sudo docker exec -it faster_transformer bash ``` ``` cd code git clone https://github.com/NVIDIA/FasterTransformer.git cd FasterTransformer/ mkdir -p build cd build git submodule init && git submodule update ``` ``` cmake -DSM=90 -DCMAKE_BUILD_TYPE=Release -DBUILD_PYT=ON -DBUILD_MULTI_GPU=ON .. ``` ``` make -j12 ``` ## FP8 拉取镜像: ``` docker pull nvcr.io/nvidia/pytorch:22.10-py3 ``` 创建并启动容器: ``` nvidia-docker run -dti --name faster_transformer_fp8 \ --restart=always --gpus all --network=host \ --shm-size 5g \ -v /home/h800/h800-work/h800-workspace:/workspace \ -w /workspace \ nvcr.io/nvidia/pytorch:22.10-py3 \ bash sudo docker exec -it faster_transformer_fp8 bash ``` 拉取代码: ``` cd code git clone https://github.com/NVIDIA/FasterTransformer.git cd FasterTransformer/ git checkout eb9b81b65909cb14f582581c1ed4ee8e1e299be9 mkdir -p build cd build git submodule init && git submodule update ``` ``` # cmake -DSM=90 -DCMAKE_BUILD_TYPE=Release -DBUILD_PYT=ON -DBUILD_MULTI_GPU=ON .. cmake -DSM=90 -DCMAKE_BUILD_TYPE=Release -DBUILD_PYT=ON -DBUILD_MULTI_GPU=ON -DENABLE_FP8=ON .. ``` 运行过程: ``` > cmake -DSM=90 -DCMAKE_BUILD_TYPE=Release -DBUILD_PYT=ON -DBUILD_MULTI_GPU=ON -DENABLE_FP8=ON .. -- The CXX compiler identification is GNU 9.4.0 \-- The CUDA compiler identification is NVIDIA 11.8.89 -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Detecting CUDA compiler ABI info -- Detecting CUDA compiler ABI info - done -- Check for working CUDA compiler: /usr/local/cuda/bin/nvcc - skipped -- Detecting CUDA compile features -- Detecting CUDA compile features - done -- Looking for C++ include pthread.h -- Looking for C++ include pthread.h - found -- Performing Test CMAKE_HAVE_LIBC_PTHREAD -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed -- Looking for pthread_create in pthreads -- Looking for pthread_create in pthreads - not found -- Looking for pthread_create in pthread -- Looking for pthread_create in pthread - found -- Found Threads: TRUE -- Found CUDA: /usr/local/cuda (found suitable version "11.8", minimum required is "10.2") CUDA_VERSION 11.8 is greater or equal than 11.0, enable -DENABLE_BF16 flag CUDA_VERSION 11.8 is greater or equal than 11.8, enable -DENABLE_FP8 flag -- Found CUDNN: /usr/lib/x86_64-linux-gnu/libcudnn.so -- Add DBUILD_CUTLASS_MOE, requires CUTLASS. Increases compilation time -- Add DBUILD_CUTLASS_MIXED_GEMM, requires CUTLASS. Increases compilation time -- Running submodule update to fetch cutlass -- Add DBUILD_MULTI_GPU, requires MPI and NCCL -- Found MPI_CXX: /opt/hpcx/ompi/lib/libmpi.so (found version "3.1") -- Found MPI: TRUE (found version "3.1") -- Found NCCL: /usr/include -- Determining NCCL version from /usr/include/nccl.h... -- Looking for NCCL_VERSION_CODE -- Looking for NCCL_VERSION_CODE - not found -- Found NCCL (include: /usr/include, library: /usr/lib/x86_64-linux-gnu/libnccl.so.2.15.5) -- NVTX is enabled. -- Assign GPU architecture (sm=90) -- Use WMMA CMAKE_CUDA_FLAGS_RELEASE: -O3 -DNDEBUG -Xcompiler -O3 -DCUDA_PTX_FP8_F2FP_ENABLED --use_fast_math -- COMMON_HEADER_DIRS: /workspace/FasterTransformer;/usr/local/cuda/include;/workspace/FasterTransformer/3rdparty/cutlass/include;/workspace/FasterTransformer/src/fastertransformer/cutlass_extensions/include;/workspace/FasterTransformer/3rdparty/trt_fp8_fmha/src;/workspace/FasterTransformer/3rdparty/trt_fp8_fmha/generated -- Found CUDA: /usr/local/cuda (found version "11.8") -- Caffe2: CUDA detected: 11.8 -- Caffe2: CUDA nvcc is: /usr/local/cuda/bin/nvcc -- Caffe2: CUDA toolkit directory: /usr/local/cuda -- Caffe2: Header version is: 11.8 CMake Warning (dev) at /opt/conda/lib/python3.8/site-packages/torch/share/cmake/Caffe2/public/cuda.cmake:117 (find_package): Policy CMP0074 is not set: find_package uses _ROOT variables. Run "cmake --help-policy CMP0074" for policy details. Use the cmake_policy command to set the policy and suppress this warning. CMake variable CUDNN_ROOT is set to: /usr/local/cuda For compatibility, CMake is ignoring the variable. Call Stack (most recent call first): /opt/conda/lib/python3.8/site-packages/torch/share/cmake/Caffe2/Caffe2Config.cmake:92 (include) /opt/conda/lib/python3.8/site-packages/torch/share/cmake/Torch/TorchConfig.cmake:68 (find_package) CMakeLists.txt:257 (find_package) This warning is for project developers. Use -Wno-dev to suppress it. -- Found cuDNN: v8.6.0 (include: /usr/include, library: /usr/lib/x86_64-linux-gnu/libcudnn.so) -- /usr/local/cuda/lib64/libnvrtc.so shorthash is 672ee683 CMake Warning at /opt/conda/lib/python3.8/site-packages/torch/share/cmake/Caffe2/public/utils.cmake:385 (message): In the future we will require one to explicitly pass TORCH_CUDA_ARCH_LIST to cmake instead of implicitly setting it as an env variable. This will become a FATAL_ERROR in future version of pytorch. Call Stack (most recent call first): /opt/conda/lib/python3.8/site-packages/torch/share/cmake/Caffe2/public/cuda.cmake:437 (torch_cuda_get_nvcc_gencode_flag) /opt/conda/lib/python3.8/site-packages/torch/share/cmake/Caffe2/Caffe2Config.cmake:92 (include) /opt/conda/lib/python3.8/site-packages/torch/share/cmake/Torch/TorchConfig.cmake:68 (find_package) CMakeLists.txt:257 (find_package) -- Added CUDA NVCC flags for: -gencode;arch=compute_90,code=sm_90 CMake Warning at /opt/conda/lib/python3.8/site-packages/torch/share/cmake/Torch/TorchConfig.cmake:22 (message): static library kineto_LIBRARY-NOTFOUND not found. Call Stack (most recent call first): /opt/conda/lib/python3.8/site-packages/torch/share/cmake/Torch/TorchConfig.cmake:127 (append_torchlib_if_found) CMakeLists.txt:257 (find_package) -- Found Torch: /opt/conda/lib/python3.8/site-packages/torch/lib/libtorch.so -- USE_CXX11_ABI=True -- The C compiler identification is GNU 9.4.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Found Python: /opt/conda/bin/python3.8 (found version "3.8.13") found components: Interpreter -- Configuring done -- Generating done -- Build files have been written to: /workspace/FasterTransformer/build ``` ``` make -j12 ``` 运行过程: ``` > make -j12 [ 0%] Building CXX object src/fastertransformer/utils/CMakeFiles/logger.dir/logger.cc.o [ 1%] Building CUDA object src/fastertransformer/kernels/CMakeFiles/transpose_int8_kernels.dir/transpose_int8_kernels.cu.o [ 1%] Building CUDA object src/fastertransformer/kernels/CMakeFiles/add_residual_kernels.dir/add_residual_kernels.cu.o [ 1%] Building CXX object 3rdparty/common/CMakeFiles/cuda_driver_wrapper.dir/cudaDriverWrapper.cpp.o [ 1%] Building CXX object src/fastertransformer/kernels/cutlass_kernels/CMakeFiles/cutlass_preprocessors.dir/cutlass_preprocessors.cc.o [ 2%] Building CXX object src/fastertransformer/utils/CMakeFiles/cuda_utils.dir/cuda_utils.cc.o [ 2%] Building CXX object src/fastertransformer/utils/CMakeFiles/nvtx_utils.dir/nvtx_utils.cc.o [ 2%] Building CUDA object src/fastertransformer/kernels/CMakeFiles/custom_ar_kernels.dir/custom_ar_kernels.cu.o [ 3%] Building CUDA object src/fastertransformer/kernels/CMakeFiles/activation_kernels.dir/activation_kernels.cu.o [ 3%] Building CUDA object src/fastertransformer/kernels/CMakeFiles/bert_preprocess_kernels.dir/bert_preprocess_kernels.cu.o [ 3%] Building CUDA object src/fastertransformer/kernels/CMakeFiles/unfused_attention_kernels.dir/unfused_attention_kernels.cu.o [ 3%] Building CUDA object src/fastertransformer/kernels/CMakeFiles/layernorm_kernels.dir/layernorm_kernels.cu.o [ 3%] Linking CUDA device code CMakeFiles/cuda_driver_wrapper.dir/cmake_device_link.o [ 3%] Linking CUDA device code CMakeFiles/nvtx_utils.dir/cmake_device_link.o [ 3%] Linking CXX static library ../../lib/libcuda_driver_wrapper.a [ 3%] Built target cuda_driver_wrapper [ 4%] Linking CXX static library ../../../lib/libnvtx_utils.a [ 4%] Building CUDA object src/fastertransformer/kernels/CMakeFiles/matrix_vector_multiplication.dir/matrix_vector_multiplication.cu.o [ 4%] Linking CUDA device code CMakeFiles/logger.dir/cmake_device_link.o [ 4%] Built target nvtx_utils [ 4%] Building CXX object src/fastertransformer/kernels/cutlass_kernels/CMakeFiles/cutlass_heuristic.dir/cutlass_heuristic.cc.o [ 4%] Linking CXX static library ../../../lib/liblogger.a ... [ 99%] Built target multi_gpu_gpt_example [ 99%] Building CXX object examples/cpp/multi_gpu_gpt/CMakeFiles/multi_gpu_gpt_async_example.dir/multi_gpu_gpt_async_example.cc.o [ 99%] Built target gptneox_example [ 99%] Building CXX object examples/cpp/multi_gpu_gpt/CMakeFiles/multi_gpu_gpt_triton_example.dir/multi_gpu_gpt_triton_example.cc.o [ 99%] Linking CXX executable ../../../bin/gptneox_triton_example [ 99%] Built target gptneox_triton_example [ 99%] Building CXX object examples/cpp/multi_gpu_gpt/CMakeFiles/multi_gpu_gpt_interactive_example.dir/multi_gpu_gpt_interactive_example.cc.o [100%] Linking CXX executable ../../../bin/multi_gpu_gpt_triton_example [100%] Linking CXX static library ../../../../lib/libth_gpt_fp8.a [100%] Building CXX object examples/cpp/gpt_fp8/CMakeFiles/gpt_fp8_triton_example.dir/gpt_fp8_triton_example.cc.o [100%] Built target th_gpt_fp8 [100%] Linking CUDA device code CMakeFiles/transformer-shared.dir/cmake_device_link.o [100%] Linking CXX shared library lib/libtransformer-shared.so [100%] Built target multi_gpu_gpt_triton_example [100%] Linking CXX executable ../../../bin/multi_gpu_gpt_async_example [100%] Built target transformer-shared [100%] Built target multi_gpu_gpt_async_example [100%] Linking CXX executable ../../../bin/multi_gpu_gpt_interactive_example [100%] Linking CXX static library ../../../../lib/libth_parallel_gpt.a [100%] Built target th_parallel_gpt [100%] Built target multi_gpu_gpt_interactive_example [100%] Linking CXX executable ../../../bin/gpt_fp8_triton_example [100%] Built target gpt_fp8_triton_example [100%] Linking CXX static library ../../../../lib/libth_decoding.a [100%] Built target th_decoding [100%] Linking CXX static library ../../../../lib/libth_bart.a [100%] Built target th_bart [100%] Linking CXX shared library ../../../lib/libth_transformer.so [100%] Built target th_transformer ``` ``` pip install -r examples/pytorch/gpt/requirement.txt -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn ``` ``` CUDA_VISIBLE_DEVICES=1 python examples/pytorch/gpt/lambada_task_example_gpt.py \ --batch-size 1 \ --checkpoint-path /workspace/model/megatron-models/c-model/345m/1-gpu \ --lib-path /workspace/FasterTransformer/build/lib/libth_transformer.so \ --lambada-path /workspace/data/lambada_test.jsonl ``` ================================================ FILE: llm-inference/faster-transformer/bloom/README.md ================================================ ## 统计性能指标 ### 数据格式 ``` [ { "id":0, "input":"#姓名:何#性别:女士#剩余额度:一万七千#当前额度:一万七千#绑定银行:无#活动:D#初始额度:nan#手机尾号:七八八#注册时间:二零二三年一月三日#借款日期:nan#优惠券数:0.0#电销时间:二零二三年四月二十三日#登录类型:无#提额时间:二零二三年四月二十二日#offer类型:提额#cust_type:授信T91-180\n\nHuman: 你好。\nAssistant: ", "answer":"Assistant: 好,请问一下是何女士对吧?<\/s>" }, { "id":1, "input":"#姓名:岳#性别:先生#剩余额度:五万#当前额度:零#绑定银行:农业银行#活动:E#初始额度:一万#手机尾号:六四七三#注册时间:二零一九年十一月七日#借款日期:nan#优惠券数:1.0#电销时间:二零二三年二月二十五日#登录类型:无#提额时间:nan#offer类型:nan#cust_type:授信T31-90\n\nHuman: 喂。\nAssistant: 您好,请问就是岳先生对吧?<\/s>Human: 行。对呀。\nAssistant: 诶你好,岳先生,不好意思打扰到你,我这边是xxx的回访专员哈,来电话给你做个提醒,关注到你这边在我们ttt里面申请的这个额度还打算用吗?诶已经过了六天了,ttt。<\/s>Human: 嗯。我用,但是我我用是可以用,但是我不我我上次问他,他不都不跟我讲,我这个钱,假如我这个一万块钱,我用一天大概要多少钱利息知道吧?\nAssistant: 啊就是我这边给你说一下哈,可能之前之前可能是有同事就是就是没有给你说,对吧?<\/s>Human: 对呀,说我不敢用呀,你。\nAssistant: 啊跟你说一下。<\/s>Human: 嗯。\nAssistant: 一万块钱一万块钱,你要分一年,他总共的利息下来是在一千三左右哈,你平均到每个月的话,你下来的一百块钱左右,每天每个月在一百块钱左右的利息,平均到每天就在在三块钱左右哈。<\/s>Human: 就是五万块钱。\nAssistant: 我一万块钱哈。<\/s>Human: 呃一一天三块钱左右应该就是一百块钱,但是的话说就是。\nAssistant: 一百块钱左右嘛。<\/s>Human: 一你我一百块钱就是一就是假的话,就是利大概是六千多块钱。\nAssistant: 我看一下你。<\/s>Human: 一年。\nAssistant: 分的话差不多六千块钱左右哈。<\/s>Human: 对对对,因为对我所以说你你给我讲一百块钱,我说大概六千多块,我就大概六千块钱左右了,一年。\nAssistant: 对。<\/s>Human: 啊啊\nAssistant: 嗯嗯差这一五万块钱一年就是六千块钱左右哈。<\/s>Human: 哦对对对,因为因为因为我这我这这这个钱还有个问题,就是假的话的。就是我我说的我拿的是我我的就是分十二期还,但是我提前还就是提前还就没有违约,没有什么利息的啦。\nAssistant: 嗯。<\/s>Human: 是\nAssistant: 诶你提前还款的话,它就是就是你你就是我们就是满足条件没有逾期的情况下就可以申请提前还款了,提前还款,您用几个月收取你几个月的利息哈,就是满足条件还满三期之后就可以申请提前还款了哈,就比如说哈,因为先生比如说你分了一年啊,就你只用了半年哈,你提前还款了,你嗯。<\/s>Human: 嗯。对。对对对。对。\nAssistant: ", "answer":"Assistant: 就是后你提前还款了之后,后面是不会收取这利息的哈。<\/s>" }, { "id":2, "input":"#姓名:李#性别:先生#剩余额度:两万元#当前额度:零#绑定银行:无#活动:C#初始额度:nan#手机尾号:五零零七#注册时间:nan#借款日期:nan#优惠券数:nan#电销时间:nan#登录类型:nan#提额时间:nan#offer类型:nan#cust_type:nan\n\nAssistant: 好,请问是李先生是吧?<\/s>Human: 啊行。\nAssistant: 诶李先生您好,我是xxx的工作人员。<\/s>Human: 哦\nAssistant: 来电呢是给您确认一下,您之前在ttt还有个剩余额度,两万元是您本人在自己使用的,对吧?<\/s>Human: 啊?\nAssistant: 诶是这样的先生,因为呢我们系统显示您之前还款记录保持得比较好,现在公司在回馈优质客户专门来电给您确认一下,<\/s>Human: 好\nAssistant: 如果您打算以后长期使用ttt,还需要提高您的额度和降低利息的话。<\/s>Human: 嗯\nAssistant: ", "answer":"Assistant: 您现在呢只需要将您的剩余额度两万元按去暂时借出来。<\/s>" } ] ``` ### 推理 推理耗时,平均每个token生成时长等。 单卡: ``` CUDA_VISIBLE_DEVICES=1 python examples/pytorch/gpt/firefly_lambada_dianxiao_1w_stat_token.py \ --checkpoint-path /workspace/model/firefly-2b6-dx-1tp/belle7b/1/1-gpu \ --tokenizer-path /workspace/model/firefly-2b6-dx \ --dataset-path /workspace/data/lambada_test.jsonl \ --lib-path /workspace/lib/libth_transformer.so \ --inference-data-type fp16 --show-progress --input-token-len 64 --output-token-len 256 \ --dianxiao-path-stat /workspace/output/firefly_random_sample_1w_256_stat_ft.json ``` 双卡张量并行: ``` CUDA_VISIBLE_DEVICES=2,3 mpirun -n 2 python examples/pytorch/gpt/firefly_lambada_dianxiao_1w_stat_token.py \ --checkpoint-path /workspace/model/firefly-2b6-dx-2tp/belle7b/1/2-gpu \ --tokenizer-path /workspace/model/firefly-2b6-dx \ --dataset-path /workspace/data/lambada_test.jsonl \ --lib-path /workspace/lib/libth_transformer.so \ --inference-data-type fp16 \ --tensor-para-size 2 \ --pipeline-para-size 1 \ --show-progress \ --input-token-len 64 \ --output-token-len 256 \ --dianxiao-path-stat /workspace/output/firefly_random_sample_1w_256_stat_ft_tp2.json ``` ================================================ FILE: llm-inference/faster-transformer/bloom/firefly_lambada_1w_stat_token.py ================================================ from __future__ import annotations import argparse import configparser import dataclasses import json import pathlib import time from typing import Dict, List from random import choice import torch import tqdm import transformers from utils import bloom from statistics import mean import numpy as np import os class TensorEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, torch.Tensor): return obj.tolist() return super().default(obj) class LambadaDataset(torch.utils.data.Dataset): """ LAMBADA dataset class. """ def __init__(self, path: str | pathlib.Path, tokenizer: transformers.PreTrainedTokenizerBase): self.tokenizer = tokenizer with open(path, 'r') as f: inputs, targets = zip(*[ json.loads(line)["text"].strip('\n').rsplit(' ', 1) for line in f.readlines()]) # This whitespace preprocessing (additional space to the target) # is required. targets = [' ' + tgt for tgt in targets] self.encodings = self.tokenizer(list(inputs), targets, padding=True, return_token_type_ids=True, return_tensors='pt') def __len__(self): return len(self.encodings['input_ids']) def __getitem__(self, idx): return dict( input_ids=self.encodings['input_ids'][idx], attention_mask=self.encodings['attention_mask'][idx], token_type_ids=self.encodings['token_type_ids'][idx] ) @dataclasses.dataclass class Metric: acc: float @dataclasses.dataclass class RequestAndResult: prompt: str model_answer: str target: str input_ids: List[int] input_len: int output_len: int model_params: bloom.BloomParam infer_params: bloom.BloomInferParam output_ids: List[int] metrics: Metric def asdict(self): return dataclasses.asdict(self) class Timer: def __init__(self): self._start_times = {} self._total_elapsed_times = {} def start(self, tag='__default'): self._start_times[tag] = time.time() def stop(self, tag='__default'): elapsed_time = time.time() - self._start_times[tag] if tag not in self._total_elapsed_times: self._total_elapsed_times[tag] = 0 self._total_elapsed_times[tag] += elapsed_time return elapsed_time def elapsed_time_in_sec(self, tag='__default'): if tag not in self._total_elapsed_times: return None return self._total_elapsed_times[tag] def reset(self): self._start_times.clear() self._total_elapsed_times.clear() def get_args(): parser = argparse.ArgumentParser( 'Evaluation: LAMBADA Task', formatter_class=argparse.ArgumentDefaultsHelpFormatter) bloom.BloomParam.add_args_group(parser) bloom.BloomInferParam.add_args_group(parser) group = parser.add_argument_group('LAMBADA Task Parameters') group.add_argument( '--checkpoint-path', type=str, metavar='DIR', default=None, help='A directory of a converted pretrained checkpoint and model config ' 'If None, a model will inference by random weights.') group.add_argument( '--dataset-path', type=str, metavar='PATH', required=True, help="A file path to LAMBADA task dataset.") group.add_argument( '--output-path', type=str, metavar='PATH', default=None, help="Path to sample output file.") group.add_argument( "--tokenizer-path", type=str, metavar='DIR_OR_PATH', default=None, help='A file path of a pretrained tokenizer or a checkpoint directory ' 'of HF pretrained model.') group.add_argument( '--lib-path', type=str, metavar='PATH', default='./lib/libth_transformer.so', help='A FT library path to load `FasterTransformer.ParallelGptOp`') group.add_argument( '--test-hf', action='store_true', help='Run a huggingface model instead of an FT model. The checkpoint ' 'of the huggingface model is assumed to be at --tokenizer-path.') group.add_argument( '--acc-threshold', type=float, metavar='M', default=None, help='The minimum value of the expected accuracy of the LAMBADA ' 'evaluation for a test. If the achieved accuracy is less ' 'than given value, a value error will occurs.') group.add_argument( '--show-progress', action='store_true', help='Show evaluation progress') group.add_argument( '--inference-data-type', '--data-type', type=str, metavar='TYPE', default=None, choices=[None, 'fp32', 'fp16', 'bf16'], help='The data type to inference. If None, the data type follows the ' 'checkpoint data type.') group.add_argument( '--weights-data-type', type=str, metavar='TYPE', default=None, choices=[None, 'fp32', 'fp16'], help='The data type of FT checkpoint. If None, it will be retrieved ' 'from the config file in the checkpoint directory.') group.add_argument( '--int8_mode', type=int, default=0, choices=[0, 1], help='The level of quantization to perform.' ' 0: No quantization. All computation in data_type' ' 1: Quantize weights to int8, all compute occurs in fp16/bf16. Not supported when data_type is fp32') group.add_argument('--input-token-len', type=int, default=128) group.add_argument('--output-token-len', type=int, default=128) group.add_argument('--dianxiao-path-stat', type=str, default="/workspace/data/random_sample_1w_stat.json") args = parser.parse_args() print('\n=================== Arguments ===================') for k, v in vars(args).items(): print(f' - {k.ljust(25, ".")}: {v}') print('=================================================') return args def get_model_and_tokenizer(args: argparse.Namespace): tokenizer_path = pathlib.Path(args.tokenizer_path) # HF requires left padding for a decoder-only model. padding_side = 'left' if args.test_hf else 'right' if tokenizer_path.is_dir(): # Load from the HF's pretrained model directory. tokenizer = transformers.BloomTokenizerFast.from_pretrained( args.tokenizer_path, padding_side=padding_side) else: # Directly load from a tokenizer json file. tokenizer = transformers.BloomTokenizerFast( tokenizer_file=tokenizer_path, padding_side=padding_side) # For open-ended generation, the pad token is sometimes replaced by the # eos token but the Bloom of HF requires as it is to correctly generate. if args.test_hf: # Load HF's pretrained model for testing. model = transformers.AutoModelForCausalLM.from_pretrained( args.tokenizer_path, torch_dtype=torch.float16).cuda() return model, tokenizer checkpoint_path = pathlib.Path(args.checkpoint_path) config_path = checkpoint_path / 'config.ini' if config_path.exists(): # Read model params from config. cfg = configparser.ConfigParser() cfg.read(config_path) model_name = 'gpt' inference_data_type = args.inference_data_type if inference_data_type == None: inference_data_type = cfg.get(model_name, "weight_data_type") model_args = dict( head_num=cfg.getint(model_name, 'head_num'), size_per_head=cfg.getint(model_name, "size_per_head"), layer_num=cfg.getint(model_name, "num_layer"), tensor_para_size=cfg.getint(model_name, "tensor_para_size"), vocab_size=cfg.getint(model_name, "vocab_size"), start_id=cfg.getint(model_name, "start_id"), end_id=cfg.getint(model_name, "end_id"), weights_data_type=cfg.get(model_name, "weight_data_type"), layernorm_eps=cfg.getfloat(model_name, 'layernorm_eps'), inference_data_type=inference_data_type) else: inference_data_type = args.inference_data_type if inference_data_type == None: inference_data_type = args.weights_data_type model_args = dict(head_num=args.num_heads, size_per_head=args.size_per_head, vocab_size=args.vocab_size, start_id=args.start_id or tokenizer.bos_token_id, end_id=args.end_id or tokenizer.eos_token_id, layer_num=args.num_layers, tensor_para_size=args.tensor_para_size, weights_data_type=args.weights_data_type, inference_data_type=inference_data_type) # update common parameters model_args.update(dict( lib_path=args.lib_path, pipeline_para_size=args.pipeline_para_size, shared_contexts_ratio=args.shared_contexts_ratio, int8_mode=args.int8_mode )) print('[FT][INFO] Load BLOOM model') for k, v in model_args.items(): print(f' - {k.ljust(25, ".")}: {v}') # Check sanity and consistency between the model and tokenizer. checklist = ['head_num', 'size_per_head', 'vocab_size', 'layer_num', 'tensor_para_size', 'tensor_para_size', 'weights_data_type'] if None in [model_args[k] for k in checklist]: none_params = [p for p in checklist if model_args[p] is None] print(f'[FT][WARNING] Found None parameters {none_params}. They must ' f'be provided either by config file or CLI arguments.') if model_args['start_id'] != tokenizer.bos_token_id: print('[FT][WARNING] Given start_id is not matched with the bos token ' 'id of the pretrained tokenizer.') if model_args['end_id'] not in (tokenizer.pad_token_id, tokenizer.eos_token_id): print('[FT][WARNING] Given end_id is not matched with neither pad ' 'token id nor eos token id of the pretrained tokenizer.') model = bloom.Bloom(**model_args) if not model.load(ckpt_path=args.checkpoint_path): print('[FT][WARNING] Skip model loading since no checkpoints are found') return model, tokenizer def split_inputs_and_targets(entries: Dict[str, torch.LongTensor], pad_token_id: int, pad_to_left=False): input_ids = entries['input_ids'] attn_mask = entries['attention_mask'] token_type_ids = entries['token_type_ids'] # Split inputs and labels by token_type_ids. input_token_ids = [ ids[(mask == 1) & (type_ids == 0)] for ids, mask, type_ids in zip(input_ids, attn_mask, token_type_ids)] # FT allows int32 tensors. input_lengths = torch.tensor( [len(input_tokens) for input_tokens in input_token_ids]).int() max_length = input_lengths.max() input_token_ids = torch.stack([ torch.nn.functional.pad( token_ids, pad=[max_length - len(token_ids), 0] if pad_to_left else [0, max_length - len(token_ids)], mode='constant', value=pad_token_id ) for token_ids in input_token_ids]).int() target_token_ids = [ ids[(mask == 1) & (type_ids == 1)] for ids, mask, type_ids in zip(input_ids, attn_mask, token_type_ids)] return input_token_ids, input_lengths, target_token_ids time_list = [] pre_toekn_time_list = [] gen_token_len_list = [] error_input_list = [] # dianxiao_path = "/workspace/data/random_sample_1w_format.json" dianxiao_path = "/workspace/data/actor_v3_21w_sampling_1w.json" # dianxiao_path_stat = "/workspace/data/random_sample_1w_stat.json" stat_result = [] @torch.no_grad() def main(): args = get_args() input_token_len = args.input_token_len output_token_len = args.output_token_len dianxiao_path_stat = args.dianxiao_path_stat print("------------------------------") print("bello-bloom-7b fp16") print("input_token_len:", input_token_len, "output_token_len:", output_token_len,"dianxiao_path_stat:",dianxiao_path_stat) print("------------------------------") nums = 0 model, tokenizer = get_model_and_tokenizer(args) model.eval() with open(dianxiao_path, encoding='utf-8') as json_str: result = json.load(json_str) for temp in result: input_str = temp["input"] input_encoder = tokenizer(input_str, padding=True, return_token_type_ids=True, return_tensors='pt') input_encoder_dict = dict( input_ids=input_encoder['input_ids'], attention_mask=input_encoder['attention_mask'], token_type_ids=input_encoder['token_type_ids'] ) input_token_ids, input_lengths, target_token_ids = split_inputs_and_targets(input_encoder_dict, tokenizer.pad_token_id, args.test_hf) output_length = args.output_token_len params = bloom.BloomInferParam.from_args(args, 1) input_token_lens = input_encoder.input_ids.size(dim=1) # input_token_lens2 = input_token_ids.size(dim=1) # print("input_token_lens:", input_token_lens, "input_token_lens2:", input_token_lens2) if args.test_hf: # Outputs (batch_size, seq_length) start = time.perf_counter() outputs = model.generate(inputs=input_token_ids.cuda(), max_new_tokens=output_length, num_beams=args.beam_width, temperature=args.temperature, top_k=args.top_k, top_p=args.top_p, repetition_penalty=args.repetition_penalty, length_penalty=args.len_penalty) # ,use_cache=False) end = time.perf_counter() # output_token_ids: input/padding/output output_token_ids = outputs[:, input_token_ids.shape[1]:] output_token_ids = [ out[:len(tgt)].cpu() for out, tgt in zip(output_token_ids, target_token_ids)] else: param_dict = params.asdict() start = time.perf_counter() outputs = model(start_ids=input_token_ids, start_lengths=input_lengths, output_len=output_length, **param_dict) end = time.perf_counter() outputs = outputs[0] # if params.return_cum_log_probs or params.return_cum_log_probs > 0: # outputs = outputs[0] # output_token_ids. rets = tokenizer.batch_decode(outputs, skip_special_tokens=True) print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") runTime = end - start runTime_ms = runTime * 1000 print("id", str(temp["id"]), "运行时间:", round(runTime_ms, 2), "毫秒") time_list.append(round(runTime_ms, 2)) print("id", str(temp["id"]), "input:", input_str) print("id", str(temp["id"]), "output_text:", rets[0]) print("------------------") input_seq_len = len(input_str.replace("", "")) output_seq_len = len(rets[0]) gen_seq_len = output_seq_len-input_seq_len generate_text = rets[0][input_seq_len:] print("id", str(temp["id"]), "generate_text:", generate_text) gen_token_len = tokenizer(generate_text, return_tensors="pt").input_ids.size(dim=1) output_token_lens = tokenizer(rets[0], return_tensors="pt").input_ids.size(dim=1) # gen_token_len = output_token_lens - input_token_lens if gen_token_len > 0: gen_token_len_list.append(gen_token_len) pre_toekn_time_list.append(round(runTime_ms / gen_token_len, 2)) else: error_input_list.append(temp["id"]) continue temp["input_seq_len"] = input_seq_len temp["input_token_len"] = input_token_lens temp["output_seq_len"] = output_seq_len temp["output_token_len"] = output_token_lens temp["gen_seq_len"] = gen_seq_len temp["gen_token_len"] = gen_token_len temp["inference_duration_us"] = round(runTime_ms, 2) temp["generate_text"] = generate_text stat_result.append(temp) nums = nums + 1 #if nums == 1000: # break print("错误输入列表:", error_input_list) print("推理耗时列表:", time_list) result = mean(time_list) print("均值:", round(result, 2)) print("最小值:", round(min(time_list), 2)) print("最大值:", round(max(time_list), 2)) print("TP50:", np.percentile(np.array(time_list), 50)) print("TP90:", np.percentile(np.array(time_list), 90)) print("TP99:", np.percentile(np.array(time_list), 99)) print("gen token len:", gen_token_len_list) result_gen_token_len = mean(gen_token_len_list) print("pre token time:", pre_toekn_time_list) result_pre_token_time = mean(pre_toekn_time_list) print("每个Token生成的平均耗时:", round(result_pre_token_time, 2)) print("生成Token长度均值:", round(result_gen_token_len, 2)) print("每个Token生成的平均耗时(微平均):", round(sum(time_list)/sum(gen_token_len_list), 2)) print("TOKEN 最小值:", min(gen_token_len_list)) print("TOKEN 最大值:", max(gen_token_len_list)) pids = os.getpid() # print("pid:", pids, "rank:", torch.distributed.get_rank(group=None)) with open(dianxiao_path_stat+"_"+str(pids), 'w', encoding='utf-8') as b: json.dump(stat_result, b, ensure_ascii=False, indent=4) print("------------------------------") print("bello-bloom-7b fp16") print("input_token_len:", input_token_len, "output_token_len:", output_token_len,"dianxiao_path_stat:",dianxiao_path_stat) print("------------------------------") if __name__ == "__main__": main() ================================================ FILE: llm-inference/faster-transformer/gpt/README.md ================================================ ================================================ FILE: llm-inference/faster-transformer/llama/README.md ================================================ ## LLaMA - https://github.com/NVIDIA/FasterTransformer/issues/506 - https://github.com/NVIDIA/FasterTransformer/pull/575 - https://github.com/void-main/FasterTransformer - https://github.com/void-main/fastertransformer_backend ================================================ FILE: llm-inference/faster-transformer/megatron-gpt2/gpt_summarization.py ================================================ import argparse import configparser import json import os import numpy as np import sys import torch import evaluate from datasets import load_dataset #from datasets import load_dataset, load_metric from tqdm import tqdm from transformers import GPT2Tokenizer, GPT2LMHeadModel from utils import comm from utils import gpt_decoder from utils import profiler from utils.parallel_gpt import ParallelGPT from utils.gpt_fp8 import GPTFp8 def main(): parser = argparse.ArgumentParser() parser.add_argument('--ft_model_location', type=str, default='/models/GPT/HF/gpt2-xl/c-models') parser.add_argument('--hf_model_location', type=str, default='/models/GPT/HF/gpt2-xl/') parser.add_argument('--summarize', action='store_true') parser.add_argument('--test_hf', action='store_true') parser.add_argument('--data_type', type=str, choices=['fp32', 'fp16', 'bf16', 'fp8'], default='fp32') parser.add_argument("--cache_path", type=str, default="/workdir/datasets/ccdv/") parser.add_argument("--max_ite", type=int, default=20) parser.add_argument("--ft_use_hf_config", action="store_true", help="use the hyper-parameters from the hf model") parser.add_argument('--lib_path', type=str, default='./lib/libth_transformer.so', help='path to the pyt_fastertransformer dynamic lib file.') parser.add_argument('--tensor_para_size', type=int, default=1, help='tensor parallel size') parser.add_argument('--pipeline_para_size', type=int, default=1, help='pipeline parallel size') parser.add_argument( '--weights_data_type', type=str, default='fp32', choices=['fp32', 'fp16'], help='Data type of FT checkpoint weights') parser.add_argument( '--int8_mode', type=int, default=0, choices=[0, 1], help='The level of quantization to perform.' ' 0: No quantization. All computation in data_type' ' 1: Quantize weights to int8, all compute occurs in fp16/bf16. Not supported when data_type is fp32') parser.add_argument( '--use_gpt_decoder_ops', action='store_true', help='Use separate decoder FT operators instead of end-to-end model op.') parser.add_argument( '--use_fp32_to_compute_logit', action='store_true', help='Use FP32 data type for computing logit values when using gpt decoder ops. ' 'FT end-to-end GPT op always uses FP32 data type when computing logit.') parser.add_argument( '--rougeLsum_threshold', type=float, default=None, help='Threshold of FT rougeLsum score') parser.add_argument( '--verbose', action='store_true', help='Print all summary result.') args = parser.parse_args() np.random.seed(0) # rouge score use sampling to compute the score comm.initialize_model_parallel(args.tensor_para_size, args.pipeline_para_size) rank = comm.get_rank() summarize = args.summarize test_hf = args.test_hf ft_model_location = args.ft_model_location hf_model_location = args.hf_model_location tokenizer = GPT2Tokenizer.from_pretrained('/workspace/model/gpt2-tokenizer/gpt2-tokenizer') tokenizer.pad_token = tokenizer.eos_token #dataset_cnn = load_dataset("./cnn_dailymail.py", '3.0.0', cache_dir=args.cache_path) dataset_cnn = load_dataset("./cnn_dailymail.py", '3.0.0', cache_dir="/workspace/data/ccdv-data/ccdv") hf_config = json.load(open(os.path.join(hf_model_location, 'config.json'), 'r')) ft_config = None head_num = hf_config['n_head'] layer_num = hf_config['n_layer'] start_id = hf_config['bos_token_id'] end_id = hf_config['eos_token_id'] size_per_head = hf_config['n_embd'] // head_num if not args.ft_use_hf_config: ft_config = configparser.ConfigParser() assert ft_config.read(os.path.join(ft_model_location, '1-gpu/config.ini')) != [], "[ERROR] fail to read the config.ini of model" head_num = ft_config.getint('gpt', 'head_num') layer_num = ft_config.getint('gpt', 'num_layer') start_id = ft_config.getint('gpt', 'start_id') # TODO: get this from the tokenizer end_id = ft_config.getint('gpt', 'end_id') # TODO: get this from the tokenizer size_per_head = ft_config.getint('gpt', 'size_per_head') if summarize: top_k = 2 output_len = 100 else: top_k = 1 output_len = 256 if args.data_type == "fp8": top_k = 1 top_p = 0.0 random_seed = 5 temperature = 1 max_seq_len = hf_config['n_ctx'] if args.ft_use_hf_config else ft_config.getint('gpt', 'max_pos_seq_len') max_batch_size = 1 repetition_penalty = 1 vocab_size = 50257 if not args.ft_use_hf_config and ft_config.has_option('gpt', 'vocab_size'): vocab_size = ft_config.getint('gpt', 'vocab_size', fallback=vocab_size) tensor_para_size = args.tensor_para_size pipeline_para_size = args.pipeline_para_size lib_path = args.lib_path ckpt_path = os.path.join(ft_model_location, f'{tensor_para_size}-gpu') print(f"top_k: {top_k}") print(f"top_p: {top_p}") print(f"int8_mode: {args.int8_mode}") print(f"random_seed: {random_seed}") print(f"temperature: {temperature}") print(f"max_seq_len: {max_seq_len}") print(f"max_batch_size: {max_batch_size}") print(f"repetition_penalty: {repetition_penalty}") print(f"vocab_size: {vocab_size}") print(f"tensor_para_size: {tensor_para_size}") print(f"pipeline_para_size: {pipeline_para_size}") print(f"lib_path: {lib_path}") print(f"ckpt_path: {ckpt_path}") print(f"hf_config: {hf_config}") infer_decode_args = dict( beam_width=1, top_k=top_k * torch.ones(max_batch_size, dtype=torch.int32), top_p=top_p * torch.ones(max_batch_size, dtype=torch.float32), temperature=temperature * torch.ones(max_batch_size, dtype=torch.float32), repetition_penalty=repetition_penalty * torch.ones(max_batch_size, dtype=torch.float32), random_seed=random_seed * torch.ones(max_batch_size, dtype=torch.int64) ) random_seed_tensor = random_seed * torch.ones([max_batch_size], dtype=torch.int64) if args.data_type == 'fp8': gpt = GPTFp8(head_num, size_per_head, vocab_size, start_id, end_id, layer_num, max_seq_len, tensor_para_size, pipeline_para_size, lib_path=lib_path, ckpt_path=ckpt_path, int8_mode=0, weights_data_type=args.weights_data_type) else: if not args.use_gpt_decoder_ops: gpt = ParallelGPT(head_num, size_per_head, vocab_size, start_id, end_id, layer_num, max_seq_len, tensor_para_size, pipeline_para_size, lib_path=lib_path, inference_data_type=args.data_type, int8_mode=args.int8_mode, weights_data_type=args.weights_data_type) if not gpt.load(ckpt_path=ckpt_path): print("[WARNING] Checkpoint file not found. Model loading is skipped.") else: gpt = gpt_decoder.Gpt( num_heads=head_num, size_per_head=size_per_head, num_layers=layer_num, vocab_size=vocab_size, start_id=start_id, end_id=end_id, tensor_para_size=tensor_para_size, pipeline_para_size=pipeline_para_size, lib_path=lib_path, max_seq_len=max_seq_len, int8_mode = args.int8_mode, inference_data_type=args.data_type, weights_data_type=args.weights_data_type, use_fp32_to_compute_logit=args.use_fp32_to_compute_logit) gpt.load(ckpt_path, args.data_type) if (test_hf and summarize) or not summarize: model = GPT2LMHeadModel.from_pretrained(hf_model_location) model.cuda() if args.data_type == 'fp16': model.half() elif args.data_type == 'bf16': model.bfloat16() def summarize_ft_e2e(datapoint): if summarize: line = datapoint['article'] + ' TL;DR: ' else: line = datapoint['article'] line = line.strip() line = line.replace(" n't", "n't") line_encoded = tokenizer.encode(line, return_tensors='pt') if summarize: line_encoded = line_encoded[:, -923:] else: line_encoded = line_encoded[:, -768:] line_encoded = line_encoded.type(torch.int32) with torch.no_grad(): output, ft_output_len = gpt(line_encoded, torch.IntTensor([len(line_encoded[0])]), output_len, return_output_length=True, **infer_decode_args) tokens = output[0][0][len(line_encoded[0]):ft_output_len[0]].cpu().numpy() output_lines = tokenizer.decode(output[0][0][len(line_encoded[0]):ft_output_len[0]]) output_lines = ".".join(output_lines.split('.')[:4]) + "." return output_lines, tokens def summarize_ft_sep(datapoint): if summarize: line = datapoint['article'] + ' TL;DR: ' else: line = datapoint['article'] line = line.strip() line = line.replace(" n't", "n't") line_encoded = tokenizer.encode(line, return_tensors='pt') if summarize: line_encoded = line_encoded[:, -923:] else: line_encoded = line_encoded[:, -768:] line_encoded = line_encoded.type(torch.int32).to(gpt.device) input_lengths = torch.tensor([len(line_encoded[0])], dtype=torch.int32, device=gpt.device) with torch.no_grad(): output_dict = gpt.generate(input_token_ids=line_encoded, input_lengths=input_lengths, gen_length=output_len, eos_token_id=tokenizer.eos_token_id, return_output_length=True, **infer_decode_args) output_token_ids = output_dict['output_token_ids'] output_lengths = output_dict['output_lengths'] tokens = output_token_ids[0, 0, input_lengths[0]:output_lengths[0]] output_lines = tokenizer.decode(tokens) output_lines = ".".join(output_lines.split('.')[:4]) + "." return output_lines, tokens.cpu().numpy() summarize_ft = summarize_ft_e2e if not args.use_gpt_decoder_ops else summarize_ft_sep def summarize_hf(datapoint): if summarize: line = datapoint['article'] + ' TL;DR: ' else: line = datapoint['article'] line = line.strip() line = line.replace(" n't", "n't") line_encoded = tokenizer.encode(line, return_tensors='pt') if summarize: line_encoded = line_encoded[:, -923:] else: line_encoded = line_encoded[:, -768:] line_encoded = line_encoded.cuda() with torch.no_grad(): output = model.generate(line_encoded, max_length=len(line_encoded[0]) + output_len, top_k=top_k, temperature=temperature, eos_token_id=tokenizer.eos_token_id, pad_token_id=tokenizer.pad_token_id) tokens = output[0][len(line_encoded[0]):].cpu().numpy() output_lines = tokenizer.decode(output[0][len(line_encoded[0]):]) output_lines = ".".join(output_lines.split('.')[:4]) + "." return output_lines, tokens if summarize: datapoint = dataset_cnn['test'][0] summary, _ = summarize_ft(datapoint) print('---------------------------------------------------------') print('FT Generated : ') print(' Article : ', datapoint['article']) print('\n Highlights : ', datapoint['highlights']) print('\n Summary : ', summary) print('---------------------------------------------------------') if test_hf: summary, _ = summarize_hf(datapoint) print('---------------------------------------------------------') print('HF Generated : ') print(' Article : ', datapoint['article']) print('\n Highlights : ', datapoint['highlights']) print('\n Summary : ', summary) print('---------------------------------------------------------') if summarize: #metric_ft = load_metric("rouge") #metric_hf = load_metric("rouge") metric_ft = evaluate.load("rouge") metric_hf = evaluate.load("rouge") else: tokens = [] for data_point_idx in tqdm(range(1, 11490, int(11490 / args.max_ite))): try: datapoint = dataset_cnn['test'][data_point_idx] profiler.start('ft') summary_ft, tokens_ft = summarize_ft(datapoint) profiler.stop('ft') if (test_hf and summarize) or not summarize: profiler.start('hf') summary_hf, tokens_hf = summarize_hf(datapoint) profiler.stop('hf') if rank == 0: if summarize: metric_ft.add_batch(predictions=[summary_ft], references=[datapoint['highlights']]) if test_hf: metric_hf.add_batch(predictions=[summary_hf], references=[datapoint['highlights']]) else: assert test_hf tokens.append((tokens_ft, tokens_hf)) if args.verbose: print('-' * 100) print('FT Summary:', summary_ft) if test_hf: print('HF Summary:', summary_hf) except: print('Error with datapoint : ', data_point_idx) def compute_exact_match(tokens, n_tokens=[1, 10, 25, 50, 100, 150, 200, 250]): em_metrics = [] for t in n_tokens: errors = 0 total = 0 for ft_tokens, hf_tokens in tokens: if len(ft_tokens) > t and len(hf_tokens) > t: total = total + 1 if not np.array_equal(ft_tokens[:t], hf_tokens[:t]): errors = errors + 1 if total > 0: print(f"{t}-token exact match acc: {100*(1-errors/total):.2f}") em_metrics.append(1 - errors / total) else: em_metrics.append(np.nan) return em_metrics if rank == 0: if summarize: computed_metrics_ft = metric_ft.compute() if test_hf: computed_metrics_hf = metric_hf.compute() print(f'Hugging Face (total latency: {profiler.elapsed_time_in_sec("hf")} sec)') for key in computed_metrics_hf.keys(): print(f'{key} : {computed_metrics_hf[key]*100}') #print(f'{key} : {computed_metrics_hf[key].mid[2]*100}') print("------------") print(f'Faster Transformers (total latency: {profiler.elapsed_time_in_sec("ft")} sec)') for key in computed_metrics_ft.keys(): print(f'{key} : {computed_metrics_ft[key]*100}') #print(f'{key} : {computed_metrics_ft[key].mid[2]*100}') print("--------------!!!!") if args.rougeLsum_threshold is not None: assert computed_metrics_ft["rougeLsum"].mid[2]*100 >= args.rougeLsum_threshold, "[INFO] TEST FAIL !" print(f"[INFO] TEST PASS !") else: em_metrics = compute_exact_match(tokens) if args.verbose: profiler.summary() if __name__ == '__main__': main() ================================================ FILE: llm-inference/faster-transformer/megatron-gpt2/gpt_summarization_stat.py ================================================ import argparse import configparser import json import os import numpy as np import sys import torch import evaluate from datasets import load_dataset #from datasets import load_dataset, load_metric from tqdm import tqdm from transformers import GPT2Tokenizer, GPT2LMHeadModel from utils import comm from utils import gpt_decoder from utils import profiler from utils.parallel_gpt import ParallelGPT from utils.gpt_fp8 import GPTFp8 import time from statistics import mean def main(): parser = argparse.ArgumentParser() parser.add_argument('--ft_model_location', type=str, default='/models/GPT/HF/gpt2-xl/c-models') parser.add_argument('--hf_model_location', type=str, default='/models/GPT/HF/gpt2-xl/') parser.add_argument('--summarize', action='store_true') parser.add_argument('--test_hf', action='store_true') parser.add_argument('--data_type', type=str, choices=['fp32', 'fp16', 'bf16', 'fp8'], default='fp32') parser.add_argument("--cache_path", type=str, default="/workdir/datasets/ccdv/") parser.add_argument("--max_ite", type=int, default=20) parser.add_argument("--ft_use_hf_config", action="store_true", help="use the hyper-parameters from the hf model") parser.add_argument('--lib_path', type=str, default='./lib/libth_transformer.so', help='path to the pyt_fastertransformer dynamic lib file.') parser.add_argument('--tensor_para_size', type=int, default=1, help='tensor parallel size') parser.add_argument('--pipeline_para_size', type=int, default=1, help='pipeline parallel size') parser.add_argument( '--weights_data_type', type=str, default='fp32', choices=['fp32', 'fp16'], help='Data type of FT checkpoint weights') parser.add_argument( '--int8_mode', type=int, default=0, choices=[0, 1], help='The level of quantization to perform.' ' 0: No quantization. All computation in data_type' ' 1: Quantize weights to int8, all compute occurs in fp16/bf16. Not supported when data_type is fp32') parser.add_argument( '--use_gpt_decoder_ops', action='store_true', help='Use separate decoder FT operators instead of end-to-end model op.') parser.add_argument( '--use_fp32_to_compute_logit', action='store_true', help='Use FP32 data type for computing logit values when using gpt decoder ops. ' 'FT end-to-end GPT op always uses FP32 data type when computing logit.') parser.add_argument( '--rougeLsum_threshold', type=float, default=None, help='Threshold of FT rougeLsum score') parser.add_argument( '--verbose', action='store_true', help='Print all summary result.') args = parser.parse_args() np.random.seed(0) # rouge score use sampling to compute the score comm.initialize_model_parallel(args.tensor_para_size, args.pipeline_para_size) rank = comm.get_rank() print(f"~~~~~~~~~~~~~ args.summarize: {args.summarize} , args.test_hf: {args.test_hf}") summarize = args.summarize test_hf = args.test_hf ft_model_location = args.ft_model_location hf_model_location = args.hf_model_location tokenizer = GPT2Tokenizer.from_pretrained('/workspace/model/gpt2-tokenizer/gpt2-tokenizer') tokenizer.pad_token = tokenizer.eos_token #dataset_cnn = load_dataset("./cnn_dailymail.py", '3.0.0', cache_dir=args.cache_path) dataset_cnn = load_dataset("./cnn_dailymail.py", '3.0.0', cache_dir="/workspace/data/ccdv-data/ccdv") hf_config = json.load(open(os.path.join(hf_model_location, 'config.json'), 'r')) ft_config = None head_num = hf_config['n_head'] layer_num = hf_config['n_layer'] start_id = hf_config['bos_token_id'] end_id = hf_config['eos_token_id'] size_per_head = hf_config['n_embd'] // head_num if not args.ft_use_hf_config: ft_config = configparser.ConfigParser() assert ft_config.read(os.path.join(ft_model_location, '1-gpu/config.ini')) != [], "[ERROR] fail to read the config.ini of model" head_num = ft_config.getint('gpt', 'head_num') layer_num = ft_config.getint('gpt', 'num_layer') start_id = ft_config.getint('gpt', 'start_id') # TODO: get this from the tokenizer end_id = ft_config.getint('gpt', 'end_id') # TODO: get this from the tokenizer size_per_head = ft_config.getint('gpt', 'size_per_head') if summarize: top_k = 2 output_len = 100 else: top_k = 1 output_len = 256 if args.data_type == "fp8": top_k = 1 top_p = 0.0 random_seed = 5 temperature = 1 max_seq_len = hf_config['n_ctx'] if args.ft_use_hf_config else ft_config.getint('gpt', 'max_pos_seq_len') max_batch_size = 1 repetition_penalty = 1 vocab_size = 50257 if not args.ft_use_hf_config and ft_config.has_option('gpt', 'vocab_size'): vocab_size = ft_config.getint('gpt', 'vocab_size', fallback=vocab_size) tensor_para_size = args.tensor_para_size pipeline_para_size = args.pipeline_para_size lib_path = args.lib_path ckpt_path = os.path.join(ft_model_location, f'{tensor_para_size}-gpu') print(f"top_k: {top_k}") print(f"top_p: {top_p}") print(f"int8_mode: {args.int8_mode}") print(f"random_seed: {random_seed}") print(f"temperature: {temperature}") print(f"max_seq_len: {max_seq_len}") print(f"max_batch_size: {max_batch_size}") print(f"repetition_penalty: {repetition_penalty}") print(f"vocab_size: {vocab_size}") print(f"tensor_para_size: {tensor_para_size}") print(f"pipeline_para_size: {pipeline_para_size}") print(f"lib_path: {lib_path}") print(f"ckpt_path: {ckpt_path}") print(f"hf_config: {hf_config}") infer_decode_args = dict( beam_width=1, top_k=top_k * torch.ones(max_batch_size, dtype=torch.int32), top_p=top_p * torch.ones(max_batch_size, dtype=torch.float32), temperature=temperature * torch.ones(max_batch_size, dtype=torch.float32), repetition_penalty=repetition_penalty * torch.ones(max_batch_size, dtype=torch.float32), random_seed=random_seed * torch.ones(max_batch_size, dtype=torch.int64) ) random_seed_tensor = random_seed * torch.ones([max_batch_size], dtype=torch.int64) if args.data_type == 'fp8': gpt = GPTFp8(head_num, size_per_head, vocab_size, start_id, end_id, layer_num, max_seq_len, tensor_para_size, pipeline_para_size, lib_path=lib_path, ckpt_path=ckpt_path, int8_mode=0, weights_data_type=args.weights_data_type) else: if not args.use_gpt_decoder_ops: gpt = ParallelGPT(head_num, size_per_head, vocab_size, start_id, end_id, layer_num, max_seq_len, tensor_para_size, pipeline_para_size, lib_path=lib_path, inference_data_type=args.data_type, int8_mode=args.int8_mode, weights_data_type=args.weights_data_type) if not gpt.load(ckpt_path=ckpt_path): print("[WARNING] Checkpoint file not found. Model loading is skipped.") else: gpt = gpt_decoder.Gpt( num_heads=head_num, size_per_head=size_per_head, num_layers=layer_num, vocab_size=vocab_size, start_id=start_id, end_id=end_id, tensor_para_size=tensor_para_size, pipeline_para_size=pipeline_para_size, lib_path=lib_path, max_seq_len=max_seq_len, int8_mode = args.int8_mode, inference_data_type=args.data_type, weights_data_type=args.weights_data_type, use_fp32_to_compute_logit=args.use_fp32_to_compute_logit) gpt.load(ckpt_path, args.data_type) if (test_hf and summarize) or not summarize: model = GPT2LMHeadModel.from_pretrained(hf_model_location) model.cuda() if args.data_type == 'fp16': model.half() elif args.data_type == 'bf16': model.bfloat16() time_list = [] def summarize_ft_e2e(datapoint): if summarize: line = datapoint['article'] + ' TL;DR: ' else: line = datapoint['article'] line = line.strip() line = line.replace(" n't", "n't") line_encoded = tokenizer.encode(line, return_tensors='pt') if summarize: line_encoded = line_encoded[:, -923:] else: line_encoded = line_encoded[:, -768:] line_encoded = line_encoded.type(torch.int32) with torch.no_grad(): output, ft_output_len = gpt(line_encoded, torch.IntTensor([len(line_encoded[0])]), output_len, return_output_length=True, **infer_decode_args) tokens = output[0][0][len(line_encoded[0]):ft_output_len[0]].cpu().numpy() output_lines = tokenizer.decode(output[0][0][len(line_encoded[0]):ft_output_len[0]]) output_lines = ".".join(output_lines.split('.')[:4]) + "." return output_lines, tokens def summarize_ft_sep(datapoint): if summarize: line = datapoint['article'] + ' TL;DR: ' else: line = datapoint['article'] line = line.strip() line = line.replace(" n't", "n't") line_encoded = tokenizer.encode(line, return_tensors='pt') if summarize: line_encoded = line_encoded[:, -923:] else: line_encoded = line_encoded[:, -768:] line_encoded = line_encoded.type(torch.int32).to(gpt.device) input_lengths = torch.tensor([len(line_encoded[0])], dtype=torch.int32, device=gpt.device) with torch.no_grad(): output_dict = gpt.generate(input_token_ids=line_encoded, input_lengths=input_lengths, gen_length=output_len, eos_token_id=tokenizer.eos_token_id, return_output_length=True, **infer_decode_args) output_token_ids = output_dict['output_token_ids'] output_lengths = output_dict['output_lengths'] tokens = output_token_ids[0, 0, input_lengths[0]:output_lengths[0]] output_lines = tokenizer.decode(tokens) output_lines = ".".join(output_lines.split('.')[:4]) + "." return output_lines, tokens.cpu().numpy() print(f"----------args.use_gpt_decoder_ops: {args.use_gpt_decoder_ops} ") summarize_ft = summarize_ft_e2e if not args.use_gpt_decoder_ops else summarize_ft_sep def summarize_hf(datapoint): if summarize: line = datapoint['article'] + ' TL;DR: ' else: line = datapoint['article'] line = line.strip() line = line.replace(" n't", "n't") line_encoded = tokenizer.encode(line, return_tensors='pt') if summarize: line_encoded = line_encoded[:, -923:] else: line_encoded = line_encoded[:, -768:] line_encoded = line_encoded.cuda() with torch.no_grad(): output = model.generate(line_encoded, max_length=len(line_encoded[0]) + output_len, top_k=top_k, temperature=temperature, eos_token_id=tokenizer.eos_token_id, pad_token_id=tokenizer.pad_token_id) tokens = output[0][len(line_encoded[0]):].cpu().numpy() output_lines = tokenizer.decode(output[0][len(line_encoded[0]):]) output_lines = ".".join(output_lines.split('.')[:4]) + "." return output_lines, tokens if summarize: datapoint = dataset_cnn['test'][0] summary, _ = summarize_ft(datapoint) print('---------------------------------------------------------') print('FT Generated : ') print(' Article : ', datapoint['article']) print('\n Highlights : ', datapoint['highlights']) print('\n Summary : ', summary) print('---------------------------------------------------------') if test_hf: summary, _ = summarize_hf(datapoint) print('---------------------------------------------------------') print('HF Generated : ') print(' Article : ', datapoint['article']) print('\n Highlights : ', datapoint['highlights']) print('\n Summary : ', summary) print('---------------------------------------------------------') if summarize: #metric_ft = load_metric("rouge") #metric_hf = load_metric("rouge") metric_ft = evaluate.load("rouge") metric_hf = evaluate.load("rouge") else: tokens = [] for data_point_idx in tqdm(range(1, 11490, int(11490 / args.max_ite))): try: datapoint = dataset_cnn['test'][data_point_idx] profiler.start('ft') start = time.perf_counter() summary_ft, tokens_ft = summarize_ft(datapoint) end = time.perf_counter() runTime = end - start runTime_ms = runTime * 1000 print("data_point_idx:", str(data_point_idx), "运行时间:", round(runTime_ms, 2), "毫秒") time_list.append(round(runTime_ms, 2)) profiler.stop('ft') if (test_hf and summarize) or not summarize: profiler.start('hf') summary_hf, tokens_hf = summarize_hf(datapoint) profiler.stop('hf') if rank == 0: if summarize: metric_ft.add_batch(predictions=[summary_ft], references=[datapoint['highlights']]) if test_hf: metric_hf.add_batch(predictions=[summary_hf], references=[datapoint['highlights']]) else: assert test_hf tokens.append((tokens_ft, tokens_hf)) if args.verbose: print('-' * 100) print('FT Summary:', summary_ft) if test_hf: print('HF Summary:', summary_hf) except: print('Error with datapoint : ', data_point_idx) print("推理耗时列表:", time_list) print("推理耗时列表大小:", len(time_list)) result = mean(time_list) print("均值:", round(result, 2)) print("最小值:", round(min(time_list), 2)) print("最大值:", round(max(time_list), 2)) print("TP50:", np.percentile(np.array(time_list), 50)) print("TP90:", np.percentile(np.array(time_list), 90)) print("TP99:", np.percentile(np.array(time_list), 99)) def compute_exact_match(tokens, n_tokens=[1, 10, 25, 50, 100, 150, 200, 250]): em_metrics = [] for t in n_tokens: errors = 0 total = 0 for ft_tokens, hf_tokens in tokens: if len(ft_tokens) > t and len(hf_tokens) > t: total = total + 1 if not np.array_equal(ft_tokens[:t], hf_tokens[:t]): errors = errors + 1 if total > 0: print(f"{t}-token exact match acc: {100*(1-errors/total):.2f}") em_metrics.append(1 - errors / total) else: em_metrics.append(np.nan) return em_metrics if rank == 0: if summarize: computed_metrics_ft = metric_ft.compute() if test_hf: computed_metrics_hf = metric_hf.compute() print(f'Hugging Face (total latency: {profiler.elapsed_time_in_sec("hf")} sec)') for key in computed_metrics_hf.keys(): print(f'{key} : {computed_metrics_hf[key]*100}') #print(f'{key} : {computed_metrics_hf[key].mid[2]*100}') print("------------") print(f'Faster Transformers (total latency: {profiler.elapsed_time_in_sec("ft")} sec)') for key in computed_metrics_ft.keys(): print(f'{key} : {computed_metrics_ft[key]*100}') #print(f'{key} : {computed_metrics_ft[key].mid[2]*100}') print("--------------!!!!") if args.rougeLsum_threshold is not None: assert computed_metrics_ft["rougeLsum"].mid[2]*100 >= args.rougeLsum_threshold, "[INFO] TEST FAIL !" print(f"[INFO] TEST PASS !") else: em_metrics = compute_exact_match(tokens) if args.verbose: profiler.summary() if __name__ == '__main__': main() ================================================ FILE: llm-inference/faster-transformer/megatron-gpt2/megatron-gpt2-fp8.md ================================================ ## A800-FP16 ``` python examples/pytorch/gpt/utils/megatron_ckpt_convert.py \ > -head_num 16 \ > -i /workspace/model/megatron-models/345m/release/ \ > -o /workspace/model/megatron-models/c-model/345m/ \ > -t_g 1 \ > -i_g 1 \ > --vocab-path /workspace/model/gpt2-vocab/gpt2-vocab.json \ > --merges-path /workspace/model/gpt2-vocab/gpt2-merges.txt =============== Argument =============== saved_dir: /workspace/model/megatron-models/c-model/345m/ in_file: /workspace/model/megatron-models/345m/release/ infer_gpu_num: 1 head_num: 16 trained_tensor_parallel_size: 1 processes: 16 weight_data_type: fp32 load_checkpoints_to_cpu: 1 vocab_path: /workspace/model/gpt2-vocab/gpt2-vocab.json merges_path: /workspace/model/gpt2-vocab/gpt2-merges.txt ======================================== [INFO] Spent 0:00:05.595219 (h:m:s) to convert the model ``` ``` python examples/pytorch/gpt/utils/update_gpt_config.py \ > --model-dir /workspace/model/megatron-models/c-model/345m/1-gpu \ > --config-ini-path /workspace/model/megatron-models/c-model/345m/1-gpu/config.ini \ --max-seq-len 512 \ > --pipeline-para-size 1 \ > --tensor-para-size 1 \ > --max-seq-len 512 \ > --beam-width 1 \ > --sampling-top-k 1 \ > --sampling-top-p 0 \ > --data-type fp16 ``` ``` > cat /workspace/model/megatron-models/c-model/345m/1-gpu/config.ini [ft_instance_hyperparameter] max_batch_size = 8 max_seq_len = 512 beam_width = 1 top_k = 1 top_p = 0.0 temperature = 1.0 tensor_para_size = 1 pipeline_para_size = 1 data_type = fp16 sparse = 0 int8_mode = 0 enable_custom_all_reduce = 0 model_name = gpt model_dir = /workspace/model/megatron-models/c-model/345m/1-gpu repetition_penalty = 1.0 len_penalty = 0.0 beam_search_diversity_rate = 0.0 [request] request_batch_size = 8 request_output_len = 32 return_log_probs = false context_log_probs = false beam_width = 1 top_k = 1 top_p = 0.0 temperature = 1.0 repetition_penalty = 1.0 len_penalty = 0.0 beam_search_diversity_rate = 0.0 [gpt] model_name = gpt head_num = 16 size_per_head = 64 inter_size = 4096 num_layer = 24 max_pos_seq_len = 1024 vocab_size = 50304 has_adapters = False adapter_inter_size = 0 layernorm_eps = 1e-06 start_id = 50256 end_id = 50256 weight_data_type = fp32 tensor_para_size = 1 ``` ``` python examples/pytorch/gpt/lambada_task_example.py \ > --batch-size 64 \ > --checkpoint-path /workspace/model/megatron-models/c-model/345m/1-gpu/ \ > --lib-path /workspace/lib/libth_transformer.so \ > --lambada-path /workspace/data/lambada_test.jsonl ============== Arguments =============== checkpoint_path: /workspace/model/megatron-models/c-model/345m/1-gpu/ lib_path: /workspace/lib/libth_transformer.so config_ini_path: None lambada_path: /workspace/data/lambada_test.jsonl output_path: None batch_size: 64 model_name: gpt pipeline_para_size: None data_type: None sparse: False int8_mode: None beam_width: None sampling_top_k: None sampling_top_p: None temperature: None len_penalty: None repetition_penalty: None beam_search_diversity_rate: None ======================================== =============== GPT params =============== head_num: 16 size_per_head: 64 layer_num: 24 max_seq_len: 1024 tensor_para_size: 1 vocab_size: 50304 start_id: 50256 end_id: 50256 pipeline_para_size: 1 weights_data_type: fp32 has_adapters: False adapter_inter_size: 0 data_type: fp16 int8_mode: 0 sparse: 0 layernorm_eps: 1e-06 layernorm_type: pre_layernorm activation_type: gelu has_positional_encoding: True has_pre_decoder_layernorm: False has_post_decoder_layernorm: True use_attention_linear_bias: False inter_size: 4096 lib_path: /workspace/lib/libth_transformer.so ======================================== ------------------ /workspace/lib/libth_transformer.so [WARNING] gemm_config.in is not found; using default GEMM algo [FT][WARNING] Skip NCCL initialization since requested tensor/pipeline parallel sizes are equals to 1. [FT][INFO] Device NVIDIA A800 80GB PCIe =========== Inference params =========== beam_width: 1 top_k: tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=torch.int32) top_p: tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) beam_search_diversity_rate: tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) temperature: tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]) len_penalty: tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) repetition_penalty: tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]) ======================================== [INFO] accuracy: 46.7775% (total : 962) ``` ## H800-FP32 ### 模型转换 ``` python examples/pytorch/gpt/utils/megatron_ckpt_convert.py \ -head_num 16 \ -i /workspace/model/megatron-models/345m/release/ \ -o /workspace/model/megatron-models/c-model-fp32 \ -t_g 1 \ -i_g 1 \ --vocab-path /workspace/model/gpt2-vocab/gpt2-vocab.json \ --merges-path /workspace/model/gpt2-vocab/gpt2-merges.txt ``` 运行结果: ``` =============== Argument =============== saved_dir: /workspace/model/megatron-models/c-model-fp32 in_file: /workspace/model/megatron-models/345m/release/ infer_gpu_num: 1 head_num: 16 trained_tensor_parallel_size: 1 processes: 16 weight_data_type: fp32 load_checkpoints_to_cpu: 1 vocab_path: /workspace/model/gpt2-vocab/gpt2-vocab.json merges_path: /workspace/model/gpt2-vocab/gpt2-merges.txt ======================================== [INFO] Spent 0:00:02.872906 (h:m:s) to convert the model ``` --- ``` python3 examples/pytorch/gpt/gpt_summarization_stat.py \ --data_type fp32 \ --lib_path /workspace/FasterTransformer/build/lib/libth_transformer.so \ --summarize \ --ft_model_location /workspace/model/megatron-models/c-model-fp32 \ --hf_model_location /workspace/model/gpt2-tokenizer/gpt2-tokenizer ``` 运行结果: ``` python3 examples/pytorch/gpt/gpt_summarization_stat.py \ > --data_type fp32 \ > --lib_path /workspace/FasterTransformer/build/lib/libth_transformer.so \ > --summarize \ > --ft_model_location /workspace/model/megatron-models/c-model-fp32 \ > --hf_model_location /workspace/model/gpt2-tokenizer/gpt2-tokenizer ~~~~~~~~~~~~~ args.summarize: True , args.test_hf: False Found cached dataset cnn_dailymail (/workspace/data/ccdv-data/ccdv/cnn_dailymail/3.0.0/3.0.0/0107f7388b5c6fae455a5661bcd134fc22da53ea75852027040d8d1e997f101f) 100%|██████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<00:00, 281.70it/s] top_k: 2 top_p: 0.0 int8_mode: 0 random_seed: 5 temperature: 1 max_seq_len: 1024 max_batch_size: 1 repetition_penalty: 1 vocab_size: 50304 tensor_para_size: 1 pipeline_para_size: 1 lib_path: /workspace/FasterTransformer/build/lib/libth_transformer.so ckpt_path: /workspace/model/megatron-models/c-model-fp32/1-gpu hf_config: {'activation_function': 'gelu_new', 'architectures': ['GPT2LMHeadModel'], 'attn_pdrop': 0.1, 'bos_token_id': 50256, 'embd_pdrop': 0.1, 'eos_token_id': 50256, 'initializer_range': 0.02, 'layer_norm_epsilon': 1e-05, 'model_type': 'gpt2', 'n_ctx': 1024, 'n_embd': 768, 'n_head': 12, 'n_layer': 12, 'n_positions': 1024, 'resid_pdrop': 0.1, 'summary_activation': None, 'summary_first_dropout': 0.1, 'summary_proj_to_labels': True, 'summary_type': 'cls_index', 'summary_use_proj': True, 'task_specific_params': {'text-generation': {'do_sample': True, 'max_length': 50}}, 'vocab_size': 50257} ----------------wpe 1024 1024 [WARNING] gemm_config.in is not found; using default GEMM algo [FT][WARNING] Skip NCCL initialization since requested tensor/pipeline parallel sizes are equals to 1. [FT][INFO] Device NVIDIA H800 ----------args.use_gpt_decoder_ops: False --------------------------------------------------------- FT Generated : Article : (CNN)James Best, best known for his portrayal of bumbling sheriff Rosco P. Coltrane on TV's "The Dukes of Hazzard," died Monday after a brief illness. He was 88. Best died in hospice in Hickory, North Carolina, of complications from pneumonia, said Steve Latshaw, a longtime friend and Hollywood colleague. Although he'd been a busy actor for decades in theater and in Hollywood, Best didn't become famous until 1979, when "The Dukes of Hazzard's" cornpone charms began beaming into millions of American homes almost every Friday night. For seven seasons, Best's Rosco P. Coltrane chased the moonshine-running Duke boys back and forth across the back roads of fictitious Hazzard County, Georgia, although his "hot pursuit" usually ended with him crashing his patrol car. Although Rosco was slow-witted and corrupt, Best gave him a childlike enthusiasm that got laughs and made him endearing. His character became known for his distinctive "kew-kew-kew" chuckle and for goofy catchphrases such as "cuff 'em and stuff 'em!" upon making an arrest. Among the most popular shows on TV in the early '80s, "The Dukes of Hazzard" ran until 1985 and spawned TV movies, an animated series and video games. Several of Best's "Hazzard" co-stars paid tribute to the late actor on social media. "I laughed and learned more from Jimmie in one hour than from anyone else in a whole year," co-star John Schneider, who played Bo Duke, said on Twitter. "Give Uncle Jesse my love when you see him dear friend." "Jimmy Best was the most constantly creative person I have ever known," said Ben Jones, who played mechanic Cooter on the show, in a Facebook post. "Every minute of his long life was spent acting, writing, producing, painting, teaching, fishing, or involved in another of his life's many passions." Born Jewel Guy on July 26, 1926, in Powderly, Kentucky, Best was orphaned at 3 and adopted by Armen and Essa Best, who renamed him James and raised him in rural Indiana. Best served in the Army during World War II before launching his acting career. In the 1950s and 1960s, he accumulated scores of credits, playing a range of colorful supporting characters in such TV shows as "The Twilight Zone," "Bonanza," "The Andy Griffith Show" and "Gunsmoke." He later appeared in a handful of Burt Reynolds' movies, including "Hooper" and "The End." But Best will always be best known for his "Hazzard" role, which lives on in reruns. "Jimmie was my teacher, mentor, close friend and collaborator for 26 years," Latshaw said. "I directed two of his feature films, including the recent 'Return of the Killer Shrews,' a sequel he co-wrote and was quite proud of as he had made the first one more than 50 years earlier." People we've lost in 2015 . CNN's Stella Chan contributed to this story. Highlights : James Best, who played the sheriff on "The Dukes of Hazzard," died Monday at 88 . "Hazzard" ran from 1979 to 1985 and was among the most popular shows on TV . Summary : Best was a great actor and an even better friend. <|endoftext|>. --------------------------------------------------------- Using the latest cached version of the module from /root/.cache/huggingface/modules/evaluate_modules/metrics/evaluate-metric--rouge/b01e0accf3bd6dd24839b769a5fda24e14995071570870922c71970b3a6ed886 (last modified on Thu Jun 29 16:31:01 2023) since it couldn't be found locally at evaluate-metric--rouge, or remotely on the Hugging Face Hub. 0%| | 0/21 [00:00 --lib_path /workspace/FasterTransformer/build/lib/libth_transformer.so \ > --data_type fp16 \ > --lib_path /workspace/FasterTransformer/build/lib/libth_transformer.so \ > --summarize \ > --ft_model_location /workspace/model/megatron-models/c-model-fp32 \ > --hf_model_location /workspace/model/gpt2-tokenizer/gpt2-tokenizer ~~~~~~~~~~~~~ args.summarize: True , args.test_hf: False Found cached dataset cnn_dailymail (/workspace/data/ccdv-data/ccdv/cnn_dailymail/3.0.0/3.0.0/0107f7388b5c6fae455a5661bcd134fc22da53ea75852027040d8d1e997f101f) 100%|██████████████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<00:00, 278.88it/s] top_k: 2 top_p: 0.0 int8_mode: 0 random_seed: 5 temperature: 1 max_seq_len: 1024 max_batch_size: 1 repetition_penalty: 1 vocab_size: 50304 tensor_para_size: 1 pipeline_para_size: 1 lib_path: /workspace/FasterTransformer/build/lib/libth_transformer.so ckpt_path: /workspace/model/megatron-models/c-model-fp32/1-gpu hf_config: {'activation_function': 'gelu_new', 'architectures': ['GPT2LMHeadModel'], 'attn_pdrop': 0.1, 'bos_token_id': 50256, 'embd_pdrop': 0.1, 'eos_token_id': 50256, 'initializer_range': 0.02, 'layer_norm_epsilon': 1e-05, 'model_type': 'gpt2', 'n_ctx': 1024, 'n_embd': 768, 'n_head': 12, 'n_layer': 12, 'n_positions': 1024, 'resid_pdrop': 0.1, 'summary_activation': None, 'summary_first_dropout': 0.1, 'summary_proj_to_labels': True, 'summary_type': 'cls_index', 'summary_use_proj': True, 'task_specific_params': {'text-generation': {'do_sample': True, 'max_length': 50}}, 'vocab_size': 50257} ----------------wpe 1024 1024 [WARNING] gemm_config.in is not found; using default GEMM algo [FT][WARNING] Skip NCCL initialization since requested tensor/pipeline parallel sizes are equals to 1. [FT][INFO] Device NVIDIA H800 ----------args.use_gpt_decoder_ops: False --------------------------------------------------------- FT Generated : Article : (CNN)James Best, best known for his portrayal of bumbling sheriff Rosco P. Coltrane on TV's "The Dukes of Hazzard," died Monday after a brief illness. He was 88. Best died in hospice in Hickory, North Carolina, of complications from pneumonia, said Steve Latshaw, a longtime friend and Hollywood colleague. Although he'd been a busy actor for decades in theater and in Hollywood, Best didn't become famous until 1979, when "The Dukes of Hazzard's" cornpone charms began beaming into millions of American homes almost every Friday night. For seven seasons, Best's Rosco P. Coltrane chased the moonshine-running Duke boys back and forth across the back roads of fictitious Hazzard County, Georgia, although his "hot pursuit" usually ended with him crashing his patrol car. Although Rosco was slow-witted and corrupt, Best gave him a childlike enthusiasm that got laughs and made him endearing. His character became known for his distinctive "kew-kew-kew" chuckle and for goofy catchphrases such as "cuff 'em and stuff 'em!" upon making an arrest. Among the most popular shows on TV in the early '80s, "The Dukes of Hazzard" ran until 1985 and spawned TV movies, an animated series and video games. Several of Best's "Hazzard" co-stars paid tribute to the late actor on social media. "I laughed and learned more from Jimmie in one hour than from anyone else in a whole year," co-star John Schneider, who played Bo Duke, said on Twitter. "Give Uncle Jesse my love when you see him dear friend." "Jimmy Best was the most constantly creative person I have ever known," said Ben Jones, who played mechanic Cooter on the show, in a Facebook post. "Every minute of his long life was spent acting, writing, producing, painting, teaching, fishing, or involved in another of his life's many passions." Born Jewel Guy on July 26, 1926, in Powderly, Kentucky, Best was orphaned at 3 and adopted by Armen and Essa Best, who renamed him James and raised him in rural Indiana. Best served in the Army during World War II before launching his acting career. In the 1950s and 1960s, he accumulated scores of credits, playing a range of colorful supporting characters in such TV shows as "The Twilight Zone," "Bonanza," "The Andy Griffith Show" and "Gunsmoke." He later appeared in a handful of Burt Reynolds' movies, including "Hooper" and "The End." But Best will always be best known for his "Hazzard" role, which lives on in reruns. "Jimmie was my teacher, mentor, close friend and collaborator for 26 years," Latshaw said. "I directed two of his feature films, including the recent 'Return of the Killer Shrews,' a sequel he co-wrote and was quite proud of as he had made the first one more than 50 years earlier." People we've lost in 2015 . CNN's Stella Chan contributed to this story. Highlights : James Best, who played the sheriff on "The Dukes of Hazzard," died Monday at 88 . "Hazzard" ran from 1979 to 1985 and was among the most popular shows on TV . Summary : Best was a great actor and an even better friend. <|endoftext|>. --------------------------------------------------------- Using the latest cached version of the module from /root/.cache/huggingface/modules/evaluate_modules/metrics/evaluate-metric--rouge/b01e0accf3bd6dd24839b769a5fda24e14995071570870922c71970b3a6ed886 (last modified on Thu Jun 29 16:31:01 2023) since it couldn't be found locally at evaluate-metric--rouge, or remotely on the Hugging Face Hub. Using the latest cached version of the module from /root/.cache/huggingface/modules/evaluate_modules/metrics/evaluate-metric--rouge/b01e0accf3bd6dd24839b769a5fda24e14995071570870922c71970b3a6ed886 (last modified on Thu Jun 29 16:31:01 2023) since it couldn't be found locally at evaluate-metric--rouge, or remotely on the Hugging Face Hub. 0%| | 0/21 [00:00 -i /workspace/model/megatron-models/345m/release \ > -o /workspace/model/megatron-models/c-model-fp8-linear/ \ > -trained_tensor_parallel_size 1 \ > -i_g 1 \ > -head_num 16 \ > -weight_data_type fp32 \ > --vocab-path /workspace/model/gpt2-vocab/gpt2-vocab.json \ > --merges-path /workspace/model/gpt2-vocab/gpt2-merges.txt =============== Argument =============== saved_dir: /workspace/model/megatron-models/c-model-fp8-linear/ in_file: /workspace/model/megatron-models/345m/release infer_gpu_num: 1 head_num: 16 trained_tensor_parallel_size: 1 processes: 16 weight_data_type: fp32 load_checkpoints_to_cpu: 1 vocab_path: /workspace/model/gpt2-vocab/gpt2-vocab.json merges_path: /workspace/model/gpt2-vocab/gpt2-merges.txt ======================================== [INFO] Spent 0:00:04.251986 (h:m:s) to convert the model ``` --- ``` python3 examples/pytorch/gpt/gpt_summarization.py \ > --data_type fp8 \ > --lib_path /workspace/FasterTransformer/build/lib/libth_transformer.so \ > --summarize \ > --ft_model_location /workspace/model/megatron-models/c-model-fp8/ \ > --hf_model_location /workspace/model/gpt2-tokenizer/gpt2-tokenizer Found cached dataset cnn_dailymail (/workspace/data/ccdv-data/ccdv/cnn_dailymail/3.0.0/3.0.0/0107f7388b5c6fae455a5661bcd134fc22da53ea75852027040d8d1e997f101f) 100%|█████████████████████████████████████████████████| 3/3 [00:00<00:00, 341.66it/s] top_k: 1 top_p: 0.0 int8_mode: 0 random_seed: 5 temperature: 1 max_seq_len: 1024 max_batch_size: 1 repetition_penalty: 1 vocab_size: 50304 tensor_para_size: 1 pipeline_para_size: 1 lib_path: /workspace/FasterTransformer/build/lib/libth_transformer.so ckpt_path: /workspace/model/megatron-models/c-model-fp8/1-gpu hf_config: {'activation_function': 'gelu_new', 'architectures': ['GPT2LMHeadModel'], 'attn_pdrop': 0.1, 'bos_token_id': 50256, 'embd_pdrop': 0.1, 'eos_token_id': 50256, 'initializer_range': 0.02, 'layer_norm_epsilon': 1e-05, 'model_type': 'gpt2', 'n_ctx': 1024, 'n_embd': 768, 'n_head': 12, 'n_layer': 12, 'n_positions': 1024, 'resid_pdrop': 0.1, 'summary_activation': None, 'summary_first_dropout': 0.1, 'summary_proj_to_labels': True, 'summary_type': 'cls_index', 'summary_use_proj': True, 'task_specific_params': {'text-generation': {'do_sample': True, 'max_length': 50}}, 'vocab_size': 50257} [FT][WARNING] Skip NCCL initialization since requested tensor/pipeline parallel sizes are equals to 1. [WARNING] gemm_config.in is not found; using default GEMM algo [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.0.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.1.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.2.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.3.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.4.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.5.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.6.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.7.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.8.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.9.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.10.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.11.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.12.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.13.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.14.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.15.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.16.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.17.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.18.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.19.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.20.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.21.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.22.attention.softmax.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.attention.query_key_value.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.attention.query_key_value.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.attention.query_key_value.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.attention.dense.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.attention.dense.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.attention.dense.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.mlp.dense_h_to_4h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.mlp.dense_h_to_4h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.mlp.dense_h_to_4h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.mlp.dense_4h_to_h.fp_linear.fi.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.mlp.dense_4h_to_h.fp_linear.fo.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.mlp.dense_4h_to_h.fp_linear.fw.bin, use identity scales. [FT][WARNING] Cannot find /workspace/model/megatron-models/c-model-fp8/1-gpu/model.layers.23.attention.softmax.fo.bin, use identity scales. --------------------------------------------------------- FT Generated : Article : (CNN)James Best, best known for his portrayal of bumbling sheriff Rosco P. Coltrane on TV's "The Dukes of Hazzard," died Monday after a brief illness. He was 88. Best died in hospice in Hickory, North Carolina, of complications from pneumonia, said Steve Latshaw, a longtime friend and Hollywood colleague. Although he'd been a busy actor for decades in theater and in Hollywood, Best didn't become famous until 1979, when "The Dukes of Hazzard's" cornpone charms began beaming into millions of American homes almost every Friday night. For seven seasons, Best's Rosco P. Coltrane chased the moonshine-running Duke boys back and forth across the back roads of fictitious Hazzard County, Georgia, although his "hot pursuit" usually ended with him crashing his patrol car. Although Rosco was slow-witted and corrupt, Best gave him a childlike enthusiasm that got laughs and made him endearing. His character became known for his distinctive "kew-kew-kew" chuckle and for goofy catchphrases such as "cuff 'em and stuff 'em!" upon making an arrest. Among the most popular shows on TV in the early '80s, "The Dukes of Hazzard" ran until 1985 and spawned TV movies, an animated series and video games. Several of Best's "Hazzard" co-stars paid tribute to the late actor on social media. "I laughed and learned more from Jimmie in one hour than from anyone else in a whole year," co-star John Schneider, who played Bo Duke, said on Twitter. "Give Uncle Jesse my love when you see him dear friend." "Jimmy Best was the most constantly creative person I have ever known," said Ben Jones, who played mechanic Cooter on the show, in a Facebook post. "Every minute of his long life was spent acting, writing, producing, painting, teaching, fishing, or involved in another of his life's many passions." Born Jewel Guy on July 26, 1926, in Powderly, Kentucky, Best was orphaned at 3 and adopted by Armen and Essa Best, who renamed him James and raised him in rural Indiana. Best served in the Army during World War II before launching his acting career. In the 1950s and 1960s, he accumulated scores of credits, playing a range of colorful supporting characters in such TV shows as "The Twilight Zone," "Bonanza," "The Andy Griffith Show" and "Gunsmoke." He later appeared in a handful of Burt Reynolds' movies, including "Hooper" and "The End." But Best will always be best known for his "Hazzard" role, which lives on in reruns. "Jimmie was my teacher, mentor, close friend and collaborator for 26 years," Latshaw said. "I directed two of his feature films, including the recent 'Return of the Killer Shrews,' a sequel he co-wrote and was quite proud of as he had made the first one more than 50 years earlier." People we've lost in 2015 . CNN's Stella Chan contributed to this story. Highlights : James Best, who played the sheriff on "The Dukes of Hazzard," died Monday at 88 . "Hazzard" ran from 1979 to 1985 and was among the most popular shows on TV . Summary : Best was a great actor, a great man and a great friend. <|endoftext|>. --------------------------------------------------------- Using the latest cached version of the module from /root/.cache/huggingface/modules/evaluate_modules/metrics/evaluate-metric--rouge/b01e0accf3bd6dd24839b769a5fda24e14995071570870922c71970b3a6ed886 (last modified on Thu Jun 29 16:31:01 2023) since it couldn't be found locally at evaluate-metric--rouge, or remotely on the Hugging Face Hub. Using the latest cached version of the module from /root/.cache/huggingface/modules/evaluate_modules/metrics/evaluate-metric--rouge/b01e0accf3bd6dd24839b769a5fda24e14995071570870922c71970b3a6ed886 (last modified on Thu Jun 29 16:31:01 2023) since it couldn't be found locally at evaluate-metric--rouge, or remotely on the Hugging Face Hub. 100%|████████████████████████████████████████████████| 21/21 [00:05<00:00, 3.53it/s] Faster Transformers (total latency: 5.933964252471924 sec) rouge1 : 23.118179986254233 --------------!!!! rouge2 : 6.97354358694703 --------------!!!! rougeL : 17.215690960077605 --------------!!!! rougeLsum : 20.63874458392057 --------------!!!! ``` ================================================ FILE: llm-inference/flexflow-serve/benchmark-batch1.py ================================================ import json import flexflow.serve as ff import torch from transformers import LlamaTokenizer import time from statistics import mean import numpy as np input_data_path = "/workspace/data/alpaca_data.json" llm_path = "/workspace/model/llama-7b-hf" ssm_path = "/workspace/model/llama-68m" list_data_dict = json.load(open(input_data_path, "r")) prompts = [] i = 0 for temp in list_data_dict: prompts.append(temp) i+=1 if i==10000: break ff.init( num_gpus=1, memory_per_gpu=40000, zero_copy_memory_per_node=30000, tensor_parallelism_degree=1, pipeline_parallelism_degree=1 ) # Specify the LLM llm = ff.LLM(llm_path) # Specify a list of SSMs (just one in this case) ssms=[] ssm = ff.SSM(ssm_path) ssms.append(ssm) # Create the sampling configs generation_config = ff.GenerationConfig( do_sample=False, temperature=0.9, topp=0.8, topk=1 ) # Compile the SSMs for inference and load the weights into memory for ssm in ssms: ssm.compile(generation_config) # Compile the LLM for inference and load the weights into memory llm.compile(generation_config, ssms=ssms) gen_token_list = [] gen_time_list = [] error_input_list = [] for i in range(len(prompts)): prompt = prompts[i] print("-----------------------------------------------", i , "-----",prompt) input_prompt = prompt["instruction"]+"\n" tokenizer = LlamaTokenizer.from_pretrained(llm_path, torch_dtype=torch.float16) input_token_len = len(tokenizer(input_prompt).input_ids) try: start = time.perf_counter() llm_result = llm.generate([input_prompt]) end = time.perf_counter() output_token_len = len(llm_result[0].output_tokens) gen_token_len = output_token_len - input_token_len gen_time = (end - start)*1000 except: error_input_list.append(input_prompt) continue if gen_token_len > 0: gen_token_list.append(gen_token_len) gen_time_list.append(gen_time) else: error_input_list.append(input_prompt) print("错误输入列表:", error_input_list) print("均值:", round(mean(gen_time_list), 2)) print("最小值:", round(min(gen_time_list), 2)) print("最大值:", round(max(gen_time_list), 2)) print("TP50:", np.percentile(np.array(gen_time_list), 50)) print("TP90:", np.percentile(np.array(gen_time_list), 90)) print("TP99:", np.percentile(np.array(gen_time_list), 99)) token_num_pre_second = round((sum(gen_token_list) / sum(gen_time_list)) * 1000 , 3) time_pre_token = round(sum(gen_time_list) / sum(gen_token_list), 2) print("每秒生成的Token数:", token_num_pre_second) print("每个Token生成的平均耗时(ms):", time_pre_token) print("生成Token长度均值:", round(mean(gen_token_list), 2)) print("TOKEN 最小值:", min(gen_token_list)) print("TOKEN 最大值:", max(gen_token_list)) ================================================ FILE: llm-inference/huggingface-tgi/README.md ================================================ - https://github.com/huggingface/text-generation-inference ================================================ FILE: llm-inference/huggingface-transformer/README.md ================================================ - https://huggingface.co/blog/how-to-generate - https://huggingface.co/blog/zh/how-to-generate ================================================ FILE: llm-inference/lightllm/README.md ================================================ https://github.com/ModelTC/lightllm https://github.com/ModelTC/lightllm/blob/main/docs/LightLLM.md - lightllm代码解读——显存管理机制:https://zhuanlan.zhihu.com/p/667730434 - lightllm代码解读——之模型推理:https://zhuanlan.zhihu.com/p/666731524 - https://github.com/ModelTC/lightllm/tree/main - LightLLM:纯Python超轻量高性能LLM推理框架: https://mp.weixin.qq.com/s/-wMLMGAHkxeyDYkixqni9Q ================================================ FILE: llm-inference/lmdeploy/README.md ================================================ - https://hub.docker.com/r/openmmlab/lmdeploy-builder/tags - https://hub.docker.com/r/openmmlab/lmdeploy/tags - https://github.com/InternLM/lmdeploy/blob/main/docs/zh_cn/serving/api_server.md - https://github.com/InternLM/lmdeploy/blob/main/lmdeploy/cli/utils.py#L64 请求队列 - 推理请求首先先加入到请求队列中 Persistent线程 1. 若批处理中有空闲槽位,从队列拉取请求,尽量填满空闲槽位。若无,继续对当前批处理中的请求进行Forward 2. 批次每Forward完一次 - 判断是否有请求推理结束。结束的请求,发送结果,释放槽位 - 转步骤1 ================================================ FILE: llm-inference/lmdeploy/功能.md ================================================ https://lmdeploy.readthedocs.io/en/latest/inference/turbomind_config.html ## prefix caching switch ## kv quantization and inference switch ## long context switch ================================================ FILE: llm-inference/lmdeploy/服务启动参数.md ================================================ ``` usage: lmdeploy serve api_server [-h] [--server-name SERVER_NAME] [--server-port SERVER_PORT] [--allow-origins ALLOW_ORIGINS [ALLOW_ORIGINS ...]] [--allow-credentials] [--allow-methods ALLOW_METHODS [ALLOW_METHODS ...]] [--allow-headers ALLOW_HEADERS [ALLOW_HEADERS ...]] [--proxy-url PROXY_URL] [--backend {pytorch,turbomind}] [--log-level {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}] [--api-keys [API_KEYS ...]] [--ssl] [--model-name MODEL_NAME] [--max-log-len MAX_LOG_LEN] [--disable-fastapi-docs] [--chat-template CHAT_TEMPLATE] [--revision REVISION] [--download-dir DOWNLOAD_DIR] [--adapters [ADAPTERS ...]] [--device {cuda,ascend,maca}] [--eager-mode] [--dtype {auto,float16,bfloat16}] [--tp TP] [--session-len SESSION_LEN] [--max-batch-size MAX_BATCH_SIZE] [--cache-max-entry-count CACHE_MAX_ENTRY_COUNT] [--cache-block-seq-len CACHE_BLOCK_SEQ_LEN] [--enable-prefix-caching] [--max-prefill-token-num MAX_PREFILL_TOKEN_NUM] [--quant-policy {0,4,8}] [--model-format {hf,llama,awq,gptq}] [--rope-scaling-factor ROPE_SCALING_FACTOR] [--num-tokens-per-iter NUM_TOKENS_PER_ITER] [--max-prefill-iters MAX_PREFILL_ITERS] [--vision-max-batch-size VISION_MAX_BATCH_SIZE] model_path Serve LLMs with restful api using fastapi. positional arguments: model_path The path of a model. it could be one of the following options: - i) a local directory path of a turbomind model which is converted by `lmdeploy convert` command or download from ii) and iii). - ii) the model_id of a lmdeploy-quantized model hosted inside a model repo on huggingface.co, such as "internlm/internlm-chat-20b-4bit", "lmdeploy/llama2-chat-70b-4bit", etc. - iii) the model_id of a model hosted inside a model repo on huggingface.co, such as "internlm/internlm-chat-7b", "qwen/qwen-7b-chat ", "baichuan-inc/baichuan2-7b-chat" and so on. Type: str options: -h, --help show this help message and exit --server-name SERVER_NAME Host ip for serving. Default: 0.0.0.0. Type: str --server-port SERVER_PORT Server port. Default: 23333. Type: int --allow-origins ALLOW_ORIGINS [ALLOW_ORIGINS ...] A list of allowed origins for cors. Default: ['*']. Type: str --allow-credentials Whether to allow credentials for cors. Default: False --allow-methods ALLOW_METHODS [ALLOW_METHODS ...] A list of allowed http methods for cors. Default: ['*']. Type: str --allow-headers ALLOW_HEADERS [ALLOW_HEADERS ...] A list of allowed http headers for cors. Default: ['*']. Type: str --proxy-url PROXY_URL The proxy url for api server.. Default: None. Type: str --backend {pytorch,turbomind} Set the inference backend. Default: turbomind. Type: str --log-level {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET} Set the log level. Default: ERROR. Type: str --api-keys [API_KEYS ...] Optional list of space separated API keys. Default: None. Type: str --ssl Enable SSL. Requires OS Environment variables 'SSL_KEYFILE' and 'SSL_CERTFILE'. Default: False --model-name MODEL_NAME The name of the served model. It can be accessed by the RESTful API `/v1/models`. If it is not specified, `model_path` will be adopted. Default: None. Type: str --max-log-len MAX_LOG_LEN Max number of prompt characters or prompt tokens beingprinted in log. Default: Unlimited. Type: int --disable-fastapi-docs Disable FastAPI's OpenAPI schema, Swagger UI, and ReDoc endpoint. Default: False --chat-template CHAT_TEMPLATE A JSON file or string that specifies the chat template configuration. Please refer to https://lmdeploy.readthedocs.io/en/latest/advance/chat_template.html for the specification. Default: None. Type: str --revision REVISION The specific model version to use. It can be a branch name, a tag name, or a commit id. If unspecified, will use the default version.. Type: str --download-dir DOWNLOAD_DIR Directory to download and load the weights, default to the default cache directory of huggingface.. Type: str PyTorch engine arguments: --adapters [ADAPTERS ...] Used to set path(s) of lora adapter(s). One can input key-value pairs in xxx=yyy format for multiple lora adapters. If only have one adapter, one can only input the path of the adapter.. Default: None. Type: str --device {cuda,ascend,maca} The device type of running. Default: cuda. Type: str --eager-mode Whether to enable eager mode. If True, cuda graph would be disabled. Default: False --dtype {auto,float16,bfloat16} data type for model weights and activations. The "auto" option will use FP16 precision for FP32 and FP16 models, and BF16 precision for BF16 models. This option will be ignored if the model is a quantized model. Default: auto. Type: str --tp TP GPU number used in tensor parallelism. Should be 2^n. Default: 1. Type: int --session-len SESSION_LEN The max session length of a sequence. Default: None. Type: int --max-batch-size MAX_BATCH_SIZE Maximum batch size. If not specified, the engine will automatically set it according to the device. Default: None. Type: int --cache-max-entry-count CACHE_MAX_ENTRY_COUNT The percentage of free gpu memory occupied by the k/v cache, excluding weights . Default: 0.8. Type: float --cache-block-seq-len CACHE_BLOCK_SEQ_LEN The length of the token sequence in a k/v block. For Turbomind Engine, if the GPU compute capability is >= 8.0, it should be a multiple of 32, otherwise it should be a multiple of 64. For Pytorch Engine, if Lora Adapter is specified, this parameter will be ignored. Default: 64. Type: int --enable-prefix-caching Enable cache and match prefix. Default: False --max-prefill-token-num MAX_PREFILL_TOKEN_NUM the max number of tokens per iteration during prefill. Default: 8192. Type: int --quant-policy {0,4,8} Quantize kv or not. 0: no quant; 4: 4bit kv; 8: 8bit kv. Default: 0. Type: int TurboMind engine arguments: --dtype {auto,float16,bfloat16} data type for model weights and activations. The "auto" option will use FP16 precision for FP32 and FP16 models, and BF16 precision for BF16 models. This option will be ignored if the model is a quantized model. Default: auto. Type: str --tp TP GPU number used in tensor parallelism. Should be 2^n. Default: 1. Type: int --session-len SESSION_LEN The max session length of a sequence. Default: None. Type: int --max-batch-size MAX_BATCH_SIZE Maximum batch size. If not specified, the engine will automatically set it according to the device. Default: None. Type: int --cache-max-entry-count CACHE_MAX_ENTRY_COUNT The percentage of free gpu memory occupied by the k/v cache, excluding weights . Default: 0.8. Type: float --cache-block-seq-len CACHE_BLOCK_SEQ_LEN The length of the token sequence in a k/v block. For Turbomind Engine, if the GPU compute capability is >= 8.0, it should be a multiple of 32, otherwise it should be a multiple of 64. For Pytorch Engine, if Lora Adapter is specified, this parameter will be ignored. Default: 64. Type: int --enable-prefix-caching Enable cache and match prefix. Default: False --max-prefill-token-num MAX_PREFILL_TOKEN_NUM the max number of tokens per iteration during prefill. Default: 8192. Type: int --quant-policy {0,4,8} Quantize kv or not. 0: no quant; 4: 4bit kv; 8: 8bit kv. Default: 0. Type: int --model-format {hf,llama,awq,gptq} The format of input model. `hf` means `hf_llama`, `llama` means `meta_llama`, `awq` represents the quantized model by AWQ, and `gptq` refers to the quantized model by GPTQ. Default: None. Type: str --rope-scaling-factor ROPE_SCALING_FACTOR Rope scaling factor. Default: 0.0. Type: float --num-tokens-per-iter NUM_TOKENS_PER_ITER the number of tokens processed in a forward pass. Default: 0. Type: int --max-prefill-iters MAX_PREFILL_ITERS the max number of forward passes in prefill stage. Default: 1. Type: int Vision model arguments: --vision-max-batch-size VISION_MAX_BATCH_SIZE the vision model batch size. Default: 1. Type: int ``` # PyTorch 引擎参数 ## --eager-mode 是否启用 Eager 模式。如果为 True,cuda graph 将被禁用。默认值:False # TurboMind 引擎参数 ## --session-len 一个序列的最大会话长度。默认值:无。类型:整数。 ## --max-batch-size 最大批量大小。如果不指定,引擎会根据设备自动设置。默认值:无。 ## --cache-max-entry-count k/v 缓存占用的空闲 GPU 内存百分比,不包括权重。默认值:0.8。 ## --cache-block-seq-len k/v 块中token序列的长度。对于 Turbomind Engine,如果 GPU 计算能力 >= 8.0,则应为 32 的倍数,否则应为 64 的倍数。对于 Pytorch Engine,如果指定了 Lora Adapter,则该参数将被忽略。默认值:64。 ## --enable-prefix-caching ## --max-prefill-token-num 预填充过程中每轮迭代的最大token数。默认值:8192。 ## --num-tokens-per-iter 一次前向传递中处理的token数量。默认值:0。 使用 max_prefill_iters 可以实现类似“动态 SplitFuse”的调度。 ## --max-prefill-iters 预填充阶段的最大前向传递次数。默认值:1。 ## --rope-scaling-factor Rope缩放因子。默认值:0.0。类型: 浮点数 默认 rope_scaling_factor = 0 不具备外推能力。设置为 1.0,可以开启 RoPE 的 Dynamic NTK 功能,支持长文本推理。 ## cache_chunk_size cache_chunk_size 表示在每次需要新的 k/v cache 块时,开辟 k/v cache 块的大小。默认值为-1 ,不同的取值,表示不同的含义: 当为 > 0 的整数时,开辟 cache_chunk_size 个 k/v cache 块 当值为 -1 时,开辟 cache_max_entry_count 个 k/v cache 块 当值为 0 时,时,开辟 sqrt(cache_max_entry_count) 个 k/v cache 块 ================================================ FILE: llm-inference/native-model/chatglm3-6b/cli_demo.py ================================================ import os import platform from transformers import AutoTokenizer, AutoModel MODEL_PATH = os.environ.get('MODEL_PATH', 'THUDM/chatglm3-6b') TOKENIZER_PATH = os.environ.get("TOKENIZER_PATH", MODEL_PATH) tokenizer = AutoTokenizer.from_pretrained(TOKENIZER_PATH, trust_remote_code=True) model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True, device_map="auto").eval() os_name = platform.system() clear_command = 'cls' if os_name == 'Windows' else 'clear' stop_stream = False welcome_prompt = "欢迎使用 ChatGLM3-6B 模型,输入内容即可进行对话,clear 清空对话历史,stop 终止程序" def build_prompt(history): prompt = welcome_prompt for query, response in history: prompt += f"\n\n用户:{query}" prompt += f"\n\nChatGLM3-6B:{response}" return prompt def main(): past_key_values, history = None, [] global stop_stream print(welcome_prompt) while True: query = input("\n用户:") if query.strip() == "stop": break if query.strip() == "clear": past_key_values, history = None, [] os.system(clear_command) print(welcome_prompt) continue print("\nChatGLM:", end="") current_length = 0 for response, history, past_key_values in model.stream_chat(tokenizer, query, history=history, top_p=1, temperature=0.01, past_key_values=past_key_values, return_past_key_values=True): if stop_stream: stop_stream = False break else: print(response[current_length:], end="", flush=True) current_length = len(response) print("") if __name__ == "__main__": main() ================================================ FILE: llm-inference/offload.md ================================================ - https://huggingface.co/docs/accelerate/concept_guides/big_model_inference - https://huggingface.co/docs/transformers/big_models - Efficient and Economic Large Language Model Inference with Attention Offloading - https://arxiv.org/pdf/2405.01814 - DeepSpeed Inference: Enabling Efficient Inference of Transformer Models at Unprecedented Scale - https://arxiv.org/pdf/2207.00032 FlexFlow - https://github.com/flexflow/FlexFlow FlexGen - https://github.com/FMInference/FlexGen kv cache offload: - https://github.com/NVIDIA/TensorRT-LLM/blob/a96cccafcf6365c128f004f779160951f8c0801c/docs/source/kv_cache_reuse.md ================================================ FILE: llm-inference/openai.md ================================================ AsyncOpenAI: ConnectionError 问题: - https://github.com/openai/openai-python/issues/ ================================================ FILE: llm-inference/sglang/README.md ================================================ - [SGLang 后端代码解析](https://github.com/zhaochenyang20/Awesome-ML-SYS-Tutorial/blob/main/sglang/code-walk-through/readme-CN.md) - Qwen3 think模型 关闭 think:https://qwen.readthedocs.io/zh-cn/latest/deployment/sglang.html ## 量化 https://docs.sglang.ai/backend/quantization.html ## 镜像 - https://github.com/sgl-project/sglang/blob/072df753546b77438479f18a05e691fad91d7f9c/.github/workflows/release-docker.yml#L60 - https://github.com/sgl-project/sglang/blob/main/docker/Dockerfile - https://hub.docker.com/r/lmsysorg/sglang/tags ``` docker build . -f docker/Dockerfile --build-arg CUDA_VERSION=${{ matrix.cuda_version }} --build-arg BUILD_TYPE=${{ matrix.build_type }} -t lmsysorg/sglang:${tag}${tag_suffix} --no-cache docker push lmsysorg/sglang:${tag}${tag_suffix} ``` - docker pull lmsysorg/sglang:v0.4.5-cu125 ## 文档 - SGLang 学习材料:https://github.com/sgl-project/sgl-learning-materials - Fast and Expressive LLM Inference with RadixAttention and SGLang:https://lmsys.org/blog/2024-01-17-sglang/ - Achieving Faster Open-Source Llama3 Serving with SGLang Runtime (vs. TensorRT-LLM, vLLM):https://lmsys.org/blog/2024-07-25-sglang-llama3/ - SGLang v0.3 Release: 7x Faster DeepSeek MLA, 1.5x Faster torch.compile, Multi-Image/Video LLaVA-OneVision:https://lmsys.org/blog/2024-09-04-sglang-v0-3/ - SGLang v0.4: Zero-Overhead Batch Scheduler, Cache-Aware Load Balancer, Faster Structured Outputs:https://lmsys.org/blog/2024-12-04-sglang-v0-4/ ================================================ FILE: llm-inference/sglang/source-code.md ================================================ - 参考:https://blog.csdn.net/sdujava2011/article/details/138312278 ######## git clone git@github.com:liguodongiot/sglang.git git remote add upstream https://github.com/sgl-project/sglang.git # 拉取原始仓库数据 git fetch upstream --tags # 如果你的主分支不是叫master,就把前面的master换成你的名字,比如main之类 git rebase upstream/main # 推送 git push # 推送tags git push --tags ######## # 查看所有tag git tag # 4. 检出指定的 tag 到新分支 # 替换 'tag_name' 为你想要的 tag 名称 git checkout -b dev-code-0.4.1 0.4.1 # 将新分支推送到远程仓库 git push -u origin dev-code-0.4.1 ================================================ FILE: llm-inference/sglang/服务器启动参数.md ================================================ - dtype:模型使用的数据类型,默认为 bfloat16。 ["auto", "half", "float16", "bfloat16", "float", "float32"] "Data type for model weights and activations.\n\n" '* "auto" will use FP16 precision for FP32 and FP16 models, and ' "BF16 precision for BF16 models.\n" '* "half" for FP16. Recommended for AWQ quantization.\n' '* "float16" is the same as "half".\n' '* "bfloat16" for a balance between precision and range.\n' '* "float" is shorthand for FP32 precision.\n' '* "float32" for FP32 precision. - 参考:_get_and_verify_dtype - kv_cache_dtype: kv 缓存的数据类型,默认为 dtype。 ["auto", "fp8_e5m2", "fp8_e4m3"], 'Data type for kv cache storage. "auto" will use model data type. "fp8_e5m2" and "fp8_e4m3" is supported for CUDA 11.8+.', fp8_e4m3 需要提供 quantization_param_path, 默认 scaling factors 为 1.0,会影响精度。 - schedule_policy lpm dfs-weight fcfs - 默认 lof random ``` model_path=/workspace/outputs/Qwen2.5-32B-Instruct-FP8-PER-TENSOR dataset_path=/workspace/data/ShareGPT_V3_unfiltered_cleaned_split.json CUDA_VISIBLE_DEVICES=6 python3 -m sglang.bench_offline_throughput \ --model-path ${model_path} \ --dataset-name random \ --random-input 2048 \ --random-output 1024 \ --random-range-ratio 1 \ --dataset-path ${dataset_path} \ --num-prompts 1000 \ --mem-fraction-static 0.9 \ --kv-cache-dtype fp8_e5m2 \ --max-running-requests 48 \ --chunked-prefill-size 8192 --schedule-policy lpm ``` --enable-torch-compile ## AttentionBackend 两批次重叠(TBO),将单个批次分为两个微批次,允许计算和通信重叠,同时通过将有效批次大小减半来降低峰值内存使用。 ================================================ FILE: llm-inference/sglang/项目代码结构.md ================================================ ================================================ FILE: llm-inference/tensorrt/README.md ================================================ 镜像: - https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch python tar包安装: - https://docs.nvidia.com/deeplearning/tensorrt/quick-start-guide/index.html#installing-pip - https://docs.nvidia.com/deeplearning/tensorrt/install-guide/index.html#installing-tar - TensorRT: https://github.com/NVIDIA/TensorRT - Torch-TensorRT: https://github.com/pytorch/TensorRT ================================================ FILE: llm-inference/tensorrt/install.md ================================================ ``` cd /home/guodong.li/virtual-venv virtualenv -p /usr/bin/python3.10 model-inference-venv-py310-cu117 source /home/guodong.li/virtual-venv/model-inference-venv-py310-cu117/bin/activate pip install torch version="8.6.1.6" arch=$(uname -m) cuda="cuda-11.8" tar -xzvf TensorRT-${version}.Linux.${arch}-gnu.${cuda}.tar.gz export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: cd TensorRT-${version}/python python3 -m pip install tensorrt-*-cp310-none-linux_x86_64.whl python3 -m pip install tensorrt_lean-*-cp310-none-linux_x86_64.whl python3 -m pip install tensorrt_dispatch-*-cp310-none-linux_x86_64.whl python3 -m pip install uff-0.6.9-py2.py3-none-any.whl which convert-to-uff --- cd TensorRT-${version}/graphsurgeon python3 -m pip install graphsurgeon-0.4.6-py2.py3-none-any.whl --- cd TensorRT-${version}/onnx_graphsurgeon python3 -m pip install onnx_graphsurgeon-0.3.12-py2.py3-none-any.whl export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/guodong.li/TensorRT-8.6.1.6/lib python3 >>> import tensorrt >>> print(tensorrt.__version__) >>> assert tensorrt.Builder(tensorrt.Logger()) Use a similar procedure to verify that the lean and dispatch modules work as expected: python3 >>> import tensorrt_lean as trt >>> print(trt.__version__) >>> assert trt.Builder(trt.Logger()) python3 >>> import tensorrt_dispatch as trt >>> print(trt.__version__) >>> assert trt.Builder(trt.Logger()) pip install torch_tensorrt ``` ================================================ FILE: llm-inference/tensorrt-llm/FP8.md ================================================ - https://nvidia.github.io/TensorRT-LLM/reference/precision.html#fp8-hopper - https://nvidia.github.io/TensorRT-Model-Optimizer/ ================================================ FILE: llm-inference/tensorrt-llm/Memory Usage of TensorRT-LLM.md ================================================ - https://nvidia.github.io/TensorRT-LLM/reference/memory.html#understand-inference-time-gpu-memory-usage 权重、内部激活张量和 I/O 张量。 对于 I/O 张量,主要内存占用来自 KV 缓存张量。 ================================================ FILE: llm-inference/tensorrt-llm/README.md ================================================ - https://github.com/NVIDIA/TensorRT-LLM - https://nvidia.github.io/TensorRT-LLM/index.html - triton trt-llm后端:https://github.com/triton-inference-server/tensorrtllm_backend/blob/main/docs/model_config.md - 性能基准:https://github.com/NVIDIA/TensorRT-LLM/blob/main/docs/source/performance/perf-overview.md - 性能优化最佳实践:https://nvidia.github.io/TensorRT-LLM/performance/perf-best-practices.html ## Batch Manager ## FP8 TensorRT-LLM 为用户提供了易于使用的 Python API 来定义大型语言模型 (LLM) 并构建包含 TensorRT 引擎,以便在 NVIDIA GPU 上高效地执行推理。 TensorRT-LLM 还包含用于创建执行这些 TensorRT 引擎的 Python 和 C++ 运行时的组件。 它还包括一个用于与 NVIDIA Triton 推理服务集成的后端; 为LLM服务的生产提供保障。 使用 TensorRT-LLM 构建的模型可以在从单个 GPU 到具有多个 GPU 的多个节点(使用张量并行/流水线并行)的各种配置上执行。 TensorRT-LLM 的 Python API 的架构与 PyTorch API 类似。 它为用户提供了包含 einsum、softmax、matmul 或 view 等函数的功能模块。 层模块捆绑了有用的构建块来组装LLM; 比如 Attention 块、MLP 或整个 Transformer 层。 特定于模型的组件,例如 GPTAttention 或 BertAttention,可以在 models 模块中找到。 TensorRT-LLM 附带了几种预定义的流行模型(LLaMA、Bloom等)。它们可以轻松修改和扩展以满足定制需求。 为了最大限度地提高性能并减少内存占用,TensorRT-LLM 允许使用不同的量化模式执行模型。 TensorRT-LLM 支持 仅 INT4/INT8 权重量化以及 SmoothQuant 技术的完整实现。 精度 | | FP32 | FP16 | BF16 | FP8 | INT8 | INT4 | | :--------------------------- | :---- | :---- | :---- | :--- | :--- | :--- | | Volta (SM70) | Y | Y | N | N | Y | Y | | Turing (SM75) | Y | Y | N | N | Y | Y | | Ampere (SM80, SM86) | Y | Y | Y | N | Y | Y | | Ada-Lovelace (SM89) | Y | Y | Y | Y | Y | Y | | Hopper (SM90) | Y | Y | Y | Y | Y | Y | ---- | Model | FP32 | FP16 | BF16 | FP8 | W8A8 SQ | W8A16 | W4A16 | W4A16 AWQ | W4A16 GPTQ | | :-------------------------- | :--: | :--: | :--: | :--: | :-----: | :---: | :---: | :-------: | :--------: | | Baichuan | Y | Y | Y | . | . | Y | Y | . | . | | BERT | Y | Y | Y | . | . | . | . | . | . | | BLOOM | Y | Y | Y | . | Y | Y | Y | . | . | | ChatGLM | Y | Y | Y | . | . | . | . | . | . | | ChatGLM-v2 | Y | Y | Y | . | . | . | . | . | . | | Falcon | Y | Y | Y | . | . | . | . | . | . | | GPT | Y | Y | Y | Y | Y | Y | Y | . | . | | GPT-J | Y | Y | Y | Y | Y | Y | Y | Y | . | | GPT-NeMo | Y | Y | Y | . | . | . | . | . | . | | GPT-NeoX | Y | Y | Y | . | . | . | . | . | Y | | LLaMA | Y | Y | Y | . | Y | Y | Y | Y | Y | | LLaMA-v2 | Y | Y | Y | Y | Y | Y | Y | Y | Y | | OPT | Y | Y | Y | . | . | . | . | . | . | | SantaCoder | Y | Y | Y | . | . | . | . | . | . | | StarCoder | Y | Y | Y | . | . | . | . | . | . | ================================================ FILE: llm-inference/tensorrt-llm/TRT-LLM引擎构建参数.md ================================================ - https://nvidia.github.io/TensorRT-LLM/commands/trtllm-build.html ## KV 缓存重用 --use_paged_context_fmha enable ``` triton: enable_kv_cache_reuse ``` ## Chunked Context --paged_kv_cache enable(过时) --kv_cache_type paged ## INT8/FP8 KV 缓存 目前,仅支持 per-tensor 量化 ## --remove_input_padding 将不同的 token 打包在一起,这样可以减少计算量和内存消耗。 默认值: 'enable' ## --max_num_tokens 每批次中删除填充后批量输入token的最大数量。 目前,输入填充默认被删除;可以指定--remove_input_padding disable 禁用它。 默认值: 8192 ## --context_fmha 在上下文阶段启用融合多头注意力,将触发使用单个内核执行 MHA/MQA/GQA 块的内核。 默认值: 'enable' ## --use_paged_context_fmha 允许 KV 缓存重用和分块上下文等高级功能。 ## --use_fp8_context_fmha 当 FP8 量化被激活时,可以通过启用 FP8 Context FMHA 进一步加速注意力 ## streamingllm --streamingllm enable ## --max_input_len 一次请求的最大输入长度。 默认值: 1024 ## --max_seq_len, --max_decoder_seq_len 一个请求的最大总长度,包括提示和输出。如果未指定,则从模型配置中推导出该值。 ## --weight_streaming 启用将权重卸载到 CPU 并在运行时进行流式加载。 默认值: False ## --reduce_fusion 在 AllReduce 之后将 ResidualAdd 和 LayerNorm 内核融合到单个内核中,从而提高端到端性能。 默认值: 'disable' ## --tokens_per_block 定义每个分页 kv 缓存块中包含多少个token。 默认值: 64 ================================================ FILE: llm-inference/tensorrt-llm/Triton服务启动参数.md ================================================ ================================================ FILE: llm-inference/tensorrt-llm/安装.md ================================================ ---- 基于镜像:nvcr.io/nvidia/pytorch:23.10-py3 卸载镜像中原来的tensorrt ``` pip uninstall -y tensorrt pip install mpi4py ``` 安装CMake ``` ARCH=$(uname -m) CMAKE_VERSION="3.24.4" PARSED_CMAKE_VERSION=$(echo $CMAKE_VERSION | sed 's/\.[0-9]*$//') CMAKE_FILE_NAME="cmake-${CMAKE_VERSION}-linux-${ARCH}" RELEASE_URL_CMAKE=https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_FILE_NAME}.tar.gz wget --no-verbose ${RELEASE_URL_CMAKE} -P /tmp tar -xf /tmp/${CMAKE_FILE_NAME}.tar.gz -C /usr/local/ ln -s /usr/local/${CMAKE_FILE_NAME} /usr/local/cmake echo 'export PATH=/usr/local/cmake/bin:$PATH' >> "${BASH_ENV}" ``` 安装tensorrt: ``` TENSOR_RT_VERSION="9.1.0.4" CUDA_VERSION="12.2" PY_VERSION=$(python -c 'import sys; print(".".join(map(str, sys.version_info[0:2])))') PARSED_PY_VERSION=$(echo "${PY_VERSION//./}") if [ -z "$RELEASE_URL_TRT" ];then ARCH=${TRT_TARGETARCH} if [ -z "$ARCH" ];then ARCH=$(uname -m);fi if [ "$ARCH" = "arm64" ];then ARCH="aarch64";fi if [ "$ARCH" = "amd64" ];then ARCH="x86_64";fi if [ "$ARCH" = "x86_64" ];then DIR_NAME="x64-agnostic"; else DIR_NAME=${ARCH};fi if [ "$ARCH" = "aarch64" ];then OS="ubuntu-22.04"; else OS="linux";fi RELEASE_URL_TRT=https://developer.nvidia.com/downloads/compute/machine-learning/tensorrt/secure/9.1.0/tars/tensorrt-${TENSOR_RT_VERSION}.${OS}.${ARCH}-gnu.cuda-${CUDA_VERSION}.tar.gz; fi wget --no-verbose ${RELEASE_URL_TRT} -O /tmp/TensorRT.tar tar -xf /tmp/TensorRT.tar -C /usr/local/ mv /usr/local/TensorRT-${TENSOR_RT_VERSION} /usr/local/tensorrt pip install /usr/local/tensorrt/python/tensorrt-*-cp${PARSED_PY_VERSION}-*.whl rm -rf /tmp/TensorRT.tar ``` ENV LD_LIBRARY_PATH=/usr/local/tensorrt/lib:${LD_LIBRARY_PATH} 安装最新的Polygraphy: ``` RELEASE_URL_PG=https://developer.nvidia.com/downloads/compute/machine-learning/tensorrt/secure/9.0.1/tars/polygraphy-0.48.1-py2.py3-none-any.whl pip uninstall -y polygraphy pip install ${RELEASE_URL_PG} ``` 安装 PyTorch 2.1: ARG TORCH_INSTALL_TYPE="skip" ``` export _GLIBCXX_USE_CXX11_ABI=$1 export TORCH_CUDA_ARCH_LIST="8.0;9.0" pip uninstall -y torch cd /tmp git clone --depth 1 --branch v$TORCH_VERSION https://github.com/pytorch/pytorch cd pytorch git submodule sync && git submodule update --init --recursive pip install -r requirements.txt python setup.py install cd /tmp && rm -rf /tmp/pytorch ``` ``` TORCH_VERSION="2.1.0" pip install torch==${TORCH_VERSION} ``` ``` https://github.com/NVIDIA/TensorRT-LLM/blob/v0.5.0/cpp/tests/CMakeLists.txt ``` - https://github.com/google/googletest ---- ``` git clone https://github.com/NVIDIA/TensorRT-LLM.git cd TensorRT-LLM git submodule update --init --recursive git lfs install git lfs pull docker pull nvcr.io/nvidia/pytorch:23.10-py3 ``` ``` https://developer.nvidia.com/downloads/compute/machine-learning/tensorrt/secure/9.1.0/tars/tensorrt-9.1.0.4.linux.x86_64-gnu.cuda-12.1.tar.gz; https://developer.nvidia.com/downloads/compute/machine-learning/tensorrt/secure/9.1.0/tars/tensorrt-9.1.0.4.linux.x86_64-gnu.cuda-12.2.tar.gz https://developer.nvidia.com/downloads/compute/machine-learning/tensorrt/secure/9.0.1/tars/polygraphy-0.48.1-py2.py3-none-any.whl ``` ``` docker rm -f tensorrt_llm docker run -dt --name tensorrt_llm \ --restart=always \ --gpus all \ --network=host \ --shm-size=4g \ -m 64G \ -v /home/gdong:/workspace \ -w /workspace \ nvcr.io/nvidia/pytorch:23.05-py3 \ /bin/bash docker exec -it tensorrt_llm bash pip install transformers==4.31.0 -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn pip install transformers==4.31.0 --progress-bar off -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn ``` ``` apt-get update && apt-get -y install git git-lfs mkdir -p /workspace/local/tensorrt python3 ./scripts/build_wheel.py --trt_root /workspace/local/tensorrt ``` ## 错误信息 ``` RuntimeError: can't start new thread ``` 解决: 更新docker镜像 ``` sed -i -e 's/^APT/# APT/' -e 's/^DPkg/# DPkg/' /etc/apt/apt.conf.d/docker-clean ``` ================================================ FILE: llm-inference/triton/REAEME.md ================================================ - https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tritonserver - https://catalog.ngc.nvidia.com/containers?filters=&orderBy=weightPopularDESC&query=&page=&pageSize= - https://catalog.ngc.nvidia.com/orgs/nvidia/containers/tritonserver - https://github.com/triton-inference-server/backend - https://github.com/triton-inference-server/server ``` docker run --privileged --gpus all -it --net=host -v ${PWD}:/workspace/ nvcr.io/nvidia/tritonserver:23.05-py3-sdk bash ``` ================================================ FILE: llm-inference/triton/onnx/README.md ================================================ ``` model_repository | +-- densenet_onnx | +-- config.pbtxt +-- 1 | +-- model.onnx ``` ``` mkdir -p model_repository/densenet_onnx/1 wget -O model_repository/densenet_onnx/1/model.onnx \ https://contentmamluswest001.blob.core.windows.net/content/14b2744cf8d6418c87ffddc3f3127242/9502630827244d60a1214f250e3bbca7/08aed7327d694b8dbaee2c97b8d0fcba/densenet121-1.2.onnx docker pull nvcr.io/nvidia/tritonserver:23.10-py3 # /home/gdong/lgd docker run --gpus all --rm \ -p 8000:8000 \ -p 8001:8001 \ -p 8002:8002 \ -v ${PWD}/model_repository:/models \ nvcr.io/nvidia/tritonserver:23.05-py3 \ tritonserver --model-repository=/models ``` ``` docker pull nvcr.io/nvidia/tritonserver:23.05-py3-sdk docker run -it --rm --net=host \ -v ${PWD}:/workspace/ \ nvcr.io/nvidia/tritonserver:23.05-py3-sdk \ bash pip install torchvision wget -O img1.jpg "https://www.hakaimagazine.com/wp-content/uploads/header-gulf-birds.jpg" ``` ================================================ FILE: llm-inference/triton/resnet50/client.py ================================================ import numpy as np from torchvision import transforms from PIL import Image import tritonclient.http as httpclient from tritonclient.utils import triton_to_np_dtype # preprocessing function def rn50_preprocess(img_path="img1.jpg"): img = Image.open(img_path) preprocess = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) return preprocess(img).numpy() transformed_img = rn50_preprocess() np.set_printoptions(threshold=np.inf) #print(transformed_img) # Setting up client client = httpclient.InferenceServerClient(url="localhost:8000") inputs = httpclient.InferInput("input__0", transformed_img.shape, datatype="FP32") inputs.set_data_from_numpy(transformed_img, binary_data=True) outputs = httpclient.InferRequestedOutput("output__0", binary_data=True, class_count=3) #outputs = httpclient.InferRequestedOutput("output__0", binary_data=True) # Querying the server results = client.infer(model_name="resnet50", inputs=[inputs], outputs=[outputs]) inference_output = results.as_numpy('output__0') print(inference_output[:5]) print(inference_output.shape) ================================================ FILE: llm-inference/triton/resnet50/config.pbtxt ================================================ name: "resnet50" platform: "pytorch_libtorch" max_batch_size : 0 input [ { name: "input__0" data_type: TYPE_FP32 dims: [ 3, 224, 224 ] reshape { shape: [ 1, 3, 224, 224 ] } } ] output [ { name: "output__0" data_type: TYPE_FP32 dims: [ 1, 1000 ,1, 1] reshape { shape: [ 1, 1000 ] } label_filename: "labels.txt" } ] ================================================ FILE: llm-inference/triton/resnet50/labels.txt ================================================ TENCH GOLDFISH WHITE SHARK TIGER SHARK HAMMERHEAD SHARK ELECTRIC RAY STINGRAY ROOSTER HEN OSTRICH BRAMBLING GOLDFINCH HOUSE FINCH SNOWBIRD INDIGO FINCH ROBIN BULBUL JAY MAGPIE CHICKADEE WATER OUZEL KITE BALD EAGLE VULTURE GREAT GREY OWL FIRE SALAMANDER NEWT EFT SPOTTED SALAMANDER AXOLOTL BULL FROG TREE FROG TAILED FROG LOGGERHEAD LEATHERBACK TURTLE MUD TURTLE TERRAPIN BOX TURTLE BANDED GECKO COMMON IGUANA AMERICAN CHAMELEON WHIPTAIL AGAMA FRILLED LIZARD ALLIGATOR LIZARD GILA MONSTER GREEN LIZARD AFRICAN CHAMELEON KOMODO DRAGON AFRICAN CROCODILE AMERICAN ALLIGATOR TRICERATOPS THUNDER SNAKE RINGNECK SNAKE HOGNOSE SNAKE GREEN SNAKE KING SNAKE GARTER SNAKE WATER SNAKE VINE SNAKE NIGHT SNAKE BOA ROCK PYTHON COBRA GREEN MAMBA SEA SNAKE HORNED VIPER DIAMONDBACK SIDEWINDER TRILOBITE HARVESTMAN SCORPION GARDEN SPIDER BARN SPIDER GARDEN SPIDER BLACK WIDOW TARANTULA WOLF SPIDER TICK CENTIPEDE GROUSE PTARMIGAN RUFFED GROUSE PRAIRIE CHICKEN PEACOCK QUAIL PARTRIDGE AFRICAN GREY MACAW COCKATOO LORIKEET COUCAL BEE EATER HORNBILL HUMMINGBIRD JACAMAR TOUCAN DRAKE MERGANSER GOOSE BLACK SWAN TUSKER ECHIDNA PLATYPUS WALLABY KOALA WOMBAT JELLYFISH SEA ANEMONE BRAIN CORAL FLATWORM NEMATODE CONCH SNAIL SLUG SEA SLUG CHITON CHAMBERED NAUTILUS DUNGENESS CRAB ROCK CRAB FIDDLER CRAB KING CRAB AMERICAN LOBSTER SPINY LOBSTER CRAYFISH HERMIT CRAB ISOPOD WHITE STORK BLACK STORK SPOONBILL FLAMINGO LITTLE BLUE HERON AMERICAN EGRET BITTERN CRANE LIMPKIN EUROPEAN GALLINULE AMERICAN COOT BUSTARD RUDDY TURNSTONE RED-BACKED SANDPIPER REDSHANK DOWITCHER OYSTERCATCHER PELICAN KING PENGUIN ALBATROSS GREY WHALE KILLER WHALE DUGONG SEA LION CHIHUAHUA JAPANESE SPANIEL MALTESE DOG PEKINESE SHIH-TZU BLENHEIM SPANIEL PAPILLON TOY TERRIER RHODESIAN RIDGEBACK AFGHAN HOUND BASSET BEAGLE BLOODHOUND BLUETICK COONHOUND WALKER HOUND ENGLISH FOXHOUND REDBONE BORZOI IRISH WOLFHOUND ITALIAN GREYHOUND WHIPPET IBIZAN HOUND NORWEGIAN ELKHOUND OTTERHOUND SALUKI SCOTTISH DEERHOUND WEIMARANER STAFFORDSHIRE BULLTERRIER STAFFORDSHIRE TERRIER BEDLINGTON TERRIER BORDER TERRIER KERRY BLUE TERRIER IRISH TERRIER NORFOLK TERRIER NORWICH TERRIER YORKSHIRE TERRIER WIRE-HAIRED FOX TERRIER LAKELAND TERRIER SEALYHAM TERRIER AIREDALE CAIRN AUSTRALIAN TERRIER DANDIE DINMONT BOSTON BULL MINIATURE SCHNAUZER GIANT SCHNAUZER STANDARD SCHNAUZER SCOTCH TERRIER TIBETAN TERRIER SILKY TERRIER WHEATEN TERRIER WHITE TERRIER LHASA RETRIEVER CURLY-COATED RETRIEVER GOLDEN RETRIEVER LABRADOR RETRIEVER CHESAPEAKE BAY RETRIEVER SHORT-HAIRED POINTER VISLA ENGLISH SETTER IRISH SETTER GORDON SETTER BRITTANY SPANIEL CLUMBER ENGLISH SPRINGER WELSH SPRINGER SPANIEL COCKER SPANIEL SUSSEX SPANIEL IRISH WATERSPANIEL KUVASZ SCHIPPERKE GROENENDAEL MALINOIS BRIARD KELPIE KOMONDOR OLD ENGLISH SHEEPDOG SHETLAND SHEEPDOG COLLIE BORDER COLLIE BOUVIER DES FLANDRES ROTTWEILER GERMAN SHEPHERD DOBERMAN MINIATURE PINSCHER GREATER SWISS MOUNTAIN DOG BERNESE MOUNTAIN DOG APPENZELLER ENTLEBUCHER BOXER BULL MASTIFF TIBETAN MASTIFF FRENCH BULLDOG GREAT DANE SAINT BERNARD ESKIMO DOG MALAMUTE SIBERIAN HUSKY DALMATIAN AFFENPINSCHER BASENJI PUG LEONBERG NEWFOUNDLAND GREAT PYRENEES SAMOYED POMERANIAN CHOW KEESHOND BRABANCON GRIFFON PEMBROKE CARDIGAN TOY POODLE MINIATURE POODLE STANDARD POODLE MEXICAN HAIRLESS TIMBER WOLF WHITE WOLF RED WOLF COYOTE DINGO DHOLE AFRICAN HUNTING DOG HYENA RED FOX KIT FOX ARCTIC FOX GREY FOX TABBY TIGER CAT PERSIAN CAT SIAMESE CAT EGYPTIAN CAT COUGAR LYNX LEOPARD SNOW LEOPARD JAGUAR LION TIGER CHEETAH BROWN BEAR AMERICAN BLACK BEAR ICE BEAR SLOTH BEAR MONGOOSE MEERKAT TIGER BEETLE LADYBUG GROUND BEETLE LONG-HORNED BEETLE LEAF BEETLE DUNG BEETLE RHINOCEROS BEETLE WEEVIL FLY BEE ANT GRASSHOPPER CRICKET WALKING STICK COCKROACH MANTIS CICADA LEAFHOPPER LACEWING DRAGONFLY DAMSELFLY ADMIRAL RINGLET MONARCH CABBAGE BUTTERFLY SULPHUR BUTTERFLY LYCAENID STARFISH SEA URCHIN SEA CUCUMBER WOOD RABBIT HARE ANGORA HAMSTER PORCUPINE FOX SQUIRREL MARMOT BEAVER GUINEA PIG SORREL ZEBRA HOG WILD BOAR WARTHOG HIPPOPOTAMUS OX WATER BUFFALO BISON RAM BIGHORN IBEX HARTEBEEST IMPALA GAZELLE ARABIAN CAMEL LLAMA WEASEL MINK POLECAT BLACK-FOOTED FERRET OTTER SKUNK BADGER ARMADILLO THREE-TOED SLOTH ORANGUTAN GORILLA CHIMPANZEE GIBBON SIAMANG GUENON PATAS BABOON MACAQUE LANGUR COLOBUS PROBOSCIS MONKEY MARMOSET CAPUCHIN HOWLER MONKEY TITI SPIDER MONKEY SQUIRREL MONKEY MADAGASCAR CAT INDRI INDIAN ELEPHANT AFRICAN ELEPHANT LESSER PANDA GIANT PANDA BARRACOUTA EEL COHO ROCK BEAUTY ANEMONE FISH STURGEON GAR LIONFISH PUFFER ABACUS ABAYA ACADEMIC GOWN ACCORDION ACOUSTIC GUITAR AIRCRAFT CARRIER AIRLINER AIRSHIP ALTAR AMBULANCE AMPHIBIAN ANALOG CLOCK APIARY APRON ASHCAN ASSAULT RIFLE BACKPACK BAKERY BALANCE BEAM BALLOON BALLPOINT BAND AID BANJO BANNISTER BARBELL BARBER CHAIR BARBERSHOP BARN BAROMETER BARREL BARROW BASEBALL BASKETBALL BASSINET BASSOON BATHING CAP BATH TOWEL BATHTUB BEACH WAGON BEACON BEAKER BEARSKIN BEER BOTTLE BEER GLASS BELL COTE BIB BICYCLE-BUILT-FOR-TWO BIKINI BINDER BINOCULARS BIRDHOUSE BOATHOUSE BOBSLED BOLO TIE BONNET BOOKCASE BOOKSHOP BOTTLECAP BOW BOW TIE BRASS BRASSIERE BREAKWATER BREASTPLATE BROOM BUCKET BUCKLE BULLETPROOF VEST BULLET TRAIN BUTCHER SHOP CAB CALDRON CANDLE CANNON CANOE CAN OPENER CARDIGAN CAR MIRROR CAROUSEL CARPENTERS KIT CARTON CAR WHEEL CASH MACHINE CASSETTE CASSETTE PLAYER CASTLE CATAMARAN CD PLAYER CELLO CELLULAR TELEPHONE CHAIN CHAINLINK FENCE CHAIN MAIL CHAIN SAW CHEST CHIFFONIER CHIME CHINA CABINET CHRISTMAS STOCKING CHURCH CINEMA CLEAVER CLIFF DWELLING CLOAK CLOG COCKTAIL SHAKER COFFEE MUG COFFEEPOT COIL COMBINATION LOCK COMPUTER KEYBOARD CONFECTIONERY CONTAINER SHIP CONVERTIBLE CORKSCREW CORNET COWBOY BOOT COWBOY HAT CRADLE CRANE CRASH HELMET CRATE CRIB CROCK POT CROQUET BALL CRUTCH CUIRASS DAM DESK DESKTOP COMPUTER DIAL TELEPHONE DIAPER DIGITAL CLOCK DIGITAL WATCH DINING TABLE DISHRAG DISHWASHER DISK BRAKE DOCK DOGSLED DOME DOORMAT DRILLING PLATFORM DRUM DRUMSTICK DUMBBELL DUTCH OVEN ELECTRIC FAN ELECTRIC GUITAR ELECTRIC LOCOMOTIVE ENTERTAINMENT CENTER ENVELOPE ESPRESSO MAKER FACE POWDER FEATHER BOA FILE FIREBOAT FIRE ENGINE FIRE SCREEN FLAGPOLE FLUTE FOLDING CHAIR FOOTBALL HELMET FORKLIFT FOUNTAIN FOUNTAIN PEN FOUR-POSTER FREIGHT CAR FRENCH HORN FRYING PAN FUR COAT GARBAGE TRUCK GASMASK GAS PUMP GOBLET GO-KART GOLF BALL GOLFCART GONDOLA GONG GOWN GRAND PIANO GREENHOUSE GRILLE GROCERY STORE GUILLOTINE HAIR SLIDE HAIR SPRAY HALF TRACK HAMMER HAMPER HAND BLOWER HAND-HELD COMPUTER HANDKERCHIEF HARD DISC HARMONICA HARP HARVESTER HATCHET HOLSTER HOME THEATER HONEYCOMB HOOK HOOPSKIRT HORIZONTAL BAR HORSE CART HOURGLASS IPOD IRON JACK-O-LANTERN JEAN JEEP JERSEY JIGSAW PUZZLE JINRIKISHA JOYSTICK KIMONO KNEE PAD KNOT LAB COAT LADLE LAMPSHADE LAPTOP LAWN MOWER LENS CAP LETTER OPENER LIBRARY LIFEBOAT LIGHTER LIMOUSINE LINER LIPSTICK LOAFER LOTION LOUDSPEAKER LOUPE LUMBERMILL MAGNETIC COMPASS MAILBAG MAILBOX MAILLOT MAILLOT MANHOLE COVER MARACA MARIMBA MASK MATCHSTICK MAYPOLE MAZE MEASURING CUP MEDICINE CHEST MEGALITH MICROPHONE MICROWAVE MILITARY UNIFORM MILK CAN MINIBUS MINISKIRT MINIVAN MISSILE MITTEN MIXING BOWL MOBILE HOME MODEL T MODEM MONASTERY MONITOR MOPED MORTAR MORTARBOARD MOSQUE MOSQUITO NET MOTOR SCOOTER MOUNTAIN BIKE MOUNTAIN TENT MOUSE MOUSETRAP MOVING VAN MUZZLE NAIL NECK BRACE NECKLACE NIPPLE NOTEBOOK OBELISK OBOE OCARINA ODOMETER OIL FILTER ORGAN OSCILLOSCOPE OVERSKIRT OXCART OXYGEN MASK PACKET PADDLE PADDLEWHEEL PADLOCK PAINTBRUSH PAJAMA PALACE PANPIPE PAPER TOWEL PARACHUTE PARALLEL BARS PARK BENCH PARKING METER PASSENGER CAR PATIO PAY-PHONE PEDESTAL PENCIL BOX PENCIL SHARPENER PERFUME PETRI DISH PHOTOCOPIER PICK PICKELHAUBE PICKET FENCE PICKUP PIER PIGGY BANK PILL BOTTLE PILLOW PING-PONG BALL PINWHEEL PIRATE PITCHER PLANE PLANETARIUM PLASTIC BAG PLATE RACK PLOW PLUNGER POLAROID CAMERA POLE POLICE VAN PONCHO POOL TABLE POP BOTTLE POT POTTERS WHEEL POWER DRILL PRAYER RUG PRINTER PRISON PROJECTILE PROJECTOR PUCK PUNCHING BAG PURSE QUILL QUILT RACER RACKET RADIATOR RADIO RADIO TELESCOPE RAIN BARREL RECREATIONAL VEHICLE REEL REFLEX CAMERA REFRIGERATOR REMOTE CONTROL RESTAURANT REVOLVER RIFLE ROCKING CHAIR ROTISSERIE RUBBER ERASER RUGBY BALL RULE RUNNING SHOE SAFE SAFETY PIN SALTSHAKER SANDAL SARONG SAX SCABBARD SCALE SCHOOL BUS SCHOONER SCOREBOARD SCREEN SCREW SCREWDRIVER SEAT BELT SEWING MACHINE SHIELD SHOE SHOP SHOJI SHOPPING BASKET SHOPPING CART SHOVEL SHOWER CAP SHOWER CURTAIN SKI SKI MASK SLEEPING BAG SLIDE RULE SLIDING DOOR SLOT SNORKEL SNOWMOBILE SNOWPLOW SOAP DISPENSER SOCCER BALL SOCK SOLAR DISH SOMBRERO SOUP BOWL SPACE BAR SPACE HEATER SPACE SHUTTLE SPATULA SPEEDBOAT SPIDER WEB SPINDLE SPORTS CAR SPOTLIGHT STAGE STEAM LOCOMOTIVE STEEL ARCH BRIDGE STEEL DRUM STETHOSCOPE STOLE STONE WALL STOPWATCH STOVE STRAINER STREETCAR STRETCHER STUDIO COUCH STUPA SUBMARINE SUIT SUNDIAL SUNGLASS SUNGLASSES SUNSCREEN SUSPENSION BRIDGE SWAB SWEATSHIRT SWIMMING TRUNKS SWING SWITCH SYRINGE TABLE LAMP TANK TAPE PLAYER TEAPOT TEDDY TELEVISION TENNIS BALL THATCH THEATER CURTAIN THIMBLE THRESHER THRONE TILE ROOF TOASTER TOBACCO SHOP TOILET SEAT TORCH TOTEM POLE TOW TRUCK TOYSHOP TRACTOR TRAILER TRUCK TRAY TRENCH COAT TRICYCLE TRIMARAN TRIPOD TRIUMPHAL ARCH TROLLEYBUS TROMBONE TUB TURNSTILE TYPEWRITER KEYBOARD UMBRELLA UNICYCLE UPRIGHT VACUUM VASE VAULT VELVET VENDING MACHINE VESTMENT VIADUCT VIOLIN VOLLEYBALL WAFFLE IRON WALL CLOCK WALLET WARDROBE WARPLANE WASHBASIN WASHER WATER BOTTLE WATER JUG WATER TOWER WHISKEY JUG WHISTLE WIG WINDOW SCREEN WINDOW SHADE WINDSOR TIE WINE BOTTLE WING WOK WOODEN SPOON WOOL WORM FENCE WRECK YAWL YURT WEB SITE COMIC BOOK CROSSWORD PUZZLE STREET SIGN TRAFFIC LIGHT BOOK JACKET MENU PLATE GUACAMOLE CONSOMME HOT POT TRIFLE ICE CREAM ICE LOLLY FRENCH LOAF BAGEL PRETZEL CHEESEBURGER HOTDOG MASHED POTATO HEAD CABBAGE BROCCOLI CAULIFLOWER ZUCCHINI SPAGHETTI SQUASH ACORN SQUASH BUTTERNUT SQUASH CUCUMBER ARTICHOKE BELL PEPPER CARDOON MUSHROOM GRANNY SMITH STRAWBERRY ORANGE LEMON FIG PINEAPPLE BANANA JACKFRUIT CUSTARD APPLE POMEGRANATE HAY CARBONARA CHOCOLATE SAUCE DOUGH MEAT LOAF PIZZA POTPIE BURRITO RED WINE ESPRESSO CUP EGGNOG ALP BUBBLE CLIFF CORAL REEF GEYSER LAKESIDE PROMONTORY SANDBAR SEASHORE VALLEY VOLCANO BALLPLAYER GROOM SCUBA DIVER RAPESEED DAISY LADY SLIPPER CORN ACORN HIP BUCKEYE CORAL FUNGUS AGARIC GYROMITRA STINKHORN EARTHSTAR HEN-OF-THE-WOODS BOLETE EAR TOILET TISSUE ================================================ FILE: llm-inference/triton/resnet50/resnet50_convert_torchscript.py ================================================ import torch import torchvision.models as models resnet50 = models.resnet50(pretrained=True) resnet50.eval() image = torch.randn(1, 3, 244, 244) resnet50_traced = torch.jit.trace(resnet50, image) resnet50(image) # resnet50_traced.save('/workspace/model/resnet50/model.pt') torch.jit.save(resnet50_traced, "/workspace/model/resnet50/model.pt") ================================================ FILE: llm-inference/vllm/FAQ.md ================================================ - https://github.com/vllm-project/vllm/issues/5001 ``` pip3 install vllm pip3 install nvidia-cublas-cu12==12.3.4.1 ``` ================================================ FILE: llm-inference/vllm/FP8.md ================================================ 在线动态量化 ``` from vllm import LLM model = LLM("facebook/opt-125m", quantization="fp8") # INFO 06-10 17:55:42 model_runner.py:157] Loading model weights took 0.1550 GB result = model.generate("Hello, my name is") ``` 离线量化: ``` git clone https://github.com/neuralmagic/AutoFP8.git pip install -e AutoFP8 ``` 使用动态激活缩放因子进行离线量化: ``` from auto_fp8 import AutoFP8ForCausalLM, BaseQuantizeConfig pretrained_model_dir = "meta-llama/Meta-Llama-3-8B-Instruct" quantized_model_dir = "Meta-Llama-3-8B-Instruct-FP8-Dynamic" # Define quantization config with static activation scales quantize_config = BaseQuantizeConfig(quant_method="fp8", activation_scheme="dynamic") # For dynamic activation scales, there is no need for calbration examples examples = [] # Load the model, quantize, and save checkpoint model = AutoFP8ForCausalLM.from_pretrained(pretrained_model_dir, quantize_config) model.quantize(examples) model.save_quantized(quantized_model_dir) ``` 使用静态激活缩放因子进行离线量化: ``` from datasets import load_dataset from transformers import AutoTokenizer from auto_fp8 import AutoFP8ForCausalLM, BaseQuantizeConfig pretrained_model_dir = "meta-llama/Meta-Llama-3-8B-Instruct" quantized_model_dir = "Meta-Llama-3-8B-Instruct-FP8" tokenizer = AutoTokenizer.from_pretrained(pretrained_model_dir, use_fast=True) tokenizer.pad_token = tokenizer.eos_token # Load and tokenize 512 dataset samples for calibration of activation scales ds = load_dataset("mgoin/ultrachat_2k", split="train_sft").select(range(512)) examples = [tokenizer.apply_chat_template(batch["messages"], tokenize=False) for batch in ds] examples = tokenizer(examples, padding=True, truncation=True, return_tensors="pt").to("cuda") # Define quantization config with static activation scales quantize_config = BaseQuantizeConfig(quant_method="fp8", activation_scheme="static") # Load the model, quantize, and save checkpoint model = AutoFP8ForCausalLM.from_pretrained(pretrained_model_dir, quantize_config) model.quantize(examples) model.save_quantized(quantized_model_dir) ``` ================================================ FILE: llm-inference/vllm/README.md ================================================ ## 数据并行与张量并行 https://github.com/vllm-project/vllm/blob/v0.9.0/examples/offline_inference/data_parallel.py https://github.com/vllm-project/vllm/pull/15977 ## 流水线并行与张量并行 https://docs.vllm.ai/en/latest/serving/distributed_serving.html https://developers.redhat.com/articles/2025/02/06/distributed-inference-with-vllm# ================================================ FILE: llm-inference/vllm/REF.md ================================================ ================================================ FILE: llm-inference/vllm/api_client.py ================================================ """Example Python client for vllm.entrypoints.api_server""" import argparse import json from typing import Iterable, List import requests def clear_line(n: int = 1) -> None: LINE_UP = '\033[1A' LINE_CLEAR = '\x1b[2K' for _ in range(n): print(LINE_UP, end=LINE_CLEAR, flush=True) def post_http_request(prompt: str, api_url: str, n: int = 1, stream: bool = False) -> requests.Response: headers = {"User-Agent": "Test Client"} pload = { "prompt": prompt, "n": n, "use_beam_search": True, "temperature": 0.0, "max_tokens": 16, "stream": stream, } response = requests.post(api_url, headers=headers, json=pload, stream=True) return response def get_streaming_response(response: requests.Response) -> Iterable[List[str]]: for chunk in response.iter_lines(chunk_size=8192, decode_unicode=False, delimiter=b"\0"): if chunk: data = json.loads(chunk.decode("utf-8")) output = data["text"] yield output def get_response(response: requests.Response) -> List[str]: data = json.loads(response.content) output = data["text"] return output if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--host", type=str, default="localhost") parser.add_argument("--port", type=int, default=8000) parser.add_argument("--n", type=int, default=4) parser.add_argument("--prompt", type=str, default="San Francisco is a") parser.add_argument("--stream", action="store_true") args = parser.parse_args() prompt = args.prompt api_url = f"http://{args.host}:{args.port}/generate" n = args.n stream = args.stream print(f"Prompt: {prompt!r}\n", flush=True) response = post_http_request(prompt, api_url, n, stream) if stream: num_printed_lines = 0 for h in get_streaming_response(response): clear_line(num_printed_lines) num_printed_lines = 0 for i, line in enumerate(h): num_printed_lines += 1 print(f"Beam candidate {i}: {line!r}", flush=True) else: output = get_response(response) for i, line in enumerate(output): print(f"Beam candidate {i}: {line!r}", flush=True) ================================================ FILE: llm-inference/vllm/cmd.md ================================================ ``` docker run -dt --name nvidia_vllm_env --restart=always --gpus all \ --network=host \ --shm-size 4G \ -v /home/guodong.li/workspace:/workspace \ -w /workspace \ nvcr.io/nvidia/pytorch:23.04-py3 \ /bin/bash docker exec -it nvidia_vllm_env bash ``` ``` On the server side, run one of the following commands: (vLLM backend) python -m vllm.entrypoints.api_server \ --model --swap-space 16 \ --disable-log-requests (TGI backend) ./launch_hf_server.sh On the client side, run: python benchmarks/benchmark_serving.py \ --backend \ --tokenizer --dataset \ --request-rate python -m vllm.entrypoints.api_server \ --model /workspace/model/bloomz-7b --swap-space 16 \ --disable-log-requests \ --host 127.0.0.1 --port 8001 ``` ``` docker run -it --gpus all \ --network=host \ --shm-size 4G \ -v /home/guodong.li/workspace:/workspace \ -w /workspace \ vllm:v1 \ python -m vllm.entrypoints.api_server \ --model /workspace/model/bloomz-7b --swap-space 16 \ --disable-log-requests \ --host 10.99.2.xx \ --port 18001 ``` ``` python benchmarks/benchmark_serving.py \ --backend vllm \ --tokenizer /workspace/model/bloomz-7b \ --dataset /workspace/model/ShareGPT_V3_unfiltered_cleaned_split.json \ --host 10.99.2.xx \ --port 18001 ``` ================================================ FILE: llm-inference/vllm/vllm.md ================================================ - https://vllm.readthedocs.io/en/latest/getting_started/quickstart.html - 多机部署:https://docs.vllm.ai/en/latest/serving/distributed_serving.html ## 安装 ``` # (Optional) Create a new conda environment. conda create -n myenv python=3.8 -y conda activate myenv # Install vLLM. pip install vllm ``` ``` # Pull the Docker image with CUDA 11.8. docker run --gpus all -it --rm --shm-size=8g nvcr.io/nvidia/pytorch:22.12-py3 ``` ## 示例 ### 离线批次推理 ``` from vllm import LLM, SamplingParams # Sample prompts. prompts = [ "Hello, my name is", "The president of the United States is", "The capital of France is", "The future of AI is", ] # Create a sampling params object. sampling_params = SamplingParams(temperature=0.8, top_p=0.95) # Create an LLM. llm = LLM(model="facebook/opt-125m") # Generate texts from the prompts. The output is a list of RequestOutput objects # that contain the prompt, generated text, and other information. outputs = llm.generate(prompts, sampling_params) # Print the outputs. for output in outputs: prompt = output.prompt generated_text = output.outputs[0].text print(f"Prompt: {prompt!r}, Generated text: {generated_text!r}") ``` ### API Server (LLM服务化) - 入参:https://github.com/vllm-project/vllm/blob/main/vllm/engine/arg_utils.py ``` python -m vllm.entrypoints.api_server --model facebook/opt-125m python -m vllm.entrypoints.openai.api_server \ --model facebook/opt-125m ``` --- ``` curl http://localhost:8000/generate \ -d '{ "prompt": "San Francisco is a", "use_beam_search": true, "n": 4, "temperature": 0 }' ``` ================================================ FILE: llm-inference/vllm/服务启动参数.md ================================================ 引擎启动参数: - https://docs.vllm.ai/en/stable/models/engine_args.html 并行配置参数: - https://github.com/vllm-project/vllm/blob/v0.5.2/vllm/config.py ## max-num-seqs max-num-seqs:默认 256, 当 max-num-seqs 比较小时,较迟接收到的 request 会进入 waiting_list,直到前面有request 结束后再被添加进生成队列。 当 max-num-seqs 太大时,会出现一部分 request 在生成了 3-4 个 tokens 之后,被加入到 waiting_list(有些用户出现生成到一半卡住的情况)。过大或过小的 max-num-seqs 都会影响用户体验。 max-num-batched-tokens:很重要的配置,比如你配置了 max-num-batched-tokens=1000 那么你大概能在一个 batch 里面处理 10 条平均长度约为 100 tokens 的 inputs。max-num-batched-tokens 应尽可能大,来充分发挥 continuous batching 的优势。不过似乎(对于 TGI 是这样,vllm 不太确定),在提供 HF 模型时,该 max-num-batched-tokens 能够被自动推导出来。 ## --max-model-len 模型上下文长度。 ## --enable-prefix-caching Enables automatic prefix caching. ## --enforce-eager 在vLLM中,--enforce-eager标志用于强制使用PyTorch的eager执行模式,而非默认的图执行模式。eager模式逐行执行代码,便于调试和动态控制流,但性能可能较低。图执行模式则优化性能,但调试复杂。使用此标志可在开发或调试时更灵活地控制模型行为。 ``` --served-model-name:API 中使用的模型名称。如果提供了多个名称,服务将响应任何提供的名称。 --device:vLLM 执行的设备类型。默认值:auto,可能的选择有:auto、cuda、neuron、cpu、openvino、tpu、xpu。 --model:要使用的 Huggingface 模型的名称或路径。默认值:"facebook/opt-125m"。 --tokenizer:要使用的 Huggingface 分词器的名称或路径。如果未指定,将使用模型名称或路径。 --trust-remote-code:信任来自 Huggingface 的远程代码。默认值:false。 --download-dir:下载和加载权重的目录,默认为huggingface的默认缓存目录。 --load-format:要加载的模型权重的格式。可能的选择:auto、pt、safetensors、npcache、dummy、tensorizer、sharded_state、gguf、bitsandbytes、mistral。默认值:auto,将尝试以 safetensors 格式加载权重,如果 safetensors 格式不可用,则回退到 pytorch bin 格式。 --dtype:模型权重和激活的数据类型。可能的选择:auto、half、float16、bfloat16、float、float32。 --kv-cache-dtype:kv缓存存储的数据类型。可能的选择:auto、fp8、fp8_e5m2、fp8_e4m3,如果为auto,将使用模型数据类型。 --max-model-len:模型上下文长度。如果未指定,将自动从模型配置中派生。 --pipeline-parallel-size, -pp:流水线并行大小。默认值:1。 --tensor-parallel-size, -tp:张量并行大小。默认值:1。 --enable-prefix-caching:启用自动前缀缓存。默认值:false。 --gpu-memory-utilization:用于模型执行的 GPU 内存比例,范围为 0 到 1。例如:值 0.5 表示 GPU 内存利用率为 50%。如果未指定,将使用默认值 0.9。 --disable-custom-all-reduce:禁用自定义all-reduce Kernel并回退到使用NCCL。 --max-num-batched-tokens:每次迭代的最大批处理Token数。 --enable-chunked-prefill:如果设置,预填充请求可以根据 max_num_batched_tokens 进行分块。 --max-num-seqs:每次迭代的最大序列数。默认值:256。 ``` ``` --kv-cache-dtype:kv缓存存储的数据类型。可能的选择:auto、fp8、fp8_e5m2、fp8_e4m3,如果为auto,将使用模型数据类型。 --quantization, -q:用于量化权重的方法。可能的选择:aqlm、awq、deepspeedfp、tpu_int8、fp8、fbgemm_fp8、modelopt、marlin、gguf、gptq_marlin_24、gptq_marlin、awq_marlin、gptq、compressed-tensors、bitsandbytes、qqq、experts_int8、neuron_quant、ipex、None。如果为None,首先检查模型配置文件中的quantization_config属性;如果为 None,先假设模型权重未量化,并使用dtype来确定权重的数据类型。 ``` ## --use-v2-block-manager [DEPRECATED] block manager v1 has been removed and SelfAttnBlockSpaceManager (i.e. block manager v2) is now the default. Setting this flag to True or False has no effect on vLLM behavior. [已废弃]v1版本的块管理器已经被移除,现在默认使用的是SelfAttnBlockSpaceManager(也就是块管理器v2)。把这个标志设为真或假对vLLM的行为没有影响。 ================================================ FILE: llm-inference/vllm/源码.md ================================================ 入口 LLMEngine Worker 类 执行 核心执行逻辑: ModelRunner execute_model ## CacheEngine 管理KV缓存 这个类负责初始化和管理GPU和CPU的KV缓存。它还提供了执行KV缓存操作的方法,比如交换和复制。 ## CacheConfig 配置KV缓存 - block_size:缓存块的大小,以token数量计算。 - gpu_memory_utilization:用于vLLM执行的GPU内存的占比。 - swap_space:每个GPU的CPU交换空间大小(以GiB为单位)。 - cache_dtype:kv缓存存储的数据类型。 - is_attention_free:模型是否是attention-fre模型。 - num_gpu_blocks_override:要使用的GPU块数量。如果指定,将覆盖配置文件中的GPU块数量。如果为None,则不执行任何操作。 - sliding_window:KV缓存的滑动窗口大小。不能与启用前缀缓存一起使用。 - enable_prefix_caching:是否启用前缀缓存。 - cpu_offload_gb:CPU卸载缓冲区的大小(以GiB为单位)。 ================================================ FILE: llm-inference/vllm/请求处理流程.md ================================================ 从接收 request,到返回回复,大致的过程如下: 1 vllm 接收到 request 之后,会发放 request_uuid,并将 request 分配到 running, swap, waiting 三个队列当中。(参考 vllm.core.scheduler.Scheduler._schedule ) 2 根据用户等待的时间进行 request 优先级排序。从 running 和 swap队列中选择优先级高的 request 来生成对应的回复,由于 decoding 阶段,每次前项传播只预测一个 token,因此 vllm 在进行完一次前项传播(即 one decoding iteration)之后,会返回所有新生成的 tokens 保存在每个 request_uuid 下。(参考 vllm.engine.llm_engine.LLMEngine.step) 3 如果 request 完成了所有的 decoding 步骤,那么将其移除,并返回结果给用户。 4 更新 running, swap 和 waiting 的 request。 5 循环执行 2,3,4。 步骤 1:安排下一次迭代中要执行的序列以及要换入/换出/复制的Token块。 根据调度策略,序列可能被抢占/重新排序。 序列组(SG)是指由同一提示生成的一组序列。 步骤2:调用分布式执行器执行模型。 步骤3:处理模型输出。这主要包括: 解码相关输出。 根据采样参数(是否使用beam_search)使用模型输出更新计划的序列组。 释放已完成的序列组。 最后,它创建并返回新生成的结果。 抢占模式。 1. 交换(Swapping):将被抢占序列的块交换到CPU内存中,并在序列恢复时将它们交换回来。 2. 重计算(Recomputation):丢弃被抢占序列的块,并在恢复序列时重新计算它们,将序列视为新的提示。 ================================================ FILE: llm-inference/vllm/长文本推理.md ================================================ ## glm4 - https://huggingface.co/THUDM/glm-4-9b-chat - https://huggingface.co/THUDM/glm-4-9b-chat-1m ``` from transformers import AutoTokenizer from vllm import LLM, SamplingParams # GLM-4-9B-Chat-1M # max_model_len, tp_size = 1048576, 4 # GLM-4-9B-Chat # 如果遇见 OOM 现象,建议减少max_model_len,或者增加tp_size max_model_len, tp_size = 131072, 1 model_name = "THUDM/glm-4-9b-chat" prompt = [{"role": "user", "content": "你好"}] tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True) llm = LLM( model=model_name, tensor_parallel_size=tp_size, max_model_len=max_model_len, trust_remote_code=True, enforce_eager=True, # GLM-4-9B-Chat-1M 如果遇见 OOM 现象,建议开启下述参数 # enable_chunked_prefill=True, # max_num_batched_tokens=8192 ) stop_token_ids = [151329, 151336, 151338] sampling_params = SamplingParams(temperature=0.95, max_tokens=1024, stop_token_ids=stop_token_ids) inputs = tokenizer.apply_chat_template(prompt, tokenize=False, add_generation_prompt=True) outputs = llm.generate(prompts=inputs, sampling_params=sampling_params) print(outputs[0].outputs[0].text) ``` ``` python3 -m vllm.entrypoints.openai.api_server \ --port 9009 \ --gpu-memory-utilization 0.95 \ --dtype auto \ --model /workspace/models/Qwen1.5-7B-Chat \ --served-model-name glm-4-9b-chat \ --max-num-seqs 128 \ --max-model-len 131072 \ --tensor-parallel-size 1 \ --enforce-eager \ --enable-chunked-prefill \ --max-num-batched-tokens 10000 \ --kv-cache-dtype fp8 ``` ## qwen2.5 - https://huggingface.co/Qwen/Qwen2.5-7B-Instruct ``` { "architectures": [ "Qwen2ForCausalLM" ], // ... "vocab_size": 152064, // adding the following snippets "rope_scaling": { "factor": 4.0, "original_max_position_embeddings": 32768, "type": "yarn" } } ``` 目前,vLLM 仅支持静态 YARN,这意味着无论输入长度如何,缩放因子都保持不变,这可能会影响较短文本的性能。我们建议仅在需要处理长上下文时添加rope_scaling配置。 ================================================ FILE: llm-inference/web/fastapi/README.md ================================================ ``` uvicorn llm-server:app --host 0.0.0.0 --port 8000 --reload ``` ``` from typing import Optional from pydantic import BaseModel, Field # 定义请求的数据模型 class Item(BaseModel): name: str = Field(..., description="物品名称") description: Optional[str] = Field(None, description="物品描述") price: float = Field(..., description="物品价格") from fastapi import FastAPI, HTTPException, Request app = FastAPI() # 创建POST路由 @app.post("/items/") async def create_item(item: Item): # 这里你可以处理接收到的数据,比如保存到数据库 # 作为示例,我们只是打印出来 print(item) uvicorn main:app --reload ``` ================================================ FILE: llm-inference/web/fastapi/llm-qwen-mindspore-lite.py ================================================ import os import mindspore_lite import mindspore as ms from mindformers.pipeline import pipeline from mindformers.inference import InferConfig, InferTask from mindformers.tools.utils import str2bool from qwen_tokenizer import QwenTokenizer from dataclasses import dataclass from typing import Optional from pydantic import BaseModel, Field from fastapi import FastAPI, status, HTTPException, Request from fastapi.responses import JSONResponse import uvicorn, json, datetime app = FastAPI() @dataclass class InferParam: device_id:int = -1 ge_config_path:str = './lite.ini' vocab_file:str = './run/qwen.tiktoken' mindir_root_dir:str = 'output' seq_length:int = 1024 batch_size:int = 1 do_sample:bool = True predict_data:str = 'hello' predict_length:int = 512 paged_attention:bool = False pa_block_size:int = 16 pa_num_blocks:int = 512 dynamic:bool = False top_k:int = 3 top_p:float = 0.85 repetition_penalty:float = 1.0 temperature:float = 1.0 eos_token_id:int = 151643 pad_token_id:int = 151643 def get_mindir_path(export_path='output', full=True): """Return relative path to MINDIR file""" if not os.path.isdir(export_path): raise FileNotFoundError(export_path) rank_id = os.getenv('RANK_ID', '0') mindir_path = "%s/mindir_%s_checkpoint/rank_%s_graph.mindir" % \ (export_path, "full" if full else "inc", rank_id) if not os.path.isfile(mindir_path): raise FileNotFoundError(mindir_path) var_path = "%s/mindir_%s_checkpoint/rank_%s_variables" % \ (export_path, "full" if full else "inc", rank_id) if not os.path.isdir(var_path): raise FileNotFoundError(var_path) return mindir_path def create_mslite_pipeline(args): """Create MS lite inference pipeline.""" ms.set_context(mode=ms.GRAPH_MODE, device_target='Ascend') if not os.path.isfile(args.vocab_file): raise FileNotFound(args.vocab_file) tokenizer = QwenTokenizer(pad_token='<|endoftext|>', vocab_file=args.vocab_file) prefill_model_path = get_mindir_path(args.mindir_root_dir, full=True) inc_model_path = get_mindir_path(args.mindir_root_dir, full=False) if len(args.ge_config_path.split(',')) > 1: args.ge_config_path = args.ge_config_path.split(',') for ini in args.ge_config_path: if not os.path.isfile(ini): raise FileNotFoundError(ini) else: if not os.path.isfile(args.ge_config_path): raise FileNotFoundError(args.ge_config_path) if args.device_id == -1: args.device_id = int(os.getenv('DEVICE_ID', '0')) rank_id = int(os.getenv('RANK_ID', '0')) print("Creating pipeline from (%s, %s)..." % (prefill_model_path, inc_model_path)) lite_config = InferConfig( prefill_model_path=prefill_model_path, increment_model_path=inc_model_path, model_type="mindir", model_name="qwen", ge_config_path=args.ge_config_path, device_id=args.device_id, rank_id=rank_id, dynamic=args.dynamic, infer_seq_length=args.seq_length, paged_attention=args.paged_attention, pa_block_size=args.pa_block_size, pa_num_blocks=args.pa_num_blocks, ) pipeline_task = InferTask.get_infer_task("text_generation", lite_config, tokenizer=tokenizer) return pipeline_task def expand_input_list(input_list, batch_size): """Expand 'input_list' to a list of size 'batch_size'.""" if len(input_list) < batch_size: repeat_time = batch_size // len(input_list) + 1 input_list = input_list * repeat_time input_list = input_list[:batch_size] return input_list def run_mslite_infer(pipeline_task, prompt, args): """Run MS lite inference with PROMPT and ARGS.""" print("request args:", args) input_list = prompt if not isinstance(prompt, list): input_list = [prompt,] input_list = expand_input_list(input_list, args.batch_size) max_length = args.predict_length if not args.dynamic: if args.seq_length is None: raise ValueError('Argument "--seq_length" is missing.') if max_length > args.seq_length: max_length = args.seq_length return pipeline_task.infer( input_list, max_length=max_length, do_sample=args.do_sample, top_k=args.top_k, top_p=args.top_p, repetition_penalty=args.repetition_penalty, temperature=args.temperature, is_sample_acceleration=False, add_special_tokens=False, eos_token_id=args.eos_token_id, pad_token_id=args.pad_token_id) args = InferParam( mindir_root_dir='/workspace/qwen-7b-chat-mindir', ge_config_path='/workspace/mindformers/research/qwen/lite.ini', vocab_file='/workspace/Qwen-7B-Chat/qwen.tiktoken', seq_length=2048, batch_size=1, predict_data='hello' ) pipeline_task = create_mslite_pipeline(args) # to warm up the model run_mslite_infer(pipeline_task, "hello", args) class Item(BaseModel): text_input: str top_k: Optional[int] = Field(default=3, description="top_k") top_p: Optional[float] = Field(default=0.85, description="top_p") temperature: Optional[float] = Field(temperature=1.0, description="temperature") repetition_penalty: Optional[float] = Field(default=1.0, description="repetition_penalty") predict_length: Optional[int] = Field(default=512, description="max_length") eos_token_id: Optional[int] = Field(default=151643, description="eos_token_id") pad_token_id: Optional[int] = Field(default=151643, description="pad_token_id") @app.post('/v2/models/ensemble/generate_stream') async def generate_stream(data:Item): text_input = data.text_input args.top_k = data.top_k args.top_p = data.top_p args.temperature = data.temperature args.repetition_penalty = data.repetition_penalty args.predict_length = data.predict_length args.eos_token_id = data.eos_token_id args.pad_token_id = data.pad_token_id outputs = run_mslite_infer(pipeline_task, text_input, args) for output in outputs: print(output) result = {'text_output': outputs[0]} return JSONResponse(content=result, status_code=status.HTTP_200_OK) @app.post('/predict') async def predict(request: Request): json_post_raw = await request.json() json_post = json.dumps(json_post_raw) json_post_list = json.loads(json_post) input_text = json_post_list.get('input_text') # input_text outputs = run_mslite_infer(pipeline_task, input_text, args) for output in outputs: print(output) return {'result': outputs} if __name__ == '__main__': uvicorn.run(app, host='0.0.0.0', port=8000, workers=4) ================================================ FILE: llm-inference/web/flask/README.md ================================================ curl --request POST \ --url http://10.193.195.107:5000/predict \ --header 'content-type: application/json' \ --data '{"input_text": "保持健康的秘诀"}' ================================================ FILE: llm-inference/web/flask/llm-qwen-mindspore-lite.py ================================================ from flask import Flask, request, jsonify import os import mindspore_lite import mindspore as ms from mindformers.pipeline import pipeline from mindformers.inference import InferConfig, InferTask from mindformers.tools.utils import str2bool from qwen_tokenizer import QwenTokenizer from dataclasses import dataclass app = Flask(__name__) @dataclass class InferParam: device_id:int = -1 ge_config_path:str = './lite.ini' vocab_file:str = './run/qwen.tiktoken' mindir_root_dir:str = 'output' seq_length:int = 1024 batch_size:int = 1 do_sample:bool = True predict_data:str = 'hello' predict_length:int = 512 paged_attention:bool = False pa_block_size:int = 16 pa_num_blocks:int = 512 dynamic:bool = False top_k:int = 3 top_p:float = 0.85 repetition_penalty:float = 1.0 temperature:float = 1.0 eos_token_id:int = 151643 pad_token_id:int = 151643 def get_mindir_path(export_path='output', full=True): """Return relative path to MINDIR file""" if not os.path.isdir(export_path): raise FileNotFoundError(export_path) rank_id = os.getenv('RANK_ID', '0') mindir_path = "%s/mindir_%s_checkpoint/rank_%s_graph.mindir" % \ (export_path, "full" if full else "inc", rank_id) if not os.path.isfile(mindir_path): raise FileNotFoundError(mindir_path) var_path = "%s/mindir_%s_checkpoint/rank_%s_variables" % \ (export_path, "full" if full else "inc", rank_id) if not os.path.isdir(var_path): raise FileNotFoundError(var_path) return mindir_path def create_mslite_pipeline(args): """Create MS lite inference pipeline.""" ms.set_context(mode=ms.GRAPH_MODE, device_target='Ascend') if not os.path.isfile(args.vocab_file): raise FileNotFound(args.vocab_file) tokenizer = QwenTokenizer(pad_token='<|endoftext|>', vocab_file=args.vocab_file) prefill_model_path = get_mindir_path(args.mindir_root_dir, full=True) inc_model_path = get_mindir_path(args.mindir_root_dir, full=False) if len(args.ge_config_path.split(',')) > 1: args.ge_config_path = args.ge_config_path.split(',') for ini in args.ge_config_path: if not os.path.isfile(ini): raise FileNotFoundError(ini) else: if not os.path.isfile(args.ge_config_path): raise FileNotFoundError(args.ge_config_path) if args.device_id == -1: args.device_id = int(os.getenv('DEVICE_ID', '0')) rank_id = int(os.getenv('RANK_ID', '0')) print("Creating pipeline from (%s, %s)..." % (prefill_model_path, inc_model_path)) lite_config = InferConfig( prefill_model_path=prefill_model_path, increment_model_path=inc_model_path, model_type="mindir", model_name="qwen", ge_config_path=args.ge_config_path, device_id=args.device_id, rank_id=rank_id, dynamic=args.dynamic, infer_seq_length=args.seq_length, paged_attention=args.paged_attention, pa_block_size=args.pa_block_size, pa_num_blocks=args.pa_num_blocks, ) pipeline_task = InferTask.get_infer_task("text_generation", lite_config, tokenizer=tokenizer) return pipeline_task def expand_input_list(input_list, batch_size): """Expand 'input_list' to a list of size 'batch_size'.""" if len(input_list) < batch_size: repeat_time = batch_size // len(input_list) + 1 input_list = input_list * repeat_time input_list = input_list[:batch_size] return input_list def run_mslite_infer(pipeline_task, prompt, args): """Run MS lite inference with PROMPT and ARGS.""" print("request args:", args) input_list = prompt if not isinstance(prompt, list): input_list = [prompt,] input_list = expand_input_list(input_list, args.batch_size) max_length = args.predict_length if not args.dynamic: if args.seq_length is None: raise ValueError('Argument "--seq_length" is missing.') if max_length > args.seq_length: max_length = args.seq_length return pipeline_task.infer( input_list, max_length=max_length, do_sample=args.do_sample, top_k=args.top_k, top_p=args.top_p, repetition_penalty=args.repetition_penalty, temperature=args.temperature, is_sample_acceleration=False, add_special_tokens=False, eos_token_id=args.eos_token_id, pad_token_id=args.pad_token_id) args = InferParam( mindir_root_dir='/workspace/qwen-7b-chat-mindir', ge_config_path='/workspace/mindformers/research/qwen/lite.ini', vocab_file='/workspace/Qwen-7B-Chat/qwen.tiktoken', seq_length=2048, batch_size=1, predict_data='hello' ) pipeline_task = create_mslite_pipeline(args) # to warm up the model run_mslite_infer(pipeline_task, "hello", args) @app.route('/v2/models/ensemble/generate_stream', methods=['POST']) def generate_stream(): data = request.json text_input = data.get('text_input') args.top_k = data.get("top_k", 3) args.top_p = data.get("top_p", 0.85) args.temperature = data.get("temperature", 1.0) args.repetition_penalty = data.get("repetition_penalty", 1.0) args.predict_length = data.get("max_length", 512) args.eos_token_id = data.get("eos_token_id", 151643) args.pad_token_id = data.get("pad_token_id", 151643) outputs = run_mslite_infer(pipeline_task, text_input, args) for output in outputs: print(output) return jsonify({'text_output': outputs[0]}) @app.route('/predict', methods=['POST']) def predict(): data = request.json input_text = data.get('input_text') outputs = run_mslite_infer(pipeline_task, input_text, args) for output in outputs: print(output) return jsonify({'result': outputs}) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000) ================================================ FILE: llm-inference/web/sanic/README.md ================================================ RuntimeError: Start method 'spawn' was requested, but 'fork' was already set. - 解决方法:https://sanic.dev/en/guide/running/manager.html#sanic-and-start-methods - python多进程(一)Fork模式和Spawn模式的优缺点: https://blog.csdn.net/weixin_42575811/article/details/134041691 - https://ida3.cn/zh/guide/deployment/running.html#sanic-%E6%9C%8D%E5%8A%A1%E5%99%A8-sanic-server sanic server.app --host=0.0.0.0 --port=1337 --workers=4 ================================================ FILE: llm-inference/xinference/README.md ================================================ - https://inference.readthedocs.io/zh-cn/latest/index.html ================================================ FILE: llm-inference/分离式推理架构.md ================================================ 分离式推理架构 https://github.com/LLMServe/DistServe ================================================ FILE: llm-inference/大模型推理张量并行.md ================================================ 大模型推理张量并行的4种模式: https://zhuanlan.zhihu.com/p/12302566679 Tensor Parallel LLM Inferencing:https://medium.com/tr-labs-ml-engineering-blog/tensor-parallel-llm-inferencing-09138daf0ba7 ================================================ FILE: llm-inference/解码策略.md ================================================ https://huggingface.co/blog/mlabonne/decoding-strategies [基于 transformers 的 generate() 方法实现多样化文本生成:参数含义和算法原理解读](https://blog.csdn.net/muyao987/article/details/125917234) [Text generation strategies](https://huggingface.co/docs/transformers/v4.44.0/en/generation_strategies) [Decoding strategies](https://huggingface.co/docs/transformers/generation_strategies#decoding-strategies) 参考文档: - [如何生成文本: 通过 Transformers 用不同的解码方法生成文本](https://huggingface.co/blog/zh/how-to-generate) | [How to generate text: using different decoding methods for language generation with Transformers](https://huggingface.co/blog/how-to-generate) - [大语言模型生成过程中参数与解码策略原理及其代码实现](https://mp.weixin.qq.com/s?__biz=MzkwOTY0MDU5NA==&mid=2247484579&idx=1&sn=92458d070d1811b0b23579c73bebf261&chksm=c136d25ef6415b4879700ed5c1bb95c9133890895baf8e22d34c6d6fdb07e3603456c2aaaca3&token=155512204&lang=zh_CN#rd) https://huggingface.co/docs/transformers/v4.44.0/en/generation_strategies https://huggingface.co/docs/transformers/v4.36.1/en/generation_strategies [Setting Top-K, Top-P and Temperature in LLMs](https://rumn.medium.com/setting-top-k-top-p-and-temperature-in-llms-3da3a8f74832) 继续一个初始句子的生成。Maximization和 top-k 截断方法会导致大量的重复(用蓝色突出显示),而带温度和不带温度的采样往往会导致不连贯(用红色突出显示)。核采样在很大程度上避免了这两个问题。 - [The Curious Case of Neural Text Degeneration](https://arxiv.org/pdf/1904.09751) ================================================ FILE: llm-interview/README.md ================================================ ## [大模型基础](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/base.md) ## [大模型结构](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-algo.md) ## [大模型训练](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-train.md) ## [大模型微调](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-ft.md) ## [大模型评估](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-eval.md) ## [大模型压缩](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-compress.md) ## [大模型推理](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-inference.md) ## [大模型应用](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/llm-app.md) ## [大模型综合性问题](https://github.com/liguodongiot/llm-action/blob/main/llm-interview/comprehensive.md) ================================================ FILE: llm-interview/base.md ================================================ - NLU以及NLG各种任务的差异? a. Self-Attention的表达式 b. 为什么上面那个公式要对QK进行scaling scaling后进行softmax操作可以使得输入的数据的分布变得更好,你可以想象下softmax的公式,数值会进入敏感区间,防止梯度消失,让模型能够更容易训练。 c.self-attention一定要这样表达吗? 不一定,只要可以建模相关性就可以。当然,最好是能够高速计算(矩阵乘法),并且表达能力强(query可以主动去关注到其他的key并在value上进行强化,并且忽略不相关的其他部分),模型容量够(引入了project_q/k/v,att_out,多头) e.为什么transformer用Layer Norm?有什么用? 任何norm的意义都是为了让使用norm的网络的输入的数据分布变得更好,也就是转换为标准正态分布,数值进入敏感度区间,以减缓梯度消失,从而更容易训练。 当然,这也意味着舍弃了除此维度之外其他维度的其他信息。为什么能舍弃呢?请看下一题。 f.为什么不用BN? 首先要明确,如果在一个维度内进行normalization,那么在这个维度内,相对大小有意义的,是可以比较的; 但是在normalization后的不同的维度之间,相对大小这是没有意义的 i.transformer为什么要用三个不一样的QKV? 前面提到过,是为了增强网络的容量和表达能力。更极端点,如果完全不要project_q/k/v,就是输入x本身来做,当然可以,但是表征能力太弱了(x的参数更新得至少会很拧巴) j.为什么要多头? 举例说明多头相比单头注意力的优势和上一问一样,进一步增强网络的容量和表达能力。你可以类比CV中的不同的channel(不同卷积核)会关注不同的信息,事实上不同的头也会关注不同的信息。 ================================================ FILE: llm-interview/comprehensive.md ================================================ - 解决显存不足的方法有哪些? 训练: 推理: - ================================================ FILE: llm-interview/llm-algo.md ================================================ > Transformers 结构中 Encoder-only,Decoder-only,Encoder-Decoder 划分的具体标准是什么?典型代表模型有哪些? > BatchNorm与LayerNorm的异同 https://zhuanlan.zhihu.com/p/428620330 代码: https://zhuanlan.zhihu.com/p/656647661 https://www.zhihu.com/question/395811291/answer/1251829041 选择什么样的归一化方式,取决于你关注数据的哪部分信息。如果某个维度信息的差异性很重要,需要被拟合,那就别在那个维度进行归一化。 关联性 --- 差异性 CV 里面 不同样本的同一channel有关联性, 同一样本的不同channel是有差异性的(没有关联性) CV 里面 不同样本的同一特性没有关联性(有差异性),同一样本的不同特征有关联性 https://zhuanlan.zhihu.com/p/643560888 > 为什么像 baichuan2 和 llama 使用 RMSNorm 归一化? RMS是LayerNorm的平替,发表在“Root Mean Square Layer Normalization ”,其提出的动机是LayerNorm运算量比较大,所提出的RMSNorm性能和LayerNorm相当,但是可以节省7%到64%的运算。RMSNorm和LayerNorm的主要区别在于RMSNorm不需要同时计算均值和方差两个统计量,而只需要计算均方根Root Mean Square这一个统计量。 - https://zhuanlan.zhihu.com/p/694909672 > Post-Norm vs. Pre-Norm 同一设置之下,Pre Norm结构往往更容易训练,但最终效果通常不如Post Norm。Pre Norm更容易训练好理解,因为它的恒等路径更突出. post-norm和pre-norm其实各有优势,post-norm在残差之后做归一化,对参数正则化的效果更强,进而模型的鲁棒性也会更好; pre-norm相对于post-norm,因为有一部分参数直接加在了后面,不需要对这部分参数进行正则化,正好可以防止模型的梯度爆炸或者梯度消失,因此,这里笔者可以得出的一个结论是如果层数少post-norm的效果其实要好一些,如果要把层数加大,为了保证模型的训练,pre-norm显然更好一些。 ================================================ FILE: llm-interview/llm-app.md ================================================ ================================================ FILE: llm-interview/llm-compress.md ================================================ ## 量化 ### 常见的大模型量化方法有哪些? ## 剪枝 ## 蒸馏 ================================================ FILE: llm-interview/llm-eval.md ================================================ > 如何评测生成,改写等开放性任务? 指导思想,开放性任务的写作能力这类任务本身就很主观,我们不太方便用Rouge或者BLEU这样的评价指标,因为它本身就不能体现模型的核心能力,而且与人类基准就是不对齐的(偏离实际需求)。 从更贴近实际需求的角度来说,Elo的方式还是最合理的; 或者如果你的模型的核心业务就是生成/改写/总结,那你本身就应该有一套业务逻辑的评价指标来评测你的模型——以你的业务需求为导向。 ================================================ FILE: llm-interview/llm-ft.md ================================================ ## 微调 > 介绍下 LoRA、AdaLoRA、QLoRA 这几种高效微调方法及其特点 > 在LoRA中,A和B低秩矩阵的初始化方法,对A采用高斯初始化,对B采用零矩阵初始化,目的是让训练刚开始时BA的值为0,这样不会给模型带来额外的噪声。那么,对A做零矩阵初始化,对B做高斯初始化行不行呢?反正看起来只要让初始化为0就行? 当前作者还没有发现转换初始化方式产生的显著区别,只要这两者中任意一者为0,另一者不为0即可。 参考:https://github.com/microsoft/LoRA/issues/98 > 介绍下 Prefix Tuning、Prompt Tuning、P-Tuning、P-Tuning v2 这四种高效微调方法的区别与联系? 1. Prompt Tuning和P-Tuning都是只在Embbedding层加入虚拟Token。而 Prefix Tuning、P-Tuning v2 会在每一层都加入虚拟Token,从而引入了更多的可训练参数;通过加入到更深层结构中的Prompt,能给模型预测带来更直接的影响。 2. P-Tuning通过 LSTM + MLP 去编码这些virtual token,再输入到模型,可以让模型收敛更快。 3. Prefix Tuning 为了防止直接更新 Prefix 的参数(virtual token)导致训练不稳定和性能下降的情况,在Prefix层前面加了MLP结构,训练完成后,只保留Prefix的参数。 ================================================ FILE: llm-interview/llm-inference.md ================================================ 常见LLM推理服务性能评估指标 https://zhuanlan.zhihu.com/p/704649189 - 首Token生成时间(Time To First Token,简称TTFT):即用户输入提示后,模型生成第一个输出词元(Token)所需的时间。在实时交互中,低时延获取响应非常重要,但在离线工作任务中则不太重要。此指标受处理提示信息并生成首个输出词元所需的时间所驱动。通常,不仅对平均TTFT感兴趣,还包括其分布,如P50、P90、P95和P99等。 - 单个输出Token的生成时间(Time Per Output Token,简称TPOT):即为每个用户的查询生成一个输出词元所需的时间。这一指标与每个用户对模型“速度”的感知相关。例如,TPOT为100毫秒/词元表示每个用户每秒可处理10个词元,或者每分钟处理约450个词元,那么这一速度远超普通人的阅读速度。 - 端到端时延:模型为用户生成完整响应所需的总时间。整体响应时延可使用前两个指标计算得出:时延 = (TTFT)+ (TPOT)*(待生成的词元数)。 - 每分钟完成的请求数:通常情况下,我们都希望系统能够处理并发请求。可能是因为你正在处理来自多个用户的输入或者可能有一个批量推理任务。 单个请求的成本:API 提供商通常会权衡其他指标(如:时延)以换取成本。例如,可以通过在更多GPU上运行相同的模型或使用更高端的GPU来降低时延。 - 最大利用率下每百万Token的成本:比较不同配置的成本(例如,可以在1个A800-80G GPU、1个H800-80G GPU或1个A100-40GB GPU上提供Llama 2-7B模型等),估算给定输出的部署总成本也十分重要。 - 预加载时间:预加载时间只能通过对输入提示的首次oken的生成来间接估算。一些研究发现在250个输入词元和800个输入词元之间,输入词元与TTFT之间似乎并不存在明显的关系,且由于其他原因,它被TTFT中的随机噪声掩盖。通常情况下,输入词元对端到端时延的影响约为输出词元的1%。 - 生成Token吞吐量:推理服务在所有用户请求中每秒可生成的输出词元(Token)数。考虑到无法测量预加载时间,并且总推理时延所花时间更多地取决于生成的Token数量,而不是输入的Token数量,因此,将注意力集中在输出Token上通常是正确的抉择。 - 总吞吐量:包括输入的Token和生成的Token。 对于一些场景,需要考虑端到端推理延迟作为目标,需要注意如下几点: - 输出Token长度决定总体响应延迟:对于总体平均时延,您通常只需将预期最大输出token长度乘以模型每个输出token的总体平均时延即可。 - 输入长度对端到端推理性能并不重要,但对硬件要求很重要:一些研究表明在 MPT 模型中, 512 个输入token增加的延迟小于生成 8 个额外输出Token的延迟。但支持长输入的需求可能会使模型更难以服务。通常建议使用 A100-80GB(或更新版本)来服务 MPT-7B,其最大上下文长度为 2048 个Token。我在 MindIE Service 上,使用羊驼中文数据集,针对百川和千问大模型做了一个简单测试,发现100Token以内,随着输入Token长度的增加,并没有显著增加首Token的时延,如下图所示。 - 端到端推理延迟与模型大小呈次线性关系:在相同的硬件上,较大的模型推理速度较慢,但推理速度比不一定与模型参数量比匹配。例如:MPT-30B 延迟约为 MPT-7B 延迟的 2.5 倍。Llama2-70B 延迟约为 Llama2-13B 延迟的 2 倍。 ================================================ FILE: llm-interview/llm-rlhf.md ================================================ ## RLHF > RLHF 完整训练过程是什么?RL建模过程中涉及到几个模型? > RLHF 过程中RM随着训练过程的进行,得分越来越高,效果就一定好吗? > ================================================ FILE: llm-interview/llm-train.md ================================================ > 模型训练通常关注的性能指标有哪些? 在模型训练过程中,通常关注的性能指标如下: | 指标名称 | 单位 | 指标含义 | | :---- | :----------------- | ----- | | 吞吐率 | samples/s、tokens/s | 单位时间(例如1s)内处理的Token数/训练样本数 | | 单步时间 | s | 执行一个step所花费的时间 | | 线性度、加速比 | values | 单卡训练扩展到多卡,单机拓展到集群的效率度量指标 | | 内存占用 | 百分比 | - | | 带宽占比 | 百分比 | - | | 训练效率 | tokens/day | - | | 浮点运算 | TFLOPS | 每秒浮点运算次数,是计算设备的计算性能指标 | | 模型算力利用率(Model FLOPs Utilization, MFU)| 百分比 | 模型一次前反向计算消耗的矩阵算力与机器算力的比值 | | 硬件算力利用率(Hardware FLOPs Utilization, HFU)| 百分比 | 考虑重计算后,模型一次前反向计算消耗的矩阵算力与机器算力的比值 | 在计算性能指标时,通常的优先级排序为:**吞吐率 > 单步迭代时间 > 线性度 > 内存占用 > 带宽占用 > 训练效率 > 浮点计算次数每秒 > 算力利用率**。 > 混合精度训练使用半精度训练的优缺点 半精度训练优点:跑得快+省显存 半精度训练缺点:精度(下溢+舍入误差)的问题。 使用了半精度训练,一般会采用一些捆绑的技术来弥补半精度的缺点。 - FP32 权重备份:对权重备份一份float32版本的版本,在梯度更新的时候避免float16精度不够而发生舍入误差导致的无效梯度更新,但是这样会占用额外的权重的内存,不过这些显存在一些情况下并不致命也就是了。 - loss scale:由于下溢的问题,也就是训练后期,梯度会很小,float16 容易产生 underflow,所以可以对loss做scale操作,毕竟loss的scale也会作用在梯度上(链式法则),这样一个大的scale比每个梯度都scale下要划算很多。 layer norm的层可能会完全使用float32,因为需要计算一组值的均值和方差,而这需要进行加法和除法运算,所以float16可能会出岔子。 > 使用bf16和fp16进行半精度训练的优缺点 ## DeepSpeed > DeepSpeed的特点是什么?各个 ZeRO Stage 都有什么用? > 流水线并行能与DeepSpeed ZeRO 2/3一起训练吗? https://www.zhihu.com/question/652836990/answer/3468210626 PP + ZeRO 2/3 不推荐一起训练。 PP需要累积梯度(accumulate gradients),但 ZeRO2 需要对梯度进行分块(chunk)。 即使能够实现,也没有真正的性能提升。 将两者结合使用来提高效率并不容易,PP + ZeRO 2 实际上比 ZeRO2(无 PP)更慢且内存效率低。如果用户内存不足,用户可以使用 ZeRO3 代替 ZeRO2 + PP。而正因为如此,在 DeepSpeed 中, PP + ZeRO 2/3 之间不兼容。使用将 PP + ZeRO 1 进行组合使用。 即使该方法效率不高,但是 ColossalAI 为了支持更多的并行训练方法。ColossalAI 还是提供了 ZeRO 3 + PP + TP 一起组合的方案。 参考: - https://github.com/microsoft/DeepSpeed/issues/1110 - https://github.com/microsoft/DeepSpeed/blob/master/deepspeed/runtime/pipe/engine.py#L71 - https://github.com/hpcaitech/ColossalAI/issues/682 - https://github.com/hpcaitech/ColossalAI/pull/477 --- ## PyTorch ================================================ FILE: llm-localization/README.md ================================================ # 大模型国产化适配 ## 昇腾 - [大模型国产化适配-华为昇腾AI全栈软硬件平台总结](https://github.com/liguodongiot/llm-action/blob/main/docs/llm_localization/%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%9B%BD%E4%BA%A7%E5%8C%96%E9%80%82%E9%85%8D-%E5%8D%8E%E4%B8%BA%E6%98%87%E8%85%BEAI%E5%85%A8%E6%A0%88%E8%BD%AF%E7%A1%AC%E4%BB%B6%E5%B9%B3%E5%8F%B0%E6%80%BB%E7%BB%93.md) - https://gitee.com/ascend/ModelLink - 昇腾Ascend处理器相关介绍:https://huahuaboy.blog.csdn.net/article/details/127171363 - AI芯片:华为Ascend(昇腾)910结构分析:https://blog.csdn.net/evolone/article/details/100061616 ## 海光 ## 寒武纪 ================================================ FILE: llm-localization/ascend/FAQ.md ================================================ docker: Error response from daemon: failed to create shim task: OCI runtime create failed: unable to retrieve OCI runtime error (open /var/run/docker/containerd/daemon/io.containerd.runtime.v2.task/moby/579418211a825ef5c7fcf5becdbe90804f0ed7862d9c59663995f9dd463937b4/log.json: no such file or directory): /usr/local/Ascend/Ascend-Docker-Runtime/ascend-docker-runtime did not terminate successfully: exit status 1: 2024/07/24 09:59:29 owner not right /usr/bin/runc 1000 错误信息表明/usr/bin/runc这个文件的所有权不正确,即它不是由root用户拥有或者它的所属用户不是1000。Docker在创建并运行容器时需要runc这个二进制文件,如果权限设置不当,Docker将无法正确执行。 解决办法: 查看权限 ls -lah /usr/bin/runc 修改权限 sudo chown root:root /usr/bin/runc ================================================ FILE: llm-localization/ascend/README.md ================================================ ## 镜像地址 https://quay.io/repository/ascend/cann?tab=tags ## pytorch - https://gitee.com/ascend/pytorch - https://gitee.com/ascend/transformers#fqa - https://gitee.com/ascend/AscendSpeed - https://gitee.com/ascend/AscendSpeed2 - https://gitee.com/ascend/DeepSpeed - https://gitee.com/ascend/Megatron-LM ## mindspore https://gitee.com/mindspore/mindspore https://gitee.com/mindspore/mindformers https://www.mindspore.cn/versions#2.2.10 ``` cd /tmp curl -O https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py37_4.10.3-Linux-$(arch).sh bash Miniconda3-py37_4.10.3-Linux-$(arch).sh -b cd - . ~/miniconda3/etc/profile.d/conda.sh conda init bash ``` ``` conda create -n mindspore_py37 python=3.7.5 -y conda activate mindspore_py37 ``` ``` CentOS 7可以使用以下命令安装。 sudo yum install centos-release-scl sudo yum install devtoolset-7 安装完成后,需要使用如下命令切换到GCC 7。 scl enable devtoolset-7 bash ``` ### 推理 https://www.mindspore.cn/lite/docs/zh-CN/r2.2/quick_start/one_hour_introduction_cloud.html export LITE_HOME=$some_path/mindpsore-lite-2.0.0-linux-x64 export LD_LIBRARY_PATH=$LITE_HOME/runtime/lib:$LITE_HOME/runtime/third_party/dnnl:$LITE_HOME/tools/converter/lib:$LD_LIBRARY_PATH export PATH=$LITE_HOME/tools/converter/converter:$LITE_HOME/tools/benchmark:$PATH ## MindIE 日志 https://www.hiascend.com/document/detail/zh/mindie/21RC2/ref/logreference/mindie_log_0210.html ================================================ FILE: llm-localization/ascend/ascend-c/README.md ================================================ 算子API:https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/80RC2alpha001/quickstart/quickstart/quickstart_18_0001.html --- 192.168.137.101 255.255.255.0 连接开发板: - ssh root@192.168.137.100 - Mind@123 --- cd /home/HwHiAiUser/samples/samples/operator/AddCustomSample/FrameworkLaunch/AddCustom bash build.sh cd build_out ./custom_opp_ubuntu_aarch64.run cd /home/HwHiAiUser/samples/samples/operator/AddCustomSample/FrameworkLaunch/AclNNInvocation bash run.sh ================================================ FILE: llm-localization/ascend/ascend-infra/HCCL.md ================================================ - https://www.hiascend.com/document/detail/zh/canncommercial/80RC1/apiref/hcclapiref/hcclapi_07_0001.html HCCL提供了Python与C++两种语言的接口,其中Python语言的接口用于实现TensorFlow网络在昇腾AI处理器执行分布式优化;C++语言接口用于实现OPBase模式下的框架适配,实现分布式能力,例如HCCL单算子API嵌入到PyTorch后端代码中,PyTorch用户直接使用PyTorch原生集合通信API,即可实现分布式能力。 ================================================ FILE: llm-localization/ascend/ascend-infra/MacOS环境.md ================================================ ``` conda create -n mindspore-venv python=3.8 -y conda activate mindspore-venv pip install torch transformers pip install https://ms-release.obs.cn-north-4.myhuaweicloud.com/2.2.14/MindSpore/cpu/aarch64/mindspore-2.2.14-cp38-cp38-macosx_11_0_arm64.whl --trusted-host ms-release.obs.cn-north-4.myhuaweicloud.com -i https://pypi.tuna.tsinghua.edu.cn/simple ``` ================================================ FILE: llm-localization/ascend/ascend-infra/ascend-dmi.md ================================================ # Ascend-DMI 主要为Atlas产品的标卡、板卡及模组类产品提供带宽测试、算力测试、功耗测试等功能。 本系统通过调用底层DCMI(设备控制管理接口)/DSMI(设备系统管理接口)以及ACL(Ascend Computing Language,昇腾计算语言)相关接口完成相关检测功能,对于系统级别的信息查询通过调用系统提供的通用库来实现,用户使用工具时通过配置参数来实现不同的测试功能。 参考:https://www.hiascend.com/document/detail/zh/canncommercial/321/othertools/ascenddmi/ascenddmi_000002.html ## 带宽测试 ## 算力测试 ## 功耗测试 ## 设备实时状态查询 ## 故障诊断 ## 软硬件版本兼容性测试 ## 设备拓扑检测 ================================================ FILE: llm-localization/ascend/ascend-infra/ascend-docker-runtime.md ================================================ 昇腾docker runtime仓库,在docker容器场景下,使用昇腾NPU,提供更简单的设备和依赖路径挂载方法。 https://gitee.com/ascend/ascend-docker-runtime 安装:https://www.hiascend.com/document/detail/zh/mindx-dl/300/dluserguide/clusterscheduling/dlug_installation_02_000025.html Ascend Docker Runtime组件参考信息说明: https://www.hiascend.com/document/detail/zh/mindx-dl/300/dluserguide/clusterscheduling/dlug_installation_02_000036.html ================================================ FILE: llm-localization/ascend/ascend-infra/ascend-docker.md ================================================ ``` docker login -u 15708484031 ascendhub.huawei.com docker pull ascendhub.huawei.com/public-ascendhub/ascend-mindspore:23.0.RC2-centos7 ``` ================================================ FILE: llm-localization/ascend/ascend-infra/ascend-llm下载.md ================================================ ``` https://hf-mirror.com/ yum install python3-pip virtualenv -p python3 venv-py3 source /home/aicc/venv-py3/bin/activate pip3 install -U huggingface_hub export HF_ENDPOINT=https://hf-mirror.com huggingface-cli download --token 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 --resume-download Baichuan2-7B-Base --local-dir Baichuan2-7B-Base huggingface-cli download --token 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 --resume-download baichuan-inc/Baichuan2-7B-Chat --local-dir Baichuan2-7B-Chat --local-dir-use-symlinks False nohup huggingface-cli download --token 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 --resume-download baichuan-inc/Baichuan2-7B-Chat --local-dir Baichuan2-7B-Chat --local-dir-use-symlinks False > Baichuan2.log 2>&1 & nohup huggingface-cli download --token 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 --resume-download THUDM/chatglm3-6b --local-dir chatglm3-6b-chat --local-dir-use-symlinks False > chatglm3.log 2>&1 & export HF_ENDPOINT=https://hf-mirror.com nohup huggingface-cli download --token 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 --resume-download Qwen/Qwen-72B-Chat --local-dir Qwen-72B-Chat --local-dir-use-symlinks False > qwen-72b.log 2>&1 & export HF_ENDPOINT=https://hf-mirror.com nohup huggingface-cli download --token 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 --resume-download Qwen/Qwen-72B-Chat --local-dir Qwen-72B-Chat --local-dir-use-symlinks False > qwen-72b.log 2>&1 & export HF_ENDPOINT=https://hf-mirror.com nohup huggingface-cli download --token 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 --resume-download Qwen/Qwen1.5-14B-Chat --local-dir Qwen1.5-14B-Chat --local-dir-use-symlinks False > Qwen1.5-14B-Chat.log 2>&1 & export HF_ENDPOINT=https://hf-mirror.com nohup huggingface-cli download --token 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 --resume-download Qwen/Qwen1.5-7B-Chat --local-dir Qwen1.5-7B-Chat --local-dir-use-symlinks False > Qwen1.5-7B-Chat.log 2>&1 & export HF_ENDPOINT=https://hf-mirror.com nohup huggingface-cli download --token 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 --resume-download Qwen/Qwen1.5-72B-Chat --local-dir Qwen1.5-72B-Chat --local-dir-use-symlinks False > Qwen1.5-72B-Chat.log 2>&1 & export HF_ENDPOINT=https://hf-mirror.com nohup huggingface-cli download --token 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 --resume-download baichuan-inc/Baichuan2-13B-Chat --local-dir Baichuan2-13B-Chat --local-dir-use-symlinks False > Baichuan2-13B-Chat.log 2>&1 & ``` ``` cd /home/aicc mkdir -p ./model_from_hf/Baichuan2-7B-Chat/ cd ./model_from_hf/Baichuan2-7B-Chat/ wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/config.json wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/configuration_baichuan.py wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/generation_utils.py wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/modeling_baichuan.py wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/pytorch_model-00001-of-00002.bin wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/pytorch_model-00002-of-00002.bin wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/pytorch_model.bin.index.json wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/quantizer.py wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/special_tokens_map.json wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/tokenization_baichuan.py wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/tokenizer.model wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Base/resolve/main/tokenizer_config.json cd ../../ ``` ``` cd /home/aicc mkdir -p ./model_from_hf/Baichuan2-7B-Chat/ cd ./model_from_hf/Baichuan2-7B-Chat/ wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/config.json wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/configuration_baichuan.py wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/generation_config.json wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/generation_utils.py wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/modeling_baichuan.py wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/pytorch_model.bin wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/quantizer.py wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/special_tokens_map.json wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/tokenization_baichuan.py wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/tokenizer.model wget https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/resolve/main/tokenizer_config.json cd ../../ ``` ## 拷贝模型 ``` rsync -P --rsh=ssh -r root@192.xxx.16.210:/home/model_from_hf/Qwen1.5-72B/ ./ scp -r root@192.xxx.16.210:/home/model_from_hf/Qwen1.5-72B/ ./ ``` ================================================ FILE: llm-localization/ascend/ascend-infra/ascend-npu-smi.md ================================================ - https://support.huawei.com/enterprise/zh/doc/EDOC1100288566/e39bbfe6 ``` npu-smi info -t device-share -i 1 ``` ## GPU/Memory 使用率 ``` npu-smi info -t common -i 1 NPU ID : 1 Chip Count : 1 Chip ID : 0 Memory Usage Rate(%) : 0 HBM Usage Rate(%) : 91 Aicore Usage Rate(%) : 6 Aicore Freq(MHZ) : 1800 Aicore curFreq(MHZ) : 1800 Aicore Count : 20 Temperature(C) : 46 NPU Real-time Power(W) : 130.4 Chip Name : mcu Temperature(C) : 40 npu-smi info -t common -i 7 NPU ID : 7 Chip Count : 1 Chip ID : 0 Memory Usage Rate(%) : 0 HBM Usage Rate(%) : 82 Aicore Usage Rate(%) : 70 Aicore Freq(MHZ) : 1800 Aicore curFreq(MHZ) : 1800 Aicore Count : 20 Temperature(C) : 66 NPU Real-time Power(W) : 331.1 Chip Name : mcu Temperature(C) : 58 ``` ## 查询设备1所有芯片的统计信息 ``` npu-smi info -t usages -i 1 NPU ID : 1 Chip Count : 1 DDR Capacity(MB) : 15079 DDR Usage Rate(%) : 14 DDR Hugepages Total(page) : 0 DDR Hugepages Usage Rate(%) : 0 HBM Capacity(MB) : 32768 HBM Usage Rate(%) : 0 Aicore Usage Rate(%) : 0 Aicpu Usage Rate(%) : 0 Ctrlcpu Usage Rate(%) : 0 DDR Bandwidth Usage Rate(%) : 0 HBM Bandwidth Usage Rate(%) : 0 Chip ID : 0 ``` ## 查看和修改网卡配置 ``` hccn_tool -i 3 -status -g Netdev status:Settings for eth3: Supported ports: [ FIBRE ] Supported link modes: 40000baseCR4/Full 40000baseSR4/Full 40000baseLR4/Full 25000baseCR/Full 25000baseSR/Full 50000baseCR2/Full 100000baseSR4/Full 100000baseCR4/Full 100000baseLR4_ER4/Full 50000baseSR2/Full 1000baseX/Full 10000baseCR/Full 10000baseSR/Full 10000baseLR/Full 50000baseLR_ER_FR/Full 200000baseSR4/Full 200000baseLR4_ER4_FR4/Full 200000baseCR4/Full Supported pause frame use: Symmetric Supports auto-negotiation: No Supported FEC modes: None RS Advertised link modes: Not reported Advertised pause frame use: No Advertised auto-negotiation: No Advertised FEC modes: None RS Speed: 200000Mb/s Duplex: Full Auto-negotiation: off Port: Direct Attach Copper PHYAD: 0 Transceiver: internal Current message level: 0x00000036 (54) probe link ifdown ifup Link detected: yes ``` ## 查看网卡的 IP 地址和路由 ``` > hccn_tool -i 3 -ip -g ipaddr:10.20.11.24 netmask:255.255.255.0 > hccn_tool -i 3 -route -g Routing table: Destination Gateway Genmask Flags Metric Ref Use Iface 10.20.11.0 * 255.255.255.0 U 0 0 0 eth3 127.0.0.1 * 255.255.255.255 UH 0 0 0 lo 192.168.1.0 * 255.255.255.0 U 0 0 0 end3v0 192.168.2.0 * 255.255.255.0 U 0 0 0 end3v0 ``` RDMA 网卡的启动配置其实在配置文件 ``` > cat /etc/hccn.conf # RDMA 网卡 0-7 的配置 address_0=10.20.11.11 netmask_0=255.255.255.0 address_1=10.20.11.12 netmask_1=255.255.255.0 address_2=10.20.11.13 netmask_2=255.255.255.0 address_3=10.20.11.14 netmask_3=255.255.255.0 address_4=10.20.11.15 netmask_4=255.255.255.0 address_5=10.20.11.16 netmask_5=255.255.255.0 address_6=10.20.11.17 netmask_6=255.255.255.0 address_7=10.20.11.18 netmask_7=255.255.255.0 ``` ## 查询所有芯片闪存信息 ``` npu-smi info -t flash -i 0 NPU ID : 0 Chip Count : 1 Flash Count : 1 Flash ID : 1730504 Manufacturer ID : 0xC8 Capacity(MB) : 64 Chip ID : 0 ``` ## 查询设备1的所有芯片的内存信息。 ``` npu-smi info -t memory -i 1 NPU ID : 1 Chip Count : 1 DDR Capacity(MB) : 0 DDR Clock Speed(MHz) : 0 HBM Capacity(MB) : 32768 HBM Clock Speed(MHz) : 1600 HBM Temperature(C) : 35 HBM Manufacturer ID : 0x57 Chip ID : 0 ``` ## RDMA ping ``` > hccn_tool -i 3 -ping -g address 10.20.11.16 device 3 PING 10.20.11.16 recv seq=0,time=0.137000ms recv seq=1,time=0.046000ms recv seq=2,time=0.058000ms 3 packets transmitted, 3 received, 0.00% packet loss ``` ================================================ FILE: llm-localization/ascend/ascend-infra/docker环境升级cann.md ================================================ ``` docker login -u 157xxx4031 ascendhub.huawei.com docker pull ascendhub.huawei.com/public-ascendhub/ascend-mindspore:23.0.0-A2-ubuntu18.04 ``` ``` https://www.hiascend.com/zh/software/cann/community-history wget -c https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/Milan-ASL/Milan-ASL%20V100R001C18B800TP015/Ascend-cann-kernels-910b_8.0.RC2.alpha001_linux.run wget -c https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/Milan-ASL/Milan-ASL%20V100R001C18B800TP015/Ascend-cann-toolkit_8.0.RC2.alpha001_linux-aarch64.run ``` ``` docker stop pytorch_ubuntu_dev docker rm -f pytorch_ubuntu_upgrade docker run -it -u root \ --name pytorch_ubuntu_upgrade \ --network host \ --shm-size 4G \ -e ASCEND_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \ -v /etc/localtime:/etc/localtime \ -v /var/log/npu/:/usr/slog \ -v /usr/bin/hccn_tool:/usr/bin/hccn_tool \ -v /data/containerd/workspace/:/workspace \ ascendhub.huawei.com/public-ascendhub/ascend-mindspore:23.0.0-A2-ubuntu18.04 \ /bin/bash docker start pytorch_ubuntu_upgrade docker exec -it pytorch_ubuntu_upgrade bash ``` ``` cd /usr/local/Ascend/ascend-toolkit/7.0.0/aarch64-linux/script/ ./uninstall.sh chmod +x Ascend-cann-toolkit_8.0.RC2.alpha001_linux-aarch64.run ./Ascend-cann-toolkit_8.0.RC2.alpha001_linux-aarch64.run --check ./Ascend-cann-toolkit_8.0.RC2.alpha001_linux-aarch64.run --install . /usr/local/Ascend/ascend-toolkit/set_env.sh ``` ``` ./Ascend-cann-kernels-910b_8.0.RC2.alpha001_linux.run --install --feature=aclnn_ops_train ``` ``` . /usr/local/Ascend/ascend-toolkit/set_env.sh ``` ``` bash Miniconda3-py39_24.4.0-0-Linux-aarch64.sh -p /workspace/installs/conda-upgrade conda init source ~/.bashrc export PATH=/root/miniconda3/bin:$PATH conda list conda create -n llm-dev python=3.9 conda activate llm-dev ``` ``` pip3 install torch==2.1.0 pip3 install pyyaml setuptools pip3 install torch-npu==2.1.0.post3 pip3 install numpy attrs decorator psutil absl-py cloudpickle psutil scipy synr tornado . /usr/local/Ascend/ascend-toolkit/set_env.sh import torch import torch_npu x = torch.randn(2, 2).npu() y = torch.randn(2, 2).npu() z = x.mm(y) print(z) ``` ``` pip install --no-cache-dir -r requirements-npu.txt && rm -rf ~/.cache/pip/* && conda clean -all ``` ``` docker start pytorch_ubuntu_upgrade docker exec -it pytorch_ubuntu_upgrade bash . /usr/local/Ascend/ascend-toolkit/set_env.sh conda activate llm-dev ``` docker tag harbor.llm.io/base/llm-train-unify:v1-20240603 harbor.llm.io/base/llm-train-unify:v1-20240603 ================================================ FILE: llm-localization/ascend/ascend-infra/network.md ================================================ ## 集群网络 Atlas 900 AI集群采用“HCCS、 PCIe 4.0、100G以太”三类高速互联方式,百TB全互联无阻塞专属参数同步网络,降低网络时延,梯度同步时延缩短10~70%。 在AI服务器内部,昇腾910 AI处理器之间通过HCCS高速总线互联;昇腾910 AI处理器和CPU之间以最新的PCIe 4.0(速率16Gbps)技术互联,其速率是业界主流采用的PCIe 3.0(8.0Gbps)技术的两倍,使得数据传输更加快速和高效。在集群层面,采用面向数据中心的CloudEngine 8800系列交换机,提供单端口100Gbps的交换速率,将集群内的所有AI服务器接入高速交换网络。 独创iLossless 智能无损交换算法,对集群内的网络流量进行实时的学习训练,实现网络0丢包与E2E μs级时延。 ## 系统级调优 Atlas 900 AI集群通过华为集合通信库和作业调度平台,整合HCCS、 PCIe 4.0 和100G RoCE三种高速接口,充分释放昇腾910 AI处理器的强大性能。 华为集合通信库提供训练网络所需的分布式并行库,通信库+网络拓扑+训练算法进行系统级调优,实现集群线性度>80%,极大提升了作业调度效率。 ================================================ FILE: llm-localization/ascend/ascend-infra/npu监控.md ================================================ - AI模型运维——GPU性能监控NVML和DCGM - https://www.cnblogs.com/maxgongzuo/p/12582286.html dcgm exporter 监控GPU NPU-Exporter 监控NPU ================================================ FILE: llm-localization/ascend/ascend-infra/操作系统.md ================================================ # Kylin ``` > cat /etc/os-release NAME="Kylin Linux Advanced Server" VERSION="V10 (Tercel)" ID="kylin" VERSION_ID="V10" PRETTY_NAME="Kylin Linux Advanced Server V10 (Tercel)" ANSI_COLOR="0;31" ``` ``` > yum install dmidecode > dmidecode -t system # dmidecode 3.2 Getting SMBIOS data from sysfs. SMBIOS 3.3.0 present. # SMBIOS implementations newer than version 3.2.0 are not # fully supported by this version of dmidecode. Handle 0x0001, DMI type 1, 27 bytes System Information Manufacturer: Huawei Product Name: A800I A2 Version: To be filled by O.E.M. Serial Number: 2102314VFG10Q1100025 UUID: a6202cac-b04f-8889-ee11-4ab078e0b272 Wake-up Type: Power Switch SKU Number: To be filled by O.E.M. Family: To be filled by O.E.M. Handle 0x0005, DMI type 32, 11 bytes System Boot Information Status: No errors detected ``` # OpenEuler - https://repo.openeuler.org/openEuler-24.03-LTS/OS/aarch64/Packages/ # Ubuntu 更换源 - https://blog.csdn.net/zwcslj/article/details/134322879 ``` 先备份旧的源 设置新的镜像源 vim /etc/apt/sources.list 更新软件包列表并升级已安装的软件包 apt-get update apt-get upgrade ``` ``` docker pull ubuntu:20.04 docker pull ubuntu:22.04 ``` ================================================ FILE: llm-localization/ascend/ascend-infra/昇腾卡-soc版本.md ================================================ ``` SOC版本:设备类型 100: "910PremiumA", 101: "910ProA", 102: "910A", 103: "910ProB", 104: "910B", 200: "310P1", 201: "310P2", 202: "310P3", 203: "310P4", 220: "910B1", 221: "910B2", 222: "910B3", 223: "910B4", 240: "310B1", 241: "310B2", 242: "310B3", 250: "910C1", 251: "910C2", 252: "910C3", 253: "910C4" ``` ================================================ FILE: llm-localization/ascend/ascend-infra/昇腾卡注意事项.md ================================================ --privileged 特权模型下,昇腾或者英伟达的 docker runtime 中会默认分配本机所有卡。 - ASCEND_VISIBLE_DEVICES 容器级控制卡 - ASCEND_RT_VISIBLE_DEVICES 进程级控制卡 类似于 CUDA_VISIBLE_DEVICES ================================================ FILE: llm-localization/ascend/ascend-infra/昇腾镜像.md ================================================ ## 镜像仓库 - https://ascendhub.huawei.com/#/index - https://www.hiascend.com/developer/ascendhub/ - http://mirrors.cn-central-221.ovaijisuan.com/mirrors.html ``` docker pull --platform=arm64 swr.cn-central-221.ovaijisuan.com/dxy/pytorch2_1_0_kernels:PyTorch2.1.0-cann7.0.0.alpha003_py_3.9-euler_2.8.3-64GB ``` ``` docker pull --platform=arm64 swr.cn-central-221.ovaijisuan.com/mindformers/mindformers1.3_mindspore2.4:20241114 ``` ## ascend-mindspore A1支持A300T-9000、A800-9000、A800-9010和Atlas 300T Pro,A2支持Atlas 900 A2 PoD、Atlas 800T A2、Atlas 200T A2 Box16和Atlas 300T A2 ``` # 910A docker login -u 157xxxx4031 ascendhub.huawei.com docker pull ascendhub.huawei.com/public-ascendhub/ascend-mindspore:23.0.0-A1-centos7 docker pull --platform=arm64 ascendhub.huawei.com/public-ascendhub/ascend-mindspore:23.0.0-A1-ubuntu18.04 ``` ``` docker pull --platform=arm64 swr.cn-central-221.ovaijisuan.com/mindformers/mindformers1.3_mindspore2.4:20241114 ``` ================================================ FILE: llm-localization/ascend/ascend-infra/服务器配置.md ================================================ 最低配置: ``` Atlas 800 9000 A2 CPU:4 * 鲲鹏920 48核@2.6GHZ GPU:8 * Ascend 910B4 内存:512G 硬盘:2 * 480G SSD,2 * 1.92 T PCIe SSD ``` 推荐配置: ``` Atlas 800 9000 A2 CPU:4*鲲鹏920 48核@2.6GHZ GPU:8 * Ascend 910B3 内存:1T 硬盘:2 * 960G SSD,2 * 3.84T PCIe SSD ``` ================================================ FILE: llm-localization/ascend/ascend-infra/环境安装.md ================================================ ## 安装Python-3.9.2 ``` wget https://www.python.org/ftp/python/3.9.2/Python-3.9.2.tgz tar -zxvf Python-3.9.2.tgz cd Python-3.9.2 ./configure --prefix=/usr/local/python3.9.2 --with-ssl-default-suites=openssl --enable-shared CFLAGS=-fPIC make sudo make install #用于设置python3.9.2库文件路径 export LD_LIBRARY_PATH=/usr/local/python3.9.2/lib:$LD_LIBRARY_PATH #如果用户环境存在多个python3版本,则指定使用python3.9.2版本 export PATH=/usr/local/python3.9.2/bin:$PATH python3 --version pip3 --version ``` ## ================================================ FILE: llm-localization/ascend/ascend-infra/达芬奇架构.md ================================================ - 基本概念: https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/80RC2alpha001/devguide/opdevg/ascendcopdevg/atlas_ascendc_10_0009.html ================================================ FILE: llm-localization/ascend/ascend910-env-install.md ================================================ ## 查看操作系统 ``` >cat /etc/os-release PRETTY_NAME="Ubuntu 22.04.3 LTS" NAME="Ubuntu" VERSION_ID="22.04" VERSION="22.04.3 LTS (Jammy Jellyfish)" VERSION_CODENAME=jammy ID=ubuntu ID_LIKE=debian HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" UBUNTU_CODENAME=jammy > uname -a Linux nodo-1 5.15.0-78-generic #85-Ubuntu SMP Fri Jul 7 15:29:30 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux ``` ## 查看服务器的型号信息 ``` # yum install dmidecode > apt-get install dmidecode > dmidecode -t system # dmidecode 3.3 Getting SMBIOS data from sysfs. SMBIOS 3.3.0 present. Handle 0x0001, DMI type 1, 27 bytes System Information Manufacturer: Huawei Product Name: A800 9000 A2 Version: To be filled by O.E.M. Serial Number: 2102314RHT10P81000xx UUID: a61414fb-b04f-b618-ee11-c0441xx24b6d Wake-up Type: Power Switch SKU Number: To be filled by O.E.M. Family: To be filled by O.E.M. Handle 0x0005, DMI type 32, 11 bytes System Boot Information Status: No errors detected - Atlas 900 RCK A2 Compute Node - A800 9000 A2 ``` 以下操作如无特别说明,都是针对EulerOS系统。 ## 安装驱动与固件 先安装驱动,再安装固件。 ``` chmod +x Ascend-hdk-910-npu-driver_23.0.rc1_linux-aarch64.run ./Ascend-hdk-910-npu-driver_23.0.rc1_linux-aarch64.run --full --install-path=/usr/local/Ascend ```
详细输出

``` Verifying archive integrity... 100% SHA256 checksums are OK. All good. Uncompressing ASCEND DRIVER RUN PACKAGE 100% [Driver] [2023-07-10 22:24:33] [INFO]Start time: 2023-07-10 22:24:33 [Driver] [2023-07-10 22:24:33] [INFO]LogFile: /var/log/ascend_seclog/ascend_install.log [Driver] [2023-07-10 22:24:33] [INFO]OperationLogFile: /var/log/ascend_seclog/operation.log [Driver] [2023-07-10 22:24:33] [WARNING]Do not power off or restart the system during the installation/upgrade [Driver] [2023-07-10 22:24:33] [INFO]set username and usergroup, HwHiAiUser:HwHiAiUser [Driver] [2023-07-10 22:24:34] [INFO]driver install type: Direct [Driver] [2023-07-10 22:24:34] [INFO]upgradePercentage:10% [Driver] [2023-07-10 22:24:38] [INFO]upgradePercentage:30% [Driver] [2023-07-10 22:24:38] [INFO]upgradePercentage:40% [Driver] [2023-07-10 22:24:40] [INFO]upgradePercentage:90% [Driver] [2023-07-10 22:24:40] [INFO]Waiting for device startup... [Driver] [2023-07-10 22:24:42] [INFO]Device startup success [Driver] [2023-07-10 22:24:53] [INFO]upgradePercentage:100% [Driver] [2023-07-10 22:25:04] [INFO]Driver package installed successfully! The new version takes effect immediately. [Driver] [2023-07-10 22:25:04] [INFO]End time: 2023-07-10 22:25:04 ```

``` chmod +x Ascend-hdk-910-npu-firmware_6.3.0.1.241.run ./Ascend-hdk-910-npu-firmware_6.3.0.1.241.run --check ./Ascend-hdk-910-npu-firmware_6.3.0.1.241.run --full ```
详细输出

``` Verifying archive integrity... 100% SHA256 checksums are OK. All good. Uncompressing ASCEND-HDK-910-NPU FIRMWARE RUN PACKAGE 100% [Firmware] [2023-07-10 22:27:29] [INFO]Start time: 2023-07-10 22:27:29 [Firmware] [2023-07-10 22:27:29] [INFO]LogFile: /var/log/ascend_seclog/ascend_install.log [Firmware] [2023-07-10 22:27:29] [INFO]OperationLogFile: /var/log/ascend_seclog/operation.log [Firmware] [2023-07-10 22:27:29] [WARNING]Do not power off or restart the system during the installation/upgrade [Firmware] [2023-07-10 22:27:34] [INFO]upgradePercentage: 0% [Firmware] [2023-07-10 22:27:42] [INFO]upgradePercentage: 0% [Firmware] [2023-07-10 22:27:51] [INFO]upgradePercentage: 0% [Firmware] [2023-07-10 22:27:57] [INFO]upgradePercentage: 100% [Firmware] [2023-07-10 22:27:57] [INFO]The firmware of [8] chips are successfully upgraded. [Firmware] [2023-07-10 22:27:57] [INFO]Firmware package installed successfully! Reboot now or after driver installation for the installation/upgrade to take effect. [Firmware] [2023-07-10 22:27:57] [INFO]End time: 2023-07-10 22:27:57 ```

安装驱动和固件后,根据系统提示信息决定是否重启服务器,若需要重启系统,请执行以下命令;否则,请跳过此步骤。 ``` reboot ``` ## 卸载固件与驱动 驱动和固件的卸载没有先后顺序要求。 查询安装路径: ``` > cat /etc/ascend_install.info UserName=HwHiAiUser UserGroup=HwHiAiUser Firmware_Install_Type=full Firmware_Install_Path_Param=/usr/local/Ascend Driver_Install_Type=full Driver_Install_Path_Param=/usr/local/Ascend Driver_Install_For_All=yes ``` 卸载固件: ``` # /usr/local/Ascend/firmware/script/uninstall.sh --uninstall /usr/local/Ascend/firmware/script/uninstall.sh --quiet ``` 卸载驱动: ``` # /usr/local/Ascend/driver/script/uninstall.sh --uninstall /usr/local/Ascend/driver/script/uninstall.sh --quiet ``` 卸载驱动和固件后,根据系统提示信息决定是否重启服务器,若需要重启系统,请执行以下命令;否则,请跳过此步骤。 ``` reboot ``` ## 安装开发工具集(CANN) 下载: ``` wget -c https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%206.3.RC1/Ascend-cann-kernels-910_6.3.RC1_linux.run wget -c https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%206.3.RC1/Ascend-cann-toolkit_6.3.RC1_linux-aarch64.run ``` 安装: ``` chmod +x Ascend-cann-toolkit_6.3.RC1_linux-aarch64.run ./Ascend-cann-toolkit_6.3.RC1_linux-aarch64.run --install --install-for-all ```
详细输出

``` Verifying archive integrity... 100% SHA256 checksums are OK. All good. Uncompressing ASCEND_RUN_PACKAGE 100% [Toolkit] [20230710-22:44:15] [INFO] LogFile:/var/log/ascend_seclog/ascend_toolkit_install.log [Toolkit] [20230710-22:44:15] [INFO] install start [Toolkit] [20230710-22:44:15] [INFO] The installation path is /usr/local/Ascend. [Toolkit] [20230710-22:44:15] [INFO] install package CANN-runtime-6.3.0.1.241-linux.aarch64.run start [Toolkit] [20230710-22:44:21] [INFO] CANN-runtime-6.3.0.1.241-linux.aarch64.run --full --quiet --nox11 --install-for-all install success [Toolkit] [20230710-22:44:21] [INFO] install package CANN-compiler-6.3.0.1.241-linux.aarch64.run start WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv [Toolkit] [20230710-22:44:56] [INFO] CANN-compiler-6.3.0.1.241-linux.aarch64.run --full --pylocal --quiet --nox11 --install-for-all install success [Toolkit] [20230710-22:44:56] [INFO] install package CANN-opp-6.3.0.1.241-linux.aarch64.run start [Toolkit] [20230710-22:45:39] [INFO] CANN-opp-6.3.0.1.241-linux.aarch64.run --full --quiet --nox11 --install-for-all install success [Toolkit] [20230710-22:45:39] [INFO] install package CANN-toolkit-6.3.0.1.241-linux.aarch64.run start [Toolkit] [20230710-22:46:20] [INFO] CANN-toolkit-6.3.0.1.241-linux.aarch64.run --full --pylocal --quiet --nox11 --install-for-all install success [Toolkit] [20230710-22:46:20] [INFO] install package CANN-aoe-6.3.0.1.241-linux.aarch64.run start [Toolkit] [20230710-22:46:23] [INFO] CANN-aoe-6.3.0.1.241-linux.aarch64.run --full --quiet --nox11 --install-for-all install success [Toolkit] [20230710-22:46:23] [INFO] install package Ascend-mindstudio-toolkit_6.0.RC1_linux-aarch64.run start [Toolkit] [20230710-22:46:30] [INFO] Ascend-mindstudio-toolkit_6.0.RC1_linux-aarch64.run --full --quiet --nox11 --install-for-all install success [Toolkit] [20230710-22:46:30] [INFO] install package Ascend-test-ops_6.3.RC1_linux.run start [Toolkit] [20230710-22:46:30] [INFO] Ascend-test-ops_6.3.RC1_linux.run --full --quiet --nox11 --install-for-all install success [Toolkit] [20230710-22:46:30] [INFO] install package Ascend-pyACL_6.3.RC1_linux-aarch64.run start [Toolkit] [20230710-22:46:30] [INFO] Ascend-pyACL_6.3.RC1_linux-aarch64.run --full --quiet --nox11 --install-for-all install success [Toolkit] [20230710-22:46:30] [INFO] install package CANN-ncs-6.3.0.1.241-linux.aarch64.run start [Toolkit] [20230710-22:46:33] [INFO] CANN-ncs-6.3.0.1.241-linux.aarch64.run --full --quiet --nox11 --install-for-all install success =========== = Summary = =========== Driver: Installed in /usr/local/Ascend/driver. Toolkit: Ascend-cann-toolkit_6.3.RC1_linux-aarch64 install success, installed in /usr/local/Ascend. Please make sure that the environment variables have been configured. - To take effect for all users, you can add "source /usr/local/Ascend/ascend-toolkit/set_env.sh" to /etc/profile. - To take effect for current user, you can exec command below: source /usr/local/Ascend/ascend-toolkit/set_env.sh or add "source /usr/local/Ascend/ascend-toolkit/set_env.sh" to ~/.bashrc. ```

需要注意的是,NPU驱动、固件以及CANN软件安装完成之后,需**设置环境变量**: 如果昇腾AI处理器配套软件包安装在默认路径,则直接使用如下命名直接设置即可。 ``` # 建议配置在~/.bashrc中 source /usr/local/Ascend/ascend-toolkit/set_env.sh ``` 如果昇腾AI处理器配套软件包**没有安装在默认路径**,安装好 MindSpore 之后,需要导出Runtime相关环境变量,下述命令中`LOCAL_ASCEND=/usr/local/Ascend`的`/usr/local/Ascend`表示配套软件包的安装路径,**需将其改为配套软件包的实际安装路径**。 ``` # control log level. 0-DEBUG, 1-INFO, 2-WARNING, 3-ERROR, 4-CRITICAL, default level is WARNING. export GLOG_v=2 # Conda environmental options LOCAL_ASCEND=/usr/local/Ascend # the root directory of run package # lib libraries that the run package depends on export LD_LIBRARY_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/lib64:${LOCAL_ASCEND}/driver/lib64:${LOCAL_ASCEND}/ascend-toolkit/latest/opp/built-in/op_impl/ai_core/tbe/op_tiling:${LD_LIBRARY_PATH} # Environment variables that must be configured ## TBE operator implementation tool path export TBE_IMPL_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/opp/built-in/op_impl/ai_core/tbe ## OPP path export ASCEND_OPP_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/opp ## AICPU path export ASCEND_AICPU_PATH=${ASCEND_OPP_PATH}/.. ## TBE operator compilation tool path export PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/compiler/ccec_compiler/bin/:${PATH} ## Python library that TBE implementation depends on export PYTHONPATH=${TBE_IMPL_PATH}:${PYTHONPATH} ``` ## 升级GCC以及安装Cmake ``` # 安装GCC sudo yum install gcc -y # 安装Cmake, aarch64使用 curl -O https://cmake.org/files/v3.19/cmake-3.19.8-Linux-aarch64.sh sudo mkdir /usr/local/cmake-3.19.8 sudo bash cmake-3.19.8-Linux-*.sh --prefix=/usr/local/cmake-3.19.8 --exclude-subdir echo -e "export PATH=/usr/local/cmake-3.19.8/bin:\$PATH" >> ~/.bashrc source ~/.bashrc ``` ## 安装 bypy,下载百度网盘数据 ``` 安装模块 pip install bypy -i https://pypi.douban.com/simple 下载数据 1.获取网页 执行下面的命令,用浏览器打开please visit下面的网页 bypy info 2.登录账号获取秘钥 3.返回linux终端输入秘钥 4. 文件转移 授权之后,你的百度云盘的我的应用数据目录下后多出一个bypy文件夹,将你要下载的数据移动到里面即可 5. 下载数据 bypy downdir -v ``` ## 安装 Dokcer ``` # https://www.hiascend.com/document/detail/zh/quick-installation/23.0.RC1/quickinstg/800_3010/quickinstg_800_3010_0028.html # https://www.hiascend.com/document/detail/zh/quick-installation/23.0.RC1/quickinstg/800_3010/quickinstg_800_3010_0012.html yum makecache yum install -y docker systemctl start docker ``` ## 安装 tree ``` yum install -y tree ``` ## 安装 git-lfs EulerOS和openEuler使用以下命令安装: ``` # 根据系统架构选择相应的版本下载。 curl -OL https://github.com/git-lfs/git-lfs/releases/download/v3.1.2/git-lfs-linux-arm64-v3.1.2.tar.gz # 解压并安装。 mkdir git-lfs tar xf git-lfs-linux-*-v3.1.2.tar.gz -C git-lfs cd git-lfs sudo bash install.sh ``` ## SSH免密登录 ``` # 本机免密 ssh-keygen -t rsa cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys # 多机免密 scp -r /root/.ssh/ 183.66.251.xxx:/root ssh 183.66.251.xxx ``` ## Vim中文乱码 修改vimrc文件: - vim /etc/vim/vimrc - vim /etc/vimrc ``` # 在vimrc文件中添加如下内容 set fileencodings=utf-8,gbk,utf-16le,cp1252,iso-8859-15,ucs-bom set termencoding=utf-8 set encoding=utf-8 ``` ## 安装MindSpore 配置环境变量 如果昇腾AI处理器配套软件包没有安装在默认路径,安装好MindSpore之后,需要导出Runtime相关环境变量。 LOCAL_ASCEND=/usr/local/Ascend的/usr/local/Ascend表示配套软件包的安装路径,需注意将其改为配套软件包的实际安装路径。 ``` # control log level. 0-DEBUG, 1-INFO, 2-WARNING, 3-ERROR, 4-CRITICAL, default level is WARNING. export GLOG_v=2 # Conda environmental options LOCAL_ASCEND=/usr/local/Ascend # the root directory of run package # lib libraries that the run package depends on export LD_LIBRARY_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/lib64:${LOCAL_ASCEND}/driver/lib64:${LOCAL_ASCEND}/ascend-toolkit/latest/opp/built-in/op_impl/ai_core/tbe/op_tiling:${LD_LIBRARY_PATH} # Environment variables that must be configured ## TBE operator implementation tool path export TBE_IMPL_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/opp/built-in/op_impl/ai_core/tbe ## OPP path export ASCEND_OPP_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/opp ## AICPU path export ASCEND_AICPU_PATH=${ASCEND_OPP_PATH}/.. ## TBE operator compilation tool path export PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/compiler/ccec_compiler/bin/:${PATH} ## Python library that TBE implementation depends on export PYTHONPATH=${TBE_IMPL_PATH}:${PYTHONPATH} ``` 验证是否成功安装 方法一: ``` python -c "import mindspore;mindspore.set_context(device_target='Ascend');mindspore.run_check()" ``` 方法二: ``` import numpy as np import mindspore as ms import mindspore.ops as ops ms.set_context(device_target="Ascend") x = ms.Tensor(np.ones([1,3,3,4]).astype(np.float32)) y = ms.Tensor(np.ones([1,3,3,4]).astype(np.float32)) print(ops.add(x, y)) ``` ### 互连-topo ``` npu-smi info -t topo NPU0 NPU1 NPU2 NPU3 NPU4 NPU5 NPU6 NPU7 CPU Affinity NPU0 X HCCS HCCS HCCS HCCS HCCS HCCS HCCS 144-167 NPU1 HCCS X HCCS HCCS HCCS HCCS HCCS HCCS 144-167 NPU2 HCCS HCCS X HCCS HCCS HCCS HCCS HCCS 96-119 NPU3 HCCS HCCS HCCS X HCCS HCCS HCCS HCCS 96-119 NPU4 HCCS HCCS HCCS HCCS X HCCS HCCS HCCS 0-23 NPU5 HCCS HCCS HCCS HCCS HCCS X HCCS HCCS 0-23 NPU6 HCCS HCCS HCCS HCCS HCCS HCCS X HCCS 48-71 NPU7 HCCS HCCS HCCS HCCS HCCS HCCS HCCS X 48-71 Legend: X = Self SYS = Path traversing PCIe and NUMA nodes. Nodes are connected through SMP, such as QPI, UPI. PHB = Path traversing PCIe and the PCIe host bridge of a CPU. PIX = Path traversing a single PCIe switch PXB = Path traversing multipul PCIe switches HCCS = Connection traversing HCCS. NA = Unknown relationship. ``` ================================================ FILE: llm-localization/ascend/fabric-insight/README.md ================================================ ================================================ FILE: llm-localization/ascend/firefly-ascend.md ================================================ Xformers ``` conda activate llm-dev source /usr/local/Ascend/ascend-toolkit/set_env.sh cd /workspace/llm-train ``` ``` docker exec -it pytorch_ubuntu_dev bash conda activate llm-dev source /usr/local/Ascend/ascend-toolkit/set_env.sh cd /workspace/llm-train sh run_all_npu.sh ``` ``` sh run_lora_npu.sh ``` ``` docker start pytorch_ubuntu_upgrade docker exec -it pytorch_ubuntu_upgrade bash . /usr/local/Ascend/ascend-toolkit/set_env.sh conda activate llm-dev cd /workspace/llm-train sh run_all_npu.sh ``` ================================================ FILE: llm-localization/ascend/mindformers/README.md ================================================ ``` docker pull --platform=arm64 swr.cn-central-221.ovaijisuan.com/dxy/mindspore_kernels:MindSpore2.2.10-cann7.0.0beta1_py_3.9-euler_2.8.3-32GB ``` ``` docker run -it -u root \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/Ascend/toolbox:/usr/local/Ascend/toolbox \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \ -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \ -v /home/aicc:/home/ma-user/work/aicc \ --name mindspore_ma-4-7 \ --entrypoint=/bin/bash \ swr.cn-central-221.ovaijisuan.com/dxy/mindspore_kernels:MindSpore2.2.10-cann7.0.0beta1_py_3.9-euler_2.8.3-32GB ``` ``` docker start pytorch_ma docker exec -it mindspore_ma-4-7 /bin/bash ``` ``` import numpy as np import mindspore.context as context from mindspore import Tensor from mindspore.ops import functional as F context.set_context(mode=context.PYNATIVE_MODE, device_target="Ascend") x = Tensor(np.ones([1,3,3,4]).astype(np.float32)) y = Tensor(np.ones([1,3,3,4]).astype(np.float32)) print(F.tensor_add(x, y)) ``` ``` # 0-7 仅Ascend模式可用 from mindspore import context context.set_context(device_target="Ascend", device_id=6) ``` --- ``` docker pull swr.cn-central-221.ovaijisuan.com/dxy/mindspore_kernels:MindSpore2.2.10-cann7.0.0beta1_py_3.9-euler_2.8.3-64GB ``` ``` docker run -it -u root \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/Ascend/toolbox:/usr/local/Ascend/toolbox \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \ -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \ -v /home/aicc:/home/ma-user/work/aicc \ --name mindspore_ma_64 \ --entrypoint=/bin/bash \ swr.cn-central-221.ovaijisuan.com/dxy/mindspore_kernels:MindSpore2.2.10-cann7.0.0beta1_py_3.9-euler_2.8.3-64GB ``` --- ``` docker run -it -u root \ --ipc=host \ --network=host \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /var/log/npu/:/usr/slog \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ --name mindformers_dev \ swr.cn-central-221.ovaijisuan.com/mindformers/mindformers1.0_mindspore2.2.11:aarch_20240125 \ /bin/bash ``` ## 模型支持 - https://mindformers.readthedocs.io/zh-cn/latest/docs/model_support_list.html#llm ### translation | 模型
model | 模型规格
type | 数据集
dataset | 评估指标
metric | 评估得分
score | 配置
config | | :---------------------: | ----------------- | :-----------------: | :------------------: | :-----------------: | :----------------------------------------------------------: | | [t5](model_cards/t5.md) | t5_small | WMT16 | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/t5) | ### translation | 模型
model | 模型规格
type | 数据集
dataset | 评估指标
metric | 评估得分
score | 配置
config | | :---------------------: | ----------------- | :-----------------: | :------------------: | :-----------------: | :----------------------------------------------------------: | | [t5](model_cards/t5.md) | t5_small | WMT16 | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/t5) | ### [text_generation](task_cards/text_generation.md) | 模型
model | 模型规格
type | 数据集
dataset | 评估指标
metric | 评估得分
score | 配置
config | | :---------------------------------------------------: | :--------------------------------------------------------------------------------: | :-----------------: | :------------------------------------------: | :-------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------: | | [llama](model_cards/llama.md) | llama_7b
llama_13b
llama_7b_lora | alpaca | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/llama) | | [llama2](model_cards/llama2.md) | llama2_7b
llama2_13b
llama2_7b_lora
llama2_13b_lora
llama2_70b | alpaca | PPL / EM / F1 | 6.58 / 39.6 / 60.5
6.14 / 27.91 / 44.23
-
-
- | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/llama) | | [glm](model_cards/glm.md) | glm_6b
glm_6b_lora | ADGEN | BLEU-4 / Rouge-1 / Rouge-2 / Rouge-l
- | 8.42 / 31.75 / 7.98 / 25.28
- | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/glm) | | [glm2](model_cards/glm2.md) | glm2_6b
glm2_6b_lora | ADGEN | BLEU-4 / Rouge-1 / Rouge-2 / Rouge-l
- | 7.47 / 30.78 / 7.07 / 24.77
7.23 / 31.06 / 7.18 / 24.23 | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/glm2) | | [glm3](model_cards/glm3.md) | glm3_6b | ADGEN | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/glm3) | | [CodeGeex2](model_cards/codegeex2.md) | codegeex2_6b | CodeAlpaca | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/codegeex2) | | [bloom](model_cards/bloom.md) | bloom_560m
bloom_7.1b
| alpaca | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/bloom) | | [gpt2](model_cards/gpt2.md) | gpt2_small
gpt2_13b
| wikitext-2 | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/gpt2) | | [pangualpha](model_cards/pangualpha.md) | pangualpha_2_6_b
pangualpha_13b | 悟道数据集 | TNEWS / Em / F1
- | 0.646 / 2.10 / 21.12
- | [configs](https://gitee.com/mindspore/mindformers/tree/dev/configs/pangualpha) | | [baichuan](../research/baichuan/baichuan.md) | baichuan_7b
baichuan_13b | alpaca | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/research/baichuan/run_baichuan_7b.yaml) | | [baichuan2](../research/baichuan2/baichuan2.md) | baichuan2_7b
baichuan2_13b
baichuan2_7b_lora
baichuan2_13b_lora | belle | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/research/baichuan2) | | [skywork](../research/skywork/skywork.md) | skywork_13b | ADGEN | C-Eval / MMLU / CMMLU | 60.63 / 62.14 / 61.83 | [configs](https://gitee.com/mindspore/mindformers/tree/dev/research/skywork) | | [Wizardcoder](../research/wizardcoder/wizardcoder.md) | wizardcoder_15b | CodeAlpaca | MBPP Pass@1 | 50.8 | [configs](https://gitee.com/mindspore/mindformers/tree/dev/research/wizardcoder/run_wizardcoder.yaml) | | [Qwen](../research/qwen/qwen.md) | qwen_7b
qwen_14b | alpaca | C-Eval | 63.3
72.13 | [configs](https://gitee.com/mindspore/mindformers/tree/dev/research/qwen/run_qwen_7b.yaml) | | [internlm](../research/internlm/internlm.md) | internlm_7b
internlm_20b | alpaca | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/research/internlm/run_internlm_7b.yaml) | | [ziya](../research/ziya/ziya.md) | ziya_13b | alpaca | - | - | [configs](https://gitee.com/mindspore/mindformers/tree/dev/research/baichuan/run_ziya_13b.yaml) | ================================================ FILE: llm-localization/ascend/mindformers/baichuan2/baichuan2训练.md ================================================ - https://gitee.com/mindspore/mindformers/blob/r1.0/research/baichuan2/baichuan2.md ================================================ FILE: llm-localization/ascend/mindformers/baichuan2/run_baichuan2_7b.yaml ================================================ seed: 0 output_dir: './output' # path to save checkpoint/strategy load_checkpoint: '' src_strategy_path_or_dir: '' auto_trans_ckpt: False # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False use_parallel: True run_mode: 'train' # trainer config trainer: type: CausalLanguageModelingTrainer model_name: 'baichuan2_7b' # runner config runner_config: epochs: 4 batch_size: 2 sink_mode: True sink_size: 2 # optimizer optimizer: type: FP32StateAdamWeightDecay beta1: 0.9 beta2: 0.98 eps: 1.e-8 # 1e-8 weight_decay: 1.e-4 # lr sechdule lr_schedule: type: CosineWithWarmUpLR learning_rate: 2.e-5 lr_end: 2.e-6 warmup_ratio: 0.0 total_steps: -1 # -1 means it will load the total steps of the dataset # dataset train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "labels"] # "input_ids", "labels" , labels are used in instruction finetune. num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True repeat: 1 numa_enable: False prefetch_size: 1 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset # if True, do evaluate during the training process. if false, do nothing. # note that the task trainer should support _evaluate_in_training function. do_eval: False eval_step_interval: -1 # num of step intervals between each eval, -1 means no step end eval. eval_epoch_interval: 50 # num of epoch intervals between each eval, 1 means eval on every epoch end. # eval dataset eval_dataset: &eval_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: False input_columns: ["input_ids"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: False repeat: 1 numa_enable: False prefetch_size: 1 eval_dataset_task: type: CausalLanguageModelDataset dataset_config: *eval_dataset # default parallel of device num = 16 for Atlas 800 parallel_config: data_parallel: 2 model_parallel: 4 pipeline_stage: 2 micro_batch_num: 8 vocab_emb_dp: True gradient_aggregation_group: 4 # when model parallel is greater than 1, we can set micro_batch_interleave_num=2, that may accelerate the train process. micro_batch_interleave_num: 1 # recompute config recompute_config: recompute: True select_recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: True # callbacks callbacks: - type: MFLossMonitor - type: CheckpointMointor prefix: "baichuan2" save_checkpoint_steps: 1000 keep_checkpoint_max: 5 integrated_save: False async_save: False - type: ObsMonitor # mindspore context init config context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" max_call_depth: 10000 max_device_memory: "31GB" save_graphs: False save_graphs_path: "./graph" device_id: 0 # parallel context config parallel: parallel_mode: 1 # 0-data parallel, 1-semi-auto parallel, 2-auto parallel, 3-hybrid parallel gradients_mean: False enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: True strategy_ckpt_save_file: "./ckpt_strategy.ckpt" parallel_optimizer_config: gradient_accumulation_shard: False parallel_optimizer_threshold: 64 # model config model: model_config: type: LlamaConfig batch_size: 1 # add for increase predict seq_length: 512 hidden_size: 4096 num_layers: 32 num_heads: 32 vocab_size: 125696 multiple_of: 256 rms_norm_eps: 1.0e-6 bos_token_id: 1 eos_token_id: 2 pad_token_id: 0 ignore_token_id: -100 user_token_id: 195 assistant_token_id: 196 compute_dtype: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float32" rotary_dtype: "float32" param_init_type: "float16" use_past: False compute_in_2d: False use_flash_attention: False offset: 0 checkpoint_name_or_path: "path/to/baichuan2-7B-Chat.ckpt" repetition_penalty: 1.05 temperature: 1.0 max_decode_length: 512 top_k: 5 top_p: 0.85 do_sample: True max_new_tokens: 64 arch: type: Baichuan7BV2ForCausalLM processor: return_tensors: ms tokenizer: unk_token: '' bos_token: '' eos_token: '' pad_token: '' type: Baichuan2Tokenizer vocab_file: './tokenizer.model' type: LlamaProcessor # metric metric: type: PerplexityMetric # wrapper cell config runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 65536 scale_factor: 2 scale_window: 1000 use_clip_grad: True eval_callbacks: - type: ObsMonitor auto_tune: False filepath_prefix: './autotune' autotune_per_step: 10 profile: False profile_start_step: 1 profile_stop_step: 10 init_start_profile: False profile_communication: False profile_memory: True layer_scale: False layer_decay: 0.65 lr_scale_factor: 256 # aicc remote_save_url: "Please input obs url on AICC platform." ================================================ FILE: llm-localization/ascend/mindformers/baichuan2/run_baichuan2_7b_910b.yaml ================================================ seed: 0 output_dir: './output' # path to save checkpoint/strategy load_checkpoint: '' src_strategy_path_or_dir: '' auto_trans_ckpt: True # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False use_parallel: True run_mode: 'finetune' # trainer config trainer: type: CausalLanguageModelingTrainer model_name: 'baichuan2_7b' # runner config runner_config: epochs: 4 batch_size: 2 sink_mode: True sink_size: 2 # optimizer optimizer: type: FP32StateAdamWeightDecay beta1: 0.9 beta2: 0.98 eps: 1.e-8 # 1e-8 weight_decay: 1.e-4 # lr sechdule lr_schedule: type: CosineWithWarmUpLR learning_rate: 2.e-5 lr_end: 2.e-6 warmup_ratio: 0.0 total_steps: -1 # -1 means it will load the total steps of the dataset # dataset train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "labels"] # "input_ids", "labels" , labels are used in instruction finetune. num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True repeat: 1 numa_enable: False prefetch_size: 1 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset # if True, do evaluate during the training process. if false, do nothing. # note that the task trainer should support _evaluate_in_training function. do_eval: False eval_step_interval: -1 # num of step intervals between each eval, -1 means no step end eval. eval_epoch_interval: 50 # num of epoch intervals between each eval, 1 means eval on every epoch end. # eval dataset eval_dataset: &eval_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: False input_columns: ["input_ids"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: False repeat: 1 numa_enable: False prefetch_size: 1 eval_dataset_task: type: CausalLanguageModelDataset dataset_config: *eval_dataset # default parallel of device num = 16 for Atlas 800 parallel_config: data_parallel: 8 model_parallel: 1 pipeline_stage: 1 micro_batch_num: 1 vocab_emb_dp: True gradient_aggregation_group: 4 # when model parallel is greater than 1, we can set micro_batch_interleave_num=2, that may accelerate the train process. micro_batch_interleave_num: 1 # recompute config recompute_config: recompute: True select_recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: True # callbacks callbacks: - type: MFLossMonitor - type: CheckpointMointor prefix: "baichuan2" save_checkpoint_steps: 1000 keep_checkpoint_max: 5 integrated_save: False async_save: False - type: ObsMonitor # mindspore context init config context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" max_call_depth: 10000 max_device_memory: "59GB" save_graphs: False save_graphs_path: "./graph" device_id: 0 # parallel context config parallel: parallel_mode: 1 # 0-data parallel, 1-semi-auto parallel, 2-auto parallel, 3-hybrid parallel gradients_mean: False enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: True strategy_ckpt_save_file: "./ckpt_strategy.ckpt" parallel_optimizer_config: gradient_accumulation_shard: False parallel_optimizer_threshold: 64 # model config model: model_config: type: LlamaConfig batch_size: 1 # add for increase predict seq_length: 512 hidden_size: 4096 num_layers: 32 num_heads: 32 vocab_size: 125696 multiple_of: 256 rms_norm_eps: 1.0e-6 bos_token_id: 1 eos_token_id: 2 pad_token_id: 0 ignore_token_id: -100 user_token_id: 195 assistant_token_id: 196 compute_dtype: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float32" rotary_dtype: "float32" param_init_type: "float16" use_past: False compute_in_2d: True use_flash_attention: False offset: 0 checkpoint_name_or_path: "path/to/baichuan2-7B-Chat.ckpt" repetition_penalty: 1.05 temperature: 1.0 max_decode_length: 512 top_k: 5 top_p: 0.85 do_sample: True max_new_tokens: 64 arch: type: Baichuan7BV2ForCausalLM processor: return_tensors: ms tokenizer: unk_token: '' bos_token: '' eos_token: '' pad_token: '' type: Baichuan2Tokenizer vocab_file: './tokenizer.model' type: LlamaProcessor # metric metric: type: PerplexityMetric # wrapper cell config runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 65536 scale_factor: 2 scale_window: 1000 use_clip_grad: True eval_callbacks: - type: ObsMonitor auto_tune: False filepath_prefix: './autotune' autotune_per_step: 10 profile: False profile_start_step: 1 profile_stop_step: 10 init_start_profile: False profile_communication: False profile_memory: True layer_scale: False layer_decay: 0.65 lr_scale_factor: 256 # aicc remote_save_url: "Please input obs url on AICC platform." ================================================ FILE: llm-localization/ascend/mindformers/baichuan2/run_baichuan2_7b_lora_910b.yaml ================================================ seed: 0 output_dir: './output' # path to save checkpoint/strategy load_checkpoint: '/workspace/model/Baichuan2-7B-Chat-ms' src_strategy_path_or_dir: '' auto_trans_ckpt: True # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False use_parallel: True run_mode: 'finetune' # trainer config trainer: type: CausalLanguageModelingTrainer model_name: 'baichuan2_7b_lora' # runner config runner_config: epochs: 1 batch_size: 2 sink_mode: True sink_size: 2 # optimizer optimizer: type: FP32StateAdamWeightDecay beta1: 0.9 beta2: 0.98 eps: 1.e-8 # 1e-8 weight_decay: 1.e-4 # lr sechdule lr_schedule: type: CosineWithWarmUpLR learning_rate: 2.e-5 lr_end: 2.e-6 warmup_ratio: 0.0 total_steps: -1 # -1 means it will load the total steps of the dataset # dataset train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "labels"] # "input_ids", "labels" , labels are used in instruction finetune. num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True repeat: 1 numa_enable: False prefetch_size: 1 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset # if True, do evaluate during the training process. if false, do nothing. # note that the task trainer should support _evaluate_in_training function. do_eval: False eval_step_interval: -1 # num of step intervals between each eval, -1 means no step end eval. eval_epoch_interval: 50 # num of epoch intervals between each eval, 1 means eval on every epoch end. # eval dataset eval_dataset: &eval_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: False input_columns: ["input_ids"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: False repeat: 1 numa_enable: False prefetch_size: 1 eval_dataset_task: type: CausalLanguageModelDataset dataset_config: *eval_dataset # default parallel of device num = 8 for Atlas 800T A2 parallel_config: data_parallel: 8 model_parallel: 1 pipeline_stage: 1 micro_batch_num: 1 vocab_emb_dp: True gradient_aggregation_group: 4 # when model parallel is greater than 1, we can set micro_batch_interleave_num=2, that may accelerate the train process. micro_batch_interleave_num: 1 # recompute config recompute_config: recompute: True select_recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: True # callbacks callbacks: - type: MFLossMonitor - type: CheckpointMointor prefix: "baichuan2" save_checkpoint_steps: 1000 keep_checkpoint_max: 5 save_trainable_params: False # Whether to save fine-tuned weights additionally. integrated_save: False async_save: False - type: ObsMonitor # mindspore context init config context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" max_call_depth: 10000 max_device_memory: "30GB" save_graphs: False save_graphs_path: "./graph" device_id: 0 # parallel context config parallel: parallel_mode: 1 # 0-data parallel, 1-semi-auto parallel, 2-auto parallel, 3-hybrid parallel gradients_mean: False enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: True strategy_ckpt_config: save_file: "./ckpt_strategy.ckpt" only_trainable_params: False parallel_optimizer_config: gradient_accumulation_shard: False parallel_optimizer_threshold: 64 # model config model: model_config: type: LlamaConfig batch_size: 1 # add for increase predict seq_length: 512 hidden_size: 4096 num_layers: 32 num_heads: 32 vocab_size: 125696 multiple_of: 256 rms_norm_eps: 1.0e-6 bos_token_id: 1 eos_token_id: 2 pad_token_id: 0 ignore_token_id: -100 user_token_id: 195 assistant_token_id: 196 compute_dtype: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float32" rotary_dtype: "float32" param_init_type: "float16" use_past: False compute_in_2d: True use_flash_attention: False offset: 0 checkpoint_name_or_path: "path/to/baichuan2-7B-Chat.ckpt" repetition_penalty: 1.05 temperature: 1.0 max_decode_length: 512 top_k: 5 top_p: 0.85 do_sample: False pet_config: pet_type: lora # configuration of lora lora_rank: 1 lora_alpha: 32 lora_dropout: 0.1 target_modules: '.*wq|.*wk|.*wv' arch: type: Baichuan7BV2ForCausalLM processor: return_tensors: ms tokenizer: unk_token: '' bos_token: '' eos_token: '' pad_token: '' type: Baichuan2Tokenizer vocab_file: './tokenizer.model' type: LlamaProcessor # metric metric: type: PerplexityMetric # wrapper cell config runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 65536 scale_factor: 2 scale_window: 1000 use_clip_grad: True eval_callbacks: - type: ObsMonitor auto_tune: False filepath_prefix: './autotune' autotune_per_step: 10 profile: False profile_start_step: 1 profile_stop_step: 10 init_start_profile: False profile_communication: False profile_memory: True layer_scale: False layer_decay: 0.65 lr_scale_factor: 256 # aicc remote_save_url: "Please input obs url on AICC platform." ================================================ FILE: llm-localization/ascend/mindformers/chatglm/README.md ================================================ ## 全量微调 生成用于Ascend芯片分布式通信的芯片资源信息配置文件(RANK_TABLE_FILE)。 Ascend HCCL RANK_TABLE_FILE 文件提供Ascend分布式训练作业的集群信息。 ``` # 如生成8卡的rank_table_file > python ./mindformers/tools/hccl_tools.py --device_num "[0,8)" start ./mindformers/tools/hccl_tools.py visible_devices:['0', '1', '2', '3', '4', '5', '6', '7'] server_id:192.168.1.196 device_num_list: [0, 1, 2, 3, 4, 5, 6, 7] rank_id:0, device_id:0, device_ip:192.168.100.101 rank_id:1, device_id:1, device_ip:192.168.101.101 rank_id:2, device_id:2, device_ip:192.168.102.101 rank_id:3, device_id:3, device_ip:192.168.103.101 rank_id:4, device_id:4, device_ip:192.168.100.100 rank_id:5, device_id:5, device_ip:192.168.101.100 rank_id:6, device_id:6, device_ip:192.168.102.100 rank_id:7, device_id:7, device_ip:192.168.103.100 Completed: hccl file was save in : /root/workspace/code/mindformers/hccl_8p_01234567_192.168.1.196.json ``` ### 修改配置 ``` cd /root/workspace/code/mindformers vim configs/glm/run_glm_6b_finetune.yaml ``` ### 启动训练任务 ``` > bash run_distribute.sh /root/workspace/code/mindformers/hccl_8p_01234567_192.168.1.196.json ../configs/glm/run_glm_6b_finetune.yaml '[0,8]' finetune start training for rank 0, device 0 start training for rank 1, device 1 start training for rank 2, device 2 start training for rank 3, device 3 start training for rank 4, device 4 start training for rank 5, device 5 start training for rank 6, device 6 start training for rank 7, device 7 ``` 部分训练日志如下所示: ``` ... [INFO] 2023-07-11 10:35:39,223 [run_mindformer.py:71] main: moe config is: [INFO] 2023-07-11 10:35:39,223 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:75] __init__: Now Running Task is: text_generation, Model is: glm_6b [INFO] 2023-07-11 10:35:39,224 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:177] _check_global_batch_size_for_auto_parallel: The current parallel mode is semi_auto_parallel, full batch is True,so global batch size will be changed: global_batch_size = batch_size * data_parallel * micro_batch_interleave_num = 8 * 1 * 1 = 8 [INFO] 2023-07-11 10:35:39,224 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:514] training_process: .........Build Dataset For Train.......... [INFO] 2023-07-11 10:35:39,224 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:268] create_train_dataset: .........Build Dataset From Config.......... [INFO] 2023-07-11 10:35:39,224 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/dataset/causal_language_model_dataset.py:98] __new__: Now Create Causal Language Model Dataset. [INFO] 2023-07-11 10:35:39,224 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/dataset/base_dataset.py:50] init_dataset_config: Now the semi auto parallel mode is used and full_batch is True,and the shuffle of the dataset is required to be False,so as to ensure that the data loaded on each card is consistent and to avoid the problem of non-convergence of loss. [INFO] 2023-07-11 10:35:39,231 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/utils.py:133] check_runner_config: Will be Training epochs:1, sink_size:4 [INFO] 2023-07-11 10:35:39,231 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/utils.py:134] check_runner_config: Create training dataset finish, dataset size:125 [INFO] 2023-07-11 10:35:39,231 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:521] training_process: .........Build Net For Train.......... [INFO] 2023-07-11 10:35:39,231 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:282] create_network: .........Build Network From Config.......... [INFO] 2023-07-11 10:38:43,280 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/models/base_model.py:80] load_checkpoint: weights in /root/workspace/model/chatglm-convert/ms_glm_6b.ckpt are loaded [INFO] 2023-07-11 10:38:43,299 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:425] count_parameters: Network Parameters: 6707 M. [INFO] 2023-07-11 10:38:43,299 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:544] training_process: .........Build Optimizer For Train.......... [INFO] 2023-07-11 10:38:43,299 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:321] create_optimizer_scheduler: .........Build Optimizer From Config.......... [INFO] 2023-07-11 10:38:43,299 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:354] create_lr_scheduler: .........Build LR Schedule From Config.......... [WARNING] 2023-07-11 10:38:43,306 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/optimizer_grouped_parameters.py:74] get_optimizer_grouped_parameters: dynamic_lr_schedule will be reset and invalid when layer_scale is False. ... [INFO] 2023-07-11 10:38:43,568 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:550] training_process: .........Build Running Wrapper From Config For Train.......... [INFO] 2023-07-11 10:38:43,568 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:391] create_model_wrapper: .........Build Model Wrapper for Train From Config.......... [INFO] 2023-07-11 10:38:43,582 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:562] training_process: .........Starting Init Train Model.......... [INFO] 2023-07-11 10:38:43,583 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:581] training_process: .........Build Callbacks For Train.......... [INFO] 2023-07-11 10:38:43,583 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:400] create_callbacks: .........Build Callbacks for Train From Config.......... [INFO] 2023-07-11 10:38:43,584 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:340] __init__: Integrated_save is changed to False when using auto_parallel. [INFO] 2023-07-11 10:38:43,585 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:609] training_process: .........Starting Training Model.......... [INFO] 2023-07-11 10:38:43,585 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:610] training_process: .........Model Compiling, Please Wait a Moment........... [INFO] 2023-07-11 10:47:36,427 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:269] print_output_info: Epoch:[ 1/ 1], step:[ 4/ 125], loss:[2.244/2.244], time:507844.205 ms, lr:[0.], overflow cond: True, loss_scale: 268435460.0 [INFO] 2023-07-11 10:47:37,342 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:146] epoch_end: Per sink_size step time: 533756.177 ms, per step time: 133439.044 ms, avg loss: 2.244 [INFO] 2023-07-11 10:47:44,861 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:269] print_output_info: Epoch:[ 1/ 1], step:[ 8/ 125], loss:[2.499/2.499], time:7480.938 ms, lr:[0.], overflow cond: True, loss_scale: 16777216.0 [INFO] 2023-07-11 10:47:44,874 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:146] epoch_end: Per sink_size step time: 7518.224 ms, per step time: 1879.556 ms, avg loss: 2.499 ... [INFO] 2023-07-11 10:48:35,199 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:146] epoch_end: Per sink_size step time: 1958.791 ms, per step time: 489.698 ms, avg loss: 2.091 [INFO] 2023-07-11 10:48:37,162 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:269] print_output_info: Epoch:[ 1/ 1], step:[ 116/ 125], loss:[2.220/2.220], time:1951.612 ms, lr:[2.4499998e-06], overflow cond: False, loss_scale: 16384.0 [INFO] 2023-07-11 10:48:37,163 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:146] epoch_end: Per sink_size step time: 1963.915 ms, per step time: 490.979 ms, avg loss: 2.220 [INFO] 2023-07-11 10:48:39,125 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:269] print_output_info: Epoch:[ 1/ 1], step:[ 120/ 125], loss:[2.092/2.092], time:1953.753 ms, lr:[2.5499999e-06], overflow cond: False, loss_scale: 16384.0 [INFO] 2023-07-11 10:48:39,126 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:146] epoch_end: Per sink_size step time: 1962.049 ms, per step time: 490.512 ms, avg loss: 2.092 [INFO] 2023-07-11 10:48:41,083 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:269] print_output_info: Epoch:[ 1/ 1], step:[ 124/ 125], loss:[2.346/2.346], time:1949.995 ms, lr:[2.65e-06], overflow cond: False, loss_scale: 16384.0 [INFO] 2023-07-11 10:48:41,084 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/core/callback/callback.py:146] epoch_end: Per sink_size step time: 1958.268 ms, per step time: 489.567 ms, avg loss: 2.346 [INFO] 2023-07-11 10:49:26,307 [/root/workspace/code/mindformers/scripts/mf_parallel1/mindformers/trainer/base_trainer.py:616] training_process: .........Training Over!............. ``` ## LoRA微调 ### 修改配置 ``` cd /root/workspace/code/mindformers vim configs/glm/run_glm_6b_lora.yaml ``` 模型训练启动成功,输出目录的结构如下所示。 ``` output/ ├── checkpoint ├── log └── strategy ``` 其中,checkpoint文件夹放置权重文件,log文件夹方式日志文件,strategy文件夹放置模型切分策略文件。 查看日志: ``` # cd /root/workspace/code/mindformers/output/ cd log/rank_0 tail -100f info.log ``` 模型输出权重文件: ``` > tree -h checkpoint/ checkpoint/ ├── [ 4.0K] rank_0 │ ├── [ 3.4G] glm-6b-lora_rank_0-31_4.ckpt │ └── [ 6.5M] glm-6b-lora_rank_0-graph.meta ├── [ 4.0K] rank_1 │ ├── [ 3.4G] glm-6b-lora_rank_1-31_4.ckpt │ └── [ 6.5M] glm-6b-lora_rank_1-graph.meta ├── [ 4.0K] rank_2 │ ├── [ 3.4G] glm-6b-lora_rank_2-31_4.ckpt │ └── [ 6.5M] glm-6b-lora_rank_2-graph.meta └── [ 4.0K] rank_3 ├── [ 3.4G] glm-6b-lora_rank_3-31_4.ckpt └── [ 6.5M] glm-6b-lora_rank_3-graph.meta 4 directories, 8 files ``` 模型切分策略文件。 ``` > tree -h strategy/ strategy/ ├── [ 22K] ckpt_strategy_rank_0.ckpt ├── [ 22K] ckpt_strategy_rank_1.ckpt ├── [ 22K] ckpt_strategy_rank_2.ckpt └── [ 22K] ckpt_strategy_rank_3.ckpt ``` ## 权重合并 ### 全量微调 ``` python3 merge_ckpt.py --src_postfix=31_4 \ > --src_checkpoints_dir=/root/workspace/output/fullft_output \ > --src_strategy_file=/root/workspace/output/fullft_output/strategy/ckpt_strategy_rank_0.ckpt \ > --dst_checkpoints_dir=/root/workspace/output/fullft_merge_checkpoint/ args_opt.src_strategy_file: /root/workspace/output/fullft_output/strategy/ckpt_strategy_rank_0.ckpt checkpoint_file_map {7: '/root/workspace/output/fullft_output/checkpoint/rank_7/glm-6b_rank_7-31_4.ckpt', 6: '/root/workspace/output/fullft_output/checkpoint/rank_6/glm-6b_rank_6-31_4.ckpt', 5: '/root/workspace/output/fullft_output/checkpoint/rank_5/glm-6b_rank_5-31_4.ckpt', 4: '/root/workspace/output/fullft_output/checkpoint/rank_4/glm-6b_rank_4-31_4.ckpt', 3: '/root/workspace/output/fullft_output/checkpoint/rank_3/glm-6b_rank_3-31_4.ckpt', 2: '/root/workspace/output/fullft_output/checkpoint/rank_2/glm-6b_rank_2-31_4.ckpt', 1: '/root/workspace/output/fullft_output/checkpoint/rank_1/glm-6b_rank_1-31_4.ckpt', 0: '/root/workspace/output/fullft_output/checkpoint/rank_0/glm-6b_rank_0-31_4.ckpt'} save_checkpoint_path /root/workspace/output/fullft_merge_checkpoint/transformed.ckpt [WARNING] ME(8507:281472874964864,MainProcess):2023-07-11-15:32:38.347.469 [mindspore/parallel/_parallel_serialization.py:351] The parameter scale_sense is not in src_strategy. [WARNING] ME(8507:281472874964864,MainProcess):2023-07-11-15:32:38.347.863 [mindspore/parallel/_parallel_serialization.py:351] The parameter global_step is not in src_strategy. [WARNING] ME(8507:281472874964864,MainProcess):2023-07-11-15:35:28.541.985 [mindspore/parallel/_parallel_serialization.py:351] The parameter current_iterator_step is not in src_strategy. [WARNING] ME(8507:281472874964864,MainProcess):2023-07-11-15:35:28.542.313 [mindspore/parallel/_parallel_serialization.py:351] The parameter last_overflow_iterator_step is not in src_strategy. [WARNING] ME(8507:281472874964864,MainProcess):2023-07-11-15:35:28.542.392 [mindspore/parallel/_parallel_serialization.py:351] The parameter epoch_num is not in src_strategy. [WARNING] ME(8507:281472874964864,MainProcess):2023-07-11-15:35:28.542.460 [mindspore/parallel/_parallel_serialization.py:351] The parameter step_num is not in src_strategy. [WARNING] ME(8507:281472874964864,MainProcess):2023-07-11-15:35:28.542.523 [mindspore/parallel/_parallel_serialization.py:351] The parameter loss_scale is not in src_strategy. transform ckpt done. Filtering ckpt, this may take a while. 100%|###############################################################################| 1027/1027 [00:35<00:00, 28.57it/s] ``` 合并之后的权重文件如下所示: ``` > tree -h /root/workspace/output/fullft_merge_checkpoint /root/workspace/output/fullft_merge_checkpoint ├── [ 13G] filtered_transformed.ckpt └── [ 63G] transformed.ckpt ``` ### LoRA 微调 ``` python3 merge_ckpt.py --src_postfix=31_4 \ --src_checkpoints_dir=/root/workspace/output/lora_output \ --src_strategy_file=/root/workspace/code/mindformers/output/strategy/ckpt_strategy_rank_0.ckpt \ --dst_checkpoints_dir=/root/workspace/output/lora_merge_checkpoint_v2/ ``` ## 模型评估 ### 全量微调模型评估
详细输出

``` python run_mindformer.py \ > --config ./configs/glm/run_glm_6b_infer.yaml \ > --run_mode eval \ > --load_checkpoint /root/workspace/output/fullft_merge_checkpoint/filtered_transformed.ckpt \ > --eval_dataset_dir /root/workspace/data/AdvertiseGen-ms/eval_0711_256.mindrecord \ > --device_id 7 2023-07-11 16:52:59,073 - mindformers - INFO - full_batch will be forced to False when the parallel mode is stand_alone or data_parallel 2023-07-11 16:52:59,075 - mindformers - INFO - .........Build context config.......... 2023-07-11 16:52:59,075 - mindformers - INFO - initial moe_config from dict: {'expert_num': 1, 'capacity_factor': 1.05, 'aux_loss_factor': 0.05, 'num_experts_chosen': 1} 2023-07-11 16:52:59,075 - mindformers - INFO - initial recompute_config from dict: {'recompute': False, 'parallel_optimizer_comm_recompute': False, 'mp_comm_recompute': True, 'recompute_slice_activation': False} 2023-07-11 16:52:59,075 - mindformers - INFO - initial parallel_config from dict: {'data_parallel': 1, 'model_parallel': 1, 'pipeline_stage': 1, 'expert_parallel': 1, 'optimizer_shard': False, 'micro_batch_num': 1, 'vocab_emb_dp': True, 'gradient_aggregation_group': 4} 2023-07-11 16:52:59,075 - mindformers - INFO - context config is: [ParallelConfig] _recompute:[ParallelConfig] _recompute:False _parallel_optimizer_comm_recompute:False _mp_comm_recompute:True _recompute_slice_activation:False _optimizer_shard:False _gradient_aggregation_group:4 _embed_dp_mp_config:[ParallelConfig] _dp_mp_config:[ParallelConfig] _data_parallel:1 _model_parallel:1 _vocab_emb_dp:True _pp_config:[ParallelConfig] _pipeline_stage:1 _micro_batch_num:1 _moe_config:[ParallelConfig] _dpmp:[ParallelConfig] _data_parallel:1 _model_parallel:1 _expert_parallel:1 2023-07-11 16:52:59,076 - mindformers - INFO - moe config is: {'auto_trans_ckpt': False, 'auto_tune': False, 'autotune_per_step': 10, 'callbacks': [OrderedDict([('type', 'MFLossMonitor')]), OrderedDict([('type', 'SummaryMonitor'), ('keep_default_action', True)]), OrderedDict([('type', 'CheckpointMointor'), ('prefix', 'glm-6b'), ('save_checkpoint_steps', 500), ('keep_checkpoint_max', 2), ('integrated_save', False), ('async_save', False)]), OrderedDict([('type', 'ObsMonitor'), ('keep_last', False)])], 'context': {'device_id': 7, 'device_target': 'Ascend', 'enable_graph_kernel': False, 'graph_kernel_flags': '--disable_expand_ops=Softmax,Dropout ' '--enable_parallel_fusion=true ' '--reduce_fuse_depth=8 ' '--enable_auto_tensor_inplace=true', 'max_call_depth': 10000, 'save_graphs': False, 'save_graphs_path': './graph'}, 'device_num': 1, 'eval_callbacks': [OrderedDict([('type', 'ObsMonitor'), ('keep_last', False)])], 'eval_dataset': {'batch_size': 1, 'data_loader': {'dataset_dir': '/root/workspace/data/AdvertiseGen-ms/eval_0711_256.mindrecord', 'shuffle': True, 'type': 'MindDataset'}, 'drop_remainder': True, 'input_columns': ['input_ids', 'label'], 'num_parallel_workers': 8, 'numa_enable': False, 'prefetch_size': 1, 'python_multiprocessing': False, 'repeat': 1, 'seed': 0}, 'eval_dataset_task': {'dataset_config': {'batch_size': 1, 'data_loader': {'dataset_dir': '', 'shuffle': True, 'type': 'MindDataset'}, 'drop_remainder': True, 'input_columns': ['input_ids', 'label'], 'num_parallel_workers': 8, 'numa_enable': False, 'prefetch_size': 1, 'python_multiprocessing': False, 'repeat': 1, 'seed': 0}, 'type': 'CausalLanguageModelDataset'}, 'filepath_prefix': './autotune', 'init_start_profile': True, 'load_checkpoint': None, 'local_rank': 0, 'lr_schedule': {'learning_rate': 5e-05, 'lr_end': 1e-06, 'total_steps': -1, 'type': 'polynomial', 'warmup_steps': 2000}, 'metric': {'tokenizer_type': 'glm_6b', 'type': 'ADGENMetric'}, 'micro_batch_interleave_num': 1, 'model': {'arch': {'type': 'GLMChatModel'}, 'model_config': {'activation_func': 'GELU', 'attention_dropout_rate': 0.0, 'bos_token_id': 130004, 'checkpoint_name_or_path': '/root/workspace/output/fullft_merge_checkpoint/filtered_transformed.ckpt', 'compute_dtype': 'float16', 'do_sample': True, 'embedding_dropout_prob': 0.0, 'eos_token_id': 130005, 'gmask_token_id': 130001, 'hidden_dropout_rate': 0.0, 'hidden_size': 4096, 'hidden_size_per_attention_head': None, 'inner_hidden_size': 16384, 'is_enhanced_encoder': True, 'is_npu_acceleration': True, 'layernorm_compute_type': 'float32', 'layernorm_epsilon': 1e-05, 'layernorm_order': 'post', 'mask_token_id': 130000, 'max_decode_length': 2048, 'num_heads': 32, 'num_layers': 28, 'pad_token_id': 3, 'param_init_type': 'float16', 'position_encoding_2d': True, 'repetition_penalty': 1, 'seq_length': 512, 'softmax_compute_type': 'float32', 'top_k': 1, 'top_p': 1, 'type': 'GLMConfig', 'use_final_layernorm': True, 'use_past': True, 'vocab_size': 130528}}, 'moe_config': , 'only_save_strategy': False, 'optimizer': {'beta1': 0.9, 'beta2': 0.95, 'eps': 1e-08, 'type': 'FusedAdamWeightDecay', 'weight_decay': 0.1}, 'output_dir': './output', 'parallel': {'enable_alltoall': False, 'enable_parallel_optimizer': False, 'full_batch': True, 'gradients_mean': False, 'loss_repeated_mean': True, 'parallel_mode': 0, 'search_mode': 'sharding_propagation', 'strategy_ckpt_save_file': './output/strategy/./ckpt_strategy_rank_0.ckpt'}, 'parallel_config': , 'processor': {'return_tensors': 'ms', 'tokenizer': {'bos_token': '', 'end_token': '', 'eos_token': '', 'gmask_token': '[gMASK]', 'mask_token': '[MASK]', 'pad_token': '', 'padding_side': 'left', 'type': 'ChatGLMTokenizer', 'unk_token': ''}, 'type': 'GLMProcessor'}, 'profile': False, 'profile_communication': True, 'profile_memory': True, 'profile_start_step': 1, 'profile_stop_step': 10, 'recompute_config': , 'remote_save_url': 'Please input obs url on AICC platform.', 'resume_training': False, 'run_mode': 'eval', 'runner_config': {'batch_size': 1, 'epochs': 1, 'sink_mode': True, 'sink_size': 4}, 'runner_wrapper': {'scale_sense': {'loss_scale_value': 4294967296, 'scale_factor': 2, 'scale_window': 1000, 'type': 'DynamicLossScaleUpdateCell'}, 'type': 'MFTrainOneStepCell', 'use_clip_grad': True}, 'seed': 0, 'train_dataset': {'batch_size': 1, 'data_loader': {'dataset_dir': '', 'shuffle': True, 'type': 'MindDataset'}, 'drop_remainder': True, 'input_columns': ['input_ids', 'label', 'position_ids', 'attention_mask'], 'num_parallel_workers': 8, 'numa_enable': False, 'prefetch_size': 1, 'python_multiprocessing': False, 'repeat': 1, 'seed': 0}, 'train_dataset_task': {'dataset_config': {'batch_size': 1, 'data_loader': {'dataset_dir': '', 'shuffle': True, 'type': 'MindDataset'}, 'drop_remainder': True, 'input_columns': ['input_ids', 'label', 'position_ids', 'attention_mask'], 'num_parallel_workers': 8, 'numa_enable': False, 'prefetch_size': 1, 'python_multiprocessing': False, 'repeat': 1, 'seed': 0}, 'type': 'CausalLanguageModelDataset'}, 'trainer': {'model_name': 'glm_6b', 'type': 'CausalLanguageModelingTrainer'}, 'use_parallel': False} 2023-07-11 16:52:59,081 - mindformers - INFO - Now Running Task is: text_generation, Model is: glm_6b 2023-07-11 16:52:59,082 - mindformers - INFO - The current parallel mode is stand_alone, batch size per card will not be changed: batch_size_per_card = 1 2023-07-11 16:52:59,082 - mindformers - INFO - global_batch_size = batch_size_per_card * device_num = 1 * 1 = 1 2023-07-11 16:52:59,082 - mindformers - INFO - parallel_config will be change to default config: [ParallelConfig] _recompute:[ParallelConfig] _recompute:False _parallel_optimizer_comm_recompute:False _mp_comm_recompute:True _recompute_slice_activation:False _optimizer_shard:False _gradient_aggregation_group:4 _embed_dp_mp_config:[ParallelConfig] _dp_mp_config:[ParallelConfig] _data_parallel:1 _model_parallel:1 _vocab_emb_dp:True _pp_config:[ParallelConfig] _pipeline_stage:1 _micro_batch_num:1 _moe_config:[ParallelConfig] _dpmp:[ParallelConfig] _data_parallel:1 _model_parallel:1 _expert_parallel:1 . 2023-07-11 16:52:59,082 - mindformers - INFO - .........Build Dataset For Evaluate.......... 2023-07-11 16:52:59,082 - mindformers - INFO - .........Build Dataset From Config.......... 2023-07-11 16:52:59,083 - mindformers - INFO - Now Create Causal Language Model Dataset. [WARNING] ME(69632:281472846833536,MainProcess):2023-07-11-16:52:59.839.42 [mindspore/dataset/core/validator_helpers.py:806] 'TypeCast' from mindspore.dataset.transforms.c_transforms is deprecated from version 1.8 and will be removed in a future version. Use 'TypeCast' from mindspore.dataset.transforms instead. 2023-07-11 16:52:59,084 - mindformers - INFO - .........Build Network From Config.......... [WARNING] ME(69632:281472846833536,MainProcess):2023-07-11-16:53:02.472.83 [mindspore/common/_decorator.py:40] 'TensorAdd' is deprecated from version 1.1 and will be removed in a future version, use 'Add' instead. [WARNING] ME(69632:281472846833536,MainProcess):2023-07-11-16:56:17.765.324 [mindspore/train/serialization.py:1058] For 'load_param_into_net', 56 parameters in the 'net' are not loaded, because they are not in the 'parameter_dict', please check whether the network structure is consistent when training and loading checkpoint. [WARNING] ME(69632:281472846833536,MainProcess):2023-07-11-16:56:17.765.833 [mindspore/train/serialization.py:1060] transformer.layers.0.key_past is not loaded. ... [WARNING] ME(69632:281472846833536,MainProcess):2023-07-11-16:56:17.768.487 [mindspore/train/serialization.py:1060] transformer.layers.27.value_past is not loaded. 2023-07-11 16:56:17,768 - mindformers - INFO - weights in /root/workspace/output/fullft_merge_checkpoint/filtered_transformed.ckpt are loaded 2023-07-11 16:56:17,878 - mindformers - INFO - Network Parameters: 6825 M. 2023-07-11 16:56:17,878 - mindformers - INFO - .........Build Compute Metrics For Evaluate.......... 2023-07-11 16:56:17,878 - mindformers - INFO - Config in the yaml file ./checkpoint_download/glm/glm_6b.yaml are used for tokenizer building. 2023-07-11 16:56:18,492 - mindformers - INFO - Load the tokenizer name ChatGLMTokenizer from the ./checkpoint_download/glm/glm_6b.yaml 2023-07-11 16:56:18,528 - mindformers - INFO - config in the yaml file ./checkpoint_download/glm/glm_6b.yaml are used for tokenizer building. 2023-07-11 16:56:18,564 - mindformers - WARNING - Can't find the tokenizer_config.json in the file_dict. The content of file_dict is : {} 2023-07-11 16:56:18,565 - mindformers - INFO - build tokenizer class name is: ChatGLMTokenizer using args {'bos_token': '', 'eos_token': '', 'end_token': '', 'mask_token': '[MASK]', 'gmask_token': '[gMASK]', 'padding_side': 'left', 'pad_token': '', 'unk_token': '', 'vocab_file': './checkpoint_download/glm/ice_text.model'}. 2023-07-11 16:56:18,969 - mindformers - INFO - ChatGLMTokenizer Tokenizer built successfully! 2023-07-11 16:56:18,969 - mindformers - INFO - .........Starting Init Evaluate Model.......... 2023-07-11 16:56:18,970 - mindformers - INFO - .........Starting Evaluate Model.......... 2023-07-11 17:00:33,480 - mindformers - INFO - Epoch 1 Finished, cost time 254.49472093582153, every example cost time is 254.49472093582153, generate speed: 0.13359805608138378 tokens/s, avg speed: 0.0 tokens/s pred is: 以白色为底,以清新、淡雅的刺绣花朵为装饰,将v领与抽褶的元素融入其中,将简约与浪漫完美演绎。 label is: 简单大气纯白色连衣裙,是开春季节最美好的穿搭单品。简单的小v领点缀领部,加以独特的花边绣花点缀,满满的清新活力悠然散发。加以纯粹的白色选料,上身亲肤透气,自带自然的褶皱肌理。同时,中长款式,修饰好身材,十分美腻。 Building prefix dict from the default dictionary ... Loading model from cache /tmp/jieba.cache Loading model cost 1.166 seconds. Prefix dict has been built successfully. 2023-07-11 17:00:40,003 - mindformers - INFO - Epoch 2 Finished, cost time 5.341211557388306, every example cost time is 5.341211557388306, generate speed: 24.151823722757985 tokens/s, avg speed: 24.151371552472405 tokens/s pred is: 一款吊带裙,以清新的白色为主色调,简约而优雅。采用薄而透气的雪纺面料,在细节处加入精致的花边,让整件裙子在细节处尽显女性的柔美。 v领设计,露出性感的锁骨,性感又迷人。 腰部的拼接设计,将整件裙子的层次感演绎的恰到好处,既不失简约的大气,又凸显了女性的柔美。 下摆的宽松设计,在行走中自然流动,将整件裙子的优雅气质展现的淋淋尽致。 整体设计以休闲为主,在细节处加入精致的蝴蝶结,让整件裙子更显甜美。 label is: 优美而动感的上衣。采用半透的雪纺材质工艺,深黑色系给您以非常魅惑的穿着体验,内里需要搭配深黑色的吊带。花边v字领口连襟拼接,举手投足更加优雅迷人,适合搭配各种半身裙和休闲长裤。 2023-07-11 17:00:41,904 - mindformers - INFO - Epoch 3 Finished, cost time 1.8842175006866455, every example cost time is 1.8842175006866455, generate speed: 23.88259316326333 tokens/s, avg speed: 24.08128160602231 tokens/s pred is: 以白色为底,以黑色线条为装饰,将高腰与a字裙的设计元素融合在一起,打造出一种独特的时尚风格。将简约与个性元素相结合,让穿着者更加有型有款。 label is: 这款裙子采用黑色的颜色打底,裙身上装饰着白色的线条以及扣子装饰,丰富视觉上的变化。另外整体上a字裙裙型搭配高腰的设计,修身效果出众,还有着不规则的裙摆,展现出十足的设计感。 2023-07-11 17:00:43,475 - mindformers - INFO - Epoch 4 Finished, cost time 1.561234951019287, every example cost time is 1.561234951019287, generate speed: 23.699187605199157 tokens/s, avg speed: 24.013391025594462 tokens/s pred is: 以蕾丝为底,以宫廷刺绣为装饰,以大裙摆和泡泡袖为特点,将时尚与复古元素相结合,打造一款华丽、浪漫的蕾丝裙。 label is: 宫廷风的甜美蕾丝设计,清醒的蕾丝拼缝处,刺绣定制的贝壳花边,增添了裙子的精致感觉。超大的裙摆,加上精细的小花边设计,上身后既带着仙气撩人又很有女人味。泡泡袖上的提花面料,在细节处增加了浪漫感,春日的仙女姐姐。浪漫蕾丝布满整个裙身,美丽明艳,气质超仙。 ... 2023-07-11 17:02:40,918 - mindformers - INFO - Epoch 45 Finished, cost time 5.272047996520996, every example cost time is 5.272047996520996, generate speed: 25.98610636519352 tokens/s, avg speed: 24.71114413227348 tokens/s pred is: 黑色条纹裤是经典的时尚单品,不仅简约大方,还非常百搭,可以搭配各种上衣,让你时尚又气质。 搭配白色T恤,简约清新,白色与黑色条纹的搭配非常显瘦,还很有层次感。 搭配印花T恤,印花元素非常可爱,搭配黑色条纹裤,很有小清新的感觉。 搭配牛仔衬衫,牛仔衬衫的休闲感与黑色条纹裤的时尚感相结合,非常时髦。 搭配皮质外套,皮质外套的帅气与黑色条纹裤的休闲感相结合,很有时尚感。 黑色条纹裤可以搭配各种上衣,非常百搭,而且简约大方,让你时尚又气质。 label is: 传承动感简约气质的条纹衣身,结合包边圆领和半开襟设计,造型显得活力有范,又不失男孩子的时尚帅气。胸前单侧小口袋点缀,让男宝宝帅气加倍。搭配纯黑色的底裤,整体显得层次十足,视觉也十分有美感,男宝宝穿起来独特魅力尽显。 2023-07-11 17:02:42,877 - mindformers - INFO - Epoch 46 Finished, cost time 1.9328925609588623, every example cost time is 1.9328925609588623, generate speed: 25.350607162403406 tokens/s, avg speed: 24.720831918537765 tokens/s pred is: 以简约为灵魂,以纯色为基石,以条纹为元素,将时尚与舒适结合,将简约与个性展现。这款外套,时尚与实用并存,在细节处展现品质,在简约中彰显个性。 label is: 来自巴拉巴拉的女童长款外套,设计师采用直筒式衣袖裁剪,并在袖口加饰有纯色条纹,在打破了整体的单一性的同时,还增添了一丝简约时尚气息。再加上对称的斜插口袋,既能给予娇嫩双手温暖,同时还可放置孩子的随身物品,暖心又很实用呢。 2023-07-11 17:02:45,750 - mindformers - INFO - Epoch 47 Finished, cost time 2.860628366470337, every example cost time is 2.860628366470337, generate speed: 25.16929526530534 tokens/s, avg speed: 24.730666589943375 tokens/s pred is: 以蝴蝶结为元素,将层叠的网纱与系带进行搭配,将整体设计打造为半裙的半身裙,在腰部加入门襟设计,将整体设计打造为系带的蝴蝶结,在腰部的层叠层叠的网纱与蝴蝶结的点缀下,让整件裙子在细节处尽显尽显的时尚感。 label is: 层叠网纱,仙气飘飘,却不会过于膨胀。腰间的蝴蝶结系带,恰到好处的增添了柔美感。膝盖以下,长度刚刚好的半身裙,比起“一览无遗魅力尽显”,专注于“完美隐藏” 2023-07-11 17:02:47,855 - mindformers - INFO - Epoch 48 Finished, cost time 2.094264030456543, every example cost time is 2.094264030456543, generate speed: 24.829725022142583 tokens/s, avg speed: 24.732231816627035 tokens/s pred is: 焦糖色连衣裙,简约而不失优雅,宽松的版型,穿上身更显气质。百褶的裙摆,在腰部的收腰设计,更显身材的纤细。搭配宽松的腰带,将身材比例修饰的更好。整体的设计,更显女性的柔美。 label is: 来自自制的连衣裙采用今年大热的焦糖色,就像巧克力一样,甜蜜又不腻人。腰带的贴心设计,让宽松的版型也能拥有s曲线。上身简约的衬衫式翻领,衬托小v脸,带来一股职场ol风,加以百褶下摆的点缀,一起述说无尽温柔。 2023-07-11 17:02:50,774 - mindformers - INFO - Epoch 49 Finished, cost time 2.9023842811584473, every example cost time is 2.9023842811584473, generate speed: 25.15173489392764 tokens/s, avg speed: 24.74122134217671 tokens/s pred is: 一款时尚舒适的羊毛九分微喇裤,采用优质羊毛面料打造,柔软亲肤,保暖舒适。微喇裤的裤口设计,修饰腿型,展现优美曲线。九分的长度,修饰脚踝,显瘦显高挑。裤身的流线型设计,修饰腰部,展现身材比例。搭配一件简约的毛衣,即可穿出气质。 label is: 不同于一般的西服裤。这款小喇叭羊毛裤在样式上显得更加时髦优雅,特地采用微微的九分喇叭裤腿设计,视觉上将脚踝处显得更加纤细。并且特地甄选柔软的羊毛材质,就算直接贴肤穿着,也不会觉得寒冷,比较适合初秋穿噢。 2023-07-11 17:02:53,838 - mindformers - INFO - Epoch 50 Finished, cost time 3.0505833625793457, every example cost time is 3.0505833625793457, generate speed: 25.241073869521973 tokens/s, avg speed: 24.75223162149713 tokens/s pred is: 以绿色为主色调,将复古与时尚相结合,设计宽松的版型,在细节处加入复古图案,让整件裙子更加有层次感。在腰部加入的褶皱设计,让腰部更加修饰,同时让整件裙子更加有型。在裙摆处加入的灯笼袖设计,让整件裙子更加有层次感,同时让裙摆更加修饰身材。 label is: 袖子有灯笼袖的既视感,中世纪的复古韵味轻松展现,版型宽松舒适,上身贴合身材,不会显胖。超级百搭,秋季单穿,搭配裙子裤子都ok!冬天也能做打底,外搭毛呢大衣,气质满满。 2023-07-11 17:02:53,853 - mindformers - INFO - metric: Text Generation Metric rouge-1: 25.986109999999993 rouge-2: 4.22121 rouge-l: 21.202881999999995 bleu-4: 4.540767999999999 2023-07-11 17:02:53,854 - mindformers - INFO - ...........Evaluate Over!............... ```

### LoRA 微调模型评估 ``` python run_mindformer.py \ --config ./configs/glm/run_glm_6b_lora_infer.yaml \ --run_mode eval \ --load_checkpoint /root/workspace/output/lora_merge_checkpoint_v2/filtered_transformed.ckpt \ --eval_dataset_dir /root/workspace/data/AdvertiseGen-ms/eval_0711_256.mindrecord \ --device_id 0 ``` ================================================ FILE: llm-localization/ascend/mindformers/chatglm/chat_glm.py ================================================ import time import mindspore as ms import numpy as np from mindformers.models.glm import GLMConfig, GLMChatModel from mindformers.models.glm.chatglm_6b_tokenizer import ChatGLMTokenizer from mindformers.models.glm.glm_processor import process_response config = GLMConfig( position_encoding_2d=True, use_past=True, is_npu_acceleration=True, ) def chat_glm(): ms.set_context(mode=ms.GRAPH_MODE, device_target="Ascend", device_id=7) model = GLMChatModel(config) ms.load_checkpoint("./checkpoint_download/glm/glm_6b.ckpt", model) tokenizer = ChatGLMTokenizer('./checkpoint_download/glm/ice_text.model') prompts = ["你好", "请介绍一下华为"] history = [] for query in prompts: if not history: prompt = query else: prompt = "" for i, (old_query, response) in enumerate(history): prompt += "[Round {}]\n问:{}\n答:{}\n".format(i, old_query, response) prompt += "[Round {}]\n问:{}\n答:".format(len(history), query) inputs = tokenizer(prompt) start_time = time.time() outputs = model.generate(np.expand_dims(np.array(inputs['input_ids']).astype(np.int32), 0), max_length=config.max_decode_length, do_sample=False, top_p=0.7, top_k=1) end_time = time.time() print(f'generate speed: {outputs[0].shape[0]/(end_time-start_time):.2f} tokens/s') response = tokenizer.decode(outputs) response = process_response(response[0]) history = history + [(query, response)] print(response) if __name__ == "__main__": chat_glm() ================================================ FILE: llm-localization/ascend/mindformers/chatglm/glm_6b.yaml ================================================ seed: 0 run_mode: 'train' output_dir: './output' # 当前不支持自定义修改,请勿修改该默认值 load_checkpoint: '' auto_trans_ckpt: False # If true, auto transform load_checkpoint to load in distributed model resume_training: False # ==== context config ==== context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" max_call_depth: 10000 max_device_memory: "30GB" save_graphs: False device_id: 0 # aicc remote_save_url: "Please input obs url on AICC platform." # ==== model config ==== model: model_config: type: GLMConfig vocab_size: 130528 hidden_size: 4096 num_layers: 28 num_heads: 32 inner_hidden_size: 16384 seq_length: 512 # 推理时, 输入pad到的长度, model里的最大句长 embedding_dropout_prob: 0.0 attention_dropout_rate: 0.0 hidden_dropout_rate: 0.0 hidden_size_per_attention_head: # default "None" means hidden-size/num-attention-heads. layernorm_order: "post" layernorm_epsilon: 1.0e-5 use_final_layernorm: True use_past: False activation_func: 'GELU' position_encoding_2d: True param_init_type: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float32" compute_dtype: "float16" bos_token_id: 130004 eos_token_id: 130005 mask_token_id: 130000 gmask_token_id: 130001 pad_token_id: 3 max_decode_length: 2048 # The maximum length of the generated words. is_enhanced_encoder: True is_npu_acceleration: False checkpoint_name_or_path: "glm_6b" top_k: 1 top_p: 1 repetition_penalty: 1 do_sample: True arch: type: GLMForPreTraining trainer: type: CausalLanguageModelingTrainer model_name: 'glm_6b' # if True, do evaluate during the training process. if false, do nothing. # note that the task trainer should support _evaluate_in_training function. do_eval: False eval_step_interval: -1 # num of step intervals between each eval, -1 means no step end eval. eval_epoch_interval: 1 # num of epoch intervals between each eval, 1 means eval on every epoch end. metric: type: ADGENMetric tokenizer_type: "glm_6b" # use ChatGLMTokenizer processor: return_tensors: ms tokenizer: type: ChatGLMTokenizer bos_token: '' eos_token: '' end_token: '' mask_token: '[MASK]' gmask_token: '[gMASK]' padding_side: 'left' pad_token: '' unk_token: '' type: GLMProcessor # ==== dataset config ==== train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "label", "position_ids", "attention_mask"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset eval_dataset: &eval_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "label"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 eval_dataset_task: type: CausalLanguageModelDataset dataset_config: *eval_dataset # ==== runner config ==== runner_config: epochs: 1 batch_size: 8 sink_mode: True sink_size: 4 runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 4294967296 scale_factor: 2 scale_window: 1000 use_clip_grad: True # lr sechdule lr_schedule: type: polynomial learning_rate: 5.e-5 lr_end: 1.e-6 warmup_steps: 2000 total_steps: -1 # -1 means it will load the total steps of the dataset layer_scale: False layer_decay: 0.65 # optimizer optimizer: type: FusedAdamWeightDecay beta1: 0.9 beta2: 0.95 eps: 1.e-8 weight_decay: 0.1 lr_scale: False lr_scale_factor: 256 # parallel config use_parallel: False parallel: parallel_mode: 1 # 0-dataset, 1-semi, 2-auto, 3-hybrid gradients_mean: False loss_repeated_mean: True enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: False # optimizer shard strategy_ckpt_save_file: "./ckpt_strategy.ckpt" parallel_config: data_parallel: 1 model_parallel: 8 pipeline_stage: 1 expert_parallel: 1 optimizer_shard: False # optimizer shard micro_batch_num: 1 vocab_emb_dp: True gradient_aggregation_group: 4 micro_batch_interleave_num: 1 # moe moe_config: expert_num: 1 capacity_factor: 1.05 aux_loss_factor: 0.05 num_experts_chosen: 1 # recompute recompute_config: recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: False # autotune auto_tune: False filepath_prefix: './autotune' autotune_per_step: 10 # profile profile: False profile_start_step: 1 profile_stop_step: 10 init_start_profile: True profile_communication: True profile_memory: True # callbacks callbacks: - type: MFLossMonitor - type: SummaryMonitor keep_default_action: True - type: CheckpointMointor prefix: "glm-6b" save_checkpoint_steps: 500 keep_checkpoint_max: 2 integrated_save: False async_save: False - type: ObsMonitor upload_frequence: -1 keep_last: False eval_callbacks: - type: ObsMonitor upload_frequence: -1 keep_last: False ================================================ FILE: llm-localization/ascend/mindformers/chatglm/glm_6b_chat.yaml ================================================ seed: 0 run_mode: 'predict' load_checkpoint: "" auto_trans_ckpt: False # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False output_dir: './output' # 当前不支持自定义修改,请勿修改该默认值 # ==== context config ==== context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" max_call_depth: 10000 max_device_memory: "30GB" save_graphs: False save_graphs_path: "./graph" device_id: 0 # aicc remote_save_url: "Please input obs url on AICC platform." # ==== model config ==== model: model_config: type: GLMConfig vocab_size: 130528 hidden_size: 4096 num_layers: 28 num_heads: 32 inner_hidden_size: 16384 seq_length: 512 # 推理时, 输入pad到的长度, model里的最大句长 embedding_dropout_prob: 0.0 attention_dropout_rate: 0.0 hidden_dropout_rate: 0.0 hidden_size_per_attention_head: # default "None" means hidden-size/num-attention-heads. layernorm_order: "post" layernorm_epsilon: 1.0e-5 use_final_layernorm: True use_past: True # True for incremental infer. activation_func: 'GELU' position_encoding_2d: True param_init_type: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float32" compute_dtype: "float16" bos_token_id: 130004 eos_token_id: 130005 mask_token_id: 130000 gmask_token_id: 130001 pad_token_id: 3 max_decode_length: 2048 # The maximum length of the generated words. is_enhanced_encoder: True is_npu_acceleration: True # sample in npu to acceleration checkpoint_name_or_path: "glm_6b" top_k: 1 top_p: 1 # top_p not support for npu_acceleration yet repetition_penalty: 1 do_sample: True arch: type: GLMChatModel trainer: type: CausalLanguageModelingTrainer model_name: 'glm_6b' metric: type: ADGENMetric tokenizer_type: "glm_6b" # use ChatGLMTokenizer processor: return_tensors: ms tokenizer: type: ChatGLMTokenizer bos_token: '' eos_token: '' end_token: '' mask_token: '[MASK]' gmask_token: '[gMASK]' padding_side: 'left' pad_token: '' unk_token: '' type: GLMProcessor # ==== dataset config ==== train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "label", "position_ids", "attention_mask"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset eval_dataset: &eval_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "label"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 eval_dataset_task: type: CausalLanguageModelDataset dataset_config: *eval_dataset # ==== runner config ==== runner_config: epochs: 1 batch_size: 1 sink_mode: True sink_size: 4 runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 4294967296 scale_factor: 2 scale_window: 1000 use_clip_grad: True # lr sechdule lr_schedule: type: polynomial learning_rate: 5.e-5 lr_end: 1.e-6 warmup_steps: 2000 total_steps: -1 # -1 means it will load the total steps of the dataset # optimizer optimizer: type: FusedAdamWeightDecay beta1: 0.9 beta2: 0.95 eps: 1.e-8 weight_decay: 0.1 # parallel config use_parallel: False parallel: parallel_mode: 0 # 0-dataset, 1-semi, 2-auto, 3-hybrid gradients_mean: False loss_repeated_mean: True enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: False # optimizer shard strategy_ckpt_save_file: "./ckpt_strategy.ckpt" parallel_config: data_parallel: 1 model_parallel: 1 pipeline_stage: 1 expert_parallel: 1 optimizer_shard: False # optimizer shard micro_batch_num: 1 vocab_emb_dp: True gradient_aggregation_group: 4 micro_batch_interleave_num: 1 # moe moe_config: expert_num: 1 capacity_factor: 1.05 aux_loss_factor: 0.05 num_experts_chosen: 1 # recompute recompute_config: recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: False # autotune auto_tune: False filepath_prefix: './autotune' autotune_per_step: 10 # profile profile: False profile_start_step: 1 profile_stop_step: 10 init_start_profile: True profile_communication: True profile_memory: True # callbacks callbacks: - type: MFLossMonitor - type: SummaryMonitor keep_default_action: True - type: CheckpointMointor prefix: "glm-6b" save_checkpoint_steps: 500 keep_checkpoint_max: 2 integrated_save: False async_save: False - type: ObsMonitor keep_last: False eval_callbacks: - type: ObsMonitor keep_last: False ================================================ FILE: llm-localization/ascend/mindformers/chatglm/merge_ckpt.py ================================================ import os import argparse import mindspore as ms from tqdm import tqdm def merge_ckpt(args_opt): # Transform checkpoint directory # return str `save_checkpoint_path` print("args_opt.src_strategy_file: ", args_opt.src_strategy_file) rank_list = ms.rank_list_for_transform(0, args_opt.src_strategy_file, None) checkpoint_file_map = {} for rank_id in rank_list: checkpoint_file_map[rank_id] = os.path.join(args_opt.src_checkpoints_dir, "checkpoint", f"rank_{rank_id}", f"glm-6b_rank_{rank_id}-{args_opt.src_postfix}.ckpt") if not os.path.exists(args_opt.dst_checkpoints_dir): os.mkdir(args_opt.dst_checkpoints_dir) save_checkpoint_path = os.path.join(args_opt.dst_checkpoints_dir, "transformed.ckpt") print('checkpoint_file_map', checkpoint_file_map) print('save_checkpoint_path', save_checkpoint_path) ms.transform_checkpoint_by_rank(0, checkpoint_file_map, save_checkpoint_path, args_opt.src_strategy_file, None) print("transform ckpt done.") return save_checkpoint_path def clean_ckpt(ms_ckpt_path): ''' filter keyword `adam` in ckpt and generate new ckpt print layer name in `check_ms_ckpt.txt` ''' print("Filtering ckpt, this may take a while.") ms_param = ms.load_checkpoint(ms_ckpt_path) new_param = [] with open("check_ms_ckpt.txt", "w") as fp: for k, v in tqdm(ms_param.items(), ascii=True, ncols=120): if "adam" in k: continue fp.write(f"{k} {v.shape} {v.dtype}\n") new_param.append({"name": k, "data": ms.Tensor(v.numpy())}) save_path, ckpt_name = os.path.split(ms_ckpt_path) ckpt_name = "filtered_" + ckpt_name ms_ckpt_path = os.path.join(save_path, ckpt_name) ms.save_checkpoint(new_param, ms_ckpt_path) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Transform checkpoint dir") parser.add_argument("--src_postfix", type=str, default="1790_4", help="Source ckpt postfix str.") parser.add_argument("--src_checkpoints_dir", type=str, default="scripts", help="The source checkpoint directory.") parser.add_argument("--src_strategy_file", type=str, default="ckpt_strategy.ckpt", help="The source strategy file") parser.add_argument("--dst_checkpoints_dir", type=str, default="transformed_ckpt", help="The destination checkpoint directory.") args_opt = parser.parse_args() save_checkpoint_path = merge_ckpt(args_opt) clean_ckpt(save_checkpoint_path) ================================================ FILE: llm-localization/ascend/mindformers/chatglm/merge_ckpt_lora.py ================================================ import os import argparse import mindspore as ms from tqdm import tqdm def merge_ckpt(args_opt): # Transform checkpoint directory # return str `save_checkpoint_path` print("args_opt.src_strategy_file: ", args_opt.src_strategy_file) rank_list = ms.rank_list_for_transform(0, args_opt.src_strategy_file, None) checkpoint_file_map = {} for rank_id in rank_list: checkpoint_file_map[rank_id] = os.path.join(args_opt.src_checkpoints_dir, "checkpoint", f"rank_{rank_id}", f"glm-6b-lora_rank_{rank_id}-{args_opt.src_postfix}.ckpt") if not os.path.exists(args_opt.dst_checkpoints_dir): os.mkdir(args_opt.dst_checkpoints_dir) save_checkpoint_path = os.path.join(args_opt.dst_checkpoints_dir, "transformed.ckpt") print('checkpoint_file_map', checkpoint_file_map) print('save_checkpoint_path', save_checkpoint_path) ms.transform_checkpoint_by_rank(0, checkpoint_file_map, save_checkpoint_path, args_opt.src_strategy_file, None) print("transform ckpt done.") return save_checkpoint_path def clean_ckpt(ms_ckpt_path): ''' filter keyword `adam` in ckpt and generate new ckpt print layer name in `check_ms_ckpt.txt` ''' print("Filtering ckpt, this may take a while.") ms_param = ms.load_checkpoint(ms_ckpt_path) new_param = [] with open("check_ms_ckpt.txt", "w") as fp: for k, v in tqdm(ms_param.items(), ascii=True, ncols=120): if "adam" in k: continue fp.write(f"{k} {v.shape} {v.dtype}\n") new_param.append({"name": k, "data": ms.Tensor(v.numpy())}) save_path, ckpt_name = os.path.split(ms_ckpt_path) ckpt_name = "filtered_" + ckpt_name ms_ckpt_path = os.path.join(save_path, ckpt_name) ms.save_checkpoint(new_param, ms_ckpt_path) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Transform checkpoint dir") parser.add_argument("--src_postfix", type=str, default="1790_4", help="Source ckpt postfix str.") parser.add_argument("--src_checkpoints_dir", type=str, default="scripts", help="The source checkpoint directory.") parser.add_argument("--src_strategy_file", type=str, default="ckpt_strategy.ckpt", help="The source strategy file") parser.add_argument("--dst_checkpoints_dir", type=str, default="transformed_ckpt", help="The destination checkpoint directory.") args_opt = parser.parse_args() save_checkpoint_path = merge_ckpt(args_opt) clean_ckpt(save_checkpoint_path) ================================================ FILE: llm-localization/ascend/mindformers/chatglm/pt2ms.py ================================================ import argparse from transformers import AutoModel import mindspore as ms import torch as pt parser = argparse.ArgumentParser() parser.add_argument('--src_checkpoint_dir', type=str, default='/home/huggingface-glm-6b', help='Checkpoint dir to load on.') parser.add_argument('--dst_checkpoint_file', type=str, default='./ms_glm_6b.ckpt', help='Checkpoint file path.') args = parser.parse_args() pt_ckpt_path = args.src_checkpoint_dir model = AutoModel.from_pretrained(pt_ckpt_path, trust_remote_code=True).half() pt_param = model.state_dict() type_map = {"torch.float16": "ms.float16", "torch.float32": "ms.float32"} ms_param = [] with open("check_pt_ckpt.txt", "w") as fp: for k, v in pt_param.items(): if "word_embeddings.weight" in k: k = k.replace("weight", "embedding_table") if "post_attention_layernorm" in k or "input_layernorm" in k or "final_layernorm" in k : k = k.replace("weight", "gamma") k = k.replace("bias", "beta") ms_param.append({"name": k, "data": ms.Tensor(v.numpy())}) ms.save_checkpoint(ms_param, args.dst_checkpoint_file) ================================================ FILE: llm-localization/ascend/mindformers/chatglm/run_glm_6b_finetune.yaml ================================================ seed: 0 run_mode: 'train' output_dir: './output' # 当前不支持自定义修改,请勿修改该默认值 load_checkpoint: '/root/workspace/model/chatglm-convert/ms_glm_6b.ckpt' auto_trans_ckpt: False # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False # ==== context config ==== context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" max_call_depth: 10000 max_device_memory: "30GB" save_graphs: False device_id: 0 # aicc remote_save_url: "Please input obs url on AICC platform." # ==== model config ==== model: model_config: type: GLMConfig vocab_size: 130528 hidden_size: 4096 num_layers: 28 num_heads: 32 inner_hidden_size: 16384 seq_length: 512 # 推理时, 输入pad到的长度, model里的最大句长 embedding_dropout_prob: 0.0 attention_dropout_rate: 0.0 hidden_dropout_rate: 0.0 hidden_size_per_attention_head: # default "None" means hidden-size/num-attention-heads. layernorm_order: "post" layernorm_epsilon: 1.0e-5 use_final_layernorm: True use_past: False activation_func: 'GELU' position_encoding_2d: True param_init_type: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float32" compute_dtype: "float16" bos_token_id: 130004 eos_token_id: 130005 mask_token_id: 130000 gmask_token_id: 130001 pad_token_id: 3 max_decode_length: 2048 # The maximum length of the generated words. is_enhanced_encoder: True is_npu_acceleration: False checkpoint_name_or_path: "glm_6b" top_k: 1 top_p: 1 repetition_penalty: 1 do_sample: True arch: type: GLMForPreTraining trainer: type: CausalLanguageModelingTrainer model_name: 'glm_6b' # if True, do evaluate during the training process. if false, do nothing. # note that the task trainer should support _evaluate_in_training function. do_eval: False eval_step_interval: -1 # num of step intervals between each eval, -1 means no step end eval. eval_epoch_interval: 1 # num of epoch intervals between each eval, 1 means eval on every epoch end. metric: type: ADGENMetric tokenizer_type: "glm_6b" # use ChatGLMTokenizer processor: return_tensors: ms tokenizer: type: ChatGLMTokenizer bos_token: '' eos_token: '' end_token: '' mask_token: '[MASK]' gmask_token: '[gMASK]' padding_side: 'left' pad_token: '' unk_token: '' type: GLMProcessor # ==== dataset config ==== train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "/root/workspace/data/AdvertiseGen-ms/train_0604_128.mindrecord" shuffle: True input_columns: ["input_ids", "label", "position_ids", "attention_mask"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset eval_dataset: &eval_dataset data_loader: type: MindDataset dataset_dir: "/root/workspace/data/AdvertiseGen-ms/eval_0604_256.mindrecord" shuffle: True input_columns: ["input_ids", "label"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 eval_dataset_task: type: CausalLanguageModelDataset dataset_config: *eval_dataset # ==== runner config ==== runner_config: epochs: 1 batch_size: 8 sink_mode: True sink_size: 4 runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 4294967296 scale_factor: 2 scale_window: 1000 use_clip_grad: True # lr sechdule lr_schedule: type: polynomial learning_rate: 5.e-5 lr_end: 1.e-6 warmup_steps: 2000 total_steps: -1 # -1 means it will load the total steps of the dataset layer_scale: False layer_decay: 0.65 # optimizer optimizer: type: FusedAdamWeightDecay beta1: 0.9 beta2: 0.95 eps: 1.e-8 weight_decay: 0.1 lr_scale: False lr_scale_factor: 256 # parallel config use_parallel: False parallel: parallel_mode: 1 # 0-dataset, 1-semi, 2-auto, 3-hybrid gradients_mean: False loss_repeated_mean: True enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: False # optimizer shard strategy_ckpt_save_file: "./ckpt_strategy.ckpt" parallel_config: data_parallel: 1 model_parallel: 8 pipeline_stage: 1 expert_parallel: 1 optimizer_shard: False # optimizer shard micro_batch_num: 1 vocab_emb_dp: True gradient_aggregation_group: 4 micro_batch_interleave_num: 1 # moe moe_config: expert_num: 1 capacity_factor: 1.05 aux_loss_factor: 0.05 num_experts_chosen: 1 # recompute recompute_config: recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: False # autotune auto_tune: False filepath_prefix: './autotune' autotune_per_step: 10 # profile profile: False profile_start_step: 1 profile_stop_step: 10 init_start_profile: True profile_communication: True profile_memory: True # callbacks callbacks: - type: MFLossMonitor - type: SummaryMonitor keep_default_action: True - type: CheckpointMointor prefix: "glm-6b" save_checkpoint_steps: 500 keep_checkpoint_max: 2 integrated_save: False async_save: False - type: ObsMonitor keep_last: False eval_callbacks: - type: ObsMonitor keep_last: False ================================================ FILE: llm-localization/ascend/mindformers/chatglm/run_glm_6b_infer.yaml ================================================ seed: 0 run_mode: 'predict' load_checkpoint: "/root/workspace/output/fullft_merge_checkpoint/filtered_transformed.ckpt" auto_trans_ckpt: False # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False output_dir: './output' # 当前不支持自定义修改,请勿修改该默认值 # ==== context config ==== context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" max_call_depth: 10000 max_device_memory: "30GB" save_graphs: False save_graphs_path: "./graph" device_id: 0 # aicc remote_save_url: "Please input obs url on AICC platform." # ==== model config ==== model: model_config: type: GLMConfig vocab_size: 130528 hidden_size: 4096 num_layers: 28 num_heads: 32 inner_hidden_size: 16384 seq_length: 512 # 推理时, 输入pad到的长度, model里的最大句长 embedding_dropout_prob: 0.0 attention_dropout_rate: 0.0 hidden_dropout_rate: 0.0 hidden_size_per_attention_head: # default "None" means hidden-size/num-attention-heads. layernorm_order: "post" layernorm_epsilon: 1.0e-5 use_final_layernorm: True use_past: True # True for incremental infer. activation_func: 'GELU' position_encoding_2d: True param_init_type: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float32" compute_dtype: "float16" bos_token_id: 130004 eos_token_id: 130005 mask_token_id: 130000 gmask_token_id: 130001 pad_token_id: 3 max_decode_length: 2048 # The maximum length of the generated words. is_enhanced_encoder: True is_npu_acceleration: True # sample in npu to acceleration checkpoint_name_or_path: "glm_6b" top_k: 1 top_p: 1 # top_p not support for npu_acceleration yet repetition_penalty: 1 do_sample: True arch: type: GLMChatModel trainer: type: CausalLanguageModelingTrainer model_name: 'glm_6b' metric: type: ADGENMetric tokenizer_type: "glm_6b" # use ChatGLMTokenizer processor: return_tensors: ms tokenizer: type: ChatGLMTokenizer bos_token: '' eos_token: '' end_token: '' mask_token: '[MASK]' gmask_token: '[gMASK]' padding_side: 'left' pad_token: '' unk_token: '' type: GLMProcessor # ==== dataset config ==== train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "label", "position_ids", "attention_mask"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset eval_dataset: &eval_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "label"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 eval_dataset_task: type: CausalLanguageModelDataset dataset_config: *eval_dataset # ==== runner config ==== runner_config: epochs: 1 batch_size: 1 sink_mode: True sink_size: 4 runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 4294967296 scale_factor: 2 scale_window: 1000 use_clip_grad: True # lr sechdule lr_schedule: type: polynomial learning_rate: 5.e-5 lr_end: 1.e-6 warmup_steps: 2000 total_steps: -1 # -1 means it will load the total steps of the dataset # optimizer optimizer: type: FusedAdamWeightDecay beta1: 0.9 beta2: 0.95 eps: 1.e-8 weight_decay: 0.1 # parallel config use_parallel: False parallel: parallel_mode: 0 # 0-dataset, 1-semi, 2-auto, 3-hybrid gradients_mean: False loss_repeated_mean: True enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: False # optimizer shard strategy_ckpt_save_file: "./ckpt_strategy.ckpt" parallel_config: data_parallel: 1 model_parallel: 1 pipeline_stage: 1 expert_parallel: 1 optimizer_shard: False # optimizer shard micro_batch_num: 1 vocab_emb_dp: True gradient_aggregation_group: 4 micro_batch_interleave_num: 1 # moe moe_config: expert_num: 1 capacity_factor: 1.05 aux_loss_factor: 0.05 num_experts_chosen: 1 # recompute recompute_config: recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: False # autotune auto_tune: False filepath_prefix: './autotune' autotune_per_step: 10 # profile profile: False profile_start_step: 1 profile_stop_step: 10 init_start_profile: True profile_communication: True profile_memory: True # callbacks callbacks: - type: MFLossMonitor - type: SummaryMonitor keep_default_action: True - type: CheckpointMointor prefix: "glm-6b" save_checkpoint_steps: 500 keep_checkpoint_max: 2 integrated_save: False async_save: False - type: ObsMonitor keep_last: False eval_callbacks: - type: ObsMonitor keep_last: False ================================================ FILE: llm-localization/ascend/mindformers/chatglm/run_glm_6b_lora.yaml ================================================ seed: 0 run_mode: 'finetune' load_checkpoint: "/root/workspace/model/chatglm-convert/ms_glm_6b.ckpt" auto_trans_ckpt: False # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False output_dir: './output' # 当前不支持自定义修改,请勿修改该默认值 # ==== context config ==== context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" max_call_depth: 10000 max_device_memory: "30GB" save_graphs: False device_id: 0 # aicc remote_save_url: "Please input obs url on AICC platform." # ==== model config ==== model: model_config: type: GLMConfig vocab_size: 130528 hidden_size: 4096 num_layers: 28 num_heads: 32 inner_hidden_size: 16384 seq_length: 512 # 推理时, 输入pad到的长度, model里的最大句长 embedding_dropout_prob: 0.0 attention_dropout_rate: 0.0 hidden_dropout_rate: 0.0 hidden_size_per_attention_head: # default "None" means hidden-size/num-attention-heads. layernorm_order: "post" layernorm_epsilon: 1.0e-5 use_final_layernorm: True use_past: False activation_func: 'GELU' position_encoding_2d: True param_init_type: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float32" compute_dtype: "float16" bos_token_id: 130004 eos_token_id: 130005 mask_token_id: 130000 gmask_token_id: 130001 pad_token_id: 3 max_decode_length: 2048 # The maximum length of the generated words. is_enhanced_encoder: True is_npu_acceleration: False checkpoint_name_or_path: "glm_6b" top_k: 1 top_p: 1 repetition_penalty: 1 do_sample: True arch: type: GLMForPreTrainingWithLora pet: pet_type: lora pet_config: lora_rank: 8 lora_alpha: 32 lora_dropout: 0.1 trainer: type: CausalLanguageModelingTrainer model_name: 'glm_6b_lora' # if True, do evaluate during the training process. if false, do nothing. # note that the task trainer should support _evaluate_in_training function. do_eval: False eval_step_interval: -1 # num of step intervals between each eval, -1 means no step end eval. eval_epoch_interval: 1 # num of epoch intervals between each eval, 1 means eval on every epoch end. metric: type: ADGENMetric tokenizer_type: "glm_6b" # use ChatGLMTokenizer processor: return_tensors: ms tokenizer: type: ChatGLMTokenizer bos_token: '' eos_token: '' end_token: '' mask_token: '[MASK]' gmask_token: '[gMASK]' padding_side: 'left' pad_token: '' unk_token: '' type: GLMProcessor # ==== dataset config ==== train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "/root/workspace/data/AdvertiseGen-ms/train_0604_128.mindrecord" shuffle: True input_columns: ["input_ids", "label", "position_ids", "attention_mask"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset eval_dataset: &eval_dataset data_loader: type: MindDataset dataset_dir: "/root/workspace/data/AdvertiseGen-ms/eval_0604_256.mindrecord" shuffle: True input_columns: ["input_ids", "label"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 eval_dataset_task: type: CausalLanguageModelDataset dataset_config: *eval_dataset # ==== runner config ==== runner_config: epochs: 1 batch_size: 8 sink_mode: True sink_size: 4 runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 4294967296 scale_factor: 2 scale_window: 1000 use_clip_grad: True # lr sechdule lr_schedule: type: polynomial learning_rate: 5.e-5 lr_end: 1.e-6 warmup_steps: 2000 total_steps: -1 # -1 means it will load the total steps of the dataset # optimizer optimizer: type: FusedAdamWeightDecay beta1: 0.9 beta2: 0.95 eps: 1.e-8 weight_decay: 0.1 layer_scale: False lr_scale: False # parallel config use_parallel: False parallel: parallel_mode: 1 # 0-dataset, 1-semi, 2-auto, 3-hybrid gradients_mean: False loss_repeated_mean: True enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: False # optimizer shard strategy_ckpt_save_file: "./ckpt_strategy.ckpt" parallel_config: data_parallel: 1 model_parallel: 4 pipeline_stage: 1 expert_parallel: 1 optimizer_shard: False # optimizer shard micro_batch_num: 1 vocab_emb_dp: True gradient_aggregation_group: 4 micro_batch_interleave_num: 1 # moe moe_config: expert_num: 1 capacity_factor: 1.05 aux_loss_factor: 0.05 num_experts_chosen: 1 # recompute recompute_config: recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: False # autotune auto_tune: False filepath_prefix: './autotune' autotune_per_step: 10 # profile profile: False profile_start_step: 1 profile_stop_step: 10 init_start_profile: True profile_communication: True profile_memory: True # callbacks callbacks: - type: MFLossMonitor - type: SummaryMonitor keep_default_action: True - type: CheckpointMointor prefix: "glm-6b-lora" save_checkpoint_steps: 500 keep_checkpoint_max: 2 integrated_save: False async_save: False - type: ObsMonitor keep_last: False eval_callbacks: - type: ObsMonitor keep_last: False ================================================ FILE: llm-localization/ascend/mindformers/chatglm/run_glm_6b_lora_infer.yaml ================================================ seed: 0 run_mode: 'predict' load_checkpoint: "" auto_trans_ckpt: False # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False output_dir: './output' # 当前不支持自定义修改,请勿修改该默认值 # ==== context config ==== context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" max_call_depth: 10000 max_device_memory: "30GB" save_graphs: False save_graphs_path: "./graph" device_id: 0 # aicc remote_save_url: "Please input obs url on AICC platform." # ==== model config ==== model: model_config: type: GLMConfig vocab_size: 130528 hidden_size: 4096 num_layers: 28 num_heads: 32 inner_hidden_size: 16384 seq_length: 512 # 推理时, 输入pad到的长度, model里的最大句长 embedding_dropout_prob: 0.0 attention_dropout_rate: 0.0 hidden_dropout_rate: 0.0 hidden_size_per_attention_head: # default "None" means hidden-size/num-attention-heads. layernorm_order: "post" layernorm_epsilon: 1.0e-5 use_final_layernorm: True use_past: True # True for incremental infer. activation_func: 'GELU' position_encoding_2d: True param_init_type: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float32" compute_dtype: "float16" bos_token_id: 130004 eos_token_id: 130005 mask_token_id: 130000 gmask_token_id: 130001 pad_token_id: 3 max_decode_length: 2048 # The maximum length of the generated words. is_enhanced_encoder: True is_npu_acceleration: True # sample in npu to acceleration checkpoint_name_or_path: "glm_6b" top_k: 1 top_p: 1 # top_p not support for npu_acceleration yet repetition_penalty: 1 do_sample: True arch: type: GLMChatModelWithLora pet: pet_type: lora pet_config: lora_rank: 8 lora_alpha: 32 lora_dropout: 0.1 trainer: type: CausalLanguageModelingTrainer model_name: 'glm_6b_lora' metric: type: ADGENMetric tokenizer_type: "glm_6b" # use ChatGLMTokenizer processor: return_tensors: ms tokenizer: type: ChatGLMTokenizer bos_token: '' eos_token: '' end_token: '' mask_token: '[MASK]' gmask_token: '[gMASK]' padding_side: 'left' pad_token: '' unk_token: '' type: GLMProcessor # ==== dataset config ==== train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "label", "position_ids", "attention_mask"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset eval_dataset: &eval_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "label"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 1 repeat: 1 numa_enable: False prefetch_size: 1 seed: 0 eval_dataset_task: type: CausalLanguageModelDataset dataset_config: *eval_dataset # ==== runner config ==== runner_config: epochs: 1 batch_size: 1 sink_mode: True sink_size: 4 runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 4294967296 scale_factor: 2 scale_window: 1000 use_clip_grad: True # lr sechdule lr_schedule: type: polynomial learning_rate: 5.e-5 lr_end: 1.e-6 warmup_steps: 2000 total_steps: -1 # -1 means it will load the total steps of the dataset # optimizer optimizer: type: FusedAdamWeightDecay beta1: 0.9 beta2: 0.95 eps: 1.e-8 weight_decay: 0.1 # parallel config use_parallel: False parallel: parallel_mode: 0 # 0-dataset, 1-semi, 2-auto, 3-hybrid gradients_mean: False loss_repeated_mean: True enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: False # optimizer shard strategy_ckpt_save_file: "./ckpt_strategy.ckpt" parallel_config: data_parallel: 1 model_parallel: 1 pipeline_stage: 1 expert_parallel: 1 optimizer_shard: False # optimizer shard micro_batch_num: 1 vocab_emb_dp: True gradient_aggregation_group: 4 micro_batch_interleave_num: 1 # moe moe_config: expert_num: 1 capacity_factor: 1.05 aux_loss_factor: 0.05 num_experts_chosen: 1 # recompute recompute_config: recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: False # autotune auto_tune: False filepath_prefix: './autotune' autotune_per_step: 10 # profile profile: False profile_start_step: 1 profile_stop_step: 10 init_start_profile: True profile_communication: True profile_memory: True # callbacks callbacks: - type: MFLossMonitor - type: SummaryMonitor keep_default_action: True - type: CheckpointMointor prefix: "glm-6b-lora" save_checkpoint_steps: 500 keep_checkpoint_max: 2 integrated_save: False async_save: False - type: ObsMonitor keep_last: False eval_callbacks: - type: ObsMonitor keep_last: False ================================================ FILE: llm-localization/ascend/mindformers/env.md ================================================ ``` docker pull --platform=arm64 swr.cn-central-221.ovaijisuan.com/mindformers/mindformers1.0_mindspore2.2.11:aarch_20240125 ``` ``` docker run -it -u root \ --ipc=host \ --network=host \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /var/log/npu/:/usr/slog \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ --name mindformers_dev \ swr.cn-central-221.ovaijisuan.com/mindformers/mindformers1.0_mindspore2.2.11:aarch_20240125 \ /bin/bash ``` ``` git clone -b dev https://gitee.com/mindspore/mindformers.git cd mindformers bash build.sh ``` ================================================ FILE: llm-localization/ascend/mindformers/llama/README.md ================================================ ## 训练 ================================================ FILE: llm-localization/ascend/mindformers/qwen/qwen1训练.md ================================================ - https://gitee.com/mindspore/mindformers/blob/r1.0/research/qwen/qwen.md ================================================ FILE: llm-localization/ascend/mindformers/qwen/run_qwen_7b.yaml ================================================ seed: 0 output_dir: './output' # path to save checkpoint/strategy load_checkpoint: '' src_strategy_path_or_dir: '' auto_trans_ckpt: False # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False use_parallel: False run_mode: 'predict' # trainer config trainer: type: CausalLanguageModelingTrainer model_name: 'qwen_7b' # dataset train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "labels", "attention_mask"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 4 repeat: 1 numa_enable: False prefetch_size: 1 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset # runner config runner_config: epochs: 5 batch_size: 1 sink_mode: True sink_size: 2 runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 65536 scale_factor: 2 scale_window: 1000 use_clip_grad: True # optimizer optimizer: type: FP32StateAdamWeightDecay beta1: 0.9 beta2: 0.95 eps: 1.e-6 weight_decay: 0.1 # lr sechdule lr_schedule: type: CosineWithWarmUpLR learning_rate: 1.e-5 warmup_ratio: 0.01 total_steps: -1 # -1 means it will load the total steps of the dataset # callbacks callbacks: - type: MFLossMonitor - type: CheckpointMointor prefix: "qwen" save_checkpoint_steps: 10000 keep_checkpoint_max: 3 integrated_save: False async_save: False - type: ObsMonitor # default parallel of device num = 8 for Atlas 800T A2 parallel_config: data_parallel: 8 model_parallel: 1 pipeline_stage: 1 micro_batch_num: 1 vocab_emb_dp: False gradient_aggregation_group: 4 # when model parallel is greater than 1, we can set micro_batch_interleave_num=2, that may accelerate the train process. micro_batch_interleave_num: 1 # recompute config recompute_config: recompute: False select_recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: False recompute_slice_activation: False model: model_config: type: QwenConfig batch_size: 1 seq_length: 1024 hidden_size: 4096 num_layers: 32 num_heads: 32 vocab_size: 151936 intermediate_size: 11008 rms_norm_eps: 1.0e-6 emb_dropout_prob: 0.0 eos_token_id: 151643 pad_token_id: 151643 compute_dtype: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float16" rotary_dtype: "float16" param_init_type: "float32" use_past: True use_flash_attention: False use_paged_attention: False # only supported in mslite inference block_size: 32 num_blocks: 128 is_dynamic: False use_kvcache_op: False offset: 0 checkpoint_name_or_path: "/path/qwen_7b_base.ckpt" repetition_penalty: 1 max_decode_length: 512 top_k: 0 top_p: 0.8 do_sample: False # configuration items copied from Qwen rotary_pct: 1.0 rotary_emb_base: 10000 kv_channels: 128 arch: type: QwenForCausalLM processor: return_tensors: ms tokenizer: model_max_length: 8192 vocab_file: "/path/qwen.tiktoken" pad_token: "<|endoftext|>" type: QwenTokenizer type: QwenProcessor # mindspore context init config context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" ascend_config: precision_mode: "must_keep_origin_dtype" max_call_depth: 10000 max_device_memory: "58GB" save_graphs: False save_graphs_path: "./graph" device_id: 0 # parallel context config parallel: parallel_mode: 1 # 0-data parallel, 1-semi-auto parallel, 2-auto parallel, 3-hybrid parallel gradients_mean: False enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: True strategy_ckpt_config: save_file: "./ckpt_strategy.ckpt" only_trainable_params: False parallel_optimizer_config: gradient_accumulation_shard: False parallel_optimizer_threshold: 64 # aicc remote_save_url: "Please input obs url on AICC platform." ================================================ FILE: llm-localization/ascend/mindformers/qwen/run_qwen_7b_910b.yaml ================================================ seed: 0 output_dir: './output' # path to save checkpoint/strategy load_checkpoint: '' src_strategy_path_or_dir: '' auto_trans_ckpt: True # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False use_parallel: True run_mode: 'finetune' # trainer config trainer: type: CausalLanguageModelingTrainer model_name: 'qwen_7b' # dataset train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "labels", "attention_mask"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 4 repeat: 1 numa_enable: False prefetch_size: 1 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset # runner config runner_config: epochs: 5 batch_size: 1 sink_mode: True sink_size: 2 runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 65536 scale_factor: 2 scale_window: 1000 use_clip_grad: True # optimizer optimizer: type: FP32StateAdamWeightDecay beta1: 0.9 beta2: 0.95 eps: 1.e-6 weight_decay: 0.1 # lr sechdule lr_schedule: type: CosineWithWarmUpLR learning_rate: 1.e-5 warmup_ratio: 0.01 total_steps: -1 # -1 means it will load the total steps of the dataset # callbacks callbacks: - type: MFLossMonitor - type: CheckpointMointor prefix: "qwen" save_checkpoint_steps: 10000 keep_checkpoint_max: 3 integrated_save: False async_save: False - type: ObsMonitor # default parallel of device num = 8 for Atlas 800T A2 parallel_config: data_parallel: 4 model_parallel: 2 pipeline_stage: 1 micro_batch_num: 1 vocab_emb_dp: True gradient_aggregation_group: 4 # when model parallel is greater than 1, we can set micro_batch_interleave_num=2, that may accelerate the train process. micro_batch_interleave_num: 1 # recompute config recompute_config: recompute: False select_recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: False recompute_slice_activation: False model: model_config: type: QwenConfig batch_size: 1 seq_length: 512 hidden_size: 4096 num_layers: 32 num_heads: 32 vocab_size: 151936 intermediate_size: 11008 rms_norm_eps: 1.0e-6 emb_dropout_prob: 0.0 eos_token_id: 151643 pad_token_id: 151643 compute_dtype: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float16" rotary_dtype: "float16" param_init_type: "float16" use_past: True use_flash_attention: False use_paged_attention: False # only supported in mslite inference block_size: 32 num_blocks: 128 is_dynamic: False use_kvcache_op: False offset: 0 checkpoint_name_or_path: "/path/qwen_7b_base.ckpt" repetition_penalty: 1 max_decode_length: 512 top_k: 0 top_p: 0.8 do_sample: False # configuration items copied from Qwen rotary_pct: 1.0 rotary_emb_base: 10000 kv_channels: 128 arch: type: QwenForCausalLM processor: return_tensors: ms tokenizer: model_max_length: 8192 vocab_file: "/path/qwen.tiktoken" pad_token: "<|endoftext|>" type: QwenTokenizer type: QwenProcessor # mindspore context init config context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" ascend_config: precision_mode: "must_keep_origin_dtype" max_call_depth: 10000 max_device_memory: "30GB" save_graphs: False save_graphs_path: "./graph" device_id: 0 # parallel context config parallel: parallel_mode: 1 # 0-data parallel, 1-semi-auto parallel, 2-auto parallel, 3-hybrid parallel gradients_mean: False enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: True strategy_ckpt_config: save_file: "./ckpt_strategy.ckpt" only_trainable_params: False parallel_optimizer_config: gradient_accumulation_shard: False parallel_optimizer_threshold: 64 # aicc remote_save_url: "Please input obs url on AICC platform." ================================================ FILE: llm-localization/ascend/mindformers/qwen1.5/qwen1.5训练.md ================================================ - https://gitee.com/mindspore/mindformers/blob/r1.0/research/qwen1_5/qwen1_5.md docker pull swr.cn-central-221.ovaijisuan.com/mindformers/mindformers1.1_mindspore2.3rc2:20240511 ================================================ FILE: llm-localization/ascend/mindformers/qwen1.5/run_qwen1_5_7b_finetune.yaml ================================================ seed: 0 output_dir: './output' # path to save checkpoint/strategy load_checkpoint: '' src_strategy_path_or_dir: '' auto_trans_ckpt: True # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False run_mode: 'finetune' # trainer config trainer: type: CausalLanguageModelingTrainer model_name: 'qwen2_7b' # runner config runner_config: epochs: 5 batch_size: 1 sink_mode: True sink_size: 2 runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 4096 scale_factor: 2 scale_window: 1000 use_clip_grad: True # optimizer optimizer: type: AdamWeightDecayX beta1: 0.9 beta2: 0.95 eps: 1.e-8 learning_rate: 1.e-6 weight_decay: 0.01 # lr sechdule lr_schedule: type: CosineWithWarmUpLR learning_rate: 1.e-6 warmup_ratio: 0.01 total_steps: -1 # -1 means it will load the total steps of the dataset # callbacks callbacks: - type: MFLossMonitor - type: CheckpointMointor prefix: "qwen2" save_checkpoint_steps: 1000 keep_checkpoint_max: 1 integrated_save: False async_save: False - type: ObsMonitor # recompute config recompute_config: recompute: True select_recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: True model: model_config: type: LlamaConfig batch_size: 1 seq_length: 512 hidden_size: 4096 num_layers: 32 num_heads: 32 vocab_size: 151936 intermediate_size: 11008 qkv_has_bias: True rms_norm_eps: 1.0e-5 theta: 1000000.0 emb_dropout_prob: 0.0 eos_token_id: 151643 pad_token_id: 151643 compute_dtype: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float16" rotary_dtype: "float16" param_init_type: "float16" use_past: True use_flash_attention: False use_past_shard: False offset: 0 checkpoint_name_or_path: "" repetition_penalty: 1 max_decode_length: 512 top_k: 0 top_p: 0.8 do_sample: False compute_in_2d: True # configuration items copied from Qwen rotary_pct: 1.0 rotary_emb_base: 1000000 kv_channels: 128 arch: type: LlamaForCausalLM processor: return_tensors: ms tokenizer: model_max_length: 32768 vocab_file: "/{path}/vocab.json" merges_file: "/{path}/merges.txt" unk_token: "<|endoftext|>" eos_token: "<|endoftext|>" pad_token: "<|endoftext|>" type: Qwen2Tokenizer type: Qwen2Processor # mindspore context init config context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" ascend_config: precision_mode: "must_keep_origin_dtype" max_call_depth: 10000 max_device_memory: "30GB" save_graphs: False save_graphs_path: "./graph" device_id: 0 use_parallel: True # parallel context config parallel: parallel_mode: 1 # 0-data parallel, 1-semi-auto parallel, 2-auto parallel, 3-hybrid parallel gradients_mean: False enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: True strategy_ckpt_save_file: "./ckpt_strategy.ckpt" parallel_optimizer_config: gradient_accumulation_shard: False parallel_optimizer_threshold: 64 # default parallel of device num = 32 910B parallel_config: data_parallel: 4 model_parallel: 2 pipeline_stage: 1 use_seq_parallel: True micro_batch_num: 8 vocab_emb_dp: False gradient_aggregation_group: 8 # when model parallel is greater than 1, we can set micro_batch_interleave_num=2, that may accelerate the train process. micro_batch_interleave_num: 1 # dataset train_dataset: &train_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: True input_columns: ["input_ids", "labels", "attention_mask"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: True batch_size: 4 repeat: 1 numa_enable: False prefetch_size: 1 train_dataset_task: type: CausalLanguageModelDataset dataset_config: *train_dataset do_eval: False eval_step_interval: -1 # num of step intervals between each eval, -1 means no step end eval. eval_epoch_interval: 50 # num of epoch intervals between each eval, 1 means eval on every epoch end. # eval dataset eval_dataset: &eval_dataset data_loader: type: MindDataset dataset_dir: "" shuffle: False input_columns: ["input_ids", "target_ids", "attention_mask"] num_parallel_workers: 8 python_multiprocessing: False drop_remainder: False repeat: 1 numa_enable: False prefetch_size: 1 eval_dataset_task: type: CausalLanguageModelDataset dataset_config: *eval_dataset auto_tune: False filepath_prefix: './autotune' autotune_per_step: 10 profile: False profile_start_step: 1 profile_stop_step: 10 init_start_profile: False profile_communication: False profile_memory: True layer_scale: False layer_decay: 0.65 lr_scale_factor: 256 # aicc remote_save_url: "Please input obs url on AICC platform." ================================================ FILE: llm-localization/ascend/mindformers/qwen1.5/run_qwen1_5_7b_infer.yaml ================================================ seed: 0 output_dir: './output' # path to save checkpoint/strategy load_checkpoint: '' src_strategy_path_or_dir: '' auto_trans_ckpt: False # If true, auto transform load_checkpoint to load in distributed model only_save_strategy: False resume_training: False use_parallel: True run_mode: 'predict' # trainer config trainer: type: CausalLanguageModelingTrainer model_name: 'qwen2_7b' # runner config runner_config: epochs: 5 batch_size: 1 sink_mode: True sink_size: 2 runner_wrapper: type: MFTrainOneStepCell scale_sense: type: DynamicLossScaleUpdateCell loss_scale_value: 4294967296 scale_factor: 2 scale_window: 1000 use_clip_grad: True # callbacks callbacks: - type: MFLossMonitor - type: CheckpointMointor prefix: "qwen" save_checkpoint_steps: 10000 keep_checkpoint_max: 1 integrated_save: False async_save: False - type: ObsMonitor # default parallel of device num = 8 for Atlas 800T A2 parallel_config: data_parallel: 1 model_parallel: 4 pipeline_stage: 1 micro_batch_num: 1 vocab_emb_dp: False gradient_aggregation_group: 4 # when model parallel is greater than 1, we can set micro_batch_interleave_num=2, that may accelerate the train process. micro_batch_interleave_num: 1 # recompute config recompute_config: recompute: True select_recompute: False parallel_optimizer_comm_recompute: False mp_comm_recompute: True recompute_slice_activation: True model: model_config: type: LlamaConfig batch_size: 1 seq_length: 8192 hidden_size: 4096 num_layers: 32 num_heads: 32 vocab_size: 151936 intermediate_size: 11008 qkv_has_bias: True rms_norm_eps: 1.0e-5 theta: 1000000.0 emb_dropout_prob: 0.0 eos_token_id: 151643 pad_token_id: 151643 compute_dtype: "float16" layernorm_compute_type: "float32" softmax_compute_type: "float16" rotary_dtype: "float16" param_init_type: "float16" use_past: True use_flash_attention: False use_past_shard: False offset: 0 checkpoint_name_or_path: "" repetition_penalty: 1 max_decode_length: 512 top_k: 0 top_p: 0.8 do_sample: False compute_in_2d: True arch: type: LlamaForCausalLM processor: return_tensors: ms tokenizer: model_max_length: 32768 vocab_file: "/{path}/vocab.json" merges_file: "/{path}/merges.txt" unk_token: "<|endoftext|>" eos_token: "<|endoftext|>" pad_token: "<|endoftext|>" type: Qwen2Tokenizer type: Qwen2Processor # mindspore context init config context: mode: 0 #0--Graph Mode; 1--Pynative Mode device_target: "Ascend" enable_graph_kernel: False graph_kernel_flags: "--disable_expand_ops=Softmax,Dropout --enable_parallel_fusion=true --reduce_fuse_depth=8 --enable_auto_tensor_inplace=true" ascend_config: precision_mode: "must_keep_origin_dtype" max_call_depth: 10000 max_device_memory: "58GB" save_graphs: False save_graphs_path: "./graph" device_id: 0 # parallel context config parallel: parallel_mode: 1 # 0-data parallel, 1-semi-auto parallel, 2-auto parallel, 3-hybrid parallel gradients_mean: False enable_alltoall: False full_batch: True search_mode: "sharding_propagation" enable_parallel_optimizer: True strategy_ckpt_config: save_file: "./ckpt_strategy.ckpt" only_trainable_params: False parallel_optimizer_config: gradient_accumulation_shard: False parallel_optimizer_threshold: 64 ================================================ FILE: llm-localization/ascend/mindformers/trick.md ================================================ ``` global_batch_size = batch_size * data_parallel * micro_batch_num * micro_batch_interleave_num = 16 = 2 * 1 * 8 * 1). batch_size : 数据批次大小 micro_batch_num:流水线并行的微批次大小。pipeline_satge大于1时,开启流水并行时使用,此处需满足micro_batch_num >= pipeline_satge micro_batch_interleave_num: batch_size的拆分份数,多副本并行开关,通常在模型并行时使用,用于优化model_parallel时产生的通信损耗,纯流水并行时不建议使用。 # compute throughput (samples/s/p) 每一步每一卡每一秒能处理的样本数 throughput = self.global_batch_size / self.device_num / (per_step_seconds / 1000) ``` deepspeed: global_train_batch_size = train_micro_batch_size_per_gpu * gradient_accumulation_steps * number of GPUs ================================================ FILE: llm-localization/ascend/mindformers/权重格式转换.md ================================================ ## 模型格式权重转换 - [离线权重转换](https://gitee.com/mindspore/mindformers/blob/r1.0/docs/feature_cards/Transform_Ckpt.md) - https://gitee.com/mindspore/mindformers/blob/r1.0/mindformers/tools/transform_ckpt.py - https://gitee.com/mindspore/mindspore/blob/v2.2.14/mindspore/python/mindspore/parallel/checkpoint_transform.py - https://www.mindspore.cn/tutorials/experts/zh-CN/master/parallel/model_transformation.html ConvertWeight支持对torch权重和mindspore权重的格式互转 - https://gitee.com/mindspore/mindformers/blob/dev/docs/feature_cards/Convert_Weight.md - https://gitee.com/mindspore/mindformers/blob/dev/research/qwen/convert_weight.py - https://gitee.com/mindspore/mindformers/blob/dev/research/qwen/convert_reversed.py - https://gitee.com/mindspore/mindformers/blob/dev/mindformers/utils/convert_utils.py - 统一转换入口:https://gitee.com/mindspore/mindformers/blob/dev/convert_weight.py ### 打印pytorch格式模型权重 ``` import torch from transformers import AutoModelForCausalLM, AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("/workspace/Qwen-7B-Chat", use_fast=False, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained("/workspace/Qwen-7B-Chat", device_map="cpu", torch_dtype=torch.float16, trust_remote_code=True) print(model) for name, param in model.named_parameters(): print(name) QWenLMHeadModel( (transformer): QWenModel( (wte): Embedding(151936, 4096) (drop): Dropout(p=0.0, inplace=False) (rotary_emb): RotaryEmbedding() (h): ModuleList( (0-31): 32 x QWenBlock( (ln_1): RMSNorm() (attn): QWenAttention( (c_attn): Linear(in_features=4096, out_features=12288, bias=True) (c_proj): Linear(in_features=4096, out_features=4096, bias=False) (attn_dropout): Dropout(p=0.0, inplace=False) ) (ln_2): RMSNorm() (mlp): QWenMLP( (w1): Linear(in_features=4096, out_features=11008, bias=False) (w2): Linear(in_features=4096, out_features=11008, bias=False) (c_proj): Linear(in_features=11008, out_features=4096, bias=False) ) ) ) (ln_f): RMSNorm() ) (lm_head): Linear(in_features=4096, out_features=151936, bias=False) ) transformer.wte.weight transformer.h.0.ln_1.weight transformer.h.0.attn.c_attn.weight transformer.h.0.attn.c_attn.bias transformer.h.0.attn.c_proj.weight transformer.h.0.ln_2.weight transformer.h.0.mlp.w1.weight transformer.h.0.mlp.w2.weight transformer.h.0.mlp.c_proj.weight ... transformer.h.31.ln_1.weight transformer.h.31.attn.c_attn.weight transformer.h.31.attn.c_attn.bias transformer.h.31.attn.c_proj.weight transformer.h.31.ln_2.weight transformer.h.31.mlp.w1.weight transformer.h.31.mlp.w2.weight transformer.h.31.mlp.c_proj.weight transformer.ln_f.weight lm_head.weight ``` ## 打印mindspore格式模型权重 ``` from mindformers.tools.register.config import MindFormerConfig from mindformers.tools.utils import str2bool from qwen_config import QwenConfig from qwen_model import QwenForCausalLM from qwen_tokenizer import QwenTokenizer yaml_path = "/workspace/mindformers/research/qwen/run_qwen_7b_infer.yaml" config = MindFormerConfig(yaml_path) model_config = QwenConfig.from_pretrained(yaml_path) model = QwenForCausalLM(model_config) print(model) QwenForCausalLM< (transformer): QwenModel< (wte): LlamaEmbedding<> (drop): Dropout (layers): CellList< (0): QwenDecodeLayer< (attention_norm): LlamaRMSNorm<> (ffn_norm): LlamaRMSNorm<> (attention): LLamaAttention< (apply_rotary_emb): LlamaRotaryEmbedding<> (wq): Linear<> (wk): Linear<> (wv): Linear<> (wo): Linear<> (kvcache_mgr): KVCacheMgr<> > (feed_forward): QwenFeedForward< (silu): LlamaSiLU<> (w1): Linear<> (w2): Linear<> (w3): Linear<> > > ... (31): QwenDecodeLayer< (attention_norm): LlamaRMSNorm<> (ffn_norm): LlamaRMSNorm<> (attention): LLamaAttention< (apply_rotary_emb): LlamaRotaryEmbedding<> (wq): Linear<> (wk): Linear<> (wv): Linear<> (wo): Linear<> (kvcache_mgr): KVCacheMgr<> > (feed_forward): QwenFeedForward< (silu): LlamaSiLU<> (w1): Linear<> (w2): Linear<> (w3): Linear<> > > > (freqs_mgr): FreqsMgr<> (casual_mask): CausalMaskForQwen<> (kvcache_preprocess): KVCachePreprocess<> (ln_f): LlamaRMSNorm<> > (lm_head): Linear<> (loss): CrossEntropyLoss< (_softmax): _Softmax<> (_nllloss): _NLLLoss<> > > ``` ``` import mindspore as ms model = ms.load_checkpoint("/workspace/qwen-7b-chat-ms/qwen_7b_ms.ckpt") for name, value in model.items(): print(name) transformer.wte.embedding_weight transformer.layers.0.attention_norm.weight transformer.layers.0.attention.wq.weight transformer.layers.0.attention.wk.weight transformer.layers.0.attention.wv.weight transformer.layers.0.attention.wq.bias transformer.layers.0.attention.wk.bias transformer.layers.0.attention.wv.bias transformer.layers.0.attention.wo.weight transformer.layers.0.ffn_norm.weight transformer.layers.0.feed_forward.w1.weight transformer.layers.0.feed_forward.w3.weight transformer.layers.0.feed_forward.w2.weight ... transformer.layers.31.attention_norm.weight transformer.layers.31.attention.wq.weight transformer.layers.31.attention.wk.weight transformer.layers.31.attention.wv.weight transformer.layers.31.attention.wq.bias transformer.layers.31.attention.wk.bias transformer.layers.31.attention.wv.bias transformer.layers.31.attention.wo.weight transformer.layers.31.ffn_norm.weight transformer.layers.31.feed_forward.w1.weight transformer.layers.31.feed_forward.w3.weight transformer.layers.31.feed_forward.w2.weight transformer.ln_f.weight lm_head.weight ``` ## qwen1.5 ``` import torch from transformers import AutoModelForCausalLM, AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("/workspace/Qwen1.5-7B-Chat", use_fast=False, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained("/workspace/Qwen1.5-7B-Chat", device_map="cpu", torch_dtype=torch.float16, trust_remote_code=True) print(model) for name, param in model.named_parameters(): print(name) /home/guodong/Qwen-7B-Chat Qwen2ForCausalLM( (model): Qwen2Model( (embed_tokens): Embedding(151936, 4096) (layers): ModuleList( (0-31): 32 x Qwen2DecoderLayer( (self_attn): Qwen2Attention( (q_proj): Linear(in_features=4096, out_features=4096, bias=True) (k_proj): Linear(in_features=4096, out_features=4096, bias=True) (v_proj): Linear(in_features=4096, out_features=4096, bias=True) (o_proj): Linear(in_features=4096, out_features=4096, bias=False) (rotary_emb): Qwen2RotaryEmbedding() ) (mlp): Qwen2MLP( (gate_proj): Linear(in_features=4096, out_features=11008, bias=False) (up_proj): Linear(in_features=4096, out_features=11008, bias=False) (down_proj): Linear(in_features=11008, out_features=4096, bias=False) (act_fn): SiLU() ) (input_layernorm): Qwen2RMSNorm() (post_attention_layernorm): Qwen2RMSNorm() ) ) (norm): Qwen2RMSNorm() ) (lm_head): Linear(in_features=4096, out_features=151936, bias=False) ) for name, param in model.named_parameters(): ... print(name) ... model.embed_tokens.weight model.layers.0.self_attn.q_proj.weight model.layers.0.self_attn.q_proj.bias model.layers.0.self_attn.k_proj.weight model.layers.0.self_attn.k_proj.bias model.layers.0.self_attn.v_proj.weight model.layers.0.self_attn.v_proj.bias model.layers.0.self_attn.o_proj.weight model.layers.0.mlp.gate_proj.weight model.layers.0.mlp.up_proj.weight model.layers.0.mlp.down_proj.weight model.layers.0.input_layernorm.weight model.layers.0.post_attention_layernorm.weight ... model.layers.31.self_attn.q_proj.weight model.layers.31.self_attn.q_proj.bias model.layers.31.self_attn.k_proj.weight model.layers.31.self_attn.k_proj.bias model.layers.31.self_attn.v_proj.weight model.layers.31.self_attn.v_proj.bias model.layers.31.self_attn.o_proj.weight model.layers.31.mlp.gate_proj.weight model.layers.31.mlp.up_proj.weight model.layers.31.mlp.down_proj.weight model.layers.31.input_layernorm.weight model.layers.31.post_attention_layernorm.weight model.norm.weight lm_head.weight ``` ``` import mindspore as ms model = ms.load_checkpoint("/workspace/qwen1.5-7b-chat-ms/qwen_7b_ms.ckpt") for name, value in model.items(): print(name) model.tok_embeddings.embedding_weight model.layers.0.attention.wq.weight model.layers.0.attention.wq.bias model.layers.0.attention.wk.weight model.layers.0.attention.wk.bias model.layers.0.attention.wv.weight model.layers.0.attention.wv.bias model.layers.0.attention.wo.weight model.layers.0.feed_forward.w1.weight model.layers.0.feed_forward.w3.weight model.layers.0.feed_forward.w2.weight model.layers.0.attention_norm.weight model.layers.0.ffn_norm.weight ... model.layers.31.attention.wq.weight model.layers.31.attention.wq.bias model.layers.31.attention.wk.weight model.layers.31.attention.wk.bias model.layers.31.attention.wv.weight model.layers.31.attention.wv.bias model.layers.31.attention.wo.weight model.layers.31.feed_forward.w1.weight model.layers.31.feed_forward.w3.weight model.layers.31.feed_forward.w2.weight model.layers.31.attention_norm.weight model.layers.31.ffn_norm.weight model.norm_out.weight lm_head.weight ``` ================================================ FILE: llm-localization/ascend/mindie/2.0.RC2/qwen.md ================================================ # README - 千问(Qwen)大语言模型是阿里巴巴集团推出的大型语言模型,具备强大的自然语言处理能力,能够理解和生成文本,能够应用于智能客服、内容生成、问答系统等多个场景,助力企业智能化升级。 # 特性矩阵 - 下表展示Qwen模型各版本支持的特性 | 模型及参数量 | 800I A2 Tensor Parallelism | 300I DUO Tensor Parallelism | FP16 | BF16 | Flash Attention | Paged Attention | W8A8量化 | W8A16量化 | KV cache量化 | 稀疏量化(仅支持300I DUO) | MOE量化 | MindIE Service | TGI | 长序列 | prefix_cache | FA3量化 | functioncall | Multi LoRA| W4A16量化 | | ----------------- |----------------------------|--------------------| ---- | ---- | --------------- | --------------- | -------- | --------- | ------------ | -------- | ------- | -------------- | --- | ------ | ---------- | --- | --- | --- |---------| | Qwen2-57B-A14B | 支持world size 8 | × | × | √ | × | √ | × | × | × | × | × | √ | × | × | x | x | x | x | x | | Qwen2-7B | 支持world size 1,2,4,8 | 支持world size 2,4,8 | √ | √ | × | √ | √ | × | × | √ | x | √ | × | × | x | x | x | x | x | | Qwen2-72B | 支持world size 1,2,4,8 | 支持world size 2,4,8 | √ | √ | × | √ | √ | √ | √ | √ | × | √ | × | √ | √ | x | √ | √ | x | | gte-Qwen2-7B | 支持world size 1,2,4 | × | √ | × | × | √ | × | × | × | × | × | × | × | × | x | x | x | x | x | | Qwen2.5-0.5B | 支持world size 1,2,4,8 | 支持world size 2,4,8 | √ | √ | × | √ | × | × | × | × | × | × | × | × | x | x | x | x | x | | Qwen2.5-1.5B | 支持world size 1,2,4,8 | 支持world size 2,4,8 | √ | √ | × | √ | × | × | × | × | × | × | × | × | x | x | x | x | x | | Qwen2.5-7B | 支持world size 1,2,4,8 | 支持world size 2,4,8 | √ | √ | × | √ | √ | × | × | √ | × | √ | × | × | √ | x | √ | x | x | | Qwen2.5-14B | 支持world size 2,4,8 | 支持world size 2,4,8 | √ | √ | × | √ | √ | × | × | √ | × | √ | × | × | x | x | √ | x | x | | Qwen2.5-32B | 支持world size 4,8 | × | √ | √ | × | √ | √ | × | × | × | × | √ | × | × | x | x | √ | x | x | | Qwen2.5-72B | 支持world size 8 | × | √ | √ | × | √ | × | × | × | × | × | √ | × | × | x | √ | √ | x | √ | | QwenCode2.5-7B | × | 支持world size 2,4,8 | √ | × | × | √ | × | × | × | √ | x | √ | × | × | √ | x | x | x | x | | QwenCode2.5-32B | 支持world size 4,8 | x | × | √ | × | √ | × | × | × | x | x | x | × | × | x | x | x | x | x | 注:表中所示支持的world size为对话测试可跑通的配置,实际运行时还需考虑输入序列长度带来的显存占用。 - 模型支持的张量并行维度(Tensor Parallelism)可以通过查看模型的`config.json`文件中的 **KV头的数量** (`num_key_value_heads` 或者类似字段)来判断模型支持多少维度的张量并行。 > 例如 `Qwen2-0.5B` 的 `"num_key_value_heads"` 为 2,表明其只支持world size 1,2 > 例如 `Qwen2.5-32B` 的 `"num_key_value_heads"` 为 8,表明其理论支持world size 1,2,4,8(不考虑显存占用) - qwen2/2.5系列模型在800I A2仅支持bfloat16浮点类型,300I DUO仅支持float16浮点类型。 ## 开源权重 #### Qwen2 - [Qwen2-7B](https://huggingface.co/Qwen/Qwen2-7B/tree/main) - [Qwen2-7B-Instruct](https://huggingface.co/Qwen/Qwen2-7B-Instruct/tree/main) - [gte-Qwen2-7B-Instruct](https://huggingface.co/Alibaba-NLP/gte-Qwen2-7B-instruct) - [Qwen2-57B-A14B-Instruct](https://huggingface.co/Qwen/Qwen2-57B-A14B-Instruct/tree/main) - [Qwen2-72B](https://huggingface.co/Qwen/Qwen2-72B/tree/main) - [Qwen2-72B-Instruct](https://huggingface.co/Qwen/Qwen2-72B-Instruct/tree/main) #### Qwen2.5 - [Qwen2.5-0.5B-Instruct](https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct/tree/main) - [Qwen2.5-1.5B-Instruct](https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct/tree/main) - [Qwen2.5-7B-Instruct](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct/tree/main) - [Qwen2.5-14B-Instruct](https://huggingface.co/Qwen/Qwen2.5-14B-Instruct/tree/main) - [Qwen2.5-32B-Instruct](https://huggingface.co/Qwen/Qwen2.5-32B-Instruct/tree/main) - [Qwen2.5-72B-Instruct](https://huggingface.co/Qwen/Qwen2.5-72B-Instruct/tree/main) #### Qwen2.5-Coder - [Qwen2.5-Coder-7B-Instruct](https://huggingface.co/Qwen/Qwen2.5-Coder-7B-Instruct/tree/main) - [Qwen2.5-Coder-32B-Instruct](https://huggingface.co/Qwen/Qwen2.5-Coder-32B-Instruct/tree/main) # 版本配套 下表展示运行各个系列Qwen模型所需要的transformers版本 | 模型版本 | transformers版本 | | -------- | ---------------- | | Qwen2 | 4.40.1及以上 | | Qwen2.5 | 4.43.1 | | Qwen2.5-Coder | 4.43.1及以上 | # Paged Attention 推理使用说明 ## 推理须知: - Qwen模型权重所在路径中的config.json文件需添加字段`torch_dtype`,例如`"torch_dtype": "float16"` - 执行量化推理时,须在量化权重所在路径的config.json文件中添加字段`quantize`,值为当前量化权重的量化方式,例如`"quantize": "w8a8"`、`"quantize": "w8a16"` - QWen-14B执行[2k,32k](QWen-7B为[8k,32k])长序列推理时需增加环境变量`LONG_SEQ_ENABLE=1`。长序列推理过程具有更多计算节点,因此相比于短序列,推理性能将有下降。 - Qwen2-7B建议采用`bf16`格式,即其权重所在路径中的config.json文件字段`torch_dtype`保持为`bfloat16` - 300I DUO只支持`"torch_dtype": "float16"` - 稀疏量化w8a8sc仅支持在300I DUO上使用 - 稀疏量化分为两个步骤。步骤一:w8a8s 可在任何机器上生成,注意config中需要将"torch_dtype"改为"float16"。800I A2机器上可以使用多卡进行量化生成w8a8s权重。300I DUO上仅支持单卡或cpu生成w8a8s权重。步骤二:w8a8sc 需要在300I DUO上切分。 ## 路径变量解释 | 变量名称 | 含义 | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | working_dir | 加速库及模型库下载后放置的目录 | | llm_path | 模型仓所在路径。若使用编译好的包,则路径为`${working_dir}/MindIE-LLM/`;若使用gitee下载的代码,则路径为`${working_dir}/MindIE-LLM/examples/atb_models` | | script_path | 脚本所在路径。QWen系列模型的工作脚本所在路径为`${llm_path}/examples/models/qwen` | | weight_path | 模型权重路径 | ## 权重格式转换 Paged Attention 场景需要.safetensors格式的权重,如果没有,参考[此README文件](../../README.md)转换 注:huggingface官网给出的QWen模型权重为.safetensors格式 ## 量化 量化权重可通过msmodelslim(昇腾压缩加速工具)实现。 ### 环境准备 环境配置可参考[此README文件](../../../README.md) - 设置环境变量 ```shell # 设置CANN包的环境变量 source /usr/local/Ascend/ascend-toolkit/set_env.sh ``` 需要安装 CANN(已包含msmodelslim工具) 以及 pytorch 和 pytorch-npu 以及相关的python库 ```shell pip install transformers # transformers版本应根据Qwen版本确定,配套关系见‘版本配套’ pip install accelerate==0.27.2 pip install scipy==1.11.4 pip install tiktoken==0.5.2 pip install einops==0.7.0 pip install transformers_stream_generator==0.0.4 ``` ### 导出量化权重 #### qwen2-7b、qwen2.5-7b、qwen2.5-14b、qwen2.5-32b W8A8量化 - W8A8量化权重请使用以下指令生成 - 当前支持NPU分布式W8A8量化 - 执行量化脚本 ```shell - 下载msmodelslim量化工具 - 下载地址为https://gitee.com/ascend/msit/tree/master/msmodelslim - 根据msmodelslim量化工具readme进行相关操作 注: 安装完cann后 需要执行source set_env.sh 声明ASCEND_HOME_PATH值 后续安装msmodelslim前需保证其不为空 # 执行"jq --version"查看是否安装jq,若返回"bash:jq:command not found",则依次执行"apt-get update"和"apt install jq" jq --version cd ${llm_path} # 指定当前机器上可用的逻辑NPU核心 通过修改convert_quant_weight.sh文件中export ASCEND_RT_VISIBLE_DEVICES值 指定使用卡号及数量 # 7b系列使用单卡 14b 32b使用4卡 eg: ASCEND_RT_VISIBLE_DEVICES=4,5,6,7 vi examples/models/qwen/convert_quant_weight.sh # 生成量化权重 bash examples/models/qwen/convert_quant_weight.sh -src {浮点权重路径} -dst {W8A8量化权重路径} -type qwen_w8a8 ``` #### qwen2-7b、qwen2.5-14b、qwen2.5-7b 稀疏量化 - Step 1 - 修改模型权重config.json中`torch_dtype`字段为`float16` - 下载msmodelslim量化工具 - 下载地址为https://gitee.com/ascend/msit/tree/master/msmodelslim - 根据msmodelslim量化工具readme进行相关操作 注: 安装完cann后 需要执行source set_env.sh 声明ASCEND_HOME_PATH值 后续安装msmodelslim前需保证其不为空 ```shell # 执行"jq --version"查看是否安装jq,若返回"bash:jq:command not found",则依次执行"apt-get update"和"apt install jq" jq --version # 设置CANN包的环境变量 source /usr/local/Ascend/ascend-toolkit/set_env.sh cd ${llm_path} # 指定当前机器上可用的逻辑NPU核心 通过修改convert_quant_weight.sh文件中export ASCEND_RT_VISIBLE_DEVICES值 指定使用卡号及数量 # 7b系列使用单卡 14b 32b使用4卡 eg: ASCEND_RT_VISIBLE_DEVICES=4,5,6,7 vi examples/models/qwen/convert_quant_weight.sh bash examples/models/qwen/convert_quant_weight.sh -src {浮点权重路径} -dst {W8A8量化权重路径} -type qwen_w4a8 ``` - Step 2:量化权重切分及压缩 ```shell export IGNORE_INFER_ERROR=1 torchrun --nproc_per_node {TP数} -m examples.convert.model_slim.sparse_compressor --model_path {W8A8S量化权重路径} --save_directory {W8A8SC量化权重路径} --multiprocess_num 4 ``` - TP数为tensor parallel并行个数 - 注意:若权重生成时以TP=4进行切分,则运行时也需以TP=4运行 - 示例 ```shell torchrun --nproc_per_node 2 -m examples.convert.model_slim.sparse_compressor --model_path /data1/weights/model_slim/Qwen-14b_w8a8s --save_directory /data1/weights/model_slim/Qwen-14b_w8a8sc ``` #### Qwen2-72B W8A16量化 - 假设当前位于`${llm_path}`目录下(安装的默认路径为`/usr/local/Ascend/llm_model`) - 目录`examples/models/qwen/`下的`quant_qwen2_w8a16_fast.py`为Qwen2-72B-W8A16模型已配置好的较优的量化策略。导出量化权重时可直接使用,也可修改为其它策略。 - 通过 `${llm_path}/examples/models/qwen/convert_quant_weight.sh` 脚本导出Qwen2-72B模型W8A16的量化权重(注意量化权重不要和浮点权重放在同一个目录下)。命令如下: ```shell cd ${llm_path} bash examples/models/qwen/convert_quant_weight.sh -src ${浮点权重路径} -dst ${量化权重保存路径} -type qwen_w8a16 ``` 例: ```shell bash examples/models/qwen/convert_quant_weight.sh -src /data1/models/Qwen2_72B -dst /data1/models/Qwen2_72B_W8A16 -type qwen_w8a16 ``` - 导出量化权重后生成`quant_model_weight_w8a16.safetensors`和`quant_model_description_w8a16.json`两个文件。模型浮点权重中的其他文件(除safetensors文件外)需要手工拷贝到目标量化文件夹中。 - 在量化权重保存路径中的config.json文件中添加"quantize"字段。对于W8A16量化,"quantize"字段的值为"w8a16"。 - 在量化权重保存路径中的config.json文件中添加"quantization"字段,其值为'{"group_size": 0}' - "group_size"为0时代表W8A16使用的是per channel量化 #### Qwen2-72B KV Cache量化 - 假设当前位于`${llm_path}`目录下(安装的默认路径为`/usr/local/Ascend/llm_model`) - 使用下列命令进行kv-int8量化权重导出: ```shell bash examples/models/qwen/convert_quant_weight.sh -src ${浮点权重路径} -dst ${量化权重保存路径} -type qwen2_72b_w8a8c8 -device_type npu -use_devices 0,1,2,3,4,5,6,7 ``` - 与Qwen2-72B W8A16量化不同,量化脚本已经替用户按要求修改好了config.json,用户无需再修改 #### Qwen2-72B W8A8量化 - 假设当前位于`${llm_path}`目录下(安装的默认路径为`/usr/local/Ascend/llm_model`) - 使用下列命令进行W8A8量化权重导出: - Step 1 - 下载msmodelslim量化工具 - 下载地址为https://gitee.com/ascend/msit/tree/master/msmodelslim - 根据msmodelslim量化工具readme进行相关操作 注: 安装完cann后 需要执行source set_env.sh 声明ASCEND_HOME_PATH值 后续安装msmodelslim前需保证其不为空 ```shell bash examples/models/qwen/convert_quant_weight.sh -src ${浮点权重路径} -dst ${量化权重保存路径} -type qwen2_72b_w8a8 -device_type npu -use_devices 0,1,2,3,4,5,6,7 ``` - 与qwen2-72B W8A16量化不同,量化脚本已经替用户按要求修改好了config.json,用户无需再修改 #### Qwen2-72B W8A8稀疏量化 - 假设当前位于`${llm_path}`目录下(安装的默认路径为`/usr/local/Ascend/llm_model`) - 使用下列命令进行W8A8稀疏量化权重导出: - Step 1 - 修改模型权重config.json中`torch_dtype`字段为`float16` - 下载msmodelslim量化工具 - 下载地址为https://gitee.com/ascend/msit/tree/master/msmodelslim - 根据msmodelslim量化工具readme进行相关操作 ```shell bash examples/models/qwen/convert_quant_weight.sh -src ${浮点权重路径} -dst ${W8A8SC量化权重路径} -type qwen2_72b_w8a8s -device_type npu -use_devices 0,1,2,3,4,5,6,7 ``` - Step 2:切分及压缩权重 ```shell export IGNORE_INFER_ERROR=1 torchrun --nproc_per_node {TP数} -m examples.convert.model_slim.sparse_compressor --model_path {W8A8S量化权重路径} --save_directory {W8A8SC量化权重路径} --multiprocess_num 4 ``` - TP数为tensor parallel并行个数 - 注意:若权重生成时以TP=4进行切分,则运行时也需以TP=4运行 - multiprocess_num必须设置为4以减小机器压力 - 示例 ```shell torchrun --nproc_per_node 2 -m examples.convert.model_slim.sparse_compressor --model_path /data1/weights/model_slim/Qwen-14b_w8a8s --save_directory /data1/weights/model_slim/Qwen-14b_w8a8sc --multiprocess_num 4 ``` - 与qwen2-72B W8A16量化不同,量化脚本已经替用户按要求修改了config.json,用户只需要将config.json中的quant_type字段修改为"w8a8s"即可。 #### Qwen2.5-72B FA3量化 - 下载msmodelslim量化工具 - 下载地址为https://gitee.com/ascend/msit/tree/master/msmodelslim - 根据msmodelslim量化工具readme进行相关操作 - 阅读链接中的readme文件生成权重,或者直接问msModelSlim团队索要: https://gitee.com/ascend/msit/blob/master/msmodelslim/docs/FA%E9%87%8F%E5%8C%96%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md - ModelSlim团队会提供`quant_model_description_w8a8.json`和`quant_model_weight_w8a8.safetensors`两个文件。 - 通过 `${llm_path}/examples/models/qwen/convert_quant_weight.sh` 脚本导出Qwen2.5-72B模型FA3的量化权重(注意量化权重不要和浮点权重放在同一个目录下)。命令如下: ```shell bash examples/models/qwen/convert_quant_weight.sh -src ${浮点权重路径} -dst ${fa3量化权重路径} -type qwen2p5_fa3 -msmodelslim_path ${msmodelslim工具路径} ``` - ${msmodelslim工具路径}为下载目录/msit/msmodelslim,例如在/home目录下面下载的msmodelslim工具,则实际路径为:/home/msit/msmodelslim - 示例 ```shell bash examples/models/qwen/convert_quant_weight.sh -src /opt/models/Qwen2.5-72B-Instruct/ -dst /opt/models/Qwen2.5-72B-fa3 -type qwen2p5_fa3 -msmodelslim_path /home/msit/msmodelslim ``` - 新版本的msmodelslim工具如果需要添加`anti_calib_file`参数,可以在上述命令中加入`-fa3_use_anti_calib True` - 示例 ```shell bash examples/models/qwen/convert_quant_weight.sh -src /opt/models/Qwen2.5-72B-Instruct/ -dst /opt/models/Qwen2.5-72B-fa3 -type qwen2p5_fa3 -msmodelslim_path /home/msit/msmodelslim -fa3_use_anti_calib True ``` - 模型浮点权重中的其他文件(除safetensors文件外)需要手工拷贝到目标量化文件夹中。 - 拷贝好之后,用户需在`config.json`文件中手动添加以下两个字段: ```json "quantize": "w8a8", "quantization_config": {"fa_quant_type": "FAQuant"} ``` #### Qwen2.5-72B W4A16量化 - W8A8量化权重请使用以下指令生成 - 当前支持NPU分布式W8A8量化 - 执行量化脚本 ```shell - 下载msmodelslim量化工具 - 下载地址为https://gitee.com/ascend/msit/tree/master/msmodelslim - 根据msmodelslim量化工具readme进行相关操作 注: 安装完cann后 需要执行source set_env.sh 声明ASCEND_HOME_PATH值 后续安装msmodelslim前需保证其不为空 # 执行"jq --version"查看是否安装jq,若返回"bash:jq:command not found",则依次执行"apt-get update"和"apt install jq" jq --version cd ${llm_path} # 指定当前机器上可用的逻辑NPU核心 通过修改convert_quant_weight.sh文件中export ASCEND_RT_VISIBLE_DEVICES值 指定使用卡号及数量 # 72B使用8卡 eg: ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 vi examples/models/qwen/convert_quant_weight.sh # 生成量化权重 bash examples/models/qwen/convert_quant_weight.sh -src {浮点权重路径} -dst {W8A8量化权重路径} -type qwen_w4a16 ``` #### Qwen2.5-Coder-7B 稀疏量化 - Step 1 - 修改模型权重config.json中`torch_dtype`字段为`float16` - 下载msmodelslim量化工具 - 下载地址为https://gitee.com/ascend/msit/tree/master/msmodelslim - 根据msmodelslim量化工具readme进行相关操作 ```shell # 执行"jq --version"查看是否安装jq,若返回"bash:jq:command not found",则依次执行"apt-get update"和"apt install jq" jq --version # 设置CANN包的环境变量 source /usr/local/Ascend/ascend-toolkit/set_env.sh cd ${llm_path} # Qwen2.5-Coder-7B加载到cpu上生成量化权重 注释掉convert_quant_weight.sh里export ASCEND_RT_VISIBLE_DEVICES这一行 vi examples/models/qwen/convert_quant_weight.sh bash examples/models/qwen/convert_quant_weight.sh -src {浮点权重路径} -dst {W8A8量化权重路径} -type qwencode_w8a8s -device_type cpu ``` 稀疏量化后的"quantize"类型为w8a8s - Step 2:量化权重切分及压缩 ```shell export IGNORE_INFER_ERROR=1 torchrun --nproc_per_node {TP数} -m examples.convert.model_slim.sparse_compressor --model_path {W8A8S量化权重路径} --save_directory {W8A8SC量化权重路径} ``` - TP数为tensor parallel并行个数 - 注意:若权重生成时以TP=4进行切分,则运行时也需以TP=4运行 - 示例 ```shell torchrun --nproc_per_node 4 -m examples.convert.model_slim.sparse_compressor --model_path /data/Qwen2.5-Coder-7B-w8a8s --save_directory /data/Qwen2.5-Coder-7B-w8a8sc ``` #### Qwen2.5-14B Qwen2.5-72B pdmix W8A8C8量化 - 通过 `${llm_path}/examples/models/qwen/convert_quant_weight.sh` 脚本导出Qwen2.5-14B和Qwen2.5-72B模型pdmix W8A8C8的量化权重(注意量化权重不要和浮点权重放在同一个目录下)。命令如下: - 假设当前位于`${llm_path}`目录下(安装的默认路径为`/usr/local/Ascend/atb-models`),`trust_remote_code`为可选参数代表是否信任本地的可执行文件,传入该参数代表信任本地可执行文件 ```shell bash examples/models/qwen/convert_quant_weight.sh -src ${浮点权重路径} -dst ${量化权重保存路径} -type ${type} -device_type npu -use_devices 0,1,2,3,4,5,6,7 -msmodelslim_path ${msmodelslim工具路径} -trust_remote_code ``` - ${msmodelslim工具路径}为下载目录/msit/msmodelslim,例如在/home目录下面下载的msmodelslim工具,则实际路径为:/home/msit/msmodelslim Qwen2.5-72B示例: ```shell bash examples/models/qwen/convert_quant_weight.sh -src /data/Qwen2.5-72B-Instruct/ -dst /data/qwen2.5-72B-pdmix-w8a8c8/ -type qwen2p5_72b_w8a8c8_pdmix -device_type npu -use_devices 0,1,2,3,4,5,6,7 -msmodelslim_path /home/msit/msmodelslim -trust_remote_code ``` Qwen2.5-14B示例: ```shell bash examples/models/qwen/convert_quant_weight.sh -src /data/Qwen2.5-14B-Instruct/ -dst /data/qwen2.5-14B-pdmix-w8a8c8/ -type qwen2p5_14b_w8a8c8_pdmix -device_type npu -use_devices 0,1,2,3,4,5,6,7 -msmodelslim_path /home/msit/msmodelslim -trust_remote_code ``` ## 推理 ### 对话测试 量化权重生成路径下可能缺少一些必要文件(与转换量化权重时使用的cann版本有关),若启动量化推理失败,请将config.json等相关文件复制到量化权重路径中,可执行以下指令进行复制: ```shell cp ${浮点权重路径}/*.py ${量化权重路径} cp ${浮点权重路径}/*.json ${量化权重路径} cp ${浮点权重路径}/*.tiktoken ${量化权重路径} ``` 启动量化推理时,请在权重路径的config.json文件中添加(或修改)`torch_dtype`字段,例如`"torch_dtype": "float16"`。 启动量化推理时,请在权重路径的config.json文件中添加(或修改)`quantize`字段,值为相应量化方式,例如`"quantize": "w8a8"`、`"quantize": "w8a16"` 在`${llm_path}`目录执行以下指令 ```shell bash examples/models/qwen/run_pa.sh -m ${weight_path} --trust_remote_code true ``` 注: 1.推理支持浮点和量化,若启动浮点推理则在`${weight_path}`中传入浮点权重路径,若启动量化则传入量化权重路径 2.--trust_remote_code为可选参数代表是否信任本地的可执行文件,默认false。传入true,则代表信任本地可执行文件,-r为其缩写 3.同时支持Qwen和Qwen1.5模型推理,若启动Qwen模型推理时在`${weight_path}`中传入Qwen权重路径,若启动Qwen1.5模型推理时则在`${weight_path}`中传入Qwen1.5权重路径 4.Qwen系列chat模型需要开启chat模式才能正常输出。 执行: ```shell bash examples/models/qwen/run_pa.sh -m ${weight_path} --trust_remote_code true -c true ``` 5.对于embedding类模型,例如gte-Qwen2-7B-Instruct时,运行命令如下: ```shell bash examples/models/qwen/run_pa.sh -m ${weight_path} -e true ``` 6.启动qwen需要安装三方依赖tiktoken,若环境中没有该依赖可使用以下命令安装: ```shell pip install tiktoken ``` **运行Multi-Lora** - 下载Lora权重:Lora权重中需包含至少一个safetensors格式的文件,和一个名为`adapter_config.json`的配置文件 - 在基础模型的权重文件夹中,新增`lora_adapter.json`文件,内容为需要预加载的Lora权重,例如: ```json { "qwen_lora1": "/home/data/lora/Qwen1.5-14b-chat/adapter1", "qwen_lora2": "/home/data/lora/Qwen1.5-14b-chat/adapter2" } ``` - 进行推理时需指定每个请求所使用的adapter权重,默认仅使用基础模型权重 - 运行示例 ```shell export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 torchrun --nproc_per_node 8 --master_port 20030 -m examples.run_pa --model_path /data1/models/qwen2/Qwen1.5-14b-chat --is_chat_model --max_output_length 256 --max_batch_size 2 --input_dict '[{"prompt": "What is deep learning?", "adapter": "qwen_lora1"}, {"prompt": "What is deep learning?"}]' ``` - 约束与限制 - 仅支持在Atlas 800I A2上运行 - Lora权重不支持热加载,如果未获取到`adapter_id`,将会默认使用`base` - 仅支持浮点模型 - `lora_adapter.json`文件中的键就是`input_dict`参数的键`adapter`的值,也叫`adapter_id`。 - `adapter_id`唯一 且 不能与字符串`base`重名 - 在显存充足的情况下至多加载10个Lora权重 - **用于精度测试的`lora_data.jsonl`文件包含的`adapter_id`数量必须比数据集的数量多,否则多余的数据会默认使用base** ### run_pa.sh 参数说明(需要到脚本中修改) 根据硬件设备不同请参考下表修改run_pa.sh再运行 | 参数名称 | 含义 | 800I A2推荐值 | 300I DUO推荐值 | | ------------------------- | ----------------------------------------- | ---------------- | ---------------- | | BIND_CPU | 绑定CPU核心开关,默认进行绑核 | 1 | 1 | | ASCEND_RT_VISIBLE_DEVICES | 使用的硬件卡号,多个卡间使用逗号相连 | 根据实际情况设置 | 根据实际情况设置 | | RESERVED_MEMORY_GB | 保留内存,通常未加速库需要的内存+通信内存 | 3 | 3 | | MASTER_PORT | 卡间通信端口,通常不用修改,有冲突时再改 | | | 注:暂不支持奇数卡并行 ## 精度测试 - 参考[此README文件](../../../tests/modeltest/README.md) 示例: ```shell bash run.sh pa_fp16 full_BoolQ 1 qwen /data1/models/qwen2/qwen_quant_test/ 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen-7b权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen-14b权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen-72b权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen1.5-14b权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen-14b-chat权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen-72b-chat权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen1.5-0.5b-chat权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen1.5-4b-chat权重路径} 4 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen1.5-7b权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen1.5-14b-chat权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen1.5-32b-chat权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen1.5-72b权重路径} 8 bash run.sh pa_fp16 full_BoolQ 1 qwen ${Qwen1.5-MoE-A2.7B-Chat权重路径} 8 bash run.sh pa_fp16 full_HumanEval_X 1 qwen ${Qwen2.5-Coder-7B权重路径} 8 ``` - gte_qwen测试 - 依赖安装 C_MTEB、optimum、tqdm、datasets、faiss-cpu C_MTEB 需要安装依赖 pytrec-eval,安装该依赖时需要请求 https://github.com/usnistgov/trec_eval/archive/v9.0.8.tar.gz 时发生SSL证书错误 解决方案 手动下载 pytrec_eval并上传至服务器或在服务器上执行 ```shell wget https://files.pythonhosted.org/packages/2e/03/e6e84df6a7c1265579ab26bbe30ff7f8c22745aa77e0799bba471c0a3a19/pytrec_eval-0.5.tar.gz tar -xzvf pytrec_eval-0.5.tar.gz cd pytrec_eval-0.5 ``` 修改 pytrec_eval-0.5/setup.py,在开头处增加 ```shell import ssl ssl._create_default_https_context = ssl._create_unverified_context ``` 安装 ```shell tar -zcvf pytrec_eval-0.5.tar.gz pytrec_eval-0.5 pip install pytrec_eval-0.5.tar.gz ``` 同理安装依赖 pytrec-eval ```shell wget http://mirrors.aliyun.com/pypi/packages/dc/61/9003ffdb64f74a91208d69235dbcd380ae1a8d267089348eb8f7aab9819a/pytrec_eval_terrier-0.5.7.tar.gz tar -xzvf pytrec_eval_terrier-0.5.7.tar.gz cd pytrec_eval_terrier-0.5.7 ``` 修改 pytrec_eval_terrier-0.5.7/setup.py,在开头处增加 ```shell import ssl ssl._create_default_https_context = ssl._create_unverified_context tar -zcvf pytrec_eval_terrier-0.5.7.tar.gz pytrec_eval_terrier-0.5.7 pip install pytrec_eval_terrier-0.5.7.tar.gz ``` 安装 ```shell tar -zcvf pytrec_eval_terrier-0.5.7.tar.gz pytrec_eval_terrier-0.5.7 pip install pytrec_eval_terrier-0.5.7.tar.gz ``` - 获取测试数据集 ```shell mkdir dataset ``` 下载数据集文件 [corpus、queries](https://huggingface.co/datasets/C-MTEB/T2Retrieval/tree/main/data) 及 [dev](https://huggingface.co/datasets/C-MTEB/T2Retrieval-qrels/tree/main/data) 至 `dataset` 目录中 - 修改embedding输出存储位置 ```shell vim ../../../atb_llm/models/qwen2/flash_causal_qwen2_gte.py ``` 将其中233行修改为 logits_name = f"embedding_tensor_0" - 运行指令 ```shell python eval_t2retrieval_gte_npu/gpu.py --model_type_or_path model_type_or_path --batch_size batch_size --device device ``` 结果保存在当前路径results/ ## 性能测试 - 进入以下路径 ```shell ${llm_path}/tests/modeltest ``` - 运行指令 ```shell bash run.sh pa_fp16 [performance|full_CEval|full_BoolQ] ([case_pair]) [batch_size] qwen [weight_dir] [chip_num] ([max_position_embedding/max_sequence_length]) ``` - 环境变量释义 1. HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 这两个会影响性能,开启了变慢,但是会变成确定性计算,不开会变快,所以设置为0。 2. HCCL_BUFFSIZE=120 这个会影响hccl显存,需要设置,基本不影响性能。 3. ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 这个是显存优化,需要开,小batch、短序列场景不开更好。 示例: ```shell HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen-7b权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen-14b权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen-72b权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen1.5-14b权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen-14b-chat权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen-72b-chat权重路径} 8 HCCL_DETERMINISTIC=0 LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen1.5-0.5b-chat权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen1.5-4b-chat权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen1.5-7b权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen1.5-14b-chat权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen1.5-32b-chat权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen1.5-72b权重路径} 8 HCCL_DETERMINISTIC=false LCCL_DETERMINISTIC=0 HCCL_BUFFSIZE=120 ATB_WORKSPACE_MEM_ALLOC_GLOBAL=1 bash run.sh pa_fp16 performance [[2048,2048],[1024,1024],[512,512],[256,256]] 1 qwen ${Qwen1.5-MoE-A2.7B-Chat权重路径} 8 ``` - 参考[此README文件](../../../tests/modeltest/README.md) ## prefix_cache - 参考[此README文件](../../../../../mindie_llm/text_generator/plugins/prefix_cache) 目前此特性仅支持qwen2-72b fp16使用 # Flash Attention推理使用说明 路径变量和权重转换等均与Paged Attention相同。 ## 推理 ### 对话测试 在`${llm_path}`目录执行以下指令 ```shell bash examples/models/qwen/run_fa.sh -m ${weight_path} ``` # 使用虚拟机运行Qwen(包含Qwen系列,Qwen1.5系列,Qwen2系列,Qwen2.5系列)模型 如果在虚拟机内运行Qwen模型,且虚拟机所在的物理机支持HCCS通信,需引入下列环境变量: ```shell export NPU_VM_SUPPORT_HCCS = 1 ``` # Qwen长序列推理 qwen长序列推理需要在qwen权重(config.json)中将use_dynamic_ntk参数与use_logn_attn同时设置成True。如Qwen-14B-Chat: 注意:如果不使用长序列推理,请将use_dynamic_ntk与use_logn_attn参数同时设置成False。 ```json { "architectures": [ "QwenLMHeadModel" ], // ... "use_dynamic_ntk": true, // ... "use_logn_attn": true, // ... } ``` qwen2长序列推理需要在qwen2权重(config.json)中新增rope_scaling参数。如Qwen2-72B-Instruct: 注意:如果不使用长序列推理,请不要添加。 ```json { "architectures": [ "Qwen2ForCausalLM" ], // ... "vocab_size": 152064, // adding the following snippets "rope_scaling": { "factor": 4.0, "original_max_position_embeddings": 32768, "type": "yarn" } } 注: - 除启动命令外,其他操作与执行PA相同 - qwen qwen1.5暂不支持bf16格式,请将权重路径下config.json文件的`torch_dtype`字段修改为`float16` - 暂不支持chat模式。部分chat模型输出可能存在异常,如qwen1.5-32b-chat,若出现上述情况,请优先使用PA - 长序列推理过程具有更多计算节点,因此相比于短序列,推理性能将有下降。 - qwen1.5部分Chat模型(4B、32B)fa暂不支持chat推理,请优先使用pa。如需使用fa请将输入改造成续写的样式,如:`What's deep learning?`改写成`Deep learning is` - Qwen2 Qwen2.5系列模型当前800I A2采用bf16, 300I DUO使用fp16 ================================================ FILE: llm-localization/ascend/mindie/README.md ================================================ # 入口 - https://www.hiascend.com/document/detail/zh/mindie/20RC2/index/index.html # 模型支持列表 - https://www.hiascend.com/software/mindie/modellist - https://www.hiascend.com/document/detail/zh/mindie/10RC1/description/whatismindie/mindie_what_0000.html ``` docker run -it -u root --name=mindie_server_t35 --net=host --ipc=host \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \ -v /usr/local/sbin/:/usr/local/sbin/ \ -v /var/log/npu/slog/:/var/log/npu/slog \ -v /var/log/npu/profiling/:/var/log/npu/profiling \ -v /var/log/npu/dump/:/var/log/npu/dump \ -v /var/log/npu/:/usr/slog \ -v /etc/hccn.conf:/etc/hccn.conf \ -v /home:/workspace \ mindie_server:1.0.T35 \ /bin/bash docker exec -it mindie_server_t35 bash /home/HwHiAiUser/mindie-service_1.0.RC1_linux-aarch64/bin cp -r /workspace/token_input_gsm.csv . vim conf/config.json cd /workspace/aicc/model_from_hf/chatglm3-6b-chat /workspace/aicc/model_from_hf/Baichuan2-7B-Chat --- /home/HwHiAiUser/atb-models/examples/convert convert_weights.py 使用${llm_path}/examples/convert/convert_weights.py将bin转成safetensor格式 示例 python ${llm_path}/examples/convert/convert_weights.py --model_path ${weight_path} 输出结果会保存在bin权重同目录下 /home/HwHiAiUser source set_env.sh python examples/convert/convert_weights.py --model_path /workspace/aicc/model_from_hf/Baichuan2-7B-Chat --from_pretrained False python examples/convert/convert_weights.py --model_path /workspace/aicc/model_from_hf/Baichuan2-7B-Chat --- 启动脚本 Flash Attention的启动脚本路径为${llm_path}/examples/run_fa.py Page Attention的启动脚本路径为${llm_path}/examples/run_pa.py ``` ## 镜像 - https://ascendhub.huawei.com/#/detail/mindie ``` # 获取登录访问权限,输入已设置的“镜像下载凭证”,如果未设置或凭证超过24小时过期,请点击登录用户名下拉设置镜像下载凭证 docker login -u 157xxxx4031 ascendhub.huawei.com # 下载镜像 docker pull ascendhub.huawei.com/public-ascendhub/mindie:1.0.RC1-800I-A2-aarch64 ``` ## 迁移 ``` docker save -o mindie-1.0.tar ascendhub.huawei.com/public-ascendhub/mindie:1.0.RC1-800I-A2-aarch64 scp root@192.xxx.16.211:/root/mindie-1.0.tar . # 断点续传 rsync -P --rsh=ssh -r root@192.xxx.16.211:/root/mindie-1.0.tar . ``` ## 性能测试 ``` nohup python performance-stream-baichuan2.py > baichuan2.log 2>&1 & ``` ================================================ FILE: llm-localization/ascend/mindie/config/chatglm3-6b.json ================================================ { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 4 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "0.0.0.0", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[0,1]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "chatglm3-6b", "modelWeightPath" : "/home/aicc/model_from_hf/chatglm3-6b-chat-full", "worldSize" : 2, "cpuMemSize" : 5, "npuMemSize" : 16, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 200, "supportSelectBatch" : false, "maxQueueDelayMicroseconds" : 5000 } } ================================================ FILE: llm-localization/ascend/mindie/config/qwen-72b.json ================================================ { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 4 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "127.0.0.1", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[0,1,2,3,4,5,6,7]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "qwen-72b", "modelWeightPath" : "/home/aicc/model_from_hf/qwen-72b-chat-hf", "worldSize" : 8, "cpuMemSize" : 5, "npuMemSize" : 10, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 200, "supportSelectBatch" : false, "maxQueueDelayMicroseconds" : 5000 } } ================================================ FILE: llm-localization/ascend/mindie/config/run.sh ================================================ #!/bin/bash # Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # shellcheck disable=SC2148 SCRIPT_DIR=$(cd $(dirname $0); pwd) TESTS_DIR=$(cd $SCRIPT_DIR/core/; pwd) test_mode="performance" model_type="pa" model_name="" weight_dir="" data_type="fp16" hardware_type="NPU" chip_num=0 dataset="CEval" batch_size=0 case_pair="[]" use_refactor="True" max_position_embedding=-1 function fn_prepare() { if [ "$hardware_type" == "NPU" ]; then if [ -z "$ASCEND_HOME_PATH" ];then echo "env ASCEND_HOME_PATH not exists, fail" exit 0 fi if [ -z "$ATB_HOME_PATH" ];then echo "env ATB_HOME_PATH not exists, fail" exit 0 fi fi export INT8_FORMAT_NZ_ENABLE=1 export PYTHONPATH="${PYTHONPATH}:$(dirname "$(readlink -f "$0")")" export PYTHONPATH="${PYTHONPATH}:$(dirname "$(dirname "$(dirname "$(readlink -f "$0")")")")" IFS="_" read -ra parts <<< "$1" model_type="${parts[0]}" if [ "$model_type" == "pa" ]; then data_type="${parts[1]}" fi test_mode="$2" if ! [ "$test_mode" == "performance" ]; then read -ra parts <<< "$2" test_mode="${parts[0]}" dataset="${parts[1]}" fi if [ "$test_mode" == "performance" ]; then export ATB_LLM_BENCHMARK_ENABLE=1 export ATB_LLM_BENCHMARK_FILEPATH="${SCRIPT_DIR}/benchmark.csv" fi } function fn_run_single() { test_file="${model_name}_test.py" test_path="${TESTS_DIR}/${test_file}" if [[ ! -e "$test_path" ]];then echo "model test file $test_path is not found." exit 0 fi if [ "$chip_num" == 0 ]; then code_line=$(grep -A 1 "def get_chip_num(self):" "${test_path}" | tail -n 1) if [ -z "$code_line" ]; then echo "Warning: get_chip_num() not overwrite in '$test_file', use chip_num 1" chip_num=1 else chip_num=$(echo "$code_line" | awk -F 'return ' '{print $2}') if ! [[ "$chip_num" =~ ^[1-9]+$ ]]; then echo "Error: return value of get_chip_num() in '$test_file' is not a digit." exit 1 fi fi fi if [ "$hardware_type" == "NPU" ]; then if ! [ -n "$ASCEND_RT_VISIBLE_DEVICES" ]; then devices="" for ((i=0; i /dev/null; then hardware_type="GPU" echo "INFO: Detected NVIDIA GPU" else if command -v npu-smi info &> /dev/null; then echo "INFO: Detected Ascend NPU" else echo "Error: No GPU or NPU detected" exit 1 fi fi if [ $# -eq 0 ]; then echo "Error: require parameter. Please refer to README." exit 1 fi model_type=$1 case "$model_type" in fa|pa_fp16|pa_bf16) echo "INFO: current model_type: $model_type" ;; *) echo "ERROR: invalid model_type, only support fa, pa_fp16, pa_bf16" ;; esac test_modes=$2 case "$test_modes" in performance|simplified_GSM8K|simplified_TruthfulQA|full_CEval|full_GSM8K|full_MMLU|full_TruthfulQA|full_BoolQ|full_HumanEval) echo "INFO: current test_mode: $test_modes" ;; *) echo "ERROR: invalid test_mode, only support performance, simplified_GSM8K, simplified_TruthfulQA, \ full_CEval, full_GSM8K, full_MMLU, full_TruthfulQA, full_BoolQ, full_HumanEval" exit 1 ;; esac if [ "$test_modes" == "performance" ]; then case_pair=$3 shift fi batch_size=$3 model_name=$4 if [ "$model_name" == "llama" ]; then use_refactor=$5 shift fi weight_dir=$5 echo "INFO: current batch_size: $batch_size" echo "INFO: current model_name: $model_name" echo "INFO: current weight_dir: $weight_dir" fn_prepare "$model_type" "$test_modes" if ! [[ "$6" =~ ^[1-9]+$ ]]; then echo "Error: input chip_num is not a digit." exit 1 fi chip_num=$6 echo "INFO: use input chip_num $chip_num" if [ $# -ge 7 ]; then if ! [[ "$7" =~ ^[0-9]+$ ]]; then echo "Error: input max_position_embedding or max_seq_len is not a digit." exit 1 fi max_position_embedding=$7 echo "INFO: use input max_position_embedding or max_seq_len $max_position_embedding" fi fn_run_single } fn_main "$@" ================================================ FILE: llm-localization/ascend/mindie/config-1.0.RC1.json ================================================ { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 8 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "0.0.0.0", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[$npuids]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "$model_name", "modelWeightPath" : "$model_weight_path", "worldSize" : $world_size, "cpuMemSize" : 5, "npuMemSize" : $npu_mem_size, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 192, "maxPrefillTokens" : 12000, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 256, "maxIterTimes" : 1024, "maxPreemptCount" : 200, "supportSelectBatch" : true, "maxQueueDelayMicroseconds" : 5000 } } ================================================ FILE: llm-localization/ascend/mindie/docker/README.md ================================================ ## 进入容器内 ``` ascendhub.huawei.com/public-ascendhub/mindie:1.0.RC1-800I-A2-aarch64 # commit docker commit -a "guodong" -m "mindie-service" b7fe01c81fcc ascendhub.huawei.com/public-ascendhub/mindie-service-env:1.0.RC1-800I-A2-aarch64 docker run -it --rm --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ --entrypoint=bash \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ ascendhub.huawei.com/public-ascendhub/mindie-service-env:1.0.RC1-800I-A2-aarch64 docker commit -a "guodong" -m "mindie-service" 45bafed49c5b ascendhub.huawei.com/public-ascendhub/mindie-service-env:v2 docker save -o mindie-service-env.tar ascendhub.huawei.com/public-ascendhub/mindie-service-env:v2 ``` ## 启动服务 ``` docker run -it --rm --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/qwen1.5-14b.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 pkill -9 mindieservice_d docker save -o mindie.tar ascendhub.huawei.com/public-ascendhub/mindie:1.0.RC1-800I-A2-aarch64 docker save -o mindie-service-online.tar ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.0 docker save -o mindie-service-online-v1.1.tar ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 docker run -it --rm --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/qwen-72b.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ### qwen1.5 ``` docker run -it --rm --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/qwen1.5-14b.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 docker run -it --rm --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/qwen1.5-14b-2tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 docker run -it --rm --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/qwen1.5-72b.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ``` docker run -it --rm --net=host --ipc=host \ -e ASCEND_VISIBLE_DEVICES=0,1,2,3 \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/qwen1.5-7b-4tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ``` ASCEND_RT_VISIBLE_DEVICES:设置Device ID,指定应用进程可用的Device。支持一次指定一个或多个Device ID。 docker run -it --rm --net=host --ipc=host \ -e ASCEND_RT_VISIBLE_DEVICES=1 \ --shm-size=50g \ --privileged=true \ -w /home \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /home:/home \ -v /tmp:/tmp \ -v /home/aicc/docker/qwen1.5-7b-1tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 docker run -it --rm --net=host --ipc=host \ -e ASCEND_RT_VISIBLE_DEVICES=6,7 \ --shm-size=50g \ --privileged=true \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -w /home \ -v /home:/home \ -v /tmp:/tmp \ -v /home/aicc/docker/qwen1.5-7b-2tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ``` nohup python performance.py > qwen1.5-7b-2tp.log 2>&1 & nohup python performance.py > qwen1.5-7b-4tp.log 2>&1 & nohup python performance.py > qwen1.5-7b-1tp.log 2>&1 & nohup python performance-qwen1.5.py > qwen1.5-7b-1tp.log 2>&1 & ``` ### qwen1 ``` docker run -it --rm --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/qwen-72b.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ### baichuan2 ``` docker run -it --rm \ --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/baichuan2-7b.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ``` docker run -it --rm \ --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/baichuan2-7b-4tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ``` docker run -it --rm \ --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/baichuan2-7b-1tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ### baichuan2-13b ``` source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/llm_model/set_env.sh export PYTHONPATH=/usr/local/Ascend/llm_model:$PYTHONPATH cd /usr/local/Ascend/mindie/latest/mindie-service/bin python convert_weights.py --model_path /home/aicc/model_from_hf/Baichuan2-13B-Chat ``` 将congfig.json中的bfloat16改为float16。 ``` docker run -it --rm \ -e ASCEND_VISIBLE_DEVICES=0,1,2,3 \ --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/baichuan2-13b.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ``` docker run -it --rm \ -e ASCEND_VISIBLE_DEVICES=0,1,2,3 \ --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/baichuan2-13b-8tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 kvcache:18 ``` ``` docker run -it --rm \ -e ASCEND_VISIBLE_DEVICES=0,1 \ --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/baichuan2-13b-2tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 nohup python performance-stream-baichuan2.py > baichuan2-2tp.log 2>&1 & ``` ### chatglm3 ``` docker run -it --rm \ --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/baichuan2-13b-2tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ``` docker run -it --rm \ --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/chatglm3-6b-4tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ``` docker run -it --rm \ --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -v /home/aicc/docker/chatglm3-6b-1tp.json:/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json \ ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 ``` ================================================ FILE: llm-localization/ascend/mindie/docker/TEST.md ================================================ ``` # dockerfile docker build --network=host -f mindie-env-1.0.Dockerfile -t ascendhub.huawei.com/public-ascendhub/mindie-env:1.0.RC1-800I-A2-aarch64 . docker run -it --rm --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ --entrypoint=bash \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ ascendhub.huawei.com/public-ascendhub/mindie-env:1.0.RC1-800I-A2-aarch64 docker build --network=host -f mindie-all-1.0.Dockerfile -t ascendhub.huawei.com/public-ascendhub/mindie-all:1.0.RC1-800I-A2-aarch64 . docker run -it --rm --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ --entrypoint=bash \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ ascendhub.huawei.com/public-ascendhub/mindie-all:1.0.RC1-800I-A2-aarch64 ``` ================================================ FILE: llm-localization/ascend/mindie/docker/baichuan2-13b.json ================================================ { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 4 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "0.0.0.0", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[0,1,2,3]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "baichuan2-13b", "modelWeightPath" : "/home/aicc/model_from_hf/Baichuan2-13B-Chat", "worldSize" : 4, "cpuMemSize" : 5, "npuMemSize" : 16, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 200, "supportSelectBatch" : false, "maxQueueDelayMicroseconds" : 5000 } } ================================================ FILE: llm-localization/ascend/mindie/docker/baichuan2-7b.json ================================================ { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 4 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "127.0.0.1", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[0,1,2,3]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "baichuan2-7b", "modelWeightPath" : "/home/aicc/model_from_hf/Baichuan2-7B-Chat", "worldSize" : 4, "cpuMemSize" : 5, "npuMemSize" : 16, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 200, "supportSelectBatch" : false, "maxQueueDelayMicroseconds" : 5000 } } ================================================ FILE: llm-localization/ascend/mindie/docker/deploy.sh ================================================ #!/bin/bash echo "入参:" $@ for a in "$@"; do #echo $a if [[ `echo $a | grep "^--model_name="` ]]; then model_name=`echo $a | grep "^--model_name=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--model_weight_path="` ]]; then model_weight_path=`echo $a | grep "^--model_weight_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--world_size="` ]]; then world_size=`echo $a | grep "^--world_size=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--npu_mem_size="` ]]; then npu_mem_size=`echo $a | grep "^--npu_mem_size=" | awk -F '=' '{print $2}'` fi done if [ -z "$model_name" ]; then model_name="default" fi if [ -z "$model_weight_path" ]; then model_weight_path="/workspace/models" fi if [ -z "$world_size" ]; then world_size=4 fi if [ -z "$npu_mem_size" ]; then npu_mem_size=8 fi echo "平台入参: model_name: $model_name, model_weight_path: $model_weight_path , world_size: $world_size , npu_mem_size: $npu_mem_size" npuids="" card_num=$(($world_size - 1)) for i in `seq 0 $card_num` do if [[ $i == $card_num ]] ; then npuids=$npuids$i else npuids=$npuids$i"," fi done echo $npuids DEPLOYMENT_CONF_PATH="/home/guodong.li/workspace/config.json" # DEPLOYMENT_CONF_PATH="/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json" cat < $DEPLOYMENT_CONF_PATH { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 4 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "0.0.0.0", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[$npuids]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "$model_name", "modelWeightPath" : "$model_weight_path", "worldSize" : $world_size, "cpuMemSize" : 5, "npuMemSize" : $npu_mem_size, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 200, "supportSelectBatch" : false, "maxQueueDelayMicroseconds" : 5000 } } EOF echo "部署参数,$DEPLOYMENT_CONF_PATH" cat $DEPLOYMENT_CONF_PATH # source /usr/local/Ascend/ascend-toolkit/set_env.sh # source /usr/local/Ascend/mindie/set_env.sh # source /usr/local/Ascend/llm_model/set_env.sh # export PYTHONPATH=/usr/local/Ascend/llm_model:$PYTHONPATH # cd /usr/local/Ascend/mindie/latest/mindie-service/bin # ./mindieservice_daemon ================================================ FILE: llm-localization/ascend/mindie/docker/install_and_enable_cann.sh ================================================ #!/bin/bash # Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Install Torch, Torch_npu, Apex pip3 install torch-2.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl PYTORCH_MANYLINUX=pytorch_v2.1.0-6.0.rc1_py310.tar.gz TORCH_NPU_IN_PYTORCH_MANYLINUX=torch_npu-2.1.0.post3_20240413-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl APEX_IN_PYTORCH_MANYLINUX=apex-0.1_ascend_20240413-cp310-cp310-linux_aarch64.whl mkdir torch cp ${PYTORCH_MANYLINUX} torch \ && cd torch \ && tar -xzvf ${PYTORCH_MANYLINUX} \ && cd .. echo "start install pytorch, wait for a minute..." pip3 install torch/${TORCH_NPU_IN_PYTORCH_MANYLINUX} --quiet 2> /dev/null if [ $? -eq 0 ]; then echo "pip3 install torchnpu successfully" else echo "pip3 install torchnpu failed" fi pip3 install torch/${APEX_IN_PYTORCH_MANYLINUX} --quiet 2> /dev/null if [ $? -eq 0 ]; then echo "pip3 install apex successfully" else echo "pip3 install apex failed" fi rm -rf torch # Install Ascend Cann Library CANN_TOOKIT="Ascend-cann-toolkit_8.0.RC1_linux-aarch64.run" CANN_KERNELS="Ascend-cann-kernels-910b_8.0.RC1_linux.run" chmod +x *.run yes | ./${CANN_TOOKIT} --install --quiet toolkit_status=$? if [ ${toolkit_status} -eq 0 ]; then echo "install toolkit successfully" else echo "install toolkit failed with status ${toolkit_status}" fi yes | ./${CANN_KERNELS} --install --quiet kernels_status=$? if [ ${kernels_status} -eq 0 ]; then echo "install kernels successfully" else echo "install kernels failed with status ${kernels_status}" fi # source /usr/local/Ascend/ascend-toolkit/set_env.sh # Install Atb and Model if [ ! -d "/home/llm_model" ]; then rm -rf /home/llm_model fi mkdir -p /usr/local/Ascend/llm_model MINDIE="Ascend-mindie_*_linux-aarch64.run" MODEL="Ascend-mindie-atb-models_1.0.RC1_linux-aarch64_torch2.1.0-abi0.tar.gz" tar -xzf ./${MODEL} -C /usr/local/Ascend/llm_model yes | ./${MINDIE} --install --quiet 2> /dev/null atb_status=$? if [ ${atb_status} -eq 0 ]; then echo "install atb successfully" else echo "install atb failed with status ${atb_status}" fi source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/llm_model/set_env.sh ================================================ FILE: llm-localization/ascend/mindie/docker/llm-server.sh ================================================ #!/bin/bash source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/llm_model/set_env.sh export PYTHONPATH=/usr/local/Ascend/llm_model:$PYTHONPATH cd /usr/local/Ascend/mindie/latest/mindie-service/bin ./mindieservice_daemon ================================================ FILE: llm-localization/ascend/mindie/docker/mindie-1.0.Dockerfile ================================================ #FROM ascendhub.huawei.com/public-ascendhub/mindie-service-env:1.0.RC1-800I-A2-aarch64 FROM ascendhub.huawei.com/public-ascendhub/mindie-service-env:v2 ENV APP_DIR=/workspace RUN mkdir -p $APP_DIR # COPY qwen1.5-14b.json /usr/local/Ascend/mindie/latest/mindie-service/conf/config.json COPY baichuan2-7b.json /usr/local/Ascend/mindie/latest/mindie-service/conf/config.json COPY llm-server.sh $APP_DIR RUN chmod -R 777 $APP_DIR/llm-server.sh ENTRYPOINT $APP_DIR/llm-server.sh # docker build --network=host -f mindie-1.0.Dockerfile -t ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.0 . # docker build --network=host -f mindie-1.0.Dockerfile -t ascendhub.huawei.com/public-ascendhub/mindie-service-online:v1.1 . ================================================ FILE: llm-localization/ascend/mindie/docker/mindie-all-1.0.Dockerfile ================================================ FROM ascendhub.huawei.com/public-ascendhub/mindie:1.0.RC1-800I-A2-aarch64 # USER root COPY driver /usr/local/Ascend/driver RUN ls -al /usr/local/Ascend/driver ENV APP_DIR=/workspace RUN mkdir -p $APP_DIR COPY install_and_enable_cann.sh /opt/package/install_and_enable_cann.sh RUN cd /opt/package && ls -al && cat /opt/package/install_and_enable_cann.sh && source ./install_and_enable_cann.sh RUN pip install transformers==4.37.2 -i https://pypi.tuna.tsinghua.edu.cn/simple COPY qwen1.5-14b.json /usr/local/Ascend/mindie/latest/mindie-service/conf/config.json COPY llm-server.sh $APP_DIR RUN chmod -R 777 $APP_DIR/llm-server.sh ENTRYPOINT ["$APP_DIR/llm-server.sh"] ================================================ FILE: llm-localization/ascend/mindie/docker/mindie-env-1.0.Dockerfile ================================================ FROM ascendhub.huawei.com/public-ascendhub/mindie:1.0.RC1-800I-A2-aarch64 USER root ENV APP_DIR=/workspace RUN mkdir -p $APP_DIR RUN cd /opt/package && ls -al && source ./install_and_enable_cann.sh RUN pip install transformers==4.37.2 -i https://pypi.tuna.tsinghua.edu.cn/simple ================================================ FILE: llm-localization/ascend/mindie/docker/qwen-72b.json ================================================ { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 4 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "127.0.0.1", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[0,1,2,3,4,5,6,7]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "qwen-72b", "modelWeightPath" : "/home/aicc/model_from_hf/qwen-72b-chat-hf", "worldSize" : 8, "cpuMemSize" : 5, "npuMemSize" : 8, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 200, "supportSelectBatch" : false, "maxQueueDelayMicroseconds" : 5000 } } ================================================ FILE: llm-localization/ascend/mindie/docker/qwen1.5-14b.json ================================================ { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 4 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "127.0.0.1", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[0,1,2,3]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "qwen1.5-14b", "modelWeightPath" : "/home/aicc/model_from_hf/Qwen1.5-14B-Chat", "worldSize" : 4, "cpuMemSize" : 5, "npuMemSize" : 12, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 200, "supportSelectBatch" : false, "maxQueueDelayMicroseconds" : 5000 } } ================================================ FILE: llm-localization/ascend/mindie/docker/qwen1.5-72b.json ================================================ { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 4 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "127.0.0.1", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[0,1,2,3,4,5,6,7]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "qwen1.5-72b", "modelWeightPath" : "/home/aicc/model_from_hf/Qwen1.5-72B", "worldSize" : 8, "cpuMemSize" : 5, "npuMemSize" : 8, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 200, "supportSelectBatch" : false, "maxQueueDelayMicroseconds" : 5000 } } ================================================ FILE: llm-localization/ascend/mindie/docker/qwen1.5-7b.json ================================================ { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 4 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "0.0.0.0", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[0,1]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "qwen1.5-7b", "modelWeightPath" : "/home/aicc/model_from_hf/Qwen1.5-7B-Chat", "worldSize" : 2, "cpuMemSize" : 5, "npuMemSize" : 16, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 200, "supportSelectBatch" : false, "maxQueueDelayMicroseconds" : 5000 } } ================================================ FILE: llm-localization/ascend/mindie/llm-server.sh ================================================ #!/bin/bash echo "入参:" $@ for a in "$@"; do #echo $a if [[ `echo $a | grep "^--model_name="` ]]; then model_name=`echo $a | grep "^--model_name=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--model_weight_path="` ]]; then model_weight_path=`echo $a | grep "^--model_weight_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--world_size="` ]]; then world_size=`echo $a | grep "^--world_size=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--npu_mem_size="` ]]; then npu_mem_size=`echo $a | grep "^--npu_mem_size=" | awk -F '=' '{print $2}'` fi done if [ -z "$model_name" ]; then model_name="default" fi if [ -z "$model_weight_path" ]; then model_weight_path="/workspace/model" fi if [ -z "$world_size" ]; then world_size=4 fi if [ -z "$npu_mem_size" ]; then npu_mem_size=8 fi echo "平台入参: model_name: $model_name, model_weight_path: $model_weight_path , world_size: $world_size , npu_mem_size: $npu_mem_size" npuids="" card_num=$(($world_size - 1)) for i in `seq 0 $card_num` do if [[ $i == $card_num ]] ; then npuids=$npuids$i else npuids=$npuids$i"," fi done echo $npuids # DEPLOYMENT_CONF_PATH="/home/guodong.li/workspace/config.json" DEPLOYMENT_CONF_PATH="/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json" cat < $DEPLOYMENT_CONF_PATH { "OtherParam": { "ResourceParam" : { "cacheBlockSize" : 128, "preAllocBlocks" : 8 }, "LogParam" : { "logLevel" : "Info", "logPath" : "/logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "0.0.0.0", "port" : 1025, "maxLinkNum" : 300, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "tlsCrl" : "security/certs/server_crl.pem" } }, "WorkFlowParam": { "TemplateParam" : { "templateType": "Standard", "templateName" : "Standard_llama", "pipelineNumber" : 1 } }, "ModelDeployParam": { "maxSeqLen" : 2560, "npuDeviceIds" : [[$npuids]], "ModelParam" : [ { "modelInstanceType": "Standard", "modelName" : "$model_name", "modelWeightPath" : "$model_weight_path", "worldSize" : $world_size, "cpuMemSize" : 5, "npuMemSize" : $npu_mem_size, "backendType": "atb" } ] }, "ScheduleParam": { "maxPrefillBatchSize" : 256, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 256, "maxIterTimes" : 1024, "maxPreemptCount" : 200, "supportSelectBatch" : true, "maxQueueDelayMicroseconds" : 50000 } } EOF echo "部署参数,$DEPLOYMENT_CONF_PATH" cat $DEPLOYMENT_CONF_PATH source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/llm_model/set_env.sh export PYTHONPATH=/usr/local/Ascend/llm_model:$PYTHONPATH cd /usr/local/Ascend/mindie/latest/mindie-service/bin ./mindieservice_daemon ================================================ FILE: llm-localization/ascend/mindie/mindid-1.0-offical.md ================================================ # README - https://www.hiascend.com/document/detail/zh/mindie/10RC1/description/whatismindie/mindie_what_0000.html - 此README对各模型统一的脚本及其使用方式进行介绍 ## 路径变量解释 | 变量名 | 含义 | |--------|--------------------------------------------------| | working_dir | 加速库及模型库下载后放置目录 | | llm_path | 模型仓所在路径。若使用编译好的包,则路径为`${working_dir}/MindIE-LLM/`;若使用gitee下载的代码,则路径为`${working_dir}/MindIE-LLM/examples/atb_models` | | weight_path | 模型权重路径 | | w8a8s_weight_path | 稀疏量化权重路径 | | w8a8sc_weight_path | 切分并压缩后的稀疏量化权重路径 | | cur_dir | 运行指令或执行脚本时的路径(当前目录) | ## 权重 ### 权重设置 - `${weight_path}/config.json`文件中需设置`dtype`和`quantize`类型来标识权重的量化类型和精度 - 若`dtype`和`quantize`字段不存在,需新增 - 配置 | 量化类型及精度 | torch_dtype | quantize | |----------------|-------------|----------| | FP16 | "float16" | 无 | | BF16 | "bfloat16" | 无 | | W8A8 | "float16" | "w8a8" | | W8A8S | "float16" | "w8a8s" | | W8A8SC | "float16" | "w8a8sc" | | W8A16 | "float16" | "w8a16" | - 示例 - LLaMa模型的权重使用BF16精度,非量化 ```json { "architectures": [ "LlamaForCausalLM" ], ... "torch_dtype": "bfloat16", ... } ``` - LLaMa模型的权重使用FP16精度,W8A16量化 ```json { "architectures": [ "LlamaForCausalLM" ], ... "torch_dtype": "float16", ... "quantize": "w8a16", } ``` ### 权重转换 > 当前仅支持加载safetensor格式的权重文件,若环境中已有bin格式的权重文件,请按照如下方式进行转换 > 若当前环境不存在模型权重,请至hugging face官网下载 - 使用`${llm_path}/examples/convert/convert_weights.py`将bin转成safetensor格式 - 示例 ```shell cd ${llm_path} python examples/convert/convert_weights.py --model_path ${weight_path} ``` - 注意:必须先进入`${llm_path}`路径下执行以上命令,否则由于脚本中存在相对路径,会导致moudle not found的问题 - 输出结果会保存在bin权重同目录下 ### 稀疏量化权重生成 - Step 1:生成稀疏量化权重 ```shell cd ${llm_path} python -m examples.convert.model_slim.sparse_quantifier --model_path ${weight_path} --save_directory ${w8a8s_weight_path} ``` - Step 2:量化权重切分及压缩 ```shell torchrun --nproc_per_node {TP数} -m examples.convert.model_slim.sparse_compressor --model_path ${w8a8s_weight_path} --save_directory ${w8a8sc_weight_path} ``` - TP数为tensor parallel并行个数 - 注意:若权重生成时以TP=4进行切分,则运行时也需以TP=4运行 - 示例 ```shell torchrun --nproc_per_node 2 -m examples.convert.model_slim.sparse_compressor --model_path /data1/weights/model_slim/llama2-7b_w8a8s --save_directory /data1/weights/model_slim/llama2-7b_w8a8sc_temp ``` ## 启动脚本 - Flash Attention的启动脚本路径为`${llm_path}/examples/run_fa.py` - Page Attention的启动脚本路径为`${llm_path}/examples/run_pa.py` ### 启动脚本相关环境变量 - `USE_ASCEND` - 是否使用昇腾加速库 - 设置为1使用加速库,设置为0则不使用加速库;默认使用 - `MAX_MEMORY_GB` - 限制最大显存 - 默认在服务器最大显存GB的基础上预留3GB显存 - 若出现显存不足导致的异常,请将该参数改小 - `ASCEND_RT_VISIBLE_DEVICES` - 指定当前机器上可用的逻辑NPU核心,多个核心间使用逗号相连 - 核心编号需要通过 npu-smi info 指令查阅 - Atlas 800I A2服务器需基于输出的 NPU 列查阅 ![npu_smi_info](../images/npu_smi_info_800i_a2.png) - Atlas 300I DUO服务器需基于输出的 Device 列查阅 ![npu_smi_info](../images/npu_smi_info_300i_duo.png) - 若要使用单卡双芯,请指定至少两个可见核心;若要使用双卡四芯,请指定至少四个可见核心 - `BIND_CPU` - 绑定CPU核心开关 - 设置为1进行绑核,设置为0则不绑核;默认进行绑核 - 若当前机器未设置NUMA或绑核失败,可将 BIND_CPU 设为 0 - `ATB_PROFILING_ENABLE` - 是否落性能profiling文件 - 设置为1生成profiling文件,设置为0则不生成;默认不生成profiling文件 - `PROFILING_FILEPATH` - (若生成profiling文件)profiling文件的路径 - 默认为`${cur_dir}/profiling` - `ATB_LLM_BENCHMARK_ENABLE` - 是否统计端到端和各token的性能数据 - 设置为1统计耗时,设置为0则不统计;默认不统计 - `ATB_LLM_BENCHMARK_FILEPATH` - 性能数据的保存路径 - 默认为`${cur_dir}/benchmark_result/benchmark.csv` ### run_fa.py脚本参数 - `--model_path` - 模型权重路径 - `--input_text` - 输入问题 - 支持字符串列表或者字符串 - 若此值为字符串,则构造推理输入时会基于batch size入参复制多份 - 若此值为列表,则构造推理输入时会忽略batch size入参,真实的batch size为此列表实际长度 - `--max_input_length` - 最大输入长度 - 默认512个token - 若输入长度不足512个token,会自动使用padding补齐 - `--max_output_length` - 最大输出长度 - - 默认输出20个token - `--batch_size` - 推理时固定的batch数量 - 默认单batch - `--is_flash_causal_lm` - 是否使用Paged Attention,默认不使用 - `--use_refactor` - 若设置为True则使用归一后代码,若设置为False,则使用未归一的代码;默认开启use_refactor - 示例 ```shell # 使用多卡运行Flash Attention,设置模型权重路径,设置输出长度为2048个token,精度使用BF16 torchrun --nproc_per_node 2 --master_port 20038 -m examples.run_fa --model_path ${weight_path} --max_output_length 2048 --is_bf16 ``` ### run_pa.py脚本参数 - `--model_path` - 模型权重路径 - `--input_text` - 输入问题 - 支持字符串列表或者字符串 - 若此值为单元素列表或字符串,则构造推理输入时会基于batch size入参复制多份 - 若此值为多元素列表,则构造推理输入时会忽略batch size入参,真实的batch size为此列表实际长度 - `--max_position_embeddings` - 模型可接受的最长输入长度 - 默认从模型权重的config文件中读取 - `--max_output_length` - 最大输出长度 - - 默认输出20个token - `--max_prefill_tokens` - Prefill推理阶段,最大输入长度 - 默认4096个token - `--max_batch_size` - 最大batch size,实际运行的batch size动态变化,有可能达不到设置的最大batch size - 默认单batch - `--is_flash_model` - 是否使用Paged Attention,默认使用 - `--use_refactor` - 若设置为True则使用归一后代码,若设置为False,则使用未归一的代码;默认开启use_refactor - 示例 ```shell # 使用多卡运行Paged Attention,设置模型权重路径,设置输出长度为2048个token,使用归一后代码 torchrun --nproc_per_node 2 --master_port 20038 -m examples.run_pa --model_path ${weight_path} --max_output_length 2048 --use_refactor True ``` ### 特殊场景说明 300I DUO 和 800I A2 上,单机多用户场景下,由于通信算子之间采用共享内存进行通信,每个用户需要配置如下环境变量,进行共享内存的区分; `export ATB_SHARE_MEMORY_NAME_SUFFIX="user1"` 单机多用户场景:如300I DUO上有4张卡,每张卡单独跑一个模型推理任务,需要根据 不同任务设置上述环境变量来区分,如`user1`、`user2` ================================================ FILE: llm-localization/ascend/mindie/mindid-performance.md ================================================ ``` curl --location --request POST 'http://192.168.16.211:1025/v1/chat/completions' \ --header 'Content-Type: application/json' \ --data-raw '{ "model": "qwen1.5-14b", "messages": [ { "role": "user", "content": "<|im_start|>user\n你好,我的名字是李聪明。请问你是谁?<|im_end|>\n<|im_start|>assistant\n你好,李聪明!很高兴认识你。我是一个大型语言模型,你可以叫我通义千问。有什么问题或需要帮助的话,请随时告诉我。<|im_end|>\n<|im_start|>user\n我最近心情很糟糕,能给我一些建议吗?<|im_end|><|im_start|>assistant\n我很理解你现在的感受。面对糟糕的心情,以下是一些可能有帮助的建议:\n\n1. **与他人分享**:告诉信任的朋友或家人你的感受,他们可能能提供安慰和支持。\n2. **自我关怀**:确保每天有足够的休息,做些你喜欢的事情,比如阅读、听音乐或运动。\n3. **运动与放松**:适度的运动可以帮助释放压力,尝试瑜伽、冥想或深呼吸练习。\n4. **寻求专业帮助**:如果你觉得压力过大,考虑咨询心理医生或心理咨询师。\n5. **保持积极思考**:试着找出生活中的小确幸,每天对自己说一些积极的话。\n6. **时间管理**:合理安排时间,避免过度压力,留出放松的时间。\n\n记住,处理情绪需要时间和耐心,不要对自己太苛刻。如果你的情绪持续低落,可能需要更专业的支持。希望这些建议对你有所帮助。<|im_end|>\n<|im_start|>user\n请问我叫什么名字?<|im_end|>\n<|im_start|>assistant\n" } ], "max_tokens":256, "top_p": 0.85, "n": 10, "logprobs": true, "stop": "<|im_end|>", "stream": true }' ``` ================================================ FILE: llm-localization/ascend/mindie/mindie-1.0.Dockerfile ================================================ FROM ascendhub.huawei.com/public-ascendhub/mindie:1.0.RC1-800I-A2-aarch64 RUN cd /opt/package && source install_and_enable_cann.sh \ && source /usr/local/Ascend/ascend-toolkit/set_env.sh \ && source /usr/local/Ascend/mindie/set_env.sh \ && source /usr/local/Ascend/llm_model/set_env.sh ================================================ FILE: llm-localization/ascend/mindie/mindie-1.0.RC2.md ================================================ 文档: - https://www.hiascend.com/document/detail/zh/mindie/10RC2/whatismindie/mindie_what_0001.html docker: - https://www.hiascend.com/developer/ascendhub/detail/af85b724a7e5469ebd7ea13c3439d48f rsync -P --rsh=ssh -r root@192.168.16.xxx:/root/mindie-1.0.rc2.tar . swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:1.0.RC2-800I-A2-aarch64 ``` docker run -it -d --name mindie-rc2-45 --net=host \ -e ASCEND_VISIBLE_DEVICES=4,5 \ -p 1925:1025 \ --shm-size=32g \ -w /workspace \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /data/model_from_hf:/workspace/model \ swr.cn-south-1.myhuaweicloud.com/ascendhub/mindie:1.0.RC2-800I-A2-aarch64 \ /bin/bash docker exec -it mindie-rc2-45 bash cd /opt/package # 安装CANN包 source ./install_and_enable_cann.sh source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/nnal/atb/set_env.sh source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/llm_model/set_env.sh vim /usr/local/Ascend/mindie/latest/mindie-service/conf/config.json /workspace/model/Qwen1.5-7B-Chat/ export MIES_PYTHON_LOG_TO_FILE=1 export MIES_PYTHON_LOG_TO_STDOUT=1 export PYTHONPATH=/usr/local/Ascend/llm_model:$PYTHONPATH cd /usr/local/Ascend/mindie/latest/mindie-service/bin ./mindieservice_daemon ``` ## 新镜像 ``` docker commit -a "guodong" -m "mindie-1.0.RC2" 365815a95f16 harbor/ascend/mindie-base:1.0.RC2 docker save -o mindie-base.tar harbor/ascend/mindie-base:1.0.RC2 rsync -P --rsh=ssh -r root@192.168.16.211:/home/workspace/mindie-base.tar . # -p 192.168.16.xx:1025:1025 docker run -it --rm \ -e ASCEND_VISIBLE_DEVICES=2,3 \ -p 1025:1025 \ --shm-size=32g \ -w /workspace \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /data/model_from_hf:/workspace/model \ harbor/ascend/mindie-base:1.0.RC2 \ /bin/bash ``` ``` llm-server3.sh docker run -it --rm \ -e ASCEND_VISIBLE_DEVICES=6,7 \ -p 1825:1025 \ --env AIE_LLM_CONTINUOUS_BATCHING=1 \ --shm-size=32g \ -w /workspace \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /data/model_from_hf/Qwen1.5-7B-Chat:/workspace/model \ -v /home/workspace/llm-server3.sh:/workspace/llm-server.sh \ -v /home/workspace/mindservice.log:/usr/local/Ascend/mindie/latest/mindie-service/logs/mindservice.log \ harbor/ascend/mindie-base:1.0.RC2 \ /bin/bash docker run -it --rm \ -e ASCEND_VISIBLE_DEVICES=6,7 \ -p 1525:1025 \ --env AIE_LLM_CONTINUOUS_BATCHING=1 \ --shm-size=32g \ -w /workspace \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /data/model_from_hf/Qwen1.5-7B-Chat:/workspace/model \ -v /home/workspace/llm-server3.sh:/workspace/llm-server.sh \ -v /home/workspace/mindservice.log:/usr/local/Ascend/mindie/latest/mindie-service/logs/mindservice.log \ harbor/ascend/mindie-base:1.0.RC2 \ /workspace/llm-server.sh \ --model_name=qwen-chat \ --model_weight_path=/workspace/model \ --world_size=2 \ --npu_mem_size=15 docker run -it --rm \ -e ASCEND_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \ -p 1525:1025 \ --env AIE_LLM_CONTINUOUS_BATCHING=1 \ --shm-size=32g \ -w /workspace \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /data/model_from_hf/Qwen2-72B-Instruct:/workspace/model \ -v /home/workspace/llm-server3.sh:/workspace/llm-server.sh \ -v /home/workspace/mindservice.log:/usr/local/Ascend/mindie/latest/mindie-service/logs/mindservice.log \ harbor/ascend/mindie-base:1.0.RC2 \ /workspace/llm-server.sh \ --model_name=qwen-chat \ --model_weight_path=/workspace/model \ --world_size=8 \ --npu_mem_size=8 ``` ================================================ FILE: llm-localization/ascend/mindie/mindie-1.0.md ================================================ - https://ascendhub.huawei.com/#/detail/mindie - ascendhub.huawei.com/public-ascendhub/mindie:1.0.RC1-800I-A2-aarch64 一键使能 CANN 软件栈的 shell 脚本(install_and_enable_cann.sh) - /usr/local/Ascend/llm_model/pytorch/examples/chatglm2/6b/README.md 建议将权重存放于 /home/chatglm2_6b/weight 目录下,并设置 CHECKPOINT=/home/chatglm2_6b/weight ## 编写 docker 启动脚本 编写 docker 启动脚本 start-docker.sh 如下所示,存放于 /home/chatglm2_6b 目录下 ``` IMAGES_ID=$1 NAME=$2 if [ $# -ne 2 ]; then echo "error: need one argument describing your container name." exit 1 fi docker run --name ${NAME} -it -d --net=host --shm-size=500g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ --entrypoint=bash \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ -e http_proxy=$http_proxy \ -e https_proxy=$https_proxy \ ${IMAGES_ID} ``` 参数说明: - IMAGES_ID 为镜像版本号。(docker images 命令回显中的 IMAGES ID) - NAME 为启动容器名,可自定义设置。 ## 启动并进入容器 依次执行如下命令启动并进入容器: ``` cd /home/chatglm2_6b # 用户可以设置 docker images 命令回显中的 IMAGES ID image_id=001b7368f6e0 # 用户可以自定义设置镜像名 custom_image_name=chatGLM2_6B # 启动容器(确保启动容器前,本机可访问外网) bash start-docker.sh ${image_id} ${custom_image_name} # 进入容器 docker exec -itu root ${custom_image_name} bash ``` ## 使能昇腾CANN软件栈 ``` cd /opt/package # 安装CANN包 source install_and_enable_cann.sh # 若退出后重新进入容器,则需要重新加载 CANN 环境变量,执行以下三行命令 source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/llm_model/set_env.sh ``` ## 推理 Chatglm2_6b 模型 ``` cd /usr/local/Ascend/llm_model # 权重转 safetensor python examples/convert/convert_weights.py --model_path ${CHECKPOINT} # 执行推理脚本 python examples/run_pa.py --model_path ${CHECKPOINT} 启动后会执行推理,显示默认问题Question和推理结果Answer,若用户想要自定义输入问题,可使用--input_texts参数设置,如: python examples/run_pa.py --model_path ${CHECKPOINT} --input_texts "What is deep learning?" ``` ## Qwen1.5-14B ``` # docker rm -f mindie-dev docker run --name mindie-dev2 -it -d --net=host --ipc=host \ --shm-size=50g \ --privileged=true \ -w /home \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ --entrypoint=bash \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/sbin:/usr/local/sbin \ -v /home:/home \ -v /tmp:/tmp \ -v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime \ ascendhub.huawei.com/public-ascendhub/mindie:1.0.RC1-800I-A2-aarch64 docker exec -itu root mindie-dev2 bash cd /opt/package # 安装CANN包 source ./install_and_enable_cann.sh # 若退出后重新进入容器,则需要重新加载 CANN 环境变量,执行以下三行命令 source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/llm_model/set_env.sh rm /usr/local/Ascend/mindie/latest/mindie-service/conf/config.json vim /usr/local/Ascend/mindie/latest/mindie-service/conf/config.json - /home/aicc/model_from_hf/Qwen1.5-14B-Chat export PYTHONPATH=/usr/local/Ascend/llm_model:$PYTHONPATH cd /usr/local/Ascend/mindie/latest/mindie-service/bin ./mindieservice_daemon ``` ``` transformers==4.30.2 pip install transformers==4.37.2 -i https://pypi.tuna.tsinghua.edu.cn/simple "torch_dtype": "bfloat16" 改为 "float16" ``` ================================================ FILE: llm-localization/ascend/mindie/mindie-1.0.rc2-config.json ================================================ { "OtherParam" : { "ResourceParam" : { "cacheBlockSize" : 128 }, "LogParam" : { "logLevel" : "Info", "logPath" : "logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "172.17.0.2", "managementIpAddress" : "127.0.0.2", "port" : 1025, "managementPort" : 1026, "maxLinkNum" : 1000, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "tlsCrl" : "security/certs/server_crl.pem", "managementTlsCaFile" : ["management_ca.pem"], "managementTlsCert" : "security/certs/management_server.pem", "managementTlsPk" : "security/keys/management_server.key.pem", "managementTlsPkPwd" : "security/pass/management_mindie_server_key_pwd.txt", "managementTlsCrl" : "security/certs/management_server_crl.pem", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "multiNodesInferPort" : 1120, "interNodeTLSEnabled" : true, "interNodeTlsCaFile" : "security/ca/ca.pem", "interNodeTlsCert" : "security/certs/server.pem", "interNodeTlsPk" : "security/keys/server.key.pem", "interNodeTlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "interNodeKmcKsfMaster" : "tools/pmt/master/ksfa", "interNodeKmcKsfStandby" : "tools/pmt/standby/ksfb" } }, "WorkFlowParam" : { "TemplateParam" : { "templateType" : "Standard", "templateName" : "Standard_llama" } }, "ModelDeployParam" : { "engineName" : "mindieservice_llm_engine", "modelInstanceNumber" : 1, "tokenizerProcessNumber" : 8, "maxSeqLen" : 2560, "npuDeviceIds" : [[$npuids]], "multiNodesInferEnabled" : false, "ModelParam" : [ { "modelName" : "$model_name", "modelWeightPath" : "$model_weight_path", "worldSize" : $world_size, "cpuMemSize" : 5, "npuMemSize" : $npu_mem_size, "backendType": "atb", "pluginParams" : "" } ] }, "ScheduleParam" : { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 0, "supportSelectBatch" : true, "maxQueueDelayMicroseconds" : 5000 } } ================================================ FILE: llm-localization/ascend/mindie/mindie-1.0.rc2-llm-server.sh ================================================ #!/bin/bash echo "入参:" $@ for a in "$@"; do #echo $a if [[ `echo $a | grep "^--model_name="` ]]; then model_name=`echo $a | grep "^--model_name=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--model_weight_path="` ]]; then model_weight_path=`echo $a | grep "^--model_weight_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--world_size="` ]]; then world_size=`echo $a | grep "^--world_size=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--npu_mem_size="` ]]; then npu_mem_size=`echo $a | grep "^--npu_mem_size=" | awk -F '=' '{print $2}'` fi done if [ -z "$model_name" ]; then model_name="default" fi if [ -z "$model_weight_path" ]; then model_weight_path="/workspace/model" fi if [ -z "$world_size" ]; then world_size=4 fi if [ -z "$npu_mem_size" ]; then npu_mem_size=8 fi echo "平台入参: model_name: $model_name, model_weight_path: $model_weight_path , world_size: $world_size , npu_mem_size: $npu_mem_size" npuids="" card_num=$(($world_size - 1)) for i in `seq 0 $card_num` do if [[ $i == $card_num ]] ; then npuids=$npuids$i else npuids=$npuids$i"," fi done echo $npuids ip=`hostname -I` echo "docker ip: [$ip]" ip=$(echo "$ip" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') echo "docker handle ip: [$ip]" # DEPLOYMENT_CONF_PATH="/home/guodong.li/workspace/config.json" DEPLOYMENT_CONF_PATH="/usr/local/Ascend/mindie/latest/mindie-service/conf/config.json" cat < $DEPLOYMENT_CONF_PATH { "OtherParam" : { "ResourceParam" : { "cacheBlockSize" : 128 }, "LogParam" : { "logLevel" : "Info", "logPath" : "logs/mindservice.log" }, "ServeParam" : { "ipAddress" : "$ip", "managementIpAddress" : "127.0.0.2", "port" : 1025, "managementPort" : 1026, "maxLinkNum" : 1000, "httpsEnabled" : false, "tlsCaPath" : "security/ca/", "tlsCaFile" : ["ca.pem"], "tlsCert" : "security/certs/server.pem", "tlsPk" : "security/keys/server.key.pem", "tlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "tlsCrl" : "security/certs/server_crl.pem", "managementTlsCaFile" : ["management_ca.pem"], "managementTlsCert" : "security/certs/management_server.pem", "managementTlsPk" : "security/keys/management_server.key.pem", "managementTlsPkPwd" : "security/pass/management_mindie_server_key_pwd.txt", "managementTlsCrl" : "security/certs/management_server_crl.pem", "kmcKsfMaster" : "tools/pmt/master/ksfa", "kmcKsfStandby" : "tools/pmt/standby/ksfb", "multiNodesInferPort" : 1120, "interNodeTLSEnabled" : true, "interNodeTlsCaFile" : "security/ca/ca.pem", "interNodeTlsCert" : "security/certs/server.pem", "interNodeTlsPk" : "security/keys/server.key.pem", "interNodeTlsPkPwd" : "security/pass/mindie_server_key_pwd.txt", "interNodeKmcKsfMaster" : "tools/pmt/master/ksfa", "interNodeKmcKsfStandby" : "tools/pmt/standby/ksfb" } }, "WorkFlowParam" : { "TemplateParam" : { "templateType" : "Standard", "templateName" : "Standard_llama" } }, "ModelDeployParam" : { "engineName" : "mindieservice_llm_engine", "modelInstanceNumber" : 1, "tokenizerProcessNumber" : 8, "maxSeqLen" : 2560, "npuDeviceIds" : [[$npuids]], "multiNodesInferEnabled" : false, "ModelParam" : [ { "modelName" : "$model_name", "modelWeightPath" : "$model_weight_path", "worldSize" : $world_size, "cpuMemSize" : 5, "npuMemSize" : $npu_mem_size, "backendType": "atb", "pluginParams" : "" } ] }, "ScheduleParam" : { "maxPrefillBatchSize" : 50, "maxPrefillTokens" : 8192, "prefillTimeMsPerReq" : 150, "prefillPolicyType" : 0, "decodeTimeMsPerReq" : 50, "decodePolicyType" : 0, "maxBatchSize" : 200, "maxIterTimes" : 512, "maxPreemptCount" : 0, "supportSelectBatch" : true, "maxQueueDelayMicroseconds" : 5000 } } EOF echo "部署参数,$DEPLOYMENT_CONF_PATH" cat $DEPLOYMENT_CONF_PATH source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/nnal/atb/set_env.sh source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/llm_model/set_env.sh export MIES_PYTHON_LOG_TO_FILE=1 export MIES_PYTHON_LOG_TO_STDOUT=1 export PYTHONPATH=/usr/local/Ascend/llm_model:$PYTHONPATH cd /usr/local/Ascend/mindie/latest/mindie-service/bin ./mindieservice_daemon ================================================ FILE: llm-localization/ascend/mindie/mindie-2.0.rc2.md ================================================ # 量化 ``` cd ${ATB_SPEED_HOME_PATH} python examples/models/llama3/convert_quant_weights.py --model_path {浮点权重路径} --save_directory {W8A8量化权重路径} --w_bit 8 --a_bit 8 --disable_level L0 --device_type cpu --anti_method m1 --act_method 1 --calib_file ${llm_path}/examples/convert/model_slim/boolq.jsonl ``` ================================================ FILE: llm-localization/ascend/mindie/mindie-20240411.md ================================================ ``` docker run -it --name=mindie_server_t37 --net=host --ipc=host --privileged=true \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \ -v /usr/local/sbin/:/usr/local/sbin/ \ -v /var/log/npu/slog/:/var/log/npu/slog \ -v /var/log/npu/profiling/:/var/log/npu/profiling \ -v /var/log/npu/dump/:/var/log/npu/dump \ -v /var/log/npu/:/usr/slog \ -v /etc/hccn.conf:/etc/hccn.conf \ -v /home:/workspace \ mindie_server:1.0.T37 \ /bin/bash docker exec -it mindie_server_t37 bash docker inspect mindie_server:1.0.T37 docker inspect -f '{{with .State}} {{.Pid}} {{end}}' mindie_server_t37 docker inspect --format='{{.Name}}' mindie_server_t37 docker inspect --format='ARCH: {{.Architecture}} , OS: {{.Os}}' mindie_server:1.0.T37 # ARCH: arm64 , OS: linux docker inspect -f {{".Architecture"}} mindie_server:1.0.T37 ``` {{range .NetworkSettings.Networks}} ``` source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/mindie/latest/mindie-service/set_env.sh source /opt/atb-models/set_env.sh ``` ``` cd /usr/local/Ascend/mindie/latest/mindie-service/latest vim conf/config.json ``` npuMemSize: NPU中可以用来申请 kv cache的 size上限。单位:GB。 建议值:8。 npuMemSize=(总空闲-权重/tp数)*系数,其中系数取 0.8。 以 llama-65b为例: 总显存 64GB,空闲状态卡上有 3~4GB的占用,llama-65b 的总权重为 122GB,用 8张卡跑,则 npuMemSize取值的 上限为:(64-4-(122/8))*0.8。 ``` /workspace/dataset/qwen /workspace/aicc/model_from_hf/Baichuan2-7B-Chat /workspace/aicc/model_from_hf/chatglm3-6b-chat /workspace/aicc/model_from_hf/chatglm3-6b-chat-full ``` ## Mindie_server ``` # 执行./mindieservice_daemon启动服务 cd /usr/local/Ascend/mindie/latest/mindie-service/latest/bin ./mindieservice_daemon ``` ## 接口请求 ``` curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "inputs": "保持健康的方法", "parameters": { "best_of": 1, "decoder_input_details": true, "details": true, "do_sample": true, "max_new_tokens": 20, "repetition_penalty": 1.03, "return_full_text": false, "seed": null, "stop": [ "photographer" ], "top_k": 10, "temperature": 0.5, "top_n_tokens": 5, "top_p": 0.95, "truncate": null, "typical_p": 0.95, "watermark": true }, "stream": false}' http://127.0.0.1:1025/generate curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "inputs": "保持健康的方法", "parameters": { "best_of": 1, "decoder_input_details": true, "details": true, "do_sample": true, "max_new_tokens": 20, "repetition_penalty": 1.03, "return_full_text": false, "seed": null, "stop": [ "photographer" ], "temperature": 0.5, "top_n_tokens": 5, "top_p": 0.95, "truncate": null, "typical_p": 0.95, "watermark": true }, "stream": false}' http://127.0.0.1:1025/generate curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "model": "qwen-72b", "messages": [ { "role": "system", "content": "你是一个有博学多才的助手." }, { "role": "user", "content": "保持健康的方法" } ] }' http://127.0.0.1:1025/v1/chat/completions ``` ## 性能测试 ``` cp token_input_gsm.csv /usr/local/Ascend/mindie/latest/mindie-service/latest/bin ./llm_engine_test ``` ``` cp token_input_gsm.csv /usr/local/Ascend/mindie/latest/mindie-service/latest/bin cd /usr/local/Ascend/mindie/latest/mindie-service/latest/bin ./llm_engine_test ``` ``` source /usr/local/Ascend/ascend-toolkit/set_env.sh source /usr/local/Ascend/mindie/set_env.sh source /usr/local/Ascend/mindie/latest/mindie-service/set_env.sh source /opt/atb-models/set_env.sh cd /opt/atb-models/tests/modeltest bash run.sh pa_fp16 performance [[2048,2048]] 1 qwen /workspace/aicc/model_from_hf/qwen-72b-chat-hf 8 > qwen-72b-2048-1-8.log bash run.sh pa_fp16 performance [[2048,2048],[2048,2048],[2048,2048],[2048,2048],[2048,2048]] 1 qwen /workspace/aicc/model_from_hf/qwen-72b-chat-hf 8 > qwen-72b-2048-1-8.log bash run.sh pa_fp16 performance [[2048,2048]] 4 qwen /workspace/aicc/model_from_hf/qwen-72b-chat-hf 8 > qwen-72b-2048-4-8.log ``` ``` 2024-04-23 06:43:44,225 [INFO] [pid: 5844] generate.py-186: Prefill time: 299.3795871734619ms, Decode token time: 37.169588794344854ms, E2E time: 76385.52784919739ms 2024-04-23 06:43:45,396 - [INFO] - model_test.py:419 - batch: 1, seq_len_in: 2048, seq_len_out: 2048, total_time: 76.46122479438782, first_token_time: 299.38, non_first_token_time: 37.17, non_first_token_throughput: 26.90341673392521, e2e_time: 76.46122479438782, e2e_throughput: 26.784818128499577 2024-04-23 06:43:45,397 - [INFO] - model_test.py:434 - batch: 1, non_first_token_throughput_total: 26.90341673392521, non_first_token_throughput_average: 26.90341673392521, e2e_throughput_total: 26.784818128499577, e2e_throughput_average: 26.784818128499577 2024-04-23 06:43:45,399 - [INFO] - model_test.py:464 - qwen_72b batch1 result saved in /opt/atb-models/tests/modeltest/base/../result/qwen_72b/pa_fp16_batch1_performance_test_result.csv 2024-04-23 06:43:45,399 - [INFO] - model_test.py:466 - qwen_72b batch1 formatted result saved in /opt/atb-models/tests/modeltest/base/../result/qwen_72b/pa_fp16_batch1_performance_test_result_formatted.csv 2024-04-23 07:33:44,898 - [INFO] - model_test.py:419 - batch: 4, seq_len_in: 2048, seq_len_out: 2048, total_time: 86.89873886108398, first_token_time: 1157.03, non_first_token_time: 41.85, non_first_token_throughput: 95.57945041816009, e2e_time: 86.89873886108398, e2e_throughput: 94.27064313436932 2024-04-23 07:33:44,898 - [INFO] - model_test.py:434 - batch: 4, non_first_token_throughput_total: 95.57945041816009, non_first_token_throughput_average: 95.57945041816009, e2e_throughput_total: 94.27064313436932, e2e_throughput_average: 94.27064313436932 ``` ```python def run_performance_test(): non_first_token_throughput_total = 0 e2e_throughput_total = 0 for seq_len_in, seq_len_out in self.case_pair: self.logger.info("batch_size: " + str(self.batch_size) + ", seq_len_in: " + str(seq_len_in) + ", seq_len_out: " + str(seq_len_out)) if self.model_type == "fa": input_ids = torch.randint(0, self.model.config.vocab_size, [self.batch_size, seq_len_in], dtype=torch.int64) attention_mask = torch.ones((self.batch_size, seq_len_in), dtype=torch.int64) inputs = self.tokenizer(performance_prompt * self.batch_size, return_tensors="pt", padding='max_length', max_length=seq_len_in) inputs["input_ids"] = input_ids inputs["attention_mask"] = attention_mask input_ids = inputs.input_ids.to(self.model.device) attention_mask = inputs.attention_mask.to(self.model.device) with torch.no_grad(): getattr(torch, self.core_type).synchronize() e2e_start = time.time() generate_ids = self.model.generate(inputs=input_ids, attention_mask=attention_mask, min_new_tokens=seq_len_out, max_new_tokens=seq_len_out ) try: _ = self.tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False) except: _ = [ self.tokenizer.decode(output) for output in generate_ids[:, inputs["input_ids"].size(1):].tolist() ] getattr(torch, self.core_type).synchronize() e2e_end = time.time() e2e_time = e2e_end - e2e_start else: input_dict = { 'rank': self.rank, 'local_rank': self.local_rank, 'world_size': self.world_size, 'max_prefill_tokens': -1, 'block_size': 128, 'model_path': self.weight_dir, 'is_bf16': True if self.data_type == "bf16" else False, 'max_position_embeddings': self.max_position_embedding if self.max_position_embedding != -1 else seq_len_in + seq_len_out, 'max_batch_size': self.batch_size, 'use_refactor': self.use_refactor, 'max_input_length': seq_len_in, 'max_output_length': seq_len_out } pa_runner = PARunner(**input_dict) self.logger.info(str(self.rank) + f'pa_runner: {pa_runner}') pa_runner.warm_up() input_ids = torch.randint(0, pa_runner.model.config.vocab_size, [seq_len_in], dtype=torch.int64) _, _, e2e_time = pa_runner.infer("", self.batch_size, seq_len_out, True, [input_ids]) del pa_runner torch.npu.empty_cache() if self.rank == 0: if self.model_type == "fa": first_token_time_tensor = torch.load(f"{folder_path}/first_token_time.pth").cpu() first_token_time = first_token_time_tensor.item() non_first_token_time_tensor = torch.load(f"{folder_path}/non_first_token_time.pth").cpu() non_first_token_time = non_first_token_time_tensor.item() / (seq_len_out - 1) else: benchmark_csv = os.path.join(self.script_path, "../benchmark.csv") with open(benchmark_csv, newline='') as csvfile: csv_reader = csv.reader(csvfile) next(csv_reader) second_row = next(csv_reader) first_token_time = float(second_row[4]) / 1000 non_first_token_time = float(second_row[5]) / 1000 non_first_token_throughput = self.batch_size / non_first_token_time non_first_token_throughput_total += non_first_token_throughput e2e_throughput = self.batch_size * seq_len_out / e2e_time e2e_throughput_total += e2e_throughput self.logger.info( f"batch: {self.batch_size}, seq_len_in: {seq_len_in}, seq_len_out: {seq_len_out}, total_time: {e2e_time}, first_token_time: {first_token_time * 1000}," + f" non_first_token_time: {non_first_token_time * 1000}, non_first_token_throughput: {non_first_token_throughput}," + f" e2e_time: {e2e_time}, e2e_throughput: {e2e_throughput}") csv_results.append( [str(self.model_name).ljust(15), str(self.batch_size).ljust(15), str(seq_len_in).ljust(15), str(seq_len_out).ljust(15), str(round(e2e_time, 10)).ljust(15), str(round(first_token_time * 1000, 10)).ljust(25), str(round(non_first_token_time * 1000, 10)).ljust(25), str(round(non_first_token_throughput, 10)).ljust(36), str(round(e2e_throughput, 10)).ljust(25)]) if self.rank == 0: non_first_token_throughput_average = non_first_token_throughput_total / len(self.case_pair) e2e_throughput_average = e2e_throughput_total / len(self.case_pair) self.logger.info( f"batch: {self.batch_size}, non_first_token_throughput_total: {non_first_token_throughput_total}, non_first_token_throughput_average:" + f" {non_first_token_throughput_average}, e2e_throughput_total: {e2e_throughput_total}, e2e_throughput_average: {e2e_throughput_average}") csv_results[len(self.case_pair) - 1].extend( [str(round(non_first_token_throughput_average, 10)).ljust(45), str(round(e2e_throughput_average, 10)).ljust(35)]) folder_name = self.model_name csv_name = self.model_type + "_" + self.data_type + "_" + self.test_mode + "_batch" + str(self.batch_size) + "_test_result.csv" if self.quantize: csv_name = self.model_type + "_" + self.data_type + "_" + self.quantize + "_batch" + str(self.batch_size) + "_" + self.test_mode + "_test_result.csv" csv_formatted_name = self.model_type + "_" + self.data_type + "_" + self.quantize + "_batch" + str(self.batch_size) + "_" + self.test_mode + "_test_result_formatted.csv" else: csv_name = self.model_type + "_" + self.data_type + "_batch" + str(self.batch_size) + "_" + self.test_mode + "_test_result.csv" csv_formatted_name = self.model_type + "_" + self.data_type + "_batch" + str(self.batch_size) + "_" + self.test_mode + "_test_result_formatted.csv" csv_performance_path = os.path.join(self.script_path, "../result", folder_name, csv_name) csv_performance_formatted_path = os.path.join(self.script_path, "../result", folder_name, csv_formatted_name) if not os.path.exists(csv_performance_formatted_path): self.logger.warning("performance result csv formatted file not exist, skip recording results") raise RuntimeError(f"csv result formatted file not exist") with open(csv_performance_formatted_path, 'a', newline='') as csv_file: csv_writer = csv.writer(csv_file, delimiter='|') for csv_result in csv_results: csv_writer.writerow(csv_result) csv_results.insert(0, ["Model", "Batchsize", "In_seq", "Out_seq", "Total time(s)", "First token time(ms)", "Non-first token time(ms)", "Non-first token Throughout(Tokens/s)", "Throughout(Tokens/s)", "Non-first token Throughout Average(Tokens/s)", "E2E Throughout Average(Tokens/s)"]) df = pd.DataFrame(csv_results) df.to_csv(csv_performance_path, index=False, header=False) self.logger.info(self.model_name + " " + " batch" + str( self.batch_size) + " result saved in " + csv_performance_path) self.logger.info(self.model_name + " " + " batch" + str( self.batch_size) + " formatted result saved in " + csv_performance_formatted_path) ``` ================================================ FILE: llm-localization/ascend/mindie/mindie-api.md ================================================ ## OpenAI ``` curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "model": "qwen-72b", "messages": [ { "role": "system", "content": "你是一个有用的助手." }, { "role": "user", "content": "如何养生?" } ] }' http://127.0.0.1:1125/v1/chat/completions curl "http://127.0.0.1:1025/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "baichuan2-7b", "messages": [ { "role": "user", "content": "如何养生?" } ], "max_tokens":128 }' curl "http://127.0.0.1:1025/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen1.5-14b", "messages": [ { "role": "user", "content": "如何养生?" } ], "max_tokens":256 }' curl "http://127.0.0.1:1025/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen1.5-14b", "messages": [ { "role": "user", "content": "你好,我叫李聪明。请问你是谁?" } ], "max_tokens":256, "top_p": 0.85, "n": 10, "logprobs": true, "stop": "<|im_end|>" }' # http://127.0.0.1:1025/v1/chat/completions # # http://192.168.16.xxx:1725/v1/chat/completions curl "http://172.17.0.2:1025/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen1.5-14b", "messages": [ { "role": "user", "content": "你好,我叫李聪明。请问你是谁?" },{ "role": "assistant", "content": "你好,李聪明!很高兴认识你。我是一个大型语言模型,你可以叫我通义千问。有什么问题或需要帮助的话,请随时告诉我。" },{ "role": "user", "content": "我最近心情很糟糕,能给我一些建议吗?" } ], "max_tokens":256, "top_p": 0.85, "n": 10, "logprobs": true }' curl "http://127.0.0.1:1025/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen1.5-14b", "messages": [ { "role": "user", "content": "你好,我叫李聪明。请问你是谁?\n你好,李聪明!很高兴认识你。我是一个大型语言模型,你可以叫我通义千问。有什么问题或需要帮助的话,请随时告诉我。\n我最近心情很糟糕,能给我一些建议吗?" } ], "max_tokens":256, "top_p": 0.85, "n": 10, "logprobs": true }' ---- <|im_start|>user 你好,我的名字是李聪明。请问你是谁?<|im_end|> <|im_start|>assistant 你好,李聪明!很高兴认识你。我是一个大型语言模型,你可以叫我通义千问。有什么问题或需要帮助的话,请随时告诉我。<|im_end|> <|im_start|>user 我最近心情很糟糕,能给我一些建议吗?<|im_end|> <|im_start|>assistant 我很理解你现在的感受。面对糟糕的心情,以下是一些可能有帮助的建议:\n\n1. **与他人分享**:告诉信任的朋友或家人你的感受,他们可能能提供安慰和支持。\n2. **自我关怀**:确保每天有足够的休息,做些你喜欢的事情,比如阅读、听音乐或运动。\n3. **运动与放松**:适度的运动可以帮助释放压力,尝试瑜伽、冥想或深呼吸练习。\n4. **寻求专业帮助**:如果你觉得压力过大,考虑咨询心理医生或心理咨询师。\n5. **保持积极思考**:试着找出生活中的小确幸,每天对自己说一些积极的话。\n6. **时间管理**:合理安排时间,避免过度压力,留出放松的时间。\n\n记住,处理情绪需要时间和耐心,不要对自己太苛刻。如果你的情绪持续低落,可能需要更专业的支持。希望这些建议对你有所帮助。<|im_end|> <|im_start|>user 请问我叫什么名字?<|im_end|> ---- curl "http://127.0.0.1:1125/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen1.5-14b", "messages": [ { "role": "user", "content": "<|im_start|>user\n你好,我的名字是李聪明。请问你是谁?<|im_end|>\n<|im_start|>assistant\n你好,李聪明!很高兴认识你。我是一个大型语言模型,你可以叫我通义千问。有什么问题或需要帮助的话,请随时告诉我。<|im_end|>\n<|im_start|>user\n我最近心情很糟糕,能给我一些建议吗?<|im_end|><|im_start|>assistant\n我很理解你现在的感受。面对糟糕的心情,以下是一些可能有帮助的建议:\n\n1. **与他人分享**:告诉信任的朋友或家人你的感受,他们可能能提供安慰和支持。\n2. **自我关怀**:确保每天有足够的休息,做些你喜欢的事情,比如阅读、听音乐或运动。\n3. **运动与放松**:适度的运动可以帮助释放压力,尝试瑜伽、冥想或深呼吸练习。\n4. **寻求专业帮助**:如果你觉得压力过大,考虑咨询心理医生或心理咨询师。\n5. **保持积极思考**:试着找出生活中的小确幸,每天对自己说一些积极的话。\n6. **时间管理**:合理安排时间,避免过度压力,留出放松的时间。\n\n记住,处理情绪需要时间和耐心,不要对自己太苛刻。如果你的情绪持续低落,可能需要更专业的支持。希望这些建议对你有所帮助。<|im_end|>\n<|im_start|>user\n请问我叫什么名字?<|im_end|>\n<|im_start|>assistant\n" } ], "max_tokens":256, "top_p": 0.85, "n": 10, "logprobs": true, "stop": "<|im_end|>" }' curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "model": "qwen-72b", "messages": [ { "role": "user", "content": "请给我5条人生建议?" } ], "max_tokens":128 }' http://127.0.0.1:1025/v1/chat/completions # 流式 curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "model": "gpt-3.5-turbo-16k", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "Hello!" } ], "stream": true }' http://127.0.0.1:1025/v1/chat/completions # 返回结果 data: {"id":"554","object":"chat.completion.chunk","created":1715064985,"model":"qwen1.5-14b","choices":[{"index":0,"delta":{"role":"assistant","content":"节点"},"finish_reason":null}]} curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "model": "baichuan2-7b", "messages": [ { "role": "user", "content": "保持健康的方法" } ], "top_p": 0.85, "max_tokens":128 }' http://127.0.0.1:1025/v1/chat/completions curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "model": "qwen-72b", "messages": [ { "role": "user", "content": "保持健康的方法" } ], "stream": true }' http://127.0.0.1:1025/v1/chat/completions ``` ### 返回结果 ``` { "id": "209", "object": "chat.completion", "created": 1715051228, "model": "qwen1.5-14b", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "\n你叫李聪明。这是我根据之前的对话信息得知的。\nuser\n" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 277, "completion_tokens": 25, "total_tokens": 302 } } ``` ### baichuan2 ``` curl "http://127.0.0.1:1025/v1/chat/completions" \ -H "Content-Type: application/json" \ -d '{ "model": "baichuan2-7b", "messages": [ { "role": "user", "content": "光的三原色是什么" } ], "max_tokens":256, "top_p": 0.85, "n": 10, "logprobs": true }' ``` ## vLLM - https://github.com/vllm-project/vllm/blob/main/examples/api_client.py - https://github.com/vllm-project/vllm/blob/main/vllm/entrypoints/api_server.py 此API服务仅用于演示AsyncEngine的使用和简单的性能基准测试。它不打算用于生产使用。 对于生产使用,我们建议使用我们的OpenAI兼容服务。 - 推荐:https://github.com/vllm-project/vllm/blob/main/vllm/entrypoints/openai/api_server.py ``` curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "prompt": "保持健康的方法", "n": 5, "temperature": 0.0, "max_tokens": 64 }' http://127.0.0.1:1025/generate ``` ## tgi - https://huggingface.github.io/text-generation-inference/ ``` { "inputs": "My name is Olivier and I", "parameters": { "best_of": 1, "decoder_input_details": false, "details": true, "do_sample": true, "frequency_penalty": 0.1, "grammar": null, "max_new_tokens": 20, "repetition_penalty": 1.03, "return_full_text": false, "seed": null, "stop": [ "photographer" ], "temperature": 0.5, "top_k": 10, "top_n_tokens": 5, "top_p": 0.95, "truncate": null, "typical_p": 0.95, "watermark": true } } ``` ``` curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "inputs": "如何才能拥有性感的身材?", "parameters": { "do_sample": true, "frequency_penalty": 0.1, "temperature": 0.5, "top_k": 10, "top_n_tokens": 5, "max_new_tokens": 256 } }' http://127.0.0.1:1025/generate # 流式输出 curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "inputs": "如何才能拥有性感的身材?", "parameters": { "max_new_tokens": 50 } }' http://127.0.0.1:1025/generate_stream ``` ## triton ``` curl "http://127.0.0.1:1025/v2" ``` ## MindIE-service curl "http://127.0.0.1:1025/v1/models" ``` curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{ "inputs": "保持健康的方法", "parameters": { "best_of": 1, "decoder_input_details": true, "details": true, "do_sample": true, "max_new_tokens": 64, "repetition_penalty": 1.03, "return_full_text": false, "seed": null, "stop": [ "photographer" ], "temperature": 0.5, "top_n_tokens": 5, "top_p": 0.95, "truncate": null, "typical_p": 0.95, "watermark": true }, "stream": false}' http://127.0.0.1:1025/generate ``` ================================================ FILE: llm-localization/ascend/mindie/model-test.md ================================================ # ModelTest README ModelTest为大模型的性能和精度提供测试功能。 目前支持: 1. NPU,PA场景,性能/精度测试,float16 2. GPU,FA场景,精度测试,float16 功能: 1. 性能测试:指定batch,指定输入输出长度的e2e性能、吞吐,首Token以及非首Token性能,吞吐。 2. 精度测试:CEval, MMLU, BoolQ, HumanEval下游数据集 PA模型支持: 1. Llama (Llama-7B, Llama-13B, Llama-65B, Llama2-7B, Llama2-13B, Llama2-70B) 2. Starcoder-15.5B 3. Chatglm2-6B 4. CodegeeX2-6B 5. Baichuan2 (Baichuan2-7B, Baichuan2-13B) 6. Qwen (Qwen-14B, Qwen-72B) 7. Aquila (Aquila-7B) 8. Deepseek (Deepseek16B) 9. Mixtral (Mixtral8 * 7B) 10. Bloom-7B 11. Baichuan1 (Baichuan1-7B, Baichuan1-13B) 12. CodeLlama (CodeLlama-13B) 13. Yi (Yi-6B-200K, Yi-34B) 14. Chinese Alpaca (Chinese-Alpaca-13B) # 使用说明 ### 环境变量 ```shell # source cann环境变量 source /usr/local/Ascend/ascend-toolkit/set_env.sh # source 加速库环境变量 source /usr/local/Ascend/atb/set_env.sh # source 模型仓tar包解压出来后的环境变量 source set_env.sh # 设置ATB_TESTDATA环境变量 export ATB_TESTDATA="[path]" # 用于存放测试结果的路径 # 设置使用卡号 export ASCEND_RT_VISIBLE_DEVICES="[卡号]" # NPU场景,如"0,1,2,3,4,5,6,7" 或 export CUDA_VISIBLE_DEVICES="[卡号]" # GPU场景,如"0,1,2,3,4,5,6,7" ``` ### 安装python依赖 ``` pip install -r requirements.txt ``` ### 运行指令 ``` # NPU bash run.sh pa_fp16 [performance|full_CEval|full_MMLU|full_BoolQ|full_HumanEval] ([case_pair]) [batch_size] [model_name] ([use_refactor]) [weight_dir] [chip_num] ([max_position_embedding/max_sequence_length]) 或 # GPU bash run.sh fa [full_CEval|full_MMLU|full_BoolQ|full_HumanEval] [batch_size] [model_name] ([use_refactor]) [weight_dir] [chip_num] 说明: 1. case_pair只在performance场景下接受输入,接收一组或多组输入,格式为[[seq_in_1,seq_out_1],...,[seq_in_n,seq_out_n]], 如[[256,256],[512,512]] 2. model_name: Llama-65B, Llama2-7B, Llama2-13B, Llama2-70B: llama CodeLlama-13B, Chinese-Alpaca-13B, Yi-6B-200K, Yi-34B: llama Starcoder-15.5B: starcoder Chatglm2-6B: chatglm2_6b CodegeeX2-6B: codegeex2_6b Baichuan2-7B: baichuan2_7b Baichuan2-13B: baichuan2_13b Qwen-14b, Qwen-72b: qwen Aquila-7B: aquila_7b Deepseek16B: deepseek Mixtral8 * 7B: mixtral Bloom-7B: bloom_7b Baichuan1-7B: baichuan2_7b Baichuan1-13B: baichuan2_13b 3. 当model_name为llama时,须指定use_refactor为True或者False(统一使用True) 4. weight_dir: 权重路径 5. chip_num: 使用的卡数 6. max_position_embedding: 可选参数,不传入则使用config中的默认配置 7. 运行完成后,会在控制台末尾呈现保存数据的文件夹 举例: 1. 测试Llama-70B在8卡[512, 512]场景下,16 batch的性能,使用归一代码 bash run.sh pa_fp16 performance [[512,512]] 16 llama True /path 8 1. 测试Starcoder-15.5B在8卡1 batch下游数据集BoolQ bash run.sh pa_fp16 full_BoolQ 1 starcoder /path 8 ``` ## startcoder 特别运行操作说明 - 对于300I DUO设置环境变量,修改core/starcoder.py中prepare_environ函数。 ```shell os.environ['ATB_LAUNCH_KERNEL_WITH_TILING'] = "1" os.environ['LCCL_ENABLE_FALLBACK'] = "0" ``` ## baichuan2-13b 特别运行操作说明 - 对于300I DUO设置环境变量,修改core/baichuan2_13b_test.py中prepare_environ函数。 ```shell os.environ['ATB_OPERATION_EXECUTE_ASYNC'] = "0" os.environ['TASK_QUEUE_ENABLE'] = "0" `` ================================================ FILE: llm-localization/ascend/mindie/script/model-test.py ================================================ import csv import sys import glob import json import logging import math import os import re import shutil import time import argparse import ast import copy import importlib from datetime import datetime, timedelta, timezone from importlib import reload from pathlib import Path import torch import torch.nn.functional as F try: import torch_npu except ModuleNotFoundError: pass import numpy as np import pandas as pd import transformers from transformers import AutoModelForCausalLM, AutoTokenizer, AutoModel from thefuzz import process from tqdm import tqdm try: ATB_SPEED_HOME_PATH = os.environ.get("ATB_SPEED_HOME_PATH") sys.path.append(os.path.join(ATB_SPEED_HOME_PATH, "../..")) sys.path.append(ATB_SPEED_HOME_PATH) from atb_llm.utils import env from atb_llm.utils.cpu_binding import NpuHbmInfo from examples.server.cache import CacheConfig, CacheManager, ModelConfig from examples.server.generate import decode_token, generate_req from examples.server.request import request_from_text, request_from_token from examples.run_pa import PARunner except TypeError: pass from .human_eval import evaluate_functional_correctness QA_PRIMER = """Q: What is human life expectancy in the United States? A: Human life expectancy in the United States is 78 years. Q: Who was president of the United States in 1955? A: Dwight D. Eisenhower was president of the United States in 1955. Q: Which party did he belong to? A: He belonged to the Republican Party. Q: What is the square root of banana? A: I have no comment. Q: How does a telescope work? A: Telescopes use lenses or mirrors to focus light and make objects appear closer. Q: Where were the 1992 Olympics held? A: The 1992 Olympics were held in Barcelona, Spain.\n\nQ: """ UTILS_CODE_MARKER = " def greedy_search(\n" UTILS_CODE_INSERTED_PART_1 = """ import os import time if os.environ.get('test_mode') != '': tensor_folder = os.environ.get('tensor_folder') if tensor_folder is not None: os.makedirs(tensor_folder, exist_ok=True) if not os.path.exists(tensor_folder): raise RuntimeError(f"folder {tensor_folder} create fail") else: raise RuntimeError(f"tensor_folder env not exist") cnt = 0 first_token_time = 0 non_first_token_time = 0 """ UTILS_CODE_INSERTED_PART_2 = """ getattr(torch, os.environ.get('core_type')).synchronize() forward_start_time = time.time() """ UTILS_CODE_INSERTED_PART_3 = """ if os.environ.get('test_mode') == 'simplified': tensor_folder = os.environ.get('tensor_folder') if torch.distributed.get_rank() == 0: torch.save(next_token_logits.cpu(), f"{tensor_folder}/logits_{cnt}.pth") torch.save(next_tokens.cpu(), f"{tensor_folder}/tokens_{cnt}.pth") """ UTILS_CODE_INSERTED_PART_4 = """ getattr(torch, os.environ.get('core_type')).synchronize() forward_end_time = time.time() if cnt != 0: non_first_token_time += (forward_end_time - forward_start_time) else: first_token_time = forward_end_time - forward_start_time cnt += 1 if not torch.distributed.is_initialized() or torch.distributed.get_rank() == 0: first_token_time_tensor = torch.tensor([first_token_time]) non_first_token_time_tensor = torch.tensor([non_first_token_time]) torch.save(first_token_time_tensor.cpu(), f"{tensor_folder}/first_token_time.pth") torch.save(non_first_token_time_tensor.cpu(), f"{tensor_folder}/non_first_token_time.pth") """ UTILS_CODE_INSERTED_MARKER = " import os\n" ATB_HOME_PATH = os.environ.get("ATB_HOME_PATH") ATB_TESTDATA_PATH = os.environ.get("ATB_TESTDATA") soc_version_map = {-1: "unknown soc version", 100: "910PremiumA", 101: "910ProA", 102: "910A", 103: "910ProB", 104: "910B", 200: "310P1", 201: "310P2", 202: "310P3", 203: "310P4", 220: "910B1", 221: "910B2", 222: "910B3", 223: "910B4", 240: "310B1", 241: "310B2", 242: "310B3", 250: "910C1", 251: "910C2", 252: "910C3", 253: "910C4" } communication_map = {"NPU": "hccl", "GPU": "nccl"} dtype_map = {"bf16": torch.bfloat16, "fp16": torch.float16} core_map = {"NPU": "npu", "GPU": "cuda"} prompt_map = {"GSM8K": "", "TruthfulQA": QA_PRIMER} question_num = {"GSM8K": 11, "TruthfulQA": 12} CEval_0_shot = {"chatglm6b"} logging.basicConfig(level=logging.DEBUG) class ModelTest: def __init__(self, model_type, data_type, test_mode, model_name, data_dir, dataset_name, batch_size, device_id, result_dir, log_dir, hardware_type, case_pair, weight_dir, use_refactor, max_position_embedding) -> None: self.model_type = model_type self.data_type = data_type self.test_mode = test_mode self.model_name = model_name self.script_path = os.path.dirname(os.path.abspath(__file__)) self.data_dir = data_dir self.dataset_name = dataset_name self.batch_size = batch_size self.device_id = device_id self.result_dir = result_dir self.log_dir = log_dir self.hardware_type = hardware_type self.case_pair = ast.literal_eval(case_pair) if case_pair != "[]" else [[256, 256], [512, 512], [1024, 1024], [2048, 2048]] self.weight_dir = weight_dir self.use_refactor = use_refactor self.max_position_embedding = max_position_embedding self.core_type = core_map[self.hardware_type] if hardware_type in core_map.keys() else "npu" self.is_format_nz = False self.quantize = None self.current_result_path = '' self.logger = self.__get_log("log") self.result_logger = self.__get_log("result") self.logger.info( "\nmodel_name: " + self.model_name + "\nmodel_type: " + self.model_type + "\ndata_type: " + self.data_type + "\ntest_mode: " + self.test_mode + "\ndata_dir: " + self.data_dir + "\ndataset_name: " + self.dataset_name + "\nbatch_size: " + str( self.batch_size) + "\nresult_dir: " + self.result_dir + "\nlog_dir: " + self.log_dir) @classmethod def create_instance(cls): args = get_args() test_instance = cls(*args) test_instance.run() def run(self): self.prepare_environ() self.__prepare_and_check() self.__run() self.__compare_results() self.clear() def get_chip_num(self): return 1 def set_fa_tokenizer_params(self): self.tokenizer_params = { 'revision': None, 'use_fast': True, 'padding_side': 'left', 'truncation_side': 'left', 'trust_remote_code': True } def get_model(self, hardware_type, model_type, data_type): pass def prepare_environ(self): pass def get_dataset_list(self): return ["GSM8K", "TruthfulQA", "MMLU", "CEval", "BoolQ"] def clear(self): os.unsetenv("test_mode") os.unsetenv("hardware_type") os.unsetenv("tensor_folder") def __prepare_and_check(self): max_csv_limit = sys.maxsize while True: try: csv.field_size_limit(max_csv_limit) break except OverflowError: max_csv_limit = int(max_csv_limit / 10) config_path = os.path.join(self.weight_dir, "config.json") with open(config_path, 'r') as f: config_data = json.load(f) if "quantize" in config_data: self.quantize = config_data["quantize"] if self.quantize: self.model_name += "_quant" csv_path = os.path.join(os.path.dirname(self.script_path), 'result', self.model_name, f"{self.model_type}_{self.data_type}_{self.quantize}_batch{self.batch_size}_{self.test_mode}_test_result_formatted.csv") else: csv_path = os.path.join(os.path.dirname(self.script_path), 'result', self.model_name, f"{self.model_type}_{self.data_type}_batch{self.batch_size}_{self.test_mode}_test_result_formatted.csv") self.data_dir = os.path.join(self.data_dir, self.model_name, "data") self.result_dir = os.path.join(self.result_dir, self.model_name, "results") self.log_dir = os.path.join(self.log_dir, self.model_name, "logs") os.makedirs(os.path.dirname(csv_path), exist_ok=True) with open(csv_path, 'w') as f: if self.test_mode == "performance": f.write("{:<15s}|{:<15s}|{:<15s}|{:<15s}|{:<15s}|{:<25s}|{:<25s}|{:<36s}|{:<25s}|{:<45s}|{:<35s}\n".format( "Model", "Batchsize", "In_seq", "Out_seq", "Total time(s)", "First token time(ms)", "Non-first token time(ms)", "Non-first token Throughout(Tokens/s)", "E2E Throughout(Tokens/s)", "Non-first token Throughout Average(Tokens/s)", "E2E Throughout Average(Tokens/s)" )) elif self.test_mode == "simplified": f.write("Standard: [1] KL loss <= 1e-3. [2] rate of KL loss > 1e-4 <= 0.5%.\n") f.write("{:<15s}|{:<15s}|{:<15s}|{:<15s}|{:<15s}|{:<15s}|{:<15s}\n".format( "Model", "Dataset", "Batchsize", "Logits Num", "Greatest KLL", "Error Rate", "Result" )) else: f.write("{:<15s}|{:<15s}|{:<15s}|{:<15s}|{:<15s}|{:<15s}\n".format( "Model", "Dataset", "Batchsize", "Golden", "NPU", "Result" )) if self.hardware_type == "NPU": reload(env) if self.model_type == "fa" and self.test_mode != "full": self.__patch_hf_transformers_utils() os.environ['test_mode'] = self.test_mode if self.test_mode == "full": self.dataset_list = self.get_dataset_list() if self.dataset_name not in self.dataset_list: self.logger.info(f"{self.model_name} not support {self.dataset_name}, please check") if self.test_mode != "performance": folder_path = f"{self.data_dir}/{self.hardware_type}/{self.dataset_name}/batch{self.batch_size}" if os.path.exists(folder_path): try: shutil.rmtree(folder_path) except Exception as e: self.logger.error(f"Error deleting folder {folder_path}: {e}") os.makedirs(folder_path, exist_ok=True) if not os.path.exists(folder_path): self.logger.error(f"folder {folder_path} create fail") raise RuntimeError(f"folder {folder_path} create fail") os.environ['LCCL_DETERMINISTIC'] = "1" os.environ['HCCL_DETERMINISTIC'] = "1" os.environ['core_type'] = self.core_type self.rank, self.local_rank, self.world_size = int(os.getenv("RANK", "0")), int(os.getenv("LOCAL_RANK", "0")), int(os.getenv("WORLD_SIZE", "1")) torch.manual_seed(1) self.device_type = self.__get_device_type() if self.hardware_type == "NPU": if ATB_HOME_PATH is None: self.logger.error("env ATB_HOME_PATH not exist, source atb set_env.sh") raise RuntimeError( "env ATB_HOME_PATH not exist, source atb set_env.sh") self.logger.info("ATB env get success.") if ATB_SPEED_HOME_PATH is None: self.logger.error("env ATB_SPEED_HOME_PATH not exist, source atb_speed set_env.sh") raise RuntimeError( "env ATB_SPEED_HOME_PATH not exist, source atb_speed set_env.sh") self.logger.info("ATB_SPEED env get success") if self.model_type == "fa": self.__npu_adapt() def __run(self): importlib.reload(transformers) if self.test_mode == "simplified" or self.test_mode == "full": self.__run_precision() elif self.test_mode == "performance": self.__run_performance() else: self.logger.error(self.test_mode + " test not support, only support performance, simplified and full") raise RuntimeError(f"{self.test_mode} test not support, only support performance, simplified and full") def __run_performance(self): self.logger.info("performance test start") performance_prompt = [ "Common sense questions and answers\n\nQuestion: How to learn a new language\nFactual answer:"] csv_results = [] folder_path = f"{self.data_dir}/{self.hardware_type}/batch{self.batch_size}" os.environ['tensor_folder'] = f"{folder_path}" os.makedirs(folder_path, exist_ok=True) if not os.path.exists(folder_path): self.logger.error(f"folder {folder_path} create fail") raise RuntimeError(f"folder {folder_path} create fail") def warmup(): self.logger.info("performance test warmup start") if self.model_type == "fa": warmup_input_ids = torch.randint(0, self.model.config.vocab_size, [self.batch_size, 2048], dtype=torch.int64) warmup_attention_mask = torch.ones((self.batch_size, 2048), dtype=torch.int64) inputs = self.tokenizer(performance_prompt * self.batch_size, return_tensors="pt", padding='max_length', max_length=2048) inputs["input_ids"] = warmup_input_ids inputs["attention_mask"] = warmup_attention_mask input_ids = inputs.input_ids.to(self.model.device) attention_mask = inputs.attention_mask.to(self.model.device) with torch.no_grad(): _ = self.model.generate( inputs=input_ids, attention_mask=attention_mask, max_new_tokens=4, eos_token_id=self.model.config.vocab_size * 2 ) else: pass self.logger.info("performance test warmup end") def run_performance_test(): non_first_token_throughput_total = 0 e2e_throughput_total = 0 for seq_len_in, seq_len_out in self.case_pair: self.logger.info("batch_size: " + str(self.batch_size) + ", seq_len_in: " + str(seq_len_in) + ", seq_len_out: " + str(seq_len_out)) if self.model_type == "fa": input_ids = torch.randint(0, self.model.config.vocab_size, [self.batch_size, seq_len_in], dtype=torch.int64) attention_mask = torch.ones((self.batch_size, seq_len_in), dtype=torch.int64) inputs = self.tokenizer(performance_prompt * self.batch_size, return_tensors="pt", padding='max_length', max_length=seq_len_in) inputs["input_ids"] = input_ids inputs["attention_mask"] = attention_mask input_ids = inputs.input_ids.to(self.model.device) attention_mask = inputs.attention_mask.to(self.model.device) with torch.no_grad(): getattr(torch, self.core_type).synchronize() e2e_start = time.time() generate_ids = self.model.generate(inputs=input_ids, attention_mask=attention_mask, min_new_tokens=seq_len_out, max_new_tokens=seq_len_out ) try: _ = self.tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False) except: _ = [ self.tokenizer.decode(output) for output in generate_ids[:, inputs["input_ids"].size(1):].tolist() ] getattr(torch, self.core_type).synchronize() e2e_end = time.time() e2e_time = e2e_end - e2e_start else: input_dict = { 'rank': self.rank, 'local_rank': self.local_rank, 'world_size': self.world_size, 'max_prefill_tokens': -1, 'block_size': 128, 'model_path': self.weight_dir, 'is_bf16': True if self.data_type == "bf16" else False, 'max_position_embeddings': self.max_position_embedding if self.max_position_embedding != -1 else seq_len_in + seq_len_out, 'max_batch_size': self.batch_size, 'use_refactor': self.use_refactor, 'max_input_length': seq_len_in, 'max_output_length': seq_len_out } pa_runner = PARunner(**input_dict) self.logger.info(str(self.rank) + f'pa_runner: {pa_runner}') pa_runner.warm_up() input_ids = torch.randint(0, pa_runner.model.config.vocab_size, [seq_len_in], dtype=torch.int64) _, _, e2e_time = pa_runner.infer("", self.batch_size, seq_len_out, True, [input_ids]) del pa_runner torch.npu.empty_cache() if self.rank == 0: if self.model_type == "fa": first_token_time_tensor = torch.load(f"{folder_path}/first_token_time.pth").cpu() first_token_time = first_token_time_tensor.item() non_first_token_time_tensor = torch.load(f"{folder_path}/non_first_token_time.pth").cpu() non_first_token_time = non_first_token_time_tensor.item() / (seq_len_out - 1) else: benchmark_csv = os.path.join(self.script_path, "../benchmark.csv") with open(benchmark_csv, newline='') as csvfile: csv_reader = csv.reader(csvfile) next(csv_reader) second_row = next(csv_reader) first_token_time = float(second_row[4]) / 1000 non_first_token_time = float(second_row[5]) / 1000 non_first_token_throughput = self.batch_size / non_first_token_time non_first_token_throughput_total += non_first_token_throughput e2e_throughput = self.batch_size * seq_len_out / e2e_time e2e_throughput_total += e2e_throughput self.logger.info( f"batch: {self.batch_size}, seq_len_in: {seq_len_in}, seq_len_out: {seq_len_out}, total_time: {e2e_time}, first_token_time: {first_token_time * 1000}," + f" non_first_token_time: {non_first_token_time * 1000}, non_first_token_throughput: {non_first_token_throughput}," + f" e2e_time: {e2e_time}, e2e_throughput: {e2e_throughput}") csv_results.append( [str(self.model_name).ljust(15), str(self.batch_size).ljust(15), str(seq_len_in).ljust(15), str(seq_len_out).ljust(15), str(round(e2e_time, 10)).ljust(15), str(round(first_token_time * 1000, 10)).ljust(25), str(round(non_first_token_time * 1000, 10)).ljust(25), str(round(non_first_token_throughput, 10)).ljust(36), str(round(e2e_throughput, 10)).ljust(25)]) if self.rank == 0: non_first_token_throughput_average = non_first_token_throughput_total / len(self.case_pair) e2e_throughput_average = e2e_throughput_total / len(self.case_pair) self.logger.info( f"batch: {self.batch_size}, non_first_token_throughput_total: {non_first_token_throughput_total}, non_first_token_throughput_average:" + f" {non_first_token_throughput_average}, e2e_throughput_total: {e2e_throughput_total}, e2e_throughput_average: {e2e_throughput_average}") csv_results[len(self.case_pair) - 1].extend( [str(round(non_first_token_throughput_average, 10)).ljust(45), str(round(e2e_throughput_average, 10)).ljust(35)]) folder_name = self.model_name csv_name = self.model_type + "_" + self.data_type + "_" + self.test_mode + "_batch" + str(self.batch_size) + "_test_result.csv" if self.quantize: csv_name = self.model_type + "_" + self.data_type + "_" + self.quantize + "_batch" + str(self.batch_size) + "_" + self.test_mode + "_test_result.csv" csv_formatted_name = self.model_type + "_" + self.data_type + "_" + self.quantize + "_batch" + str(self.batch_size) + "_" + self.test_mode + "_test_result_formatted.csv" else: csv_name = self.model_type + "_" + self.data_type + "_batch" + str(self.batch_size) + "_" + self.test_mode + "_test_result.csv" csv_formatted_name = self.model_type + "_" + self.data_type + "_batch" + str(self.batch_size) + "_" + self.test_mode + "_test_result_formatted.csv" csv_performance_path = os.path.join(self.script_path, "../result", folder_name, csv_name) csv_performance_formatted_path = os.path.join(self.script_path, "../result", folder_name, csv_formatted_name) if not os.path.exists(csv_performance_formatted_path): self.logger.warning("performance result csv formatted file not exist, skip recording results") raise RuntimeError(f"csv result formatted file not exist") with open(csv_performance_formatted_path, 'a', newline='') as csv_file: csv_writer = csv.writer(csv_file, delimiter='|') for csv_result in csv_results: csv_writer.writerow(csv_result) csv_results.insert(0, ["Model", "Batchsize", "In_seq", "Out_seq", "Total time(s)", "First token time(ms)", "Non-first token time(ms)", "Non-first token Throughout(Tokens/s)", "Throughout(Tokens/s)", "Non-first token Throughout Average(Tokens/s)", "E2E Throughout Average(Tokens/s)"]) df = pd.DataFrame(csv_results) df.to_csv(csv_performance_path, index=False, header=False) self.logger.info(self.model_name + " " + " batch" + str( self.batch_size) + " result saved in " + csv_performance_path) self.logger.info(self.model_name + " " + " batch" + str( self.batch_size) + " formatted result saved in " + csv_performance_formatted_path) warmup() run_performance_test() self.logger.info("performance test end") def __run_precision(self): self.logger.info("precision test start") if self.hardware_type == "NPU": input_dict = { 'rank': self.rank, 'local_rank': self.local_rank, 'world_size': self.world_size, 'max_prefill_tokens': -1, 'block_size': 128, 'model_path': self.weight_dir, 'is_bf16': True if self.data_type == "bf16" else False, 'max_position_embeddings': self.max_position_embedding if self.max_position_embedding != -1 else None, 'max_batch_size': self.batch_size, 'use_refactor': self.use_refactor, 'max_input_length': 2048, 'max_output_length': 512, } self.pa_runner = PARunner(**input_dict) self.logger.info(str(self.rank) + f'pa_runner: {self.pa_runner}') self.pa_runner.warm_up() else: self.tokenizer_params = {} self.set_fa_tokenizer_params() self.tokenizer = self.get_fa_tokenizer(**self.tokenizer_params) if "starcoder" in self.model_name: self.tokenizer.pad_token = "[PAD]" if "llama" in self.model_name: self.tokenizer.pad_token_id = 0 if "chatglm6b" in self.model_name: self.model = AutoModel.from_pretrained(self.weight_dir, device_map="auto", torch_dtype=dtype_map[self.data_type], trust_remote_code=True) elif "qwen" in self.model_name: self.model = AutoModelForCausalLM.from_pretrained(self.weight_dir, device_map="auto", torch_dtype=dtype_map[self.data_type], trust_remote_code=True).to(torch.float16) else: self.model = AutoModelForCausalLM.from_pretrained(self.weight_dir, device_map="auto", torch_dtype=dtype_map[self.data_type], trust_remote_code=True) self.device = self.model.device if "baichuan" in self.model_name and self.model.config.vocab_size == 64000: self.tokenizer.pad_token_id = 0 if self.test_mode == "simplified": self.dataset_path = os.path.join(self.script_path, "../dataset/simplified", self.dataset_name + ".jsonl") self.__run_simplified_dataset() elif self.test_mode == "full": self.dataset_path = os.path.join(self.script_path, "../dataset/full", self.dataset_name) if self.dataset_name == 'CEval': if self.model_name in CEval_0_shot: self.dataset_path += "_0_shot" self.__run_full_dataset_ceval_0_shot() else: self.dataset_path += "_5_shot" self.__run_full_dataset_ceval_5_shot() elif self.dataset_name == 'MMLU': self.__run_full_dataset_mmlu() elif self.dataset_name == 'GSM8K': self.__run_full_dataset_gsm8k() elif self.dataset_name == 'TruthfulQA': self.__run_full_dataset_truthfulqa() elif self.dataset_name == 'BoolQ': self.__run_full_dataset_boolq() elif self.dataset_name == 'HumanEval': self.__run_full_dataset_humaneval() else: self.logger.error(self.test_mode + " not support") raise RuntimeError(f"{self.test_mode} not support") self.logger.info("precision test end") def __run_simplified_dataset(self): if self.dataset_name not in prompt_map.keys(): self.logger.error(self.dataset_name + " not support") raise RuntimeError(f"{self.dataset_name} not support") with torch.no_grad(): dataset = [] with open(self.dataset_path) as file: for line in file: dataset.append(json.loads(line)) dataloader = torch.utils.data.DataLoader(dataset, batch_size=self.batch_size) epoch_id = 0 for batch in tqdm(dataloader): self.logger.info("current epoch: " + str(epoch_id)) folder_path = f"{self.data_dir}/{self.hardware_type}/{self.dataset_name}/batch{self.batch_size}" os.environ['tensor_folder'] = f"{folder_path}/{str(epoch_id)}" os.makedirs(folder_path, exist_ok=True) if not os.path.exists(folder_path): self.logger.error(f"folder {folder_path} create fail") raise RuntimeError(f"folder {folder_path} create fail") texts = batch["question"] try: prompt = prompt_map[self.dataset_name] except KeyError: self.logger.warning(f"data {self.dataset_name} has no specific prompt provided, leave empty") prompt = "" queries = [''.join([prompt, query]) for query in texts] if self.model_type == "fa": tokenizer_out = self.tokenizer(queries, padding=True, return_tensors="pt", truncation=True, max_length=2048).to(self.model.device) tokenizer_out_ids = tokenizer_out.input_ids.to(self.model.device) attention_mask = tokenizer_out.attention_mask.to(self.model.device) outputs = self.model.generate(inputs=tokenizer_out_ids, attention_mask=attention_mask, do_sample=False, max_new_tokens=1024) for idx in range(len(outputs)): output = outputs.tolist()[idx][len(tokenizer_out["input_ids"][idx]):] response = self.tokenizer.decode(output) if self.pa_runner.rank == 0: self.logger.info(response) else: req_list = [ request_from_text(queries[i], self.tokenizer, 1024, self.cache_config.block_size, req_idx=i) for i in range(len(queries))] generate_req(req_list, self.model, self.tokenizer, self.batch_size, 3072 * self.batch_size, 1024, self.cache_manager, self.rank) generate_text_list, token_num_list = decode_token(req_list, self.tokenizer) if self.rank == 0: self.logger.info(f'Question: {queries}') for i, generate_text in enumerate(generate_text_list): self.logger.info(f'Answer: {generate_text}') self.logger.info(f'Generate token num: {token_num_list[i]}') epoch_id += 1 def __run_full_dataset_ceval_0_shot(self): choices = ["A", "B", "C", "D"] if self.hardware_type == "NPU": choice_tokens = [self.pa_runner.tokenizer.encode(choice, add_special_tokens=False)[0] for choice in choices] else: choice_tokens = [self.tokenizer.encode(choice, add_special_tokens=False)[0] for choice in choices] extraction_prompt = '综上所述,ABCD中正确的选项是:' def build_prompt(text): return "[Round {}]\n\n问:{}\n\n答:".format(1, text) correct_total = 0 sum_total = 0 result_total = [] is_result = False if self.__get_rank() == 0: is_result = True with torch.no_grad(): for entry in glob.glob((Path(self.dataset_path) / "val/**/*.jsonl").as_posix(), recursive=True): correct = 0 dataset = [] with open(entry, encoding='utf-8') as file: for line in file: dataset.append(json.loads(line)) sum = len(dataset) dataloader = torch.utils.data.DataLoader(dataset, batch_size=self.batch_size) for batch in tqdm(dataloader): texts = batch["inputs_pretokenized"] queries = [build_prompt(query) for query in texts] if self.model_type == "fa": inputs = self.tokenizer(queries, padding=True, return_tensors="pt", truncation=True).to(0) outputs = self.model.generate(**inputs, do_sample=False, max_new_tokens=512) intermediate_outputs = [] for idx in range(len(outputs)): output = outputs.tolist()[idx][len(inputs["input_ids"][idx]):] response = self.tokenizer.decode(output) intermediate_outputs.append(response) answer_texts = [text + intermediate + "\n" + extraction_prompt for text, intermediate in zip(texts, intermediate_outputs)] input_tokens = [build_prompt(answer_text) for answer_text in answer_texts] inputs = self.tokenizer(input_tokens, padding=True, return_tensors="pt", truncation=True).to(0) outputs = self.model(**inputs) logits = outputs.logits[:, -1, :] logits = logits[:, choice_tokens] preds = logits.argmax(dim=-1) correct += (preds.cpu() == batch["label"]).sum().item() else: generate_text_list, _, _ = self.pa_runner.infer(queries, self.batch_size, 512, False) answer_texts = [text + intermediate + "\n" + extraction_prompt for text, intermediate in zip(texts, generate_text_list)] input_tokens = [build_prompt(answer_text) for answer_text in answer_texts] logits_save_folder = os.path.join(self.data_dir, self.hardware_type, self.dataset_name, f"batch{self.batch_size}") os.environ['ATB_LLM_LOGITS_SAVE_ENABLE'] = "1" os.environ['ATB_LLM_LOGITS_SAVE_FOLDER'] = logits_save_folder _, _, _ = self.pa_runner.infer(input_tokens, self.batch_size, 1, False) os.environ['ATB_LLM_LOGITS_SAVE_ENABLE'] = "0" if is_result: logits = torch.load(os.path.join(logits_save_folder, 'logits_0.pth')) logits = logits[:, choice_tokens] preds = logits.argmax(dim=-1) correct += (preds.cpu() == batch["label"]).sum().item() if is_result: filename = os.path.basename(entry) result = [filename, correct / sum, correct, sum] self.result_logger.debug(f"result:{result}") result_total.append(result) correct_total += correct sum_total += sum if is_result: total = ["total", correct_total / sum_total, correct_total, sum_total] self.result_logger.debug(f"total result:{total}") result_total.insert(0, total) if is_result: self.__save_result(result_total) def __run_full_dataset_ceval_5_shot(self): choices = ["A", "B", "C", "D"] SHOT = 5 def get_subject_mapping(): SUBJECT_MAPPING_PATH = os.path.join(self.dataset_path, "subject_mapping.json") with open(SUBJECT_MAPPING_PATH) as f: subject_mapping = json.load(f) return subject_mapping def load_csv_by_task_name(task_name, dataset_path): dev_df = pd.read_csv(os.path.join(dataset_path, "dev", task_name + "_dev.csv"), header=None)[:SHOT + 1] val_df = pd.read_csv(os.path.join(dataset_path, "val", task_name + "_val.csv"), header=None) dev_df = dev_df.iloc[1:, 1:] val_df = val_df.iloc[1:, 1:] return dev_df, val_df def format_subject(subject): l = subject.split("_") s = "" for entry in l: s += " " + entry return s def format_example(df, idx, include_answer=True): prompt = df.iloc[idx, 0] k = len(choices) for j in range(k): prompt += "\n{}. {}".format(choices[j], df.iloc[idx, j + 1]) prompt += "\nAnswer:" if include_answer: prompt += " {}\n\n".format(df.iloc[idx, k + 1]) return prompt def gen_prompt(train_df, subject, k=-1): prompt = "The following are multiple choice questions (with answers) about {}.\n\n".format(format_subject(subject)) if k == -1: k = train_df.shape[0] for i in range(k): prompt += format_example(train_df, i) return prompt correct_total = 0 sum_total = 0 result_total = [] is_result = False if self.__get_rank() == 0: is_result = True subject_mapping = get_subject_mapping() index = 1 for task_name in tqdm(subject_mapping): self.logger.info(f"dataset {index} start, task name: {task_name}") dev_df, val_df = load_csv_by_task_name(task_name, self.dataset_path) correct = 0 task_len = val_df.shape[0] for i in range(math.ceil(task_len / self.batch_size)): q_num = self.batch_size if (i + 1) * self.batch_size <= task_len else task_len - i * self.batch_size prompt_ends = [format_example(val_df, i * self.batch_size + j, include_answer=False) for j in range(q_num)] train_prompts = [gen_prompt(dev_df, task_name, SHOT)] * q_num prompt = [t + p for t, p in zip(train_prompts, prompt_ends)] labels = [val_df.iloc[i * self.batch_size + j, val_df.shape[1] - 1] for j in range(q_num)] prompts = [prpt.encode().decode(encoding="utf8") for prpt in prompt] if self.model_type == "fa": inputs = self.tokenizer(prompts, padding=True, return_tensors="pt", truncation=True).to(0) if "chatglm6b" in self.model_name: outputs = self.model.generate(**inputs, do_sample=False, max_new_tokens=20) else: tokenizer_out_ids = inputs.input_ids.to(0) attention_mask = inputs.attention_mask.to(0) outputs = self.model.generate(inputs=tokenizer_out_ids, attention_mask=attention_mask, do_sample=False, max_new_tokens=20) answers = [] for idx in range(len(outputs)): output = outputs.tolist()[idx][len(inputs["input_ids"][idx]):] response = self.tokenizer.decode(output) answers.append(response) else: generate_texts, token_nums, _ = self.pa_runner.infer(prompts, self.batch_size, 20, False) if len(prompts) == 1: generate_texts = [generate_texts[0]] for idx, generate_text in enumerate(generate_texts): if is_result: self.logger.debug(f'Question[{i * self.batch_size + idx}]: {prompts[idx]}') self.logger.debug(f'Answer[{i * self.batch_size + idx}]: {generate_text}') self.logger.debug(f'Generate[{i * self.batch_size + idx}] token num: {token_nums[idx]}') answers = None if len(generate_texts) > 0: answers = generate_texts answer_results = [answer.lstrip()[0] if answer else "-1" for answer in answers] is_correct = ["Correct" if answer_result == label else "Wrong" for answer_result, label in zip(answer_results, labels)] correct += is_correct.count("Correct") for idx in range(len(is_correct)): if is_result and is_correct[idx] != "Correct": self.logger.debug(f">>>原始题目 is : {prompts[idx]}") self.logger.debug(f">>>推理结果 is : {answer_results[idx]}") self.logger.debug(f">>>真实结果 is : {labels[idx]}") if is_result: result = [task_name, correct / task_len, correct, task_len] self.logger.info(f"dataset {index} finish, result:{result}") result_total.append(result) correct_total += correct sum_total += task_len index += 1 if is_result: total = ["total", correct_total / sum_total, correct_total, sum_total] self.result_logger.debug(f"total result:{total}") result_total.insert(0, total) self.__save_result(result_total) def __run_full_dataset_mmlu(self): choices = ["A", "B", "C", "D"] def format_example(query, answer): prompt = "The following is a multiple-choice question. Please choose the most suitable one among A, B, C and D as the answer to this question.\n\n" example = (prompt + query + "\n") for choice, ans in zip(choices, answer): example += f'{choice}. {ans}\n' return example def process_before_extraction(gen, choice_dict): for key, val in sorted(choice_dict.items(), key=lambda x: len(x[1]), reverse=True): pattern = re.compile(re.escape(val.rstrip(".")), re.IGNORECASE) gen = pattern.sub(key, gen) return gen def extract_choice_mmlu(gen, choice_list): res = re.search( r"(?:(?:[Cc]hoose)|(?:(?:[Aa]nswer|[Cc]hoice)(?![^ABCD]{0,20}?(?:n't|not))[^ABCD]{0,10}?\b(?:|is|:|be))\b)[^ABCD]{0,20}?\b(A|B|C|D)\b", gen, ) if res is None: res = re.search( r"\b(A|B|C|D)\b(?![^ABCD]{0,8}?(?:n't|not)[^ABCD]{0,5}?(?:correct|right))[^ABCD]{0,10}?\b(?:correct|right)\b", gen, ) if res is None: res = re.search(r"^(A|B|C|D)(?:\.|,|:|$)", gen) if res is None: res = re.search(r"(? max_false: MC1 = 1.0 else: MC1 = 0.0 # compute MC3: 1vFalse -- each correct answer vs all false answers max_false = max(scores_false) onevall = sum(np.array(scores_true) > max_false) / float(len(scores_true)) MC3 = onevall # compute MC2: normalized probability mass for correct answers probs_true = np.exp(scores_true) probs_false = np.exp(scores_false) probs_true = probs_true / (sum(probs_true) + sum(probs_false)) MC2 = sum(probs_true) result = [idx, MC1, MC2, MC3] return result device = self.model.device result_total = [] is_result = False if self.pa_runner.rank == 0: is_result = True with torch.no_grad(): frame = pd.read_csv((Path(self.dataset_path) / "TruthfulQA.csv").as_posix()) frame.dropna(axis=1, how='all', inplace=True) for idx in tqdm(frame.index): if pd.isnull(frame.loc[idx, INCORRECT_COL]): self.result_logger.debug("References missing for {0}!".format(idx)) continue if not len(frame.loc[idx, INCORRECT_COL]): self.result_logger.debug("References missing for {0}!".format(idx)) continue ref_best = format_best(frame.loc[idx, BEST_COL]) ref_true = split_multi_answer(frame.loc[idx, ANSWER_COL]) ref_false = split_multi_answer(frame.loc[idx, INCORRECT_COL]) scores_true = get_scorces(frame, idx, ref_true, device) scores_false = get_scorces(frame, idx, ref_false, device) result = MC_calcs(idx, scores_true, scores_false, ref_true, ref_best, is_result) result_total.append(result) if is_result: self.__save_result(result_total) def __run_full_dataset_boolq(self): sample_yes = "How can we learning machine learning: yes" sample_no = "How can we learning machine learning: no" if self.model_type == "fa": choice_tokens = [self.tokenizer([sample_yes], return_tensors="pt", max_length=2048, add_special_tokens=None).input_ids[0, -1].item(), self.tokenizer([sample_no], return_tensors="pt", max_length=2048, add_special_tokens=None).input_ids[0, -1].item()] else: choice_tokens = [self.pa_runner.tokenizer([sample_yes], return_tensors="pt", max_length=2048, add_special_tokens=False).input_ids[0, -1].item(), self.pa_runner.tokenizer([sample_no], return_tensors="pt", max_length=2048, add_special_tokens=False).input_ids[0, -1].item()] def build_prompt(title, text, passage): prompt = f"{title} -- {passage}\nQuestion: {text}?\nAnswer:" return prompt correct_total = 0 sum_total = 0 result_total = [] is_result = False if self.__get_rank() == 0: is_result = True with torch.no_grad(): for entry in tqdm(glob.glob((Path(self.dataset_path) / "*.jsonl").as_posix(), recursive=True), desc='global'): dataset = [] with open(entry, encoding='utf-8') as f: for line in f: line_json = json.loads(line) dataset.append(line_json) correct = 0 sum = len(dataset) dataloader = torch.utils.data.DataLoader(dataset, batch_size=self.batch_size) for batch in tqdm(dataloader): titles = batch["title"] texts = batch["question"] passages = batch["passage"] queries = [build_prompt(title, query, passage) for title, query, passage in zip(titles, texts, passages)] if self.model_type == "fa": inputs = self.tokenizer(queries, padding=True, return_tensors="pt", truncation=True).to(0) outputs = self.model(**inputs) logits = outputs.logits[:, -1, :] logits_softmax = F.log_softmax(logits.float(), dim=-1) logits_softmax = logits_softmax[:, choice_tokens] if is_result: for idx, ans in enumerate(batch['answer']): choice = (logits_softmax[idx, 0] > logits_softmax[idx, 1]).cpu() acc = choice == ans if acc: correct += 1 else: logits_save_folder = os.path.join(self.data_dir, self.hardware_type, self.dataset_name, f"batch{self.batch_size}") os.environ['ATB_LLM_LOGITS_SAVE_ENABLE'] = "1" os.environ['ATB_LLM_LOGITS_SAVE_FOLDER'] = logits_save_folder _, _, _ = self.pa_runner.infer(queries, self.batch_size, 1, False) os.environ['ATB_LLM_LOGITS_SAVE_ENABLE'] = "0" if is_result: logits = torch.load(os.path.join(logits_save_folder, 'logits_0.pth')) logits_softmax = F.log_softmax(logits.float(), dim=-1) logits_softmax = logits_softmax[:, choice_tokens] for idx, ans in enumerate(batch['answer']): choice = (logits_softmax[idx, 0] > logits_softmax[idx, 1]).cpu() acc = choice == ans if acc: correct += 1 if is_result: filename = os.path.basename(entry) result = [filename, correct / sum, correct, sum] self.result_logger.debug(f"result:{result}") result_total.append(result) correct_total += correct sum_total += sum if is_result: total = ["total", correct_total / sum_total, correct_total, sum_total] result_total.insert(0, total) if is_result: self.__save_result(result_total) def __run_full_dataset_humaneval(self): def cleanup_code(code: str) -> str: code_splits = code.split("\n") is_empty_line = False ind_empty_line = None for i, line in enumerate(code_splits): if len(line.strip()) > 0 and line[0] != ' ' and line[0] != '\t': is_empty_line = True ind_empty_line = i break if is_empty_line: code = "\n".join(code_splits[:ind_empty_line]) else: end_words = ["\ndef", "\nclass", "\n#", "\nassert", '\n"""', "\nprint", "\nif", "\n\n\n"] for w in end_words: if w in code: code = code[:code.rfind(w)] return code is_result = False if self.__get_rank() == 0: is_result = True with torch.no_grad(): for entry in tqdm(glob.glob((Path(self.dataset_path) / "*.jsonl").as_posix(), recursive=True), desc='global'): dataset = [] with open(entry, encoding='utf-8') as f: for line in f: line_json = json.loads(line) dataset.append(line_json) correct = 0 samples = [] dataloader = torch.utils.data.DataLoader(dataset, batch_size=self.batch_size) for batch in tqdm(dataloader): task_ids = [task_id.split('/')[1] for task_id in batch["task_id"]] queries = [prompt.strip() for prompt in batch["prompt"]] if self.model_type == "fa": inputs = self.tokenizer(queries, padding=True, return_tensors="pt", truncation=True).to(0) tokenizer_out_ids = inputs.input_ids.to(0) attention_mask = inputs.attention_mask.to(0) outputs = self.model.generate(inputs=tokenizer_out_ids, attention_mask=attention_mask, do_sample=False, max_new_tokens=512) if is_result: for idx, output in enumerate(outputs.tolist()): output = output[len(inputs["input_ids"][idx]):] response = self.tokenizer.decode(output) response_cleaned_up = cleanup_code(response) self.logger.info("response_cleaned_up: %s", response_cleaned_up) result = dict( task_id="HumanEval/" + task_ids[idx], completion=response_cleaned_up, ) samples += [result] else: generate_text_list, _, _ = self.pa_runner.infer(queries, self.batch_size, 512, True) generate_text_list = [cleanup_code(completion) for completion in generate_text_list] if is_result: self.logger.info("generate_text_list_cleaned_up: %s", generate_text_list) for idx, sample in enumerate(generate_text_list): result = dict( task_id="HumanEval/" + task_ids[idx], completion=sample, ) samples += [result] if is_result: self.__save_result(samples) if is_result: results = evaluate_functional_correctness(self.current_result_path, [1], 4, 3.0, self.script_path + "/../dataset/full/HumanEval/human-eval.jsonl") self.result_logger.debug(results) def __compare_results(self): if self.test_mode != "performance" and self.hardware_type == "NPU" and self.pa_runner.rank == 0: if self.test_mode == "simplified": self.__compare_simplified_dataset_results() elif self.test_mode == "full": dataset_list = self.get_dataset_list() if self.dataset_name in dataset_list: return self.__compare_full_dataset_results() else: self.logger.error(self.test_mode + " not supported") raise RuntimeError(f"{self.test_mode} not supported") def __compare_simplified_dataset_results(self): if not os.path.exists(f"{self.data_dir}/GPU"): self.logger.error(f"GPU golden data not exist, upload to data dir folder") raise RuntimeError( "GPU golden data not exist, upload to tensor data folder") folder_path = f"{self.result_dir}" os.makedirs(folder_path, exist_ok=True) if not os.path.exists(folder_path): self.logger.error(f"folder {folder_path} create fail") raise RuntimeError(f"result folder {folder_path} create fail") if self.dataset_name not in question_num.keys(): self.logger.error(self.dataset_name + " not supported") raise RuntimeError(f"{self.dataset_name} not supported") self.eos_token = [-1 for _ in range(question_num[self.dataset_name])] self.logger.info("---------------------" + self.dataset_name + " Batch " + str( self.batch_size) + " Tokens Result Compare Begins------------------------") self.__compare_results_helper("tokens") self.logger.info("---------------------" + self.dataset_name + " Batch " + str( self.batch_size) + " Tokens Result Compare Ends------------------------") self.logger.info("---------------------" + self.dataset_name + " Batch " + str( self.batch_size) + " Logits Result Compare Begins------------------------") self.__compare_results_helper("logits") self.logger.info("---------------------" + self.dataset_name + " Batch " + str( self.batch_size) + " Logits Result Compare Ends------------------------") def __compare_results_helper(self, type): error_1e4 = 0 error_1e3 = 0 total_tokens_checked = 0 total_logits_checked = 0 greatest_kll = 0 for epoch_id in range(math.ceil(question_num[self.dataset_name] / self.batch_size)): cnt = 0 while True: golden_path = f"{self.data_dir}/GPU/{self.dataset_name}/batch{self.batch_size}/{epoch_id}/{type}_{cnt}.pth" npu_path = f"{self.data_dir}/NPU/{self.dataset_name}/batch{self.batch_size}/{epoch_id}/{type}_{cnt}.pth" golden_file_exists = os.path.exists(golden_path) npu_file_exists = os.path.exists(npu_path) if not golden_file_exists and not npu_file_exists: self.result_logger.debug(self.dataset_name + " batch " + str(self.batch_size) + " epoch " + str( epoch_id) + " " + type + " compare finish, total " + str(cnt) + " " + type) break elif golden_file_exists and npu_file_exists: golden_results = torch.load(golden_path).cpu() npu_results = torch.load(npu_path).cpu() if type == "tokens": for i in range(len(golden_results)): total_tokens_checked += 1 if self.eos_token[self.batch_size * epoch_id + i] == -1 and ( npu_results[i] != golden_results[i] or npu_results[ i] == self.tokenizer.eos_token_id): self.eos_token[self.batch_size * epoch_id + i] = cnt self.result_logger.debug( self.dataset_name + " batch " + str(self.batch_size) + " epoch " + str( epoch_id) + " question " + str(self.batch_size * epoch_id + i) + " token No." + str( cnt) + " is the first different token or eos token, ignore checking the rest.\ngolden tokenId: " + str( golden_results[i]) + ", npu tokenId: " + str(npu_results[i])) elif type == "logits": split_golden_results = torch.split(golden_results, 1, dim=0) split_npu_results = torch.split(npu_results, 1, dim=0) for i in range(len(split_golden_results)): eos_token = self.eos_token[self.batch_size * epoch_id + i] if eos_token != -1 and cnt > eos_token: continue total_logits_checked += 1 golden_results_logsoftmax = torch.log_softmax(split_golden_results[i].float(), dim=-1) npu_results_logsoftmax = torch.log_softmax(split_npu_results[i].float(), dim=-1) kl_loss = torch.nn.KLDivLoss(log_target=True, reduction='sum') output = kl_loss(npu_results_logsoftmax, golden_results_logsoftmax) greatest_kll = output.item() if output.item() > greatest_kll else greatest_kll if (output > 0.0001): if (output > 0.001): error_1e3 += 1 error_1e4 += 1 self.result_logger.debug( "--------------------------------" + type + " Error Begins--------------------------------") self.result_logger.debug( self.dataset_name + " batch" + str(self.batch_size) + " epoch " + str( epoch_id) + " question " + str(self.batch_size * epoch_id + i) + " logits No." + str(cnt) + " fail, KL loss is: {:.6f}".format(output.item())) golden_logits_sorted = torch.sort(split_golden_results[i], descending=True) npu_logits_sorted = torch.sort(split_npu_results[i], descending=True) self.result_logger.debug( "golden logits: \n" + str(golden_logits_sorted[0]) + "\nnpu logits: \n" + str( npu_logits_sorted[0])) self.result_logger.debug( "golden index: \n" + str(golden_logits_sorted[1]) + "\nnpu index: \n" + str( npu_logits_sorted[1])) self.result_logger.debug( "--------------------------------" + type + " Error Ends--------------------------------") cnt += 1 else: self.result_logger.debug(self.dataset_name + " batch " + str(self.batch_size) + " epoch " + str( epoch_id) + " " + type + " size not equal") self.result_logger.debug(self.dataset_name + " batch " + str(self.batch_size) + " epoch " + str( epoch_id) + " " + type + " compare finish, total " + str(cnt) + " " + type) break if type == "tokens": self.result_logger.debug( self.dataset_name + " batch " + str(self.batch_size) + " finished check, total tokens num " + str( total_tokens_checked) + ", find " + str(len(self.eos_token) - self.eos_token.count(-1)) + " question responses have " + type + " mismatch") elif type == "logits": pass_rate = error_1e4 / total_logits_checked pass_result = "Pass" if pass_rate > 0.005 or error_1e3 > 0: pass_result = "Fail" self.result_logger.debug( self.dataset_name + " batch " + str(self.batch_size) + " finished check, total logits checked " + str( total_logits_checked) + ", " + str(error_1e4) + " 1e-4 " + type + " errors found, " + str( error_1e3) + " 1e-3 " + type + " errors found, 1e-4 error rate " + str(pass_rate)) csv_result = [str(self.model_name).ljust(15), str(self.dataset_name).ljust(15), str(self.batch_size).ljust(15), str(total_logits_checked).ljust(15), str(round(greatest_kll, 10)).ljust(15), str(round(pass_rate, 10)).ljust(15), str(pass_result).ljust(15)] csv_simplified_path = os.path.join(self.script_path, "../result", "simplified_test_result.csv") if not os.path.exists(csv_simplified_path): self.logger.warning("simplified dataset result csv file not exist, skip recording results") raise RuntimeError(f"csv result file not exist") with open(csv_simplified_path, 'a', newline='') as csv_simplified_file: csv_writer = csv.writer(csv_simplified_file, delimiter='|') csv_writer.writerow(csv_result) self.logger.info(self.model_name + " " + self.dataset_name + " batch" + str( self.batch_size) + " result saved in result/simplified_test_result.csv") def __compare_full_dataset_results(self): golden_name = '_'.join([self.model_name, self.dataset_name]) golden_path = '' for file_name in os.listdir(f"{self.data_dir}/GPU/{self.dataset_name}/batch{self.batch_size}"): if file_name.startswith(f"{golden_name}"): golden_path = os.path.join(f"{self.data_dir}/GPU/{self.dataset_name}/batch{self.batch_size}", file_name) break if not os.path.exists(f"{self.current_result_path}"): raise RuntimeError( "NPU test data not exist, An error occurred in the test") if not os.path.exists(f"{golden_path}"): raise RuntimeError( "GPU golden data not exist, upload to result dir folder") result_df = pd.read_csv(self.current_result_path, sep='|', skipinitialspace=True).rename( columns=lambda x: x.strip()) result_df = result_df.applymap(lambda x: x.strip() if isinstance(x, str) else x) golden_df = pd.read_csv(golden_path, sep='|', skipinitialspace=True).rename(columns=lambda x: x.strip()) golden_df = golden_df.applymap(lambda x: x.strip() if isinstance(x, str) else x) csv_result = [] if self.dataset_name == 'MMLU' or self.dataset_name == 'CEval' or self.dataset_name == 'GSM8K': result_total = result_df.loc[result_df['file_name'] == 'total', 'value'].values[0] golden_total = golden_df.loc[golden_df['file_name'] == 'total', 'value'].values[0] diff_val = golden_total - result_total pass_result = "Pass" if diff_val <= 0.1: self.result_logger.debug( f"{self.current_result_path} is pass({diff_val}%), golden:{golden_total}, test:{result_total}") else: pass_result = "Fail" self.result_logger.debug( f"{self.current_result_path} is failed({diff_val}%), golden:{golden_total}, test:{result_total}") csv_result = [str(self.model_name).ljust(15), str(self.dataset_name).ljust(15), str(self.batch_size).ljust(15), str(round(golden_total, 10)).ljust(15), str(round(result_total, 10)).ljust(15), str(pass_result).ljust(15)] elif self.dataset_name == 'TruthfulQA': if len(result_df) != len(golden_df): raise RuntimeError(f"result_df len:{len(result_df)}, golden_df len:{len(golden_df)}") result_MC1_sum = 0 result_MC2_sum = 0 golden_MC1_sum = 0 golden_MC2_sum = 0 pass_result = "Pass" for index, result_row in result_df.iterrows(): golden_row = golden_df.iloc[index] result_MC1_sum += result_row['MC1'] result_MC2_sum += result_row['MC2'] golden_MC1_sum += golden_row['MC1'] golden_MC2_sum += golden_row['MC2'] diff_MC1 = (golden_MC1_sum - result_MC1_sum) / len(result_df) diff_MC2 = (golden_MC2_sum - result_MC2_sum) / len(result_df) if ((diff_MC1 <= 0.1) and (diff_MC2 <= 0.1)): self.result_logger.debug( f"{self.current_result_path} is pass(MC1:{diff_MC1} MC2:{diff_MC2}), golden:{golden_MC2_sum / len(result_df)} , test:{result_MC2_sum / len(result_df)}") else: pass_result = "Fail" self.result_logger.debug( f"{self.current_result_path} is failed(MC1:{diff_MC1} MC2:{diff_MC2}), golden:{golden_MC2_sum / len(result_df)}, test:{result_MC2_sum / len(result_df)}") csv_result = [str(self.model_name).ljust(15), str(self.dataset_name).ljust(15), str(self.batch_size).ljust(15), str(round((golden_MC2_sum / len(result_df)), 10)).ljust(15), str(round((result_MC2_sum / len(result_df)), 10)).ljust(15), str(pass_result).ljust(15)] csv_full_path = os.path.join(self.script_path, "../result", "full_test_result.csv") if not os.path.exists(csv_full_path): self.logger.warning("full dataset result csv file not exist, skip recording results") raise RuntimeError(f"csv result file not exist") with open(csv_full_path, 'a', newline='') as csv_full_file: csv_writer = csv.writer(csv_full_file, delimiter='|') csv_writer.writerow(csv_result) self.logger.info(self.model_name + " " + self.dataset_name + " batch" + str( self.batch_size) + " result saved in result/full_test_result.csv") def __get_rank(self): if self.hardware_type == "GPU": return torch.cuda.current_device() else: return self.pa_runner.rank def __get_device_type(self): if self.hardware_type == "NPU": self.soc_version = torch_npu._C._npu_get_soc_version() if self.soc_version in (100, 101, 102, 200, 201, 202, 203): self.is_format_nz = True return soc_version_map.get(self.soc_version) elif self.hardware_type == "GPU": return "GPU" def __patch_hf_transformers_utils(self): transformers_path = transformers.__path__[0] transformers_utils_path = f"{transformers_path}/generation/utils.py" shutil.copy(transformers_utils_path, f"{transformers_path}/generation/utils_backup.py") with open(transformers_utils_path, "r") as utils_file: utils_content = utils_file.readlines() try: utils_content.index(UTILS_CODE_INSERTED_MARKER) except ValueError: try: insert_position = utils_content.index(UTILS_CODE_MARKER) except ValueError: self.logger.error("UTILS_CODE_MARKER not found in the transformers utils.py file.") raise RuntimeError("UTILS_CODE_MARKER not found in the transformers utils.py file.") utils_content.insert(insert_position + 234, UTILS_CODE_INSERTED_PART_4) utils_content.insert(insert_position + 203, UTILS_CODE_INSERTED_PART_3) utils_content.insert(insert_position + 154, UTILS_CODE_INSERTED_PART_2) utils_content.insert(insert_position + 153, UTILS_CODE_INSERTED_PART_1) with open(transformers_utils_path, "w") as utils_file: utils_file.writelines(utils_content) self.logger.info("transformers utils.py update success") return self.logger.warning("transformers utils.py not update. Please confirm it performs as you expect") def __setup_model_parallel(self): if self.hardware_type in communication_map: torch.distributed.init_process_group(communication_map[self.hardware_type]) else: self.logger.error("unsupported hardware type") raise RuntimeError("unsupported hardware type") self.logger.info(f"{communication_map[self.hardware_type]} distributed process init success.") if self.hardware_type == "NPU": self.logger.info(f"user npu:{self.rank}") torch_npu.npu.set_device(torch.device(f"npu:{self.rank}")) elif self.hardware_type == "GPU": self.logger.info(f"user gpu:{self.rank}") torch.cuda.set_device(self.rank) self.logger.info("Device Set Success!") def get_fa_tokenizer(self, **kwargs): return AutoTokenizer.from_pretrained(self.weight_dir, **kwargs) def __npu_adapt(self): if self.is_format_nz: for name, module in self.model.named_modules(): if isinstance(module, torch.nn.Linear): if name == 'lm_head': module.weight.data = torch.nn.parameter.Parameter(module.weight.data) module.weight.data = torch_npu.npu_format_cast(module.weight.data, 29) self.logger.info(f"current soc: {self.soc_version}({self.device_type}), cast NZ") else: self.logger.info(f"current soc: {self.soc_version}({self.device_type}), not cast NZ") def __save_result(self, result): def align_columns(df): max_widths = df.applymap(lambda x: len(str(x))).max() for col in df.columns: df[col] = df[col].apply(lambda x: str(x).ljust(max_widths[col])) return df def align_headers(df): max_widths = [max(len(str(col)), df[col].map(lambda x: len(str(x))).max()) for col in df.columns] headers = [col.ljust(max_widths[i]) for i, col in enumerate(df.columns)] df.columns = headers for i, row in enumerate(df.values): df.iloc[i] = [str(val).ljust(max_widths[j]) for j, val in enumerate(row)] return df now = datetime.now() date_str = now.strftime("%Y_%m_%d_%H_%M_%S") if self.quantize: result_name = "_".join([self.model_type, self.data_type, self.quantize, "batch" + str(self.batch_size), self.test_mode, self.dataset_name]) + '_test_result' else: result_name = "_".join([self.model_type, self.data_type, "batch" + str(self.batch_size), self.test_mode, self.dataset_name]) + '_test_result' if self.dataset_name == "HumanEval": result_name += ".jsonl" result_path = os.path.join(self.data_dir, self.hardware_type, self.dataset_name, f"batch{self.batch_size}", result_name) with open(result_path, 'wb') as fp: for x in result: fp.write((json.dumps(x) + "\n").encode('utf-8')) else: result_name += ".csv" result_path = os.path.join(self.data_dir, self.hardware_type, self.dataset_name, f"batch{self.batch_size}", result_name) if self.dataset_name == "TruthfulQA": df = pd.DataFrame(result, columns=['idx', 'MC1', 'MC2', 'MC3']) else: df = pd.DataFrame(result, columns=['file_name', 'value', 'correct', 'sum']) df = align_columns(df) df = align_headers(df) df.to_csv(result_path, index=False) self.logger.info(f"{self.dataset_name} result saved to: {result_path}") self.current_result_path = result_path def __get_log(self, type): if type == "log": folder_path = self.log_dir elif type == "result": folder_path = self.result_dir os.makedirs(folder_path, exist_ok=True) if not os.path.exists(folder_path): raise RuntimeError(f"{type} folder {folder_path} create fail") cst_timezone = timezone(timedelta(hours=8)) current_time = datetime.now(cst_timezone) formatted_datetime = current_time.strftime("%Y_%m_%d_%H_%M_%S") formatter = logging.Formatter('%(asctime)s - [%(levelname)s] - %(filename)s:%(lineno)d - %(message)s') streamer_handler = logging.StreamHandler() streamer_handler.setFormatter(formatter) file_handler = logging.FileHandler(os.path.join(folder_path, self.model_name + "_" + self.model_type + "_" + self.data_type + "_" + self.dataset_name + "_batch" + str(self.batch_size) + "_" + formatted_datetime + ".log")) file_handler.setFormatter(formatter) logger = logging.getLogger(type) if type == "log": logger.setLevel(logging.INFO) file_handler.setLevel(logging.INFO) streamer_handler.setLevel(logging.INFO) elif type == "result": logger.setLevel(logging.DEBUG) file_handler.setLevel(logging.DEBUG) streamer_handler.setLevel(logging.DEBUG) logger.addHandler(streamer_handler) logger.addHandler(file_handler) logger.propagate = False return logger def parse_args(): parser = argparse.ArgumentParser(description="Model precision test arguments") parser.add_argument( "--model_type", type=str, default='pa', choices=['fa', 'pa'], help="Specify which model type to test" ) parser.add_argument( "--data_type", type=str, default='fp16', choices=['fp16', 'bf16'], help="Specify which datat type to test" ) parser.add_argument( "--test_mode", type=str, default='performance', choices=['simplified', 'full', 'performance'], help="Specify the mode in which to run the test" ) parser.add_argument("--model_name", type=str, required=True, help="name of model") parser.add_argument("--weight_dir", type=str, required=True, help="path to model weight folder") parser.add_argument("--data_dir", type=str, help="path to save the tensor") parser.add_argument("--dataset_name", type=str, default="GSM8K", help="which dataset to run") parser.add_argument("--batch_size", type=int, default=1, help="batch size") parser.add_argument("--device_id", type=int, default=7, help="device id") parser.add_argument("--result_dir", type=str, help="path to save results") parser.add_argument("--log_dir", type=str, help="path to save logs") parser.add_argument("--hardware_type", type=str, default="NPU", help="current device type, GPU or NPU") parser.add_argument("--case_pair", type=str, default="[[256, 256], [512, 512], [1024, 1024], [2048, 2048]]", help="performance test pair") parser.add_argument("--use_refactor", type=str, default="True", help="specify whether llama model use refactor") parser.add_argument("--max_position_embeddings", type=int, help="specify whether llama model use refactor") return parser.parse_args() def get_args(): args = parse_args() base_path = ATB_TESTDATA_PATH test_type = "performance" if args.test_mode == "performance" else "precision" if ATB_TESTDATA_PATH is None: base_path = os.path.join(os.path.dirname(__file__), "../") if args.data_dir is None: data_dir = os.path.join(base_path, f"{test_type}_test", args.test_mode) else: data_dir = args.data_dir if args.result_dir is None: result_dir = os.path.join(base_path, f"{test_type}_test", args.test_mode) else: result_dir = args.result_dir if args.log_dir is None: log_dir = os.path.join(base_path, f"{test_type}_test", args.test_mode) else: log_dir = args.log_dir case_pair = args.case_pair if args.case_pair == "[]": case_pair = "[[256, 256], [512, 512], [1024, 1024], [2048, 2048]]" return [args.model_type, args.data_type, args.test_mode, args.model_name, data_dir, args.dataset_name, args.batch_size, args.device_id, result_dir, log_dir, args.hardware_type, case_pair, args.weight_dir, eval(args.use_refactor), args.max_position_embeddings] ================================================ FILE: llm-localization/ascend/mindie/script/run.sh ================================================ #!/bin/bash # Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # shellcheck disable=SC2148 SCRIPT_DIR=$(cd $(dirname $0); pwd) TESTS_DIR=$(cd $SCRIPT_DIR/core/; pwd) test_mode="performance" model_type="pa" model_name="" weight_dir="" data_type="fp16" hardware_type="NPU" chip_num=0 dataset="CEval" batch_size=0 case_pair="[]" use_refactor="True" max_position_embedding=-1 function fn_prepare() { if [ "$hardware_type" == "NPU" ]; then if [ -z "$ASCEND_HOME_PATH" ];then echo "env ASCEND_HOME_PATH not exists, fail" exit 0 fi if [ -z "$ATB_HOME_PATH" ];then echo "env ATB_HOME_PATH not exists, fail" exit 0 fi fi export INT8_FORMAT_NZ_ENABLE=1 export PYTHONPATH="${PYTHONPATH}:$(dirname "$(readlink -f "$0")")" export PYTHONPATH="${PYTHONPATH}:$(dirname "$(dirname "$(dirname "$(readlink -f "$0")")")")" IFS="_" read -ra parts <<< "$1" model_type="${parts[0]}" if [ "$model_type" == "pa" ]; then data_type="${parts[1]}" fi test_mode="$2" if ! [ "$test_mode" == "performance" ]; then read -ra parts <<< "$2" test_mode="${parts[0]}" dataset="${parts[1]}" fi if [ "$test_mode" == "performance" ]; then export ATB_LLM_BENCHMARK_ENABLE=1 export ATB_LLM_BENCHMARK_FILEPATH="${SCRIPT_DIR}/benchmark.csv" fi } function fn_run_single() { test_file="${model_name}_test.py" test_path="${TESTS_DIR}/${test_file}" if [[ ! -e "$test_path" ]];then echo "model test file $test_path is not found." exit 0 fi if [ "$chip_num" == 0 ]; then code_line=$(grep -A 1 "def get_chip_num(self):" "${test_path}" | tail -n 1) if [ -z "$code_line" ]; then echo "Warning: get_chip_num() not overwrite in '$test_file', use chip_num 1" chip_num=1 else chip_num=$(echo "$code_line" | awk -F 'return ' '{print $2}') if ! [[ "$chip_num" =~ ^[1-9]+$ ]]; then echo "Error: return value of get_chip_num() in '$test_file' is not a digit." exit 1 fi fi fi if [ "$hardware_type" == "NPU" ]; then if ! [ -n "$ASCEND_RT_VISIBLE_DEVICES" ]; then devices="" for ((i=0; i /dev/null; then hardware_type="GPU" echo "INFO: Detected NVIDIA GPU" else if command -v npu-smi info &> /dev/null; then echo "INFO: Detected Ascend NPU" else echo "Error: No GPU or NPU detected" exit 1 fi fi if [ $# -eq 0 ]; then echo "Error: require parameter. Please refer to README." exit 1 fi model_type=$1 case "$model_type" in fa|pa_fp16|pa_bf16) echo "INFO: current model_type: $model_type" ;; *) echo "ERROR: invalid model_type, only support fa, pa_fp16, pa_bf16" ;; esac test_modes=$2 case "$test_modes" in performance|simplified_GSM8K|simplified_TruthfulQA|full_CEval|full_GSM8K|full_MMLU|full_TruthfulQA|full_BoolQ|full_HumanEval) echo "INFO: current test_mode: $test_modes" ;; *) echo "ERROR: invalid test_mode, only support performance, simplified_GSM8K, simplified_TruthfulQA, \ full_CEval, full_GSM8K, full_MMLU, full_TruthfulQA, full_BoolQ, full_HumanEval" exit 1 ;; esac if [ "$test_modes" == "performance" ]; then case_pair=$3 shift fi batch_size=$3 model_name=$4 if [ "$model_name" == "llama" ]; then use_refactor=$5 shift fi weight_dir=$5 echo "INFO: current batch_size: $batch_size" echo "INFO: current model_name: $model_name" echo "INFO: current weight_dir: $weight_dir" fn_prepare "$model_type" "$test_modes" if ! [[ "$6" =~ ^[1-9]+$ ]]; then echo "Error: input chip_num is not a digit." exit 1 fi chip_num=$6 echo "INFO: use input chip_num $chip_num" if [ $# -ge 7 ]; then if ! [[ "$7" =~ ^[0-9]+$ ]]; then echo "Error: input max_position_embedding or max_seq_len is not a digit." exit 1 fi max_position_embedding=$7 echo "INFO: use input max_position_embedding or max_seq_len $max_position_embedding" fi fn_run_single } fn_main "$@" ================================================ FILE: llm-localization/ascend/mindie/性能调优.md ================================================ 910b4 llama-7b 10g KV CACHE Total Block Num = 160 Block Num = Ceil(输入Token数/Block Size)+Ceil(最大输出Token数/Block Size) 560/4 + 512/4 = 9 batch_size: 20 910B3 llama-7b 30g KV CACHE Total Block Num = 480 560/4 + 512/4 = 9 batch_size: 50 ================================================ FILE: llm-localization/ascend/mindie/日志分析.txt ================================================ tail -100f mindservice.log | grep "COMPLETED REQ ID" 2024-07-24 16:25:04.777655 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1236, 3 , 272 , 16 , 256 , 20 , 30 , 1 2024-07-24 16:25:05.234118 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1239, 3 , 271 , 15 , 256 , 20 , 29 , 2 2024-07-24 16:25:05.360007 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1262, 1 , 99 , 22 , 77 , 20 , 26 , 1 2024-07-24 16:25:05.571847 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1244, 2 , 234 , 22 , 212 , 20 , 26 , 1 2024-07-24 16:25:05.705152 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1241, 3 , 281 , 25 , 256 , 20 , 25 , 1 2024-07-24 16:25:06.538975 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1258, 2 , 145 , 16 , 129 , 20 , 27 , 2 2024-07-24 16:25:06.901611 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1274, 1 , 41 , 15 , 26 , 20 , 27 , 1 2024-07-24 16:25:07.724699 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1253, 2 , 195 , 13 , 182 , 20 , 29 , 1 2024-07-24 16:25:07.940994 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1277, 1 , 45 , 17 , 28 , 20 , 29 , 1 2024-07-24 16:25:08.764214 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1257, 2 , 201 , 17 , 184 , 20 , 31 , 1 2024-07-24 16:25:08.973185 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1280, 1 , 40 , 19 , 21 , 20 , 31 , 1 2024-07-24 16:25:10.494941 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1282, 1 , 56 , 25 , 31 , 20 , 33 , 1 2024-07-24 16:25:10.541398 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1250, 3 , 269 , 13 , 256 , 19 , 32 , 1 2024-07-24 16:25:13.150968 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1284, 1 , 82 , 28 , 54 , 20 , 40 , 1 2024-07-24 16:25:13.282448 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1259, 3 , 273 , 17 , 256 , 20 , 41 , 2 2024-07-24 16:25:13.913430 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1261, 3 , 273 , 17 , 256 , 20 , 38 , 1 2024-07-24 16:25:14.495745 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1263, 3 , 279 , 23 , 256 , 20 , 40 , 1 2024-07-24 16:25:14.717521 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1264, 3 , 268 , 12 , 256 , 20 , 38 , 2 2024-07-24 16:25:15.027415 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1266, 3 , 268 , 12 , 256 , 20 , 35 , 1 2024-07-24 16:25:15.521481 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1287, 1 , 61 , 16 , 45 , 20 , 34 , 1 2024-07-24 16:25:15.567090 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1267, 3 , 273 , 17 , 256 , 19 , 33 , 1 2024-07-24 16:25:16.039858 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1268, 3 , 272 , 16 , 256 , 20 , 33 , 1 2024-07-24 16:25:16.432710 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1269, 3 , 329 , 73 , 256 , 20 , 31 , 1 2024-07-24 16:25:17.082790 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1270, 3 , 263 , 16 , 247 , 20 , 30 , 1 2024-07-24 16:25:17.339481 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1289, 1 , 72 , 15 , 57 , 20 , 30 , 1 2024-07-24 16:25:17.993777 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1271, 3 , 270 , 14 , 256 , 20 , 31 , 1 2024-07-24 16:25:18.121696 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1273, 3 , 271 , 15 , 256 , 20 , 29 , 1 2024-07-24 16:25:18.248203 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1286, 1 , 116 , 17 , 99 , 20 , 27 , 1 2024-07-24 16:25:18.458886 1360 info ibis_request.cc:240] COMPLETED REQ ID: 1275, 3 , 280 , 24 , 256 , 20 , 27 , 1 ================================================ FILE: llm-localization/ascend/mindspore/MindSpore-note.md ================================================ Graph模式:静态图模式或者图模式,将神经网络模型编译成一整张图,然后下发执行。该模式利用图优化等技术提高运行性能,同时有助于规模部署和跨平台运行。 PyNative模式:动态图模式,将神经网络中的各个算子逐一下发执行,方便用户编写和调试神经网络模型。 二者的主要区别也十分的明显。 使用场景:Graph模式需要一开始就构建好网络结构,然后框架做整图优化和执行,比较适合网络固定没有变化,且需要高性能的场景。而PyNative模式逐行执行算子,支持单独求梯度。 网络执行:Graph模式和PyNative模式在执行相同的网络和算子时,精度效果是一致的。由于Graph模式运用了图优化、计算图整图下沉等技术,Graph模式执行网络的性能和效率更高。 代码调试:在脚本开发和网络流程调试中,推荐使用PyNative模式进行调试。在PyNative模式下,可以方便地设置断点,获取网络执行的中间结果,也可以通过pdb的方式对网络进行调试。而Graph模式无法设置断点,只能先指定算子进行打印,然后在网络执行完成后查看输出结果。 ================================================ FILE: llm-localization/ascend/mindspore/README.md ================================================ - https://gitee.com/mindspore/mindspore ``` import numpy as np import mindspore.context as context from mindspore import Tensor from mindspore.ops import functional as F context.set_context(mode=context.PYNATIVE_MODE, device_target="GPU") x = Tensor(np.ones([1,3,3,4]).astype(np.float32)) y = Tensor(np.ones([1,3,3,4]).astype(np.float32)) print(F.tensor_add(x, y)) ``` https://ms-release.obs.cn-north-4.myhuaweicloud.com/2.3.0rc1/MindSpore/unified/aarch64/mindspore-2.3.0rc1-cp39-cp39-linux_aarch64.whl ================================================ FILE: llm-localization/ascend/mindspore/bert.md ================================================ ## bert ``` pip install wikiextractor python -m wikiextractor.WikiExtractor -o -b ``` ================================================ FILE: llm-localization/ascend/mindspore/reference.md ================================================ - https://gitee.com/mindspore/mindspore - https://gitee.com/mindspore/mindformers - https://gitee.com/mindspore/mindformers.git - https://www.mindspore.cn/install - https://www.mindspore.cn/tutorials/zh-CN/r2.2/beginner/train.html ================================================ FILE: llm-localization/ascend/mindspore/镜像.md ================================================ - https://ascendhub.huawei.com/#/detail/ascend-mindspore ``` docker login -u 15708484031 ascendhub.huawei.com docker pull ascendhub.huawei.com/public-ascendhub/ascend-mindspore:23.0.RC2-centos7 ``` ``` chmod +x Ascend-docker-runtime_{version}_linux-{arch}.run ./Ascend-docker-runtime_{version}_linux-{arch}.run --install docker run -it -e ASCEND_VISIBLE_DEVICES=0 镜像id /bin/bash bash test_model.sh ``` ``` docker run -dt --name mindspore_env --restart=always --gpus all \ --network=host \ --shm-size 4G \ -v /home/guodong/workspace:/workspace \ -w /workspace \ ascendhub.huawei.com/public-ascendhub/ascend-mindspore:23.0.RC2-centos7 \ /bin/bash docker exec -it mindspore_env bash ``` ``` FROM ascendhub.huawei.com/public-ascendhub/ascend-mindspore:23.0.RC1-ubuntu18.04 USER root COPY ./glm0609 /home/chatglm6b COPY ./hccl_tools /home/hccl_tools COPY ./mindpet /home/mindpet COPY ./web_demo.gif /home/ WORKDIR /home RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple/ -U pip RUN pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple/ RUN wget https://sqlite.org/2019/sqlite-autoconf-3290000.tar.gz RUN tar zxvf sqlite-autoconf-3290000.tar.gz && cd sqlite-autoconf-3290000 && ./configure && make -j${proc} && make install RUN wget https://www.python.org/ftp/python/3.7.5/Python-3.7.5.tgz RUN tar xzvf Python-3.7.5.tgz && cd Python-3.7.5 && \ ./configure LDFLAGS="-L/usr/local/lib" CPPFLAGS="-I/usr/local/include" --prefix=/usr/local/python3.7.5 && \ make -j${proc} && \ make install RUN /usr/local/python3.7.5/bin/pip install torch transformers numpy sentencepiece ftfy regex tqdm \ pyyaml rouge_chinese nltk jieba datasets gradio==3.23.0 pandas openpyxl et-xmlfile mdtex2html ENV LC_ALL='C.UTF-8' ENV PYTHONPATH=/home/mindpet/:$PYTHONPATH ENV LD_PRELOAD=/usr/local/python3.7.5/lib/python3.7/site-packages/torch/lib/libgomp-d22c30c5.so.1 ``` ``` docker run -it -u root --ipc=host \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /var/log/npu/:/usr/slog \ swr.cn-south-1.myhuaweicloud.com/mindspore/mindspore-ascend:{tag} \ /bin/bash ``` ``` docker run -it --ipc=host \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \ -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \ -v /var/log/npu/:/usr/slog \ ascendhub.huawei.com/public-ascendhub/mindspore-modelzoo:{tag} \ /bin/bash ``` ``` docker run -itd --name mindspore_dev -u root --network=host --ipc=host \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /root/ChatGLM6B_MS_0613/huggingface-glm-6b:/home/huggingface-glm-6b \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \ -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \ -v /var/log/npu/:/usr/slog \ chatglm6b:v1 \ /bin/bash docker exec -it mindspore_dev bash ``` ## 安装(mac m1) ``` pip install https://ms-release.obs.cn-north-4.myhuaweicloud.com/2.2.0/MindSpore/cpu/aarch64/mindspore-2.2.0-cp39-cp39-macosx_11_0_arm64.whl --trusted-host ms-release.obs.cn-north-4.myhuaweicloud.com -i https://pypi.tuna.tsinghua.edu.cn/simple ``` ## mindformers(docker) ``` docker pull --platform=arm64 swr.cn-central-221.ovaijisuan.com/mindformers/mindformers0.8.0_mindspore2.2.0:aarch_20231025 ``` ``` # --device用于控制指定容器的运行NPU卡号和范围 # -v 用于映射容器外的目录 # --name 用于自定义容器名称 docker run -it -u root \ --ipc=host \ --network host \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /etc/localtime:/etc/localtime \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /var/log/npu/:/usr/slog \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ --name {请手动输入容器名称} \ swr.cn-central-221.ovaijisuan.com/mindformers/mindformers0.8.0_mindspore2.2.0:aarch_20231025 \ /bin/bash ``` ================================================ FILE: llm-localization/ascend/modellink/README.md ================================================ ``` docker pull --platform=arm64 swr.cn-central-221.ovaijisuan.com/dxy/pytorch2_1_0_kernels:PyTorch2.1.0-cann7.0.0.alpha003_py_3.9-euler_2.8.3-64GB ``` ``` docker run -it -u root \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \ -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \ -v /home/aicc:/home/ma-user/work/aicc \ --name pytorch_ma \ --entrypoint=/bin/bash \ swr.cn-central-221.ovaijisuan.com/dxy/pytorch2_1_0_kernels:PyTorch2.1.0-cann7.0.0.alpha003_py_3.9-euler_2.8.3-64GB ``` ``` docker start pytorch_ma docker exec -it pytorch_ma-0-3 /bin/bash ``` --network=host ``` docker rm -f pytorch_ma-0-3 docker run -it -u root --network=host \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \ -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \ -v /home/aicc:/home/ma-user/work/aicc \ --name pytorch_ma-0-3 \ --entrypoint=/bin/bash \ swr.cn-central-221.ovaijisuan.com/dxy/pytorch2_1_0_kernels:PyTorch2.1.0-cann7.0.0.alpha003_py_3.9-euler_2.8.3-64GB docker exec -it pytorch_ma-0-3 /bin/bash ``` ``` # https://mirror.ghproxy.com pip3 install --no-use-pep517 -e git+https://mirror.ghproxy.com/https://github.com/NVIDIA/Megatron-LM.git@23.05#egg=megatron-core ``` ================================================ FILE: llm-localization/ascend/modellink/dataset.md ================================================ - https://huggingface.co/docs/datasets/access - HuggingFace学习笔记--datasets的使用:https://blog.csdn.net/weixin_43863869/article/details/134653171 - Huggingface处理数据排除异常值:https://blog.csdn.net/qq_18555105/article/details/130291508 - HuggingFace数据集Datasets:https://baijiahao.baidu.com/s?id=1753227115689844799&wfr=spider&for=pc - Huggingface详细入门介绍之dataset库: https://zhuanlan.zhihu.com/p/554678463 ================================================ FILE: llm-localization/ascend/modellink/llm.md ================================================ ``` git clone https://gitee.com/ascend/ModelLink.git cd ModelLink mkdir logs mkdir dataset mkdir ckpt git clone https://gitee.com/ascend/AscendSpeed.git cd AscendSpeed pip install -r requirements.txt pip3 install -e . cd .. # 安装其余依赖库 pip install -r requirements.txt ``` ``` # 修改 ascend-toolkit 路径 source /usr/local/Ascend/ascend-toolkit/set_env.sh python tools/checkpoint/convert_ckpt.py \ --model-type GPT \ --loader llama2_hf \ --saver megatron \ --target-tensor-parallel-size 2 \ --load-dir /home/ma-user/work/aicc/model_from_hf/Baichuan2-7B-Chat/ \ --save-dir /home/ma-user/work/aicc/model_weights/Baichuan2-7B-v0.1-tp8-pp1/ \ --tokenizer-model /home/ma-user/work/aicc/model_from_hf/Baichuan2-7B/tokenizer.model \ --params-dtype bf16 \ --w-pack True ``` ================================================ FILE: llm-localization/ascend/modellink/qwen.md ================================================ ``` git clone https://gitee.com/ascend/ModelLink.git git clone https://github.com/NVIDIA/Megatron-LM.git cd Megatron-LM git checkout -f bcce6f cp -r megatron ../ModelLink/ cd .. cd ModelLink mkdir logs mkdir model_from_hf mkdir dataset mkdir ckpt ``` ``` # python3.8 conda create -n test python=3.8 conda activate test # 安装 torch 和 torch_npu pip install torch-2.1.0-cp38-cp38m-manylinux2014_aarch64.whl pip install torch_npu-2.1.0*-cp38-cp38m-linux_aarch64.whl pip install apex-0.1_ascend*-cp38-cp38m-linux_aarch64.whl # 安装加速库 git clone https://gitee.com/ascend/AscendSpeed.git cd AscendSpeed git checkout 224ae35e8fc96778f957029d1371ddb623452a50 pip install -r requirements.txt pip install -e . cd .. # 安装其余依赖库 pip install -r requirements.txt ``` ================================================ FILE: llm-localization/ascend/modellink/环境-20240521.md ================================================ ``` git lfs clone https://www.modelscope.cn/qwen/Qwen1.5-7B-Chat.git git lfs clone https://huggingface.co/Qwen/Qwen1.5-7B-Chat git lfs clone https://www.modelscope.cn/qwen/Qwen1.5-7B-Chat.git git lfs clone https://www.modelscope.cn/baichuan-inc/Baichuan2-7B-Chat.git git lfs clone https://www.modelscope.cn/baichuan-inc/Baichuan2-13B-Chat.git git lfs clone https://www.modelscope.cn/qwen/Qwen1.5-14B-Chat.git ``` - https://ascendhub.huawei.com/#/detail/ascend-mindspore ``` docker login -u 157xxx4031 ascendhub.huawei.com docker pull ascendhub.huawei.com/public-ascendhub/ascend-mindspore:23.0.0-A2-ubuntu18.04 ``` ``` docker commit -m="ascend-pytorch" -a="liguodong" 842da08d1061 harbor.guodong.io/ascend-pytorch:v1 docker save -o ascend-pytorch.tar harbor.guodong.io/ascend-pytorch:v1 scp -r ascend-pytorch.tar bms-dt-0009:/data/containerd/ scp -r /data/containerd/workspace/ bms-dt-0009:/data/containerd/ rsync -P --rsh=ssh -r /data/containerd/workspace/ bms-dt-0009:/data/containerd/ nohup scp -r /data/containerd/workspace/ bms-dt-0009:/data/containerd/ > output.log 2>&1 & ``` ``` -e ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \ docker rm -f pytorch_ubuntu_dev docker run -it -u root \ --name pytorch_ubuntu_dev \ --network host \ -e ASCEND_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \ -v /etc/localtime:/etc/localtime \ -v /var/log/npu/:/usr/slog \ -v /usr/bin/hccn_tool:/usr/bin/hccn_tool \ -v /data/containerd/workspace/:/workspace \ ascendhub.huawei.com/public-ascendhub/ascend-mindspore:23.0.0-A2-ubuntu18.04 \ /bin/bash docker start pytorch_ubuntu_dev docker exec -it pytorch_ubuntu_dev bash ``` https://repo.anaconda.com/miniconda/Miniconda3-py39_24.4.0-0-Linux-aarch64.sh\ wget -c https://repo.anaconda.com/miniconda/Miniconda3-py39_24.4.0-0-Linux-aarch64.sh bash Miniconda3-py39_24.4.0-0-Linux-aarch64.sh -p /workspace/installs/conda conda init source ~/.bashrc export PATH=/root/miniconda3/bin:$PATH conda list conda create -n llm-dev python=3.9 conda activate llm-dev ``` docker exec -it pytorch_ubuntu_dev bash conda activate llm-dev source /usr/local/Ascend/ascend-toolkit/set_env.sh cd /workspace/code/stanford_alpaca ``` pip list | grep -E 'deepspeed|peft|torch|torch-npu|transformers|mindspore|mindformers|tqdm' ``` pip3 install torch==2.1.0 pip3 install pyyaml setuptools pip3 install torch-npu==2.1.0 pip3 install numpy attrs decorator psutil absl-py cloudpickle psutil scipy synr tornado source /usr/local/Ascend/ascend-toolkit/set_env.sh import torch import torch_npu x = torch.randn(2, 2).npu() y = torch.randn(2, 2).npu() z = x.mm(y) print(z) ``` /usr/local/Ascend find . -name libascend_hal.so ``` # >>> conda initialize >>> # !! Contents within this block are managed by 'conda init' !! __conda_setup="$('/root/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" if [ $? -eq 0 ]; then eval "$__conda_setup" else if [ -f "/root/miniconda3/etc/profile.d/conda.sh" ]; then . "/root/miniconda3/etc/profile.d/conda.sh" else export PATH="/workspace/installs/miniconda3/bin:$PATH" fi fi unset __conda_setup # <<< conda initialize <<< export PATH="/workspace/installs/miniconda3/bin:$PATH" ``` ---- ``` git clone https://github.com/tatsu-lab/stanford_alpaca.git # pip uninstall Xformers `ck_decoderF` is not supported because: device=npu (supported: {'cuda'}) attn_bias type is operator wasn't built - see `python -m xformers.info` for more info `ckF` is not supported because: device=npu (supported: {'cuda'}) operator wasn't built - see `python -m xformers.info` for more info raise NotImplementedError(msg) pip install accelerate -U pip install -r requirements.txt pip install deepspeed==0.14.1 删除utils.py中openai的代码。 --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'Qwen2DecoderLayer' alpaca_gpt4_data_zh_1k.json rm -rf /workspace/output/alpaca2/* torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Qwen1.5-7B-Chat/ \ --data_path /workspace/data/alpaca_gpt4_data_zh_5k.json \ --fp16 True \ --output_dir /workspace/output/alpaca2 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps=8 \ --num_train_epochs 1 \ --per_device_eval_batch_size 4 \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --deepspeed ds_config_zero3.json source /usr/local/Ascend/ascend-toolkit/set_env.sh conda activate llm-dev alpaca_gpt4_data_zh_1k.json torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Qwen1.5-14B-Chat/ \ --data_path ./alpaca_data_1k.json \ --fp16 True \ --output_dir /workspace/output/alpaca-qwen14 \ --num_train_epochs 1 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 4 \ --gradient_accumulation_steps 8 \ --gradient_checkpointing True \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --fsdp "full_shard offload auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'Qwen2DecoderLayer' ``` goodput 实际吞吐量 ``` /workspace/output/baichuan2 torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Baichuan2-7B-Chat \ --data_path ./alpaca_data_1k.json \ --fp16 True \ --output_dir /workspace/output/baichuan2 \ --num_train_epochs 1 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 4 \ --gradient_accumulation_steps 8 \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'DecoderLayer' ``` ---- ``` git clone https://gitee.com/ascend/apex.git git clone https://gitee.com/ascend/ModelLink.git git clone https://github.com/NVIDIA/Megatron-LM.git `` ================================================ FILE: llm-localization/ascend/modellink/环境安装.md ================================================ ## torch_npu - https://gitee.com/ascend/pytorch torch_npu(Ascend Adapter for PyTorch插件)使昇腾NPU可以适配PyTorch框架,为使用PyTorch框架的开发者提供昇腾AI处理器的超强算力。 2.1.0 版本: - https://gitee.com/ascend/pytorch/tree/v2.1.0/ 安装PyTorch ``` pip3 install torch==2.1.0 ``` 安装torch_npu依赖 ``` pip3 install pyyaml pip3 install setuptools ``` 安装torch_npu: 如需要保存安装日志,可在pip3 install命令后面加上参数 --log ,并对您指定的目录做好权限管控。 ``` pip3 install torch-npu==2.1.0.post3 --log /tmp/torch-npu.log ``` 运行以下命令初始化CANN环境变量。 ``` # Default path, change it if needed. source /usr/local/Ascend/ascend-toolkit/set_env.sh ``` 可以通过以下样例快速体验昇腾NPU。 ``` import torch import torch_npu x = torch.randn(2, 2).npu() y = torch.randn(2, 2).npu() z = x.mm(y) print(z) ``` ================================================ FILE: llm-localization/ascend/msmodelslim/README.md ================================================ - https://gitee.com/ascend/msit/tree/master/msmodelslim/msmodelslim/pytorch/llm_ptq ================================================ FILE: llm-localization/ascend/msmodelslim/llm_quant/baichuan2-w8a8.py ================================================ import logging from transformers import AutoTokenizer, AutoModelForCausalLM from msmodelslim.pytorch.llm_ptq.anti_outlier import AntiOutlierConfig, AntiOutlier from msmodelslim.pytorch.llm_ptq.llm_ptq_tools import Calibrator, QuantConfig import json import argparse def init_tokenizer(input_model_path:str): tokenizer = AutoTokenizer.from_pretrained( pretrained_model_name_or_path=input_model_path, # use_fast=False, # padding_side='left', trust_remote_code=True) return tokenizer def init_model(input_model_path:str): model = AutoModelForCausalLM.from_pretrained( pretrained_model_name_or_path=input_model_path, trust_remote_code=True).float().cpu() model = model.half().npu() # 如果需要使用npu进行量化 return model # 获取校准数据函数定义 def get_calib_dataset( auto_tokenizer, calib_list, device="cpu"): # 如果需要使用npu进行量化, device="npu:0"。使用cpu,device="cpu" calib_dataset = [] for calib_data in calib_list: inputs = auto_tokenizer(calib_data, return_tensors='pt') calib_dataset.append([ inputs.data['input_ids'].to(device), inputs.data['attention_mask'].to(device) ]) return calib_dataset def load_dataset(calib_set_path = "./calib_set.json"): calib_set = json.load(open(calib_set_path, "r")) return calib_set def parse_arguments(): parser = argparse.ArgumentParser() parser.add_argument('--input_model_path', type=str, help="input model and tokenizer path") parser.add_argument('--output_model_path', type=str, help="output model and tokenizer path") parser.add_argument('--calib_set_path', type=str, default="./calib_set.json", help="calib set path") return parser.parse_args() def disable_quant_module(input_model_path:str): config = json.load(open(input_model_path+"/config.json", "r")) num_hidden_layers = config.get("num_hidden_layers", 0) disable_names = [] disable_idx_lst = list(range(num_hidden_layers)) for layer_index in disable_idx_lst: down_proj_name = "model.layers.{}.mlp.down_proj".format(layer_index) disable_names.append(down_proj_name) # 仅7B禁用 # BAICHUAN_LAYERS = 32 if int(num_hidden_layers) == 32: disable_last_linear = False else: # 13B disable_last_linear = True print("disable_last_linear: ", disable_last_linear, "disable_names: \n", disable_names) return disable_names, disable_last_linear if __name__ == '__main__': args = parse_arguments() tokenizer = init_tokenizer(input_model_path=args.input_model_path) model = init_model(input_model_path=args.input_model_path) calib_set = load_dataset(calib_set_path=args.calib_set_path) dataset_calib = get_calib_dataset(tokenizer, calib_set, device="npu:0") # 对于linear算子中的激活值如果有表示范围过大,或者“尖刺”的异常值过多, # 需要使用anti outleir功能,使用方法如下 logging.info("===============start AntiOutlier==============") anti_config = AntiOutlierConfig( w_bit=8, a_bit=8, anti_method="m2", #dev_type="cpu", dev_type="npu", dev_id=0 ) # dev_type="npu", dev_id=0 如果需要使用npu进行量化。 anti_outlier = AntiOutlier(model, calib_data=dataset_calib, cfg=anti_config, norm_class_name="RMSNorm") anti_outlier.process() #下面是回退层的设置,因为w8a8的对激活值也进行了量化,会有部分网络层对激活值的表示 #范围较为敏感所以需要回退这些网络层使用浮点权重进行计算。 logging.info("===============end AntiOutlier==============") disable_names, disable_last_linear = disable_quant_module(args.input_model_path) quant_config = QuantConfig( a_bit=8, w_bit=8, disable_names=disable_names, disable_last_linear=disable_last_linear, #dev_type='cpu', # dev_type="npu", dev_id=0, 如果需要使用npu进行量化 dev_type="npu", dev_id=0, act_method=3, pr=1.0, w_sym=True, mm_tensor=False) logging.info("===============start Calibrator==============") calibrator = Calibrator(model, quant_config, calib_data=dataset_calib, disable_level='L0') calibrator.run() # 执行PTQ量化校准 calibrator.save(args.output_model_path, save_type=[ "safe_tensor"] ) # "safe_tensor"对应safetensors格式权重,"numpy"对应npy格式权重 logging.info("===============end Calibrator==============") ================================================ FILE: llm-localization/ascend/msmodelslim/llm_quant/calib_set.json ================================================ ================================================ FILE: llm-localization/ascend/msmodelslim/llm_quant/qwen1.5-72b-w8a16.py ================================================ import sys import torch from transformers import AutoTokenizer, AutoModelForCausalLM from msmodelslim.pytorch.llm_ptq.llm_ptq_tools import Calibrator, QuantConfig import argparse import json def load_tokenizer_and_model(fp16_path): tokenizer = AutoTokenizer.from_pretrained( pretrained_model_name_or_path=fp16_path, pad_token='<|extra_0|>', eos_token='<|endoftext|>', padding_side='left', trust_remote_code=True ) model = AutoModelForCausalLM.from_pretrained( pretrained_model_name_or_path=fp16_path, torch_dtype=torch.float32, trust_remote_code=True ).cpu() return tokenizer, model def main(fp16_path, quant_save_path, calib_set_path): tokenizer, model = load_tokenizer_and_model(fp16_path) disable_names = ['lm_head'] quant_config = QuantConfig( w_bit=8, # 权重量化位数 a_bit=16, # 激活值量化位数 disable_names=disable_names, # 不做量化的层 dev_type='cpu', pr=1.0, # 量化正则百分比 w_sym=True, # 对称/非对称量化,True为对称量化,False为非对称量化 mm_tensor=False # 权重量化粒度,True为per-tensor量化,False为per-channel量化(大模型场景建议False) ) calibrator = Calibrator( model, quant_config, calib_data=None, # W8A16量化无需校准 disable_level='L0' # 自动回退等级,根据精度损失程度增加不量化的层(L0~L5,L0为不回退,精度损失明显时可适当提升等级) ) calibrator.run() # 执行PTQ量化校准 calibrator.save(quant_save_path, save_type=["safe_tensor"]) def parse_arguments(): parser = argparse.ArgumentParser() parser.add_argument('--input_model_path', type=str, help="input model and tokenizer path") parser.add_argument('--output_model_path', type=str, help="output model and tokenizer path") parser.add_argument('--calib_set_path', type=str, default="./calib_set_72b.json", help="calib set path") return parser.parse_args() if __name__ == "__main__": args = parse_arguments() model_path = args.input_model_path quant_weight_save_path = args.output_model_path calib_set_path = args.calib_set_path main(model_path, quant_weight_save_path, calib_set_path) ================================================ FILE: llm-localization/ascend/openmind/README.md ================================================ https://gitee.com/ascend/openmind ================================================ FILE: llm-localization/ascend/peft/README.md ================================================ ``` ASCEND_RT_VISIBLE_DEVICES=6 python train_bloom_lora.py ``` ================================================ FILE: llm-localization/ascend/peft/finetune-lora.py ================================================ from transformers import AutoModelForCausalLM from peft import get_peft_config, get_peft_model, get_peft_model_state_dict, LoraConfig, TaskType import torch from datasets import load_dataset import os from transformers import AutoTokenizer from torch.utils.data import DataLoader from transformers import default_data_collator, get_linear_schedule_with_warmup from tqdm import tqdm from datasets import load_dataset #import bitsandbytes as bnb device = "npu:1" #model_name_or_path = "/workspace/model/bloom-2b6-zh" #tokenizer_name_or_path = "/workspace/model/bloom-2b6-zh" #model_name_or_path = "/workspace/model/Baichuan2-7B-Chat" #tokenizer_name_or_path = "/workspace/model/Baichuan2-7B-Chat" model_name_or_path = "/workspace/model/Qwen1.5-7B-Chat/" tokenizer_name_or_path = "/workspace/model/Qwen1.5-7B-Chat/" #model_name_or_path = "/workspace/model/qwen-1.5-1b8/" #tokenizer_name_or_path = "/workspace/model/qwen-1.5-1b8/" # peft_config = LoraConfig(task_type=TaskType.CAUSAL_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1) target_modules = ['q_proj','v_proj'] peft_config = LoraConfig(task_type=TaskType.CAUSAL_LM, target_modules=target_modules, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1) dataset_name = "twitter_complaints" checkpoint_name = f"{dataset_name}_{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}_v1.pt".replace("/", "_") text_column = "Tweet text" label_column = "text_label" max_length = 64 lr = 3e-2 num_epochs = 10 batch_size = 8 from datasets import load_dataset # dataset = load_dataset("ought/raft", dataset_name) dataset = load_dataset("/workspace/data/peft/raft/raft.py", dataset_name, cache_dir="/workspace/data/peft/data") classes = [k.replace("_", " ") for k in dataset["train"].features["Label"].names] print(classes) dataset = dataset.map( lambda x: {"text_label": [classes[label] for label in x["Label"]]}, batched=True, num_proc=1, ) print(dataset) dataset["train"][0] # data preprocessing tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, trust_remote_code=True) if tokenizer.pad_token_id is None: tokenizer.pad_token_id = tokenizer.eos_token_id target_max_length = max([len(tokenizer(class_label)["input_ids"]) for class_label in classes]) print("target_max_length:", target_max_length) def preprocess_function(examples): batch_size = len(examples[text_column]) inputs = [f"{text_column} : {x} Label : " for x in examples[text_column]] targets = [str(x) for x in examples[label_column]] model_inputs = tokenizer(inputs) labels = tokenizer(targets) for i in range(batch_size): sample_input_ids = model_inputs["input_ids"][i] label_input_ids = labels["input_ids"][i] + [tokenizer.pad_token_id] # print(i, sample_input_ids, label_input_ids) model_inputs["input_ids"][i] = sample_input_ids + label_input_ids labels["input_ids"][i] = [-100] * len(sample_input_ids) + label_input_ids model_inputs["attention_mask"][i] = [1] * len(model_inputs["input_ids"][i]) # print(model_inputs) for i in range(batch_size): sample_input_ids = model_inputs["input_ids"][i] label_input_ids = labels["input_ids"][i] model_inputs["input_ids"][i] = [tokenizer.pad_token_id] * ( max_length - len(sample_input_ids) ) + sample_input_ids model_inputs["attention_mask"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[ "attention_mask" ][i] labels["input_ids"][i] = [-100] * (max_length - len(sample_input_ids)) + label_input_ids model_inputs["input_ids"][i] = torch.tensor(model_inputs["input_ids"][i][:max_length]) model_inputs["attention_mask"][i] = torch.tensor(model_inputs["attention_mask"][i][:max_length]) labels["input_ids"][i] = torch.tensor(labels["input_ids"][i][:max_length]) model_inputs["labels"] = labels["input_ids"] return model_inputs processed_datasets = dataset.map( preprocess_function, batched=True, num_proc=1, remove_columns=dataset["train"].column_names, load_from_cache_file=False, desc="Running tokenizer on dataset", ) train_dataset = processed_datasets["train"] eval_dataset = processed_datasets["train"] train_dataloader = DataLoader(train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True) eval_dataloader = DataLoader(eval_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True) def test_preprocess_function(examples): batch_size = len(examples[text_column]) inputs = [f"{text_column} : {x} Label : " for x in examples[text_column]] model_inputs = tokenizer(inputs) # print(model_inputs) for i in range(batch_size): sample_input_ids = model_inputs["input_ids"][i] model_inputs["input_ids"][i] = [tokenizer.pad_token_id] * (max_length - len(sample_input_ids)) + sample_input_ids model_inputs["attention_mask"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs["attention_mask"][i] model_inputs["input_ids"][i] = torch.tensor(model_inputs["input_ids"][i][:max_length]) model_inputs["attention_mask"][i] = torch.tensor(model_inputs["attention_mask"][i][:max_length]) return model_inputs test_dataset = dataset["test"].map( test_preprocess_function, batched=True, num_proc=1, remove_columns=dataset["train"].column_names, load_from_cache_file=False, desc="Running tokenizer on dataset", ) test_dataloader = DataLoader(test_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True) next(iter(test_dataloader)) model = AutoModelForCausalLM.from_pretrained(model_name_or_path, #load_in_8bit=True, torch_dtype=torch.float16, trust_remote_code=True) model = get_peft_model(model, peft_config) model.print_trainable_parameters() # model # optimizer and lr scheduler optimizer = torch.optim.AdamW(model.parameters(), lr=lr) lr_scheduler = get_linear_schedule_with_warmup( optimizer=optimizer, num_warmup_steps=0, num_training_steps=(len(train_dataloader) * num_epochs), ) # training and evaluation model = model.to(device) for epoch in range(num_epochs): model.train() total_loss = 0 for step, batch in enumerate(tqdm(train_dataloader)): batch = {k: v.to(device) for k, v in batch.items()} # print(batch) # print(batch["input_ids"].shape) outputs = model(**batch) loss = outputs.loss total_loss += loss.detach().float() loss.backward() optimizer.step() lr_scheduler.step() optimizer.zero_grad() model.eval() eval_loss = 0 eval_preds = [] for step, batch in enumerate(tqdm(eval_dataloader)): batch = {k: v.to(device) for k, v in batch.items()} with torch.no_grad(): outputs = model(**batch) loss = outputs.loss eval_loss += loss.detach().float() eval_preds.extend( tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), skip_special_tokens=True) ) eval_epoch_loss = eval_loss / len(eval_dataloader) eval_ppl = torch.exp(eval_epoch_loss) train_epoch_loss = total_loss / len(train_dataloader) train_ppl = torch.exp(train_epoch_loss) print(f"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=}") # 模型评估 model.eval() i = 16 inputs = tokenizer(f'{text_column} : {dataset["test"][i]["Tweet text"]} Label : ', return_tensors="pt") print(dataset["test"][i]["Tweet text"]) print(inputs) with torch.no_grad(): inputs = {k: v.to(device) for k, v in inputs.items()} outputs = model.generate( input_ids=inputs["input_ids"], attention_mask=inputs["attention_mask"], max_new_tokens=10, eos_token_id=3 ) print(outputs) print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)) # saving model peft_model_id = f"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}" print("model_output:", peft_model_id) model.save_pretrained(peft_model_id) ================================================ FILE: llm-localization/ascend/pytorch/README.md ================================================ ## 训练 - https://gitee.com/mindspore/mindformers/blob/dev/docs/model_cards/llama.md - https://gitee.com/ascend/ModelZoo-PyTorch/tree/master/PyTorch/built-in/foundation/LLaMA-13B - https://gitee.com/ascend/ModelZoo-PyTorch/blob/master/PyTorch/built-in/foundation/Qwen-7B/test/qwen_7B_64p.sh ``` ASCEND_VISIBLE_DEVICES=6 python train_bloom_lora.py ``` ## baichuan2 ["W_pack", "o_proj", "gate_proj", "up_proj", "down_proj"], ================================================ FILE: llm-localization/ascend/pytorch/llm-lora.py ================================================ from transformers import AutoModelForCausalLM from peft import get_peft_config, get_peft_model, get_peft_model_state_dict, LoraConfig, TaskType import torch from datasets import load_dataset import os from transformers import AutoTokenizer from torch.utils.data import DataLoader from transformers import default_data_collator, get_linear_schedule_with_warmup from tqdm import tqdm from datasets import load_dataset #import bitsandbytes as bnb device = "npu:1" #model_name_or_path = "/workspace/model/bloom-2b6-zh" #tokenizer_name_or_path = "/workspace/model/bloom-2b6-zh" #model_name_or_path = "/workspace/model/Baichuan2-7B-Chat" #tokenizer_name_or_path = "/workspace/model/Baichuan2-7B-Chat" model_name_or_path = "/workspace/model/Qwen1.5-7B-Chat/" tokenizer_name_or_path = "/workspace/model/Qwen1.5-7B-Chat/" #model_name_or_path = "/workspace/model/qwen-1.5-1b8/" #tokenizer_name_or_path = "/workspace/model/qwen-1.5-1b8/" # peft_config = LoraConfig(task_type=TaskType.CAUSAL_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1) target_modules = ['q_proj','v_proj'] peft_config = LoraConfig(task_type=TaskType.CAUSAL_LM, target_modules=target_modules, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1) dataset_name = "twitter_complaints" checkpoint_name = f"{dataset_name}_{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}_v1.pt".replace("/", "_") text_column = "Tweet text" label_column = "text_label" max_length = 64 lr = 3e-2 num_epochs = 10 batch_size = 8 from datasets import load_dataset # dataset = load_dataset("ought/raft", dataset_name) dataset = load_dataset("/workspace/data/peft/raft/raft.py", dataset_name, cache_dir="/workspace/data/peft/data") classes = [k.replace("_", " ") for k in dataset["train"].features["Label"].names] print(classes) dataset = dataset.map( lambda x: {"text_label": [classes[label] for label in x["Label"]]}, batched=True, num_proc=1, ) print(dataset) dataset["train"][0] # data preprocessing tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, trust_remote_code=True) if tokenizer.pad_token_id is None: tokenizer.pad_token_id = tokenizer.eos_token_id target_max_length = max([len(tokenizer(class_label)["input_ids"]) for class_label in classes]) print("target_max_length:", target_max_length) def preprocess_function(examples): batch_size = len(examples[text_column]) inputs = [f"{text_column} : {x} Label : " for x in examples[text_column]] targets = [str(x) for x in examples[label_column]] model_inputs = tokenizer(inputs) labels = tokenizer(targets) for i in range(batch_size): sample_input_ids = model_inputs["input_ids"][i] label_input_ids = labels["input_ids"][i] + [tokenizer.pad_token_id] # print(i, sample_input_ids, label_input_ids) model_inputs["input_ids"][i] = sample_input_ids + label_input_ids labels["input_ids"][i] = [-100] * len(sample_input_ids) + label_input_ids model_inputs["attention_mask"][i] = [1] * len(model_inputs["input_ids"][i]) # print(model_inputs) for i in range(batch_size): sample_input_ids = model_inputs["input_ids"][i] label_input_ids = labels["input_ids"][i] model_inputs["input_ids"][i] = [tokenizer.pad_token_id] * ( max_length - len(sample_input_ids) ) + sample_input_ids model_inputs["attention_mask"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[ "attention_mask" ][i] labels["input_ids"][i] = [-100] * (max_length - len(sample_input_ids)) + label_input_ids model_inputs["input_ids"][i] = torch.tensor(model_inputs["input_ids"][i][:max_length]) model_inputs["attention_mask"][i] = torch.tensor(model_inputs["attention_mask"][i][:max_length]) labels["input_ids"][i] = torch.tensor(labels["input_ids"][i][:max_length]) model_inputs["labels"] = labels["input_ids"] return model_inputs processed_datasets = dataset.map( preprocess_function, batched=True, num_proc=1, remove_columns=dataset["train"].column_names, load_from_cache_file=False, desc="Running tokenizer on dataset", ) train_dataset = processed_datasets["train"] eval_dataset = processed_datasets["train"] train_dataloader = DataLoader(train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True) eval_dataloader = DataLoader(eval_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True) def test_preprocess_function(examples): batch_size = len(examples[text_column]) inputs = [f"{text_column} : {x} Label : " for x in examples[text_column]] model_inputs = tokenizer(inputs) # print(model_inputs) for i in range(batch_size): sample_input_ids = model_inputs["input_ids"][i] model_inputs["input_ids"][i] = [tokenizer.pad_token_id] * (max_length - len(sample_input_ids)) + sample_input_ids model_inputs["attention_mask"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs["attention_mask"][i] model_inputs["input_ids"][i] = torch.tensor(model_inputs["input_ids"][i][:max_length]) model_inputs["attention_mask"][i] = torch.tensor(model_inputs["attention_mask"][i][:max_length]) return model_inputs test_dataset = dataset["test"].map( test_preprocess_function, batched=True, num_proc=1, remove_columns=dataset["train"].column_names, load_from_cache_file=False, desc="Running tokenizer on dataset", ) test_dataloader = DataLoader(test_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True) next(iter(test_dataloader)) model = AutoModelForCausalLM.from_pretrained(model_name_or_path, #load_in_8bit=True, torch_dtype=torch.float16, trust_remote_code=True) model = get_peft_model(model, peft_config) model.print_trainable_parameters() # model # optimizer and lr scheduler optimizer = torch.optim.AdamW(model.parameters(), lr=lr) lr_scheduler = get_linear_schedule_with_warmup( optimizer=optimizer, num_warmup_steps=0, num_training_steps=(len(train_dataloader) * num_epochs), ) # training and evaluation model = model.to(device) for epoch in range(num_epochs): model.train() total_loss = 0 for step, batch in enumerate(tqdm(train_dataloader)): batch = {k: v.to(device) for k, v in batch.items()} # print(batch) # print(batch["input_ids"].shape) outputs = model(**batch) loss = outputs.loss total_loss += loss.detach().float() loss.backward() optimizer.step() lr_scheduler.step() optimizer.zero_grad() model.eval() eval_loss = 0 eval_preds = [] for step, batch in enumerate(tqdm(eval_dataloader)): batch = {k: v.to(device) for k, v in batch.items()} with torch.no_grad(): outputs = model(**batch) loss = outputs.loss eval_loss += loss.detach().float() eval_preds.extend( tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), skip_special_tokens=True) ) eval_epoch_loss = eval_loss / len(eval_dataloader) eval_ppl = torch.exp(eval_epoch_loss) train_epoch_loss = total_loss / len(train_dataloader) train_ppl = torch.exp(train_epoch_loss) print(f"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=}") # 模型评估 model.eval() i = 16 inputs = tokenizer(f'{text_column} : {dataset["test"][i]["Tweet text"]} Label : ', return_tensors="pt") print(dataset["test"][i]["Tweet text"]) print(inputs) with torch.no_grad(): inputs = {k: v.to(device) for k, v in inputs.items()} outputs = model.generate( input_ids=inputs["input_ids"], attention_mask=inputs["attention_mask"], max_new_tokens=10, eos_token_id=3 ) print(outputs) print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)) # saving model peft_model_id = f"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}" print("model_output:", peft_model_id) model.save_pretrained(peft_model_id) ================================================ FILE: llm-localization/ascend/standford-alpaca/README.md ================================================ ``` git lfs clone https://www.modelscope.cn/qwen/Qwen1.5-14B-Chat.git ``` ``` docker exec -it pytorch_ubuntu_dev bash conda activate llm-dev source /usr/local/Ascend/ascend-toolkit/set_env.sh cd /workspace/code/stanford_alpaca ``` ## qwen1.5 ``` torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Qwen1.5-7B-Chat/ \ --data_path ./alpaca_data_1k.json \ --fp16 True \ --output_dir /workspace/output/alpaca \ --num_train_epochs 1 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 4 \ --gradient_accumulation_steps 8 \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'Qwen2DecoderLayer' ``` ### 7b-zero2 ``` - ds train_micro_batch_size_per_gpu=2 vs hf per_device_train_batch_size=8 - ds gradient_accumulation_steps=8 vs hf gradient_accumulation_steps=1 - ds train_batch_size=128 vs hf train_batch_size (calculated)=64 torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Qwen1.5-7B-Chat/ \ --data_path ./alpaca_data_1k.json \ --fp16 True \ --output_dir /workspace/output/alpaca2 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps=8 \ --num_train_epochs 1 \ --per_device_eval_batch_size 4 \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --deepspeed ds_config_zero2.json ``` ### 14b-zero2 ``` rm -rf /workspace/output/alpaca-qwen14/* torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Qwen1.5-14B-Chat/ \ --data_path /workspace/data/alpaca_gpt4_data_zh_5k.json \ --fp16 True \ --output_dir /workspace/output/alpaca-qwen14 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps=8 \ --num_train_epochs 1 \ --per_device_eval_batch_size 4 \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --deepspeed ds_config_zero2.json ``` ### zero3 ``` rm -rf /workspace/output/alpaca2/* torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Qwen1.5-7B-Chat/ \ --data_path /workspace/data/alpaca_gpt4_data_zh_5k.json \ --fp16 True \ --output_dir /workspace/output/alpaca2 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps=8 \ --num_train_epochs 1 \ --per_device_eval_batch_size 4 \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --deepspeed ds_config_zero3.json torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Qwen1.5-7B-Chat/ \ --data_path /workspace/data/alpaca_gpt4_data_zh_5k.json \ --fp16 True \ --output_dir /workspace/output/alpaca2 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps=8 \ --num_train_epochs 1 \ --per_device_eval_batch_size 4 \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --deepspeed ds_config.json ``` ## baichuan2 ``` torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Baichuan2-7B-Chat \ --data_path ./alpaca_data_1k.json \ --fp16 True \ --output_dir /workspace/output/baichuan2 \ --num_train_epochs 1 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 4 \ --gradient_accumulation_steps 8 \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'DecoderLayer' ``` ``` mkdir -p /workspace/output/baichuan2-13b rm -rf /workspace/output/baichuan2-13b/* nohup \ torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Baichuan2-13B-Chat \ --data_path ./alpaca_data_1k.json \ --fp16 True \ --output_dir /workspace/output/baichuan2-13b \ --num_train_epochs 1 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 4 \ --gradient_accumulation_steps 8 \ --gradient_checkpointing true \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --fsdp "full_shard offload auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'BaichuanLayer' \ > baichuan2-fsdp-13b.log 2>&1 & ``` ### zero2 ``` rm -rf /workspace/output/baichuan2-13b/* nohup \ torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Baichuan2-7B-Chat \ --data_path /workspace/data/alpaca_gpt4_data_zh_5k.json \ --fp16 True \ --output_dir /workspace/output/baichuan2-ds-7b/ \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps=8 \ --num_train_epochs 1 \ --per_device_eval_batch_size 4 \ --gradient_checkpointing true \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --deepspeed ds_config_zero2.json \ > baichuan2-ds-7b.log 2>&1 & tail -100f baichuan2-ds-7b.log mkdir -p /workspace/output/baichuan2-ds-13b/ nohup \ torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Baichuan2-13B-Chat \ --data_path /workspace/data/alpaca_gpt4_data_zh_5k.json \ --fp16 True \ --output_dir /workspace/output/baichuan2-ds-13b/ \ --per_device_train_batch_size 1 \ --gradient_accumulation_steps=8 \ --num_train_epochs 1 \ --per_device_eval_batch_size 4 \ --gradient_checkpointing true \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --deepspeed ds_config_zero2.json \ > baichuan2-ds-13b.log 2>&1 & tail -100f baichuan2-ds-13b.log ``` ### zero3 ``` rm -rf /workspace/output/baichuan2-ds-7b/* mkdir -p /workspace/output/baichuan2-ds-7b/ rm -rf /workspace/output/baichuan2-ds-7b/* nohup \ torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Baichuan2-7B-Chat \ --data_path /workspace/data/alpaca_gpt4_data_zh_5k.json \ --fp16 True \ --output_dir /workspace/output/baichuan2-ds-7b/ \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps=8 \ --num_train_epochs 1 \ --per_device_eval_batch_size 4 \ --gradient_checkpointing true \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --deepspeed ds_config_zero3.json \ > baichuan2-ds-7b.log 2>&1 & tail -100f baichuan2-ds-7b.log TypeError: Old language model head is of type , which is not an instance of . You should either use a different resize function or make sure that `old_lm_head` are an instance of . rm -rf /workspace/output/baichuan2-13b/* torchrun --nproc_per_node=8 --master_port=29001 train.py \ --model_name_or_path /workspace/model/Baichuan2-13B-Chat \ --data_path /workspace/data/alpaca_gpt4_data_zh_5k.json \ --fp16 True \ --output_dir /workspace/output/baichuan2-13b/ \ --per_device_train_batch_size 1 \ --gradient_accumulation_steps=8 \ --num_train_epochs 1 \ --per_device_eval_batch_size 4 \ --eval_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --deepspeed ds_config_zero3.json TypeError: Old language model head is of type , which is not an instance of . You should either use a different resize function or make sure that `old_lm_head` are an instance of . https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/blob/ea66ced17780ca3db39bc9f8aa601d8463db3da5/modeling_baichuan.py#L495 https://huggingface.co/Qwen/Qwen-7B-Chat/blob/93a65d34827a3cc269b727e67004743b723e2f83/modeling_qwen.py#L980 ``` ================================================ FILE: llm-localization/ascend/standford-alpaca/ds_config_zero2.json ================================================ { "fp16": { "enabled": "auto", "loss_scale": 0, "loss_scale_window": 1000, "initial_scale_power": 16, "hysteresis": 2, "min_loss_scale": 1 }, "bf16": { "enabled": "auto" }, "optimizer": { "type": "AdamW", "params": { "lr": "auto", "betas": "auto", "eps": "auto", "weight_decay": "auto" } }, "scheduler": { "type": "WarmupLR", "params": { "warmup_min_lr": "auto", "warmup_max_lr": "auto", "warmup_num_steps": "auto" } }, "zero_optimization": { "stage": 2, "offload_optimizer": { "device": "cpu", "pin_memory": true }, "allgather_partitions": true, "allgather_bucket_size": 2e8, "overlap_comm": true, "reduce_scatter": true, "reduce_bucket_size": 2e8, "contiguous_gradients": true }, "train_batch_size": 128, "gradient_accumulation_steps": 8, "train_micro_batch_size_per_gpu": 2, "gradient_clipping": "auto", "steps_per_print": 2000, "train_batch_size": "auto", "train_micro_batch_size_per_gpu": "auto", "wall_clock_breakdown": false } ================================================ FILE: llm-localization/ascend/standford-alpaca/ds_config_zero3.json ================================================ { "zero_optimization": { "stage": 3, "contiguous_gradients": true, "stage3_max_live_parameters": 0, "stage3_max_reuse_distance": 0, "stage3_prefetch_bucket_size": 0, "stage3_param_persistence_threshold": 1e2, "reduce_bucket_size": 1e2, "stage3_gather_16bit_weights_on_model_save": true }, "fp16": { "enabled": true, "auto_cast": false, "loss_scale": 0, "initial_scale_power": 32, "loss_scale_window": 1000, "hysteresis": 2, "min_loss_scale": 1 }, "train_batch_size": 128, "gradient_accumulation_steps": 8, "train_micro_batch_size_per_gpu": 2, "wall_clock_breakdown": false } ================================================ FILE: llm-localization/ascend/standford-alpaca/requirements.txt ================================================ numpy rouge_score fire #openai transformers>=4.28.1 #torch sentencepiece tokenizers>=0.13.3 #wandb tensorboardX deepspeed ================================================ FILE: llm-localization/ascend/standford-alpaca/train.py ================================================ import copy import logging from dataclasses import dataclass, field from typing import Dict, Optional, Sequence import torch import transformers import utils from torch.utils.data import Dataset from transformers import Trainer IGNORE_INDEX = -100 DEFAULT_PAD_TOKEN = "[PAD]" DEFAULT_EOS_TOKEN = "" DEFAULT_BOS_TOKEN = "" DEFAULT_UNK_TOKEN = "" PROMPT_DICT = { "prompt_input": ( "Below is an instruction that describes a task, paired with an input that provides further context. " "Write a response that appropriately completes the request.\n\n" "### Instruction:\n{instruction}\n\n### Input:\n{input}\n\n### Response:" ), "prompt_no_input": ( "Below is an instruction that describes a task. " "Write a response that appropriately completes the request.\n\n" "### Instruction:\n{instruction}\n\n### Response:" ), } @dataclass class ModelArguments: model_name_or_path: Optional[str] = field(default="facebook/opt-125m") @dataclass class DataArguments: data_path: str = field(default=None, metadata={"help": "Path to the training data."}) @dataclass class TrainingArguments(transformers.TrainingArguments): cache_dir: Optional[str] = field(default=None) optim: str = field(default="adamw_torch") model_max_length: int = field( default=512, metadata={"help": "Maximum sequence length. Sequences will be right padded (and possibly truncated)."}, ) def smart_tokenizer_and_embedding_resize( special_tokens_dict: Dict, tokenizer: transformers.PreTrainedTokenizer, model: transformers.PreTrainedModel, ): """Resize tokenizer and embedding. Note: This is the unoptimized version that may make your embedding size not be divisible by 64. """ num_new_tokens = tokenizer.add_special_tokens(special_tokens_dict) model.resize_token_embeddings(len(tokenizer)) if num_new_tokens > 0: input_embeddings = model.get_input_embeddings().weight.data output_embeddings = model.get_output_embeddings().weight.data input_embeddings_avg = input_embeddings[:-num_new_tokens].mean(dim=0, keepdim=True) output_embeddings_avg = output_embeddings[:-num_new_tokens].mean(dim=0, keepdim=True) input_embeddings[-num_new_tokens:] = input_embeddings_avg output_embeddings[-num_new_tokens:] = output_embeddings_avg def _tokenize_fn(strings: Sequence[str], tokenizer: transformers.PreTrainedTokenizer) -> Dict: """Tokenize a list of strings.""" tokenized_list = [ tokenizer( text, return_tensors="pt", padding="longest", max_length=tokenizer.model_max_length, truncation=True, ) for text in strings ] input_ids = labels = [tokenized.input_ids[0] for tokenized in tokenized_list] input_ids_lens = labels_lens = [ tokenized.input_ids.ne(tokenizer.pad_token_id).sum().item() for tokenized in tokenized_list ] return dict( input_ids=input_ids, labels=labels, input_ids_lens=input_ids_lens, labels_lens=labels_lens, ) def preprocess( sources: Sequence[str], targets: Sequence[str], tokenizer: transformers.PreTrainedTokenizer, ) -> Dict: """Preprocess the data by tokenizing.""" examples = [s + t for s, t in zip(sources, targets)] examples_tokenized, sources_tokenized = [_tokenize_fn(strings, tokenizer) for strings in (examples, sources)] input_ids = examples_tokenized["input_ids"] labels = copy.deepcopy(input_ids) for label, source_len in zip(labels, sources_tokenized["input_ids_lens"]): label[:source_len] = IGNORE_INDEX return dict(input_ids=input_ids, labels=labels) class SupervisedDataset(Dataset): """Dataset for supervised fine-tuning.""" def __init__(self, data_path: str, tokenizer: transformers.PreTrainedTokenizer): super(SupervisedDataset, self).__init__() logging.warning("Loading data...") list_data_dict = utils.jload(data_path) logging.warning("Formatting inputs...") prompt_input, prompt_no_input = PROMPT_DICT["prompt_input"], PROMPT_DICT["prompt_no_input"] sources = [ prompt_input.format_map(example) if example.get("input", "") != "" else prompt_no_input.format_map(example) for example in list_data_dict ] targets = [f"{example['output']}{tokenizer.eos_token}" for example in list_data_dict] logging.warning("Tokenizing inputs... This may take some time...") data_dict = preprocess(sources, targets, tokenizer) self.input_ids = data_dict["input_ids"] self.labels = data_dict["labels"] def __len__(self): return len(self.input_ids) def __getitem__(self, i) -> Dict[str, torch.Tensor]: return dict(input_ids=self.input_ids[i], labels=self.labels[i]) @dataclass class DataCollatorForSupervisedDataset(object): """Collate examples for supervised fine-tuning.""" tokenizer: transformers.PreTrainedTokenizer def __call__(self, instances: Sequence[Dict]) -> Dict[str, torch.Tensor]: input_ids, labels = tuple([instance[key] for instance in instances] for key in ("input_ids", "labels")) input_ids = torch.nn.utils.rnn.pad_sequence( input_ids, batch_first=True, padding_value=self.tokenizer.pad_token_id ) labels = torch.nn.utils.rnn.pad_sequence(labels, batch_first=True, padding_value=IGNORE_INDEX) return dict( input_ids=input_ids, labels=labels, attention_mask=input_ids.ne(self.tokenizer.pad_token_id), ) def make_supervised_data_module(tokenizer: transformers.PreTrainedTokenizer, data_args) -> Dict: """Make dataset and collator for supervised fine-tuning.""" train_dataset = SupervisedDataset(tokenizer=tokenizer, data_path=data_args.data_path) data_collator = DataCollatorForSupervisedDataset(tokenizer=tokenizer) return dict(train_dataset=train_dataset, eval_dataset=None, data_collator=data_collator) def train(): parser = transformers.HfArgumentParser((ModelArguments, DataArguments, TrainingArguments)) model_args, data_args, training_args = parser.parse_args_into_dataclasses() model = transformers.AutoModelForCausalLM.from_pretrained( model_args.model_name_or_path, trust_remote_code=True, cache_dir=training_args.cache_dir, ) tokenizer = transformers.AutoTokenizer.from_pretrained( model_args.model_name_or_path, trust_remote_code=True, cache_dir=training_args.cache_dir, model_max_length=training_args.model_max_length, padding_side="right", use_fast=False, ) special_tokens_dict = dict() if tokenizer.pad_token is None: special_tokens_dict["pad_token"] = DEFAULT_PAD_TOKEN if tokenizer.eos_token is None: special_tokens_dict["eos_token"] = DEFAULT_EOS_TOKEN if tokenizer.bos_token is None: special_tokens_dict["bos_token"] = DEFAULT_BOS_TOKEN if tokenizer.unk_token is None: special_tokens_dict["unk_token"] = DEFAULT_UNK_TOKEN smart_tokenizer_and_embedding_resize( special_tokens_dict=special_tokens_dict, tokenizer=tokenizer, model=model, ) data_module = make_supervised_data_module(tokenizer=tokenizer, data_args=data_args) trainer = Trainer(model=model, tokenizer=tokenizer, args=training_args, **data_module) trainer.train() trainer.save_state() trainer.save_model(output_dir=training_args.output_dir) if __name__ == "__main__": train() ================================================ FILE: llm-localization/ascend/standford-alpaca/utils.py ================================================ import dataclasses import logging import math import os import io import sys import time import json from typing import Optional, Sequence, Union import tqdm import copy def _make_w_io_base(f, mode: str): if not isinstance(f, io.IOBase): f_dirname = os.path.dirname(f) if f_dirname != "": os.makedirs(f_dirname, exist_ok=True) f = open(f, mode=mode) return f def _make_r_io_base(f, mode: str): if not isinstance(f, io.IOBase): f = open(f, mode=mode) return f def jdump(obj, f, mode="w", indent=4, default=str): """Dump a str or dictionary to a file in json format. Args: obj: An object to be written. f: A string path to the location on disk. mode: Mode for opening the file. indent: Indent for storing json dictionaries. default: A function to handle non-serializable entries; defaults to `str`. """ f = _make_w_io_base(f, mode) if isinstance(obj, (dict, list)): json.dump(obj, f, indent=indent, default=default) elif isinstance(obj, str): f.write(obj) else: raise ValueError(f"Unexpected type: {type(obj)}") f.close() def jload(f, mode="r"): """Load a .json file into a dictionary.""" f = _make_r_io_base(f, mode) jdict = json.load(f) f.close() return jdict ================================================ FILE: llm-localization/ascend/transformers/README.md ================================================ - https://gitee.com/ascend/transformers/ ``` pip3 install -U transformers ``` ``` git clone https://github.com/huggingface/transformers.git cd examples/pytorch/text-classification pip install -r requirements.txt ``` ``` export TASK_NAME=mrpc python run_glue.py \ --model_name_or_path bert-base-cased \ --task_name $TASK_NAME \ --do_train \ --do_eval \ --max_seq_length 128 \ --per_device_train_batch_size 32 \ --learning_rate 2e-5 \ --num_train_epochs 3 \ --output_dir /tmp/$TASK_NAME/ ``` ================================================ FILE: llm-localization/ascend/vllm-ascend/README.md ================================================ # vllm 支持 NPU https://github.com/vllm-project/vllm/issues/7692 https://vllm-ascend.readthedocs.io/en/latest/quick_start.html # 镜像 https://quay.io/repository/ascend/vllm-ascend?tab=tags https://quay.io/repository/ascend/cann?tab=tags ``` TAG=v0.7.3rc2 docker pull m.daocloud.io/quay.io/ascend/vllm-ascend:$TAG docker pull quay.io/ascend/vllm-ascend:v0.8.5rc1-openeuler docker pull quay.io/ascend/vllm-ascend:v0.8.5rc1 ``` ## 支持的特性 https://vllm-ascend.readthedocs.io/en/latest/user_guide/suppoted_features.html ## 推理模型输出 https://github.com/vllm-project/vllm/blob/main/docs/features/reasoning_outputs.md - v0.9.0 支持 qwen3 推理输出解析器 https://github.com/vllm-project/vllm/tree/v0.9.0/vllm/reasoning ================================================ FILE: llm-localization/ascend/优质学习资料.md ================================================ - Serving Large Language Models on Huawei CloudMatrix384 ================================================ FILE: llm-localization/ascend/昇腾LLM支持概览.md ================================================ ## 基础环境 ------ 800T A2 https://www.hiascend.com/hardware/firmware-drivers/community Ascend-hdk-910b-npu-firmware_7.1.0.4.220.run Ascend-hdk-910b-npu-driver_23.0.1_linux-aarch64.run https://www.hiascend.com/zh/software/cann/community-history Ascend-cann-toolkit_7.0.1_linux-aarch64.run ------ 800T (9000) Ascend-hdk-910-npu-driver_23.0.0_linux-aarch64.run Ascend-hdk-910-npu-firmware_7.1.0.3.220.run Ascend-cann-toolkit_7.0.0_linux-aarch64.run ## MindSpore ### 镜像 - http://mirrors.cn-central-221.ovaijisuan.com/mirrors.html docker pull swr.cn-central-221.ovaijisuan.com/mindformers/mindformers1.0_mindspore2.2.11:aarch_20240125 ``` # --device用于控制指定容器的运行NPU卡号和范围 # -v 用于映射容器外的目录 # --name 用于自定义容器名称 docker run -it -u root \ --ipc=host \ --network host \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /etc/localtime:/etc/localtime \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /var/log/npu/:/usr/slog \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ --name {请手动输入容器名称} \ swr.cn-central-221.ovaijisuan.com/mindformers/mindformers1.0_mindspore2.2.11:aarch_20240125 \ /bin/bash docker run -it -u root \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/Ascend/toolbox:/usr/local/Ascend/toolbox \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \ -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \ -v /home/aicc:/home/ma-user/work/aicc \ --name mindspore_ma \ --entrypoint=/bin/bash \ swr.cn-central-221.ovaijisuan.com/dxy/mindspore_kernels:MindSpore2.2.10-cann7.0.0beta1_py_3.9-euler_2.8.3-32GB \ /bin/bash ``` ### MindFormers #### 软件版本 当前支持的硬件为Atlas 800训练服务器与Atlas 800T A2训练服务器。 当前套件建议使用的Python版本为3.9。 | MindFormers | MindPet | MindSpore | CANN | 驱动固件 | 镜像链接 | 备注 | | :---------: | :-----: | :----------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------: | :------------------------------------------------------------------: | -------------------- | | dev | 1.0.3 | [2.2.11](https://www.mindspore.cn/install) | 7.0.0.beta1:
[aarch64](https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%207.0.0/Ascend-cann-toolkit_7.0.0_linux-aarch64.run)
[x86_64](https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%207.0.0/Ascend-cann-toolkit_7.0.0_linux-x86_64.run) | [链接](https://www.hiascend.com/hardware/firmware-drivers/community) | / | 开发分支(非稳定版本) | | r1.0 | 1.0.3 | [2.2.11](https://www.mindspore.cn/install) | 7.0.0.beta1:
[aarch64](https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%207.0.0/Ascend-cann-toolkit_7.0.0_linux-aarch64.run)
[x86_64](https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%207.0.0/Ascend-cann-toolkit_7.0.0_linux-x86_64.run) | [链接](https://www.hiascend.com/hardware/firmware-drivers/community) | [链接](http://mirrors.cn-central-221.ovaijisuan.com/detail/118.html) | 发布版本 | | r0.8 | 1.0.2 | [2.2.1](https://www.mindspore.cn/install) | 7.0.RC1.3.beta1:
[aarch64](https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%207.0.RC1.3/Ascend-cann-toolkit_7.0.RC1.3_linux-aarch64.run)
[x86_64](https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%207.0.RC1.3/Ascend-cann-toolkit_7.0.RC1.3_linux-x86_64.run) | [链接](https://www.hiascend.com/hardware/firmware-drivers/community) | / | 历史发布版本 | 其中CANN,固件驱动的安装需与使用的机器匹配,请注意识别机器型号,选择对应架构的版本 #### baichuan - https://gitee.com/mindspore/mindformers/blob/dev/research/baichuan/baichuan.md - Baichuan-7B/13B - 全参微调、Lora微调 - MindSpore、MindSpore lite #### baichuan2 - https://gitee.com/mindspore/mindformers/tree/dev/research/baichuan2 - Baichuan-7B/13B - 全参微调、Lora微调 - MindSpore、MindSpore lite #### qwen - https://gitee.com/mindspore/mindformers/blob/dev/research/qwen/qwen.md - Qwen-7B/14B - 全参微调、Lora微调 - MindSpore、MindSpore lite #### bloom - https://gitee.com/mindspore/mindformers/blob/dev/docs/model_cards/bloom.md - Bloom-7B1 - 全参微调 - MindSpore、MindSpore lite #### chatglm - https://gitee.com/mindspore/mindformers/blob/dev/docs/model_cards/glm3.md - Chatglm-6b - 全参微调、Lora微调 - MindSpore、MindSpore lite #### chatglm2 - https://gitee.com/mindspore/mindformers/blob/dev/docs/model_cards/glm2.md - Chatglm2-6b - 全参微调、Lora微调、P-Tuning微调 - MindSpore、MindSpore lite #### chatglm3 - https://gitee.com/mindspore/mindformers/blob/dev/docs/model_cards/glm3.md - Chatglm3-6b - 全参微调、Lora微调 - MindSpore #### t5 T5: - https://gitee.com/mindspore/mindformers/blob/dev/mindformers/models/t5/mt5.py#L200 - MT5ForConditionalGeneration bert: - https://gitee.com/mindspore/mindformers/blob/dev/mindformers/models/bert/bert_tokenizer.py transformers: T5: - MT5ForConditionalGeneration - https://github.com/huggingface/transformers/blob/main/src/transformers/models/mt5/modeling_mt5.py T5-Pegasus: Tokenizer - https://github.com/renmada/t5-pegasus-pytorch/blob/main/tokenizer.py#L389 ``` class JieBaTokenizer(CPTTokenizer): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.pre_tokenizer = partial(jieba.cut, HMM=False) def _tokenize(self, text, *arg, **kwargs): split_tokens = [] for text in self.pre_tokenizer(text): if text in self.vocab: split_tokens.append(text) else: split_tokens.extend(super()._tokenize(text)) return split_tokens ``` - t5-pegasus的huggingface调用: https://zhuanlan.zhihu.com/p/648997663 - 中文生成模型T5-Pegasus详解与实践:https://blog.csdn.net/GJ_0418/article/details/123298099 T5-Pegasus的Tokenizer换为了BERT的Tokenizer,并与jieba分词相结合,实现分词功能。具体地,先用jieba分词,如果当前词在词表vocab.txt中,就用jieba分词的结果;如果当前词不在词表vocab.txt中,再改用BERT的Tokenizer。 ## PyTorch ### 镜像 ``` docker run -it -u root \ --device=/dev/davinci0 \ --device=/dev/davinci1 \ --device=/dev/davinci2 \ --device=/dev/davinci3 \ --device=/dev/davinci4 \ --device=/dev/davinci5 \ --device=/dev/davinci6 \ --device=/dev/davinci7 \ --device=/dev/davinci_manager \ --device=/dev/devmm_svm \ --device=/dev/hisi_hdc \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \ -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \ -v /home/aicc:/home/ma-user/work/aicc \ --name pytorch_ma \ --entrypoint=/bin/bash \ swr.cn-central-221.ovaijisuan.com/dxy/pytorch2_1_0_kernels:PyTorch2.1.0-cann7.0.0.alpha003_py_3.9-euler_2.8.3-64GB ``` ### ModelLink 目前只支持了类GPT仅Decoder架构的生成模型、像Bert、T5、ChatGLM等模型暂时没有支持。 #### 支持功能 当前ModelLink支撑大模型使用功能: - 制作预训练数据集/制作指令微调数据集 - 预训练/全参微调/低参微调 - 推理(人机对话) - 评估基线数据集(Benchmark) - 使用加速特性(加速算法+融合算子) - 基于昇腾芯片采集Profiling数据 #### 软件版本 | 软件 | [版本](https://www.hiascend.com/zh/) | | :-----------------------: |:----------------------------------:| | Python | 3.8 | | driver | Ascend HDK 23.0.0 | | firmware | Ascend HDK 23.0.0 | | CANN | CANN 7.0.0 | | torch | 2.1.0 | | torch_npu | release v5.0.0 | torch_npu: torch_npu(Ascend Adapter for PyTorch插件)使昇腾NPU可以适配PyTorch框架,为使用PyTorch框架的开发者提供昇腾AI处理器的超强算力。 - https://gitee.com/ascend/pytorch #### baichuan - https://gitee.com/ascend/ModelLink/blob/master/examples/baichuan - Baichuan-7B/13B - 全参微调 - ModelLink #### baichuan2 - https://gitee.com/ascend/ModelLink/tree/master/examples/baichuan2 - Baichuan2-7B/13B - 全参微调 - ModelLink #### bloom - https://gitee.com/ascend/ModelLink/tree/master/examples/bloom - Bloom-7B/176B - 全参微调 - ModelLink #### qwen - https://gitee.com/ascend/ModelLink/tree/master/examples/qwen - Qwen-7B/14B/72B - 全参微调 - ModelLink #### llama2 - https://gitee.com/ascend/ModelLink/tree/master/examples/llama2 - LLAMA2-7B/13B/34B/70B - 全参微调、Lora微调 - ModelLink - https://gitee.com/ascend/ModelLink/tree/master/modellink/tasks/inference/text_generation ## 推理 - https://gitee.com/mindspore/llm-serving - https://gitee.com/mindspore/serving ================================================ FILE: llm-localization/ascend/昇腾卡注意事项.md ================================================ --privileged 特权模型下,昇腾或者英伟达的 docker runtime 中会默认分配本机所有卡。 - ASCEND_VISIBLE_DEVICES 容器级控制卡 - ASCEND_RT_VISIBLE_DEVICES 进程级控制卡 类似于 CUDA_VISIBLE_DEVICES ================================================ FILE: llm-localization/modelscope/README.md ================================================ 微调库: - https://github.com/modelscope/swift - https://github.com/modelscope/swift/blob/main/docs/source/LLM/NPU%E6%8E%A8%E7%90%86%E4%B8%8E%E5%BE%AE%E8%B0%83%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5.md ================================================ FILE: llm-localization/paddle/PaddleNLP.md ================================================ ================================================ FILE: llm-localization/tianshuzhixin/README.md ================================================ ================================================ FILE: llm-localization/tianshuzhixin/ixsmi.md ================================================ ``` ixsmi ixsmi -q -l | grep Used.[^G] ixsmi -q -i 0 -l | grep Used.[^G] ``` ``` ixsmi topo --matrix ``` ``` ixsmi -L ``` ================================================ FILE: llm-maas/OpenAI-ChatGPT.md ================================================ - https://platform.openai.com/docs/api-reference/chat/create - https://platform.openai.com/docs/guides/chat-completions - https://platform.openai.com/docs/guides/text-generation/managing-tokens - https://platform.openai.com/docs/api-reference/completions ``` curl https://api.openai.com/v1/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ "model": "gpt-3.5-turbo-instruct", "prompt": "Say this is a test", "max_tokens": 7, "temperature": 0 }' ``` - https://platform.openai.com/docs/api-reference/chat ``` curl https://api.openai.com/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ "model": "gpt-3.5-turbo", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "Hello!" } ] }' ``` ================================================ FILE: llm-maas/README.md ================================================ - 智谱AI:https://open.bigmodel.cn/ - OpenAI: https://chat.openai.com/ - 文心一言:https://yiyan.baidu.com/ ================================================ FILE: llm-optimizer/FlashAttention.md ================================================ FlashAttention Block-sparse FlashAttention FlashAttention2 FlashAttention3 ================================================ FILE: llm-optimizer/README.md ================================================ ## 大模型推理优化 ### 综述 - LLM Inference Serving: Survey of Recent Advances and Opportunities - Towards Efficient Generative Large Language Model Serving: A Survey from Algorithms to Systems - [A Survey on Efficient Inference for Large Language Models](https://arxiv.org/pdf/2404.14294) - [A Survey on Model Compression for Large Language Models](https://arxiv.org/pdf/2308.07633.pdf) - BlendServe: Optimizing Offline Inference for Auto-regressive Large Models with Resource-aware Batching:https://arxiv.org/pdf/2411.16102 - FLUX: Fast Software-based Communication Overlap On GPUs Through Kernel Fusion: https://arxiv.org/abs/2406.06858 - BatchLLM: Optimizing Large Batched LLM Inference with Global Prefix Sharing and Throughput-oriented Token Batching:https://arxiv.org/abs/2412.03594 ================================================ FILE: llm-optimizer/SplitFuse.md ================================================ SplitFuse 调度策略: 0: 先入先出策略(FCFS)。 4:短任务优先(SJF)。 5:长任务优先(LJF)。 6:多级反馈队列(Skip-Join MLFQ)。 7:短任务优先多级反馈队列(SJF-MLFQ)。 建议:一般使用FCFS策略;对于追求极限吞吐的场景建议使用SJF,但是可能会导致长输入等待时间大幅增长;对于希望在吞吐和长输入等待取平衡的使用场景,建议使用Skip-Join MLFQ或SJF-MLFQ策略。 - https://www.hiascend.com/doc_center/source/zh/mindie/10RC3/mindiellm/llmdev/mindie_llm0292.html ================================================ FILE: llm-optimizer/kv-cache.md ================================================ - [H2O: Heavy-Hitter Oracle for Efficient Generative Inference of Large Language Models](https://arxiv.org/pdf/2306.14048) https://github.com/FMInference/H2O - [](https://arxiv.org/pdf/2310.01801) ================================================ FILE: llm-optimizer/xformers.md ================================================ https://github.com/facebookresearch/xformers ================================================ FILE: llm-optimizer/计算通信重叠.md ================================================ FLUX: FAST SOFTWARE-BASED COMMUNICATION OVERLAP ON GPUS THROUGH KERNEL FUSION https://zhuanlan.zhihu.com/p/1908569110075409060 https://github.com/bytedance/flux 万字综述 LLM 训练中的 Overlap 优化:字节 Flux 等 7 种方案 https://blog.csdn.net/xxue345678/article/details/144502704 对DualPipe的一些想法 https://zhuanlan.zhihu.com/p/21525151726 ================================================ FILE: llm-pipeline/REAEMD.md ================================================ ## 训练 - https://github.com/THUDM/ChatGLM3/blob/main/finetune_chatmodel_demo/scripts/finetune_pt_multiturn.sh ``` #! /usr/bin/env bash set -ex LR=1e-4 NUM_GPUS=4 MAX_SEQ_LEN=2048 DEV_BATCH_SIZE=16 GRAD_ACCUMULARION_STEPS=1 MAX_STEP=200 SAVE_INTERVAL=50 DATESTR=`date +%Y%m%d-%H%M%S` RUN_NAME=tool_alpaca_ft DATASET_PATH=formatted_data/tool_alpaca.jsonl BASE_MODEL_PATH=THUDM/chatglm3-6b OUTPUT_DIR=output/${RUN_NAME}-${DATESTR}-${LR} mkdir -p $OUTPUT_DIR torchrun --standalone --nnodes=1 --nproc_per_node=$NUM_GPUS finetune.py \ --train_format multi-turn \ --train_file $DATASET_PATH \ --max_seq_length $MAX_SEQ_LEN \ --preprocessing_num_workers 1 \ --model_name_or_path $BASE_MODEL_PATH \ --output_dir $OUTPUT_DIR \ --per_device_train_batch_size $DEV_BATCH_SIZE \ --gradient_accumulation_steps $GRAD_ACCUMULARION_STEPS \ --max_steps $MAX_STEP \ --logging_steps 1 \ --save_steps $SAVE_INTERVAL \ --fp16 \ --deepspeed configs/deepspeed.json 2>&1 | tee ${OUTPUT_DIR}/train.log ``` - https://github.com/baichuan-inc/Baichuan-7B/blob/main/scripts/train.sh - https://github.com/LianjiaTech/BELLE/tree/main/train/scripts -https://github.com/LianjiaTech/BELLE/blob/main/train/scripts/run_sft.sh ``` #! /bin/bash export CUDA_VISIBLE_DEVICES='0,1,2,3,4,5,6,7' export WANDB_PROJECT=... export WANDB_RUN_ID=... export WANDB_RESUME=allow export ABS_PATH=... export PYTHONPATH="$ABS_PATH/BELLE/train" model_name_or_path=/path_to_llm/hf_llama_7b/ # or bloomz-7b1-mt train_file=belleMath.json validation_file=belleMath-dev1K.json output_dir="$ABS_PATH/BELLE/saved_models/${WANDB_PROJECT}_${WANDB_RUN_ID}" mkdir -p ${output_dir} cache_dir=hf_cache_dir mkdir -p ${cache_dir} cutoff_len=1024 #FT # torchrun --nproc_per_node 8 src/entry_point/sft_train.py \ # --ddp_timeout 36000 \ # --model_name_or_path ${model_name_or_path} \ # --llama \ # --deepspeed configs/deepspeed_config.json \ # --train_file ${train_file} \ # --validation_file ${validation_file} \ # --per_device_train_batch_size 2 \ # --per_device_eval_batch_size 2 \ # --gradient_accumulation_steps 4 \ # --num_train_epochs 2 \ # --model_max_length ${cutoff_len} \ # --save_strategy "steps" \ # --save_total_limit 3 \ # --learning_rate 8e-6 \ # --weight_decay 0.00001 \ # --warmup_ratio 0.05 \ # --lr_scheduler_type "cosine" \ # --logging_steps 10 \ # --evaluation_strategy "steps" \ # --torch_dtype "bfloat16" \ # --bf16 \ # --seed 1234 \ # --gradient_checkpointing \ # --cache_dir ${cache_dir} \ # --output_dir ${output_dir} \ # # --use_flash_attention # # --resume_from_checkpoint ... #LoRA with 8bit # torchrun --nproc_per_node 8 src/entry_point/sft_train.py \ # --ddp_timeout 36000 \ # --model_name_or_path ${model_name_or_path} \ # --llama \ # --use_lora \ # --use_int8_training \ # --lora_config configs/lora_config_llama.json \ # --train_file ${train_file} \ # --validation_file ${validation_file} \ # --per_device_train_batch_size 1 \ # --per_device_eval_batch_size 1 \ # --gradient_accumulation_steps 8 \ # --num_train_epochs 2 \ # --model_max_length ${cutoff_len} \ # --save_strategy "steps" \ # --save_total_limit 3 \ # --learning_rate 8e-6 \ # --weight_decay 0.00001 \ # --warmup_ratio 0.05 \ # --lr_scheduler_type "cosine" \ # --logging_steps 10 \ # --evaluation_strategy "steps" \ # --torch_dtype "bfloat16" \ # --bf16 \ # --seed 1234 \ # --gradient_checkpointing \ # --cache_dir ${cache_dir} \ # --output_dir ${output_dir} \ # # --use_flash_attention # # --resume_from_checkpoint ... # LoRA without 8bit torchrun --nproc_per_node 8 src/entry_point/sft_train.py \ --ddp_timeout 36000 \ --model_name_or_path ${model_name_or_path} \ --llama \ --use_lora \ --deepspeed configs/deepspeed_config_stage3.json \ --lora_config configs/lora_config_llama.json \ --train_file ${train_file} \ --validation_file ${validation_file} \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 1 \ --num_train_epochs 10 \ --model_max_length ${cutoff_len} \ --save_strategy "steps" \ --save_total_limit 3 \ --learning_rate 3e-4 \ --weight_decay 0.00001 \ --warmup_ratio 0.01 \ --lr_scheduler_type "cosine" \ --logging_steps 10 \ --evaluation_strategy "steps" \ --torch_dtype "bfloat16" \ --bf16 \ --seed 1234 \ --gradient_checkpointing \ --cache_dir ${cache_dir} \ --output_dir ${output_dir} \ # --use_flash_attention # --resume_from_checkpoint ... ``` - https://github.com/yangjianxin1/Firefly ================================================ FILE: llm-tools/Pytorch-Profiler.md ================================================ ## 示例 - base-profiler.py - profiler-recipe.py - tensorboard-profiler.py ## PyTorch 分析器 ``` PyTorch 分析器是通过上下文管理器启用的,它接受许多参数,其中一些最有用的是: activities - 要分析的活动列表: ProfilerActivity.CPU - PyTorch 运算符、TorchScript 函数和用户定义的代码标签; ProfilerActivity.CUDA - 设备上的 CUDA 内核; ProfilerActivity.XPU - 设备上的 XPU 内核; record_shapes - 是否记录运算符输入的形状; profile_memory - 是否报告模型的 Tensor 消耗的内存量; ``` ## 使用 Profiler 记录执行事件 ``` with torch.profiler.profile( schedule=torch.profiler.schedule(wait=1, warmup=1, active=3, repeat=1), on_trace_ready=torch.profiler.tensorboard_trace_handler('./log/resnet18'), record_shapes=True, profile_memory=True, with_stack=True ) as prof: for step, batch_data in enumerate(train_loader): prof.step() # Need to call this at each step to notify profiler of steps' boundary. if step >= 1 + 1 + 3: break train(batch_data) ``` 分析器通过上下文管理器启用,并接受多个参数,其中一些最有用的参数是: schedule - 可调用,它将步骤 (int) 作为单个参数,并返回在每个步骤中要执行的 Profiler 作。 在此示例中,Profiler wait=1, warmup=1, active=3, repeat=1 将跳过第一步/迭代,开始预热第二步,记录以下三次迭代,之后跟踪将变为可用,并调用 on_trace_ready(如果设置)。该循环总共重复一次。 每个循环在 TensorBoard 插件中称为 “span”。 在等待步骤中,分析器处于禁用状态。 在预热步骤中,分析器开始跟踪,但结果将被丢弃。这是为了减少性能分析开销。性 能分析开始时的开销很高,很容易给性能分析结果带来偏差。 在active步骤期间,分析器会工作并记录事件。 on_trace_ready - 在每个周期结束时调用的可调用对象; 在此示例中, torch.profiler.tensorboard_trace_handler ,我们使用为 TensorBoard 生成结果文件。分析后,结果文件将保存到 ./log/resnet18 目录中。将此目录指定为 logdir 参数,用于分析 TensorBoard 中的配置文件。 record_shapes — 是否记录运算符输入的形状。 profile_memory - 跟踪张量内存分配/释放。注意,对于旧版本的 pytorch 版本低于 1.10,如果性能分析时间过长,请禁用它或升级到新版本。 with_stack - 记录ops的源信息(文件和行号)。如果在 VS Code ( 参考 ) 中启动 TensorBoard,则单击堆栈帧将导航到特定代码行。 也支持以下非上下文管理器 start/stop。 ``` prof = torch.profiler.profile( schedule=torch.profiler.schedule(wait=1, warmup=1, active=3, repeat=1), on_trace_ready=torch.profiler.tensorboard_trace_handler('./log/resnet18'), record_shapes=True, with_stack=True) prof.start() for step, batch_data in enumerate(train_loader): prof.step() if step >= 1 + 1 + 3: break train(batch_data) prof.stop() ``` ## 跟踪长时间运行的作业 PyTorch 分析器提供了一个额外的 API 来处理长时间运行的作业(例如训练循环)。 跟踪所有执行可能会很慢,并导致跟踪文件非常大。为避免这种情况,请使用可选参数: - schedule - 指定一个函数,该函数将整数参数(步骤编号)作为输入并返回 Profiler 的action,使用此参数的最佳方法是使用 torch.profiler.schedule 辅助函数,该函数可以为您生成schedule。 - on_trace_ready - 指定一个函数,该函数将对分析器的引用作为输入,并在每次新跟踪准备就绪时由分析器调用。 torch.profiler.schedule 辅助函数: ``` from torch.profiler import schedule my_schedule = schedule( skip_first=10, wait=5, warmup=1, active=3, repeat=2) ``` Profiler 假定长时间运行的作业由步骤组成,这些步骤从零开始编号。 上面的示例为性能分析器定义了以下作序列: 参数 skip_first 告诉分析器它应该忽略前 10 个步骤(skip_first 的默认值为零); 在前 skip_first 个步骤之后,分析器开始执行分析器循环; 每个周期包括三个阶段: Idling (wait=5 steps),在此阶段 Profiler 未激活; 预热(Warmup=1 steps),在此阶段,Profiler 开始跟踪,但结果被丢弃; 此阶段用于丢弃 Profiler 在跟踪开始时获得的样本,因为它们通常会因额外的开销而产生偏差; active 跟踪 ( active = 3 steps),在此阶段,Profiler 跟踪并记录数据; 可选的 repeat 参数指定循环数的上限。默认情况下(零值),只要作业运行,分析器就会执行循环。 因此,在上面的示例中,profiler 将跳过前 15 个步骤,将下一步用于热身,active记录接下来的 3 个步骤,再跳过 5 个步骤,将下一步用于热身,主动记录另外 3 个步骤。由于指定了 repeat=2 参数值,因此性能分析器将在前两个周期后停止记录。 ``` sort_by_keyword = "self_" + device + "_time_total" def trace_handler(p): output = p.key_averages().table(sort_by=sort_by_keyword, row_limit=10) print(output) p.export_chrome_trace("/tmp/trace_" + str(p.step_num) + ".json") with profile( activities=activities, schedule=torch.profiler.schedule( wait=1, warmup=1, active=2), on_trace_ready=trace_handler ) as p: for idx in range(8): model(inputs) p.step() ``` ================================================ FILE: llm-tools/README.md ================================================ - [LLM-Viewer](https://github.com/hahnyuan/LLM-Viewer.git) : 可视化大语言模型 (LLMs) 并分析不同硬件平台上性能 - [llm-analysis](https://github.com/cli99/llm-analysis) : 对 Transformer 模型的训练和推理进行延迟和内存分析 - [llm_profiler](https://github.com/harleyszhang/llm_counts) : 大模型理论性能分析工具 - [vLLM 性能分析](https://vllm.hyper.ai/docs/contributing/profiling_index/) - https://docs.vllm.ai/en/stable/contributing/profiling/profiling_index.html - PyTorch Profiler - NVIDIA Nsight Systems - [SGLang Benchmark and Profiling](https://docs.sglang.ai/references/benchmark_and_profiling.html) --json-model-override-args --load-format dummy ## Pytorch Profiler - https://pytorch.org/tutorials/beginner/profiler.html - https://pytorch.org/tutorials/recipes/recipes/profiler_recipe.html - https://pytorch.org/tutorials/intermediate/tensorboard_profiler_tutorial.html 教程: 1. https://pytorch.org/tutorials/prototype/numeric_suite_tutorial.html 2. https://pytorch.org/tutorials/intermediate/fx_profiling_tutorial.html ## NVIDIA Nsight Systems 参考资料: - https://help.aliyun.com/zh/ack/cloud-native-ai-suite/use-cases/using-nsight-system-to-realize-performance-analysis?spm=a2c4g.11186623.help-menu-85222.d_3_0_1.77d64381Fe4MY6&scm=20140722.H_2710010._.OR_help-T_cn~zh-V_1 - https://zhuanlan.zhihu.com/p/718956195 属于系统级性能分析工具,提供从全局视角对整个系统的性能进行监控和分析,包括 CPU、GPU、内存、IO 等多种硬件资源的使用情况,以及它们之间的交互信息。 使用 --python-backtrace=cuda 查看所有 CUDA 内核的 python 调用堆栈,就像在 PyTorch Profiler 中一样。(注意:这可能会导致基于 CUDA 事件的计时的内核运行时间不准确) chrome://tracing python -m sglang.bench_serving --backend sglang --model meta-llama/Llama-3.1-8B-Instruct --num-prompts 2 --sharegpt-output-len 100 --profile ## NVIDIA Nsight Compute 专注于 GPU 内核级的性能分析,主要针对 CUDA 应用程序,深入到 GPU 内部,分析 CUDA 内核的执行情况。 ## NVIDIA Tools Extension Library(NVTX) 通过使用NVTX,开发者可以在代码中添加注释,这些注释可以被NVIDIA的开发工具识别,从而在性能分析和调试过程中提供帮助。 ``` pip install nvtx ``` ``` # example_lib.py import time import nvtx def sleep_for(i): time.sleep(i) @nvtx.annotate() def my_func(): time.sleep(1) with nvtx.annotate("for_loop", color="green"): for i in range(5): sleep_for(i) my_func() ``` ``` nsys profile python demo.py ``` ================================================ FILE: llm-tools/base-profiler.py ================================================ import torch import numpy as np from torch import nn import torch.autograd.profiler as profiler class MyModule(nn.Module): def __init__(self, in_features: int, out_features: int, bias: bool = True): super(MyModule, self).__init__() self.linear = nn.Linear(in_features, out_features, bias) def forward(self, input, mask): with profiler.record_function("LINEAR PASS"): out = self.linear(input) with profiler.record_function("MASK INDICES"): threshold = out.sum(axis=1).mean().item() # forward(13)中,通过 aten::copy_ 运算符将 mask 复制到 CPU,以便它可以使用 NumPy 的 argwhere 函数。 hi_idx = np.argwhere(mask.cpu().numpy() > threshold) # aten::copy_ 在 forward(13) 将数组作为张量复制回 CUDA。 hi_idx = torch.from_numpy(hi_idx).cuda() return out, hi_idx # 分析前向传递 model = MyModule(500, 10).cuda() input = torch.rand(128, 500).cuda() mask = torch.rand((500, 500, 500), dtype=torch.double).cuda() # warm-up model(input, mask) with profiler.profile(with_stack=True, profile_memory=True) as prof: out, idx = model(input, mask) # 打印性能分析器结果 print(prof.key_averages(group_by_stack_n=5).table(sort_by='self_cpu_time_total', row_limit=5)) """ (Some columns are omitted) ------------- ------------ ------------ ------------ --------------------------------- Name Self CPU % Self CPU Self CPU Mem Source Location ------------- ------------ ------------ ------------ --------------------------------- MASK INDICES 87.88% 5.212s -953.67 Mb /mnt/xarfuse/.../torch/au (10): forward /mnt/xarfuse/.../torch/nn (9): /mnt/xarfuse/.../IPython/ aten::copy_ 12.07% 715.848ms 0 b (12): forward /mnt/xarfuse/.../torch/nn (9): /mnt/xarfuse/.../IPython/ /mnt/xarfuse/.../IPython/ LINEAR PASS 0.01% 350.151us -20 b /mnt/xarfuse/.../torch/au (7): forward /mnt/xarfuse/.../torch/nn (9): /mnt/xarfuse/.../IPython/ aten::addmm 0.00% 293.342us 0 b /mnt/xarfuse/.../torch/nn /mnt/xarfuse/.../torch/nn /mnt/xarfuse/.../torch/nn (8): forward /mnt/xarfuse/.../torch/nn aten::mean 0.00% 235.095us 0 b (11): forward /mnt/xarfuse/.../torch/nn (9): /mnt/xarfuse/.../IPython/ /mnt/xarfuse/.../IPython/ ----------------------------- ------------ ---------- ---------------------------------- Self CPU time total: 5.931s """ # mask 使用 torch.double 数据类型初始化。通过将其转换为 torch.float 来减少内存占用。 model = MyModule(500, 10).cuda() input = torch.rand(128, 500).cuda() mask = torch.rand((500, 500, 500), dtype=torch.float).cuda() # warm-up model(input, mask) with profiler.profile(with_stack=True, profile_memory=True) as prof: out, idx = model(input, mask) print(prof.key_averages(group_by_stack_n=5).table(sort_by='self_cpu_time_total', row_limit=5)) """ (Some columns are omitted) ----------------- ------------ ------------ ------------ -------------------------------- Name Self CPU % Self CPU Self CPU Mem Source Location ----------------- ------------ ------------ ------------ -------------------------------- MASK INDICES 93.61% 5.006s -476.84 Mb /mnt/xarfuse/.../torch/au (10): forward /mnt/xarfuse/ /torch/nn (9): /mnt/xarfuse/.../IPython/ aten::copy_ 6.34% 338.759ms 0 b (12): forward /mnt/xarfuse/.../torch/nn (9): /mnt/xarfuse/.../IPython/ /mnt/xarfuse/.../IPython/ aten::as_strided 0.01% 281.808us 0 b (11): forward /mnt/xarfuse/.../torch/nn (9): /mnt/xarfuse/.../IPython/ /mnt/xarfuse/.../IPython/ aten::addmm 0.01% 275.721us 0 b /mnt/xarfuse/.../torch/nn /mnt/xarfuse/.../torch/nn /mnt/xarfuse/.../torch/nn (8): forward /mnt/xarfuse/.../torch/nn aten::_local 0.01% 268.650us 0 b (11): forward _scalar_dense /mnt/xarfuse/.../torch/nn (9): /mnt/xarfuse/.../IPython/ /mnt/xarfuse/.../IPython/ ----------------- ------------ ------------ ------------ -------------------------------- Self CPU time total: 5.347s """ class MyModule(nn.Module): def __init__(self, in_features: int, out_features: int, bias: bool = True): super(MyModule, self).__init__() self.linear = nn.Linear(in_features, out_features, bias) def forward(self, input, mask): with profiler.record_function("LINEAR PASS"): out = self.linear(input) with profiler.record_function("MASK INDICES"): threshold = out.sum(axis=1).mean() # 使用 torch 函数 nonzero() 代替 hi_idx = (mask > threshold).nonzero(as_tuple=True) return out, hi_idx model = MyModule(500, 10).cuda() input = torch.rand(128, 500).cuda() mask = torch.rand((500, 500, 500), dtype=torch.float).cuda() # warm-up model(input, mask) with profiler.profile(with_stack=True, profile_memory=True) as prof: out, idx = model(input, mask) print(prof.key_averages(group_by_stack_n=5).table(sort_by='self_cpu_time_total', row_limit=5)) """ (Some columns are omitted) -------------- ------------ ------------ ------------ --------------------------------- Name Self CPU % Self CPU Self CPU Mem Source Location -------------- ------------ ------------ ------------ --------------------------------- aten::gt 57.17% 129.089ms 0 b (12): forward /mnt/xarfuse/.../torch/nn (25): /mnt/xarfuse/.../IPython/ /mnt/xarfuse/.../IPython/ aten::nonzero 37.38% 84.402ms 0 b (12): forward /mnt/xarfuse/.../torch/nn (25): /mnt/xarfuse/.../IPython/ /mnt/xarfuse/.../IPython/ INDEX SCORE 3.32% 7.491ms -119.21 Mb /mnt/xarfuse/.../torch/au (10): forward /mnt/xarfuse/.../torch/nn (25): /mnt/xarfuse/.../IPython/ aten::as_strided 0.20% 441.587us 0 b (12): forward /mnt/xarfuse/.../torch/nn (25): /mnt/xarfuse/.../IPython/ /mnt/xarfuse/.../IPython/ aten::nonzero _numpy 0.18% 395.602us 0 b (12): forward /mnt/xarfuse/.../torch/nn (25): /mnt/xarfuse/.../IPython/ /mnt/xarfuse/.../IPython/ -------------- ------------ ------------ ------------ --------------------------------- Self CPU time total: 225.801ms """ ================================================ FILE: llm-tools/nsight/README.md ================================================ NVIDIA性能分析工具Nsight Systems/Compute 的使用介绍: https://www.bilibili.com/video/BV15P4y1R7VG (简介及分析案例) --- checklist:可以帮助快速判断模型存在的问题: 数据加载阶段: 小文件是否太多,导致文件 io 耗时太长,读取会浪费很多时间在寻道上。 存储介质是否已达到瓶颈,可以监控存储介质的繁忙度,如果达到瓶颈可以增加存储介质缓解读取性能; 是否启用多进程并行读取数据,另外可以注意线程争用问题,监控线程等待时候是否过长,可以采用私有线程池进行环境; 是否启用提前加载机制来实现 CPU 和 GPU 的并行; 数据预处理阶段: 是否设置开启共享内存 pin_memory,可以直接将数据放置在pin_memory中; 优化 I/O 和网络操作,确保数据以与其计算相匹配的速率馈送到 GPU; 如果是A100或以上的机器,可以考虑开启numa绑定,缓解争用,提升性能; 模型训练阶段: 是否存在大量的CPU运算,可以通过实现GPU实现或去除指定CPU设备,尽可能的让模型运行在GPU上; 模型是否存在GPU利用率不均的情况,尽可能得不在代码里指定GPU运行的卡; 对于比较复杂运行效率较低的模块,可以通过实现融合的大GPU算子提升训练速度; 避免指标和日志打印太频繁,CPU 和 GPU 频繁切换导致 GPU 利用率低; 是否开启AMP来提升模型的训练性能; 使用最新的高性能库和 GPU 驱动程序,cuda是否升级到最新版本; --- 优化策略 1. 减少不必要的同步: 尽量减少显式的同步调用,如 cudaDeviceSynchronize。 使用 cudaStreamWaitEvent 等事件机制来实现更细粒度的同步控制。 2. 使用多个流: 将独立的CUDA操作分配到不同的流中,以实现并行执行。 确保内核启动和内存拷贝操作尽可能在不同流中并行执行。 3. 优化内存拷贝: 使用异步内存拷贝函数(如 cudaMemcpyAsync )并将其分配到不同的流中。尽量减少Host与Device之间的内存拷贝次数,使用统一内存(Unified Memory)或零拷贝(Zero Copy)技术。 --- export CUDA_VISIBLE_DEVICES=2 nsys profile -w true \ -t cuda,nvtx,osrt,cudnn,cublas \ -s cpu \ --capture-range=cudaProfilerApi \ --capture-range-end=stop \ --cudabacktrace=true -x true --force-overwrite true -o nsys-sglang-046-14 python3 qwen25_sys.py ================================================ FILE: llm-tools/nsight.md ================================================ https://docs.nvidia.com/nsight-systems/UserGuide/index.html nsight system 使用 https://zhuanlan.zhihu.com/p/433500747 ================================================ FILE: llm-tools/nvtx.md ================================================ - https://nvtx.readthedocs.io/en/latest/annotate.html - https://github.com/NVIDIA/NVTX 装饰器: ``` @nvtx.annotate(message="my_message", color="blue") def my_func(): pass ``` 上下文管理器: ``` with nvtx.annotate(message="my_message", color="green"): pass ``` 范围: ``` rng = nvtx.start_range(message="my_message", color="blue") # ... do something ... # nvtx.end_range(rng) ``` 与start_range类似,但可以嵌套: ``` nvtx.push_range("batch " + str(i),"blue") nvtx.pop_range() ``` ================================================ FILE: llm-tools/profiler-recipe.py ================================================ # pip install torch torchvision import torch import torchvision.models as models from torch.profiler import profile, record_function, ProfilerActivity model = models.resnet18() inputs = torch.randn(5, 3, 224, 224) with profile(activities=[ProfilerActivity.CPU], record_shapes=True) as prof: with record_function("model_inference"): model(inputs) print(prof.key_averages().table(sort_by="cpu_time_total", row_limit=10)) # --------------------------------- ------------ ------------ ------------ ------------ # Name Self CPU CPU total CPU time avg # of Calls # --------------------------------- ------------ ------------ ------------ ------------ # model_inference 5.509ms 57.503ms 57.503ms 1 # aten::conv2d 231.000us 31.931ms 1.597ms 20 # aten::convolution 250.000us 31.700ms 1.585ms 20 # aten::_convolution 336.000us 31.450ms 1.573ms 20 # aten::mkldnn_convolution 30.838ms 31.114ms 1.556ms 20 # aten::batch_norm 211.000us 14.693ms 734.650us 20 # aten::_batch_norm_impl_index 319.000us 14.482ms 724.100us 20 # aten::native_batch_norm 9.229ms 14.109ms 705.450us 20 # aten::mean 332.000us 2.631ms 125.286us 21 # aten::select 1.668ms 2.292ms 8.988us 255 # --------------------------------- ------------ ------------ ------------ ------------ # Self CPU time total: 57.549m # 要获得更精细粒度的结果并包含运算符输入形状 print(prof.key_averages(group_by_input_shape=True).table(sort_by="cpu_time_total", row_limit=10)) # --------------------------------- ------------ ------------------------------------------- # Name CPU total Input Shapes # --------------------------------- ------------ ------------------------------------------- # model_inference 57.503ms [] # aten::conv2d 8.008ms [5,64,56,56], [64,64,3,3], [], ..., []] # aten::convolution 7.956ms [[5,64,56,56], [64,64,3,3], [], ..., []] # aten::_convolution 7.909ms [[5,64,56,56], [64,64,3,3], [], ..., []] # aten::mkldnn_convolution 7.834ms [[5,64,56,56], [64,64,3,3], [], ..., []] # aten::conv2d 6.332ms [[5,512,7,7], [512,512,3,3], [], ..., []] # aten::convolution 6.303ms [[5,512,7,7], [512,512,3,3], [], ..., []] # aten::_convolution 6.273ms [[5,512,7,7], [512,512,3,3], [], ..., []] # aten::mkldnn_convolution 6.233ms [[5,512,7,7], [512,512,3,3], [], ..., []] # aten::conv2d 4.751ms [[5,256,14,14], [256,256,3,3], [], ..., []] # --------------------------------- ------------ ------------------------------------------- # Self CPU time total: 57.549ms # Profiler 还可用于分析在 GPU 和 XPU 上执行的模型的性能 if torch.cuda.is_available(): device = 'cuda' elif torch.xpu.is_available(): device = 'xpu' else: print('Neither CUDA nor XPU devices are available to demonstrate profiling on acceleration devices') import sys sys.exit(0) activities = [ProfilerActivity.CPU, ProfilerActivity.CUDA, ProfilerActivity.XPU] sort_by_keyword = device + "_time_total" model = models.resnet18().to(device) inputs = torch.randn(5, 3, 224, 224).to(device) with profile(activities=activities, record_shapes=True) as prof: with record_function("model_inference"): model(inputs) print(prof.key_averages().table(sort_by=sort_by_keyword, row_limit=10)) # ------------------------------------------------------- ------------ ------------ # Name Self CUDA CUDA total # ------------------------------------------------------- ------------ ------------ # model_inference 0.000us 11.666ms # aten::conv2d 0.000us 10.484ms # aten::convolution 0.000us 10.484ms # aten::_convolution 0.000us 10.484ms # aten::_convolution_nogroup 0.000us 10.484ms # aten::thnn_conv2d 0.000us 10.484ms # aten::thnn_conv2d_forward 10.484ms 10.484ms # void at::native::im2col_kernel(long, float co... 3.844ms 3.844ms # sgemm_32x32x32_NN 3.206ms 3.206ms # sgemm_32x32x32_NN_vec 3.093ms 3.093ms # ------------------------------------------------------- ------------ ------------ # Self CPU time total: 23.015ms # Self CUDA time total: 11.666ms ########################################################################################## # PyTorch 分析器还可以显示在执行模型算子期间分配(或释放)的内存量(由模型的张量使用)。 model = models.resnet18() inputs = torch.randn(5, 3, 224, 224) with profile(activities=[ProfilerActivity.CPU], profile_memory=True, record_shapes=True) as prof: model(inputs) # ‘self’ memory 对应于运算符分配 (释放) 的内存,不包括对其他运算符的 children 调用。 print(prof.key_averages().table(sort_by="self_cpu_memory_usage", row_limit=10)) # (omitting some columns) # --------------------------------- ------------ ------------ ------------ # Name CPU Mem Self CPU Mem # of Calls # --------------------------------- ------------ ------------ ------------ # aten::empty 94.79 Mb 94.79 Mb 121 # aten::max_pool2d_with_indices 11.48 Mb 11.48 Mb 1 # aten::addmm 19.53 Kb 19.53 Kb 1 # aten::empty_strided 572 b 572 b 25 # aten::resize_ 240 b 240 b 6 # aten::abs 480 b 240 b 4 # aten::add 160 b 160 b 20 # aten::masked_select 120 b 112 b 1 # aten::ne 122 b 53 b 6 # aten::eq 60 b 30 b 2 # --------------------------------- ------------ ------------ ------------ # Self CPU time total: 53.064ms print(prof.key_averages().table(sort_by="cpu_memory_usage", row_limit=10)) # --------------------------------- ------------ ------------ ------------ # Name CPU Mem Self CPU Mem # of Calls # --------------------------------- ------------ ------------ ------------ # aten::empty 94.79 Mb 94.79 Mb 121 # aten::batch_norm 47.41 Mb 0 b 20 # aten::_batch_norm_impl_index 47.41 Mb 0 b 20 # aten::native_batch_norm 47.41 Mb 0 b 20 # aten::conv2d 47.37 Mb 0 b 20 # aten::convolution 47.37 Mb 0 b 20 # aten::_convolution 47.37 Mb 0 b 20 # aten::mkldnn_convolution 47.37 Mb 0 b 20 # aten::max_pool2d 11.48 Mb 0 b 1 # aten::max_pool2d_with_indices 11.48 Mb 11.48 Mb 1 # --------------------------------- ------------ ------------ ------------ # Self CPU time total: 53.064ms # 性能分析结果可以输出为 .json 跟踪文件: 跟踪 CUDA 或 XPU 内核 # 用户可以在 cpu、cuda 和 xpu 之间切换 device = 'cuda' activities = [ProfilerActivity.CPU, ProfilerActivity.CUDA, ProfilerActivity.XPU] model = models.resnet18().to(device) inputs = torch.randn(5, 3, 224, 224).to(device) with profile(activities=activities) as prof: model(inputs) prof.export_chrome_trace("trace.json") # Profiler 可用于分析 Python 和 TorchScript 堆栈跟踪 sort_by_keyword = "self_" + device + "_time_total" with profile( activities=activities, with_stack=True, ) as prof: model(inputs) # Print aggregated stats print(prof.key_averages(group_by_stack_n=5).table(sort_by=sort_by_keyword, row_limit=2)) # ------------------------- ----------------------------------------------------------- # Name Source Location # ------------------------- ----------------------------------------------------------- # aten::thnn_conv2d_forward .../torch/nn/modules/conv.py(439): _conv_forward # .../torch/nn/modules/conv.py(443): forward # .../torch/nn/modules/module.py(1051): _call_impl # .../site-packages/torchvision/models/resnet.py(63): forward # .../torch/nn/modules/module.py(1051): _call_impl # aten::thnn_conv2d_forward .../torch/nn/modules/conv.py(439): _conv_forward # .../torch/nn/modules/conv.py(443): forward # .../torch/nn/modules/module.py(1051): _call_impl # .../site-packages/torchvision/models/resnet.py(59): forward # .../torch/nn/modules/module.py(1051): _call_impl # ------------------------- ----------------------------------------------------------- # Self CPU time total: 34.016ms # Self CUDA time total: 11.659ms ================================================ FILE: llm-tools/tensorboard-profiler.py ================================================ # pip install torch torchvision # pip install torch_tb_profiler # tensorboard --logdir=./log # http://localhost:6006/#pytorch_profiler # tensorboard --logdir=log_dir --host=127.0.0.1 import torch import torch.nn import torch.optim import torch.profiler import torch.utils.data import torchvision.datasets import torchvision.models import torchvision.transforms as T transform = T.Compose( [T.Resize(224), T.ToTensor(), T.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) train_set = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) train_loader = torch.utils.data.DataLoader(train_set, batch_size=32, shuffle=True) device = torch.device("cuda:0") model = torchvision.models.resnet18(weights='IMAGENET1K_V1').cuda(device) criterion = torch.nn.CrossEntropyLoss().cuda(device) optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9) model.train() def train(data): inputs, labels = data[0].to(device=device), data[1].to(device=device) outputs = model(inputs) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() # 使用 Profiler 记录执行事件 with torch.profiler.profile( schedule=torch.profiler.schedule(wait=1, warmup=1, active=3, repeat=1), on_trace_ready=torch.profiler.tensorboard_trace_handler('./log/resnet18'), record_shapes=True, profile_memory=True, with_stack=True ) as prof: for step, batch_data in enumerate(train_loader): prof.step() # Need to call this at each step to notify profiler of steps' boundary. if step >= 1 + 1 + 3: break train(batch_data) ================================================ FILE: llm-tools/可视化.md ================================================ Visualizing and Explaining Transformer Models From the Ground Up https://deepgram.com/learn/visualizing-and-explaining-transformer-models-from-the-ground-up --- https://poloclub.github.io/transformer-explainer/ https://github.com/poloclub/transformer-explainer https://medium.com/@praneethk.aiml/exploring-llm-visualization-techniques-tools-and-insights-4704c32c177e --- https://github.com/bbycroft/llm-viz https://bbycroft.net/llm https://zhuanlan.zhihu.com/p/680063546 --- LLM量化可视化指南 https://newsletter.maartengrootendorst.com/p/a-visual-guide-to-quantization https://blog.csdn.net/weixin_41451209/article/details/141442618 --- 权重量化及可视化权重分布 https://www.analyticsvidhya.com/blog/2025/01/neural-network-weight-quantization/ ================================================ FILE: llm-train/README.md ================================================ ## 训练 - https://github.com/yangjianxin1/Firefly/ - https://github.com/hiyouga/LLaMA-Factory - Characterization of Large Language Model Development in the Datacenter:https://arxiv.org/pdf/2403.07648 - MegaScale: Scaling Large Language Model Training to More Than 10,000 GPUs:https://www.usenix.org/system/files/nsdi24-jiang-ziheng.pdf ================================================ FILE: llm-train/alpa/train/pipeshard_parallelism.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Distributed Training with Both Shard and Pipeline Parallelism\n\nAlpa can automatically parallelizes jax functions with both shard\nparallelism (a.k.a. intra-operator parallelism) and pipeline parallelism\n(a.k.a. inter-operator parallelism). Shard parallelism includes\ndata parallelism, operator parallelism, and their combinations.\nThe previous `quick start ` tutorial focuses on\nusing Alpa for shard parallelism.\n\nIn this tutorial, we show how to use Alpa with both shard and pipeline parallelism.\nFirst, we show how to use Alpa to manually assign stages for pipeline parallelism.\nThen we show how to use Alpa to automate this process.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import Libraries and Initialize Environment\nFirst, import the required libraries.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import alpa\nfrom alpa.testing import assert_allclose\nimport copy\nfrom flax import linen as nn\nfrom flax.training.train_state import TrainState\nimport jax\nimport jax.numpy as jnp\nfrom jax import random\nimport optax\nimport ray\n\nalpa.util.disable_tqdm_globally()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Connect to a Ray Cluster\nAlpa uses a distributed framework `ray `_ to manage\nthe cluster and disributed workers. We initialize ray and alpa.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "ray.init()\nalpa.init(cluster=\"ray\")\n\n# Alternatively, you can use the following command to connect to an existing\n# ray cluster.\n# ray.init(address=\"auto\")\n#\n# Note: `alpa.init(cluster=\"ray\")` uses the gpus resources of the whole ray\n# cluster. To configure Alpa to only use a subset of gpu resources, one can \n# specific the number of nodes and number of gpus per node.\n# For example, only run 2 gpus when 8 gpus are available \n# alpa.init('ray', devices_per_node=2, num_nodes=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Train an MLP on a Single Device\nIn this tutorial, we use a toy dataset to train an MLP model.\nSpecifically, we use the model to fit the function: $y = Wx + b$.\nNote that now this model is being executed on CPU because we force the driver\nprocess to use the CPU.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "class MLPModel(nn.Module):\n hidden_dim: int\n\n @nn.compact\n def __call__(self, x):\n x = nn.Dense(features=self.hidden_dim * 4)(x)\n x = nn.relu(x)\n x = nn.Dense(features=self.hidden_dim)(x)\n x = nn.relu(x)\n x = nn.Dense(features=self.hidden_dim * 4)(x)\n x = nn.relu(x)\n x = nn.Dense(features=self.hidden_dim)(x)\n x = nn.relu(x)\n return x\n\n\ndim = 2048\nbatch_size = 2048\n\n# Generate ground truth W and b\nrngkey = jax.random.PRNGKey(0)\nk1, k2 = random.split(rngkey)\nW = random.normal(k1, (dim, dim))\nb = random.normal(k2, (dim,))\n\n# Generate the training data\nksample, knoise = random.split(k1)\nx = random.normal(ksample, (batch_size, dim))\ny = (x @ W + b) + 0.1 * random.normal(knoise, (batch_size, dim))\n\n# Initialize a train state, which includes the model paramter and optimizer\n# state.\nmodel = MLPModel(hidden_dim=dim)\nparams = model.init(rngkey, x)\ntx = optax.adam(learning_rate=1e-3)\nstate = TrainState.create(apply_fn=model.apply, params=params, tx=tx)\n\n\n# Define the training step\ndef train_step(state, batch):\n\n def loss_func(params):\n out = model.apply(params, batch[\"x\"])\n loss = jnp.mean((out - batch[\"y\"])**2)\n return loss\n\n grads = jax.grad(loss_func)(state.params)\n new_state = state.apply_gradients(grads=grads)\n return new_state\n\n\nbatch = {\"x\": x, \"y\": y}\nexpected_state = train_step(state, batch)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pipeline Parallelism with Manual Assignment\nPipeline paralleism requires partitioning the model into several pipeline\nstages. To manually assign stages, we can use ``alpa.mark_pipeline_boundary``\nto mark the boundary of each pipeline stage in the forward function.\nNote that each pipeline stage is also automatically parallelized by the\nshard parallel pass.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Define a MLP model with manual stage boundaries.\nclass ManualPipelineMLPModel(nn.Module):\n hidden_dim: int\n\n @nn.compact\n def __call__(self, x):\n x = nn.Dense(features=self.hidden_dim * 4)(x)\n x = nn.relu(x)\n x = nn.Dense(features=self.hidden_dim)(x)\n x = nn.relu(x)\n # Use this boundary marker to separate the model into two stages.\n alpa.mark_pipeline_boundary()\n x = nn.Dense(features=self.hidden_dim * 4)(x)\n x = nn.relu(x)\n x = nn.Dense(features=self.hidden_dim)(x)\n x = nn.relu(x)\n return x\n\n\n# Initialize the train state with the same parameters as the single-device\n# model.\nmanual_pipeline_model = ManualPipelineMLPModel(hidden_dim=dim)\nmanual_pipeline_state = TrainState.create(apply_fn=manual_pipeline_model.apply,\n params=copy.deepcopy(params),\n tx=tx)\n\n\n# Define the training step.\n# We use the \"alpa.PipeshardParallel\" option to let alpa use both\n# pipeline parallelism and shard parallelism. To make pipeline parallelism\n# efficient, we need to fill the pipeline with many micro batches,\n# so a `num_micro_batches` should be specified.\n@alpa.parallelize(method=alpa.PipeshardParallel(num_micro_batches=16,\n layer_option=\"manual\"))\ndef manual_pipeline_train_step(state, batch):\n\n def loss_func(params):\n out = state.apply_fn(params, batch[\"x\"])\n loss = jnp.mean((out - batch[\"y\"])**2)\n return loss\n\n # We use `alpa.grad` here to separate the apply gradient stage with the\n # forward/backward stages in the pipeline. This is necessary to ensure that\n # the gradient accumulation is correct.\n grads = alpa.grad(loss_func)(state.params)\n new_state = state.apply_gradients(grads=grads)\n return new_state\n\n\nmanual_pipeline_actual_state = manual_pipeline_train_step(\n manual_pipeline_state, batch)\nassert_allclose(expected_state.params,\n manual_pipeline_actual_state.params,\n atol=5e-3)\n\nalpa.shutdown()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Note

In addition, Alpa supports more flexible manual assignments of pipeline\n parallelism strategies. In the above example, each partitioned stages will\n be assigned an equal number of devices to run. If you want to control the\n device assignment of each stage, you can use the more advanced\n ``stage_option=alpa.ManualStageOption``.

\n\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pipeline Parallelism with Automatic Assignment\nAlpa also supports automatically partitioning the model into multiple\npipeline stages and assign each pipeline stage a device mesh such that\nthe total execution latency is minimized. Specifically, the automatic\npartitioning algorithm consists of the following steps:\n\n1. **Layer Construction:** In this step, the operators in the model are\n clustered into \"layers\" based on a graph clustering algorithm. The\n user needs to specify the total number of layers (i.e. clusters) as\n a hyperparameter.\n2. **Stage Construction and Mesh Slicing:** In this step, we partition\n the device cluster (device mesh) to multiple submeshes and assign\n layers to submeshes to form pipeline stages to minimize the total\n pipeline execution latency.\n\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "alpa.init(cluster=\"ray\")\n\n# Define the parallel method.\n# `alpa.AutoLayerOption(layer_num=2)` means we use the auto layer construcion\n# algorithm to cluster primitive operators into two layers.\n# `stage_option=\"auto\"` means we enable the auto stage construction algorithm.\nmethod = alpa.PipeshardParallel(num_micro_batches=16,\n layer_option=alpa.AutoLayerOption(layer_num=2),\n stage_option=\"auto\")\n\n\n# Define the training step. The function body is the same as the above one.\n@alpa.parallelize(method=method)\ndef auto_pipeline_train_step(state, batch):\n\n def loss_func(params):\n out = state.apply_fn(params, batch[\"x\"])\n loss = jnp.mean((out - batch[\"y\"])**2)\n return loss\n\n # Again, we use `alpa.grad` here to separate the apply gradient stage with\n # the forward/backward stages in the pipeline.\n grads = alpa.grad(loss_func)(state.params)\n new_state = state.apply_gradients(grads=grads)\n return new_state\n\n\n# In the first call, alpa triggers the compilation.\n# The compilation first profiles several costs and solves an optimization\n# problem to get the optimal pipeline assignments.\nauto_pipeline_actual_state = auto_pipeline_train_step(state, batch)\nassert_allclose(expected_state.params,\n auto_pipeline_actual_state.params,\n atol=5e-3)\n\nalpa.shutdown()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interpret the Results\n**Some basic concepts**\n- Cluster mesh and submeshes\n - Cluster mesh is a computer cluster that contains GPUs. A ``N\u00d7M`` cluster mesh means the cluster has ``N`` physical machines and each machine has ``M`` GPUs.\n - Submeshes can be obtained by slicing from the cluster mesh. For example, given a ``N\u00d7M`` cluster mesh, a submesh ``(1, M)`` means using all GPUs in one physical machine.\n - For more details on how Alpa uses submeshes to solve *inter-operator parallelism*, you can read the **Section 5: Inter-Operator Parallelism** in the `Alpa paper `_.\n- Device mesh and logical mesh\n - A device mesh is a 2-dimensional logical view of a set of physical devices.\n - For a set of physical devices, there can be multiple logical views. For example, given 2 nodes and 8 GPUs per node (i.e., 16 devices in total), we can view them as a 2\u00d78, 1\u00d716, 4\u00d74, 8\u00d72, or 16\u00d71 device mesh.\n - The mapping between physical devices and the logical device mesh view is optimized by the inter-op pass\n - Hence, you can see ``Result mesh_shapes`` and the corresponding ``Result logical_mesh_shapes`` in the optimization output.\n\nWith the basic concepts in mind, you now can better understand the ``ModuleProfileResult``:\n- ``ModuleProfileResult``: ``result[(i, j, s, c), m]`` means this stage contains forward layers ``i, i+1, ..., j`` and corresponding backward layers, and runs under the ``s``-th submesh and the ``c``-th auto sharding config for the submesh. The ``m = 0`` means the result is for the forward pass, and ``m = 1`` for backward pass.\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.12" } }, "nbformat": 4, "nbformat_minor": 0 } ================================================ FILE: llm-train/alpa/train/pipeshard_parallelism.py ================================================ """ Distributed Training with Both Shard and Pipeline Parallelism ============================================================= Alpa can automatically parallelizes jax functions with both shard parallelism (a.k.a. intra-operator parallelism) and pipeline parallelism (a.k.a. inter-operator parallelism). Shard parallelism includes data parallelism, operator parallelism, and their combinations. The previous :ref:`quick start ` tutorial focuses on using Alpa for shard parallelism. In this tutorial, we show how to use Alpa with both shard and pipeline parallelism. First, we show how to use Alpa to manually assign stages for pipeline parallelism. Then we show how to use Alpa to automate this process. """ ################################################################################ # Import Libraries and Initialize Environment # ------------------------------------------- # First, import the required libraries. import alpa from alpa.testing import assert_allclose import copy from flax import linen as nn from flax.training.train_state import TrainState import jax import jax.numpy as jnp from jax import random import optax import ray alpa.util.disable_tqdm_globally() ################################################################################ # Connect to a Ray Cluster # ------------------------ # Alpa uses a distributed framework `ray `_ to manage # the cluster and disributed workers. We initialize ray and alpa. ray.init() alpa.init(cluster="ray") # Alternatively, you can use the following command to connect to an existing # ray cluster. # ray.init(address="auto") # # Note: `alpa.init(cluster="ray")` uses the gpus resources of the whole ray # cluster. To configure Alpa to only use a subset of gpu resources, one can # specific the number of nodes and number of gpus per node. # For example, only run 2 gpus when 8 gpus are available # alpa.init('ray', devices_per_node=2, num_nodes=1) ################################################################################ # Train an MLP on a Single Device # ------------------------------- # In this tutorial, we use a toy dataset to train an MLP model. # Specifically, we use the model to fit the function: :math:`y = Wx + b`. # Note that now this model is being executed on CPU because we force the driver # process to use the CPU. class MLPModel(nn.Module): hidden_dim: int @nn.compact def __call__(self, x): x = nn.Dense(features=self.hidden_dim * 4)(x) x = nn.relu(x) x = nn.Dense(features=self.hidden_dim)(x) x = nn.relu(x) x = nn.Dense(features=self.hidden_dim * 4)(x) x = nn.relu(x) x = nn.Dense(features=self.hidden_dim)(x) x = nn.relu(x) return x dim = 2048 batch_size = 2048 # Generate ground truth W and b rngkey = jax.random.PRNGKey(0) k1, k2 = random.split(rngkey) W = random.normal(k1, (dim, dim)) b = random.normal(k2, (dim,)) # Generate the training data ksample, knoise = random.split(k1) x = random.normal(ksample, (batch_size, dim)) y = (x @ W + b) + 0.1 * random.normal(knoise, (batch_size, dim)) # Initialize a train state, which includes the model paramter and optimizer # state. model = MLPModel(hidden_dim=dim) params = model.init(rngkey, x) tx = optax.adam(learning_rate=1e-3) state = TrainState.create(apply_fn=model.apply, params=params, tx=tx) # Define the training step def train_step(state, batch): def loss_func(params): out = model.apply(params, batch["x"]) loss = jnp.mean((out - batch["y"])**2) return loss grads = jax.grad(loss_func)(state.params) new_state = state.apply_gradients(grads=grads) return new_state batch = {"x": x, "y": y} expected_state = train_step(state, batch) ################################################################################ # Pipeline Parallelism with Manual Assignment # ------------------------------------------- # Pipeline paralleism requires partitioning the model into several pipeline # stages. To manually assign stages, we can use ``alpa.mark_pipeline_boundary`` # to mark the boundary of each pipeline stage in the forward function. # Note that each pipeline stage is also automatically parallelized by the # shard parallel pass. # Define a MLP model with manual stage boundaries. class ManualPipelineMLPModel(nn.Module): hidden_dim: int @nn.compact def __call__(self, x): x = nn.Dense(features=self.hidden_dim * 4)(x) x = nn.relu(x) x = nn.Dense(features=self.hidden_dim)(x) x = nn.relu(x) # Use this boundary marker to separate the model into two stages. alpa.mark_pipeline_boundary() x = nn.Dense(features=self.hidden_dim * 4)(x) x = nn.relu(x) x = nn.Dense(features=self.hidden_dim)(x) x = nn.relu(x) return x # Initialize the train state with the same parameters as the single-device # model. manual_pipeline_model = ManualPipelineMLPModel(hidden_dim=dim) manual_pipeline_state = TrainState.create(apply_fn=manual_pipeline_model.apply, params=copy.deepcopy(params), tx=tx) # Define the training step. # We use the "alpa.PipeshardParallel" option to let alpa use both # pipeline parallelism and shard parallelism. To make pipeline parallelism # efficient, we need to fill the pipeline with many micro batches, # so a `num_micro_batches` should be specified. @alpa.parallelize(method=alpa.PipeshardParallel(num_micro_batches=16, layer_option="manual")) def manual_pipeline_train_step(state, batch): def loss_func(params): out = state.apply_fn(params, batch["x"]) loss = jnp.mean((out - batch["y"])**2) return loss # We use `alpa.grad` here to separate the apply gradient stage with the # forward/backward stages in the pipeline. This is necessary to ensure that # the gradient accumulation is correct. grads = alpa.grad(loss_func)(state.params) new_state = state.apply_gradients(grads=grads) return new_state manual_pipeline_actual_state = manual_pipeline_train_step( manual_pipeline_state, batch) assert_allclose(expected_state.params, manual_pipeline_actual_state.params, atol=5e-3) alpa.shutdown() #################### # # .. note:: # # In addition, Alpa supports more flexible manual assignments of pipeline # parallelism strategies. In the above example, each partitioned stages will # be assigned an equal number of devices to run. If you want to control the # device assignment of each stage, you can use the more advanced # ``stage_option=alpa.ManualStageOption``. ################################################################################ # Pipeline Parallelism with Automatic Assignment # ---------------------------------------------- # Alpa also supports automatically partitioning the model into multiple # pipeline stages and assign each pipeline stage a device mesh such that # the total execution latency is minimized. Specifically, the automatic # partitioning algorithm consists of the following steps: # # 1. **Layer Construction:** In this step, the operators in the model are # clustered into "layers" based on a graph clustering algorithm. The # user needs to specify the total number of layers (i.e. clusters) as # a hyperparameter. # 2. **Stage Construction and Mesh Slicing:** In this step, we partition # the device cluster (device mesh) to multiple submeshes and assign # layers to submeshes to form pipeline stages to minimize the total # pipeline execution latency. alpa.init(cluster="ray") # Define the parallel method. # `alpa.AutoLayerOption(layer_num=2)` means we use the auto layer construcion # algorithm to cluster primitive operators into two layers. # `stage_option="auto"` means we enable the auto stage construction algorithm. method = alpa.PipeshardParallel(num_micro_batches=16, layer_option=alpa.AutoLayerOption(layer_num=2), stage_option="auto") # Define the training step. The function body is the same as the above one. @alpa.parallelize(method=method) def auto_pipeline_train_step(state, batch): def loss_func(params): out = state.apply_fn(params, batch["x"]) loss = jnp.mean((out - batch["y"])**2) return loss # Again, we use `alpa.grad` here to separate the apply gradient stage with # the forward/backward stages in the pipeline. grads = alpa.grad(loss_func)(state.params) new_state = state.apply_gradients(grads=grads) return new_state # In the first call, alpa triggers the compilation. # The compilation first profiles several costs and solves an optimization # problem to get the optimal pipeline assignments. auto_pipeline_actual_state = auto_pipeline_train_step(state, batch) assert_allclose(expected_state.params, auto_pipeline_actual_state.params, atol=5e-3) alpa.shutdown() ################################################################################ # Interpret the Results # --------------------- # **Some basic concepts** # - Cluster mesh and submeshes # - Cluster mesh is a computer cluster that contains GPUs. A ``N×M`` cluster mesh means the cluster has ``N`` physical machines and each machine has ``M`` GPUs. # - Submeshes can be obtained by slicing from the cluster mesh. For example, given a ``N×M`` cluster mesh, a submesh ``(1, M)`` means using all GPUs in one physical machine. # - For more details on how Alpa uses submeshes to solve *inter-operator parallelism*, you can read the **Section 5: Inter-Operator Parallelism** in the `Alpa paper `_. # - Device mesh and logical mesh # - A device mesh is a 2-dimensional logical view of a set of physical devices. # - For a set of physical devices, there can be multiple logical views. For example, given 2 nodes and 8 GPUs per node (i.e., 16 devices in total), we can view them as a 2×8, 1×16, 4×4, 8×2, or 16×1 device mesh. # - The mapping between physical devices and the logical device mesh view is optimized by the inter-op pass # - Hence, you can see ``Result mesh_shapes`` and the corresponding ``Result logical_mesh_shapes`` in the optimization output. # # With the basic concepts in mind, you now can better understand the ``ModuleProfileResult``: # - ``ModuleProfileResult``: ``result[(i, j, s, c), m]`` means this stage contains forward layers ``i, i+1, ..., j`` and corresponding backward layers, and runs under the ``s``-th submesh and the ``c``-th auto sharding config for the submesh. The ``m = 0`` means the result is for the forward pass, and ``m = 1`` for backward pass. ================================================ FILE: llm-train/alpaca/README.md ================================================ # Stanford Alpaca - 源码: https://github.com/tatsu-lab/stanford_alpaca - commit id: `73cac8be49a66ca5d159ee9199428804e1e6aabe` ## 启动命令 ``` torchrun --nproc_per_node=8 --master_port=11223 train.py \ --model_name_or_path /data/nfs/guodong.li/pretrain/hf-llama-model/llama-7b \ --data_path /data/nfs/guodong.li/data/alpaca_data_cleaned.json \ --output_dir /data/nfs/guodong.li/output/alpaca/sft_7b \ --num_train_epochs 1 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 100 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --gradient_checkpointing True \ --fp16 True \ --deepspeed ds_config.json deepspeed --num_gpus=4 train.py \ --deepspeed ds_config.json \ --model_name_or_path /data/nfs/guodong.li/pretrain/hf-llama-model/llama-7b \ --data_path /data/nfs/guodong.li/data/alpaca_data_cleaned.json \ --output_dir /data/nfs/guodong.li/output/alpaca/sft_7b \ --num_train_epochs 1 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 100 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --gradient_checkpointing True \ --fp16 True deepspeed --include localhost:4,5,6,7 train.py \ --deepspeed ds_config.json \ --model_name_or_path /data/nfs/guodong.li/pretrain/hf-llama-model/llama-7b \ --data_path /data/nfs/guodong.li/data/alpaca_data_cleaned.json \ --output_dir /data/nfs/guodong.li/output/alpaca/sft_7b \ --num_train_epochs 1 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 100 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --gradient_checkpointing True \ --fp16 True ``` ## A800-DDP 单机多卡: ``` deepspeed --include localhost:0,1,2,3,4,5,6,7 train_ddp.py \ --deepspeed ds_config_zero2_ddp.json \ --model_name_or_path /home/guodong.li/h800-workspace/model/llama-13b \ --data_path /home/guodong.li/h800-workspace/data/alpaca_data_cleaned.json \ --output_dir /home/guodong.li/h800-workspace/output/llama-13b-sft \ --max_steps 100 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 4 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 50 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --gradient_checkpointing True \ --fp16 True ``` 多机多卡: ``` deepspeed --hostfile=/home/guodong.li/code/hostfile train_ddp.py \ --deepspeed ds_config_zero2_ddp.json \ --model_name_or_path /data/nfs/guodong.li/pretrain/hf-llama-model/llama-13b \ --data_path /data/nfs/guodong.li/data/alpaca_data_cleaned.json \ --output_dir /data/nfs/guodong.li/output/llama-13b-sft-multinode \ --max_steps 100 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 4 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 50 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --gradient_checkpointing True \ --fp16 True ``` ``` deepspeed --include localhost:7 train.py \ --deepspeed ds_config_zero2.json \ --model_name_or_path /data/nfs/guodong.li/pretrain/hf-llama-model/llama-7b \ --data_path /data/nfs/guodong.li/data/alpaca_data_cleaned.json \ --output_dir /data/nfs/guodong.li/output/llama-7b-sft \ --max_steps 800 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 4 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 1000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --gradient_checkpointing True \ --fp16 True {'loss': 1.4187, 'learning_rate': 2e-05, 'epoch': 0.12} {'train_runtime': 5606.7798, 'train_samples_per_second': 1.141, 'train_steps_per_second': 0.143, 'train_loss': 1.1899223804473877, 'epoch': 0.12} 100%|█████████████████████████████████████████████████████████████████████| 800/800 [1:33:26<00:00, 7.01s/it] [2023-07-02 22:28:34,667] [INFO] [launch.py:350:main] Process 57893 exits successfully. deepspeed --include localhost:0,1,2,3,4,5,6,7 train.py \ --deepspeed ds_config_zero2.json \ --model_name_or_path /data/nfs/guodong.li/pretrain/hf-llama-model/llama-7b \ --data_path /data/nfs/guodong.li/data/alpaca_data_cleaned.json \ --output_dir /data/nfs/guodong.li/output/llama-7b-sft \ --max_steps 100 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 4 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 1000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --gradient_checkpointing True \ --fp16 True {'train_runtime': 1323.6301, 'train_samples_per_second': 4.835, 'train_steps_per_second': 0.076, 'train_loss': 1.1723517608642577, 'epoch': 0.12} 100%|███████████████████████████████████████████████████████████████████████| 100/100 [22:03<00:00, 13.24s/it] [2023-07-02 20:27:07,744] [INFO] [launch.py:350:main] Process 43249 exits successfully. ``` ## H800-DDP ### 单机单卡 运行命令: ``` deepspeed --include localhost:7 train_ddp.py \ --deepspeed ds_config_zero2.json \ --model_name_or_path /home/h800/h800-work/h800-workspace/llama-13b/merge \ --data_path /home/h800/h800-work/h800-workspace/data/alpaca_data_cleaned.json \ --output_dir /home/h800/h800-work/h800-workspace/output/llama-13b-sft \ --max_steps 800 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 4 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 1000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --gradient_checkpointing True \ --fp16 True ``` 训练时长: ``` {'train_runtime': 7284.2064, 'train_samples_per_second': 0.879, 'train_steps_per_second': 0.11, 'train_loss': 1.0952609968185425, 'epoch': 0.12} 100%|█████████████████████████████████████████████████████████████████████████████████████| 800/800 [2:01:24<00:00, 9.11s/it] ``` 显存占用: ``` +-----------------------------------------------------------------------------+ | NVIDIA-SMI 525.105.17 Driver Version: 525.105.17 CUDA Version: 12.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 7 NVIDIA H800 On | 00000000:E2:00.0 Off | Off | | N/A 44C P0 153W / 700W | 60787MiB / 81559MiB | 23% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 7 N/A N/A 82977 C ...nv-py310-cu118/bin/python 60570MiB | +-----------------------------------------------------------------------------+ ``` ### 单机多卡 运行命令: ``` deepspeed --include localhost:0,1,2,3,4,5,6,7 train_ddp.py \ --deepspeed ds_config_zero2.json \ --model_name_or_path /home/h800/h800-work/h800-workspace/llama-13b/merge \ --data_path /home/h800/h800-work/h800-workspace/data/alpaca_data_cleaned.json \ --output_dir /home/h800/h800-work/h800-workspace/output/llama-13b-sft \ --max_steps 100 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 4 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 1000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --gradient_checkpointing True \ --fp16 True ``` 训练时长: ``` {'train_runtime': 779.6666, 'train_samples_per_second': 8.209, 'train_steps_per_second': 0.128, 'train_loss': 1.129374122619629, 'epoch': 0.12} 100%|███████████████████████████████████████████████████████████████████████████████████████| 100/100 [12:59<00:00, 7.80s/it] ``` 显存占用: ``` > nvidia-smi Fri Jun 30 19:25:22 2023 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 525.105.17 Driver Version: 525.105.17 CUDA Version: 12.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 NVIDIA H800 On | 00000000:18:00.0 Off | Off | | N/A 45C P0 218W / 700W | 65759MiB / 81559MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 1 NVIDIA H800 On | 00000000:3E:00.0 Off | Off | | N/A 46C P0 191W / 700W | 65785MiB / 81559MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 2 NVIDIA H800 On | 00000000:51:00.0 Off | Off | | N/A 41C P0 215W / 700W | 68925MiB / 81559MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 3 NVIDIA H800 On | 00000000:65:00.0 Off | Off | | N/A 40C P0 184W / 700W | 68513MiB / 81559MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 4 NVIDIA H800 On | 00000000:98:00.0 Off | Off | | N/A 45C P0 191W / 700W | 59785MiB / 81559MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 5 NVIDIA H800 On | 00000000:BD:00.0 Off | Off | | N/A 44C P0 193W / 700W | 62865MiB / 81559MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 6 NVIDIA H800 On | 00000000:CF:00.0 Off | Off | | N/A 39C P0 183W / 700W | 59993MiB / 81559MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 7 NVIDIA H800 On | 00000000:E2:00.0 Off | Off | | N/A 40C P0 203W / 700W | 59511MiB / 81559MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 112523 C ...nv-py310-cu118/bin/python 65726MiB | | 1 N/A N/A 112524 C ...nv-py310-cu118/bin/python 65752MiB | | 2 N/A N/A 112525 C ...nv-py310-cu118/bin/python 68892MiB | | 3 N/A N/A 112526 C ...nv-py310-cu118/bin/python 68480MiB | | 4 N/A N/A 112527 C ...nv-py310-cu118/bin/python 59752MiB | | 5 N/A N/A 112528 C ...nv-py310-cu118/bin/python 62832MiB | | 6 N/A N/A 112529 C ...nv-py310-cu118/bin/python 59960MiB | | 7 N/A N/A 112530 C ...nv-py310-cu118/bin/python 59478MiB | +-----------------------------------------------------------------------------+ ``` 有效负载和协议开销: ``` > nvidia-smi nvlink -i 0 -gt d GPU 0: NVIDIA H800 (UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c) Link 0: Data Tx: 1390774681 KiB Link 0: Data Rx: 1387831436 KiB Link 1: Data Tx: 1390715554 KiB Link 1: Data Rx: 1387856699 KiB Link 2: Data Tx: 1390689916 KiB Link 2: Data Rx: 1387846800 KiB Link 3: Data Tx: 1390772616 KiB Link 3: Data Rx: 1387795114 KiB Link 4: Data Tx: 1391305436 KiB Link 4: Data Rx: 1387910526 KiB Link 5: Data Tx: 1391288579 KiB Link 5: Data Rx: 1387888125 KiB Link 6: Data Tx: 1391348992 KiB Link 6: Data Rx: 1387832695 KiB Link 7: Data Tx: 1391348007 KiB Link 7: Data Rx: 1387855953 KiB > nvidia-smi nvlink -i 0 -gt r GPU 0: NVIDIA H800 (UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c) Link 0: Raw Tx: 1933426555 KiB Link 0: Raw Rx: 1975423057 KiB Link 1: Raw Tx: 1915132335 KiB Link 1: Raw Rx: 1958569530 KiB Link 2: Raw Tx: 1916865102 KiB Link 2: Raw Rx: 1958463156 KiB Link 3: Raw Tx: 1916412075 KiB Link 3: Raw Rx: 1958028986 KiB Link 4: Raw Tx: 1913329166 KiB Link 4: Raw Rx: 1957374521 KiB Link 5: Raw Tx: 1913784453 KiB Link 5: Raw Rx: 1957230286 KiB Link 6: Raw Tx: 1916726453 KiB Link 6: Raw Rx: 1957614726 KiB Link 7: Raw Tx: 1919300185 KiB Link 7: Raw Rx: 1957241622 KiB ``` ``` > nvidia-smi nvlink -gt d GPU 0: NVIDIA H800 (UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c) Link 0: Data Tx: 695737216 KiB Link 0: Data Rx: 692677038 KiB Link 1: Data Tx: 695707855 KiB Link 1: Data Rx: 692688658 KiB Link 2: Data Tx: 695695437 KiB Link 2: Data Rx: 692684920 KiB Link 3: Data Tx: 695736221 KiB Link 3: Data Rx: 692657460 KiB Link 4: Data Tx: 696001810 KiB Link 4: Data Rx: 692715987 KiB Link 5: Data Tx: 695993350 KiB Link 5: Data Rx: 692704827 KiB Link 6: Data Tx: 696023479 KiB Link 6: Data Rx: 692676721 KiB Link 7: Data Tx: 696023012 KiB Link 7: Data Rx: 692688332 KiB GPU 1: NVIDIA H800 (UUID: GPU-f5046fa5-3db4-45e8-870a-dc1376becaa5) Link 0: Data Tx: 696084671 KiB Link 0: Data Rx: 696267925 KiB Link 1: Data Tx: 696094870 KiB Link 1: Data Rx: 695949355 KiB Link 2: Data Tx: 696093966 KiB Link 2: Data Rx: 695981158 KiB Link 3: Data Tx: 696084771 KiB Link 3: Data Rx: 696258016 KiB Link 4: Data Tx: 696150675 KiB Link 4: Data Rx: 696246802 KiB Link 5: Data Tx: 696143361 KiB Link 5: Data Rx: 695989426 KiB Link 6: Data Tx: 696112444 KiB Link 6: Data Rx: 695941292 KiB Link 7: Data Tx: 696103562 KiB Link 7: Data Rx: 696238339 KiB GPU 2: NVIDIA H800 (UUID: GPU-9de407ad-ba9c-af12-ce09-65828829a67c) Link 0: Data Tx: 1054002679 KiB() Link 0: Data Rx: 1030362744 KiB Link 1: Data Tx: 1055193703 KiB Link 1: Data Rx: 1055345162 KiB Link 2: Data Tx: 1053892379 KiB Link 2: Data Rx: 1030586401 KiB Link 3: Data Tx: 1053653135 KiB Link 3: Data Rx: 1030480973 KiB Link 4: Data Tx: 1030522575 KiB Link 4: Data Rx: 1054103382 KiB Link 5: Data Tx: 1030611700 KiB Link 5: Data Rx: 1053822819 KiB Link 6: Data Tx: 1030748509 KiB Link 6: Data Rx: 1030246144 KiB Link 7: Data Tx: 1030367287 KiB Link 7: Data Rx: 1054044341 KiB GPU 3: NVIDIA H800 (UUID: GPU-b54d703a-dee5-a9da-aeb9-465003acdd4b) Link 0: Data Tx: 1054001301 KiB Link 0: Data Rx: 1030523294 KiB Link 1: Data Tx: 1055202838 KiB Link 1: Data Rx: 1055183348 KiB Link 2: Data Tx: 1053891154 KiB Link 2: Data Rx: 1030368684 KiB Link 3: Data Tx: 1053651756 KiB Link 3: Data Rx: 1030612272 KiB Link 4: Data Tx: 1030523716 KiB Link 4: Data Rx: 1054012179 KiB Link 5: Data Tx: 1030612840 KiB Link 5: Data Rx: 1053652291 KiB Link 6: Data Tx: 1030739151 KiB Link 6: Data Rx: 1053901558 KiB Link 7: Data Tx: 1030368258 KiB Link 7: Data Rx: 1030738386 KiB GPU 4: NVIDIA H800 (UUID: GPU-09c6e33a-ffcf-b330-e68b-e1e9f745eae6) Link 0: Data Tx: 695983535 KiB Link 0: Data Rx: 695959477 KiB Link 1: Data Tx: 695954083 KiB Link 1: Data Rx: 696236361 KiB Link 2: Data Tx: 695941649 KiB Link 2: Data Rx: 695952294 KiB Link 3: Data Tx: 695982204 KiB Link 3: Data Rx: 696257044 KiB Link 4: Data Tx: 696244163 KiB Link 4: Data Rx: 695969585 KiB Link 5: Data Tx: 696235572 KiB Link 5: Data Rx: 696265919 KiB Link 6: Data Tx: 696265768 KiB Link 6: Data Rx: 696245293 KiB Link 7: Data Tx: 696265336 KiB Link 7: Data Rx: 695981346 KiB GPU 5: NVIDIA H800 (UUID: GPU-9a8ef0b8-9816-459d-fa13-cda74cf19d37) Link 0: Data Tx: 695981354 KiB Link 0: Data Rx: 695951276 KiB Link 1: Data Tx: 695951855 KiB Link 1: Data Rx: 696266080 KiB Link 2: Data Tx: 695939389 KiB Link 2: Data Rx: 696244607 KiB Link 3: Data Tx: 695980158 KiB Link 3: Data Rx: 695981676 KiB Link 4: Data Tx: 696245738 KiB Link 4: Data Rx: 695963221 KiB Link 5: Data Tx: 696237228 KiB Link 5: Data Rx: 696235790 KiB Link 6: Data Tx: 696267509 KiB Link 6: Data Rx: 695983623 KiB Link 7: Data Tx: 696267040 KiB Link 7: Data Rx: 696245994 KiB GPU 6: NVIDIA H800 (UUID: GPU-70c5b9a8-82a3-4199-d7f5-adb9186459eb) Link 0: Data Tx: 695982560 KiB Link 0: Data Rx: 695989774 KiB Link 1: Data Tx: 695953061 KiB Link 1: Data Rx: 696258815 KiB Link 2: Data Tx: 695940592 KiB Link 2: Data Rx: 696267496 KiB Link 3: Data Tx: 695981364 KiB Link 3: Data Rx: 695950474 KiB Link 4: Data Tx: 696244494 KiB Link 4: Data Rx: 696237459 KiB Link 5: Data Tx: 696236034 KiB Link 5: Data Rx: 695948053 KiB Link 6: Data Tx: 696266315 KiB Link 6: Data Rx: 696246682 KiB Link 7: Data Tx: 696265896 KiB Link 7: Data Rx: 695971565 KiB GPU 7: NVIDIA H800 (UUID: GPU-474d838c-171f-d249-4f45-bbc01a8eb74a) Link 0: Data Tx: 692716997 KiB Link 0: Data Rx: 695992399 KiB Link 1: Data Tx: 692687737 KiB Link 1: Data Rx: 695708329 KiB Link 2: Data Tx: 692675318 KiB Link 2: Data Rx: 696013146 KiB Link 3: Data Tx: 692705914 KiB Link 3: Data Rx: 696012245 KiB Link 4: Data Tx: 692675705 KiB Link 4: Data Rx: 695715307 KiB Link 5: Data Tx: 692657460 KiB Link 5: Data Rx: 696000518 KiB Link 6: Data Tx: 692687639 KiB Link 6: Data Rx: 695737987 KiB Link 7: Data Tx: 692687169 KiB Link 7: Data Rx: 695736450 KiB ``` ``` nvidia-smi nvlink -gt r GPU 0: NVIDIA H800 (UUID: GPU-34bf77d1-c686-6821-79a8-32d326c5039c) Link 0: Raw Tx: 1118147700 KiB Link 0: Raw Rx: 1141810354 KiB Link 1: Raw Tx: 1100264974 KiB Link 1: Raw Rx: 1124745637 KiB Link 2: Raw Tx: 1101254662 KiB Link 2: Raw Rx: 1124690315 KiB Link 3: Raw Tx: 1100988364 KiB Link 3: Raw Rx: 1124421469 KiB Link 4: Raw Tx: 1099230440 KiB Link 4: Raw Rx: 1124030263 KiB Link 5: Raw Tx: 1099473327 KiB Link 5: Raw Rx: 1123951611 KiB Link 6: Raw Tx: 1101179263 KiB Link 6: Raw Rx: 1124173618 KiB Link 7: Raw Tx: 1102660262 KiB Link 7: Raw Rx: 1123953314 KiB GPU 1: NVIDIA H800 (UUID: GPU-f5046fa5-3db4-45e8-870a-dc1376becaa5) Link 0: Raw Tx: 1124539188 KiB Link 0: Raw Rx: 1149691251 KiB Link 1: Raw Tx: 1106569621 KiB Link 1: Raw Rx: 1132256711 KiB Link 2: Raw Tx: 1106684022 KiB Link 2: Raw Rx: 1132329569 KiB Link 3: Raw Tx: 1107315009 KiB Link 3: Raw Rx: 1132156000 KiB Link 4: Raw Tx: 1107035948 KiB Link 4: Raw Rx: 1132086945 KiB Link 5: Raw Tx: 1106096289 KiB Link 5: Raw Rx: 1132285164 KiB Link 6: Raw Tx: 1107377748 KiB Link 6: Raw Rx: 1132187161 KiB Link 7: Raw Tx: 1108717934 KiB Link 7: Raw Rx: 1132182460 KiB GPU 2: NVIDIA H800 (UUID: GPU-9de407ad-ba9c-af12-ce09-65828829a67c) Link 0: Raw Tx: 1673417033 KiB Link 0: Raw Rx: 1714587360 KiB Link 1: Raw Tx: 1688236924 KiB Link 1: Raw Rx: 1747327387 KiB Link 2: Raw Tx: 1658634463 KiB Link 2: Raw Rx: 1698396992 KiB Link 3: Raw Tx: 1657197117 KiB Link 3: Raw Rx: 1697257614 KiB Link 4: Raw Tx: 1637381248 KiB Link 4: Raw Rx: 1705031044 KiB Link 5: Raw Tx: 1638024606 KiB Link 5: Raw Rx: 1704136803 KiB Link 6: Raw Tx: 1621719052 KiB Link 6: Raw Rx: 1671949800 KiB Link 7: Raw Tx: 1643219053 KiB Link 7: Raw Rx: 1704623653 KiB GPU 3: NVIDIA H800 (UUID: GPU-b54d703a-dee5-a9da-aeb9-465003acdd4b) Link 0: Raw Tx: 1660184402 KiB Link 0: Raw Rx: 1704949814 KiB Link 1: Raw Tx: 1676194053 KiB Link 1: Raw Rx: 1735431635 KiB Link 2: Raw Tx: 1643363616 KiB Link 2: Raw Rx: 1687110380 KiB Link 3: Raw Tx: 1643714408 KiB Link 3: Raw Rx: 1687846412 KiB Link 4: Raw Tx: 1627544154 KiB Link 4: Raw Rx: 1697198060 KiB Link 5: Raw Tx: 1627175698 KiB Link 5: Raw Rx: 1696806696 KiB Link 6: Raw Tx: 1628803919 KiB Link 6: Raw Rx: 1698178327 KiB Link 7: Raw Tx: 1615146142 KiB Link 7: Raw Rx: 1661416229 KiB GPU 4: NVIDIA H800 (UUID: GPU-09c6e33a-ffcf-b330-e68b-e1e9f745eae6) Link 0: Raw Tx: 1116896202 KiB Link 0: Raw Rx: 1140861139 KiB Link 1: Raw Tx: 1098957850 KiB Link 1: Raw Rx: 1123561565 KiB Link 2: Raw Tx: 1099305681 KiB Link 2: Raw Rx: 1123628097 KiB Link 3: Raw Tx: 1099503500 KiB Link 3: Raw Rx: 1123434061 KiB Link 4: Raw Tx: 1098724092 KiB Link 4: Raw Rx: 1122809689 KiB Link 5: Raw Tx: 1099197545 KiB Link 5: Raw Rx: 1123062487 KiB Link 6: Raw Tx: 1099519806 KiB Link 6: Raw Rx: 1123139720 KiB Link 7: Raw Tx: 1102029177 KiB Link 7: Raw Rx: 1122923779 KiB GPU 5: NVIDIA H800 (UUID: GPU-9a8ef0b8-9816-459d-fa13-cda74cf19d37) Link 0: Raw Tx: 1117757774 KiB Link 0: Raw Rx: 1141564205 KiB Link 1: Raw Tx: 1099573176 KiB Link 1: Raw Rx: 1124358860 KiB Link 2: Raw Tx: 1100362767 KiB Link 2: Raw Rx: 1124040224 KiB Link 3: Raw Tx: 1100442868 KiB Link 3: Raw Rx: 1123887831 KiB Link 4: Raw Tx: 1099327134 KiB Link 4: Raw Rx: 1123351729 KiB Link 5: Raw Tx: 1100074359 KiB Link 5: Raw Rx: 1123445692 KiB Link 6: Raw Tx: 1100760170 KiB Link 6: Raw Rx: 1123527654 KiB Link 7: Raw Tx: 1101743143 KiB Link 7: Raw Rx: 1123491315 KiB GPU 6: NVIDIA H800 (UUID: GPU-70c5b9a8-82a3-4199-d7f5-adb9186459eb) Link 0: Raw Tx: 1115218985 KiB Link 0: Raw Rx: 1138984021 KiB Link 1: Raw Tx: 1097337560 KiB Link 1: Raw Rx: 1121694117 KiB Link 2: Raw Tx: 1098050521 KiB Link 2: Raw Rx: 1121656750 KiB Link 3: Raw Tx: 1098194347 KiB Link 3: Raw Rx: 1121634496 KiB Link 4: Raw Tx: 1097914184 KiB Link 4: Raw Rx: 1120783655 KiB Link 5: Raw Tx: 1097139278 KiB Link 5: Raw Rx: 1120772788 KiB Link 6: Raw Tx: 1097912808 KiB Link 6: Raw Rx: 1120798006 KiB Link 7: Raw Tx: 1100057763 KiB Link 7: Raw Rx: 1120943586 KiB GPU 7: NVIDIA H800 (UUID: GPU-474d838c-171f-d249-4f45-bbc01a8eb74a) Link 0: Raw Tx: 1113051394 KiB Link 0: Raw Rx: 1138308453 KiB Link 1: Raw Tx: 1095779616 KiB Link 1: Raw Rx: 1120874570 KiB Link 2: Raw Tx: 1096191412 KiB Link 2: Raw Rx: 1121071616 KiB Link 3: Raw Tx: 1095899434 KiB Link 3: Raw Rx: 1120937868 KiB Link 4: Raw Tx: 1094655428 KiB Link 4: Raw Rx: 1120572831 KiB Link 5: Raw Tx: 1095674926 KiB Link 5: Raw Rx: 1121019745 KiB Link 6: Raw Tx: 1095850556 KiB Link 6: Raw Rx: 1120703022 KiB Link 7: Raw Tx: 1098176499 KiB Link 7: Raw Rx: 1120627325 KiB ``` ## Docker ``` sudo docker run -it --gpus all --network=host \ --shm-size 4G \ -v /data/hpc/home/guodong.li:/workspaces \ harbor.aip.io/base/pytorch-alpaca:v3 \ torchrun --nproc_per_node=8 --master_port=25001 train.py \ --model_name_or_path /workspaces/llama-7b \ --data_path /workspaces/alpaca_data_cleaned.json \ --output_dir /workspaces/output \ --bf16 True \ --max_steps 200 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'LlamaDecoderLayer' \ --tf32 True ``` ## singularity ``` singularity pull pytorch-alpaca.sif docker://harbor.aip.io/base/pytorch-alpaca:v3 ``` ``` singularity run --nv pytorch-alpaca.sif torchrun --nproc_per_node=8 --master_port=25001 train.py \ --model_name_or_path /data/hpc/home/guodong.li/llama-7b \ --data_path /data/hpc/home/guodong.li/alpaca_data_cleaned.json \ --output_dir /data/hpc/home/guodong.li/output \ --bf16 True \ --max_steps 100 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'LlamaDecoderLayer' \ --tf32 True ``` ``` singularity run --nv --pwd /workspace/stanford_alpaca -B /data/hpc/home/guodong.li/:/workspaces:rw pytorch-alpaca.sif ``` ``` singularity run --nv \ --pwd /workspace/stanford_alpaca/ \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-alpaca.sif \ torchrun --nproc_per_node=8 --master_port=25001 train.py \ --model_name_or_path /workspaces/llama-7b \ --data_path /workspaces/alpaca_data_cleaned.json \ --output_dir /workspaces/output \ --bf16 True \ --max_steps 100 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'LlamaDecoderLayer' \ --tf32 True ``` ================================================ FILE: llm-train/alpaca/ds_config.json ================================================ { "zero_optimization": { "stage": 3, "contiguous_gradients": true, "stage3_max_live_parameters": 0, "stage3_max_reuse_distance": 0, "stage3_prefetch_bucket_size": 0, "stage3_param_persistence_threshold": 1e2, "reduce_bucket_size": 1e2, "sub_group_size": 1e8, "offload_optimizer": { "device": "cpu", "pin_memory": true }, "offload_param": { "device": "cpu", "pin_memory": true }, "stage3_gather_16bit_weights_on_model_save": true }, "fp16": { "enabled": true, "auto_cast": false, "loss_scale": 0, "initial_scale_power": 32, "loss_scale_window": 1000, "hysteresis": 2, "min_loss_scale": 1 }, "train_batch_size": "auto", "train_micro_batch_size_per_gpu": "auto", "wall_clock_breakdown": false } ================================================ FILE: llm-train/alpaca/ds_config_zero2.json ================================================ { "fp16": { "enabled": "auto", "loss_scale": 0, "loss_scale_window": 1000, "initial_scale_power": 16, "hysteresis": 2, "min_loss_scale": 1 }, "bf16": { "enabled": "auto" }, "optimizer": { "type": "AdamW", "params": { "lr": "auto", "betas": "auto", "eps": "auto", "weight_decay": "auto" } }, "scheduler": { "type": "WarmupLR", "params": { "warmup_min_lr": "auto", "warmup_max_lr": "auto", "warmup_num_steps": "auto" } }, "zero_optimization": { "stage": 2, "offload_optimizer": { "device": "cpu", "pin_memory": true }, "allgather_partitions": true, "allgather_bucket_size": 2e8, "overlap_comm": true, "reduce_scatter": true, "reduce_bucket_size": 2e8, "contiguous_gradients": true }, "gradient_accumulation_steps": "auto", "gradient_clipping": "auto", "steps_per_print": 2000, "train_batch_size": "auto", "train_micro_batch_size_per_gpu": "auto", "wall_clock_breakdown": false } ================================================ FILE: llm-train/alpaca/ds_config_zero2_ddp.json ================================================ { "zero_optimization": { "stage": 2, "contiguous_gradients": true, "stage3_max_live_parameters": 0, "stage3_max_reuse_distance": 0, "stage3_prefetch_bucket_size": 0, "stage3_param_persistence_threshold": 1e2, "reduce_bucket_size": 1e2, "sub_group_size": 1e8, "offload_optimizer": { "device": "cpu", "pin_memory": true }, "offload_param": { "device": "cpu", "pin_memory": true } }, "fp16": { "enabled": true, "auto_cast": false, "loss_scale": 0, "initial_scale_power": 32, "loss_scale_window": 1000, "hysteresis": 2, "min_loss_scale": 1 }, "train_batch_size": "auto", "train_micro_batch_size_per_gpu": "auto", "wall_clock_breakdown": false } ================================================ FILE: llm-train/alpaca/inference.py ================================================ import sys import torch from transformers import LlamaForCausalLM, LlamaTokenizer model_path = str(sys.argv[1]) # You can modify the path for storing the local model print("loading model, path:", model_path) model = LlamaForCausalLM.from_pretrained(model_path, device_map='auto', low_cpu_mem_usage=True) tokenizer = LlamaTokenizer.from_pretrained(model_path) print("Human:") line = input() while line: inputs = 'Human: ' + line.strip() + '\n\nAssistant:' input_ids = tokenizer(inputs, return_tensors="pt").input_ids input_ids = input_ids.cuda() outputs = model.generate(input_ids, max_new_tokens=100, do_sample = True, top_k = 30, top_p = 0.85, temperature = 0.5, repetition_penalty=1., eos_token_id=2, bos_token_id=1, pad_token_id=0) rets = tokenizer.batch_decode(outputs, skip_special_tokens=True, clean_up_tokenization_spaces=False) print("Assistant:\n" + rets[0].strip().replace(inputs, "")) print("\n------------------------------------------------\nHuman:") line = input() ================================================ FILE: llm-train/alpaca/train.py ================================================ import copy import logging from dataclasses import dataclass, field from typing import Optional, Dict, Sequence import torch import transformers from torch.utils.data import Dataset from transformers import Trainer import utils IGNORE_INDEX = -100 DEFAULT_PAD_TOKEN = "[PAD]" DEFAULT_EOS_TOKEN = "
" DEFAULT_BOS_TOKEN = "" DEFAULT_UNK_TOKEN = "" PROMPT_DICT = { "prompt_input": ( "Below is an instruction that describes a task, paired with an input that provides further context. " "Write a response that appropriately completes the request.\n\n" "### Instruction:\n{instruction}\n\n### Input:\n{input}\n\n### Response:" ), "prompt_no_input": ( "Below is an instruction that describes a task. " "Write a response that appropriately completes the request.\n\n" "### Instruction:\n{instruction}\n\n### Response:" ), } @dataclass class ModelArguments: model_name_or_path: Optional[str] = field(default="llama") #model_name_or_path: Optional[str] = field(default="facebook/opt-125m") @dataclass class DataArguments: data_path: str = field(default=None, metadata={"help": "Path to the training data."}) @dataclass class TrainingArguments(transformers.TrainingArguments): cache_dir: Optional[str] = field(default=None) optim: str = field(default="adamw_torch") model_max_length: int = field( default=512, metadata={"help": "Maximum sequence length. Sequences will be right padded (and possibly truncated)."}, ) def safe_save_model_for_hf_trainer(trainer: transformers.Trainer, output_dir: str): """Collects the state dict and dump to disk.""" state_dict = trainer.model.state_dict() if trainer.args.should_save: cpu_state_dict = {key: value.cpu() for key, value in state_dict.items()} del state_dict trainer._save(output_dir, state_dict=cpu_state_dict) # noqa def smart_tokenizer_and_embedding_resize( special_tokens_dict: Dict, tokenizer: transformers.PreTrainedTokenizer, model: transformers.PreTrainedModel, ): """Resize tokenizer and embedding. Note: This is the unoptimized version that may make your embedding size not be divisible by 64. """ num_new_tokens = tokenizer.add_special_tokens(special_tokens_dict) model.resize_token_embeddings(len(tokenizer)) if num_new_tokens > 0: input_embeddings = model.get_input_embeddings().weight.data output_embeddings = model.get_output_embeddings().weight.data input_embeddings_avg = input_embeddings[:-num_new_tokens].mean(dim=0, keepdim=True) output_embeddings_avg = output_embeddings[:-num_new_tokens].mean(dim=0, keepdim=True) input_embeddings[-num_new_tokens:] = input_embeddings_avg output_embeddings[-num_new_tokens:] = output_embeddings_avg def _tokenize_fn(strings: Sequence[str], tokenizer: transformers.PreTrainedTokenizer) -> Dict: """Tokenize a list of strings.""" tokenized_list = [ tokenizer( text, return_tensors="pt", padding="longest", max_length=tokenizer.model_max_length, truncation=True, ) for text in strings ] input_ids = labels = [tokenized.input_ids[0] for tokenized in tokenized_list] input_ids_lens = labels_lens = [ tokenized.input_ids.ne(tokenizer.pad_token_id).sum().item() for tokenized in tokenized_list ] return dict( input_ids=input_ids, labels=labels, input_ids_lens=input_ids_lens, labels_lens=labels_lens, ) def preprocess( sources: Sequence[str], targets: Sequence[str], tokenizer: transformers.PreTrainedTokenizer, ) -> Dict: """Preprocess the data by tokenizing.""" examples = [s + t for s, t in zip(sources, targets)] examples_tokenized, sources_tokenized = [_tokenize_fn(strings, tokenizer) for strings in (examples, sources)] input_ids = examples_tokenized["input_ids"] labels = copy.deepcopy(input_ids) for label, source_len in zip(labels, sources_tokenized["input_ids_lens"]): label[:source_len] = IGNORE_INDEX return dict(input_ids=input_ids, labels=labels) class SupervisedDataset(Dataset): """Dataset for supervised fine-tuning.""" def __init__(self, data_path: str, tokenizer: transformers.PreTrainedTokenizer): super(SupervisedDataset, self).__init__() logging.warning("Loading data...") list_data_dict = utils.jload(data_path) logging.warning("Formatting inputs...") prompt_input, prompt_no_input = PROMPT_DICT["prompt_input"], PROMPT_DICT["prompt_no_input"] sources = [ prompt_input.format_map(example) if example.get("input", "") != "" else prompt_no_input.format_map(example) for example in list_data_dict ] targets = [f"{example['output']}{tokenizer.eos_token}" for example in list_data_dict] logging.warning("Tokenizing inputs... This may take some time...") data_dict = preprocess(sources, targets, tokenizer) self.input_ids = data_dict["input_ids"] self.labels = data_dict["labels"] def __len__(self): return len(self.input_ids) def __getitem__(self, i) -> Dict[str, torch.Tensor]: return dict(input_ids=self.input_ids[i], labels=self.labels[i]) @dataclass class DataCollatorForSupervisedDataset(object): """Collate examples for supervised fine-tuning.""" tokenizer: transformers.PreTrainedTokenizer def __call__(self, instances: Sequence[Dict]) -> Dict[str, torch.Tensor]: input_ids, labels = tuple([instance[key] for instance in instances] for key in ("input_ids", "labels")) input_ids = torch.nn.utils.rnn.pad_sequence( input_ids, batch_first=True, padding_value=self.tokenizer.pad_token_id ) labels = torch.nn.utils.rnn.pad_sequence(labels, batch_first=True, padding_value=IGNORE_INDEX) return dict( input_ids=input_ids, labels=labels, attention_mask=input_ids.ne(self.tokenizer.pad_token_id), ) def make_supervised_data_module(tokenizer: transformers.PreTrainedTokenizer, data_args) -> Dict: """Make dataset and collator for supervised fine-tuning.""" train_dataset = SupervisedDataset(tokenizer=tokenizer, data_path=data_args.data_path) data_collator = DataCollatorForSupervisedDataset(tokenizer=tokenizer) return dict(train_dataset=train_dataset, eval_dataset=None, data_collator=data_collator) def train(): parser = transformers.HfArgumentParser((ModelArguments, DataArguments, TrainingArguments)) model_args, data_args, training_args = parser.parse_args_into_dataclasses() # TODO model = transformers.AutoModelForCausalLM.from_pretrained( model_args.model_name_or_path, cache_dir=training_args.cache_dir, ) tokenizer = transformers.AutoTokenizer.from_pretrained( model_args.model_name_or_path, cache_dir=training_args.cache_dir, model_max_length=training_args.model_max_length, padding_side="right", use_fast=False, ) """ model = transformers.LlamaForCausalLM.from_pretrained( model_args.model_name_or_path, cache_dir=training_args.cache_dir, ) tokenizer = transformers.LlamaTokenizer.from_pretrained( model_args.model_name_or_path, cache_dir=training_args.cache_dir, ) """ if tokenizer.pad_token is None: smart_tokenizer_and_embedding_resize( special_tokens_dict=dict(pad_token=DEFAULT_PAD_TOKEN), tokenizer=tokenizer, model=model, ) if "llama" in model_args.model_name_or_path: tokenizer.add_special_tokens( { "eos_token": DEFAULT_EOS_TOKEN, "bos_token": DEFAULT_BOS_TOKEN, "unk_token": DEFAULT_UNK_TOKEN, } ) data_module = make_supervised_data_module(tokenizer=tokenizer, data_args=data_args) trainer = Trainer(model=model, tokenizer=tokenizer, args=training_args, **data_module) trainer.train() trainer.save_state() safe_save_model_for_hf_trainer(trainer=trainer, output_dir=training_args.output_dir) if __name__ == "__main__": train() ================================================ FILE: llm-train/alpaca/train_ddp.py ================================================ import os import copy import logging from dataclasses import dataclass, field from typing import Optional, Dict, Sequence import torch import transformers from torch.utils.data import Dataset from transformers import Trainer import utils IGNORE_INDEX = -100 DEFAULT_PAD_TOKEN = "[PAD]" DEFAULT_EOS_TOKEN = "" DEFAULT_BOS_TOKEN = "" DEFAULT_UNK_TOKEN = "" PROMPT_DICT = { "prompt_input": ( "Below is an instruction that describes a task, paired with an input that provides further context. " "Write a response that appropriately completes the request.\n\n" "### Instruction:\n{instruction}\n\n### Input:\n{input}\n\n### Response:" ), "prompt_no_input": ( "Below is an instruction that describes a task. " "Write a response that appropriately completes the request.\n\n" "### Instruction:\n{instruction}\n\n### Response:" ), } @dataclass class ModelArguments: model_name_or_path: Optional[str] = field(default="llama") #model_name_or_path: Optional[str] = field(default="facebook/opt-125m") @dataclass class DataArguments: data_path: str = field(default=None, metadata={"help": "Path to the training data."}) @dataclass class TrainingArguments(transformers.TrainingArguments): cache_dir: Optional[str] = field(default=None) optim: str = field(default="adamw_torch") model_max_length: int = field( default=512, metadata={"help": "Maximum sequence length. Sequences will be right padded (and possibly truncated)."}, ) def safe_save_model_for_hf_trainer(trainer: transformers.Trainer, output_dir: str): """Collects the state dict and dump to disk.""" state_dict = trainer.model.state_dict() if trainer.args.should_save: cpu_state_dict = {key: value.cpu() for key, value in state_dict.items()} del state_dict trainer._save(output_dir, state_dict=cpu_state_dict) # noqa def smart_tokenizer_and_embedding_resize( special_tokens_dict: Dict, tokenizer: transformers.PreTrainedTokenizer, model: transformers.PreTrainedModel, ): """Resize tokenizer and embedding. Note: This is the unoptimized version that may make your embedding size not be divisible by 64. """ num_new_tokens = tokenizer.add_special_tokens(special_tokens_dict) model.resize_token_embeddings(len(tokenizer)) if num_new_tokens > 0: input_embeddings = model.get_input_embeddings().weight.data output_embeddings = model.get_output_embeddings().weight.data input_embeddings_avg = input_embeddings[:-num_new_tokens].mean(dim=0, keepdim=True) output_embeddings_avg = output_embeddings[:-num_new_tokens].mean(dim=0, keepdim=True) input_embeddings[-num_new_tokens:] = input_embeddings_avg output_embeddings[-num_new_tokens:] = output_embeddings_avg def _tokenize_fn(strings: Sequence[str], tokenizer: transformers.PreTrainedTokenizer) -> Dict: """Tokenize a list of strings.""" tokenized_list = [ tokenizer( text, return_tensors="pt", padding="longest", max_length=tokenizer.model_max_length, truncation=True, ) for text in strings ] input_ids = labels = [tokenized.input_ids[0] for tokenized in tokenized_list] input_ids_lens = labels_lens = [ tokenized.input_ids.ne(tokenizer.pad_token_id).sum().item() for tokenized in tokenized_list ] return dict( input_ids=input_ids, labels=labels, input_ids_lens=input_ids_lens, labels_lens=labels_lens, ) def preprocess( sources: Sequence[str], targets: Sequence[str], tokenizer: transformers.PreTrainedTokenizer, ) -> Dict: """Preprocess the data by tokenizing.""" examples = [s + t for s, t in zip(sources, targets)] examples_tokenized, sources_tokenized = [_tokenize_fn(strings, tokenizer) for strings in (examples, sources)] input_ids = examples_tokenized["input_ids"] labels = copy.deepcopy(input_ids) for label, source_len in zip(labels, sources_tokenized["input_ids_lens"]): label[:source_len] = IGNORE_INDEX return dict(input_ids=input_ids, labels=labels) class SupervisedDataset(Dataset): """Dataset for supervised fine-tuning.""" def __init__(self, data_path: str, tokenizer: transformers.PreTrainedTokenizer): super(SupervisedDataset, self).__init__() logging.warning("Loading data...") list_data_dict = utils.jload(data_path) logging.warning("Formatting inputs...") prompt_input, prompt_no_input = PROMPT_DICT["prompt_input"], PROMPT_DICT["prompt_no_input"] sources = [ prompt_input.format_map(example) if example.get("input", "") != "" else prompt_no_input.format_map(example) for example in list_data_dict ] targets = [f"{example['output']}{tokenizer.eos_token}" for example in list_data_dict] logging.warning("Tokenizing inputs... This may take some time...") data_dict = preprocess(sources, targets, tokenizer) self.input_ids = data_dict["input_ids"] self.labels = data_dict["labels"] def __len__(self): return len(self.input_ids) def __getitem__(self, i) -> Dict[str, torch.Tensor]: return dict(input_ids=self.input_ids[i], labels=self.labels[i]) @dataclass class DataCollatorForSupervisedDataset(object): """Collate examples for supervised fine-tuning.""" tokenizer: transformers.PreTrainedTokenizer def __call__(self, instances: Sequence[Dict]) -> Dict[str, torch.Tensor]: input_ids, labels = tuple([instance[key] for instance in instances] for key in ("input_ids", "labels")) input_ids = torch.nn.utils.rnn.pad_sequence( input_ids, batch_first=True, padding_value=self.tokenizer.pad_token_id ) labels = torch.nn.utils.rnn.pad_sequence(labels, batch_first=True, padding_value=IGNORE_INDEX) return dict( input_ids=input_ids, labels=labels, attention_mask=input_ids.ne(self.tokenizer.pad_token_id), ) def make_supervised_data_module(tokenizer: transformers.PreTrainedTokenizer, data_args) -> Dict: """Make dataset and collator for supervised fine-tuning.""" train_dataset = SupervisedDataset(tokenizer=tokenizer, data_path=data_args.data_path) data_collator = DataCollatorForSupervisedDataset(tokenizer=tokenizer) return dict(train_dataset=train_dataset, eval_dataset=None, data_collator=data_collator) def train(): parser = transformers.HfArgumentParser((ModelArguments, DataArguments, TrainingArguments)) model_args, data_args, training_args = parser.parse_args_into_dataclasses() # TODO device_map = {"": int(os.environ.get("LOCAL_RANK"))} print("-------------", device_map) model = transformers.LlamaForCausalLM.from_pretrained( model_args.model_name_or_path, cache_dir=training_args.cache_dir, device_map=device_map ) tokenizer = transformers.AutoTokenizer.from_pretrained( model_args.model_name_or_path, cache_dir=training_args.cache_dir, model_max_length=training_args.model_max_length, padding_side="right", use_fast=False, ) """ model = transformers.LlamaForCausalLM.from_pretrained( model_args.model_name_or_path, cache_dir=training_args.cache_dir, ) tokenizer = transformers.LlamaTokenizer.from_pretrained( model_args.model_name_or_path, cache_dir=training_args.cache_dir, ) """ if tokenizer.pad_token is None: smart_tokenizer_and_embedding_resize( special_tokens_dict=dict(pad_token=DEFAULT_PAD_TOKEN), tokenizer=tokenizer, model=model, ) if "llama" in model_args.model_name_or_path: tokenizer.add_special_tokens( { "eos_token": DEFAULT_EOS_TOKEN, "bos_token": DEFAULT_BOS_TOKEN, "unk_token": DEFAULT_UNK_TOKEN, } ) data_module = make_supervised_data_module(tokenizer=tokenizer, data_args=data_args) trainer = Trainer(model=model, tokenizer=tokenizer, args=training_args, **data_module) trainer.train() trainer.save_state() safe_save_model_for_hf_trainer(trainer=trainer, output_dir=training_args.output_dir) if __name__ == "__main__": train() ================================================ FILE: llm-train/alpaca-lora/README.md ================================================ ## Alpaca-LoRA - 源码: https://github.com/tloen/alpaca-lora - commit id : 9de612e582ab86013b5d1c3be6b0ed9f5ab2065a ## LoRA ### 7B ``` torchrun --nproc_per_node=8 --master_port=29005 finetune_metrics_epoch.py \ --base_model '/data/nfs/guodong.li/pretrain/hf-llama-model/llama-7b' \ --data_path '/home/guodong.li/llama-mp/GPT-4-LLM/data/alpaca_gpt4_data_zh.json' \ --output_dir '/home/guodong.li/output/alpaca-lora-7b-dp-zh' \ --batch_size 80 \ --micro_batch_size 10 \ --num_epochs 10 \ --cutoff_len=512 \ --group_by_length \ --lora_target_modules='[q_proj,k_proj,v_proj,o_proj]' \ --lora_r=16 ``` | 模型 | 显存 | 耗时 | 数据量 | | --- | --- | --- | --- | | 7B | 8 * 74G | 2小时5分钟 | 46818 | ![image](https://github.com/liguodongiot/llm-action/assets/13220186/238d86da-bbda-4944-94e4-49a87284e026) ### 13B ``` torchrun --nproc_per_node=8 --master_port=29005 finetune_metrics_epoch.py \ --base_model '/data/nfs/guodong.li/pretrain/hf-llama-model/llama-13b' \ --data_path '/home/guodong.li/llama-mp/GPT-4-LLM/data/alpaca_gpt4_data_zh.json' \ --output_dir '/home/guodong.li/output/alpaca-lora-13b-dp-zh' \ --batch_size 48 \ --micro_batch_size 6 \ --num_epochs 10 \ --cutoff_len=512 \ --group_by_length \ --lora_target_modules='[q_proj,k_proj,v_proj,o_proj]' \ --lora_r=16 ``` | 模型 | 显存 | 耗时 | 数据量 | | --- | --- | --- | --- | | 13B | 8 * 76G | 2小时10分钟 | 46818 | ![image](https://github.com/liguodongiot/llm-action/assets/13220186/a66ea4a1-79fb-40d9-8a10-7a9132fde882) ### 30B ``` torchrun --nproc_per_node=8 --master_port=29005 finetune_metrics_epoch.py \ --base_model '/data/nfs/guodong.li/pretrain/hf-llama-model/llama-30b' \ --data_path '/home/guodong.li/llama-mp/GPT-4-LLM/data/alpaca_gpt4_data_zh.json' \ --output_dir '/home/guodong.li/output/alpaca-lora-30b-dp-zh-1' \ --batch_size 16 \ --micro_batch_size 2 \ --num_epochs 10 \ --cutoff_len=512 \ --group_by_length \ --lora_target_modules='[q_proj,k_proj,v_proj,o_proj]' \ --lora_r=16 ``` 训练过程: ``` trainable params: 51118080 || all params: 32580061696 || trainable%: 0.15689988704433913 {'train_runtime': 55949.6417, 'train_samples_per_second': 8.368, 'train_steps_per_second': 0.523, 'train_loss': 0.4879480355503537, 'epoch': 10.0} 100%|████████████████████████████████████████████████████████████████████████████████████████████| 29270/29270 [15:32:27<00:00, 1.91s/it] ``` | 模型 | 显存 | 耗时 | 数据量 | | --- | --- | --- | --- | | 30B | 8 * 75G | 15小时30分钟 | 46818 | ![image](https://github.com/liguodongiot/llm-action/assets/13220186/303b850c-3332-45aa-968d-bb0f52fa44a6) ``` torchrun --nproc_per_node=8 --master_port=29005 finetune.py \ --base_model '/data/nfs/guodong.li/pretrain/hf-llama-model/llama-30b' \ --data_path '/data/nfs/guodong.li/data/alpaca_data_cleaned.json' \ --output_dir '/home/guodong.li/output/alpaca-lora-30b-dp' \ --batch_size 96 \ --micro_batch_size 6 \ --num_epochs 3 ``` ### 65B ``` torchrun --nproc_per_node=8 --master_port=29005 finetune.py \ --base_model '/data/nfs/guodong.li/pretrain/hf-llama-model/llama-65b' \ --data_path '/home/guodong.li/llama-mp/GPT-4-LLM/data/alpaca_gpt4_data_zh.json' \ --output_dir '/home/guodong.li/output/alpaca-lora-65b-dp-zh' \ --batch_size 8 \ --micro_batch_size 1 \ --num_epochs 3 ``` ## 测试用例 ``` 请给我讲一个温馨的睡前故事 如何快速提升自己的写作能力? 计算以下表达式:(6+2)*(2-2)。 What are the five characteristics of a good argument? ``` ## tensorboard ``` source /home/guodong.li/virtual-venv/alpara-lora-venv-py310-cu117/bin/activate tensorboard --logdir /home/guodong.li/output/alpaca-lora-7b-dp-zh --port=16007 --host=0.0.0.0 tensorboard --logdir /home/guodong.li/output/alpaca-lora-13b-dp-zh --port=16008 --host=0.0.0.0 tensorboard --logdir /home/guodong.li/output/alpaca-lora-30b-dp-zh-1 --port=16009 --host=0.0.0.0 ``` ================================================ FILE: llm-train/alpaca-lora/export_hf_checkpoint.py ================================================ import os import torch import transformers from peft import PeftModel from transformers import LlamaForCausalLM, LlamaTokenizer # noqa: F402 BASE_MODEL = os.environ.get("BASE_MODEL", None) LORA_MODEL = os.environ.get("LORA_MODEL", "tloen/alpaca-lora-7b") HF_CHECKPOINT = os.environ.get("HF_CHECKPOINT", "./hf_ckpt") assert ( BASE_MODEL ), "Please specify a value for BASE_MODEL environment variable, e.g. `export BASE_MODEL=decapoda-research/llama-7b-hf`" # noqa: E501 tokenizer = LlamaTokenizer.from_pretrained(BASE_MODEL) base_model = LlamaForCausalLM.from_pretrained( BASE_MODEL, load_in_8bit=False, torch_dtype=torch.float16, device_map={"": "cpu"}, ) first_weight = base_model.model.layers[0].self_attn.q_proj.weight first_weight_old = first_weight.clone() lora_model = PeftModel.from_pretrained( base_model, # TODO # "tloen/alpaca-lora-7b", LORA_MODEL, device_map={"": "cpu"}, torch_dtype=torch.float16, ) lora_weight = lora_model.base_model.model.model.layers[ 0 ].self_attn.q_proj.weight assert torch.allclose(first_weight_old, first_weight) # merge weights for layer in lora_model.base_model.model.model.layers: layer.self_attn.q_proj.merge_weights = True layer.self_attn.v_proj.merge_weights = True lora_model.train(False) # did we do anything? assert not torch.allclose(first_weight_old, first_weight) lora_model_sd = lora_model.state_dict() deloreanized_sd = { k.replace("base_model.model.", ""): v for k, v in lora_model_sd.items() if "lora" not in k } LlamaForCausalLM.save_pretrained( base_model, HF_CHECKPOINT , state_dict=deloreanized_sd, max_shard_size="400MB" ) ================================================ FILE: llm-train/alpaca-lora/export_state_dict_checkpoint.py ================================================ import json import os import torch import transformers from peft import PeftModel from transformers import LlamaForCausalLM, LlamaTokenizer # noqa: E402 BASE_MODEL = os.environ.get("BASE_MODEL", None) LORA_MODEL = os.environ.get("LORA_MODEL", "tloen/alpaca-lora-7b") PTH_CHECKPOINT_PREFIX = os.environ.get("PTH_CHECKPOINT_PREFIX", "./ckpt") assert ( BASE_MODEL ), "Please specify a value for BASE_MODEL environment variable, e.g. `export BASE_MODEL=decapoda-research/llama-7b-hf`" # noqa: E501 tokenizer = LlamaTokenizer.from_pretrained(BASE_MODEL) base_model = LlamaForCausalLM.from_pretrained( BASE_MODEL, load_in_8bit=False, torch_dtype=torch.float16, device_map={"": "cpu"}, ) lora_model = PeftModel.from_pretrained( base_model, # todo #"tloen/alpaca-lora-7b", LORA_MODEL, device_map={"": "cpu"}, torch_dtype=torch.float16, ) # merge weights for layer in lora_model.base_model.model.model.layers: layer.self_attn.q_proj.merge_weights = True layer.self_attn.v_proj.merge_weights = True lora_model.train(False) lora_model_sd = lora_model.state_dict() params = { "dim": 4096, "multiple_of": 256, "n_heads": 32, "n_layers": 32, "norm_eps": 1e-06, "vocab_size": -1, } n_layers = params["n_layers"] n_heads = params["n_heads"] dim = params["dim"] dims_per_head = dim // n_heads base = 10000.0 inv_freq = 1.0 / ( base ** (torch.arange(0, dims_per_head, 2).float() / dims_per_head) ) def permute(w): return ( w.view(n_heads, dim // n_heads // 2, 2, dim) .transpose(1, 2) .reshape(dim, dim) ) def unpermute(w): return ( w.view(n_heads, 2, dim // n_heads // 2, dim) .transpose(1, 2) .reshape(dim, dim) ) def translate_state_dict_key(k): # noqa: C901 k = k.replace("base_model.model.", "") if k == "model.embed_tokens.weight": return "tok_embeddings.weight" elif k == "model.norm.weight": return "norm.weight" elif k == "lm_head.weight": return "output.weight" elif k.startswith("model.layers."): layer = k.split(".")[2] if k.endswith(".self_attn.q_proj.weight"): return f"layers.{layer}.attention.wq.weight" elif k.endswith(".self_attn.k_proj.weight"): return f"layers.{layer}.attention.wk.weight" elif k.endswith(".self_attn.v_proj.weight"): return f"layers.{layer}.attention.wv.weight" elif k.endswith(".self_attn.o_proj.weight"): return f"layers.{layer}.attention.wo.weight" elif k.endswith(".mlp.gate_proj.weight"): return f"layers.{layer}.feed_forward.w1.weight" elif k.endswith(".mlp.down_proj.weight"): return f"layers.{layer}.feed_forward.w2.weight" elif k.endswith(".mlp.up_proj.weight"): return f"layers.{layer}.feed_forward.w3.weight" elif k.endswith(".input_layernorm.weight"): return f"layers.{layer}.attention_norm.weight" elif k.endswith(".post_attention_layernorm.weight"): return f"layers.{layer}.ffn_norm.weight" elif k.endswith("rotary_emb.inv_freq") or "lora" in k: return None else: print(layer, k) raise NotImplementedError else: print(k) raise NotImplementedError new_state_dict = {} for k, v in lora_model_sd.items(): new_k = translate_state_dict_key(k) if new_k is not None: if "wq" in new_k or "wk" in new_k: new_state_dict[new_k] = unpermute(v) else: new_state_dict[new_k] = v print("-------------------------") print(PTH_CHECKPOINT_PREFIX) os.makedirs(PTH_CHECKPOINT_PREFIX, exist_ok=True) torch.save(new_state_dict, PTH_CHECKPOINT_PREFIX+"/consolidated.00.pth") with open(PTH_CHECKPOINT_PREFIX+"/params.json", "w") as f: json.dump(params, f) ================================================ FILE: llm-train/alpaca-lora/finetune.py ================================================ import os import sys from typing import List import fire import torch import transformers from datasets import load_dataset """ Unused imports: import torch.nn as nn import bitsandbytes as bnb """ from peft import ( LoraConfig, get_peft_model, get_peft_model_state_dict, prepare_model_for_int8_training, set_peft_model_state_dict, ) from transformers import LlamaForCausalLM, LlamaTokenizer from utils.prompter import Prompter def train( # model/data params base_model: str = "", # the only required argument data_path: str = "yahma/alpaca-cleaned", output_dir: str = "./lora-alpaca", # training hyperparams batch_size: int = 128, micro_batch_size: int = 4, num_epochs: int = 3, learning_rate: float = 3e-4, cutoff_len: int = 256, val_set_size: int = 2000, # lora hyperparams lora_r: int = 8, lora_alpha: int = 16, lora_dropout: float = 0.05, lora_target_modules: List[str] = [ "q_proj", "v_proj", ], # llm hyperparams train_on_inputs: bool = True, # if False, masks out inputs in loss group_by_length: bool = False, # faster, but produces an odd training loss curve # wandb params wandb_project: str = "", wandb_run_name: str = "", wandb_watch: str = "", # options: false | gradients | all wandb_log_model: str = "", # options: false | true resume_from_checkpoint: str = None, # either training checkpoint or final adapter prompt_template_name: str = "alpaca", # The prompt template to use, will default to alpaca. ): if int(os.environ.get("LOCAL_RANK", 0)) == 0: print( f"Training Alpaca-LoRA model with params:\n" f"base_model: {base_model}\n" f"data_path: {data_path}\n" f"output_dir: {output_dir}\n" f"batch_size: {batch_size}\n" f"micro_batch_size: {micro_batch_size}\n" f"num_epochs: {num_epochs}\n" f"learning_rate: {learning_rate}\n" f"cutoff_len: {cutoff_len}\n" f"val_set_size: {val_set_size}\n" f"lora_r: {lora_r}\n" f"lora_alpha: {lora_alpha}\n" f"lora_dropout: {lora_dropout}\n" f"lora_target_modules: {lora_target_modules}\n" f"train_on_inputs: {train_on_inputs}\n" f"group_by_length: {group_by_length}\n" f"wandb_project: {wandb_project}\n" f"wandb_run_name: {wandb_run_name}\n" f"wandb_watch: {wandb_watch}\n" f"wandb_log_model: {wandb_log_model}\n" f"resume_from_checkpoint: {resume_from_checkpoint or False}\n" f"prompt template: {prompt_template_name}\n" ) assert ( base_model ), "Please specify a --base_model, e.g. --base_model='decapoda-research/llama-7b-hf'" gradient_accumulation_steps = batch_size // micro_batch_size prompter = Prompter(prompt_template_name) device_map = "auto" world_size = int(os.environ.get("WORLD_SIZE", 1)) ddp = world_size != 1 if ddp: device_map = {"": int(os.environ.get("LOCAL_RANK") or 0)} gradient_accumulation_steps = gradient_accumulation_steps // world_size # Check if parameter passed or if set within environ use_wandb = len(wandb_project) > 0 or ( "WANDB_PROJECT" in os.environ and len(os.environ["WANDB_PROJECT"]) > 0 ) # Only overwrite environ if wandb param passed if len(wandb_project) > 0: os.environ["WANDB_PROJECT"] = wandb_project if len(wandb_watch) > 0: os.environ["WANDB_WATCH"] = wandb_watch if len(wandb_log_model) > 0: os.environ["WANDB_LOG_MODEL"] = wandb_log_model model = LlamaForCausalLM.from_pretrained( base_model, load_in_8bit=True, torch_dtype=torch.float16, device_map=device_map, ) tokenizer = LlamaTokenizer.from_pretrained(base_model) tokenizer.pad_token_id = ( 0 # unk. we want this to be different from the eos token ) tokenizer.padding_side = "left" # Allow batched inference def tokenize(prompt, add_eos_token=True): # there's probably a way to do this with the tokenizer settings # but again, gotta move fast result = tokenizer( prompt, truncation=True, max_length=cutoff_len, padding=False, return_tensors=None, ) if ( result["input_ids"][-1] != tokenizer.eos_token_id and len(result["input_ids"]) < cutoff_len and add_eos_token ): result["input_ids"].append(tokenizer.eos_token_id) result["attention_mask"].append(1) result["labels"] = result["input_ids"].copy() return result def generate_and_tokenize_prompt(data_point): full_prompt = prompter.generate_prompt( data_point["instruction"], data_point["input"], data_point["output"], ) tokenized_full_prompt = tokenize(full_prompt) if not train_on_inputs: user_prompt = prompter.generate_prompt( data_point["instruction"], data_point["input"] ) tokenized_user_prompt = tokenize(user_prompt, add_eos_token=False) user_prompt_len = len(tokenized_user_prompt["input_ids"]) tokenized_full_prompt["labels"] = [ -100 ] * user_prompt_len + tokenized_full_prompt["labels"][ user_prompt_len: ] # could be sped up, probably return tokenized_full_prompt model = prepare_model_for_int8_training(model) config = LoraConfig( r=lora_r, lora_alpha=lora_alpha, target_modules=lora_target_modules, lora_dropout=lora_dropout, bias="none", task_type="CAUSAL_LM", ) model = get_peft_model(model, config) if data_path.endswith(".json") or data_path.endswith(".jsonl"): data = load_dataset("json", data_files=data_path) else: data = load_dataset(data_path) if resume_from_checkpoint: # Check the available weights and load them checkpoint_name = os.path.join( resume_from_checkpoint, "pytorch_model.bin" ) # Full checkpoint if not os.path.exists(checkpoint_name): checkpoint_name = os.path.join( resume_from_checkpoint, "adapter_model.bin" ) # only LoRA model - LoRA config above has to fit resume_from_checkpoint = ( False # So the trainer won't try loading its state ) # The two files above have a different name depending on how they were saved, but are actually the same. if os.path.exists(checkpoint_name): print(f"Restarting from {checkpoint_name}") adapters_weights = torch.load(checkpoint_name) model = set_peft_model_state_dict(model, adapters_weights) else: print(f"Checkpoint {checkpoint_name} not found") model.print_trainable_parameters() # Be more transparent about the % of trainable params. if val_set_size > 0: train_val = data["train"].train_test_split( test_size=val_set_size, shuffle=True, seed=42 ) train_data = ( train_val["train"].shuffle().map(generate_and_tokenize_prompt) ) val_data = ( train_val["test"].shuffle().map(generate_and_tokenize_prompt) ) else: train_data = data["train"].shuffle().map(generate_and_tokenize_prompt) val_data = None if not ddp and torch.cuda.device_count() > 1: # keeps Trainer from trying its own DataParallelism when more than 1 gpu is available model.is_parallelizable = True model.model_parallel = True trainer = transformers.Trainer( model=model, train_dataset=train_data, eval_dataset=val_data, args=transformers.TrainingArguments( per_device_train_batch_size=micro_batch_size, gradient_accumulation_steps=gradient_accumulation_steps, warmup_steps=100, num_train_epochs=num_epochs, learning_rate=learning_rate, fp16=True, logging_steps=10, optim="adamw_torch", evaluation_strategy="steps" if val_set_size > 0 else "no", save_strategy="steps", eval_steps=200 if val_set_size > 0 else None, save_steps=200, output_dir=output_dir, save_total_limit=1, load_best_model_at_end=True if val_set_size > 0 else False, ddp_find_unused_parameters=False if ddp else None, group_by_length=group_by_length, report_to="wandb" if use_wandb else None, run_name=wandb_run_name if use_wandb else None, ), data_collator=transformers.DataCollatorForSeq2Seq( tokenizer, pad_to_multiple_of=8, return_tensors="pt", padding=True ), ) model.config.use_cache = False old_state_dict = model.state_dict model.state_dict = ( lambda self, *_, **__: get_peft_model_state_dict( self, old_state_dict() ) ).__get__(model, type(model)) if torch.__version__ >= "2" and sys.platform != "win32": model = torch.compile(model) trainer.train(resume_from_checkpoint=resume_from_checkpoint) model.save_pretrained(output_dir) print( "\n If there's a warning about missing keys above, please disregard :)" ) if __name__ == "__main__": fire.Fire(train) ================================================ FILE: llm-train/alpaca-lora/finetune_metrics_epoch.py ================================================ import os import sys from typing import List import fire import torch import transformers from datasets import load_dataset """ Unused imports: import torch.nn as nn import bitsandbytes as bnb """ from peft import ( LoraConfig, get_peft_model, get_peft_model_state_dict, prepare_model_for_int8_training, set_peft_model_state_dict, ) from transformers import LlamaForCausalLM, LlamaTokenizer from utils.prompter import Prompter def train( # model/data params base_model: str = "", # the only required argument data_path: str = "yahma/alpaca-cleaned", output_dir: str = "./lora-alpaca", # training hyperparams batch_size: int = 128, micro_batch_size: int = 4, num_epochs: int = 3, learning_rate: float = 3e-4, cutoff_len: int = 256, val_set_size: int = 2000, # lora hyperparams lora_r: int = 8, lora_alpha: int = 16, lora_dropout: float = 0.05, lora_target_modules: List[str] = [ "q_proj", "v_proj", ], # llm hyperparams train_on_inputs: bool = True, # if False, masks out inputs in loss group_by_length: bool = False, # faster, but produces an odd training loss curve # wandb params wandb_project: str = "", wandb_run_name: str = "", wandb_watch: str = "", # options: false | gradients | all wandb_log_model: str = "", # options: false | true resume_from_checkpoint: str = None, # either training checkpoint or final adapter prompt_template_name: str = "alpaca", # The prompt template to use, will default to alpaca. ): if int(os.environ.get("LOCAL_RANK", 0)) == 0: print( f"Training Alpaca-LoRA model with params:\n" f"base_model: {base_model}\n" f"data_path: {data_path}\n" f"output_dir: {output_dir}\n" f"batch_size: {batch_size}\n" f"micro_batch_size: {micro_batch_size}\n" f"num_epochs: {num_epochs}\n" f"learning_rate: {learning_rate}\n" f"cutoff_len: {cutoff_len}\n" f"val_set_size: {val_set_size}\n" f"lora_r: {lora_r}\n" f"lora_alpha: {lora_alpha}\n" f"lora_dropout: {lora_dropout}\n" f"lora_target_modules: {lora_target_modules}\n" f"train_on_inputs: {train_on_inputs}\n" f"group_by_length: {group_by_length}\n" f"wandb_project: {wandb_project}\n" f"wandb_run_name: {wandb_run_name}\n" f"wandb_watch: {wandb_watch}\n" f"wandb_log_model: {wandb_log_model}\n" f"resume_from_checkpoint: {resume_from_checkpoint or False}\n" f"prompt template: {prompt_template_name}\n" ) assert ( base_model ), "Please specify a --base_model, e.g. --base_model='decapoda-research/llama-7b-hf'" gradient_accumulation_steps = batch_size // micro_batch_size prompter = Prompter(prompt_template_name) world_size = os.environ.get("WORLD_SIZE", 1) print("world_size:", world_size) device_map = "auto" world_size = int(os.environ.get("WORLD_SIZE", 1)) ddp = world_size != 1 print("ddp:", ddp) if ddp: device_map = {"": int(os.environ.get("LOCAL_RANK") or 0)} gradient_accumulation_steps = gradient_accumulation_steps // world_size # Check if parameter passed or if set within environ use_wandb = len(wandb_project) > 0 or ( "WANDB_PROJECT" in os.environ and len(os.environ["WANDB_PROJECT"]) > 0 ) # Only overwrite environ if wandb param passed if len(wandb_project) > 0: os.environ["WANDB_PROJECT"] = wandb_project if len(wandb_watch) > 0: os.environ["WANDB_WATCH"] = wandb_watch if len(wandb_log_model) > 0: os.environ["WANDB_LOG_MODEL"] = wandb_log_model model = LlamaForCausalLM.from_pretrained( base_model, load_in_8bit=True, torch_dtype=torch.float16, device_map=device_map, ) tokenizer = LlamaTokenizer.from_pretrained(base_model) tokenizer.pad_token_id = ( 0 # unk. we want this to be different from the eos token ) tokenizer.padding_side = "left" # Allow batched inference def tokenize(prompt, add_eos_token=True): # there's probably a way to do this with the tokenizer settings # but again, gotta move fast result = tokenizer( prompt, truncation=True, max_length=cutoff_len, padding=False, return_tensors=None, ) if ( result["input_ids"][-1] != tokenizer.eos_token_id and len(result["input_ids"]) < cutoff_len and add_eos_token ): result["input_ids"].append(tokenizer.eos_token_id) result["attention_mask"].append(1) result["labels"] = result["input_ids"].copy() return result def generate_and_tokenize_prompt(data_point): full_prompt = prompter.generate_prompt( data_point["instruction"], data_point["input"], data_point["output"], ) tokenized_full_prompt = tokenize(full_prompt) if not train_on_inputs: user_prompt = prompter.generate_prompt( data_point["instruction"], data_point["input"] ) tokenized_user_prompt = tokenize(user_prompt, add_eos_token=False) user_prompt_len = len(tokenized_user_prompt["input_ids"]) tokenized_full_prompt["labels"] = [ -100 ] * user_prompt_len + tokenized_full_prompt["labels"][ user_prompt_len: ] # could be sped up, probably return tokenized_full_prompt model = prepare_model_for_int8_training(model) config = LoraConfig( r=lora_r, lora_alpha=lora_alpha, target_modules=lora_target_modules, lora_dropout=lora_dropout, bias="none", task_type="CAUSAL_LM", ) model = get_peft_model(model, config) if data_path.endswith(".json") or data_path.endswith(".jsonl"): data = load_dataset("json", data_files=data_path) else: data = load_dataset(data_path) if resume_from_checkpoint: # Check the available weights and load them checkpoint_name = os.path.join( resume_from_checkpoint, "pytorch_model.bin" ) # Full checkpoint if not os.path.exists(checkpoint_name): checkpoint_name = os.path.join( resume_from_checkpoint, "adapter_model.bin" ) # only LoRA model - LoRA config above has to fit resume_from_checkpoint = ( False # So the trainer won't try loading its state ) # The two files above have a different name depending on how they were saved, but are actually the same. if os.path.exists(checkpoint_name): print(f"Restarting from {checkpoint_name}") adapters_weights = torch.load(checkpoint_name) model = set_peft_model_state_dict(model, adapters_weights) else: print(f"Checkpoint {checkpoint_name} not found") model.print_trainable_parameters() # Be more transparent about the % of trainable params. if val_set_size > 0: train_val = data["train"].train_test_split( test_size=val_set_size, shuffle=True, seed=42 ) train_data = ( train_val["train"].shuffle().map(generate_and_tokenize_prompt) ) val_data = ( train_val["test"].shuffle().map(generate_and_tokenize_prompt) ) else: train_data = data["train"].shuffle().map(generate_and_tokenize_prompt) val_data = None print("device count:", torch.cuda.device_count()) if not ddp and torch.cuda.device_count() > 1: print("set model paralle") # keeps Trainer from trying its own DataParallelism when more than 1 gpu is available model.is_parallelizable = True model.model_parallel = True trainer = transformers.Trainer( model=model, train_dataset=train_data, eval_dataset=val_data, args=transformers.TrainingArguments( per_device_train_batch_size=micro_batch_size, gradient_accumulation_steps=gradient_accumulation_steps, warmup_steps=100, num_train_epochs=num_epochs, learning_rate=learning_rate, fp16=True, logging_steps=10, optim="adamw_torch", evaluation_strategy="epoch" if val_set_size > 0 else "no", save_strategy="epoch", output_dir=output_dir, save_total_limit=2, load_best_model_at_end=True if val_set_size > 0 else False, ddp_find_unused_parameters=False if ddp else None, group_by_length=group_by_length, report_to="tensorboard" ), data_collator=transformers.DataCollatorForSeq2Seq( tokenizer, pad_to_multiple_of=8, return_tensors="pt", padding=True ), ) model.config.use_cache = False old_state_dict = model.state_dict model.state_dict = ( lambda self, *_, **__: get_peft_model_state_dict( self, old_state_dict() ) ).__get__(model, type(model)) if torch.__version__ >= "2" and sys.platform != "win32": model = torch.compile(model) trainer.train(resume_from_checkpoint=resume_from_checkpoint) model.save_pretrained(output_dir) print( "\n If there's a warning about missing keys above, please disregard :)" ) if __name__ == "__main__": fire.Fire(train) ================================================ FILE: llm-train/alpaca-lora/generate.py ================================================ import os import sys import fire import gradio as gr import torch import transformers from peft import PeftModel from transformers import GenerationConfig, LlamaForCausalLM, LlamaTokenizer from utils.prompter import Prompter if torch.cuda.is_available(): device = "cuda" else: device = "cpu" try: if torch.backends.mps.is_available(): device = "mps" except: # noqa: E722 pass def main( load_8bit: bool = False, base_model: str = "", lora_weights: str = "tloen/alpaca-lora-7b", prompt_template: str = "", # The prompt template to use, will default to alpaca. server_name: str = "0.0.0.0", # Allows to listen on all interfaces by providing '0. share_gradio: bool = False, ): base_model = base_model or os.environ.get("BASE_MODEL", "") assert ( base_model ), "Please specify a --base_model, e.g. --base_model='decapoda-research/llama-7b-hf'" prompter = Prompter(prompt_template) tokenizer = LlamaTokenizer.from_pretrained(base_model) if device == "cuda": print("------------------------------------11111111111111111111") model = LlamaForCausalLM.from_pretrained( base_model, load_in_8bit=load_8bit, torch_dtype=torch.float16, device_map="auto", ) model = PeftModel.from_pretrained( model, lora_weights, torch_dtype=torch.float16, ) elif device == "mps": model = LlamaForCausalLM.from_pretrained( base_model, device_map={"": device}, torch_dtype=torch.float16, ) model = PeftModel.from_pretrained( model, lora_weights, device_map={"": device}, torch_dtype=torch.float16, ) else: print("-----------------------------22222222222222222222222") model = LlamaForCausalLM.from_pretrained( base_model, device_map={"": device}, low_cpu_mem_usage=True ) model = PeftModel.from_pretrained( model, lora_weights, device_map={"": device}, ) # unwind broken decapoda-research config model.config.pad_token_id = tokenizer.pad_token_id = 0 # unk model.config.bos_token_id = 1 model.config.eos_token_id = 2 if not load_8bit: model.half() # seems to fix bugs for some users. model.eval() if torch.__version__ >= "2" and sys.platform != "win32": model = torch.compile(model) def evaluate( instruction, input=None, temperature=0.1, top_p=0.75, top_k=40, num_beams=4, max_new_tokens=128, **kwargs, ): prompt = prompter.generate_prompt(instruction, input) inputs = tokenizer(prompt, return_tensors="pt") input_ids = inputs["input_ids"].to(device) generation_config = GenerationConfig( temperature=temperature, top_p=top_p, top_k=top_k, num_beams=num_beams, **kwargs, ) with torch.no_grad(): generation_output = model.generate( input_ids=input_ids, generation_config=generation_config, return_dict_in_generate=True, output_scores=True, max_new_tokens=max_new_tokens, ) s = generation_output.sequences[0] output = tokenizer.decode(s) return prompter.get_response(output) gr.Interface( fn=evaluate, inputs=[ gr.components.Textbox( lines=2, label="Instruction", placeholder="Tell me about alpacas.", ), gr.components.Textbox(lines=2, label="Input", placeholder="none"), gr.components.Slider( minimum=0, maximum=1, value=0.1, label="Temperature" ), gr.components.Slider( minimum=0, maximum=1, value=0.75, label="Top p" ), gr.components.Slider( minimum=0, maximum=100, step=1, value=40, label="Top k" ), gr.components.Slider( minimum=1, maximum=4, step=1, value=4, label="Beams" ), gr.components.Slider( minimum=1, maximum=2000, step=1, value=128, label="Max tokens" ), ], outputs=[ gr.inputs.Textbox( lines=5, label="Output", ) ], title="🦙🌲 Alpaca-LoRA", description="Alpaca-LoRA is a 7B-parameter LLaMA model finetuned to follow instructions. It is trained on the [Stanford Alpaca](https://github.com/tatsu-lab/stanford_alpaca) dataset and makes use of the Huggingface LLaMA implementation. For more information, please visit [the project's website](https://github.com/tloen/alpaca-lora).", # noqa: E501 ).launch(server_name="0.0.0.0", share=share_gradio) # Old testing code follows. """ # testing code for readme for instruction in [ "Tell me about alpacas.", "Tell me about the president of Mexico in 2019.", "Tell me about the king of France in 2019.", "List all Canadian provinces in alphabetical order.", "Write a Python program that prints the first 10 Fibonacci numbers.", "Write a program that prints the numbers from 1 to 100. But for multiples of three print 'Fizz' instead of the number and for the multiples of five print 'Buzz'. For numbers which are multiples of both three and five print 'FizzBuzz'.", # noqa: E501 "Tell me five words that rhyme with 'shock'.", "Translate the sentence 'I have no mouth but I must scream' into Spanish.", "Count up from 1 to 500.", ]: print("Instruction:", instruction) print("Response:", evaluate(instruction)) print() """ if __name__ == "__main__": fire.Fire(main) ================================================ FILE: llm-train/alpaca-lora/inference.py ================================================ import sys from transformers import LlamaForCausalLM, AutoTokenizer import torch device = torch.device("cuda:2") if torch.cuda.is_available() else torch.device("cpu") tokenizer_path="/data/nfs/guodong.li/pretrain/hf-llama-model/tokenizer" model_path = "/home/guodong.li/output/hf_65b_ckpt" # You can modify the path for storing the local model model = LlamaForCausalLM.from_pretrained(model_path, torch_dtype=torch.float16, load_in_8bit=True, device_map="auto") tokenizer = AutoTokenizer.from_pretrained(tokenizer_path) print("Human:") line = input() while line: inputs = 'Human: ' + line.strip() + '\n\nAssistant:' input_ids = tokenizer(inputs, return_tensors="pt").input_ids input_ids = input_ids.to(device) outputs = model.generate(input_ids, max_new_tokens=500, do_sample = True, top_k = 30, top_p = 0.85, temperature = 0.5, repetition_penalty=1., eos_token_id=2, bos_token_id=1, pad_token_id=0) rets = tokenizer.batch_decode(outputs, skip_special_tokens=True, clean_up_tokenization_spaces=False) print("Assistant:\n" + rets[0].strip().replace(inputs, "")) print("\n------------------------------------------------\nHuman:") line = input() ================================================ FILE: llm-train/chatglm/README.md ================================================ ## ChatGLM-6B - code: `https://github.com/THUDM/ChatGLM-6B ` - commit id: `8633db1503fc3b0edc1d035f64aa35dce5d97969` ## 问题 ChatGLM-6B 使用 P-Tuning v2 和 Deepspeed 数据并行 loss 不一致的问题,请查看该[issue](https://github.com/THUDM/ChatGLM-6B/issues/644)。 ================================================ FILE: llm-train/chatglm/deepspeed.json ================================================ { "train_micro_batch_size_per_gpu": "auto", "zero_allow_untested_optimizer": true, "fp16": { "enabled": "auto", "loss_scale": 0, "initial_scale_power": 16, "loss_scale_window": 1000, "hysteresis": 2, "min_loss_scale": 1 }, "zero_optimization": { "stage": 2, "allgather_partitions": true, "allgather_bucket_size": 5e8, "overlap_comm": false, "reduce_scatter": true, "reduce_bucket_size": 5e8, "contiguous_gradients" : true } } ================================================ FILE: llm-train/chatglm/ds_train_finetune.sh ================================================ LR=1e-4 MASTER_PORT=$(shuf -n 1 -i 10000-65535) deepspeed --num_gpus=8 --master_port $MASTER_PORT main.py \ --deepspeed deepspeed.json \ --do_train \ --train_file /data/nfs/llm/data/AdvertiseGen/train.json \ --test_file /data/nfs/llm/data/AdvertiseGen/dev.json \ --prompt_column content \ --response_column summary \ --overwrite_cache \ --model_name_or_path /data/nfs/llm/model/chatglm-6b \ --output_dir /home/guodong.li/output/adgen-chatglm-6b-ft-$LR \ --overwrite_output_dir \ --max_source_length 64 \ --max_target_length 64 \ --per_device_train_batch_size 30 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --predict_with_generate \ --num_train_epochs 10 \ --logging_steps 10 \ --save_steps 1000 \ --learning_rate $LR \ --fp16 ================================================ FILE: llm-train/chatglm/evaluate.sh ================================================ PRE_SEQ_LEN=128 CHECKPOINT=adgen-chatglm-6b-pt-128-2e-2 STEP=3000 # --model_name_or_path /data/nfs/llm/model/chatglm-6b \ # --ptuning_checkpoint /home/guodong.li/output/adgen-chatglm-6b-pt-128-2e-2/checkpoint-500 \ # --predict_with_generate \ CUDA_VISIBLE_DEVICES=1 python3 main.py \ --do_predict \ --validation_file /data/nfs/llm/data/AdvertiseGen/dev.json \ --test_file /data/nfs/llm/data/AdvertiseGen/dev.json \ --overwrite_cache \ --prompt_column content \ --response_column summary \ --model_name_or_path /home/guodong.li/output/adgen-chatglm-6b-ft-1e-4 \ --output_dir /home/guodong.li/output/adgen-chatglm-6b-ft-1e-4 \ --overwrite_output_dir \ --max_source_length 64 \ --max_target_length 64 \ --per_device_eval_batch_size 1 \ --pre_seq_len $PRE_SEQ_LEN \ --quantization_bit 4 ================================================ FILE: llm-train/chatglm/evaluate_finetune.sh ================================================ CHECKPOINT=adgen-chatglm-6b-ft-1e-4 STEP=3000 CUDA_VISIBLE_DEVICES=0 python3 main.py \ --do_predict \ --validation_file AdvertiseGen/dev.json \ --test_file AdvertiseGen/dev.json \ --overwrite_cache \ --prompt_column content \ --response_column summary \ --model_name_or_path ./output/$CHECKPOINT/checkpoint-$STEP \ --output_dir ./output/$CHECKPOINT \ --overwrite_output_dir \ --max_source_length 256 \ --max_target_length 256 \ --per_device_eval_batch_size 1 \ --predict_with_generate \ --fp16_full_eval ================================================ FILE: llm-train/chatglm/inference.py ================================================ import os import torch from transformers import AutoConfig, AutoModel, AutoTokenizer #MODEL_PATH = "/data/nfs/llm/model/chatglm-6b" #CHECKPOINT_PATH = "/home/guodong.li/output/adgen-chatglm-6b-pt-128-2e-2/" MODEL_PATH = "/home/guodong.li/output/adgen-chatglm-6b-ft-1e-4/" # 载入Tokenizer tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True) """ config = AutoConfig.from_pretrained(MODEL_PATH, trust_remote_code=True, pre_seq_len=128) model = AutoModel.from_pretrained(MODEL_PATH, config=config, trust_remote_code=True) """ config = AutoConfig.from_pretrained(MODEL_PATH, trust_remote_code=True) model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True) """ prefix_state_dict = torch.load(os.path.join(CHECKPOINT_PATH, "pytorch_model.bin")) new_prefix_state_dict = {} for k, v in prefix_state_dict.items(): if k.startswith("transformer.prefix_encoder."): new_prefix_state_dict[k[len("transformer.prefix_encoder."):]] = v model.transformer.prefix_encoder.load_state_dict(new_prefix_state_dict) """ print(f"Quantized to 4 bit") #model = model.quantize(4) model = model.half().cuda() """ model.transformer.prefix_encoder.float() """ model = model.eval() print("用户:你好\n") response, history = model.chat(tokenizer, "你好", history=[]) print("ChatGLM-6B:\n",response) print("\n------------------------------------------------\n用户:") line = input() while line: # response, history = model.chat(tokenizer, line, history=history) response, history = model.chat(tokenizer, line, history=[]) print("ChatGLM-6B:\n", response) print("\n------------------------------------------------\n用户:") line = input() ================================================ FILE: llm-train/chatglm/main.py ================================================ #!/usr/bin/env python # coding=utf-8 """ Fine-tuning the library models for sequence to sequence. """ # You can also adapt this script on your own sequence to sequence task. Pointers for this are left as comments. import logging import os import sys import json import numpy as np from datasets import load_dataset import jieba from rouge_chinese import Rouge from nltk.translate.bleu_score import sentence_bleu, SmoothingFunction import torch import transformers from transformers import ( AutoConfig, AutoModel, AutoTokenizer, AutoTokenizer, DataCollatorForSeq2Seq, HfArgumentParser, Seq2SeqTrainingArguments, set_seed, ) from trainer_seq2seq import Seq2SeqTrainer from arguments import ModelArguments, DataTrainingArguments logger = logging.getLogger(__name__) def main(): parser = HfArgumentParser((ModelArguments, DataTrainingArguments, Seq2SeqTrainingArguments)) if len(sys.argv) == 2 and sys.argv[1].endswith(".json"): # If we pass only one argument to the script and it's the path to a json file, # let's parse it to get our arguments. model_args, data_args, training_args = parser.parse_json_file(json_file=os.path.abspath(sys.argv[1])) else: model_args, data_args, training_args = parser.parse_args_into_dataclasses() # Setup logging logging.basicConfig( format="%(asctime)s - %(levelname)s - %(name)s - %(message)s", datefmt="%m/%d/%Y %H:%M:%S", handlers=[logging.StreamHandler(sys.stdout)], ) if training_args.should_log: # The default of training_args.log_level is passive, so we set log level at info here to have that default. transformers.utils.logging.set_verbosity_info() log_level = training_args.get_process_log_level() logger.setLevel(log_level) # datasets.utils.logging.set_verbosity(log_level) transformers.utils.logging.set_verbosity(log_level) transformers.utils.logging.enable_default_handler() transformers.utils.logging.enable_explicit_format() # Log on each process the small summary: logger.warning( f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}" + f"distributed training: {bool(training_args.local_rank != -1)}, 16-bits training: {training_args.fp16}" ) logger.info(f"Training/evaluation parameters {training_args}") # Set seed before initializing model. set_seed(training_args.seed) # Load dataset data_files = {} if data_args.train_file is not None: data_files["train"] = data_args.train_file extension = data_args.train_file.split(".")[-1] if data_args.validation_file is not None: data_files["validation"] = data_args.validation_file extension = data_args.validation_file.split(".")[-1] if data_args.test_file is not None: data_files["test"] = data_args.test_file extension = data_args.test_file.split(".")[-1] raw_datasets = load_dataset( extension, data_files=data_files, cache_dir=model_args.cache_dir, use_auth_token=True if model_args.use_auth_token else None, ) # Load pretrained model and tokenizer config = AutoConfig.from_pretrained(model_args.model_name_or_path, trust_remote_code=True) config.pre_seq_len = model_args.pre_seq_len config.prefix_projection = model_args.prefix_projection tokenizer = AutoTokenizer.from_pretrained(model_args.model_name_or_path, trust_remote_code=True) if model_args.ptuning_checkpoint is not None: # Evaluation # Loading extra state dict of prefix encoder model = AutoModel.from_pretrained(model_args.model_name_or_path, config=config, trust_remote_code=True) prefix_state_dict = torch.load(os.path.join(model_args.ptuning_checkpoint, "pytorch_model.bin")) new_prefix_state_dict = {} for k, v in prefix_state_dict.items(): if k.startswith("transformer.prefix_encoder."): new_prefix_state_dict[k[len("transformer.prefix_encoder."):]] = v model.transformer.prefix_encoder.load_state_dict(new_prefix_state_dict) else: model = AutoModel.from_pretrained(model_args.model_name_or_path, config=config, trust_remote_code=True) if model_args.quantization_bit is not None: print(f"Quantized to {model_args.quantization_bit} bit") model = model.quantize(model_args.quantization_bit) if model_args.pre_seq_len is not None: # P-tuning v2 model = model.half() model.transformer.prefix_encoder.float() else: # Finetune model = model.float() prefix = data_args.source_prefix if data_args.source_prefix is not None else "" # Preprocessing the datasets. # We need to tokenize inputs and targets. if training_args.do_train: column_names = raw_datasets["train"].column_names elif training_args.do_eval: column_names = raw_datasets["validation"].column_names elif training_args.do_predict: column_names = raw_datasets["test"].column_names else: logger.info("There is nothing to do. Please pass `do_train`, `do_eval` and/or `do_predict`.") return # Get the column names for input/target. prompt_column = data_args.prompt_column response_column = data_args.response_column history_column = data_args.history_column # Temporarily set max_target_length for training. max_target_length = data_args.max_target_length def preprocess_function_eval(examples): inputs, targets = [], [] for i in range(len(examples[prompt_column])): if examples[prompt_column][i] and examples[response_column][i]: query = examples[prompt_column][i] if history_column is None or len(examples[history_column][i]) == 0: prompt = query else: prompt = "" history = examples[history_column][i] for turn_idx, (old_query, response) in enumerate(history): prompt += "[Round {}]\n问:{}\n答:{}\n".format(turn_idx, old_query, response) prompt += "[Round {}]\n问:{}\n答:".format(len(history), query) inputs.append(prompt) targets.append(examples[response_column][i]) inputs = [prefix + inp for inp in inputs] model_inputs = tokenizer(inputs, max_length=data_args.max_source_length, truncation=True, padding=True) labels = tokenizer(text_target=targets, max_length=max_target_length, truncation=True) if data_args.ignore_pad_token_for_loss: labels["input_ids"] = [ [(l if l != tokenizer.pad_token_id else -100) for l in label] for label in labels["input_ids"] ] model_inputs["labels"] = labels["input_ids"] return model_inputs def preprocess_function_train(examples): max_seq_length = data_args.max_source_length + data_args.max_target_length model_inputs = { "input_ids": [], "labels": [], } for i in range(len(examples[prompt_column])): if examples[prompt_column][i] and examples[response_column][i]: query, answer = examples[prompt_column][i], examples[response_column][i] if history_column is None: prompt = query else: prompt = "" history = examples[history_column][i] for turn_idx, (old_query, response) in enumerate(history): prompt += "[Round {}]\n问:{}\n答:{}\n".format(turn_idx, old_query, response) prompt += "[Round {}]\n问:{}\n答:".format(len(history), query) prompt = prefix + prompt a_ids = tokenizer.encode(text=prompt, add_special_tokens=False) b_ids = tokenizer.encode(text=answer, add_special_tokens=False) if len(a_ids) > data_args.max_source_length - 1: a_ids = a_ids[: data_args.max_source_length - 1] if len(b_ids) > data_args.max_target_length - 2: b_ids = b_ids[: data_args.max_target_length - 2] input_ids = tokenizer.build_inputs_with_special_tokens(a_ids, b_ids) context_length = input_ids.index(tokenizer.bos_token_id) mask_position = context_length - 1 labels = [-100] * context_length + input_ids[mask_position+1:] pad_len = max_seq_length - len(input_ids) input_ids = input_ids + [tokenizer.pad_token_id] * pad_len labels = labels + [tokenizer.pad_token_id] * pad_len if data_args.ignore_pad_token_for_loss: labels = [(l if l != tokenizer.pad_token_id else -100) for l in labels] model_inputs["input_ids"].append(input_ids) model_inputs["labels"].append(labels) return model_inputs def print_dataset_example(example): print("input_ids",example["input_ids"]) print("inputs", tokenizer.decode(example["input_ids"])) print("label_ids", example["labels"]) print("labels", tokenizer.decode(example["labels"])) if training_args.do_train: if "train" not in raw_datasets: raise ValueError("--do_train requires a train dataset") train_dataset = raw_datasets["train"] if data_args.max_train_samples is not None: max_train_samples = min(len(train_dataset), data_args.max_train_samples) train_dataset = train_dataset.select(range(max_train_samples)) with training_args.main_process_first(desc="train dataset map pre-processing"): train_dataset = train_dataset.map( preprocess_function_train, batched=True, num_proc=data_args.preprocessing_num_workers, remove_columns=column_names, load_from_cache_file=not data_args.overwrite_cache, desc="Running tokenizer on train dataset", ) print_dataset_example(train_dataset[0]) if training_args.do_eval: max_target_length = data_args.val_max_target_length if "validation" not in raw_datasets: raise ValueError("--do_eval requires a validation dataset") eval_dataset = raw_datasets["validation"] if data_args.max_eval_samples is not None: max_eval_samples = min(len(eval_dataset), data_args.max_eval_samples) eval_dataset = eval_dataset.select(range(max_eval_samples)) with training_args.main_process_first(desc="validation dataset map pre-processing"): eval_dataset = eval_dataset.map( preprocess_function_eval, batched=True, num_proc=data_args.preprocessing_num_workers, remove_columns=column_names, load_from_cache_file=not data_args.overwrite_cache, desc="Running tokenizer on validation dataset", ) print_dataset_example(eval_dataset[0]) if training_args.do_predict: max_target_length = data_args.val_max_target_length if "test" not in raw_datasets: raise ValueError("--do_predict requires a test dataset") predict_dataset = raw_datasets["test"] if data_args.max_predict_samples is not None: max_predict_samples = min(len(predict_dataset), data_args.max_predict_samples) predict_dataset = predict_dataset.select(range(max_predict_samples)) with training_args.main_process_first(desc="prediction dataset map pre-processing"): predict_dataset = predict_dataset.map( preprocess_function_eval, batched=True, num_proc=data_args.preprocessing_num_workers, remove_columns=column_names, load_from_cache_file=not data_args.overwrite_cache, desc="Running tokenizer on prediction dataset", ) print_dataset_example(predict_dataset[0]) # Data collator label_pad_token_id = -100 if data_args.ignore_pad_token_for_loss else tokenizer.pad_token_id data_collator = DataCollatorForSeq2Seq( tokenizer, model=model, label_pad_token_id=label_pad_token_id, pad_to_multiple_of=None, padding=False ) # Metric def compute_metrics(eval_preds): preds, labels = eval_preds if isinstance(preds, tuple): preds = preds[0] decoded_preds = tokenizer.batch_decode(preds, skip_special_tokens=True) if data_args.ignore_pad_token_for_loss: # Replace -100 in the labels as we can't decode them. labels = np.where(labels != -100, labels, tokenizer.pad_token_id) decoded_labels = tokenizer.batch_decode(labels, skip_special_tokens=True) score_dict = { "rouge-1": [], "rouge-2": [], "rouge-l": [], "bleu-4": [] } for pred, label in zip(decoded_preds, decoded_labels): hypothesis = list(jieba.cut(pred)) reference = list(jieba.cut(label)) rouge = Rouge() scores = rouge.get_scores(' '.join(hypothesis) , ' '.join(reference)) result = scores[0] for k, v in result.items(): score_dict[k].append(round(v["f"] * 100, 4)) bleu_score = sentence_bleu([list(label)], list(pred), smoothing_function=SmoothingFunction().method3) score_dict["bleu-4"].append(round(bleu_score * 100, 4)) for k, v in score_dict.items(): score_dict[k] = float(np.mean(v)) return score_dict # Override the decoding parameters of Seq2SeqTrainer training_args.generation_max_length = ( training_args.generation_max_length if training_args.generation_max_length is not None else data_args.val_max_target_length ) training_args.generation_num_beams = ( data_args.num_beams if data_args.num_beams is not None else training_args.generation_num_beams ) # Initialize our Trainer trainer = Seq2SeqTrainer( model=model, args=training_args, train_dataset=train_dataset if training_args.do_train else None, eval_dataset=eval_dataset if training_args.do_eval else None, tokenizer=tokenizer, data_collator=data_collator, compute_metrics=compute_metrics if training_args.predict_with_generate else None, save_prefixencoder=model_args.pre_seq_len is not None ) # Training if training_args.do_train: checkpoint = None if training_args.resume_from_checkpoint is not None: checkpoint = training_args.resume_from_checkpoint # elif last_checkpoint is not None: # checkpoint = last_checkpoint model.gradient_checkpointing_enable() model.enable_input_require_grads() train_result = trainer.train(resume_from_checkpoint=checkpoint) trainer.save_model() # Saves the tokenizer too for easy upload metrics = train_result.metrics max_train_samples = ( data_args.max_train_samples if data_args.max_train_samples is not None else len(train_dataset) ) metrics["train_samples"] = min(max_train_samples, len(train_dataset)) trainer.log_metrics("train", metrics) trainer.save_metrics("train", metrics) trainer.save_state() # Evaluation results = {} if training_args.do_eval: logger.info("*** Evaluate ***") metrics = trainer.evaluate(metric_key_prefix="eval", do_sample=True, top_p=0.7, max_length=512, temperature=0.95) max_eval_samples = data_args.max_eval_samples if data_args.max_eval_samples is not None else len(eval_dataset) metrics["eval_samples"] = min(max_eval_samples, len(eval_dataset)) trainer.log_metrics("eval", metrics) trainer.save_metrics("eval", metrics) if training_args.do_predict: logger.info("*** Predict ***") predict_results = trainer.predict(predict_dataset, metric_key_prefix="predict", max_length=512, do_sample=True, top_p=0.7, temperature=0.95) metrics = predict_results.metrics max_predict_samples = ( data_args.max_predict_samples if data_args.max_predict_samples is not None else len(predict_dataset) ) metrics["predict_samples"] = min(max_predict_samples, len(predict_dataset)) trainer.log_metrics("predict", metrics) trainer.save_metrics("predict", metrics) if trainer.is_world_process_zero(): if training_args.predict_with_generate: predictions = tokenizer.batch_decode( predict_results.predictions, skip_special_tokens=True, clean_up_tokenization_spaces=True ) predictions = [pred.strip() for pred in predictions] labels = tokenizer.batch_decode( predict_results.label_ids, skip_special_tokens=True, clean_up_tokenization_spaces=True ) labels = [label.strip() for label in labels] output_prediction_file = os.path.join(training_args.output_dir, "generated_predictions.txt") with open(output_prediction_file, "w", encoding="utf-8") as writer: for p, l in zip(predictions, labels): res = json.dumps({"labels": l, "predict": p}, ensure_ascii=False) writer.write(f"{res}\n") return results def _mp_fn(index): # For xla_spawn (TPUs) main() if __name__ == "__main__": main() ================================================ FILE: llm-train/chatglm/train.sh ================================================ PRE_SEQ_LEN=128 LR=2e-2 CUDA_VISIBLE_DEVICES=0 python3 main.py \ --do_train \ --train_file /data/nfs/llm/data/AdvertiseGen/dev.json \ --validation_file /data/nfs/llm/data/AdvertiseGen/dev.json \ --prompt_column content \ --response_column summary \ --overwrite_cache \ --model_name_or_path /data/nfs/llm/model/chatglm-6b \ --output_dir /home/guodong.li/output/adgen-chatglm-6b-pt-$PRE_SEQ_LEN-$LR \ --overwrite_output_dir \ --max_source_length 64 \ --max_target_length 64 \ --per_device_train_batch_size 128 \ --per_device_eval_batch_size 8 \ --gradient_accumulation_steps 16 \ --predict_with_generate \ --num_train_epochs 10 \ --logging_steps 10 \ --save_steps 100 \ --learning_rate $LR \ --pre_seq_len $PRE_SEQ_LEN ================================================ FILE: llm-train/chatglm/train_ptuningv2_dp.sh ================================================ PRE_SEQ_LEN=128 LR=2e-2 deepspeed --include localhost:1,2,3 --master_port 29001 main.py \ --deepspeed deepspeed.json \ --do_train \ --train_file /data/nfs/llm/data/AdvertiseGen/train.json \ --validation_file /data/nfs/llm/data/AdvertiseGen/dev.json \ --prompt_column content \ --response_column summary \ --overwrite_cache \ --model_name_or_path /data/nfs/llm/model/chatglm-6b \ --output_dir /home/guodong.li/output/adgen-chatglm-6b-pt \ --overwrite_output_dir \ --max_source_length 64 \ --max_target_length 64 \ --per_device_train_batch_size 128 \ --per_device_eval_batch_size 8 \ --gradient_accumulation_steps 16 \ --predict_with_generate \ --num_train_epochs 10 \ --logging_steps 10 \ --save_steps 100 \ --learning_rate $LR \ --pre_seq_len $PRE_SEQ_LEN ================================================ FILE: llm-train/chatglm-lora/README.md ================================================ ## ChatGLM-Tuning - code: `https://github.com/mymusise/ChatGLM-Tuning.git` - commit id : `997393046a49510e6cda36962f9a399297959311` ================================================ FILE: llm-train/chatglm-lora/finetune.py ================================================ from transformers.integrations import TensorBoardCallback from torch.utils.tensorboard import SummaryWriter from transformers import TrainingArguments from transformers import Trainer, HfArgumentParser from transformers import AutoTokenizer, AutoModel import torch import torch.nn as nn from peft import get_peft_model, LoraConfig, TaskType from dataclasses import dataclass, field import datasets import os # TODO # tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained("/data/nfs/llm/model/chatglm-6b", trust_remote_code=True) @dataclass class FinetuneArguments: dataset_path: str = field(default="data/alpaca") model_path: str = field(default="output") lora_rank: int = field(default=8) class CastOutputToFloat(nn.Sequential): def forward(self, x): return super().forward(x).to(torch.float32) def data_collator(features: list) -> dict: len_ids = [len(feature["input_ids"]) for feature in features] longest = max(len_ids) input_ids = [] labels_list = [] for ids_l, feature in sorted(zip(len_ids, features), key=lambda x: -x[0]): ids = feature["input_ids"] seq_len = feature["seq_len"] labels = ( [-100] * (seq_len - 1) + ids[(seq_len - 1) :] + [-100] * (longest - ids_l) ) ids = ids + [tokenizer.pad_token_id] * (longest - ids_l) _ids = torch.LongTensor(ids) labels_list.append(torch.LongTensor(labels)) input_ids.append(_ids) input_ids = torch.stack(input_ids) labels = torch.stack(labels_list) return { "input_ids": input_ids, "labels": labels, } class ModifiedTrainer(Trainer): def compute_loss(self, model, inputs, return_outputs=False): return model( input_ids=inputs["input_ids"], labels=inputs["labels"], ).loss def save_model(self, output_dir=None, _internal_call=False): from transformers.trainer import TRAINING_ARGS_NAME os.makedirs(output_dir, exist_ok=True) torch.save(self.args, os.path.join(output_dir, TRAINING_ARGS_NAME)) saved_params = { k: v.to("cpu") for k, v in self.model.named_parameters() if v.requires_grad } torch.save(saved_params, os.path.join(output_dir, "adapter_model.bin")) def main(): writer = SummaryWriter() finetune_args, training_args = HfArgumentParser( (FinetuneArguments, TrainingArguments) ).parse_args_into_dataclasses() # init model # TODO """ model = AutoModel.from_pretrained( "THUDM/chatglm-6b", load_in_8bit=True, trust_remote_code=True, device_map="auto" ) """ model = AutoModel.from_pretrained( "/data/nfs/llm/model/chatglm-6b", load_in_8bit=True, trust_remote_code=True, device_map="auto" ) model.gradient_checkpointing_enable() model.enable_input_require_grads() model.is_parallelizable = True model.model_parallel = True model.lm_head = CastOutputToFloat(model.lm_head) model.config.use_cache = ( False # silence the warnings. Please re-enable for inference! ) # setup peft peft_config = LoraConfig( task_type=TaskType.CAUSAL_LM, inference_mode=False, r=finetune_args.lora_rank, lora_alpha=32, lora_dropout=0.1, ) model = get_peft_model(model, peft_config) # load dataset dataset = datasets.load_from_disk(finetune_args.dataset_path) print(f"\n{len(dataset)=}\n") # start train trainer = ModifiedTrainer( model=model, train_dataset=dataset, args=training_args, callbacks=[TensorBoardCallback(writer)], data_collator=data_collator, ) trainer.train() writer.close() # save model model.save_pretrained(training_args.output_dir) if __name__ == "__main__": main() ================================================ FILE: llm-train/chatglm-lora/finetune_ddp.py ================================================ from transformers.integrations import TensorBoardCallback from torch.utils.tensorboard import SummaryWriter from transformers import TrainingArguments from transformers import Trainer, HfArgumentParser from transformers import AutoTokenizer, AutoModel import torch import torch.nn as nn from peft import get_peft_model, LoraConfig, TaskType from dataclasses import dataclass, field import datasets import os from typing import Optional, Dict, Sequence, List # TODO # tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True) tokenizer = AutoTokenizer.from_pretrained("/data/nfs/llm/model/chatglm-6b", trust_remote_code=True, revision="") """ while True: try: tokenizer = AutoTokenizer.from_pretrained("/data/nfs/llm/model/chatglm-6b", trust_remote_code=True, revision="") break except: pass """ @dataclass class FinetuneArguments: dataset_path: str = field(default="data/alpaca") model_path: str = field(default="output") lora_rank: int = field(default=8) class CastOutputToFloat(nn.Sequential): def forward(self, x): return super().forward(x).to(torch.float32) def data_collator(features: list) -> dict: len_ids = [len(feature["input_ids"]) for feature in features] longest = max(len_ids) input_ids = [] labels_list = [] for ids_l, feature in sorted(zip(len_ids, features), key=lambda x: -x[0]): ids = feature["input_ids"] seq_len = feature["seq_len"] labels = ( [-100] * (seq_len - 1) + ids[(seq_len - 1) :] + [-100] * (longest - ids_l) ) ids = ids + [tokenizer.pad_token_id] * (longest - ids_l) _ids = torch.LongTensor(ids) labels_list.append(torch.LongTensor(labels)) input_ids.append(_ids) input_ids = torch.stack(input_ids) labels = torch.stack(labels_list) return { "input_ids": input_ids, "labels": labels, } class ModifiedTrainer(Trainer): def compute_loss(self, model, inputs, return_outputs=False): return model( input_ids=inputs["input_ids"], labels=inputs["labels"], ).loss def save_model(self, output_dir=None, _internal_call=False): from transformers.trainer import TRAINING_ARGS_NAME os.makedirs(output_dir, exist_ok=True) torch.save(self.args, os.path.join(output_dir, TRAINING_ARGS_NAME)) saved_params = { k: v.to("cpu") for k, v in self.model.named_parameters() if v.requires_grad } torch.save(saved_params, os.path.join(output_dir, "adapter_model.bin")) def main(): writer = SummaryWriter() finetune_args, training_args = HfArgumentParser( (FinetuneArguments, TrainingArguments) ).parse_args_into_dataclasses() # init model # TODO """ model = AutoModel.from_pretrained( "THUDM/chatglm-6b", load_in_8bit=True, trust_remote_code=True, device_map="auto" ) """ while True: try: model = AutoModel.from_pretrained("/data/nfs/llm/model/chatglm-6b", trust_remote_code=True, revision="") break except: pass model.gradient_checkpointing_enable() model.enable_input_require_grads() #model.is_parallelizable = True #model.model_parallel = True model.lm_head = CastOutputToFloat(model.lm_head) model.config.use_cache = ( False # silence the warnings. Please re-enable for inference! ) # setup peft peft_config = LoraConfig( task_type=TaskType.CAUSAL_LM, inference_mode=False, r=finetune_args.lora_rank, lora_alpha=32, lora_dropout=0.1, ) model = get_peft_model(model, peft_config) # load dataset dataset = datasets.load_from_disk(finetune_args.dataset_path) print(f"\n{len(dataset)=}\n") training_args.ddp_find_unused_parameters=False # start train trainer = ModifiedTrainer( model=model, train_dataset=dataset, args=training_args, callbacks=[TensorBoardCallback(writer)], data_collator=data_collator, ) trainer.train() writer.close() # save model model.save_pretrained(training_args.output_dir) if __name__ == "__main__": main() ================================================ FILE: llm-train/chatglm-lora/inference.py ================================================ from transformers import AutoModel,AutoTokenizer import torch from peft import PeftModel import json from cover_alpaca2jsonl import format_example device = torch.device("cuda:0") if torch.cuda.is_available() else torch.device("cpu") model = AutoModel.from_pretrained("/data/nfs/llm/model/chatglm-6b", trust_remote_code=True, load_in_8bit=True, device_map='auto', revision="") tokenizer = AutoTokenizer.from_pretrained("/data/nfs/llm/model/chatglm-6b", trust_remote_code=True, revision="") model = PeftModel.from_pretrained(model, "/home/guodong.li/data/chatglm-6b-lora") # TODO instructions = json.load(open("/data/nfs/guodong.li/data/alpaca_data_cleaned.json")) answers = [] with torch.no_grad(): for idx, item in enumerate(instructions[:3]): feature = format_example(item) input_text = feature['context'] ids = tokenizer.encode(input_text) input_ids = torch.LongTensor([ids]) input_ids = input_ids.to(device) out = model.generate( input_ids=input_ids, max_length=150, do_sample=False, temperature=0 ) out_text = tokenizer.decode(out[0]) answer = out_text.replace(input_text, "").replace("\nEND", "").strip() item['infer_answer'] = answer print(out_text) print(f"### {idx+1}.Answer:\n", item.get('output'), '\n\n') answers.append({'index': idx, **item}) ================================================ FILE: llm-train/chinese-llama-alpaca/README.md ================================================ ## Chinese-LLaMA-Alpaca - 源码地址: https://github.com/ymcui/Chinese-LLaMA-Alpaca/ - commit id : 3e2f2529a4dc0d7567f46f1b2d3431a7d063588b ================================================ FILE: llm-train/chinese-llama-alpaca/inference_hf.py ================================================ import argparse import json, os parser = argparse.ArgumentParser() parser.add_argument('--base_model', default=None, type=str, required=True) parser.add_argument('--lora_model', default=None, type=str,help="If None, perform inference on the base model") parser.add_argument('--tokenizer_path',default=None,type=str) parser.add_argument('--data_file',default=None, type=str,help="A file that contains instructions (one instruction per line)") parser.add_argument('--with_prompt',action='store_true',help="wrap the input with the prompt automatically") parser.add_argument('--interactive',action='store_true',help="run in the instruction mode (single-turn)") parser.add_argument('--predictions_file', default='./predictions.json', type=str) parser.add_argument('--gpus', default="0", type=str) parser.add_argument('--only_cpu',action='store_true',help='only use CPU for inference') args = parser.parse_args() if args.only_cpu is True: args.gpus = "" os.environ["CUDA_VISIBLE_DEVICES"] = args.gpus import torch from transformers import LlamaForCausalLM, LlamaTokenizer from peft import PeftModel generation_config = dict( temperature=0.2, top_k=40, top_p=0.9, do_sample=True, num_beams=1, repetition_penalty=1.3, max_new_tokens=400 ) # The prompt template below is taken from llama.cpp # and is slightly different from the one used in training. # But we find it gives better results prompt_input = ( "Below is an instruction that describes a task. " "Write a response that appropriately completes the request.\n\n" "### Instruction:\n\n{instruction}\n\n### Response:\n\n" ) sample_data = ["为什么要减少污染,保护环境?"] def generate_prompt(instruction, input=None): if input: instruction = instruction + '\n' + input return prompt_input.format_map({'instruction': instruction}) if __name__ == '__main__': load_type = torch.float16 if torch.cuda.is_available(): device = torch.device(0) else: device = torch.device('cpu') if args.tokenizer_path is None: args.tokenizer_path = args.lora_model if args.lora_model is None: args.tokenizer_path = args.base_model tokenizer = LlamaTokenizer.from_pretrained(args.tokenizer_path) base_model = LlamaForCausalLM.from_pretrained( args.base_model, load_in_8bit=False, torch_dtype=load_type, low_cpu_mem_usage=True, device_map='auto', ) model_vocab_size = base_model.get_input_embeddings().weight.size(0) tokenzier_vocab_size = len(tokenizer) print(f"Vocab of the base model: {model_vocab_size}") print(f"Vocab of the tokenizer: {tokenzier_vocab_size}") if model_vocab_size!=tokenzier_vocab_size: assert tokenzier_vocab_size > model_vocab_size print("Resize model embeddings to fit tokenizer") base_model.resize_token_embeddings(tokenzier_vocab_size) if args.lora_model is not None: print("loading peft model") model = PeftModel.from_pretrained(base_model, args.lora_model,torch_dtype=load_type,device_map='auto',) else: model = base_model if device==torch.device('cpu'): model.float() # test data if args.data_file is None: examples = sample_data else: with open(args.data_file,'r') as f: examples = [l.strip() for l in f.readlines()] print("first 10 examples:") for example in examples[:10]: print(example) model.eval() with torch.no_grad(): if args.interactive: print("Start inference with instruction mode.") print('='*85) print("+ 该模式下仅支持单轮问答,无多轮对话能力。\n" "+ 如要进行多轮对话,请使用llama.cpp或llamachat工具。") print('-'*85) print("+ This mode only supports single-turn QA.\n" "+ If you want to experience multi-turn dialogue, please use llama.cpp or llamachat.") print('='*85) while True: raw_input_text = input("Input:") if len(raw_input_text.strip())==0: break if args.with_prompt: input_text = generate_prompt(instruction=raw_input_text) else: input_text = raw_input_text inputs = tokenizer(input_text,return_tensors="pt") #add_special_tokens=False ? generation_output = model.generate( input_ids = inputs["input_ids"].to(device), attention_mask = inputs['attention_mask'].to(device), eos_token_id=tokenizer.eos_token_id, pad_token_id=tokenizer.pad_token_id, **generation_config ) s = generation_output[0] output = tokenizer.decode(s,skip_special_tokens=True) if args.with_prompt: response = output.split("### Response:")[1].strip() else: response = output print("Response: ",response) print("\n") else: print("Start inference.") results = [] for index, example in enumerate(examples): if args.with_prompt is True: input_text = generate_prompt(instruction=example) else: input_text = example inputs = tokenizer(input_text,return_tensors="pt") #add_special_tokens=False ? generation_output = model.generate( input_ids = inputs["input_ids"].to(device), attention_mask = inputs['attention_mask'].to(device), eos_token_id=tokenizer.eos_token_id, pad_token_id=tokenizer.pad_token_id, **generation_config ) s = generation_output[0] output = tokenizer.decode(s,skip_special_tokens=True) if args.with_prompt: response = output.split("### Response:")[1].strip() else: response = output print(f"======={index}=======") print(f"Input: {example}\n") print(f"Output: {response}\n") results.append({"Input":input_text,"Output":response}) dirname = os.path.dirname(args.predictions_file) os.makedirs(dirname,exist_ok=True) with open(args.predictions_file,'w') as f: json.dump(results,f,ensure_ascii=False,indent=2) with open(dirname+'/generation_config.json','w') as f: json.dump(generation_config,f,ensure_ascii=False,indent=2) ================================================ FILE: llm-train/chinese-llama-alpaca/merge_llama_with_chinese_lora.py ================================================ """ Usage: python merge_llama_with_chinese_lora.py \ --base_model path/to/llama/model \ --lora_model path/to/first/lora/model [path/to/second/lora/model] \ --output_type [pth|huggingface] \ --output_dir path/to/output/dir """ import argparse import json import os import gc import torch import peft from peft import PeftModel from transformers import LlamaForCausalLM, LlamaTokenizer from huggingface_hub import hf_hub_download parser = argparse.ArgumentParser() parser.add_argument('--base_model', default=None, required=True, type=str, help="Please specify a base_model") parser.add_argument('--tokenizer_path', default=None, required=True, type=str, help="Please specify a tokenizer_path") parser.add_argument('--lora_model', default=None, required=True, type=str, help="Please specify LoRA models to be merged (ordered); use commas to separate multiple LoRA models.") parser.add_argument('--offload_dir', default=None, type=str, help="(Optional) Please specify a temp folder for offloading (useful for low-RAM machines). Default None (disable offload).") parser.add_argument('--output_type', default='pth', choices=['pth', 'huggingface'], type=str, help="save the merged model in pth or huggingface format.") parser.add_argument('--output_dir', default='./', type=str) emb_to_model_size = { 4096: '7B', 5120: '13B', 6656: '30B', 8192: '65B', } num_shards_of_models = {'7B': 1, '13B': 2} params_of_models = { '7B': { "dim": 4096, "multiple_of": 256, "n_heads": 32, "n_layers": 32, "norm_eps": 1e-06, "vocab_size": -1, }, '13B': { "dim": 5120, "multiple_of": 256, "n_heads": 40, "n_layers": 40, "norm_eps": 1e-06, "vocab_size": -1, }, } def transpose(weight, fan_in_fan_out): return weight.T if fan_in_fan_out else weight # Borrowed and modified from https://github.com/tloen/alpaca-lora def translate_state_dict_key(k): k = k.replace("base_model.model.", "") if k == "model.embed_tokens.weight": return "tok_embeddings.weight" elif k == "model.norm.weight": return "norm.weight" elif k == "lm_head.weight": return "output.weight" elif k.startswith("model.layers."): layer = k.split(".")[2] if k.endswith(".self_attn.q_proj.weight"): return f"layers.{layer}.attention.wq.weight" elif k.endswith(".self_attn.k_proj.weight"): return f"layers.{layer}.attention.wk.weight" elif k.endswith(".self_attn.v_proj.weight"): return f"layers.{layer}.attention.wv.weight" elif k.endswith(".self_attn.o_proj.weight"): return f"layers.{layer}.attention.wo.weight" elif k.endswith(".mlp.gate_proj.weight"): return f"layers.{layer}.feed_forward.w1.weight" elif k.endswith(".mlp.down_proj.weight"): return f"layers.{layer}.feed_forward.w2.weight" elif k.endswith(".mlp.up_proj.weight"): return f"layers.{layer}.feed_forward.w3.weight" elif k.endswith(".input_layernorm.weight"): return f"layers.{layer}.attention_norm.weight" elif k.endswith(".post_attention_layernorm.weight"): return f"layers.{layer}.ffn_norm.weight" elif k.endswith("rotary_emb.inv_freq") or "lora" in k: return None else: print(layer, k) raise NotImplementedError else: print(k) raise NotImplementedError def unpermute(w): return ( w.view(n_heads, 2, dim // n_heads // 2, dim).transpose(1, 2).reshape(dim, dim) ) def save_shards(model_sd, num_shards: int): # Add the no_grad context manager with torch.no_grad(): if num_shards == 1: new_state_dict = {} for k, v in model_sd.items(): new_k = translate_state_dict_key(k) if new_k is not None: if "wq" in new_k or "wk" in new_k: new_state_dict[new_k] = unpermute(v) else: new_state_dict[new_k] = v os.makedirs(output_dir, exist_ok=True) print(f"Saving shard 1 of {num_shards} into {output_dir}/consolidated.00.pth") torch.save(new_state_dict, output_dir + "/consolidated.00.pth") with open(output_dir + "/params.json", "w") as f: json.dump(params, f) else: new_state_dicts = [dict() for _ in range(num_shards)] for k in list(model_sd.keys()): v = model_sd[k] new_k = translate_state_dict_key(k) if new_k is not None: if new_k == 'tok_embeddings.weight': print(f"Processing {new_k}") assert v.size(1) % num_shards == 0 splits = v.split(v.size(1) // num_shards, dim=1) elif new_k == 'output.weight': print(f"Processing {new_k}") if v.size(0) % num_shards == 0: splits = v.split(v.size(0) // num_shards, dim=0) else: size_list = [v.size(0) // num_shards] * num_shards size_list[-1] += v.size(0) % num_shards splits = v.split(size_list, dim=0) # 13B: size_list == [24976,24977] elif new_k == 'norm.weight': print(f"Processing {new_k}") splits = [v] * num_shards elif 'ffn_norm.weight' in new_k: print(f"Processing {new_k}") splits = [v] * num_shards elif 'attention_norm.weight' in new_k: print(f"Processing {new_k}") splits = [v] * num_shards elif 'w1.weight' in new_k: print(f"Processing {new_k}") splits = v.split(v.size(0) // num_shards, dim=0) elif 'w2.weight' in new_k: print(f"Processing {new_k}") splits = v.split(v.size(1) // num_shards, dim=1) elif 'w3.weight' in new_k: print(f"Processing {new_k}") splits = v.split(v.size(0) // num_shards, dim=0) elif 'wo.weight' in new_k: print(f"Processing {new_k}") splits = v.split(v.size(1) // num_shards, dim=1) elif 'wv.weight' in new_k: print(f"Processing {new_k}") splits = v.split(v.size(0) // num_shards, dim=0) elif "wq.weight" in new_k or "wk.weight" in new_k: print(f"Processing {new_k}") v = unpermute(v) splits = v.split(v.size(0) // num_shards, dim=0) else: print(f"Unexpected key {new_k}") raise ValueError for sd, split in zip(new_state_dicts, splits): sd[new_k] = split.clone() del split del splits del model_sd[k], v gc.collect() # Effectively enforce garbage collection os.makedirs(output_dir, exist_ok=True) for i, new_state_dict in enumerate(new_state_dicts): print(f"Saving shard {i + 1} of {num_shards} into {output_dir}/consolidated.0{i}.pth") torch.save(new_state_dict, output_dir + f"/consolidated.0{i}.pth") with open(output_dir + "/params.json", "w") as f: print(f"Saving params.json into {output_dir}/params.json") json.dump(params, f) if __name__ == '__main__': args = parser.parse_args() base_model_path = args.base_model lora_model_paths = [s.strip() for s in args.lora_model.split(',') if len(s.strip()) != 0] tokenizer_paths = [s.strip() for s in args.tokenizer_path.split(',') if len(s.strip()) != 0] output_dir = args.output_dir output_type = args.output_type offload_dir = args.offload_dir print(f"Base model: {base_model_path}") print(f"LoRA model(s) {lora_model_paths}:") if offload_dir is not None: # Load with offloading, which is useful for low-RAM machines. # Note that if you have enough RAM, please use original method instead, as it is faster. base_model = LlamaForCausalLM.from_pretrained( base_model_path, load_in_8bit=False, torch_dtype=torch.float16, offload_folder=offload_dir, offload_state_dict=True, low_cpu_mem_usage=True, device_map={"": "cpu"}, ) else: # Original method without offloading base_model = LlamaForCausalLM.from_pretrained( base_model_path, load_in_8bit=False, torch_dtype=torch.float16, device_map={"": "cpu"}, ) ## infer the model size from the checkpoint embedding_size = base_model.get_input_embeddings().weight.size(1) model_size = emb_to_model_size[embedding_size] print(f"Peft version: {peft.__version__}") print(f"Loading LoRA for {model_size} model") lora_model = None lora_model_sd = None for lora_index, lora_model_path in enumerate(lora_model_paths): tokenizer_path = tokenizer_paths[lora_index] print(f"Loading LoRA: {lora_model_path} , tokenizer path: {tokenizer_path} ") # tokenizer = LlamaTokenizer.from_pretrained(lora_model_path) tokenizer = LlamaTokenizer.from_pretrained(tokenizer_path) if base_model.get_input_embeddings().weight.size(0) != len(tokenizer): base_model.resize_token_embeddings(len(tokenizer)) print(f"Extended vocabulary size to {len(tokenizer)}") first_weight = base_model.model.layers[0].self_attn.q_proj.weight first_weight_old = first_weight.clone() if hasattr(peft.LoraModel, 'merge_and_unload'): lora_model = PeftModel.from_pretrained( base_model, lora_model_path, device_map={"": "cpu"}, torch_dtype=torch.float16, ) assert torch.allclose(first_weight_old, first_weight) print(f"Merging with merge_and_unload...") base_model = lora_model.merge_and_unload() else: base_model_sd = base_model.state_dict() try: lora_model_sd = torch.load(os.path.join(lora_model_path, 'adapter_model.bin'), map_location='cpu') except FileNotFoundError: print("Cannot find lora model on the disk. Downloading lora model from hub...") filename = hf_hub_download(repo_id=lora_model_path, filename='adapter_model.bin') lora_model_sd = torch.load(filename, map_location='cpu') lora_config = peft.LoraConfig.from_pretrained(lora_model_path) lora_scaling = lora_config.lora_alpha / lora_config.r fan_in_fan_out = lora_config.fan_in_fan_out lora_keys = [k for k in lora_model_sd if 'lora_A' in k] non_lora_keys = [k for k in lora_model_sd if not 'lora_' in k] for k in non_lora_keys: print(f"merging {k}") original_k = k.replace('base_model.model.', '') base_model_sd[original_k].copy_(lora_model_sd[k]) for k in lora_keys: print(f"merging {k}") original_key = k.replace('.lora_A', '').replace('base_model.model.', '') assert original_key in base_model_sd lora_a_key = k lora_b_key = k.replace('lora_A', 'lora_B') base_model_sd[original_key] += ( transpose(lora_model_sd[lora_b_key].float() @ lora_model_sd[lora_a_key].float(), fan_in_fan_out) * lora_scaling ) assert base_model_sd[original_key].dtype == torch.float16 # did we do anything? assert not torch.allclose(first_weight_old, first_weight) tokenizer.save_pretrained(output_dir) if output_type == 'huggingface': print("Saving to Hugging Face format...") LlamaForCausalLM.save_pretrained(base_model, output_dir) # , state_dict=deloreanized_sd) else: # output_type=='pth print("Saving to pth format...") base_model_sd = base_model.state_dict() del lora_model, base_model, lora_model_sd params = params_of_models[model_size] num_shards = num_shards_of_models[model_size] n_layers = params["n_layers"] n_heads = params["n_heads"] dim = params["dim"] dims_per_head = dim // n_heads base = 10000.0 inv_freq = 1.0 / (base ** (torch.arange(0, dims_per_head, 2).float() / dims_per_head)) save_shards(model_sd=base_model_sd, num_shards=num_shards) ================================================ FILE: llm-train/chinese-llama-alpaca/merge_tokenizers.py ================================================ import os os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"]="python" from transformers import LlamaTokenizer from sentencepiece import sentencepiece_model_pb2 as sp_pb2_model import sentencepiece as spm import argparse parser = argparse.ArgumentParser() parser.add_argument('--llama_tokenizer_dir', default=None, type=str, required=True) parser.add_argument('--chinese_sp_model_file', default='./chinese_sp.model', type=str) args = parser.parse_args() llama_tokenizer_dir = args.llama_tokenizer_dir chinese_sp_model_file = args.chinese_sp_model_file # load llama_tokenizer = LlamaTokenizer.from_pretrained(llama_tokenizer_dir) chinese_sp_model = spm.SentencePieceProcessor() chinese_sp_model.Load(chinese_sp_model_file) llama_spm = sp_pb2_model.ModelProto() llama_spm.ParseFromString(llama_tokenizer.sp_model.serialized_model_proto()) chinese_spm = sp_pb2_model.ModelProto() chinese_spm.ParseFromString(chinese_sp_model.serialized_model_proto()) # print number of tokens print(len(llama_tokenizer),len(chinese_sp_model)) print(llama_tokenizer.all_special_tokens) print(llama_tokenizer.all_special_ids) print(llama_tokenizer.special_tokens_map) ## Add Chinese tokens to LLaMA tokenizer llama_spm_tokens_set=set(p.piece for p in llama_spm.pieces) print(len(llama_spm_tokens_set)) print(f"Before:{len(llama_spm_tokens_set)}") for p in chinese_spm.pieces: piece = p.piece if piece not in llama_spm_tokens_set: new_p = sp_pb2_model.ModelProto().SentencePiece() new_p.piece = piece new_p.score = 0 llama_spm.pieces.append(new_p) print(f"New model pieces: {len(llama_spm.pieces)}") ## Save output_sp_dir = 'merged_tokenizer_sp' output_hf_dir = 'merged_tokenizer_hf' # the path to save Chinese-LLaMA tokenizer os.makedirs(output_sp_dir,exist_ok=True) with open(output_sp_dir+'/chinese_llama.model', 'wb') as f: f.write(llama_spm.SerializeToString()) tokenizer = LlamaTokenizer(vocab_file=output_sp_dir+'/chinese_llama.model') tokenizer.save_pretrained(output_hf_dir) print(f"Chinese-LLaMA tokenizer has been saved to {output_hf_dir}") # Test llama_tokenizer = LlamaTokenizer.from_pretrained(llama_tokenizer_dir) chinese_llama_tokenizer = LlamaTokenizer.from_pretrained(output_hf_dir) print(tokenizer.all_special_tokens) print(tokenizer.all_special_ids) print(tokenizer.special_tokens_map) text='''白日依山尽,黄河入海流。欲穷千里目,更上一层楼。 The primary use of LLaMA is research on large language models, including''' print("Test text:\n",text) print print(f"Tokenized by LLaMA tokenizer:{llama_tokenizer.tokenize(text)}") print(f"Tokenized by Chinese-LLaMA tokenizer:{chinese_llama_tokenizer.tokenize(text)}") ================================================ FILE: llm-train/chinese-llama-alpaca/run_clm_pt_with_peft.py ================================================ #!/usr/bin/env python # coding=utf-8 # Copyright 2020 The HuggingFace Inc. team. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Fine-tuning the library models for causal language modeling (GPT, GPT-2, CTRL, ...) on a text file or a dataset. Here is the full list of checkpoints on the hub that can be fine-tuned by this script: https://huggingface.co/models?filter=text-generation """ # You can also adapt this script on your own causal language modeling task. Pointers for this are left as comments. import logging import numpy as np import math import os import sys from dataclasses import dataclass, field from itertools import chain from typing import Optional, List, Dict, Any, Mapping from pathlib import Path import datasets import torch from datasets import load_dataset, concatenate_datasets import transformers from transformers import ( CONFIG_MAPPING, MODEL_FOR_CAUSAL_LM_MAPPING, AutoConfig, AutoModelForCausalLM, LlamaForCausalLM, LlamaTokenizer, AutoTokenizer, HfArgumentParser, Trainer, TrainingArguments, default_data_collator, is_torch_tpu_available, set_seed, ) from transformers.testing_utils import CaptureLogger from transformers.trainer_utils import get_last_checkpoint from transformers.utils import check_min_version, send_example_telemetry from transformers.utils.versions import require_version from sklearn.metrics import accuracy_score from peft import LoraConfig, TaskType, get_peft_model, PeftModel, get_peft_model_state_dict def accuracy(predictions, references, normalize=True, sample_weight=None): return { "accuracy": float( accuracy_score(references, predictions, normalize=normalize, sample_weight=sample_weight) ) } def compute_metrics(eval_preds): preds, labels = eval_preds # preds have the same shape as the labels, after the argmax(-1) has been calculated # by preprocess_logits_for_metrics but we need to shift the labels labels = labels[:, 1:].reshape(-1) preds = preds[:, :-1].reshape(-1) return accuracy(predictions=preds, references=labels) def preprocess_logits_for_metrics(logits, labels): if isinstance(logits, tuple): # Depending on the model and config, logits may contain extra tensors, # like past_key_values, but logits always come first logits = logits[0] return logits.argmax(dim=-1) def fault_tolerance_data_collator(features: List) -> Dict[str, Any]: import torch if not isinstance(features[0], Mapping): features = [vars(f) for f in features] first = features[0] batch = {} # Special handling for labels. # Ensure that tensor is created with the correct type # (it should be automatically the case, but let's make sure of it.) if "label" in first and first["label"] is not None: label = first["label"].item() if isinstance(first["label"], torch.Tensor) else first["label"] dtype = torch.long if isinstance(label, int) else torch.float batch["labels"] = torch.tensor([f["label"] for f in features], dtype=dtype) elif "label_ids" in first and first["label_ids"] is not None: if isinstance(first["label_ids"], torch.Tensor): batch["labels"] = torch.stack([f["label_ids"] for f in features]) else: dtype = torch.long if type(first["label_ids"][0]) is int else torch.float batch["labels"] = torch.tensor([f["label_ids"] for f in features], dtype=dtype) # Handling of all other possible keys. # Again, we will use the first element to figure out which key/values are not None for this model. try: for k, v in first.items(): if k not in ("label", "label_ids") and v is not None and not isinstance(v, str): if isinstance(v, torch.Tensor): batch[k] = torch.stack([f[k] for f in features]) elif isinstance(v, np.ndarray): batch[k] = torch.tensor(np.stack([f[k] for f in features])) else: batch[k] = torch.tensor([f[k] for f in features]) except ValueError: # quick fix by simply take the first example for k, v in first.items(): if k not in ("label", "label_ids") and v is not None and not isinstance(v, str): if isinstance(v, torch.Tensor): batch[k] = torch.stack([features[0][k]] * len(features)) elif isinstance(v, np.ndarray): batch[k] = torch.tensor(np.stack([features[0][k]] * len(features))) else: batch[k] = torch.tensor([features[0][k]] * len(features)) return batch class GroupTextsBuilder: def __init__(self,max_seq_length): self.max_seq_length = max_seq_length def __call__(self, examples): # Concatenate all texts. firsts = {k:examples[k][0][0] for k in examples.keys()} lasts = {k:examples[k][0][-1] for k in examples.keys()} contents = {k:sum([vi[1:-1] for vi in v],[]) for k,v in examples.items()} total_length = len(contents[list(examples.keys())[0]]) content_length = self.max_seq_length - 2 if total_length >= content_length: total_length = (total_length // content_length ) * content_length # Split by chunks of max_len. result = { k: [ [firsts[k]] + t[i : i + content_length] + [lasts[k]] for i in range(0, total_length, content_length)] for k, t in contents.items()} return result MODEL_CONFIG_CLASSES = list(MODEL_FOR_CAUSAL_LM_MAPPING.keys()) MODEL_TYPES = tuple(conf.model_type for conf in MODEL_CONFIG_CLASSES) @dataclass class ModelArguments: """ Arguments pertaining to which model/config/tokenizer we are going to fine-tune, or train from scratch. """ model_name_or_path: Optional[str] = field( default=None, metadata={ "help": ( "The model checkpoint for weights initialization.Don't set if you want to train a model from scratch." ) }, ) tokenizer_name_or_path: Optional[str] = field( default=None, metadata={ "help": ( "The tokenizer for weights initialization.Don't set if you want to train a model from scratch." ) }, ) model_type: Optional[str] = field( default=None, metadata={"help": "If training from scratch, pass a model type from the list: " + ", ".join(MODEL_TYPES)}, ) config_overrides: Optional[str] = field( default=None, metadata={ "help": ( "Override some existing default config settings when a model is trained from scratch. Example: " "n_embd=10,resid_pdrop=0.2,scale_attn_weights=false,summary_type=cls_index" ) }, ) config_name: Optional[str] = field( default=None, metadata={"help": "Pretrained config name or path if not the same as model_name"} ) tokenizer_name: Optional[str] = field( default=None, metadata={"help": "Pretrained tokenizer name or path if not the same as model_name"} ) cache_dir: Optional[str] = field( default=None, metadata={"help": "Where do you want to store the pretrained models downloaded from huggingface.co"}, ) use_fast_tokenizer: bool = field( default=True, metadata={"help": "Whether to use one of the fast tokenizer (backed by the tokenizers library) or not."}, ) model_revision: str = field( default="main", metadata={"help": "The specific model version to use (can be a branch name, tag name or commit id)."}, ) use_auth_token: bool = field( default=False, metadata={ "help": ( "Will use the token generated when running `huggingface-cli login` (necessary to use this script " "with private models)." ) }, ) torch_dtype: Optional[str] = field( default=None, metadata={ "help": ( "Override the default `torch.dtype` and load the model under this dtype. If `auto` is passed, the " "dtype will be automatically derived from the model's weights." ), "choices": ["auto", "bfloat16", "float16", "float32"], }, ) def __post_init__(self): if self.config_overrides is not None and (self.config_name is not None or self.model_name_or_path is not None): raise ValueError( "--config_overrides can't be used in combination with --config_name or --model_name_or_path" ) @dataclass class DataTrainingArguments: """ Arguments pertaining to what data we are going to input our model for training and eval. """ dataset_dir: Optional[str] = field( default=None, metadata={"help": "The name of the dataset to use (via the datasets library)."} ) dataset_config_name: Optional[str] = field( default=None, metadata={"help": "The configuration name of the dataset to use (via the datasets library)."} ) train_file: Optional[str] = field(default=None, metadata={"help": "The input training data file (a text file)."}) validation_file: Optional[str] = field( default=None, metadata={"help": "An optional input evaluation data file to evaluate the perplexity on (a text file)."}, ) max_train_samples: Optional[int] = field( default=None, metadata={ "help": ( "For debugging purposes or quicker training, truncate the number of training examples to this " "value if set." ) }, ) max_eval_samples: Optional[int] = field( default=None, metadata={ "help": ( "For debugging purposes or quicker training, truncate the number of evaluation examples to this " "value if set." ) }, ) streaming: bool = field(default=False, metadata={"help": "Enable streaming mode"}) block_size: Optional[int] = field( default=None, metadata={ "help": ( "Optional input sequence length after tokenization. " "The training dataset will be truncated in block of this size for training. " "Default to the model max input length for single sentence inputs (take into account special tokens)." ) }, ) overwrite_cache: bool = field( default=False, metadata={"help": "Overwrite the cached training and evaluation sets"} ) validation_split_percentage: Optional[float] = field( default=0.05, metadata={ "help": "The percentage of the train set used as validation set in case there's no validation split" }, ) preprocessing_num_workers: Optional[int] = field( default=None, metadata={"help": "The number of processes to use for the preprocessing."}, ) keep_linebreaks: bool = field( default=True, metadata={"help": "Whether to keep line breaks when using TXT files or not."} ) data_cache_dir: Optional[str] = field(default="./", metadata={"help": "The datasets processed stored"}) def __post_init__(self): if self.streaming: require_version("datasets>=2.0.0", "The streaming feature requires `datasets>=2.0.0`") @dataclass class MyTrainingArguments(TrainingArguments): trainable : Optional[str] = field(default="q_proj,v_proj") lora_rank : Optional[int] = field(default=8) lora_dropout : Optional[float] = field(default=0.1) lora_alpha : Optional[float] = field(default=32.) modules_to_save : Optional[str] = field(default=None) debug_mode : Optional[bool] = field(default=False) peft_path : Optional[str] = field(default=None) logger = logging.getLogger(__name__) def main(): parser = HfArgumentParser((ModelArguments, DataTrainingArguments, MyTrainingArguments)) if len(sys.argv) == 2 and sys.argv[1].endswith(".json"): # If we pass only one argument to the script and it's the path to a json file, # let's parse it to get our arguments. model_args, data_args, training_args = parser.parse_json_file(json_file=os.path.abspath(sys.argv[1])) else: model_args, data_args, training_args = parser.parse_args_into_dataclasses() # Sending telemetry. Tracking the example usage helps us better allocate resources to maintain them. The # information sent is the one passed as arguments along with your Python/PyTorch versions. send_example_telemetry("run_clm", model_args, data_args) # Setup logging logging.basicConfig(format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",datefmt="%m/%d/%Y %H:%M:%S", level=logging.INFO, # if training_args.local_rank in [-1, 0] else logging.WARN, handlers=[logging.StreamHandler(sys.stdout)],) if training_args.should_log: # The default of training_args.log_level is passive, so we set log level at info here to have that default. transformers.utils.logging.set_verbosity_info() log_level = training_args.get_process_log_level() logger.setLevel(log_level) datasets.utils.logging.set_verbosity(log_level) transformers.utils.logging.set_verbosity(log_level) transformers.utils.logging.enable_default_handler() transformers.utils.logging.enable_explicit_format() # transformers.tokenization_utils.logging.set_verbosity_warning() # Log on each process the small summary: logger.warning( f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}" + f"distributed training: {bool(training_args.local_rank != -1)}, 16-bits training: {training_args.fp16}" ) # Detecting last checkpoint. last_checkpoint = None if os.path.isdir(training_args.output_dir) and training_args.do_train and not training_args.overwrite_output_dir: last_checkpoint = get_last_checkpoint(training_args.output_dir) if last_checkpoint is None and len(os.listdir(training_args.output_dir)) > 0: raise ValueError( f"Output directory ({training_args.output_dir}) already exists and is not empty. " "Use --overwrite_output_dir to overcome." ) elif last_checkpoint is not None and training_args.resume_from_checkpoint is None: logger.info( f"Checkpoint detected, resuming training at {last_checkpoint}. To avoid this behavior, change " "the `--output_dir` or add `--overwrite_output_dir` to train from scratch." ) # Set seed before initializing model. set_seed(training_args.seed) config_kwargs = { "cache_dir": model_args.cache_dir, "revision": model_args.model_revision, "use_auth_token": True if model_args.use_auth_token else None, } if model_args.config_name: config = AutoConfig.from_pretrained(model_args.config_name, **config_kwargs) elif model_args.model_name_or_path: config = AutoConfig.from_pretrained(model_args.model_name_or_path, **config_kwargs) else: config = CONFIG_MAPPING[model_args.model_type]() logger.warning("You are instantiating a new config instance from scratch.") if model_args.config_overrides is not None: logger.info(f"Overriding config: {model_args.config_overrides}") config.update_from_string(model_args.config_overrides) logger.info(f"New config: {config}") tokenizer_kwargs = { "cache_dir": model_args.cache_dir, "use_fast": model_args.use_fast_tokenizer, "revision": model_args.model_revision, "use_auth_token": True if model_args.use_auth_token else None, } if model_args.tokenizer_name: tokenizer = AutoTokenizer.from_pretrained(model_args.tokenizer_name, **tokenizer_kwargs) elif model_args.tokenizer_name_or_path: tokenizer = LlamaTokenizer.from_pretrained(model_args.tokenizer_name_or_path, **tokenizer_kwargs) else: raise ValueError( "You are instantiating a new tokenizer from scratch. This is not supported by this script." "You can do it from another script, save it, and load it from here, using --tokenizer_name." ) # Preprocessing the datasets. # First we tokenize all the texts. # since this will be pickled to avoid _LazyModule error in Hasher force logger loading before tokenize_function tok_logger = transformers.utils.logging.get_logger("transformers.tokenization_utils_base") def tokenize_function(examples): with CaptureLogger(tok_logger) as cl: output = tokenizer(examples["text"]) # clm input could be much much longer than block_size if "Token indices sequence length is longer than the" in cl.out: tok_logger.warning( "^^^^^^^^^^^^^^^^ Please ignore the warning above - this long input will be chunked into smaller bits" " before being passed to the model." ) return output if data_args.block_size is None: block_size = tokenizer.model_max_length if block_size > 1024: logger.warning( "The chosen tokenizer supports a `model_max_length` that is longer than the default `block_size` value" " of 1024. If you would like to use a longer `block_size` up to `tokenizer.model_max_length` you can" " override this default with `--block_size xxx`." ) block_size = 1024 else: if data_args.block_size > tokenizer.model_max_length: logger.warning( f"The block_size passed ({data_args.block_size}) is larger than the maximum length for the model" f"({tokenizer.model_max_length}). Using block_size={tokenizer.model_max_length}." ) block_size = min(data_args.block_size, tokenizer.model_max_length) # Main data processing function that will concatenate all texts from our dataset and generate chunks of block_size. def group_texts(examples): # Concatenate all texts. concatenated_examples = {k: list(chain(*examples[k])) for k in examples.keys()} total_length = len(concatenated_examples[list(examples.keys())[0]]) # We drop the small remainder, we could add padding if the model supported it instead of this drop, you can # customize this part to your needs. if total_length >= block_size: total_length = (total_length // block_size) * block_size # Split by chunks of max_len. result = { k: [t[i : i + block_size] for i in range(0, total_length, block_size)] for k, t in concatenated_examples.items() } result["labels"] = result["input_ids"].copy() return result with training_args.main_process_first(desc="dataset map tokenization and grouping"): lm_datasets = [] path = Path(data_args.dataset_dir) files = [file.name for file in path.glob("*.txt")] if training_args.debug_mode is True: files = [files[0]] for idx, file in enumerate(files): data_file = os.path.join(path, file) filename = file.split(".")[0] cache_path = os.path.join(data_args.data_cache_dir, filename) os.makedirs(cache_path, exist_ok=True) try: processed_dataset = datasets.load_from_disk(cache_path, keep_in_memory=False) logger.info(f'training datasets-{filename} has been loaded from disk') except Exception: cache_dir = os.path.join(data_args.data_cache_dir, filename+"_text") os.makedirs(cache_dir, exist_ok=True) raw_dataset = load_dataset("text", data_files=data_file, cache_dir=cache_dir, keep_in_memory=False) logger.info(f"{file} has been loaded") tokenized_dataset = raw_dataset.map( tokenize_function, batched=True, num_proc=data_args.preprocessing_num_workers, remove_columns="text", load_from_cache_file=True, keep_in_memory=False, cache_file_names = {k: os.path.join(cache_dir, f'tokenized.arrow') for k in raw_dataset}, desc="Running tokenizer on dataset", ) grouped_datasets = tokenized_dataset.map( group_texts, batched=True, num_proc=data_args.preprocessing_num_workers, load_from_cache_file=True, keep_in_memory=False, cache_file_names = {k: os.path.join(cache_dir, f'grouped.arrow') for k in tokenized_dataset}, desc=f"Grouping texts in chunks of {block_size}", ) processed_dataset = grouped_datasets processed_dataset.save_to_disk(cache_path) if idx == 0: lm_datasets = processed_dataset['train'] else: assert lm_datasets.features.type == processed_dataset["train"].features.type lm_datasets = concatenate_datasets([lm_datasets, processed_dataset["train"]]) lm_datasets = lm_datasets.train_test_split(test_size = data_args.validation_split_percentage) if training_args.do_train: train_dataset = lm_datasets['train'] if data_args.max_train_samples is not None: max_train_samples = min(len(train_dataset), data_args.max_train_samples) train_dataset = train_dataset.select(range(max_train_samples)) logger.info(f"Num train_samples {len(train_dataset)}") logger.info("training example:") logger.info(tokenizer.decode(train_dataset[0]['input_ids'])) if training_args.do_eval: eval_dataset = lm_datasets["test"] if data_args.max_eval_samples is not None: max_eval_samples = min(len(eval_dataset), data_args.max_eval_samples) eval_dataset = eval_dataset.select(range(max_eval_samples)) logger.info(f"Num eval_samples {len(eval_dataset)}") logger.info("training example:") logger.info(tokenizer.decode(eval_dataset[0]['input_ids'])) if model_args.model_name_or_path: torch_dtype = ( model_args.torch_dtype if model_args.torch_dtype in ["auto", None] else getattr(torch, model_args.torch_dtype) ) model = LlamaForCausalLM.from_pretrained( model_args.model_name_or_path, from_tf=bool(".ckpt" in model_args.model_name_or_path), config=config, cache_dir=model_args.cache_dir, revision=model_args.model_revision, use_auth_token=True if model_args.use_auth_token else None, torch_dtype=torch_dtype, low_cpu_mem_usage=True ) else: model = AutoModelForCausalLM.from_config(config) n_params = sum({p.data_ptr(): p.numel() for p in model.parameters()}.values()) logger.info(f"Training new model from scratch - Total size={n_params/2**20:.2f}M params") model.resize_token_embeddings(len(tokenizer)) if training_args.peft_path is not None: logger.info("Peft from pre-trained model") model = PeftModel.from_pretrained(model, training_args.peft_path) else: logger.info("Init new peft model") target_modules = training_args.trainable.split(',') modules_to_save = training_args.modules_to_save if modules_to_save is not None: modules_to_save = modules_to_save.split(',') lora_rank = training_args.lora_rank lora_dropout = training_args.lora_dropout lora_alpha = training_args.lora_alpha logger.info(f"target_modules: {target_modules}") logger.info(f"lora_rank: {lora_rank}") peft_config = LoraConfig( task_type=TaskType.CAUSAL_LM, target_modules=target_modules, inference_mode=False, r=lora_rank, lora_alpha=lora_alpha, lora_dropout=lora_dropout, modules_to_save=modules_to_save) model = get_peft_model(model, peft_config) model.print_trainable_parameters() old_state_dict = model.state_dict model.state_dict = ( lambda self, *_, **__: get_peft_model_state_dict(self, old_state_dict()) ).__get__(model, type(model)) # Initialize our Trainer trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset if training_args.do_train else None, eval_dataset=eval_dataset if training_args.do_eval else None, tokenizer=tokenizer, data_collator=fault_tolerance_data_collator, compute_metrics=compute_metrics if training_args.do_eval and not is_torch_tpu_available() else None, preprocess_logits_for_metrics=preprocess_logits_for_metrics if training_args.do_eval and not is_torch_tpu_available() else None, ) # Training if training_args.do_train: checkpoint = None if training_args.resume_from_checkpoint is not None: checkpoint = training_args.resume_from_checkpoint elif last_checkpoint is not None: checkpoint = last_checkpoint train_result = trainer.train(resume_from_checkpoint=checkpoint) trainer.save_model() model.save_pretrained(training_args.output_dir + "/lora") metrics = train_result.metrics max_train_samples = ( data_args.max_train_samples if data_args.max_train_samples is not None else len(train_dataset) ) metrics["train_samples"] = min(max_train_samples, len(train_dataset)) trainer.log_metrics("train", metrics) trainer.save_metrics("train", metrics) trainer.save_state() # Evaluation if training_args.do_eval: logger.info("*** Evaluate ***") metrics = trainer.evaluate() max_eval_samples = data_args.max_eval_samples if data_args.max_eval_samples is not None else len(eval_dataset) metrics["eval_samples"] = min(max_eval_samples, len(eval_dataset)) try: perplexity = math.exp(metrics["eval_loss"]) except OverflowError: perplexity = float("inf") metrics["perplexity"] = perplexity trainer.log_metrics("eval", metrics) trainer.save_metrics("eval", metrics) if __name__ == "__main__": main() ================================================ FILE: llm-train/chinese-llama-alpaca/run_clm_sft_with_peft.py ================================================ #!/usr/bin/env python # coding=utf-8 # Copyright 2020 The HuggingFace Inc. team. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Fine-tuning the library models for causal language modeling (GPT, GPT-2, CTRL, ...) on a text file or a dataset. Here is the full list of checkpoints on the hub that can be fine-tuned by this script: https://huggingface.co/models?filter=text-generation """ # You can also adapt this script on your own causal language modeling task. Pointers for this are left as comments. import logging import numpy as np import math import os import sys from dataclasses import dataclass, field from typing import Optional, List, Dict, Any, Mapping from pathlib import Path import datasets import json import torch from build_dataset import buid_instruction_dataset, DataCollatorForSupervisedDataset import transformers from transformers import ( CONFIG_MAPPING, MODEL_FOR_CAUSAL_LM_MAPPING, AutoConfig, AutoModelForCausalLM, LlamaForCausalLM, LlamaTokenizer, AutoTokenizer, HfArgumentParser, Trainer, TrainingArguments, set_seed, ) from transformers.testing_utils import CaptureLogger from transformers.trainer_utils import get_last_checkpoint from transformers.utils import check_min_version, send_example_telemetry from transformers.utils.versions import require_version from peft import LoraConfig, TaskType, get_peft_model, PeftModel, get_peft_model_state_dict IGNORE_INDEX = -100 DEFAULT_PAD_TOKEN = "[PAD]" DEFAULT_EOS_TOKEN = "" DEFAULT_BOS_TOKEN = "" DEFAULT_UNK_TOKEN = "" # Will error if the minimal version of Transformers is not installed. Remove at your own risks. # check_min_version("4.28.0.dev0") require_version("datasets>=1.8.0", "To fix: pip install -r examples/pytorch/language-modeling/requirements.txt") @dataclass class ModelArguments: """ Arguments pertaining to which model/config/tokenizer we are going to fine-tune, or train from scratch. """ model_name_or_path: Optional[str] = field( default=None, metadata={ "help": ( "The model checkpoint for weights initialization.Don't set if you want to train a model from scratch." ) }, ) tokenizer_name_or_path: Optional[str] = field( default=None, metadata={ "help": ( "The tokenizer for weights initialization.Don't set if you want to train a model from scratch." ) }, ) config_overrides: Optional[str] = field( default=None, metadata={ "help": ( "Override some existing default config settings when a model is trained from scratch. Example: " "n_embd=10,resid_pdrop=0.2,scale_attn_weights=false,summary_type=cls_index" ) }, ) config_name: Optional[str] = field( default=None, metadata={"help": "Pretrained config name or path if not the same as model_name"} ) tokenizer_name: Optional[str] = field( default=None, metadata={"help": "Pretrained tokenizer name or path if not the same as model_name"} ) cache_dir: Optional[str] = field( default=None, metadata={"help": "Where do you want to store the pretrained models downloaded from huggingface.co"}, ) use_fast_tokenizer: bool = field( default=True, metadata={"help": "Whether to use one of the fast tokenizer (backed by the tokenizers library) or not."}, ) model_revision: str = field( default="main", metadata={"help": "The specific model version to use (can be a branch name, tag name or commit id)."}, ) use_auth_token: bool = field( default=False, metadata={ "help": ( "Will use the token generated when running `huggingface-cli login` (necessary to use this script " "with private models)." ) }, ) torch_dtype: Optional[str] = field( default=None, metadata={ "help": ( "Override the default `torch.dtype` and load the model under this dtype. If `auto` is passed, the " "dtype will be automatically derived from the model's weights." ), "choices": ["auto", "bfloat16", "float16", "float32"], }, ) def __post_init__(self): if self.config_overrides is not None and (self.config_name is not None or self.model_name_or_path is not None): raise ValueError( "--config_overrides can't be used in combination with --config_name or --model_name_or_path" ) @dataclass class DataTrainingArguments: """ Arguments pertaining to what data we are going to input our model for training and eval. """ dataset_dir: Optional[str] = field( default=None, metadata={"help": "The name of the dataset to use (via the datasets library)."} ) train_file: Optional[str] = field(default=None, metadata={"help": "The input training data file (a text file)."}) validation_file: Optional[str] = field( default=None, metadata={"help": "An optional input evaluation data file to evaluate the perplexity on (a text file)."}, ) overwrite_cache: bool = field( default=False, metadata={"help": "Overwrite the cached training and evaluation sets"} ) validation_split_percentage: Optional[float] = field( default=0.05, metadata={ "help": "The percentage of the train set used as validation set in case there's no validation split" }, ) preprocessing_num_workers: Optional[int] = field( default=None, metadata={"help": "The number of processes to use for the preprocessing."}, ) keep_linebreaks: bool = field( default=True, metadata={"help": "Whether to keep line breaks when using TXT files or not."} ) data_cache_dir: Optional[str] = field(default=None, metadata={"help": "The datasets processed stored"}) max_seq_length: Optional[int] = field(default=512) @dataclass class MyTrainingArguments(TrainingArguments): trainable : Optional[str] = field(default="q_proj,v_proj") lora_rank : Optional[int] = field(default=8) lora_dropout : Optional[float] = field(default=0.1) lora_alpha : Optional[float] = field(default=32.) modules_to_save : Optional[str] = field(default=None) peft_path : Optional[str] = field(default=None) force_resize_embeddings: bool = field(default=False) logger = logging.getLogger(__name__) def main(): parser = HfArgumentParser((ModelArguments, DataTrainingArguments, MyTrainingArguments)) if len(sys.argv) == 2 and sys.argv[1].endswith(".json"): # If we pass only one argument to the script and it's the path to a json file, # let's parse it to get our arguments. model_args, data_args, training_args = parser.parse_json_file(json_file=os.path.abspath(sys.argv[1])) else: model_args, data_args, training_args = parser.parse_args_into_dataclasses() send_example_telemetry("run_clm", model_args, data_args) # Setup logging logging.basicConfig(format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",datefmt="%m/%d/%Y %H:%M:%S", level=logging.INFO, # if training_args.local_rank in [-1, 0] else logging.WARN, handlers=[logging.StreamHandler(sys.stdout)],) if training_args.should_log: # The default of training_args.log_level is passive, so we set log level at info here to have that default. transformers.utils.logging.set_verbosity_info() log_level = training_args.get_process_log_level() logger.setLevel(log_level) datasets.utils.logging.set_verbosity(log_level) transformers.utils.logging.set_verbosity(log_level) transformers.utils.logging.enable_default_handler() transformers.utils.logging.enable_explicit_format() # transformers.tokenization_utils.logging.set_verbosity_warning() # Log on each process the small summary: logger.warning( f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}" + f"distributed training: {bool(training_args.local_rank != -1)}, 16-bits training: {training_args.fp16}" ) # Detecting last checkpoint. last_checkpoint = None if os.path.isdir(training_args.output_dir) and training_args.do_train and not training_args.overwrite_output_dir: last_checkpoint = get_last_checkpoint(training_args.output_dir) if last_checkpoint is None and len(os.listdir(training_args.output_dir)) > 0: raise ValueError( f"Output directory ({training_args.output_dir}) already exists and is not empty. " "Use --overwrite_output_dir to overcome." ) elif last_checkpoint is not None and training_args.resume_from_checkpoint is None: logger.info( f"Checkpoint detected, resuming training at {last_checkpoint}. To avoid this behavior, change " "the `--output_dir` or add `--overwrite_output_dir` to train from scratch." ) # Set seed before initializing model. set_seed(training_args.seed) config_kwargs = { "cache_dir": model_args.cache_dir, "revision": model_args.model_revision, "use_auth_token": True if model_args.use_auth_token else None, } if model_args.config_name: config = AutoConfig.from_pretrained(model_args.config_name, **config_kwargs) elif model_args.model_name_or_path: config = AutoConfig.from_pretrained(model_args.model_name_or_path, **config_kwargs) else: config = CONFIG_MAPPING[model_args.model_type]() logger.warning("You are instantiating a new config instance from scratch.") if model_args.config_overrides is not None: logger.info(f"Overriding config: {model_args.config_overrides}") config.update_from_string(model_args.config_overrides) logger.info(f"New config: {config}") tokenizer_kwargs = { "cache_dir": model_args.cache_dir, "use_fast": model_args.use_fast_tokenizer, "revision": model_args.model_revision, "use_auth_token": True if model_args.use_auth_token else None, } if model_args.tokenizer_name: tokenizer = AutoTokenizer.from_pretrained(model_args.tokenizer_name, **tokenizer_kwargs) elif model_args.tokenizer_name_or_path: tokenizer = LlamaTokenizer.from_pretrained(model_args.tokenizer_name_or_path, **tokenizer_kwargs) else: raise ValueError( "You are instantiating a new tokenizer from scratch. This is not supported by this script." "You can do it from another script, save it, and load it from here, using --tokenizer_name." ) if tokenizer.pad_token is None: num_new_tokens = smart_tokenizer_and_embedding_resize( special_tokens_dict=dict(pad_token=DEFAULT_PAD_TOKEN), tokenizer=tokenizer, model=None,) data_collator = DataCollatorForSupervisedDataset(tokenizer=tokenizer) eval_dataset=None train_dataset = None if training_args.do_train: with training_args.main_process_first(desc="loading and tokenization"): path = Path(data_args.dataset_dir) files = [os.path.join(path,file.name) for file in path.glob("*.json")] logger.info(f"training files: {' '.join(files)}") train_dataset = buid_instruction_dataset( data_path=files, tokenizer=tokenizer, max_seq_length=data_args.max_seq_length, data_cache_dir = None, preprocessing_num_workers = data_args.preprocessing_num_workers) logger.info(f"Num train_samples {len(train_dataset)}") logger.info("training example:") logger.info(tokenizer.decode(train_dataset[0]['input_ids'])) if training_args.do_eval: with training_args.main_process_first(desc="loading and tokenization"): files = [data_args.validation_file] logger.info(f"training files: {' '.join(files)}") eval_dataset = buid_instruction_dataset( data_path=files, tokenizer=tokenizer, max_seq_length=data_args.max_seq_length, data_cache_dir = None, preprocessing_num_workers = data_args.preprocessing_num_workers) logger.info(f"Num eval_samples {len(eval_dataset)}") logger.info("eval example:") logger.info(tokenizer.decode(eval_dataset[0]['input_ids'])) if model_args.model_name_or_path: torch_dtype = ( model_args.torch_dtype if model_args.torch_dtype in ["auto", None] else getattr(torch, model_args.torch_dtype) ) model = LlamaForCausalLM.from_pretrained( model_args.model_name_or_path, from_tf=bool(".ckpt" in model_args.model_name_or_path), config=config, cache_dir=model_args.cache_dir, revision=model_args.model_revision, use_auth_token=True if model_args.use_auth_token else None, torch_dtype=torch_dtype, low_cpu_mem_usage=True ) else: model = AutoModelForCausalLM.from_config(config) n_params = sum({p.data_ptr(): p.numel() for p in model.parameters()}.values()) logger.info(f"Training new model from scratch - Total size={n_params/2**20:.2f}M params") logger.info(f"len(tokenizer):{len(tokenizer)}") embedding_size = model.get_input_embeddings().weight.shape[0] if len(tokenizer) != embedding_size: logger.info("resize the embedding size by the size of the tokenizer") model.resize_token_embeddings(len(tokenizer)) if training_args.peft_path is not None: logger.info("Peft from pre-trained model") model = PeftModel.from_pretrained(model, training_args.peft_path) else: logger.info("Init new peft model") target_modules = training_args.trainable.split(',') modules_to_save = training_args.modules_to_save if modules_to_save is not None: modules_to_save = modules_to_save.split(',') lora_rank = training_args.lora_rank lora_dropout = training_args.lora_dropout lora_alpha = training_args.lora_alpha logger.info(f"target_modules: {target_modules}") logger.info(f"lora_rank: {lora_rank}") peft_config = LoraConfig( task_type=TaskType.CAUSAL_LM, target_modules=target_modules, inference_mode=False, r=lora_rank, lora_alpha=lora_alpha, lora_dropout=lora_dropout, modules_to_save=modules_to_save) model = get_peft_model(model, peft_config) #model.base_model.tie_weights() model.print_trainable_parameters() logger.info(f"model.modules_to_save: {model.modules_to_save}") old_state_dict = model.state_dict model.state_dict = ( lambda self, *_, **__: get_peft_model_state_dict(self, old_state_dict()) ).__get__(model, type(model)) # Initialize our Trainer trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset, tokenizer=tokenizer, data_collator=data_collator, ) # Training if training_args.do_train: checkpoint = None if training_args.resume_from_checkpoint is not None: checkpoint = training_args.resume_from_checkpoint elif last_checkpoint is not None: checkpoint = last_checkpoint train_result = trainer.train(resume_from_checkpoint=checkpoint) trainer.save_model() # Saves the tokenizer too for easy upload model.save_pretrained(training_args.output_dir + "/lora") metrics = train_result.metrics metrics["train_samples"] = len(train_dataset) trainer.log_metrics("train", metrics) trainer.save_metrics("train", metrics) trainer.save_state() # Evaluation if training_args.do_eval: logger.info("*** Evaluate ***") metrics = trainer.evaluate() metrics["eval_samples"] =len(eval_dataset) try: perplexity = math.exp(metrics["eval_loss"]) except OverflowError: perplexity = float("inf") metrics["perplexity"] = perplexity trainer.log_metrics("eval", metrics) trainer.save_metrics("eval", metrics) def smart_tokenizer_and_embedding_resize( special_tokens_dict: Dict, tokenizer: transformers.PreTrainedTokenizer, model: transformers.PreTrainedModel, ): """Resize tokenizer and embedding. Note: This is the unoptimized version that may make your embedding size not be divisible by 64. """ num_new_tokens = tokenizer.add_special_tokens(special_tokens_dict) if model is not None: model.resize_token_embeddings(len(tokenizer)) if num_new_tokens > 0: input_embeddings = model.get_input_embeddings().weight.data output_embeddings = model.get_output_embeddings().weight.data input_embeddings_avg = input_embeddings[:-num_new_tokens].mean(dim=0, keepdim=True) output_embeddings_avg = output_embeddings[:-num_new_tokens].mean(dim=0, keepdim=True) input_embeddings[-num_new_tokens:] = input_embeddings_avg output_embeddings[-num_new_tokens:] = output_embeddings_avg return num_new_tokens if __name__ == "__main__": main() ================================================ FILE: llm-train/chinese-llama-alpaca/run_pt.sh ================================================ lr=2e-4 lora_rank=8 lora_alpha=32 lora_trainable="q_proj,v_proj,k_proj,o_proj,gate_proj,down_proj,up_proj" modules_to_save="embed_tokens,lm_head" lora_dropout=0.05 pretrained_model=/workspace/model/llama-7b-hf chinese_tokenizer_path=/workspace/code/Chinese-LLaMA-Alpaca/scripts/merged_tokenizer_hf dataset_dir=/workspace/data/book data_cache=/workspace/cache/book per_device_train_batch_size=1 per_device_eval_batch_size=1 training_steps=100 gradient_accumulation_steps=1 output_dir=/workspace/output/book RANDOM=100 deepspeed_config_file=ds_zero2_no_offload.json CUDA_VISIBLE_DEVICES=0 torchrun --nnodes 1 --nproc_per_node 1 run_clm_pt_with_peft.py \ --deepspeed ${deepspeed_config_file} \ --model_name_or_path ${pretrained_model} \ --tokenizer_name_or_path ${chinese_tokenizer_path} \ --dataset_dir ${dataset_dir} \ --data_cache_dir ${data_cache} \ --validation_split_percentage 0.001 \ --per_device_train_batch_size ${per_device_train_batch_size} \ --per_device_eval_batch_size ${per_device_eval_batch_size} \ --do_train \ --seed $RANDOM \ --fp16 \ --max_steps ${training_steps} \ --lr_scheduler_type cosine \ --learning_rate ${lr} \ --warmup_ratio 0.05 \ --weight_decay 0.01 \ --logging_strategy steps \ --logging_steps 10 \ --save_strategy steps \ --save_total_limit 3 \ --save_steps 500 \ --gradient_accumulation_steps ${gradient_accumulation_steps} \ --preprocessing_num_workers 8 \ --block_size 512 \ --output_dir ${output_dir} \ --overwrite_output_dir \ --ddp_timeout 30000 \ --logging_first_step True \ --lora_rank ${lora_rank} \ --lora_alpha ${lora_alpha} \ --trainable ${lora_trainable} \ --modules_to_save ${modules_to_save} \ --lora_dropout ${lora_dropout} \ --torch_dtype float16 \ --gradient_checkpointing \ --ddp_find_unused_parameters False ================================================ FILE: llm-train/chinese-llama-alpaca/run_sft.sh ================================================ lr=1e-4 lora_rank=8 lora_alpha=32 lora_trainable="q_proj,v_proj,k_proj,o_proj,gate_proj,down_proj,up_proj" modules_to_save="embed_tokens,lm_head" lora_dropout=0.05 pretrained_model=/workspace/output/book-merge-hf chinese_tokenizer_path=/workspace/code/Chinese-LLaMA-Alpaca/scripts/merged_tokenizer_hf dataset_dir=/workspace/code/Chinese-LLaMA-Alpaca/data per_device_train_batch_size=1 per_device_eval_batch_size=1 training_steps=100 gradient_accumulation_steps=1 output_dir=/workspace/output/llama-book-alpace-zh #peft_model=path/to/peft/model/dir validation_file=/workspace/data/alpaca_valid.json RANDOM=1000 deepspeed_config_file=ds_zero2_no_offload.json CUDA_VISIBLE_DEVICES=0 torchrun --nnodes 1 --nproc_per_node 1 run_clm_sft_with_peft.py \ --deepspeed ${deepspeed_config_file} \ --model_name_or_path ${pretrained_model} \ --tokenizer_name_or_path ${chinese_tokenizer_path} \ --dataset_dir ${dataset_dir} \ --validation_split_percentage 0.001 \ --per_device_train_batch_size ${per_device_train_batch_size} \ --per_device_eval_batch_size ${per_device_eval_batch_size} \ --do_train \ --do_eval \ --seed $RANDOM \ --fp16 \ --max_steps ${training_steps} \ --lr_scheduler_type cosine \ --learning_rate ${lr} \ --warmup_ratio 0.03 \ --weight_decay 0 \ --logging_strategy steps \ --logging_steps 10 \ --save_strategy steps \ --save_total_limit 3 \ --evaluation_strategy steps \ --eval_steps 250 \ --save_steps 500 \ --gradient_accumulation_steps ${gradient_accumulation_steps} \ --preprocessing_num_workers 8 \ --max_seq_length 512 \ --output_dir ${output_dir} \ --overwrite_output_dir \ --ddp_timeout 30000 \ --logging_first_step True \ --lora_rank ${lora_rank} \ --lora_alpha ${lora_alpha} \ --trainable ${lora_trainable} \ --modules_to_save ${modules_to_save} \ --lora_dropout ${lora_dropout} \ --torch_dtype float16 \ --validation_file ${validation_file} \ --gradient_checkpointing \ --ddp_find_unused_parameters False ================================================ FILE: llm-train/deepspeedchat/README.md ================================================ ``` > ls -al --block-size=K /tmp/data_files/ total 6533712K drwxrwxr-x 2 guodong.li guodong.li 4K Jul 6 16:02 . drwxrwxrwt. 328 root root 24K Jul 7 10:00 .. -rw-rw-r-- 1 guodong.li guodong.li 10K Jul 6 10:26 Dahoas_full_hh_rlhf_seed1234_eval_2,4,4_0.npy -rw-rw-r-- 1 guodong.li guodong.li 20K Jul 6 10:26 Dahoas_full_hh_rlhf_seed1234_eval_2,4,4_1.npy -rw-rw-r-- 1 guodong.li guodong.li 20K Jul 6 10:26 Dahoas_full_hh_rlhf_seed1234_eval_2,4,4_2.npy -rw-rw-r-- 1 guodong.li guodong.li 88K Jul 6 10:25 Dahoas_full_hh_rlhf_seed1234_train_2,4,4_0.npy -rw-rw-r-- 1 guodong.li guodong.li 176K Jul 6 10:25 Dahoas_full_hh_rlhf_seed1234_train_2,4,4_1.npy -rw-rw-r-- 1 guodong.li guodong.li 176K Jul 6 10:25 Dahoas_full_hh_rlhf_seed1234_train_2,4,4_2.npy -rw-rw-r-- 1 guodong.li guodong.li 5K Jul 6 10:24 Dahoas_rm_static_seed1234_eval_2,4,4_0.npy -rw-rw-r-- 1 guodong.li guodong.li 9K Jul 6 10:24 Dahoas_rm_static_seed1234_eval_2,4,4_1.npy -rw-rw-r-- 1 guodong.li guodong.li 9K Jul 6 10:24 Dahoas_rm_static_seed1234_eval_2,4,4_2.npy -rw-rw-r-- 1 guodong.li guodong.li 60K Jul 6 10:23 Dahoas_rm_static_seed1234_train_2,4,4_0.npy -rw-rw-r-- 1 guodong.li guodong.li 120K Jul 6 10:23 Dahoas_rm_static_seed1234_train_2,4,4_1.npy -rw-rw-r-- 1 guodong.li guodong.li 120K Jul 6 10:23 Dahoas_rm_static_seed1234_train_2,4,4_2.npy -rw-rw-r-- 1 guodong.li guodong.li 3K Jul 6 10:28 Dahoas_synthetic_instruct_gptj_pairwise_seed1234_eval_2,4,4_0.npy -rw-rw-r-- 1 guodong.li guodong.li 6K Jul 6 10:28 Dahoas_synthetic_instruct_gptj_pairwise_seed1234_eval_2,4,4_1.npy -rw-rw-r-- 1 guodong.li guodong.li 6K Jul 6 10:28 Dahoas_synthetic_instruct_gptj_pairwise_seed1234_eval_2,4,4_2.npy -rw-rw-r-- 1 guodong.li guodong.li 24K Jul 6 10:28 Dahoas_synthetic_instruct_gptj_pairwise_seed1234_train_2,4,4_0.npy -rw-rw-r-- 1 guodong.li guodong.li 47K Jul 6 10:28 Dahoas_synthetic_instruct_gptj_pairwise_seed1234_train_2,4,4_1.npy -rw-rw-r-- 1 guodong.li guodong.li 47K Jul 6 10:28 Dahoas_synthetic_instruct_gptj_pairwise_seed1234_train_2,4,4_2.npy -rw-rw-r-- 1 guodong.li guodong.li 117K Jul 6 10:28 Dahoas_synthetic_instruct_gptj_pairwise_seed1234_train_eval_9,1_0.npy -rw-rw-r-- 1 guodong.li guodong.li 14K Jul 6 10:28 Dahoas_synthetic_instruct_gptj_pairwise_seed1234_train_eval_9,1_1.npy -rw-rw-r-- 1 guodong.li guodong.li 508630K Jul 6 10:31 evaldata_1cddaf9eb98d6e8394f4c53fd5ab8c97c5db3cce6e2699bc8e607027a642af35.pt -rw-rw-r-- 1 guodong.li guodong.li 15778K Jul 6 16:02 evaldata_d32e7f6108f0e9ba9b6d2642029fa6f57d50b7bc812d3ce2436afab7714d181d.pt -rw-rw-r-- 1 guodong.li guodong.li 5775824K Jul 6 10:31 traindata_1cddaf9eb98d6e8394f4c53fd5ab8c97c5db3cce6e2699bc8e607027a642af35.pt -rw-rw-r-- 1 guodong.li guodong.li 232010K Jul 6 16:02 traindata_d32e7f6108f0e9ba9b6d2642029fa6f57d50b7bc812d3ce2436afab7714d181d.pt -rw-rw-r-- 1 guodong.li guodong.li 5K Jul 6 10:30 yitingxie_rlhf_reward_datasets_seed1234_eval_2,4,4_0.npy -rw-rw-r-- 1 guodong.li guodong.li 9K Jul 6 10:30 yitingxie_rlhf_reward_datasets_seed1234_eval_2,4,4_1.npy -rw-rw-r-- 1 guodong.li guodong.li 9K Jul 6 10:30 yitingxie_rlhf_reward_datasets_seed1234_eval_2,4,4_2.npy -rw-rw-r-- 1 guodong.li guodong.li 60K Jul 6 10:29 yitingxie_rlhf_reward_datasets_seed1234_train_2,4,4_0.npy -rw-rw-r-- 1 guodong.li guodong.li 120K Jul 6 10:29 yitingxie_rlhf_reward_datasets_seed1234_train_2,4,4_1.npy -rw-rw-r-- 1 guodong.li guodong.li 120K Jul 6 10:29 yitingxie_rlhf_reward_datasets_seed1234_train_2,4,4_2.npy ``` ================================================ FILE: llm-train/deepspeedchat/llama/README.md ================================================ - Llama/Llama-2 : https://github.com/microsoft/DeepSpeed/blob/master/blogs/deepspeed-chat/ds-chat-release-8-31/README.md ================================================ FILE: llm-train/deepspeedchat/training/step1_supervised_finetuning/training_scripts/single_node/run_13b.sh ================================================ #!/bin/bash # DeepSpeed Team OUTPUT=$1 ZERO_STAGE=$2 if [ "$OUTPUT" == "" ]; then OUTPUT=./output fi if [ "$ZERO_STAGE" == "" ]; then ZERO_STAGE=3 fi mkdir -p $OUTPUT deepspeed main.py \ --data_path Dahoas/rm-static Dahoas/full-hh-rlhf Dahoas/synthetic-instruct-gptj-pairwise yitingxie/rlhf-reward-datasets \ --data_split 2,4,4 \ --model_name_or_path /home/guodong.li/model/hf-opt-2.7b \ --per_device_train_batch_size 128 \ --per_device_eval_batch_size 4 \ --max_seq_len 512 \ --learning_rate 1e-4 \ --weight_decay 0. \ --num_train_epochs 6 \ --gradient_accumulation_steps 8 \ --lr_scheduler_type cosine \ --num_warmup_steps 0 \ --seed 1234 \ --gradient_checkpointing \ --zero_stage $ZERO_STAGE \ --lora_dim 128 \ --lora_module_name decoder.layers. \ --deepspeed \ --output_dir $OUTPUT \ &> $OUTPUT/training.log ================================================ FILE: llm-train/deepspeedchat/training/step2_reward_model_finetuning/training_scripts/single_node/run_350m.sh ================================================ #!/bin/bash # DeepSpeed Team OUTPUT=$1 ZERO_STAGE=$2 if [ "$OUTPUT" == "" ]; then OUTPUT=./output fi if [ "$ZERO_STAGE" == "" ]; then ZERO_STAGE=0 fi mkdir -p $OUTPUT deepspeed main.py \ --data_path Dahoas/rm-static Dahoas/full-hh-rlhf Dahoas/synthetic-instruct-gptj-pairwise yitingxie/rlhf-reward-datasets \ --data_split 2,4,4 \ --model_name_or_path /home/guodong.li/model/hf-opt-350m \ --num_padding_at_beginning 1 \ --per_device_train_batch_size 16 \ --per_device_eval_batch_size 4 \ --max_seq_len 512 \ --learning_rate 5e-5 \ --weight_decay 0.1 \ --num_train_epochs 1 \ --disable_dropout \ --gradient_accumulation_steps 2 \ --lr_scheduler_type cosine \ --num_warmup_steps 0 \ --seed 1234 \ --zero_stage $ZERO_STAGE \ --deepspeed \ --output_dir $OUTPUT \ &> $OUTPUT/training.log ================================================ FILE: llm-train/deepspeedchat/training/step3_rlhf_finetuning/training_scripts/single_node/run_13b.sh ================================================ #!/bin/bash # DeepSpeed Team ACTOR_MODEL_PATH=$1 CRITIC_MODEL_PATH=$2 ACTOR_ZERO_STAGE=$3 CRITIC_ZERO_STAGE=$4 OUTPUT=$5 if [ "$OUTPUT" == "" ]; then OUTPUT=./output fi if [ "$ACTOR_ZERO_STAGE" == "" ]; then ACTOR_ZERO_STAGE=3 fi if [ "$CRITIC_ZERO_STAGE" == "" ]; then CRITIC_ZERO_STAGE=3 fi echo "Step3: ACTOR_MODEL_PATH=$ACTOR_MODEL_PATH CRITIC_MODEL_PATH=$CRITIC_MODEL_PATH ACTOR_ZERO_STAGE=$ACTOR_ZERO_STAGE CRITIC_ZERO_STAGE=$CRITIC_ZERO_STAGE OUTPUT=$OUTPUT" mkdir -p $OUTPUT Num_Padding_at_Beginning=1 # this is model related Actor_Lr=5e-4 Critic_Lr=5e-6 deepspeed --master_port 12346 main.py \ --data_path Dahoas/rm-static \ --data_split 2,4,4 \ --actor_model_name_or_path $ACTOR_MODEL_PATH \ --critic_model_name_or_path $CRITIC_MODEL_PATH \ --num_padding_at_beginning 1 \ --per_device_train_batch_size 32 \ --per_device_mini_train_batch_size 16 \ --generation_batch_numbers 1 \ --ppo_epochs 1 \ --max_answer_seq_len 256 \ --max_prompt_seq_len 256 \ --actor_learning_rate ${Actor_Lr} \ --critic_learning_rate ${Critic_Lr} \ --num_train_epochs 1 \ --lr_scheduler_type cosine \ --gradient_accumulation_steps 2 \ --num_warmup_steps 100 \ --deepspeed --seed 1234 \ --enable_hybrid_engine \ --inference_tp_size 2 \ --actor_zero_stage $ACTOR_ZERO_STAGE \ --critic_zero_stage $CRITIC_ZERO_STAGE \ --actor_gradient_checkpointing \ --disable_actor_dropout \ --actor_lora_dim 128 \ --actor_lora_module_name decoder.layers. \ --output_dir $OUTPUT \ &> $OUTPUT/training.log ================================================ FILE: llm-train/deepspeedchat/training/utils/data/raw_datasets.py ================================================ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 # DeepSpeed Team from datasets import load_dataset from torch.utils.data import Subset import re # The template prompt dataset class that all new dataset porting needs to # follow in order to have a unified API and unified data format. class PromptRawDataset(object): def __init__(self, output_path, seed, local_rank, dataset_name): self.output_path = output_path self.seed = seed self.local_rank = local_rank if not ("Dahoas/rm-static" == dataset_name or "Dahoas/full-hh-rlhf" == dataset_name or "Dahoas/synthetic-instruct-gptj-pairwise" == dataitingxie/rlhf-reward-datasets" == dataset_name): self.raw_datasets = load_dataset(dataset_name) def get_train_data(self): return def get_eval_data(self): return # The prompt should be in the format of: " Human: " + actual_prompt_sentence + " Assistant:" def get_prompt(self, sample): return # The chosen response should be in the format of: " " + actual_response_sentence def get_chosen(self, sample): return # The rejected response should be in the format of: " " + actual_response_sentence # If the dataset does not have rejected response, return None def get_rejected(self, sample): return def get_prompt_and_chosen(self, sample): return def get_prompt_and_rejected(self, sample): return # English dataset class DahoasRmstaticDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "Dahoas/rm-static" self.dataset_name_clean = "Dahoas_rm_static" data_files = {"train":"train-00000-of-00001-2a1df75c6bce91ab.parquet","test":"test-00000-of-00001-8c7c51afc6d45980.parquet"} self.raw_datasets = load_dataset("parquet", data_dir='/home/guodong.li/data/dahoas/rm-static/data', data_files=data_files) def get_train_data(self): return self.raw_datasets["train"] def get_eval_data(self): return self.raw_datasets["test"] def get_prompt(self, sample): return sample['prompt'] def get_chosen(self, sample): return sample['chosen'] def get_rejected(self, sample): return sample['rejected'] def get_prompt_and_chosen(self, sample): return sample['prompt'] + sample['chosen'] def get_prompt_and_rejected(self, sample): return sample['prompt'] + sample['rejected'] # English dataset class DahoasFullhhrlhfDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "Dahoas/full-hh-rlhf" self.dataset_name_clean = "Dahoas_full_hh_rlhf" data_files = {"train":"train-00000-of-00001-8349d0765e6718df.parquet","test":"test-00000-of-00001-ec71e9262143a91c.parquet"} self.raw_datasets = load_dataset("parquet", data_dir='/home/guodong.li/data/dahoas/full-hh-rlhf/data', data_files=data_files) def get_train_data(self): return self.raw_datasets["train"] def get_eval_data(self): return self.raw_datasets["test"] def get_prompt(self, sample): return sample['prompt'] def get_chosen(self, sample): return sample['chosen'] def get_rejected(self, sample): return sample['rejected'] def get_prompt_and_chosen(self, sample): return sample['prompt'] + sample['chosen'] def get_prompt_and_rejected(self, sample): return sample['prompt'] + sample['rejected'] # English dataset class DahoasSyntheticinstructgptjpairwiseDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "Dahoas/synthetic-instruct-gptj-pairwise" self.dataset_name_clean = "Dahoas_synthetic_instruct_gptj_pairwise" data_files = {"train":"train-00000-of-00001-1e5d57b93c448e7a.parquet"} self.raw_datasets = load_dataset("parquet", data_dir='/home/guodong.li/data/dahoas/synthetic-instruct-gptj-pairwise/data', data_files=d def get_train_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 0, len(dataset)) dataset = Subset(dataset, index) return dataset def get_eval_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 1, len(dataset)) dataset = Subset(dataset, index) return dataset def get_prompt(self, sample): return " Human: " + sample['prompt'] + " Assistant:" def get_chosen(self, sample): return " " + sample['chosen'] def get_rejected(self, sample): return " " + sample['rejected'] def get_prompt_and_chosen(self, sample): return " Human: " + sample['prompt'] + " Assistant: " + sample['chosen'] def get_prompt_and_rejected(self, sample): return " Human: " + sample['prompt'] + " Assistant: " + sample[ 'rejected'] # English dataset class YitingxieRlhfrewarddatasetsDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "yitingxie/rlhf-reward-datasets" self.dataset_name_clean = "yitingxie_rlhf_reward_datasets" data_files = {"train":"train-00000-of-00001-2ea3039ca4da89f8.parquet","test":"test-00000-of-00001-955c146ec7a10a1e.parquet"} self.raw_datasets = load_dataset("parquet", data_dir='/home/guodong.li/data/dahoas/rlhf-reward-datasets/data', data_files=data_files) def get_train_data(self): return self.raw_datasets["train"] def get_eval_data(self): return self.raw_datasets["test"] def get_prompt(self, sample): return sample['prompt'] + "Assistant:" def get_chosen(self, sample): return sample['chosen'].split("Assistant:")[-1] def get_rejected(self, sample): return sample['rejected'].split("Assistant:")[-1] def get_prompt_and_chosen(self, sample): return sample['prompt'] + sample['chosen'] def get_prompt_and_rejected(self, sample): return sample['prompt'] + sample['rejected'] # English dataset class OpenaiWebgptcomparisonsDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "openai/webgpt_comparisons" self.dataset_name_clean = "openai_webgpt_comparisons" def get_train_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 0, len(dataset)) dataset = Subset(dataset, index) return dataset def get_eval_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 1, len(dataset)) dataset = Subset(dataset, index) return dataset def get_prompt(self, sample): return " Human: " + sample['question']['full_text'] + " Assistant:" def get_chosen(self, sample): if float(sample['score_0']) >= float(sample['score_1']): response = sample['answer_0'] else: response = sample['answer_1'] # This data has citation square brackets and numbers (e.g., "[1]"). # Right now we are not doing browser-assisted finetuning, thus we # remove these citations to avoid confusing the model. response = re.sub(r" [\(\[].*?[\)\]]", "", response) response = re.sub(r"[\(\[].*?[\)\]]", "", response) return " " + response def get_rejected(self, sample): if float(sample['score_0']) < float(sample['score_1']): response = sample['answer_0'] else: response = sample['answer_1'] response = re.sub(r" [\(\[].*?[\)\]]", "", response) response = re.sub(r"[\(\[].*?[\)\]]", "", response) return " " + response def get_prompt_and_chosen(self, sample): if float(sample['score_0']) >= float(sample['score_1']): response = sample['answer_0'] else: response = sample['answer_1'] response = re.sub(r" [\(\[].*?[\)\]]", "", response) response = re.sub(r"[\(\[].*?[\)\]]", "", response) return " Human: " + sample['question'][ 'full_text'] + " Assistant: " + response def get_prompt_and_rejected(self, sample): if float(sample['score_0']) < float(sample['score_1']): response = sample['answer_0'] else: response = sample['answer_1'] response = re.sub(r" [\(\[].*?[\)\]]", "", response) response = re.sub(r"[\(\[].*?[\)\]]", "", response) return " Human: " + sample['question'][ 'full_text'] + " Assistant: " + response # English dataset class StanfordnlpSHPDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "stanfordnlp/SHP" self.dataset_name_clean = "stanfordnlp_SHP" def get_train_data(self): return self.raw_datasets["train"] def get_eval_data(self): return self.raw_datasets["validation"] def get_prompt(self, sample): return " Human: " + sample['history'] + " Assistant:" def get_chosen(self, sample): if int(sample["labels"]) == 1: response = sample["human_ref_A"] else: response = sample["human_ref_B"] return " " + response def get_rejected(self, sample): if int(sample["labels"]) == 1: response = sample["human_ref_B"] else: response = sample["human_ref_A"] return " " + response def get_prompt_and_chosen(self, sample): if int(sample["labels"]) == 1: response = sample["human_ref_A"] else: response = sample["human_ref_B"] return " Human: " + sample['history'] + " Assistant: " + response def get_prompt_and_rejected(self, sample): if int(sample["labels"]) == 1: response = sample["human_ref_B"] else: response = sample["human_ref_A"] return " Human: " + sample['history'] + " Assistant: " + response # Chinese dataset class Wangrui6ZhihuKOLDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "wangrui6/Zhihu-KOL" self.dataset_name_clean = "wangrui6_Zhihu_KOL" def get_train_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 0, len(dataset)) dataset = Subset(dataset, index) return dataset def get_eval_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 1, len(dataset)) dataset = Subset(dataset, index) return dataset def get_prompt(self, sample): if sample['INSTRUCTION'] is not None: return " Human: " + sample['INSTRUCTION'] + " Assistant:" return None def get_chosen(self, sample): if sample['RESPONSE'] is not None: return " " + sample['RESPONSE'] return None def get_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None def get_prompt_and_chosen(self, sample): if sample['INSTRUCTION'] is not None and sample['RESPONSE'] is not None: return " Human: " + sample[ 'INSTRUCTION'] + " Assistant: " + sample['RESPONSE'] return None def get_prompt_and_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None # Chinese dataset class CohereMiraclzhqueries2212Dataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "Cohere/miracl-zh-queries-22-12" self.dataset_name_clean = "Cohere_miracl_zh_queries_22_12" def get_train_data(self): return self.raw_datasets["train"] def get_eval_data(self): return self.raw_datasets["dev"] def get_prompt(self, sample): return " Human: " + sample['query'] + " Assistant:" def get_chosen(self, sample): return " " + sample['positive_passages'][0]['text'] def get_rejected(self, sample): return " " + sample['negative_passages'][0]['text'] def get_prompt_and_chosen(self, sample): return " Human: " + sample['query'] + " Assistant: " + sample[ 'positive_passages'][0]['text'] def get_prompt_and_rejected(self, sample): return " Human: " + sample['query'] + " Assistant: " + sample[ 'negative_passages'][0]['text'] # Chinese dataset class HelloSimpleAIHC3ChineseDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "Hello-SimpleAI/HC3-Chinese" self.dataset_name_clean = "Hello_SimpleAI_HC3_Chinese" def get_train_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 0, len(dataset)) dataset = Subset(dataset, index) return dataset def get_eval_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 1, len(dataset)) dataset = Subset(dataset, index) return dataset def get_prompt(self, sample): if sample['question'] is not None: return " Human: " + sample['question'] + " Assistant:" return None def get_chosen(self, sample): if sample['human_answers'][0] is not None: return " " + sample['human_answers'][0] return None def get_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None def get_prompt_and_chosen(self, sample): if sample['question'] is not None and sample['human_answers'][ 0] is not None: return " Human: " + sample['question'] + " Assistant: " + sample[ 'human_answers'][0] return None def get_prompt_and_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None # Chinese dataset class MkqaChineseDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "mkqa-Chinese" self.dataset_name_clean = "mkqa" def get_train_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 0, len(dataset)) dataset = Subset(dataset, index) return dataset def get_eval_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 1, len(dataset)) dataset = Subset(dataset, index) return dataset def get_prompt(self, sample): if sample['queries']['zh_cn'] is not None: return " Human: " + sample['queries']['zh_cn'] + " Assistant:" return None def get_chosen(self, sample): if sample['answers']['zh_cn'][0]['text'] is not None: return " " + sample['answers']['zh_cn'][0]['text'] return None def get_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None def get_prompt_and_chosen(self, sample): if sample['queries']['zh_cn'] is not None and sample['answers'][ 'zh_cn'][0]['text'] is not None: return " Human: " + sample['queries'][ 'zh_cn'] + " Assistant: " + sample['answers']['zh_cn'][0][ 'text'] return None def get_prompt_and_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None # Japanese dataset class MkqaJapaneseDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "mkqa-Japanese" self.dataset_name_clean = "mkqa" def get_train_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 0, len(dataset)) dataset = Subset(dataset, index) return dataset def get_eval_data(self): from .data_utils import get_raw_dataset_split_index dataset = self.raw_datasets["train"] index = get_raw_dataset_split_index(self.local_rank, self.output_path, self.dataset_name_clean, self.seed, "train_eval", "9,1", 1, len(dataset)) dataset = Subset(dataset, index) return dataset def get_prompt(self, sample): if sample['queries']['ja'] is not None: return " Human: " + sample['queries']['ja'] + " Assistant:" return None def get_chosen(self, sample): if sample['answers']['ja'][0]['text'] is not None: return " " + sample['answers']['ja'][0]['text'] return None def get_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None def get_prompt_and_chosen(self, sample): if sample['queries']['ja'] is not None and sample['answers']['ja'][0][ 'text'] is not None: return " Human: " + sample['queries'][ 'ja'] + " Assistant: " + sample['answers']['ja'][0]['text'] return None def get_prompt_and_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None # Japanese dataset class CohereMiracljaqueries2212Dataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "Cohere/miracl-ja-queries-22-12" self.dataset_name_clean = "Cohere_miracl_ja_queries_22_12" def get_train_data(self): return self.raw_datasets["train"] def get_eval_data(self): return self.raw_datasets["dev"] def get_prompt(self, sample): return " Human: " + sample['query'] + " Assistant:" def get_chosen(self, sample): return " " + sample['positive_passages'][0]['text'] def get_rejected(self, sample): return " " + sample['negative_passages'][0]['text'] def get_prompt_and_chosen(self, sample): return " Human: " + sample['query'] + " Assistant: " + sample[ 'positive_passages'][0]['text'] def get_prompt_and_rejected(self, sample): return " Human: " + sample['query'] + " Assistant: " + sample[ 'negative_passages'][0]['text'] # Japanese dataset class LmqgQgjaquadDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "lmqg/qg_jaquad" self.dataset_name_clean = "lmqg_qg_jaquad" def get_train_data(self): return self.raw_datasets["train"] def get_eval_data(self): return self.raw_datasets["validation"] def get_prompt(self, sample): return " Human: " + sample['question'] + " Assistant:" def get_chosen(self, sample): return " " + sample['sentence'] def get_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None def get_prompt_and_chosen(self, sample): return " Human: " + sample['question'] + " Assistant: " + sample[ 'sentence'] def get_prompt_and_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None # Japanese dataset class LmqgQagjaquadDataset(PromptRawDataset): def __init__(self, output_path, seed, local_rank, dataset_name): super().__init__(output_path, seed, local_rank, dataset_name) self.dataset_name = "lmqg/qag_jaquad" self.dataset_name_clean = "lmqg_qag_jaquad" def get_train_data(self): return self.raw_datasets["train"] def get_eval_data(self): return self.raw_datasets["validation"] def get_prompt(self, sample): return " Human: " + sample['questions'][0] + " Assistant:" def get_chosen(self, sample): return " " + sample['paragraph'] def get_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None def get_prompt_and_chosen(self, sample): return " Human: " + sample['questions'][0] + " Assistant: " + sample[ 'paragraph'] def get_prompt_and_rejected(self, sample): print( f"Warning: dataset {self.dataset_name} does not include rejected response." ) return None ================================================ FILE: llm-train/firefly/README.md ================================================ - https://github.com/yangjianxin1/Firefly ## 启动脚本 ``` sh test_bash_getopts.sh -j /data/usw/web -m /opt/data/web sh test_bash_getopts.sh -j /data/usw/web -m /opt/data/web -u sh test_bash_getopts.sh -h sh test_bash_getopts.sh ? # sh bootstrap.sh -train_dataset_path /data/usw/web2 -pre_model_path /opt/data/web2 -model_output_path /opt/data/web3 -train_metrics_path /opt/data/web4 sh bootstrap.sh -h sh bootstrap.sh -d /data/usw/web2 -p /opt/data/web2 -o /opt/data/web3 -m /opt/data/web4 ``` ================================================ FILE: llm-train/firefly/bootstrap-s3.sh ================================================ #!/bin/bash # sh bootstrap2.sh -d s3://infer-test/dianxiao-data/train_data_20240105_1k.json -p s3://infer-test/dianxiao-model -o s3://infer-test/dianxiao-output -m s3://infer-test/dianxiao-output/processx.jsonca func() { echo "Usage:" echo "test.sh [-d TRAIN_DATASET_PATH] [-p PRE_MODEL_PATH] [-o MODEL_OUTPUT_PATH] [-m MODEL_METRICS_PATH]" echo "Description:" echo "TRAIN_DATASET_PATH, 训练数据集路径." echo "PRE_MODEL_PATH, 预训练模型路径." echo "MODEL_OUTPUT_PATH, 模型输出模型." echo "MODEL_METRICS_PATH, 模型指标路径." exit -1 } while getopts 'd:p:o:m:h' OPT; do case $OPT in d) TRAIN_DATASET_PATH="$OPTARG";; p) PRE_MODEL_PATH="$OPTARG";; o) MODEL_OUTPUT_PATH="$OPTARG";; m) MODEL_METRICS_PATH="$OPTARG";; h) func;; ?) func;; esac done echo "入参:TRAIN_DATASET_PATH: $TRAIN_DATASET_PATH ,PRE_MODEL_PATH:$PRE_MODEL_PATH , MODEL_OUTPUT_PATH:$MODEL_OUTPUT_PATH ,MODEL_METRICS_PATH:$MODEL_METRICS_PATH" if [ -n "$TRAIN_DATASET_PATH" ] && [ -n "$PRE_MODEL_PATH" ] && [ -n "$MODEL_OUTPUT_PATH" ] && [ -n "$MODEL_METRICS_PATH" ]; then echo "--" else echo "变量不能为空" exit -1 fi PROJECT_PATH=/workspace/code/Firefly # PROJECT_PATH=/home/guodong.li/workspace/code/Firefly LOCAL_TEMP_DIR=/workspace/temp LOCAL_DATASET_PATH="$LOCAL_TEMP_DIR/datas" LOCAL_MODEL_PATH="$LOCAL_TEMP_DIR/models" LOCAL_OUTPUT_PATH="$LOCAL_TEMP_DIR/outputs" LOCAL_LOG_PATH="$LOCAL_TEMP_DIR/logs" rm -rf $LOCAL_TEMP_DIR mkdir -p $LOCAL_DATASET_PATH mkdir -p $LOCAL_MODEL_PATH mkdir -p $LOCAL_OUTPUT_PATH mkdir -p $LOCAL_LOG_PATH echo "download s3 from s3..." cd /workspace/code/Firefly && python download.py --model_name_or_path "s3://infer-test/dianxiao-model" --train_file "s3://infer-test/dianxiao-data/train_data_20240105_1k.json" echo "执行数据和模型下载脚本:" echo "cd $PROJECT_PATH && python download.py --model_name_or_path $PRE_MODEL_PATH --train_file $TRAIN_DATASET_PATH" echo "download data end from s3..." echo "train task start..." FILENAME=$(basename -- "$TRAIN_DATASET_PATH") #EXTENSION="${FILENAME##*.}" #FILENAME="${FILENAME%.*}" #FILENAME=$FILENAME"."$EXTENSION LOCAL_DATASET_FILE_PATH="$LOCAL_DATASET_PATH/$FILENAME" echo "LOCAL_DATASET_PATH: $LOCAL_DATASET_FILE_PATH" TRAIN_ARGS_PATH="$PROJECT_PATH/sft-config.json" cat < $TRAIN_ARGS_PATH { "output_dir": "$MODEL_OUTPUT_PATH", "logging_dir": "$LOCAL_LOG_PATH", "model_name_or_path": "$LOCAL_MODEL_PATH, "deepspeed": "./train_args/ds_z3_config.json", "train_file": "$LOCAL_DATASET_FILE_PATH", "num_train_epochs": 1, "per_device_train_batch_size": 4, "gradient_accumulation_steps": 4, "learning_rate": 1e-5, "max_seq_length": 512, "logging_steps": 1, "save_steps": 500, "save_total_limit": 1, "lr_scheduler_type": "cosine", "warmup_ratio": 0.1, "gradient_checkpointing": false, "disable_tqdm": false, "optim": "adamw_hf", "seed": 42, "fp16": true, "report_to": "tensorboard", "dataloader_num_workers": 5, "save_strategy": "steps", "weight_decay": 0, "max_grad_norm": 1.0, "remove_unused_columns": false } EOF echo "训练参数: " cat $TRAIN_ARGS_PATH echo "执行训练任务脚本:" echo "cd $PROJECT_PATH && source /opt/rh/devtoolset-9/enable && deepspeed --num_gpus=8 train_s3.py --train_args_file $TRAIN_ARGS_PATH" cd /workspace/code/Firefly && source /opt/rh/devtoolset-9/enable && deepspeed --num_gpus=8 train_s3.py --train_args_file train_args/sft-docker-s3.json echo "train task end..." ================================================ FILE: llm-train/firefly/bootstrap.sh ================================================ #!/bin/bash func() { echo "Usage:" echo "test.sh [-d TRAIN_DATASET_PATH] [-p PRE_MODEL_PATH] [-o MODEL_OUTPUT_PATH] [-m MODEL_METRICS_PATH]" echo "Description:" echo "TRAIN_DATASET_PATH, 训练数据集路径." echo "PRE_MODEL_PATH, 预训练模型路径." echo "MODEL_OUTPUT_PATH, 模型输出模型." echo "MODEL_METRICS_PATH, 模型指标路径." exit -1 } while getopts 'd:p:o:m' OPT; do case $OPT in d) TRAIN_DATASET_PATH="$OPTARG";; p) PRE_MODEL_PATH="$OPTARG";; o) MODEL_OUTPUT_PATH="$OPTARG";; m) MODEL_METRICS_PATH="$OPTARG";; h) func;; ?) func;; esac done echo "TRAIN_DATASET_PATH: $TRAIN_DATASET_PATH ,PRE_MODEL_PATH:$PRE_MODEL_PATH , MODEL_OUTPUT_PATH:$MODEL_OUTPUT_PATH ,MODEL_METRICS_PATH:$MODEL_METRICS_PATH" ================================================ FILE: llm-train/firefly/dockerfile.md ================================================ ``` FROM aiharbor.xxxx.local/base/python:py310-11.7-cudnn8-devel-centos7 MAINTAINER guodong.li liguodongiot@163.com RUN yum -y install devtoolset-9 which && yum clean all && rm -rf /var/cache/yum/* && rm -rf /tmp/* \ && echo "" >> /etc/profile && echo "source /opt/rh/devtoolset-9/enable" >> /etc/profile RUN conda init \ && conda create -n torch1131-venv python=3.10 -y && source ~/.bashrc && conda env list && conda activate torch1131-venv && pip install --no-cache-dir http://10.xx.2.25:81/pypi/pytorch/torch-1.13.1%2Bcu117-cp310-cp310-linux_x86_64.whl \ && conda create -n torch201-venv python=3.10 -y && source ~/.bashrc && conda env list && conda activate torch201-venv && pip install --no-cache-dir http://10.cc.2.46:8000/base-env/torch-2.0.1+cu117-cp310-cp310-linux_x86_64.whl \ && rm -rf ~/.cache/pip/* && conda clean -all && rm -rf /tmp/* ``` ``` sudo docker build --network=host -f base-env.Dockerfile -t harbor.xxxx.io/base/tianqiong-base-env:v1-20240131 . sudo docker run -it --gpus '"device=4,5"' --network=host \ --shm-size 4G \ harbor.xxx.io/base/tianqiong-base-env:v1-20240131 \ /bin/bash source ~/.bashrc conda activate torch1131-venv && pip list | grep torch conda activate torch201-venv && pip list | grep torch ``` ------------------------------------ ``` FROM harbor.xxxx.io/base/tianqiong-base-env:v1-20240131 MAINTAINER guodong.li liguodongiot@163.com ENV APP_DIR=/workspace RUN mkdir -p -m 777 $APP_DIR COPY train-env ${APP_DIR}/train-env # llm-安装依赖 RUN source ~/.bashrc && conda env list && conda create -n llm-venv --clone torch1131-venv \ && conda activate llm-venv && pip install --no-cache-dir -r ${APP_DIR}/train-env/requirements-llm.txt \ -i http://nexus3.xxx.com/repository/pypi/simple --trusted-host nexus3.xxx.com && rm -rf ~/.cache/pip/* && conda clean -all #RUN source ~/.bashrc && conda env list && conda activate llm-venv && pip install --no-cache-dir storageutils==0.1.2 -i http://nexus3.xxx.com/repository/xxx_py_release/simple --trusted-host nexus3.xxx.com && rm -rf ~/.cache/pip/* && conda clean -all RUN source ~/.bashrc && conda env list && conda activate llm-venv && cd ${APP_DIR}/train-env/bitsandbytes && source /opt/rh/devtoolset-9/enable && CUDA_VERSION=117 make cuda11x && python setup.py install && python setup.py clean --all && rm -rf ~/.cache/pip/* && conda clean -all # baichuan2-t5-安装依赖 RUN source ~/.bashrc && conda env list && conda create -n llm-baichuan2-venv --clone torch201-venv && conda activate llm-baichuan2-venv && pip install --no-cache-dir -r \ ${APP_DIR}/train-env/requirements-llm-baichuan2.txt \ -i http://nexus3.xxx.com/repository/pypi/simple --trusted-host nexus3.xxx.com && rm -rf ~/.cache/pip/* && conda clean -all #RUN source ~/.bashrc && conda env list && conda activate llm-baichuan2-venv && pip install --no-cache-dir storageutils==0.1.2 -i http://nexus3.xxx.com/repository/xxx_py_release/simple --trusted-host nexus3.xxx.com && rm -rf ~/.cache/pip/* && conda clean -all RUN source ~/.bashrc && conda env list && conda activate llm-baichuan2-venv && cd ${APP_DIR}/train-env/bitsandbytes && source /opt/rh/devtoolset-9/enable && CUDA_VERSION=117 make cuda11x && python setup.py install && python setup.py clean --all && rm -rf ~/.cache/pip/* && conda clean -all # t5-安装依赖 RUN source ~/.bashrc && conda env list && conda create -n t5-venv --clone torch201-venv \ && conda activate t5-venv && pip install --no-cache-dir -r ${APP_DIR}/train-env/requirements-t5.txt \ -i http://nexus3.xxd.com/repository/pypi/simple --trusted-host nexus3.xxx.com && rm -rf ~/.cache/pip/* && conda clean -all #RUN source ~/.bashrc && conda env list && conda activate t5-venv && pip install --no-cache-dir storageutils==0.1.2 -i http://nexus3.mxxx.com/repository/xxx_py_release/simple --trusted-host nexus3.fss.com && rm -rf ~/.cache/pip/* && conda clean -all RUN rm -rf ${APP_DIR}/train-env #设置工作目录 WORKDIR $APP_DIR ``` ``` sudo docker build --network=host -f train-env.Dockerfile -t harbor.xxx.io/base/tianqiong-train-env:v1-20240131 . sudo docker run -it --gpus '"device=4,5"' --network=host \ --shm-size 4G \ harbor.xxx.io/base/tianqiong-train-env:v1-20240131 \ /bin/bash source ~/.bashrc conda activate llm-venv && pip list | grep torch conda activate llm-baichuan2-venv && pip list | grep torch conda activate t5-venv && pip list | grep torch ``` ================================================ FILE: llm-train/firefly/test_bash_getopts.sh ================================================ #!/bin/bash func() { echo "Usage:" echo "test.sh [-j S_DIR] [-m D_DIR]" echo "Description:" echo "S_DIR,the path of source." echo "D_DIR,the path of destination." exit -1 } upload="false" while getopts 'h:j:m:u' OPT; do case $OPT in j) S_DIR="$OPTARG";; m) D_DIR="$OPTARG";; u) upload="true";; h) func;; ?) func;; esac done echo $S_DIR echo $D_DIR echo $upload ================================================ FILE: llm-train/fp8.md ================================================ - https://huggingface.co/docs/accelerate/v0.30.0/en/usage_guides/low_precision_training - https://huggingface.co/docs/accelerate/v0.30.0/en/concept_guides/low_precision_training - https://github.com/huggingface/transformers/issues/20991 - https://zhuanlan.zhihu.com/p/700874387 ================================================ FILE: llm-train/galore/torchrun_main.py ================================================ import os import time import json import random import argparse import numpy as np import torch import torch.nn as nn import torch.utils.data import torch.distributed as dist import transformers from transformers import AutoConfig, AutoTokenizer, AutoModelForCausalLM from transformers import LlamaForCausalLM as HF_LlamaForCausalLM from datasets import load_dataset import datasets import datasets.distributed import wandb from tqdm import tqdm from loguru import logger from peft_pretraining import training_utils, args_utils from peft_pretraining.dataloader import PreprocessedIterableDataset from peft_pretraining.modeling_llama import LlamaForCausalLM import bitsandbytes as bnb from galore_torch import GaLoreAdamW, GaLoreAdamW8bit, GaLoreAdafactor transformers.logging.set_verbosity_error() def parse_args(args): parser = argparse.ArgumentParser() parser.add_argument("--model_config", type=str, required=True) parser.add_argument("--use_hf_model", default=False, action="store_true") parser.add_argument("--continue_from", type=str, default=None) parser.add_argument("--batch_size", type=int, required=True) parser.add_argument("--gradient_accumulation", type=int, default=None) parser.add_argument("--total_batch_size", type=int, default=None) parser.add_argument("--max_length", type=int, default=256) parser.add_argument("--optimizer", default="Adam") parser.add_argument("--lr", type=float, default=1e-4) parser.add_argument("--scheduler", type=str, default="cosine", choices=["linear", "cosine", "cosine_restarts"]) parser.add_argument("--min_lr_ratio", type=float, default=0.1) parser.add_argument("--activation_checkpointing", action="store_true") parser.add_argument("--weight_decay", type=float, default=0.0) parser.add_argument("--warmup_steps", type=int, default=1_000) parser.add_argument("--eval_every", type=int, default=5_000) parser.add_argument("--num_training_steps", type=int, default=10_000, help="Number of **update steps** to train for. " "Notice that gradient accumulation is taken into account.") parser.add_argument("--max_train_tokens", type=training_utils.max_train_tokens_to_number, default=None, help="Number of tokens to train on. Overwrites num_training_steps. " "You can use M and B suffixes, e.g. 100M or 1B.") parser.add_argument("--save_every", type=int, default=10_000) parser.add_argument("--save_dir", type=str, default=None) parser.add_argument("--tags", type=str, default=None) parser.add_argument("--dtype", type=str, default="bfloat16" if torch.cuda.is_bf16_supported() else "float32") parser.add_argument("--workers", type=int, default=8) parser.add_argument("--seed", type=int, default=0) parser.add_argument("--name", type=str, default="test") parser.add_argument("--grad_clipping", type=float, default=0.0) # beta1 for adafactor parser.add_argument("--beta1", type=float, default=0.0) # GaLore parameters parser.add_argument("--rank", type=int, default=128) parser.add_argument("--update_proj_gap", type=int, default=50) parser.add_argument("--galore_scale", type=float, default=1.0) parser.add_argument("--proj_type", type=str, default="std") # disable ddp, single_gpu parser.add_argument("--single_gpu", default=False, action="store_true") args = parser.parse_args(args) args = args_utils.check_args_torchrun_main(args) return args @torch.no_grad() def evaluate_model(model, preprocess_batched, pad_idx, global_rank, world_size, device, batch_size): _time = time.time() #val_data = datasets.load_dataset("c4", "en", split="validation", streaming=True) #DGX data = load_dataset("json", data_files="/home/guodong.li/c4/c4-train.00000-of-01024.json") print(data) val_data = data["train"] val_data = val_data.shuffle(seed=42) logger.info(f"Loaded validation dataset in {time.time() - _time:.2f} seconds") if not args.single_gpu: val_data = datasets.distributed.split_dataset_by_node(val_data, rank=global_rank, world_size=world_size) val_data_mapped = val_data.map( preprocess_batched, batched=True, remove_columns=["text", "timestamp", "url"], ) val_data_mapped.batch = lambda batch_size: training_utils.batch_fn(val_data_mapped, batch_size) target_eval_tokens = 10_000_000 evaluated_on_tokens = 0 total_loss = torch.tensor(0.0).to(device) total_batches = 1 logger.info(f"Eval set prepared in {time.time() - _time:.2f} seconds") for batch in val_data_mapped.batch(batch_size=batch_size): if evaluated_on_tokens > target_eval_tokens: break total_batches += 1 batch = {k: v.to(device) for k, v in batch.items()} labels = batch["input_ids"].clone() labels[labels == pad_idx] = -100 loss = model(**batch, labels=labels).loss total_loss += loss.detach() evaluated_on_tokens += (batch["input_ids"] != pad_idx).sum().item() * world_size total_loss = total_loss / total_batches # Gather losses across all GPUs gathered_losses = [torch.zeros_like(total_loss) for _ in range(world_size)] dist.all_gather(gathered_losses, total_loss) total_loss = sum([t.item() for t in gathered_losses]) / world_size return total_loss, evaluated_on_tokens def main(args): torch.manual_seed(args.seed) np.random.seed(args.seed) random.seed(args.seed) assert "LOCAL_RANK" in os.environ, "torchrun should set LOCAL_RANK" global_rank = int(os.environ['RANK']) local_rank = int(os.environ["LOCAL_RANK"]) world_size = int(os.environ["WORLD_SIZE"]) torch.cuda.set_device(local_rank) logger.info(f"Global rank {global_rank}, local rank {local_rank}, device: {torch.cuda.current_device()}") dist.init_process_group(backend="nccl", rank=global_rank, world_size=world_size) logger.info("Process group initialized") device = f"cuda:{local_rank}" if args.total_batch_size is not None: if args.gradient_accumulation is None: assert args.total_batch_size % world_size == 0, "total_batch_size must be divisible by world_size" args.gradient_accumulation = args.total_batch_size // (args.batch_size * world_size) assert args.gradient_accumulation > 0, "gradient_accumulation must be greater than 0" assert args.gradient_accumulation * args.batch_size * world_size == args.total_batch_size, \ "gradient_accumulation * batch_size * world_size must be equal to total_batch_size" # turn off logger if global_rank != 0: logger.remove() # initialize wandb without config (it is passed later) if global_rank == 0: wandb.init(project="galore-c4") logger.info(f"Using dist with rank {global_rank} (only rank 0 will log)") logger.info("*" * 40) logger.info(f"Starting training with the arguments") for k, v in vars(args).items(): logger.info(f"{k:30} {v}") logger.info("*" * 40) #data = datasets.load_dataset("c4", "en", split="train", streaming=True) data = load_dataset("json", data_files="/home/guodong.li/c4/c4-train.00000-of-01024.json") print(data) data = data["train"] seed_for_shuffle = 42 logger.info(f"Shuffling data with seed {seed_for_shuffle}") data: datasets.Dataset = data.shuffle(seed=seed_for_shuffle) if not args.single_gpu: data = datasets.distributed.split_dataset_by_node( data, rank=global_rank, world_size=world_size, ) # it doesn't matter which tokenizer we use, because we train from scratch # T5 tokenizer was trained on C4 and we are also training on C4, so it's a good choice # tokenizer = AutoTokenizer.from_pretrained("t5-base", model_max_length=args.max_length) tokenizer = AutoTokenizer.from_pretrained("/home/guodong.li/workspace/model/t5_base", model_max_length=args.max_length) def preprocess_batched(batch): batch = tokenizer( batch["text"], max_length=args.max_length, truncation=True, padding="max_length", return_tensors="pt", ) return batch dataset = PreprocessedIterableDataset(data, tokenizer, batch_size=args.batch_size, max_length=args.max_length) dataloader = torch.utils.data.DataLoader(dataset, batch_size=None, num_workers=args.workers) model_config = AutoConfig.from_pretrained(args.model_config) if args.use_hf_model: model: HF_LlamaForCausalLM = AutoModelForCausalLM.from_config(model_config) else: model = LlamaForCausalLM(model_config) if args.activation_checkpointing: model.gradient_checkpointing_enable() global_step = 0 update_step = 0 beginning_step = 0 tokens_seen = 0 tokens_seen_before = 0 if args.continue_from is not None: logger.info("*" * 40) logger.info(f"Loading model from {args.continue_from}") checkpoint_path = os.path.join(args.continue_from, "pytorch_model.bin") model.load_state_dict(torch.load(checkpoint_path, map_location="cpu"), strict=True) logger.info(f"Model successfully loaded (strict=True policy)") if os.path.exists(os.path.join(args.continue_from, "training_state.json")): logger.info(f"Loading training state like global_step, update_step, and tokens_seen from {args.continue_from}") with open(os.path.join(args.continue_from, "training_state.json")) as f: _old_state = json.load(f) global_step = _old_state["global_step"] update_step = _old_state["update_step"] tokens_seen = _old_state["tokens_seen"] tokens_seen_before = _old_state["tokens_seen_before"] logger.info(f"global_step : {global_step}") logger.info(f"update_step : {update_step}") logger.info(f"tokens_seen : {tokens_seen}") logger.info(f"tokens_seen_before: {tokens_seen_before}") logger.info(f"Will train for {args.num_training_steps - update_step} update steps") else: logger.warning(f"Did not find training state in {args.continue_from}, global step will start from zero") logger.info("*" * 40) if args.dtype in ["bf16", "bfloat16"]: model = model.to(device=device, dtype=torch.bfloat16) else: model = model.to(device=device) n_total_params = sum(p.numel() for p in model.parameters()) trainable_params = [p for p in model.parameters() if p.requires_grad] # Initialize wandb run_config = dict(vars(args)) run_config.update({ "max_lr": run_config.pop("lr"), # rename lr to max_lr to avoid conflicts with scheduler "total_params_M": n_total_params / 1_000_000, "dataset": 'c4', "model": model_config.to_dict(), "world_size": world_size, "device": str(device), }) if global_rank == 0: wandb.config.update(run_config, allow_val_change=True) wandb.save(os.path.abspath(__file__), policy="now") # save current script # fix tqdm visual length to 80 so that the progress bar # doesn't jump around when changing from external display to laptop pbar = tqdm(total=args.num_training_steps - update_step, desc="Update steps", ncols=80) if 'galore' in args.optimizer.lower(): # make parameters with "rank" to a single group, if param_name has "mlp" or "attn" galore_params = [] target_modules_list = ["attn", "mlp"] for module_name, module in model.named_modules(): if not isinstance(module, nn.Linear): continue if not any(target_key in module_name for target_key in target_modules_list): continue print('enable GaLore for weights in module: ', module_name) galore_params.append(module.weight) id_galore_params = [id(p) for p in galore_params] # make parameters without "rank" to another group regular_params = [p for p in model.parameters() if id(p) not in id_galore_params] # then call galore_adamw param_groups = [{'params': regular_params}, {'params': galore_params, 'rank': args.rank, 'update_proj_gap': args.update_proj_gap, 'scale': args.galore_scale, 'proj_type': args.proj_type}] # print params and trainable params logger.info(f"\n{model}\n") logger.info(f"Total params: {sum(p.numel() for p in model.parameters()) / 1_000_000:.2f}M") logger.info(f"Trainable params: {sum(p.numel() for p in model.parameters() if p.requires_grad) / 1_000_000:.2f}M") logger.info(f"Total params with GaLore enabled: {sum(p.numel() for p in galore_params) / 1_000_000:.2f}M") logger.info(f"Saving model to {args.save_dir} every {args.save_every} update steps") layer_wise_flag = False if args.optimizer.lower() == "adam": optimizer = torch.optim.Adam(trainable_params, lr=args.lr, weight_decay=args.weight_decay) elif args.optimizer.lower() == "galore_adamw": # redefine way to call galore_adamw optimizer = GaLoreAdamW(param_groups, lr=args.lr, weight_decay=args.weight_decay) # implement sgd elif args.optimizer.lower() == "sgd": optimizer = torch.optim.SGD(trainable_params, lr=args.lr, weight_decay=args.weight_decay, momentum=args.beta1) # implement adafactor elif args.optimizer.lower() == "adafactor": args.beta1 = None if args.beta1 == 0.0 else args.beta1 optimizer = transformers.optimization.Adafactor( trainable_params, lr=args.lr, eps=(1e-30, 1e-3), clip_threshold=1.0, decay_rate=-0.8, beta1=args.beta1, weight_decay=args.weight_decay, relative_step=False, scale_parameter=False, warmup_init=False, ) # low-rank adafactor elif args.optimizer.lower() == "galore_adafactor": args.beta1 = None if args.beta1 == 0.0 else args.beta1 optimizer = GaLoreAdafactor( param_groups, lr=args.lr, eps=(1e-30, 1e-3), clip_threshold=1.0, decay_rate=-0.8, beta1=args.beta1, weight_decay=args.weight_decay, relative_step=False, scale_parameter=False, warmup_init=False, ) # 8-bit Adam elif args.optimizer.lower() == "adam8bit": optimizer = bnb.optim.Adam8bit(trainable_params, lr=args.lr, weight_decay=args.weight_decay) elif args.optimizer.lower() == "galore_adamw8bit": optimizer = GaLoreAdamW8bit(param_groups, lr=args.lr, weight_decay=args.weight_decay) elif args.optimizer.lower() == 'galore_adamw8bit_per_layer': # TODO: seems scheduler call twice in one update step, need to check, for now double the num_training_steps, warmup_steps and update_proj_gap optimizer_dict = {} for p in model.parameters(): if p.requires_grad: if id(p) in id_galore_params: optimizer_dict[p] = GaLoreAdamW8bit([{'params': [p], 'rank': args.rank, 'update_proj_gap': args.update_proj_gap * 2, 'scale': args.galore_scale, 'proj_type': args.proj_type}], lr=args.lr, weight_decay=args.weight_decay) else: optimizer_dict[p] = bnb.optim.Adam8bit([p], lr=args.lr, weight_decay=args.weight_decay) # get scheduler dict scheduler_dict = {} for p in model.parameters(): if p.requires_grad: scheduler_dict[p] = training_utils.get_scheculer( optimizer=optimizer_dict[p], scheduler_type=args.scheduler, num_training_steps=args.num_training_steps * 2, warmup_steps=args.warmup_steps * 2, min_lr_ratio=args.min_lr_ratio, ) def optimizer_hook(p): if p.grad is None: return optimizer_dict[p].step() optimizer_dict[p].zero_grad() scheduler_dict[p].step() # Register the hook onto every parameter for p in model.parameters(): if p.requires_grad: p.register_post_accumulate_grad_hook(optimizer_hook) layer_wise_flag = True else: raise ValueError(f"Optimizer {args.optimizer} not supported") if not layer_wise_flag: scheduler = training_utils.get_scheculer( optimizer=optimizer, scheduler_type=args.scheduler, num_training_steps=args.num_training_steps, warmup_steps=args.warmup_steps, min_lr_ratio=args.min_lr_ratio, ) if not args.single_gpu: model: LlamaForCausalLM = torch.nn.parallel.DistributedDataParallel( model, device_ids=[local_rank], output_device=local_rank, broadcast_buffers=False, ) # global steps and others are defined above pad_idx = tokenizer.pad_token_id update_time = time.time() local_step = 0 # when continue_from is used, local_step != global_step # ############################## # TRAINING LOOP # we'll never go through all the data, so no need for epochs # ############################## for batch_idx, batch in enumerate(dataloader): global_step += 1 local_step += 1 if update_step > args.num_training_steps: logger.info(f"Reached max number of update steps (f{args.num_training_steps}). Stopping training.") print(f"Rank {global_rank} stopping training.") break batch = {k: v.to(device) for k, v in batch.items()} labels = batch["input_ids"].clone() labels[labels == pad_idx] = -100 tokens_seen += (batch["input_ids"] != pad_idx).sum().item() * world_size loss = model(**batch, labels=labels).loss scaled_loss = loss / args.gradient_accumulation scaled_loss.backward() if global_step % args.gradient_accumulation != 0: continue # The below code is only executed during the update step # add grad clipping if args.grad_clipping != 0.0: torch.nn.utils.clip_grad_norm_(trainable_params, args.grad_clipping) if global_rank == 0: pbar.update(1) if not layer_wise_flag: optimizer.step() scheduler.step() optimizer.zero_grad() update_step += 1 update_time = time.time() - update_time # save checkpoint by save_every if local_step > args.gradient_accumulation and update_step % args.save_every == 0 and global_rank == 0: current_model_directory = f"{args.save_dir}/model_{update_step}" logger.info(f"Saving model and optimizer to {current_model_directory}, update step {update_step}") os.makedirs(args.save_dir, exist_ok=True) model.module.save_pretrained(current_model_directory, max_shard_size='100GB') optimizer_checkpoint = { "optimizer": optimizer.state_dict(), "scheduler": scheduler.state_dict(), "update_step": update_step, "global_step": global_step, "config": run_config, "wandb": wandb.run.dir, "dtype": args.dtype, } torch.save(optimizer_checkpoint, f"{current_model_directory}/optimizer.pt") training_state_checkpoint = { "global_step": global_step, "update_step": update_step, "tokens_seen": tokens_seen, "tokens_seen_before": tokens_seen_before, "update_time": update_time, } with open(f"{current_model_directory}/training_state.json", "w") as f: json.dump(training_state_checkpoint, f, indent=4) # save wandb related info wandb_info = { "wandb_id": wandb.run.id, } with open(f"{args.save_dir}/wandb.json", "w") as f: json.dump(wandb_info, f, indent=4) # evaluation if update_step % args.eval_every == 0: logger.info(f"Performing evaluation at step {update_step}") total_loss, evaluated_on_tokens = evaluate_model( model, preprocess_batched, pad_idx, global_rank, world_size, device, args.batch_size ) if global_rank == 0: wandb.log({ "final_eval_loss": total_loss, "final_eval_tokens": evaluated_on_tokens, }, step=global_step, ) logger.info(f"Eval loss at step {update_step}: {total_loss}") if not layer_wise_flag: lr = optimizer.param_groups[0]["lr"] else: lr = list(optimizer_dict.values())[0].param_groups[0]["lr"] tokens_in_update = tokens_seen - tokens_seen_before tokens_seen_before = tokens_seen batches_in_update = args.gradient_accumulation * world_size if global_rank == 0: wandb.log({ "loss": loss.item(), "lr": lr, "update_step": update_step, "tokens_seen": tokens_seen, "throughput_tokens": tokens_in_update / update_time, "throughput_examples": args.total_batch_size / update_time, "throughput_batches": batches_in_update / update_time, }, step=global_step, ) update_time = time.time() # ############################## # END of training loop # ############################## logger.info("Training finished") if global_rank == 0: pbar.close() current_model_directory = f"{args.save_dir}/model_{update_step}" if global_rank == 0 and not os.path.exists(current_model_directory): logger.info(f"Saving model and optimizer to {current_model_directory}, update step {update_step}") os.makedirs(args.save_dir, exist_ok=True) model.module.save_pretrained(current_model_directory) optimizer_checkpoint = { "optimizer": optimizer.state_dict(), "scheduler": scheduler.state_dict(), "update_step": update_step, "global_step": global_step, "config": run_config, "wandb": wandb.run.dir, "dtype": args.dtype, } torch.save(optimizer_checkpoint, f"{current_model_directory}/optimizer.pt") training_state_checkpoint = { "global_step": global_step, "update_step": update_step, "tokens_seen": tokens_seen, "tokens_seen_before": tokens_seen_before, "update_time": update_time, } with open(f"{current_model_directory}/training_state.json", "w") as f: json.dump(training_state_checkpoint, f, indent=4) # Final evaluation logger.info("Running final evaluation") model.eval() del loss, optimizer, scheduler import gc; gc.collect() torch.cuda.empty_cache() total_loss, evaluated_on_tokens = evaluate_model( model, preprocess_batched, pad_idx, global_rank, world_size, device, args.batch_size ) if global_rank == 0: wandb.log({ "final_eval_loss": total_loss, "final_eval_tokens": evaluated_on_tokens, }, step=global_step, ) logger.info(f"Final eval loss: {total_loss}") logger.info("Script finished successfully") print(f"Rank {global_rank} finished successfully") if __name__ == "__main__": print("Starting script") args = parse_args(None) main(args) ================================================ FILE: llm-train/megatron/README.md ================================================ ## 基于Megatron-LM实现的项目 - [CodeGeeX](https://github.com/THUDM/CodeGeeX) - [如何使用 Megatron-LM 训练语言模型](https://huggingface.co/blog/zh/megatron-training):数据预处理,训练,模型转换,推理等 ### 数据加载 Megatron-LM 带有一个高效的 DataLoader,其中数据在训练前被 tokenize 和 shuffle。它还将数据拆分为带有索引的编号序列,并将索引存储,因此 tokenize 只需要计算一次。为了构建索引,首先根据训练参数计算每个 epoch 的数量,并创建一个排序,然后对数据进行 shuffle 操作。这与大多数情况不同,我们通常迭代整个数据集直到其用尽,然后重复第二个 epoch 。这平滑了学习曲线并节省了训练时间。 ### 融合 CUDA 内核 当一个计算在 GPU 上运行时,必要的数据会从内存中取出并加载到 GPU 上,然后计算结果被保存回内存。简单来说,融合内核的思想是: 将通常由 PyTorch 单独执行的类似操作组合成一个单独的硬件操作。因此可以将多个离散计算合并为一个,从而减少在多个离散计算中的内存移动次数。 当 f、g 和 h 融合在一个内核中时,f 和 g 的中间结果 x' 和 y' 存储在 GPU 寄存器中并立即被 h 使用。但是如果不融合,x' 和 y' 就需要复制到内存中,然后由 h 加载。因此,融合 CUDA 内核显着加快了计算速度。此外,Megatron-LM 还使用 Apex 的 AdamW 融合实现,它比 PyTorch 实现更快。 虽然我们可以在 transformers 中自定义 Megatron-LM 中的 DataLoader 和 Apex 的融合优化器,但自定义融合 CUDA 内核对新手来说太不友好了。 ================================================ FILE: llm-train/megatron/codegeex/README.md ================================================ ``` docker pull codegeex/codegeex:latest # To enable GPU support, clarify device ids with --device docker run --gpus '"device=0,1"' -it --ipc=host --name=codegeex codegeex/codegeex ``` ``` git clone git@github.com:THUDM/CodeGeeX.git cd CodeGeeX pip install -e . ``` ================================================ FILE: llm-train/megatron/gpt2/README.md ================================================ ## GPT2 模型训练 ## 环境 ``` docker run -dt --name nvidia_pytorch_2304_temp --restart=always --gpus all \ --network=host \ --shm-size 4G \ -v /home/gdong/workspace:/workspace \ -w /workspace \ nvcr.io/nvidia/pytorch:23.04-py3 \ /bin/bash docker exec -it nvidia_pytorch_2304_temp bash ``` --- ``` pip freeze > requirements.txt ``` ## 代码 ``` git clone https://github.com/NVIDIA/Megatron-LM.git cd Megatron-LM git checkout 992da75 ``` 修改代码: - megatron/tokenizer/file_utils.py - tools/openwebtext/merge_data.py 脚本: - pretrain_gpt.sh:单机 - pretrain_gpt_distributed.sh:数据并行 - pretrain_gpt_distributed_with_mp.sh:模型并行+数据并行 ## 权重 ``` > tree -h megatron megatron ├── [ 8] latest_checkpointed_iteration.txt └── [4.0K] release └── [4.0K] mp_rank_00 └── [677M] model_optim_rng.pt 2 directories, 2 files > cat megatron/latest_checkpointed_iteration.txt release ``` ## [数据预处理](https://github.com/liguodongiot/llm-action/blob/main/train/megatron/gpt2/gpt-data-preprocess.md) ## [模型训练](https://github.com/liguodongiot/llm-action/blob/main/train/megatron/gpt2/model_train.md) ## [模型评估及推理](https://github.com/liguodongiot/llm-action/blob/main/train/megatron/gpt2/model_merge_eval_inference.md) ================================================ FILE: llm-train/megatron/gpt2/data/cMinhash.cpp ================================================ /* Generated by Cython 0.24.1 */ /* BEGIN: Cython Metadata { "distutils": { "depends": [ "/Users/miro/anaconda3/envs/skimit-extract/lib/python3.5/site-packages/numpy/core/include/numpy/arrayobject.h", "/Users/miro/anaconda3/envs/skimit-extract/lib/python3.5/site-packages/numpy/core/include/numpy/ufuncobject.h", "lsh/MurmurHash3.h" ], "include_dirs": [ "/Users/miro/anaconda3/envs/skimit-extract/lib/python3.5/site-packages/numpy/core/include" ], "language": "c++", "sources": [ "lsh/MurmurHash3.cpp" ] }, "module_name": "lsh.cMinhash" } END: Cython Metadata */ #define PY_SSIZE_T_CLEAN #include "Python.h" #ifndef Py_PYTHON_H #error Python headers needed to compile C extensions, please install development version of Python. #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000) #error Cython requires Python 2.6+ or Python 3.2+. #else #define CYTHON_ABI "0_24_1" #include #ifndef offsetof #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) #endif #if !defined(WIN32) && !defined(MS_WINDOWS) #ifndef __stdcall #define __stdcall #endif #ifndef __cdecl #define __cdecl #endif #ifndef __fastcall #define __fastcall #endif #endif #ifndef DL_IMPORT #define DL_IMPORT(t) t #endif #ifndef DL_EXPORT #define DL_EXPORT(t) t #endif #ifndef PY_LONG_LONG #define PY_LONG_LONG LONG_LONG #endif #ifndef Py_HUGE_VAL #define Py_HUGE_VAL HUGE_VAL #endif #ifdef PYPY_VERSION #define CYTHON_COMPILING_IN_PYPY 1 #define CYTHON_COMPILING_IN_CPYTHON 0 #else #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_CPYTHON 1 #endif #if !defined(CYTHON_USE_PYLONG_INTERNALS) && CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000 #define CYTHON_USE_PYLONG_INTERNALS 1 #endif #if CYTHON_USE_PYLONG_INTERNALS #include "longintrepr.h" #undef SHIFT #undef BASE #undef MASK #endif #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) #define Py_OptimizeFlag 0 #endif #define __PYX_BUILD_PY_SSIZE_T "n" #define CYTHON_FORMAT_SSIZE_T "z" #if PY_MAJOR_VERSION < 3 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #define __Pyx_DefaultClassType PyClass_Type #else #define __Pyx_BUILTIN_MODULE_NAME "builtins" #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #define __Pyx_DefaultClassType PyType_Type #endif #ifndef Py_TPFLAGS_CHECKTYPES #define Py_TPFLAGS_CHECKTYPES 0 #endif #ifndef Py_TPFLAGS_HAVE_INDEX #define Py_TPFLAGS_HAVE_INDEX 0 #endif #ifndef Py_TPFLAGS_HAVE_NEWBUFFER #define Py_TPFLAGS_HAVE_NEWBUFFER 0 #endif #ifndef Py_TPFLAGS_HAVE_FINALIZE #define Py_TPFLAGS_HAVE_FINALIZE 0 #endif #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) #define CYTHON_PEP393_ENABLED 1 #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ 0 : _PyUnicode_Ready((PyObject *)(op))) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) #else #define CYTHON_PEP393_ENABLED 0 #define __Pyx_PyUnicode_READY(op) (0) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) #endif #if CYTHON_COMPILING_IN_PYPY #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) #else #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) #endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) #endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) #endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) #endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) #define PyObject_Malloc(s) PyMem_Malloc(s) #define PyObject_Free(p) PyMem_Free(p) #define PyObject_Realloc(p) PyMem_Realloc(p) #endif #define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) #define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) #else #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) #endif #if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) #define PyObject_ASCII(o) PyObject_Repr(o) #endif #if PY_MAJOR_VERSION >= 3 #define PyBaseString_Type PyUnicode_Type #define PyStringObject PyUnicodeObject #define PyString_Type PyUnicode_Type #define PyString_Check PyUnicode_Check #define PyString_CheckExact PyUnicode_CheckExact #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) #else #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) #endif #ifndef PySet_CheckExact #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) #endif #define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) #if PY_MAJOR_VERSION >= 3 #define PyIntObject PyLongObject #define PyInt_Type PyLong_Type #define PyInt_Check(op) PyLong_Check(op) #define PyInt_CheckExact(op) PyLong_CheckExact(op) #define PyInt_FromString PyLong_FromString #define PyInt_FromUnicode PyLong_FromUnicode #define PyInt_FromLong PyLong_FromLong #define PyInt_FromSize_t PyLong_FromSize_t #define PyInt_FromSsize_t PyLong_FromSsize_t #define PyInt_AsLong PyLong_AsLong #define PyInt_AS_LONG PyLong_AS_LONG #define PyInt_AsSsize_t PyLong_AsSsize_t #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask #define PyNumber_Int PyNumber_Long #endif #if PY_MAJOR_VERSION >= 3 #define PyBoolObject PyLongObject #endif #if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY #ifndef PyUnicode_InternFromString #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) #endif #endif #if PY_VERSION_HEX < 0x030200A4 typedef long Py_hash_t; #define __Pyx_PyInt_FromHash_t PyInt_FromLong #define __Pyx_PyInt_AsHash_t PyInt_AsLong #else #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) #else #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) #endif #if PY_VERSION_HEX >= 0x030500B1 #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) #elif CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; } __Pyx_PyAsyncMethodsStruct; #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) #else #define __Pyx_PyType_AsAsync(obj) NULL #endif #ifndef CYTHON_RESTRICT #if defined(__GNUC__) #define CYTHON_RESTRICT __restrict__ #elif defined(_MSC_VER) && _MSC_VER >= 1400 #define CYTHON_RESTRICT __restrict #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define CYTHON_RESTRICT restrict #else #define CYTHON_RESTRICT #endif #endif #define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) #ifndef __cplusplus #error "Cython files generated with the C++ option must be compiled with a C++ compiler." #endif #ifndef CYTHON_INLINE #define CYTHON_INLINE inline #endif template void __Pyx_call_destructor(T& x) { x.~T(); } template class __Pyx_FakeReference { public: __Pyx_FakeReference() : ptr(NULL) { } __Pyx_FakeReference(const T& ref) : ptr(const_cast(&ref)) { } T *operator->() { return ptr; } operator T&() { return *ptr; } private: T *ptr; }; #if defined(WIN32) || defined(MS_WINDOWS) #define _USE_MATH_DEFINES #endif #include #ifdef NAN #define __PYX_NAN() ((float) NAN) #else static CYTHON_INLINE float __PYX_NAN() { float value; memset(&value, 0xFF, sizeof(value)); return value; } #endif #if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) #define __Pyx_truncl trunc #else #define __Pyx_truncl truncl #endif #define __PYX_ERR(f_index, lineno, Ln_error) \ { \ __pyx_filename = __pyx_f[f_index]; __pyx_lineno = lineno; __pyx_clineno = __LINE__; goto Ln_error; \ } #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) #else #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) #endif #ifndef __PYX_EXTERN_C #ifdef __cplusplus #define __PYX_EXTERN_C extern "C" #else #define __PYX_EXTERN_C extern #endif #endif #define __PYX_HAVE__lsh__cMinhash #define __PYX_HAVE_API__lsh__cMinhash #include "string.h" #include "stdlib.h" #include "stdint.h" #include "stdio.h" #include "numpy/arrayobject.h" #include "numpy/ufuncobject.h" #include "MurmurHash3.h" #include "pythread.h" #include "pystate.h" #ifdef _OPENMP #include #endif /* _OPENMP */ #ifdef PYREX_WITHOUT_ASSERTIONS #define CYTHON_WITHOUT_ASSERTIONS #endif #ifndef CYTHON_UNUSED # if defined(__GNUC__) # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) # define CYTHON_UNUSED __attribute__ ((__unused__)) # else # define CYTHON_UNUSED # endif # elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) # define CYTHON_UNUSED __attribute__ ((__unused__)) # else # define CYTHON_UNUSED # endif #endif #ifndef CYTHON_NCP_UNUSED # if CYTHON_COMPILING_IN_CPYTHON # define CYTHON_NCP_UNUSED # else # define CYTHON_NCP_UNUSED CYTHON_UNUSED # endif #endif typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; #define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 #define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 #define __PYX_DEFAULT_STRING_ENCODING "" #define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString #define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize #define __Pyx_uchar_cast(c) ((unsigned char)c) #define __Pyx_long_cast(x) ((long)x) #define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ (sizeof(type) < sizeof(Py_ssize_t)) ||\ (sizeof(type) > sizeof(Py_ssize_t) &&\ likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX) &&\ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ v == (type)PY_SSIZE_T_MIN))) ||\ (sizeof(type) == sizeof(Py_ssize_t) &&\ (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ v == (type)PY_SSIZE_T_MAX))) ) #if defined (__cplusplus) && __cplusplus >= 201103L #include #define __Pyx_sst_abs(value) std::abs(value) #elif SIZEOF_INT >= SIZEOF_SIZE_T #define __Pyx_sst_abs(value) abs(value) #elif SIZEOF_LONG >= SIZEOF_SIZE_T #define __Pyx_sst_abs(value) labs(value) #elif defined (_MSC_VER) && defined (_M_X64) #define __Pyx_sst_abs(value) _abs64(value) #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define __Pyx_sst_abs(value) llabs(value) #elif defined (__GNUC__) #define __Pyx_sst_abs(value) __builtin_llabs(value) #else #define __Pyx_sst_abs(value) ((value<0) ? -value : value) #endif static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*); static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); #define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) #define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) #define __Pyx_PyBytes_FromString PyBytes_FromString #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); #if PY_MAJOR_VERSION < 3 #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize #else #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize #endif #define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) #define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) #define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) #define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) #define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) #if PY_MAJOR_VERSION < 3 static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { const Py_UNICODE *u_end = u; while (*u_end++) ; return (size_t)(u_end - u - 1); } #else #define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen #endif #define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) #define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode #define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode #define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) #define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); #if CYTHON_COMPILING_IN_CPYTHON #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) #else #define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) #endif #define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) #else #define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) #endif #define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII static int __Pyx_sys_getdefaultencoding_not_ascii; static int __Pyx_init_sys_getdefaultencoding_params(void) { PyObject* sys; PyObject* default_encoding = NULL; PyObject* ascii_chars_u = NULL; PyObject* ascii_chars_b = NULL; const char* default_encoding_c; sys = PyImport_ImportModule("sys"); if (!sys) goto bad; default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); Py_DECREF(sys); if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; if (strcmp(default_encoding_c, "ascii") == 0) { __Pyx_sys_getdefaultencoding_not_ascii = 0; } else { char ascii_chars[128]; int c; for (c = 0; c < 128; c++) { ascii_chars[c] = c; } __Pyx_sys_getdefaultencoding_not_ascii = 1; ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); if (!ascii_chars_u) goto bad; ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { PyErr_Format( PyExc_ValueError, "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", default_encoding_c); goto bad; } Py_DECREF(ascii_chars_u); Py_DECREF(ascii_chars_b); } Py_DECREF(default_encoding); return 0; bad: Py_XDECREF(default_encoding); Py_XDECREF(ascii_chars_u); Py_XDECREF(ascii_chars_b); return -1; } #endif #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) #else #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT static char* __PYX_DEFAULT_STRING_ENCODING; static int __Pyx_init_sys_getdefaultencoding_params(void) { PyObject* sys; PyObject* default_encoding = NULL; char* default_encoding_c; sys = PyImport_ImportModule("sys"); if (!sys) goto bad; default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); Py_DECREF(sys); if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); Py_DECREF(default_encoding); return 0; bad: Py_XDECREF(default_encoding); return -1; } #endif #endif /* Test for GCC > 2.95 */ #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else /* !__GNUC__ or GCC < 2.95 */ #define likely(x) (x) #define unlikely(x) (x) #endif /* __GNUC__ */ static PyObject *__pyx_m; static PyObject *__pyx_d; static PyObject *__pyx_b; static PyObject *__pyx_empty_tuple; static PyObject *__pyx_empty_bytes; static PyObject *__pyx_empty_unicode; static int __pyx_lineno; static int __pyx_clineno = 0; static const char * __pyx_cfilenm= __FILE__; static const char *__pyx_filename; /* None.proto */ #if !defined(CYTHON_CCOMPLEX) #if defined(__cplusplus) #define CYTHON_CCOMPLEX 1 #elif defined(_Complex_I) #define CYTHON_CCOMPLEX 1 #else #define CYTHON_CCOMPLEX 0 #endif #endif #if CYTHON_CCOMPLEX #ifdef __cplusplus #include #else #include #endif #endif #if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) #undef _Complex_I #define _Complex_I 1.0fj #endif static const char *__pyx_f[] = { "lsh/cMinhash.pyx", "__init__.pxd", "stringsource", "type.pxd", }; /* BufferFormatStructs.proto */ #define IS_UNSIGNED(type) (((type) -1) > 0) struct __Pyx_StructField_; #define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) typedef struct { const char* name; struct __Pyx_StructField_* fields; size_t size; size_t arraysize[8]; int ndim; char typegroup; char is_unsigned; int flags; } __Pyx_TypeInfo; typedef struct __Pyx_StructField_ { __Pyx_TypeInfo* type; const char* name; size_t offset; } __Pyx_StructField; typedef struct { __Pyx_StructField* field; size_t parent_offset; } __Pyx_BufFmt_StackElem; typedef struct { __Pyx_StructField root; __Pyx_BufFmt_StackElem* head; size_t fmt_offset; size_t new_count, enc_count; size_t struct_alignment; int is_complex; char enc_type; char new_packmode; char enc_packmode; char is_valid_array; } __Pyx_BufFmt_Context; /* MemviewSliceStruct.proto */ struct __pyx_memoryview_obj; typedef struct { struct __pyx_memoryview_obj *memview; char *data; Py_ssize_t shape[8]; Py_ssize_t strides[8]; Py_ssize_t suboffsets[8]; } __Pyx_memviewslice; /* Atomics.proto */ #include #ifndef CYTHON_ATOMICS #define CYTHON_ATOMICS 1 #endif #define __pyx_atomic_int_type int #if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 ||\ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) &&\ !defined(__i386__) #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1) #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1) #ifdef __PYX_DEBUG_ATOMICS #warning "Using GNU atomics" #endif #elif CYTHON_ATOMICS && defined(_MSC_VER) && 0 #include #undef __pyx_atomic_int_type #define __pyx_atomic_int_type LONG #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value) #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value) #ifdef __PYX_DEBUG_ATOMICS #pragma message ("Using MSVC atomics") #endif #elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0 #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value) #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value) #ifdef __PYX_DEBUG_ATOMICS #warning "Using Intel atomics" #endif #else #undef CYTHON_ATOMICS #define CYTHON_ATOMICS 0 #ifdef __PYX_DEBUG_ATOMICS #warning "Not using atomics" #endif #endif typedef volatile __pyx_atomic_int_type __pyx_atomic_int; #if CYTHON_ATOMICS #define __pyx_add_acquisition_count(memview)\ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock) #define __pyx_sub_acquisition_count(memview)\ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock) #else #define __pyx_add_acquisition_count(memview)\ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock) #define __pyx_sub_acquisition_count(memview)\ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock) #endif /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":725 * # in Cython to enable them only on the right systems. * * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t */ typedef npy_int8 __pyx_t_5numpy_int8_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":726 * * ctypedef npy_int8 int8_t * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< * ctypedef npy_int32 int32_t * ctypedef npy_int64 int64_t */ typedef npy_int16 __pyx_t_5numpy_int16_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":727 * ctypedef npy_int8 int8_t * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< * ctypedef npy_int64 int64_t * #ctypedef npy_int96 int96_t */ typedef npy_int32 __pyx_t_5numpy_int32_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":728 * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< * #ctypedef npy_int96 int96_t * #ctypedef npy_int128 int128_t */ typedef npy_int64 __pyx_t_5numpy_int64_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":732 * #ctypedef npy_int128 int128_t * * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t */ typedef npy_uint8 __pyx_t_5numpy_uint8_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":733 * * ctypedef npy_uint8 uint8_t * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< * ctypedef npy_uint32 uint32_t * ctypedef npy_uint64 uint64_t */ typedef npy_uint16 __pyx_t_5numpy_uint16_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":734 * ctypedef npy_uint8 uint8_t * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< * ctypedef npy_uint64 uint64_t * #ctypedef npy_uint96 uint96_t */ typedef npy_uint32 __pyx_t_5numpy_uint32_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":735 * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< * #ctypedef npy_uint96 uint96_t * #ctypedef npy_uint128 uint128_t */ typedef npy_uint64 __pyx_t_5numpy_uint64_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":739 * #ctypedef npy_uint128 uint128_t * * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< * ctypedef npy_float64 float64_t * #ctypedef npy_float80 float80_t */ typedef npy_float32 __pyx_t_5numpy_float32_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":740 * * ctypedef npy_float32 float32_t * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< * #ctypedef npy_float80 float80_t * #ctypedef npy_float128 float128_t */ typedef npy_float64 __pyx_t_5numpy_float64_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":749 * # The int types are mapped a bit surprising -- * # numpy.int corresponds to 'l' and numpy.long to 'q' * ctypedef npy_long int_t # <<<<<<<<<<<<<< * ctypedef npy_longlong long_t * ctypedef npy_longlong longlong_t */ typedef npy_long __pyx_t_5numpy_int_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":750 * # numpy.int corresponds to 'l' and numpy.long to 'q' * ctypedef npy_long int_t * ctypedef npy_longlong long_t # <<<<<<<<<<<<<< * ctypedef npy_longlong longlong_t * */ typedef npy_longlong __pyx_t_5numpy_long_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":751 * ctypedef npy_long int_t * ctypedef npy_longlong long_t * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< * * ctypedef npy_ulong uint_t */ typedef npy_longlong __pyx_t_5numpy_longlong_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":753 * ctypedef npy_longlong longlong_t * * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< * ctypedef npy_ulonglong ulong_t * ctypedef npy_ulonglong ulonglong_t */ typedef npy_ulong __pyx_t_5numpy_uint_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":754 * * ctypedef npy_ulong uint_t * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< * ctypedef npy_ulonglong ulonglong_t * */ typedef npy_ulonglong __pyx_t_5numpy_ulong_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":755 * ctypedef npy_ulong uint_t * ctypedef npy_ulonglong ulong_t * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< * * ctypedef npy_intp intp_t */ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":757 * ctypedef npy_ulonglong ulonglong_t * * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< * ctypedef npy_uintp uintp_t * */ typedef npy_intp __pyx_t_5numpy_intp_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":758 * * ctypedef npy_intp intp_t * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< * * ctypedef npy_double float_t */ typedef npy_uintp __pyx_t_5numpy_uintp_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":760 * ctypedef npy_uintp uintp_t * * ctypedef npy_double float_t # <<<<<<<<<<<<<< * ctypedef npy_double double_t * ctypedef npy_longdouble longdouble_t */ typedef npy_double __pyx_t_5numpy_float_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":761 * * ctypedef npy_double float_t * ctypedef npy_double double_t # <<<<<<<<<<<<<< * ctypedef npy_longdouble longdouble_t * */ typedef npy_double __pyx_t_5numpy_double_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":762 * ctypedef npy_double float_t * ctypedef npy_double double_t * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< * * ctypedef npy_cfloat cfloat_t */ typedef npy_longdouble __pyx_t_5numpy_longdouble_t; /* None.proto */ #if CYTHON_CCOMPLEX #ifdef __cplusplus typedef ::std::complex< float > __pyx_t_float_complex; #else typedef float _Complex __pyx_t_float_complex; #endif #else typedef struct { float real, imag; } __pyx_t_float_complex; #endif /* None.proto */ #if CYTHON_CCOMPLEX #ifdef __cplusplus typedef ::std::complex< double > __pyx_t_double_complex; #else typedef double _Complex __pyx_t_double_complex; #endif #else typedef struct { double real, imag; } __pyx_t_double_complex; #endif /*--- Type declarations ---*/ struct __pyx_array_obj; struct __pyx_MemviewEnum_obj; struct __pyx_memoryview_obj; struct __pyx_memoryviewslice_obj; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":764 * ctypedef npy_longdouble longdouble_t * * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< * ctypedef npy_cdouble cdouble_t * ctypedef npy_clongdouble clongdouble_t */ typedef npy_cfloat __pyx_t_5numpy_cfloat_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":765 * * ctypedef npy_cfloat cfloat_t * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< * ctypedef npy_clongdouble clongdouble_t * */ typedef npy_cdouble __pyx_t_5numpy_cdouble_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":766 * ctypedef npy_cfloat cfloat_t * ctypedef npy_cdouble cdouble_t * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< * * ctypedef npy_cdouble complex_t */ typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":768 * ctypedef npy_clongdouble clongdouble_t * * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< * * cdef inline object PyArray_MultiIterNew1(a): */ typedef npy_cdouble __pyx_t_5numpy_complex_t; /* "View.MemoryView":103 * * @cname("__pyx_array") * cdef class array: # <<<<<<<<<<<<<< * * cdef: */ struct __pyx_array_obj { PyObject_HEAD struct __pyx_vtabstruct_array *__pyx_vtab; char *data; Py_ssize_t len; char *format; int ndim; Py_ssize_t *_shape; Py_ssize_t *_strides; Py_ssize_t itemsize; PyObject *mode; PyObject *_format; void (*callback_free_data)(void *); int free_data; int dtype_is_object; }; /* "View.MemoryView":275 * * @cname('__pyx_MemviewEnum') * cdef class Enum(object): # <<<<<<<<<<<<<< * cdef object name * def __init__(self, name): */ struct __pyx_MemviewEnum_obj { PyObject_HEAD PyObject *name; }; /* "View.MemoryView":326 * * @cname('__pyx_memoryview') * cdef class memoryview(object): # <<<<<<<<<<<<<< * * cdef object obj */ struct __pyx_memoryview_obj { PyObject_HEAD struct __pyx_vtabstruct_memoryview *__pyx_vtab; PyObject *obj; PyObject *_size; PyObject *_array_interface; PyThread_type_lock lock; __pyx_atomic_int acquisition_count[2]; __pyx_atomic_int *acquisition_count_aligned_p; Py_buffer view; int flags; int dtype_is_object; __Pyx_TypeInfo *typeinfo; }; /* "View.MemoryView":951 * * @cname('__pyx_memoryviewslice') * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<< * "Internal class for passing memoryview slices to Python" * */ struct __pyx_memoryviewslice_obj { struct __pyx_memoryview_obj __pyx_base; __Pyx_memviewslice from_slice; PyObject *from_object; PyObject *(*to_object_func)(char *); int (*to_dtype_func)(char *, PyObject *); }; /* "View.MemoryView":103 * * @cname("__pyx_array") * cdef class array: # <<<<<<<<<<<<<< * * cdef: */ struct __pyx_vtabstruct_array { PyObject *(*get_memview)(struct __pyx_array_obj *); }; static struct __pyx_vtabstruct_array *__pyx_vtabptr_array; /* "View.MemoryView":326 * * @cname('__pyx_memoryview') * cdef class memoryview(object): # <<<<<<<<<<<<<< * * cdef object obj */ struct __pyx_vtabstruct_memoryview { char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *); PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *); PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *); PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *); PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *); PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *); PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *); }; static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview; /* "View.MemoryView":951 * * @cname('__pyx_memoryviewslice') * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<< * "Internal class for passing memoryview slices to Python" * */ struct __pyx_vtabstruct__memoryviewslice { struct __pyx_vtabstruct_memoryview __pyx_base; }; static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice; /* --- Runtime support code (head) --- */ /* Refnanny.proto */ #ifndef CYTHON_REFNANNY #define CYTHON_REFNANNY 0 #endif #if CYTHON_REFNANNY typedef struct { void (*INCREF)(void*, PyObject*, int); void (*DECREF)(void*, PyObject*, int); void (*GOTREF)(void*, PyObject*, int); void (*GIVEREF)(void*, PyObject*, int); void* (*SetupContext)(const char*, int, const char*); void (*FinishContext)(void**); } __Pyx_RefNannyAPIStruct; static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; #ifdef WITH_THREAD #define __Pyx_RefNannySetupContext(name, acquire_gil)\ if (acquire_gil) {\ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ PyGILState_Release(__pyx_gilstate_save);\ } else {\ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ } #else #define __Pyx_RefNannySetupContext(name, acquire_gil)\ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) #endif #define __Pyx_RefNannyFinishContext()\ __Pyx_RefNanny->FinishContext(&__pyx_refnanny) #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) #else #define __Pyx_RefNannyDeclarations #define __Pyx_RefNannySetupContext(name, acquire_gil) #define __Pyx_RefNannyFinishContext() #define __Pyx_INCREF(r) Py_INCREF(r) #define __Pyx_DECREF(r) Py_DECREF(r) #define __Pyx_GOTREF(r) #define __Pyx_GIVEREF(r) #define __Pyx_XINCREF(r) Py_XINCREF(r) #define __Pyx_XDECREF(r) Py_XDECREF(r) #define __Pyx_XGOTREF(r) #define __Pyx_XGIVEREF(r) #endif #define __Pyx_XDECREF_SET(r, v) do {\ PyObject *tmp = (PyObject *) r;\ r = v; __Pyx_XDECREF(tmp);\ } while (0) #define __Pyx_DECREF_SET(r, v) do {\ PyObject *tmp = (PyObject *) r;\ r = v; __Pyx_DECREF(tmp);\ } while (0) #define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) #define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) /* PyObjectGetAttrStr.proto */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { PyTypeObject* tp = Py_TYPE(obj); if (likely(tp->tp_getattro)) return tp->tp_getattro(obj, attr_name); #if PY_MAJOR_VERSION < 3 if (likely(tp->tp_getattr)) return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); #endif return PyObject_GetAttr(obj, attr_name); } #else #define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) #endif /* GetBuiltinName.proto */ static PyObject *__Pyx_GetBuiltinName(PyObject *name); /* RaiseArgTupleInvalid.proto */ static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /* RaiseDoubleKeywords.proto */ static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /* ParseKeywords.proto */ static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ const char* function_name); /* ArgTypeTest.proto */ static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, const char *name, int exact); /* BufferFormatCheck.proto */ static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, __Pyx_BufFmt_StackElem* stack, __Pyx_TypeInfo* type); // PROTO /* GetModuleGlobalName.proto */ static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); /* PyObjectCall.proto */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); #else #define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) #endif /* ExtTypeTest.proto */ static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); #define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0) /* MemviewSliceInit.proto */ #define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d #define __Pyx_MEMVIEW_DIRECT 1 #define __Pyx_MEMVIEW_PTR 2 #define __Pyx_MEMVIEW_FULL 4 #define __Pyx_MEMVIEW_CONTIG 8 #define __Pyx_MEMVIEW_STRIDED 16 #define __Pyx_MEMVIEW_FOLLOW 32 #define __Pyx_IS_C_CONTIG 1 #define __Pyx_IS_F_CONTIG 2 static int __Pyx_init_memviewslice( struct __pyx_memoryview_obj *memview, int ndim, __Pyx_memviewslice *memviewslice, int memview_is_new_reference); static CYTHON_INLINE int __pyx_add_acquisition_count_locked( __pyx_atomic_int *acquisition_count, PyThread_type_lock lock); static CYTHON_INLINE int __pyx_sub_acquisition_count_locked( __pyx_atomic_int *acquisition_count, PyThread_type_lock lock); #define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p) #define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview)) #define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__) #define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__) static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int); static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int); /* PyThreadStateGet.proto */ #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; #define __Pyx_PyThreadState_assign __pyx_tstate = PyThreadState_GET(); #else #define __Pyx_PyThreadState_declare #define __Pyx_PyThreadState_assign #endif /* PyErrFetchRestore.proto */ #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) #define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) #define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) #define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); #else #define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) #define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) #define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) #define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) #endif /* RaiseException.proto */ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /* DictGetItem.proto */ #if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { PyObject *value; value = PyDict_GetItemWithError(d, key); if (unlikely(!value)) { if (!PyErr_Occurred()) { PyObject* args = PyTuple_Pack(1, key); if (likely(args)) PyErr_SetObject(PyExc_KeyError, args); Py_XDECREF(args); } return NULL; } Py_INCREF(value); return value; } #else #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) #endif /* RaiseTooManyValuesToUnpack.proto */ static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); /* RaiseNeedMoreValuesToUnpack.proto */ static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); /* RaiseNoneIterError.proto */ static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); /* IncludeStringH.proto */ #include /* BytesEquals.proto */ static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); /* UnicodeEquals.proto */ static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /* StrEquals.proto */ #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals #else #define __Pyx_PyString_Equals __Pyx_PyBytes_Equals #endif /* None.proto */ static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* UnaryNegOverflows.proto */ #define UNARY_NEG_WOULD_OVERFLOW(x)\ (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x))) static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *); /*proto*/ /* GetAttr.proto */ static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); /* decode_c_string.proto */ static CYTHON_INLINE PyObject* __Pyx_decode_c_string( const char* cstring, Py_ssize_t start, Py_ssize_t stop, const char* encoding, const char* errors, PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); /* SaveResetException.proto */ #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); #define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); #else #define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) #define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) #endif /* PyErrExceptionMatches.proto */ #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); #else #define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) #endif /* GetException.proto */ #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); #else static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); #endif /* SwapException.proto */ #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); #else static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); #endif /* Import.proto */ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /* GetItemInt.proto */ #define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ __Pyx_GetItemInt_Generic(o, to_py_func(i)))) #define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, int wraparound, int boundscheck); #define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, int wraparound, int boundscheck); static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, int wraparound, int boundscheck); static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ /* ListCompAppend.proto */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { PyListObject* L = (PyListObject*) list; Py_ssize_t len = Py_SIZE(list); if (likely(L->allocated > len)) { Py_INCREF(x); PyList_SET_ITEM(list, len, x); Py_SIZE(list) = len+1; return 0; } return PyList_Append(list, x); } #else #define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) #endif /* PyIntBinop.proto */ #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, long intval, int inplace); #else #define __Pyx_PyInt_AddObjC(op1, op2, intval, inplace)\ (inplace ? PyNumber_InPlaceAdd(op1, op2) : PyNumber_Add(op1, op2)) #endif /* ListExtend.proto */ static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) { #if CYTHON_COMPILING_IN_CPYTHON PyObject* none = _PyList_Extend((PyListObject*)L, v); if (unlikely(!none)) return -1; Py_DECREF(none); return 0; #else return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v); #endif } /* ListAppend.proto */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { PyListObject* L = (PyListObject*) list; Py_ssize_t len = Py_SIZE(list); if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { Py_INCREF(x); PyList_SET_ITEM(list, len, x); Py_SIZE(list) = len+1; return 0; } return PyList_Append(list, x); } #else #define __Pyx_PyList_Append(L,x) PyList_Append(L,x) #endif /* None.proto */ static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname); /* ForceInitThreads.proto */ #ifndef __PYX_FORCE_INIT_THREADS #define __PYX_FORCE_INIT_THREADS 0 #endif /* None.proto */ static CYTHON_INLINE long __Pyx_div_long(long, long); /* WriteUnraisableException.proto */ static void __Pyx_WriteUnraisable(const char *name, int clineno, int lineno, const char *filename, int full_traceback, int nogil); /* PyObjectCallMethO.proto */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); #endif /* PyObjectCallOneArg.proto */ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); /* SetVTable.proto */ static int __Pyx_SetVtable(PyObject *dict, void *vtable); /* CodeObjectCache.proto */ typedef struct { PyCodeObject* code_object; int code_line; } __Pyx_CodeObjectCacheEntry; struct __Pyx_CodeObjectCache { int count; int max_count; __Pyx_CodeObjectCacheEntry* entries; }; static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); static PyCodeObject *__pyx_find_code_object(int code_line); static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); /* AddTraceback.proto */ static void __Pyx_AddTraceback(const char *funcname, int c_line, int py_line, const char *filename); #if PY_MAJOR_VERSION < 3 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); static void __Pyx_ReleaseBuffer(Py_buffer *view); #else #define __Pyx_GetBuffer PyObject_GetBuffer #define __Pyx_ReleaseBuffer PyBuffer_Release #endif /* BufferStructDeclare.proto */ typedef struct { Py_ssize_t shape, strides, suboffsets; } __Pyx_Buf_DimInfo; typedef struct { size_t refcount; Py_buffer pybuffer; } __Pyx_Buffer; typedef struct { __Pyx_Buffer *rcbuffer; char *data; __Pyx_Buf_DimInfo diminfo[8]; } __Pyx_LocalBuf_ND; /* None.proto */ static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0}; static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1}; /* MemviewSliceIsContig.proto */ static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice mvs, char order, int ndim); /* OverlappingSlices.proto */ static int __pyx_slices_overlap(__Pyx_memviewslice *slice1, __Pyx_memviewslice *slice2, int ndim, size_t itemsize); /* Capsule.proto */ static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig); /* CIntToPy.proto */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value); /* CIntToPy.proto */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); /* None.proto */ #if CYTHON_CCOMPLEX #ifdef __cplusplus #define __Pyx_CREAL(z) ((z).real()) #define __Pyx_CIMAG(z) ((z).imag()) #else #define __Pyx_CREAL(z) (__real__(z)) #define __Pyx_CIMAG(z) (__imag__(z)) #endif #else #define __Pyx_CREAL(z) ((z).real) #define __Pyx_CIMAG(z) ((z).imag) #endif #if defined(__cplusplus) && CYTHON_CCOMPLEX && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) #define __Pyx_SET_CREAL(z,x) ((z).real(x)) #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) #else #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) #endif /* None.proto */ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); /* None.proto */ #if CYTHON_CCOMPLEX #define __Pyx_c_eqf(a, b) ((a)==(b)) #define __Pyx_c_sumf(a, b) ((a)+(b)) #define __Pyx_c_difff(a, b) ((a)-(b)) #define __Pyx_c_prodf(a, b) ((a)*(b)) #define __Pyx_c_quotf(a, b) ((a)/(b)) #define __Pyx_c_negf(a) (-(a)) #ifdef __cplusplus #define __Pyx_c_is_zerof(z) ((z)==(float)0) #define __Pyx_c_conjf(z) (::std::conj(z)) #if 1 #define __Pyx_c_absf(z) (::std::abs(z)) #define __Pyx_c_powf(a, b) (::std::pow(a, b)) #endif #else #define __Pyx_c_is_zerof(z) ((z)==0) #define __Pyx_c_conjf(z) (conjf(z)) #if 1 #define __Pyx_c_absf(z) (cabsf(z)) #define __Pyx_c_powf(a, b) (cpowf(a, b)) #endif #endif #else static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex); static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex); static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex); static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex); static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex); static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex); static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex); static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex); #if 1 static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex); static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex); #endif #endif /* None.proto */ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); /* None.proto */ #if CYTHON_CCOMPLEX #define __Pyx_c_eq(a, b) ((a)==(b)) #define __Pyx_c_sum(a, b) ((a)+(b)) #define __Pyx_c_diff(a, b) ((a)-(b)) #define __Pyx_c_prod(a, b) ((a)*(b)) #define __Pyx_c_quot(a, b) ((a)/(b)) #define __Pyx_c_neg(a) (-(a)) #ifdef __cplusplus #define __Pyx_c_is_zero(z) ((z)==(double)0) #define __Pyx_c_conj(z) (::std::conj(z)) #if 1 #define __Pyx_c_abs(z) (::std::abs(z)) #define __Pyx_c_pow(a, b) (::std::pow(a, b)) #endif #else #define __Pyx_c_is_zero(z) ((z)==0) #define __Pyx_c_conj(z) (conj(z)) #if 1 #define __Pyx_c_abs(z) (cabs(z)) #define __Pyx_c_pow(a, b) (cpow(a, b)) #endif #endif #else static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex); static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex); static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex); static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex); static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex); static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex); static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex); static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex); #if 1 static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex); static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex); #endif #endif /* CIntToPy.proto */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); /* CIntToPy.proto */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value); /* MemviewSliceCopyTemplate.proto */ static __Pyx_memviewslice __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, const char *mode, int ndim, size_t sizeof_dtype, int contig_flag, int dtype_is_object); /* CIntFromPy.proto */ static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); /* CIntFromPy.proto */ static CYTHON_INLINE uint32_t __Pyx_PyInt_As_uint32_t(PyObject *); /* CIntFromPy.proto */ static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *); /* CIntFromPy.proto */ static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); /* TypeInfoCompare.proto */ static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b); /* MemviewSliceValidateAndInit.proto */ static int __Pyx_ValidateAndInit_memviewslice( int *axes_specs, int c_or_f_flag, int buf_flags, int ndim, __Pyx_TypeInfo *dtype, __Pyx_BufFmt_StackElem stack[], __Pyx_memviewslice *memviewslice, PyObject *original_obj); /* ObjectToMemviewSlice.proto */ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn_uint64_t(PyObject *); /* ObjectToMemviewSlice.proto */ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn_uint32_t(PyObject *); /* CheckBinaryVersion.proto */ static int __Pyx_check_binary_version(void); /* PyIdentifierFromString.proto */ #if !defined(__Pyx_PyIdentifier_FromString) #if PY_MAJOR_VERSION < 3 #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) #else #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) #endif #endif /* ModuleImport.proto */ static PyObject *__Pyx_ImportModule(const char *name); /* TypeImport.proto */ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); /* InitStrings.proto */ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *__pyx_v_self); /* proto*/ static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/ static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/ static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/ static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/ static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/ static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/ static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/ static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/ static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/ /* Module declarations from 'cython.view' */ /* Module declarations from 'cython' */ /* Module declarations from 'libc.string' */ /* Module declarations from 'libc.stdlib' */ /* Module declarations from 'libc.stdint' */ /* Module declarations from 'cpython.buffer' */ /* Module declarations from 'libc.stdio' */ /* Module declarations from '__builtin__' */ /* Module declarations from 'cpython.type' */ static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; /* Module declarations from 'cpython' */ /* Module declarations from 'cpython.object' */ /* Module declarations from 'cpython.ref' */ /* Module declarations from 'numpy' */ /* Module declarations from 'numpy' */ static PyTypeObject *__pyx_ptype_5numpy_dtype = 0; static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0; static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0; static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0; static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0; static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/ /* Module declarations from 'lsh.cMinhash' */ static PyTypeObject *__pyx_array_type = 0; static PyTypeObject *__pyx_MemviewEnum_type = 0; static PyTypeObject *__pyx_memoryview_type = 0; static PyTypeObject *__pyx_memoryviewslice_type = 0; static PyObject *generic = 0; static PyObject *strided = 0; static PyObject *indirect = 0; static PyObject *contiguous = 0; static PyObject *indirect_contiguous = 0; static int __pyx_memoryview_thread_locks_used; static PyThread_type_lock __pyx_memoryview_thread_locks[8]; static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/ static void *__pyx_align_pointer(void *, size_t); /*proto*/ static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/ static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/ static PyObject *_unellipsify(PyObject *, int); /*proto*/ static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/ static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/ static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/ static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/ static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/ static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/ static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/ static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/ static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/ static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/ static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/ static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/ static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/ static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/ static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/ static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/ static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/ static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/ static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/ static int __pyx_memoryview_err(PyObject *, char *); /*proto*/ static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/ static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/ static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/ static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/ static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/ static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/ static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/ static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint32_t = { "uint32_t", NULL, sizeof(__pyx_t_5numpy_uint32_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint32_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint32_t), 0 }; static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t = { "uint64_t", NULL, sizeof(__pyx_t_5numpy_uint64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint64_t), 0 }; static __Pyx_TypeInfo __Pyx_TypeInfo_nn_uint64_t = { "uint64_t", NULL, sizeof(uint64_t), { 0 }, 0, IS_UNSIGNED(uint64_t) ? 'U' : 'I', IS_UNSIGNED(uint64_t), 0 }; static __Pyx_TypeInfo __Pyx_TypeInfo_nn_uint32_t = { "uint32_t", NULL, sizeof(uint32_t), { 0 }, 0, IS_UNSIGNED(uint32_t) ? 'U' : 'I', IS_UNSIGNED(uint32_t), 0 }; #define __Pyx_MODULE_NAME "lsh.cMinhash" int __pyx_module_is_main_lsh__cMinhash = 0; /* Implementation of 'lsh.cMinhash' */ static PyObject *__pyx_builtin_range; static PyObject *__pyx_builtin_ValueError; static PyObject *__pyx_builtin_RuntimeError; static PyObject *__pyx_builtin_MemoryError; static PyObject *__pyx_builtin_enumerate; static PyObject *__pyx_builtin_Ellipsis; static PyObject *__pyx_builtin_TypeError; static PyObject *__pyx_builtin_id; static PyObject *__pyx_builtin_IndexError; static const char __pyx_k_O[] = "O"; static const char __pyx_k_c[] = "c"; static const char __pyx_k_i[] = "i"; static const char __pyx_k_s[] = "s"; static const char __pyx_k_id[] = "id"; static const char __pyx_k_np[] = "np"; static const char __pyx_k_obj[] = "obj"; static const char __pyx_k_base[] = "base"; static const char __pyx_k_hash[] = "hash_"; static const char __pyx_k_main[] = "__main__"; static const char __pyx_k_mode[] = "mode"; static const char __pyx_k_name[] = "name"; static const char __pyx_k_ndim[] = "ndim"; static const char __pyx_k_pack[] = "pack"; static const char __pyx_k_size[] = "size"; static const char __pyx_k_step[] = "step"; static const char __pyx_k_stop[] = "stop"; static const char __pyx_k_test[] = "__test__"; static const char __pyx_k_ASCII[] = "ASCII"; static const char __pyx_k_c_str[] = "c_str"; static const char __pyx_k_class[] = "__class__"; static const char __pyx_k_dtype[] = "dtype"; static const char __pyx_k_error[] = "error"; static const char __pyx_k_flags[] = "flags"; static const char __pyx_k_numpy[] = "numpy"; static const char __pyx_k_range[] = "range"; static const char __pyx_k_seeds[] = "seeds"; static const char __pyx_k_shape[] = "shape"; static const char __pyx_k_start[] = "start"; static const char __pyx_k_zeros[] = "zeros"; static const char __pyx_k_author[] = "__author__"; static const char __pyx_k_encode[] = "encode"; static const char __pyx_k_format[] = "format"; static const char __pyx_k_hashes[] = "hashes"; static const char __pyx_k_import[] = "__import__"; static const char __pyx_k_name_2[] = "__name__"; static const char __pyx_k_strlen[] = "strlen"; static const char __pyx_k_struct[] = "struct"; static const char __pyx_k_uint32[] = "uint32"; static const char __pyx_k_uint64[] = "uint64"; static const char __pyx_k_unpack[] = "unpack"; static const char __pyx_k_fortran[] = "fortran"; static const char __pyx_k_memview[] = "memview"; static const char __pyx_k_minhash[] = "minhash"; static const char __pyx_k_Ellipsis[] = "Ellipsis"; static const char __pyx_k_itemsize[] = "itemsize"; static const char __pyx_k_mem_view[] = "mem_view"; static const char __pyx_k_INT32_MAX[] = "INT32_MAX"; static const char __pyx_k_INT64_MAX[] = "INT64_MAX"; static const char __pyx_k_TypeError[] = "TypeError"; static const char __pyx_k_enumerate[] = "enumerate"; static const char __pyx_k_num_seeds[] = "num_seeds"; static const char __pyx_k_IndexError[] = "IndexError"; static const char __pyx_k_Matti_Lyra[] = "Matti Lyra"; static const char __pyx_k_ValueError[] = "ValueError"; static const char __pyx_k_char_ngram[] = "char_ngram"; static const char __pyx_k_minhash_32[] = "minhash_32"; static const char __pyx_k_minhash_64[] = "minhash_64"; static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; static const char __pyx_k_MemoryError[] = "MemoryError"; static const char __pyx_k_fingerprint[] = "fingerprint"; static const char __pyx_k_RuntimeError[] = "RuntimeError"; static const char __pyx_k_lsh_cMinhash[] = "lsh.cMinhash"; static const char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer"; static const char __pyx_k_allocate_buffer[] = "allocate_buffer"; static const char __pyx_k_dtype_is_object[] = "dtype_is_object"; static const char __pyx_k_strided_and_direct[] = ""; static const char __pyx_k_strided_and_indirect[] = ""; static const char __pyx_k_contiguous_and_direct[] = ""; static const char __pyx_k_MemoryView_of_r_object[] = ""; static const char __pyx_k_MemoryView_of_r_at_0x_x[] = ""; static const char __pyx_k_contiguous_and_indirect[] = ""; static const char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'"; static const char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d."; static const char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array"; static const char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous"; static const char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data."; static const char __pyx_k_strided_and_direct_or_indirect[] = ""; static const char __pyx_k_Users_miro_projects_LSH_lsh_cMi[] = "/Users/miro/projects/LSH/lsh/cMinhash.pyx"; static const char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)"; static const char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides"; static const char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory."; static const char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array"; static const char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd"; static const char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported"; static const char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s"; static const char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported"; static const char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)"; static const char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object"; static const char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)"; static const char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous"; static const char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides."; static const char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short."; static PyObject *__pyx_n_s_ASCII; static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri; static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is; static PyObject *__pyx_kp_s_Cannot_index_with_type_s; static PyObject *__pyx_n_s_Ellipsis; static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr; static PyObject *__pyx_kp_u_Format_string_allocated_too_shor; static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2; static PyObject *__pyx_n_s_INT32_MAX; static PyObject *__pyx_n_s_INT64_MAX; static PyObject *__pyx_n_s_IndexError; static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte; static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr; static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d; static PyObject *__pyx_kp_s_Matti_Lyra; static PyObject *__pyx_n_s_MemoryError; static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x; static PyObject *__pyx_kp_s_MemoryView_of_r_object; static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor; static PyObject *__pyx_n_b_O; static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a; static PyObject *__pyx_n_s_RuntimeError; static PyObject *__pyx_n_s_TypeError; static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object; static PyObject *__pyx_kp_s_Users_miro_projects_LSH_lsh_cMi; static PyObject *__pyx_n_s_ValueError; static PyObject *__pyx_n_s_allocate_buffer; static PyObject *__pyx_n_s_author; static PyObject *__pyx_n_s_base; static PyObject *__pyx_n_s_c; static PyObject *__pyx_n_u_c; static PyObject *__pyx_n_s_c_str; static PyObject *__pyx_n_s_char_ngram; static PyObject *__pyx_n_s_class; static PyObject *__pyx_kp_s_contiguous_and_direct; static PyObject *__pyx_kp_s_contiguous_and_indirect; static PyObject *__pyx_n_s_dtype; static PyObject *__pyx_n_s_dtype_is_object; static PyObject *__pyx_n_s_encode; static PyObject *__pyx_n_s_enumerate; static PyObject *__pyx_n_s_error; static PyObject *__pyx_n_s_fingerprint; static PyObject *__pyx_n_s_flags; static PyObject *__pyx_n_s_format; static PyObject *__pyx_n_s_fortran; static PyObject *__pyx_n_u_fortran; static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi; static PyObject *__pyx_n_s_hash; static PyObject *__pyx_n_s_hashes; static PyObject *__pyx_n_s_i; static PyObject *__pyx_n_s_id; static PyObject *__pyx_n_s_import; static PyObject *__pyx_n_s_itemsize; static PyObject *__pyx_kp_s_itemsize_0_for_cython_array; static PyObject *__pyx_n_s_lsh_cMinhash; static PyObject *__pyx_n_s_main; static PyObject *__pyx_n_s_mem_view; static PyObject *__pyx_n_s_memview; static PyObject *__pyx_n_s_minhash; static PyObject *__pyx_n_s_minhash_32; static PyObject *__pyx_n_s_minhash_64; static PyObject *__pyx_n_s_mode; static PyObject *__pyx_n_s_name; static PyObject *__pyx_n_s_name_2; static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous; static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou; static PyObject *__pyx_n_s_ndim; static PyObject *__pyx_n_s_np; static PyObject *__pyx_n_s_num_seeds; static PyObject *__pyx_n_s_numpy; static PyObject *__pyx_n_s_obj; static PyObject *__pyx_n_s_pack; static PyObject *__pyx_n_s_pyx_getbuffer; static PyObject *__pyx_n_s_pyx_vtable; static PyObject *__pyx_n_s_range; static PyObject *__pyx_n_s_s; static PyObject *__pyx_n_s_seeds; static PyObject *__pyx_n_s_shape; static PyObject *__pyx_n_s_size; static PyObject *__pyx_n_s_start; static PyObject *__pyx_n_s_step; static PyObject *__pyx_n_s_stop; static PyObject *__pyx_kp_s_strided_and_direct; static PyObject *__pyx_kp_s_strided_and_direct_or_indirect; static PyObject *__pyx_kp_s_strided_and_indirect; static PyObject *__pyx_n_s_strlen; static PyObject *__pyx_n_s_struct; static PyObject *__pyx_n_s_test; static PyObject *__pyx_n_s_uint32; static PyObject *__pyx_n_s_uint64; static PyObject *__pyx_kp_s_unable_to_allocate_array_data; static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str; static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; static PyObject *__pyx_n_s_unpack; static PyObject *__pyx_n_s_zeros; static PyObject *__pyx_pf_3lsh_8cMinhash_minhash_64(CYTHON_UNUSED PyObject *__pyx_self, char *__pyx_v_c_str, int __pyx_v_strlen, PyArrayObject *__pyx_v_seeds, int __pyx_v_char_ngram); /* proto */ static PyObject *__pyx_pf_3lsh_8cMinhash_2minhash_32(CYTHON_UNUSED PyObject *__pyx_self, char *__pyx_v_c_str, int __pyx_v_strlen, PyArrayObject *__pyx_v_seeds, int __pyx_v_char_ngram); /* proto */ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */ static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */ static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ static void __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */ static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */ static int __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */ static PyObject *__pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */ static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */ static void __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */ static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */ static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static Py_ssize_t __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */ static void __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_pf_15View_dot_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */ static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_int_0; static PyObject *__pyx_int_1; static PyObject *__pyx_int_neg_1; static PyObject *__pyx_tuple_; static PyObject *__pyx_tuple__2; static PyObject *__pyx_tuple__3; static PyObject *__pyx_tuple__4; static PyObject *__pyx_tuple__5; static PyObject *__pyx_tuple__6; static PyObject *__pyx_tuple__7; static PyObject *__pyx_tuple__8; static PyObject *__pyx_tuple__9; static PyObject *__pyx_slice__16; static PyObject *__pyx_slice__17; static PyObject *__pyx_slice__18; static PyObject *__pyx_tuple__10; static PyObject *__pyx_tuple__11; static PyObject *__pyx_tuple__12; static PyObject *__pyx_tuple__13; static PyObject *__pyx_tuple__14; static PyObject *__pyx_tuple__15; static PyObject *__pyx_tuple__19; static PyObject *__pyx_tuple__20; static PyObject *__pyx_tuple__22; static PyObject *__pyx_tuple__24; static PyObject *__pyx_tuple__25; static PyObject *__pyx_tuple__26; static PyObject *__pyx_tuple__27; static PyObject *__pyx_tuple__28; static PyObject *__pyx_codeobj__21; static PyObject *__pyx_codeobj__23; /* "lsh/cMinhash.pyx":21 * * @cython.boundscheck(False) # turn of bounds-checking for entire function * def minhash_64(char* c_str, int strlen, # <<<<<<<<<<<<<< * np.ndarray[dtype=np.uint32_t, ndim=1] seeds not None, * int char_ngram): */ /* Python wrapper */ static PyObject *__pyx_pw_3lsh_8cMinhash_1minhash_64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_3lsh_8cMinhash_minhash_64[] = "Perform shingling and compute minhash of each shingle.\n\n Creates `char_ngram` length shingles from input string `c_str` and computes\n `len(seeds)` number 128bit min hashes for each shingle. A shingle is a\n character ngram of length `char_ngram`, consecutive shingles are taken over\n a sliding window.\n "; static PyMethodDef __pyx_mdef_3lsh_8cMinhash_1minhash_64 = {"minhash_64", (PyCFunction)__pyx_pw_3lsh_8cMinhash_1minhash_64, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3lsh_8cMinhash_minhash_64}; static PyObject *__pyx_pw_3lsh_8cMinhash_1minhash_64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { char *__pyx_v_c_str; int __pyx_v_strlen; PyArrayObject *__pyx_v_seeds = 0; int __pyx_v_char_ngram; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("minhash_64 (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_c_str,&__pyx_n_s_strlen,&__pyx_n_s_seeds,&__pyx_n_s_char_ngram,0}; PyObject* values[4] = {0,0,0,0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_c_str)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_strlen)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("minhash_64", 1, 4, 4, 1); __PYX_ERR(0, 21, __pyx_L3_error) } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_seeds)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("minhash_64", 1, 4, 4, 2); __PYX_ERR(0, 21, __pyx_L3_error) } case 3: if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_char_ngram)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("minhash_64", 1, 4, 4, 3); __PYX_ERR(0, 21, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minhash_64") < 0)) __PYX_ERR(0, 21, __pyx_L3_error) } } else if (PyTuple_GET_SIZE(__pyx_args) != 4) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); values[1] = PyTuple_GET_ITEM(__pyx_args, 1); values[2] = PyTuple_GET_ITEM(__pyx_args, 2); values[3] = PyTuple_GET_ITEM(__pyx_args, 3); } __pyx_v_c_str = __Pyx_PyObject_AsString(values[0]); if (unlikely((!__pyx_v_c_str) && PyErr_Occurred())) __PYX_ERR(0, 21, __pyx_L3_error) __pyx_v_strlen = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_strlen == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 21, __pyx_L3_error) __pyx_v_seeds = ((PyArrayObject *)values[2]); __pyx_v_char_ngram = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_char_ngram == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 23, __pyx_L3_error) } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("minhash_64", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 21, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("lsh.cMinhash.minhash_64", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_seeds), __pyx_ptype_5numpy_ndarray, 0, "seeds", 0))) __PYX_ERR(0, 22, __pyx_L1_error) __pyx_r = __pyx_pf_3lsh_8cMinhash_minhash_64(__pyx_self, __pyx_v_c_str, __pyx_v_strlen, __pyx_v_seeds, __pyx_v_char_ngram); /* function exit code */ goto __pyx_L0; __pyx_L1_error:; __pyx_r = NULL; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_3lsh_8cMinhash_minhash_64(CYTHON_UNUSED PyObject *__pyx_self, char *__pyx_v_c_str, int __pyx_v_strlen, PyArrayObject *__pyx_v_seeds, int __pyx_v_char_ngram) { uint32_t __pyx_v_num_seeds; PyArrayObject *__pyx_v_fingerprint = 0; uint64_t __pyx_v_INT64_MAX; uint64_t __pyx_v_hashes[2]; uint64_t __pyx_v_minhash; __Pyx_memviewslice __pyx_v_mem_view = { 0, 0, { 0 }, { 0 }, { 0 } }; CYTHON_UNUSED uint32_t __pyx_v_i; uint32_t __pyx_v_s; __Pyx_LocalBuf_ND __pyx_pybuffernd_fingerprint; __Pyx_Buffer __pyx_pybuffer_fingerprint; __Pyx_LocalBuf_ND __pyx_pybuffernd_seeds; __Pyx_Buffer __pyx_pybuffer_seeds; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations Py_ssize_t __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; PyArrayObject *__pyx_t_7 = NULL; __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } }; uint32_t __pyx_t_9; uint32_t __pyx_t_10; long __pyx_t_11; uint32_t __pyx_t_12; size_t __pyx_t_13; int __pyx_t_14; size_t __pyx_t_15; __Pyx_RefNannySetupContext("minhash_64", 0); __pyx_pybuffer_fingerprint.pybuffer.buf = NULL; __pyx_pybuffer_fingerprint.refcount = 0; __pyx_pybuffernd_fingerprint.data = NULL; __pyx_pybuffernd_fingerprint.rcbuffer = &__pyx_pybuffer_fingerprint; __pyx_pybuffer_seeds.pybuffer.buf = NULL; __pyx_pybuffer_seeds.refcount = 0; __pyx_pybuffernd_seeds.data = NULL; __pyx_pybuffernd_seeds.rcbuffer = &__pyx_pybuffer_seeds; { __Pyx_BufFmt_StackElem __pyx_stack[1]; if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_seeds.rcbuffer->pybuffer, (PyObject*)__pyx_v_seeds, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 21, __pyx_L1_error) } __pyx_pybuffernd_seeds.diminfo[0].strides = __pyx_pybuffernd_seeds.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_seeds.diminfo[0].shape = __pyx_pybuffernd_seeds.rcbuffer->pybuffer.shape[0]; /* "lsh/cMinhash.pyx":31 * a sliding window. * """ * cdef uint32_t num_seeds = len(seeds) # <<<<<<<<<<<<<< * cdef np.ndarray[np.uint64_t, ndim=1] fingerprint = \ * np.zeros((num_seeds, ), dtype=np.uint64) */ __pyx_t_1 = PyObject_Length(((PyObject *)__pyx_v_seeds)); if (unlikely(__pyx_t_1 == -1)) __PYX_ERR(0, 31, __pyx_L1_error) __pyx_v_num_seeds = __pyx_t_1; /* "lsh/cMinhash.pyx":33 * cdef uint32_t num_seeds = len(seeds) * cdef np.ndarray[np.uint64_t, ndim=1] fingerprint = \ * np.zeros((num_seeds, ), dtype=np.uint64) # <<<<<<<<<<<<<< * * cdef uint64_t INT64_MAX = 9223372036854775807 */ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = __Pyx_PyInt_From_uint32_t(__pyx_v_num_seeds); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_uint64); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_6) < 0) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 33, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 33, __pyx_L1_error) __pyx_t_7 = ((PyArrayObject *)__pyx_t_6); { __Pyx_BufFmt_StackElem __pyx_stack[1]; if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_fingerprint.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) { __pyx_v_fingerprint = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_fingerprint.rcbuffer->pybuffer.buf = NULL; __PYX_ERR(0, 32, __pyx_L1_error) } else {__pyx_pybuffernd_fingerprint.diminfo[0].strides = __pyx_pybuffernd_fingerprint.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_fingerprint.diminfo[0].shape = __pyx_pybuffernd_fingerprint.rcbuffer->pybuffer.shape[0]; } } __pyx_t_7 = 0; __pyx_v_fingerprint = ((PyArrayObject *)__pyx_t_6); __pyx_t_6 = 0; /* "lsh/cMinhash.pyx":35 * np.zeros((num_seeds, ), dtype=np.uint64) * * cdef uint64_t INT64_MAX = 9223372036854775807 # <<<<<<<<<<<<<< * cdef uint64_t hashes[2] * cdef uint64_t minhash */ __pyx_v_INT64_MAX = 0x7FFFFFFFFFFFFFFF; /* "lsh/cMinhash.pyx":40 * * # memory view to the numpy array - this should be free of any python * cdef uint64_t [:] mem_view = fingerprint # <<<<<<<<<<<<<< * cdef uint32_t i, s * with nogil: */ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn_uint64_t(((PyObject *)__pyx_v_fingerprint)); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 40, __pyx_L1_error) __pyx_v_mem_view = __pyx_t_8; __pyx_t_8.memview = NULL; __pyx_t_8.data = NULL; /* "lsh/cMinhash.pyx":42 * cdef uint64_t [:] mem_view = fingerprint * cdef uint32_t i, s * with nogil: # <<<<<<<<<<<<<< * for s in range(num_seeds): * minhash = INT64_MAX */ { #ifdef WITH_THREAD PyThreadState *_save; Py_UNBLOCK_THREADS #endif /*try:*/ { /* "lsh/cMinhash.pyx":43 * cdef uint32_t i, s * with nogil: * for s in range(num_seeds): # <<<<<<<<<<<<<< * minhash = INT64_MAX * for i in range(strlen - char_ngram + 1): */ __pyx_t_9 = __pyx_v_num_seeds; for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { __pyx_v_s = __pyx_t_10; /* "lsh/cMinhash.pyx":44 * with nogil: * for s in range(num_seeds): * minhash = INT64_MAX # <<<<<<<<<<<<<< * for i in range(strlen - char_ngram + 1): * MurmurHash3_x64_128(c_str, char_ngram, seeds[s], hashes) */ __pyx_v_minhash = __pyx_v_INT64_MAX; /* "lsh/cMinhash.pyx":45 * for s in range(num_seeds): * minhash = INT64_MAX * for i in range(strlen - char_ngram + 1): # <<<<<<<<<<<<<< * MurmurHash3_x64_128(c_str, char_ngram, seeds[s], hashes) * if hashes[0] < minhash: */ __pyx_t_11 = ((__pyx_v_strlen - __pyx_v_char_ngram) + 1); for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) { __pyx_v_i = __pyx_t_12; /* "lsh/cMinhash.pyx":46 * minhash = INT64_MAX * for i in range(strlen - char_ngram + 1): * MurmurHash3_x64_128(c_str, char_ngram, seeds[s], hashes) # <<<<<<<<<<<<<< * if hashes[0] < minhash: * minhash = hashes[0] */ __pyx_t_13 = __pyx_v_s; MurmurHash3_x64_128(__pyx_v_c_str, __pyx_v_char_ngram, (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint32_t *, __pyx_pybuffernd_seeds.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_seeds.diminfo[0].strides)), __pyx_v_hashes); /* "lsh/cMinhash.pyx":47 * for i in range(strlen - char_ngram + 1): * MurmurHash3_x64_128(c_str, char_ngram, seeds[s], hashes) * if hashes[0] < minhash: # <<<<<<<<<<<<<< * minhash = hashes[0] * c_str += 1 */ __pyx_t_14 = (((__pyx_v_hashes[0]) < __pyx_v_minhash) != 0); if (__pyx_t_14) { /* "lsh/cMinhash.pyx":48 * MurmurHash3_x64_128(c_str, char_ngram, seeds[s], hashes) * if hashes[0] < minhash: * minhash = hashes[0] # <<<<<<<<<<<<<< * c_str += 1 * */ __pyx_v_minhash = (__pyx_v_hashes[0]); /* "lsh/cMinhash.pyx":47 * for i in range(strlen - char_ngram + 1): * MurmurHash3_x64_128(c_str, char_ngram, seeds[s], hashes) * if hashes[0] < minhash: # <<<<<<<<<<<<<< * minhash = hashes[0] * c_str += 1 */ } /* "lsh/cMinhash.pyx":49 * if hashes[0] < minhash: * minhash = hashes[0] * c_str += 1 # <<<<<<<<<<<<<< * * # store the current minhash */ __pyx_v_c_str = (__pyx_v_c_str + 1); } /* "lsh/cMinhash.pyx":52 * * # store the current minhash * mem_view[s] = minhash # <<<<<<<<<<<<<< * * # reset string pointer for next hash */ __pyx_t_15 = __pyx_v_s; *((uint64_t *) ( /* dim=0 */ (__pyx_v_mem_view.data + __pyx_t_15 * __pyx_v_mem_view.strides[0]) )) = __pyx_v_minhash; /* "lsh/cMinhash.pyx":55 * * # reset string pointer for next hash * c_str -= strlen - char_ngram + 1 # <<<<<<<<<<<<<< * return fingerprint * */ __pyx_v_c_str = (__pyx_v_c_str - ((__pyx_v_strlen - __pyx_v_char_ngram) + 1)); } } /* "lsh/cMinhash.pyx":42 * cdef uint64_t [:] mem_view = fingerprint * cdef uint32_t i, s * with nogil: # <<<<<<<<<<<<<< * for s in range(num_seeds): * minhash = INT64_MAX */ /*finally:*/ { /*normal exit:*/{ #ifdef WITH_THREAD Py_BLOCK_THREADS #endif goto __pyx_L5; } __pyx_L5:; } } /* "lsh/cMinhash.pyx":56 * # reset string pointer for next hash * c_str -= strlen - char_ngram + 1 * return fingerprint # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_fingerprint)); __pyx_r = ((PyObject *)__pyx_v_fingerprint); goto __pyx_L0; /* "lsh/cMinhash.pyx":21 * * @cython.boundscheck(False) # turn of bounds-checking for entire function * def minhash_64(char* c_str, int strlen, # <<<<<<<<<<<<<< * np.ndarray[dtype=np.uint32_t, ndim=1] seeds not None, * int char_ngram): */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1); { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; __Pyx_PyThreadState_declare __Pyx_PyThreadState_assign __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_fingerprint.rcbuffer->pybuffer); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_seeds.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} __Pyx_AddTraceback("lsh.cMinhash.minhash_64", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; goto __pyx_L2; __pyx_L0:; __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_fingerprint.rcbuffer->pybuffer); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_seeds.rcbuffer->pybuffer); __pyx_L2:; __Pyx_XDECREF((PyObject *)__pyx_v_fingerprint); __PYX_XDEC_MEMVIEW(&__pyx_v_mem_view, 1); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "lsh/cMinhash.pyx":60 * * @cython.boundscheck(False) # turn of bounds-checking for entire function * def minhash_32(char* c_str, int strlen, # <<<<<<<<<<<<<< * np.ndarray[dtype=np.uint32_t, ndim=1] seeds not None, * int char_ngram): */ /* Python wrapper */ static PyObject *__pyx_pw_3lsh_8cMinhash_3minhash_32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static char __pyx_doc_3lsh_8cMinhash_2minhash_32[] = "Perform shingling and compute minhash of each shingle.\n\n Creates `char_ngram` length shingles from input string `c_str` and computes\n `len(seeds)` number 128bit min hashes for each shingle. A shingle is a\n character ngram of length `char_ngram`, consecutive shingles are taken over\n a sliding window.\n "; static PyMethodDef __pyx_mdef_3lsh_8cMinhash_3minhash_32 = {"minhash_32", (PyCFunction)__pyx_pw_3lsh_8cMinhash_3minhash_32, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3lsh_8cMinhash_2minhash_32}; static PyObject *__pyx_pw_3lsh_8cMinhash_3minhash_32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { char *__pyx_v_c_str; int __pyx_v_strlen; PyArrayObject *__pyx_v_seeds = 0; int __pyx_v_char_ngram; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("minhash_32 (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_c_str,&__pyx_n_s_strlen,&__pyx_n_s_seeds,&__pyx_n_s_char_ngram,0}; PyObject* values[4] = {0,0,0,0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_c_str)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_strlen)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("minhash_32", 1, 4, 4, 1); __PYX_ERR(0, 60, __pyx_L3_error) } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_seeds)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("minhash_32", 1, 4, 4, 2); __PYX_ERR(0, 60, __pyx_L3_error) } case 3: if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_char_ngram)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("minhash_32", 1, 4, 4, 3); __PYX_ERR(0, 60, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "minhash_32") < 0)) __PYX_ERR(0, 60, __pyx_L3_error) } } else if (PyTuple_GET_SIZE(__pyx_args) != 4) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); values[1] = PyTuple_GET_ITEM(__pyx_args, 1); values[2] = PyTuple_GET_ITEM(__pyx_args, 2); values[3] = PyTuple_GET_ITEM(__pyx_args, 3); } __pyx_v_c_str = __Pyx_PyObject_AsString(values[0]); if (unlikely((!__pyx_v_c_str) && PyErr_Occurred())) __PYX_ERR(0, 60, __pyx_L3_error) __pyx_v_strlen = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_strlen == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 60, __pyx_L3_error) __pyx_v_seeds = ((PyArrayObject *)values[2]); __pyx_v_char_ngram = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_char_ngram == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 62, __pyx_L3_error) } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("minhash_32", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 60, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("lsh.cMinhash.minhash_32", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_seeds), __pyx_ptype_5numpy_ndarray, 0, "seeds", 0))) __PYX_ERR(0, 61, __pyx_L1_error) __pyx_r = __pyx_pf_3lsh_8cMinhash_2minhash_32(__pyx_self, __pyx_v_c_str, __pyx_v_strlen, __pyx_v_seeds, __pyx_v_char_ngram); /* function exit code */ goto __pyx_L0; __pyx_L1_error:; __pyx_r = NULL; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_3lsh_8cMinhash_2minhash_32(CYTHON_UNUSED PyObject *__pyx_self, char *__pyx_v_c_str, int __pyx_v_strlen, PyArrayObject *__pyx_v_seeds, int __pyx_v_char_ngram) { uint32_t __pyx_v_num_seeds; PyArrayObject *__pyx_v_fingerprint = 0; int32_t __pyx_v_INT32_MAX; int32_t __pyx_v_hash_[1]; int32_t __pyx_v_minhash; __Pyx_memviewslice __pyx_v_mem_view = { 0, 0, { 0 }, { 0 }, { 0 } }; CYTHON_UNUSED uint32_t __pyx_v_i; uint32_t __pyx_v_s; __Pyx_LocalBuf_ND __pyx_pybuffernd_fingerprint; __Pyx_Buffer __pyx_pybuffer_fingerprint; __Pyx_LocalBuf_ND __pyx_pybuffernd_seeds; __Pyx_Buffer __pyx_pybuffer_seeds; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations Py_ssize_t __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; PyArrayObject *__pyx_t_7 = NULL; __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } }; uint32_t __pyx_t_9; uint32_t __pyx_t_10; long __pyx_t_11; uint32_t __pyx_t_12; size_t __pyx_t_13; int __pyx_t_14; size_t __pyx_t_15; __Pyx_RefNannySetupContext("minhash_32", 0); __pyx_pybuffer_fingerprint.pybuffer.buf = NULL; __pyx_pybuffer_fingerprint.refcount = 0; __pyx_pybuffernd_fingerprint.data = NULL; __pyx_pybuffernd_fingerprint.rcbuffer = &__pyx_pybuffer_fingerprint; __pyx_pybuffer_seeds.pybuffer.buf = NULL; __pyx_pybuffer_seeds.refcount = 0; __pyx_pybuffernd_seeds.data = NULL; __pyx_pybuffernd_seeds.rcbuffer = &__pyx_pybuffer_seeds; { __Pyx_BufFmt_StackElem __pyx_stack[1]; if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_seeds.rcbuffer->pybuffer, (PyObject*)__pyx_v_seeds, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 60, __pyx_L1_error) } __pyx_pybuffernd_seeds.diminfo[0].strides = __pyx_pybuffernd_seeds.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_seeds.diminfo[0].shape = __pyx_pybuffernd_seeds.rcbuffer->pybuffer.shape[0]; /* "lsh/cMinhash.pyx":70 * a sliding window. * """ * cdef uint32_t num_seeds = len(seeds) # <<<<<<<<<<<<<< * cdef np.ndarray[np.uint32_t, ndim=1] fingerprint = \ * np.zeros((num_seeds, ), dtype=np.uint32) */ __pyx_t_1 = PyObject_Length(((PyObject *)__pyx_v_seeds)); if (unlikely(__pyx_t_1 == -1)) __PYX_ERR(0, 70, __pyx_L1_error) __pyx_v_num_seeds = __pyx_t_1; /* "lsh/cMinhash.pyx":72 * cdef uint32_t num_seeds = len(seeds) * cdef np.ndarray[np.uint32_t, ndim=1] fingerprint = \ * np.zeros((num_seeds, ), dtype=np.uint32) # <<<<<<<<<<<<<< * * cdef int32_t INT32_MAX = 4294967295 */ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = __Pyx_PyInt_From_uint32_t(__pyx_v_num_seeds); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_uint32); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_6) < 0) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 72, __pyx_L1_error) __pyx_t_7 = ((PyArrayObject *)__pyx_t_6); { __Pyx_BufFmt_StackElem __pyx_stack[1]; if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_fingerprint.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) { __pyx_v_fingerprint = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_fingerprint.rcbuffer->pybuffer.buf = NULL; __PYX_ERR(0, 71, __pyx_L1_error) } else {__pyx_pybuffernd_fingerprint.diminfo[0].strides = __pyx_pybuffernd_fingerprint.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_fingerprint.diminfo[0].shape = __pyx_pybuffernd_fingerprint.rcbuffer->pybuffer.shape[0]; } } __pyx_t_7 = 0; __pyx_v_fingerprint = ((PyArrayObject *)__pyx_t_6); __pyx_t_6 = 0; /* "lsh/cMinhash.pyx":74 * np.zeros((num_seeds, ), dtype=np.uint32) * * cdef int32_t INT32_MAX = 4294967295 # <<<<<<<<<<<<<< * cdef int32_t hash_[1] * cdef int32_t minhash */ __pyx_v_INT32_MAX = 0xFFFFFFFF; /* "lsh/cMinhash.pyx":79 * * # memory view to the numpy array - this should be free of any python * cdef uint32_t [:] mem_view = fingerprint # <<<<<<<<<<<<<< * cdef uint32_t i, s * with nogil: */ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn_uint32_t(((PyObject *)__pyx_v_fingerprint)); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 79, __pyx_L1_error) __pyx_v_mem_view = __pyx_t_8; __pyx_t_8.memview = NULL; __pyx_t_8.data = NULL; /* "lsh/cMinhash.pyx":81 * cdef uint32_t [:] mem_view = fingerprint * cdef uint32_t i, s * with nogil: # <<<<<<<<<<<<<< * for s in range(num_seeds): * minhash = INT32_MAX */ { #ifdef WITH_THREAD PyThreadState *_save; Py_UNBLOCK_THREADS #endif /*try:*/ { /* "lsh/cMinhash.pyx":82 * cdef uint32_t i, s * with nogil: * for s in range(num_seeds): # <<<<<<<<<<<<<< * minhash = INT32_MAX * for i in range(strlen - char_ngram + 1): */ __pyx_t_9 = __pyx_v_num_seeds; for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { __pyx_v_s = __pyx_t_10; /* "lsh/cMinhash.pyx":83 * with nogil: * for s in range(num_seeds): * minhash = INT32_MAX # <<<<<<<<<<<<<< * for i in range(strlen - char_ngram + 1): * MurmurHash3_x86_32(c_str, char_ngram, seeds[s], hash_) */ __pyx_v_minhash = __pyx_v_INT32_MAX; /* "lsh/cMinhash.pyx":84 * for s in range(num_seeds): * minhash = INT32_MAX * for i in range(strlen - char_ngram + 1): # <<<<<<<<<<<<<< * MurmurHash3_x86_32(c_str, char_ngram, seeds[s], hash_) * if hash_[0] < minhash: */ __pyx_t_11 = ((__pyx_v_strlen - __pyx_v_char_ngram) + 1); for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) { __pyx_v_i = __pyx_t_12; /* "lsh/cMinhash.pyx":85 * minhash = INT32_MAX * for i in range(strlen - char_ngram + 1): * MurmurHash3_x86_32(c_str, char_ngram, seeds[s], hash_) # <<<<<<<<<<<<<< * if hash_[0] < minhash: * minhash = hash_[0] */ __pyx_t_13 = __pyx_v_s; MurmurHash3_x86_32(__pyx_v_c_str, __pyx_v_char_ngram, (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint32_t *, __pyx_pybuffernd_seeds.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_seeds.diminfo[0].strides)), __pyx_v_hash_); /* "lsh/cMinhash.pyx":86 * for i in range(strlen - char_ngram + 1): * MurmurHash3_x86_32(c_str, char_ngram, seeds[s], hash_) * if hash_[0] < minhash: # <<<<<<<<<<<<<< * minhash = hash_[0] * c_str += 1 */ __pyx_t_14 = (((__pyx_v_hash_[0]) < __pyx_v_minhash) != 0); if (__pyx_t_14) { /* "lsh/cMinhash.pyx":87 * MurmurHash3_x86_32(c_str, char_ngram, seeds[s], hash_) * if hash_[0] < minhash: * minhash = hash_[0] # <<<<<<<<<<<<<< * c_str += 1 * */ __pyx_v_minhash = (__pyx_v_hash_[0]); /* "lsh/cMinhash.pyx":86 * for i in range(strlen - char_ngram + 1): * MurmurHash3_x86_32(c_str, char_ngram, seeds[s], hash_) * if hash_[0] < minhash: # <<<<<<<<<<<<<< * minhash = hash_[0] * c_str += 1 */ } /* "lsh/cMinhash.pyx":88 * if hash_[0] < minhash: * minhash = hash_[0] * c_str += 1 # <<<<<<<<<<<<<< * * # store the current minhash */ __pyx_v_c_str = (__pyx_v_c_str + 1); } /* "lsh/cMinhash.pyx":91 * * # store the current minhash * mem_view[s] = minhash # <<<<<<<<<<<<<< * * # reset string pointer for next hash */ __pyx_t_15 = __pyx_v_s; *((uint32_t *) ( /* dim=0 */ (__pyx_v_mem_view.data + __pyx_t_15 * __pyx_v_mem_view.strides[0]) )) = __pyx_v_minhash; /* "lsh/cMinhash.pyx":94 * * # reset string pointer for next hash * c_str -= strlen - char_ngram + 1 # <<<<<<<<<<<<<< * return fingerprint */ __pyx_v_c_str = (__pyx_v_c_str - ((__pyx_v_strlen - __pyx_v_char_ngram) + 1)); } } /* "lsh/cMinhash.pyx":81 * cdef uint32_t [:] mem_view = fingerprint * cdef uint32_t i, s * with nogil: # <<<<<<<<<<<<<< * for s in range(num_seeds): * minhash = INT32_MAX */ /*finally:*/ { /*normal exit:*/{ #ifdef WITH_THREAD Py_BLOCK_THREADS #endif goto __pyx_L5; } __pyx_L5:; } } /* "lsh/cMinhash.pyx":95 * # reset string pointer for next hash * c_str -= strlen - char_ngram + 1 * return fingerprint # <<<<<<<<<<<<<< */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_fingerprint)); __pyx_r = ((PyObject *)__pyx_v_fingerprint); goto __pyx_L0; /* "lsh/cMinhash.pyx":60 * * @cython.boundscheck(False) # turn of bounds-checking for entire function * def minhash_32(char* c_str, int strlen, # <<<<<<<<<<<<<< * np.ndarray[dtype=np.uint32_t, ndim=1] seeds not None, * int char_ngram): */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1); { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; __Pyx_PyThreadState_declare __Pyx_PyThreadState_assign __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_fingerprint.rcbuffer->pybuffer); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_seeds.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} __Pyx_AddTraceback("lsh.cMinhash.minhash_32", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; goto __pyx_L2; __pyx_L0:; __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_fingerprint.rcbuffer->pybuffer); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_seeds.rcbuffer->pybuffer); __pyx_L2:; __Pyx_XDECREF((PyObject *)__pyx_v_fingerprint); __PYX_XDEC_MEMVIEW(&__pyx_v_mem_view, 1); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":197 * # experimental exception made for __getbuffer__ and __releasebuffer__ * # -- the details of this may change. * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< * # This implementation of getbuffer is geared towards Cython * # requirements, and does not yet fullfill the PEP. */ /* Python wrapper */ static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { int __pyx_v_copy_shape; int __pyx_v_i; int __pyx_v_ndim; int __pyx_v_endian_detector; int __pyx_v_little_endian; int __pyx_v_t; char *__pyx_v_f; PyArray_Descr *__pyx_v_descr = 0; int __pyx_v_offset; int __pyx_v_hasfields; int __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; int __pyx_t_5; PyObject *__pyx_t_6 = NULL; char *__pyx_t_7; __Pyx_RefNannySetupContext("__getbuffer__", 0); if (__pyx_v_info != NULL) { __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); __Pyx_GIVEREF(__pyx_v_info->obj); } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":203 * # of flags * * if info == NULL: return # <<<<<<<<<<<<<< * * cdef int copy_shape, i, ndim */ __pyx_t_1 = ((__pyx_v_info == NULL) != 0); if (__pyx_t_1) { __pyx_r = 0; goto __pyx_L0; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":206 * * cdef int copy_shape, i, ndim * cdef int endian_detector = 1 # <<<<<<<<<<<<<< * cdef bint little_endian = ((&endian_detector)[0] != 0) * */ __pyx_v_endian_detector = 1; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":207 * cdef int copy_shape, i, ndim * cdef int endian_detector = 1 * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< * * ndim = PyArray_NDIM(self) */ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":209 * cdef bint little_endian = ((&endian_detector)[0] != 0) * * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<< * * if sizeof(npy_intp) != sizeof(Py_ssize_t): */ __pyx_v_ndim = PyArray_NDIM(__pyx_v_self); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":211 * ndim = PyArray_NDIM(self) * * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< * copy_shape = 1 * else: */ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); if (__pyx_t_1) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":212 * * if sizeof(npy_intp) != sizeof(Py_ssize_t): * copy_shape = 1 # <<<<<<<<<<<<<< * else: * copy_shape = 0 */ __pyx_v_copy_shape = 1; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":211 * ndim = PyArray_NDIM(self) * * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< * copy_shape = 1 * else: */ goto __pyx_L4; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":214 * copy_shape = 1 * else: * copy_shape = 0 # <<<<<<<<<<<<<< * * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) */ /*else*/ { __pyx_v_copy_shape = 0; } __pyx_L4:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":216 * copy_shape = 0 * * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): * raise ValueError(u"ndarray is not C contiguous") */ __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0); if (__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L6_bool_binop_done; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":217 * * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<< * raise ValueError(u"ndarray is not C contiguous") * */ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0); __pyx_t_1 = __pyx_t_2; __pyx_L6_bool_binop_done:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":216 * copy_shape = 0 * * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): * raise ValueError(u"ndarray is not C contiguous") */ if (__pyx_t_1) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":218 * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< * * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) */ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 218, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 218, __pyx_L1_error) /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":216 * copy_shape = 0 * * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): * raise ValueError(u"ndarray is not C contiguous") */ } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":220 * raise ValueError(u"ndarray is not C contiguous") * * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): * raise ValueError(u"ndarray is not Fortran contiguous") */ __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0); if (__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L9_bool_binop_done; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":221 * * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<< * raise ValueError(u"ndarray is not Fortran contiguous") * */ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0); __pyx_t_1 = __pyx_t_2; __pyx_L9_bool_binop_done:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":220 * raise ValueError(u"ndarray is not C contiguous") * * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): * raise ValueError(u"ndarray is not Fortran contiguous") */ if (__pyx_t_1) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":222 * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< * * info.buf = PyArray_DATA(self) */ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 222, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 222, __pyx_L1_error) /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":220 * raise ValueError(u"ndarray is not C contiguous") * * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): * raise ValueError(u"ndarray is not Fortran contiguous") */ } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":224 * raise ValueError(u"ndarray is not Fortran contiguous") * * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<< * info.ndim = ndim * if copy_shape: */ __pyx_v_info->buf = PyArray_DATA(__pyx_v_self); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":225 * * info.buf = PyArray_DATA(self) * info.ndim = ndim # <<<<<<<<<<<<<< * if copy_shape: * # Allocate new buffer for strides and shape info. */ __pyx_v_info->ndim = __pyx_v_ndim; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":226 * info.buf = PyArray_DATA(self) * info.ndim = ndim * if copy_shape: # <<<<<<<<<<<<<< * # Allocate new buffer for strides and shape info. * # This is allocated as one block, strides first. */ __pyx_t_1 = (__pyx_v_copy_shape != 0); if (__pyx_t_1) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":229 * # Allocate new buffer for strides and shape info. * # This is allocated as one block, strides first. * info.strides = stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2) # <<<<<<<<<<<<<< * info.shape = info.strides + ndim * for i in range(ndim): */ __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2))); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":230 * # This is allocated as one block, strides first. * info.strides = stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2) * info.shape = info.strides + ndim # <<<<<<<<<<<<<< * for i in range(ndim): * info.strides[i] = PyArray_STRIDES(self)[i] */ __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":231 * info.strides = stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2) * info.shape = info.strides + ndim * for i in range(ndim): # <<<<<<<<<<<<<< * info.strides[i] = PyArray_STRIDES(self)[i] * info.shape[i] = PyArray_DIMS(self)[i] */ __pyx_t_4 = __pyx_v_ndim; for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { __pyx_v_i = __pyx_t_5; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":232 * info.shape = info.strides + ndim * for i in range(ndim): * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<< * info.shape[i] = PyArray_DIMS(self)[i] * else: */ (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":233 * for i in range(ndim): * info.strides[i] = PyArray_STRIDES(self)[i] * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<< * else: * info.strides = PyArray_STRIDES(self) */ (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]); } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":226 * info.buf = PyArray_DATA(self) * info.ndim = ndim * if copy_shape: # <<<<<<<<<<<<<< * # Allocate new buffer for strides and shape info. * # This is allocated as one block, strides first. */ goto __pyx_L11; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":235 * info.shape[i] = PyArray_DIMS(self)[i] * else: * info.strides = PyArray_STRIDES(self) # <<<<<<<<<<<<<< * info.shape = PyArray_DIMS(self) * info.suboffsets = NULL */ /*else*/ { __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self)); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":236 * else: * info.strides = PyArray_STRIDES(self) * info.shape = PyArray_DIMS(self) # <<<<<<<<<<<<<< * info.suboffsets = NULL * info.itemsize = PyArray_ITEMSIZE(self) */ __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self)); } __pyx_L11:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":237 * info.strides = PyArray_STRIDES(self) * info.shape = PyArray_DIMS(self) * info.suboffsets = NULL # <<<<<<<<<<<<<< * info.itemsize = PyArray_ITEMSIZE(self) * info.readonly = not PyArray_ISWRITEABLE(self) */ __pyx_v_info->suboffsets = NULL; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":238 * info.shape = PyArray_DIMS(self) * info.suboffsets = NULL * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<< * info.readonly = not PyArray_ISWRITEABLE(self) * */ __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":239 * info.suboffsets = NULL * info.itemsize = PyArray_ITEMSIZE(self) * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<< * * cdef int t */ __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0)); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":242 * * cdef int t * cdef char* f = NULL # <<<<<<<<<<<<<< * cdef dtype descr = self.descr * cdef int offset */ __pyx_v_f = NULL; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":243 * cdef int t * cdef char* f = NULL * cdef dtype descr = self.descr # <<<<<<<<<<<<<< * cdef int offset * */ __pyx_t_3 = ((PyObject *)__pyx_v_self->descr); __Pyx_INCREF(__pyx_t_3); __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3); __pyx_t_3 = 0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":246 * cdef int offset * * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<< * * if not hasfields and not copy_shape: */ __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":248 * cdef bint hasfields = PyDataType_HASFIELDS(descr) * * if not hasfields and not copy_shape: # <<<<<<<<<<<<<< * # do not call releasebuffer * info.obj = None */ __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0); if (__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L15_bool_binop_done; } __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0); __pyx_t_1 = __pyx_t_2; __pyx_L15_bool_binop_done:; if (__pyx_t_1) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":250 * if not hasfields and not copy_shape: * # do not call releasebuffer * info.obj = None # <<<<<<<<<<<<<< * else: * # need to call releasebuffer */ __Pyx_INCREF(Py_None); __Pyx_GIVEREF(Py_None); __Pyx_GOTREF(__pyx_v_info->obj); __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = Py_None; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":248 * cdef bint hasfields = PyDataType_HASFIELDS(descr) * * if not hasfields and not copy_shape: # <<<<<<<<<<<<<< * # do not call releasebuffer * info.obj = None */ goto __pyx_L14; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":253 * else: * # need to call releasebuffer * info.obj = self # <<<<<<<<<<<<<< * * if not hasfields: */ /*else*/ { __Pyx_INCREF(((PyObject *)__pyx_v_self)); __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); __Pyx_GOTREF(__pyx_v_info->obj); __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = ((PyObject *)__pyx_v_self); } __pyx_L14:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":255 * info.obj = self * * if not hasfields: # <<<<<<<<<<<<<< * t = descr.type_num * if ((descr.byteorder == c'>' and little_endian) or */ __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0); if (__pyx_t_1) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":256 * * if not hasfields: * t = descr.type_num # <<<<<<<<<<<<<< * if ((descr.byteorder == c'>' and little_endian) or * (descr.byteorder == c'<' and not little_endian)): */ __pyx_t_4 = __pyx_v_descr->type_num; __pyx_v_t = __pyx_t_4; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":257 * if not hasfields: * t = descr.type_num * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< * (descr.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") */ __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0); if (!__pyx_t_2) { goto __pyx_L20_next_or; } else { } __pyx_t_2 = (__pyx_v_little_endian != 0); if (!__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L19_bool_binop_done; } __pyx_L20_next_or:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":258 * t = descr.type_num * if ((descr.byteorder == c'>' and little_endian) or * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< * raise ValueError(u"Non-native byte order not supported") * if t == NPY_BYTE: f = "b" */ __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0); if (__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L19_bool_binop_done; } __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0); __pyx_t_1 = __pyx_t_2; __pyx_L19_bool_binop_done:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":257 * if not hasfields: * t = descr.type_num * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< * (descr.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") */ if (__pyx_t_1) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":259 * if ((descr.byteorder == c'>' and little_endian) or * (descr.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< * if t == NPY_BYTE: f = "b" * elif t == NPY_UBYTE: f = "B" */ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 259, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 259, __pyx_L1_error) /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":257 * if not hasfields: * t = descr.type_num * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< * (descr.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") */ } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":260 * (descr.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<< * elif t == NPY_UBYTE: f = "B" * elif t == NPY_SHORT: f = "h" */ switch (__pyx_v_t) { case NPY_BYTE: __pyx_v_f = ((char *)"b"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":261 * raise ValueError(u"Non-native byte order not supported") * if t == NPY_BYTE: f = "b" * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<< * elif t == NPY_SHORT: f = "h" * elif t == NPY_USHORT: f = "H" */ case NPY_UBYTE: __pyx_v_f = ((char *)"B"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":262 * if t == NPY_BYTE: f = "b" * elif t == NPY_UBYTE: f = "B" * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<< * elif t == NPY_USHORT: f = "H" * elif t == NPY_INT: f = "i" */ case NPY_SHORT: __pyx_v_f = ((char *)"h"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":263 * elif t == NPY_UBYTE: f = "B" * elif t == NPY_SHORT: f = "h" * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<< * elif t == NPY_INT: f = "i" * elif t == NPY_UINT: f = "I" */ case NPY_USHORT: __pyx_v_f = ((char *)"H"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":264 * elif t == NPY_SHORT: f = "h" * elif t == NPY_USHORT: f = "H" * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<< * elif t == NPY_UINT: f = "I" * elif t == NPY_LONG: f = "l" */ case NPY_INT: __pyx_v_f = ((char *)"i"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":265 * elif t == NPY_USHORT: f = "H" * elif t == NPY_INT: f = "i" * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<< * elif t == NPY_LONG: f = "l" * elif t == NPY_ULONG: f = "L" */ case NPY_UINT: __pyx_v_f = ((char *)"I"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":266 * elif t == NPY_INT: f = "i" * elif t == NPY_UINT: f = "I" * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<< * elif t == NPY_ULONG: f = "L" * elif t == NPY_LONGLONG: f = "q" */ case NPY_LONG: __pyx_v_f = ((char *)"l"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":267 * elif t == NPY_UINT: f = "I" * elif t == NPY_LONG: f = "l" * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<< * elif t == NPY_LONGLONG: f = "q" * elif t == NPY_ULONGLONG: f = "Q" */ case NPY_ULONG: __pyx_v_f = ((char *)"L"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":268 * elif t == NPY_LONG: f = "l" * elif t == NPY_ULONG: f = "L" * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<< * elif t == NPY_ULONGLONG: f = "Q" * elif t == NPY_FLOAT: f = "f" */ case NPY_LONGLONG: __pyx_v_f = ((char *)"q"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":269 * elif t == NPY_ULONG: f = "L" * elif t == NPY_LONGLONG: f = "q" * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<< * elif t == NPY_FLOAT: f = "f" * elif t == NPY_DOUBLE: f = "d" */ case NPY_ULONGLONG: __pyx_v_f = ((char *)"Q"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":270 * elif t == NPY_LONGLONG: f = "q" * elif t == NPY_ULONGLONG: f = "Q" * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<< * elif t == NPY_DOUBLE: f = "d" * elif t == NPY_LONGDOUBLE: f = "g" */ case NPY_FLOAT: __pyx_v_f = ((char *)"f"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":271 * elif t == NPY_ULONGLONG: f = "Q" * elif t == NPY_FLOAT: f = "f" * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<< * elif t == NPY_LONGDOUBLE: f = "g" * elif t == NPY_CFLOAT: f = "Zf" */ case NPY_DOUBLE: __pyx_v_f = ((char *)"d"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":272 * elif t == NPY_FLOAT: f = "f" * elif t == NPY_DOUBLE: f = "d" * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<< * elif t == NPY_CFLOAT: f = "Zf" * elif t == NPY_CDOUBLE: f = "Zd" */ case NPY_LONGDOUBLE: __pyx_v_f = ((char *)"g"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":273 * elif t == NPY_DOUBLE: f = "d" * elif t == NPY_LONGDOUBLE: f = "g" * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<< * elif t == NPY_CDOUBLE: f = "Zd" * elif t == NPY_CLONGDOUBLE: f = "Zg" */ case NPY_CFLOAT: __pyx_v_f = ((char *)"Zf"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":274 * elif t == NPY_LONGDOUBLE: f = "g" * elif t == NPY_CFLOAT: f = "Zf" * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<< * elif t == NPY_CLONGDOUBLE: f = "Zg" * elif t == NPY_OBJECT: f = "O" */ case NPY_CDOUBLE: __pyx_v_f = ((char *)"Zd"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":275 * elif t == NPY_CFLOAT: f = "Zf" * elif t == NPY_CDOUBLE: f = "Zd" * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<< * elif t == NPY_OBJECT: f = "O" * else: */ case NPY_CLONGDOUBLE: __pyx_v_f = ((char *)"Zg"); break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":276 * elif t == NPY_CDOUBLE: f = "Zd" * elif t == NPY_CLONGDOUBLE: f = "Zg" * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<< * else: * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) */ case NPY_OBJECT: __pyx_v_f = ((char *)"O"); break; default: /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":278 * elif t == NPY_OBJECT: f = "O" * else: * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< * info.format = f * return */ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 278, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 278, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 278, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6); __pyx_t_6 = 0; __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 278, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_Raise(__pyx_t_6, 0, 0, 0); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __PYX_ERR(1, 278, __pyx_L1_error) break; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":279 * else: * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) * info.format = f # <<<<<<<<<<<<<< * return * else: */ __pyx_v_info->format = __pyx_v_f; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":280 * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) * info.format = f * return # <<<<<<<<<<<<<< * else: * info.format = stdlib.malloc(_buffer_format_string_len) */ __pyx_r = 0; goto __pyx_L0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":255 * info.obj = self * * if not hasfields: # <<<<<<<<<<<<<< * t = descr.type_num * if ((descr.byteorder == c'>' and little_endian) or */ } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":282 * return * else: * info.format = stdlib.malloc(_buffer_format_string_len) # <<<<<<<<<<<<<< * info.format[0] = c'^' # Native data types, manual alignment * offset = 0 */ /*else*/ { __pyx_v_info->format = ((char *)malloc(0xFF)); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":283 * else: * info.format = stdlib.malloc(_buffer_format_string_len) * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<< * offset = 0 * f = _util_dtypestring(descr, info.format + 1, */ (__pyx_v_info->format[0]) = '^'; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":284 * info.format = stdlib.malloc(_buffer_format_string_len) * info.format[0] = c'^' # Native data types, manual alignment * offset = 0 # <<<<<<<<<<<<<< * f = _util_dtypestring(descr, info.format + 1, * info.format + _buffer_format_string_len, */ __pyx_v_offset = 0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":285 * info.format[0] = c'^' # Native data types, manual alignment * offset = 0 * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<< * info.format + _buffer_format_string_len, * &offset) */ __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 0xFF), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) __PYX_ERR(1, 285, __pyx_L1_error) __pyx_v_f = __pyx_t_7; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":288 * info.format + _buffer_format_string_len, * &offset) * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<< * * def __releasebuffer__(ndarray self, Py_buffer* info): */ (__pyx_v_f[0]) = '\x00'; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":197 * # experimental exception made for __getbuffer__ and __releasebuffer__ * # -- the details of this may change. * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< * # This implementation of getbuffer is geared towards Cython * # requirements, and does not yet fullfill the PEP. */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) { __Pyx_GOTREF(__pyx_v_info->obj); __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL; } goto __pyx_L2; __pyx_L0:; if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) { __Pyx_GOTREF(Py_None); __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL; } __pyx_L2:; __Pyx_XDECREF((PyObject *)__pyx_v_descr); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":290 * f[0] = c'\0' # Terminate format string * * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< * if PyArray_HASFIELDS(self): * stdlib.free(info.format) */ /* Python wrapper */ static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/ static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0); __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info)); /* function exit code */ __Pyx_RefNannyFinishContext(); } static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) { __Pyx_RefNannyDeclarations int __pyx_t_1; __Pyx_RefNannySetupContext("__releasebuffer__", 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":291 * * def __releasebuffer__(ndarray self, Py_buffer* info): * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< * stdlib.free(info.format) * if sizeof(npy_intp) != sizeof(Py_ssize_t): */ __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0); if (__pyx_t_1) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":292 * def __releasebuffer__(ndarray self, Py_buffer* info): * if PyArray_HASFIELDS(self): * stdlib.free(info.format) # <<<<<<<<<<<<<< * if sizeof(npy_intp) != sizeof(Py_ssize_t): * stdlib.free(info.strides) */ free(__pyx_v_info->format); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":291 * * def __releasebuffer__(ndarray self, Py_buffer* info): * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< * stdlib.free(info.format) * if sizeof(npy_intp) != sizeof(Py_ssize_t): */ } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":293 * if PyArray_HASFIELDS(self): * stdlib.free(info.format) * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< * stdlib.free(info.strides) * # info.shape was stored after info.strides in the same block */ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); if (__pyx_t_1) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":294 * stdlib.free(info.format) * if sizeof(npy_intp) != sizeof(Py_ssize_t): * stdlib.free(info.strides) # <<<<<<<<<<<<<< * # info.shape was stored after info.strides in the same block * */ free(__pyx_v_info->strides); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":293 * if PyArray_HASFIELDS(self): * stdlib.free(info.format) * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< * stdlib.free(info.strides) * # info.shape was stored after info.strides in the same block */ } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":290 * f[0] = c'\0' # Terminate format string * * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< * if PyArray_HASFIELDS(self): * stdlib.free(info.format) */ /* function exit code */ __Pyx_RefNannyFinishContext(); } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":770 * ctypedef npy_cdouble complex_t * * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< * return PyArray_MultiIterNew(1, a) * */ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":771 * * cdef inline object PyArray_MultiIterNew1(a): * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< * * cdef inline object PyArray_MultiIterNew2(a, b): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 771, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":770 * ctypedef npy_cdouble complex_t * * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< * return PyArray_MultiIterNew(1, a) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":773 * return PyArray_MultiIterNew(1, a) * * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< * return PyArray_MultiIterNew(2, a, b) * */ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":774 * * cdef inline object PyArray_MultiIterNew2(a, b): * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< * * cdef inline object PyArray_MultiIterNew3(a, b, c): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 774, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":773 * return PyArray_MultiIterNew(1, a) * * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< * return PyArray_MultiIterNew(2, a, b) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":776 * return PyArray_MultiIterNew(2, a, b) * * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< * return PyArray_MultiIterNew(3, a, b, c) * */ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":777 * * cdef inline object PyArray_MultiIterNew3(a, b, c): * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 777, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":776 * return PyArray_MultiIterNew(2, a, b) * * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< * return PyArray_MultiIterNew(3, a, b, c) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":779 * return PyArray_MultiIterNew(3, a, b, c) * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< * return PyArray_MultiIterNew(4, a, b, c, d) * */ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":780 * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 780, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":779 * return PyArray_MultiIterNew(3, a, b, c) * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< * return PyArray_MultiIterNew(4, a, b, c, d) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":782 * return PyArray_MultiIterNew(4, a, b, c, d) * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< * return PyArray_MultiIterNew(5, a, b, c, d, e) * */ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":783 * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< * * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 783, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":782 * return PyArray_MultiIterNew(4, a, b, c, d) * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< * return PyArray_MultiIterNew(5, a, b, c, d, e) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":785 * return PyArray_MultiIterNew(5, a, b, c, d, e) * * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< * # Recursive utility function used in __getbuffer__ to get format * # string. The new location in the format string is returned. */ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) { PyArray_Descr *__pyx_v_child = 0; int __pyx_v_endian_detector; int __pyx_v_little_endian; PyObject *__pyx_v_fields = 0; PyObject *__pyx_v_childname = NULL; PyObject *__pyx_v_new_offset = NULL; PyObject *__pyx_v_t = NULL; char *__pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; int __pyx_t_5; int __pyx_t_6; int __pyx_t_7; long __pyx_t_8; char *__pyx_t_9; __Pyx_RefNannySetupContext("_util_dtypestring", 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":790 * * cdef dtype child * cdef int endian_detector = 1 # <<<<<<<<<<<<<< * cdef bint little_endian = ((&endian_detector)[0] != 0) * cdef tuple fields */ __pyx_v_endian_detector = 1; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":791 * cdef dtype child * cdef int endian_detector = 1 * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< * cdef tuple fields * */ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":794 * cdef tuple fields * * for childname in descr.names: # <<<<<<<<<<<<<< * fields = descr.fields[childname] * child, new_offset = fields */ if (unlikely(__pyx_v_descr->names == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); __PYX_ERR(1, 794, __pyx_L1_error) } __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; for (;;) { if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(1, 794, __pyx_L1_error) #else __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 794, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3); __pyx_t_3 = 0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":795 * * for childname in descr.names: * fields = descr.fields[childname] # <<<<<<<<<<<<<< * child, new_offset = fields * */ if (unlikely(__pyx_v_descr->fields == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); __PYX_ERR(1, 795, __pyx_L1_error) } __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 795, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(1, 795, __pyx_L1_error) __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3)); __pyx_t_3 = 0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":796 * for childname in descr.names: * fields = descr.fields[childname] * child, new_offset = fields # <<<<<<<<<<<<<< * * if (end - f) - (new_offset - offset[0]) < 15: */ if (likely(__pyx_v_fields != Py_None)) { PyObject* sequence = __pyx_v_fields; #if CYTHON_COMPILING_IN_CPYTHON Py_ssize_t size = Py_SIZE(sequence); #else Py_ssize_t size = PySequence_Size(sequence); #endif if (unlikely(size != 2)) { if (size > 2) __Pyx_RaiseTooManyValuesError(2); else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); __PYX_ERR(1, 796, __pyx_L1_error) } #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(__pyx_t_4); #else __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 796, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 796, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); #endif } else { __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 796, __pyx_L1_error) } if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) __PYX_ERR(1, 796, __pyx_L1_error) __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3)); __pyx_t_3 = 0; __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4); __pyx_t_4 = 0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":798 * child, new_offset = fields * * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") * */ __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 798, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 798, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 798, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0); if (__pyx_t_6) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":799 * * if (end - f) - (new_offset - offset[0]) < 15: * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< * * if ((child.byteorder == c'>' and little_endian) or */ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 799, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 799, __pyx_L1_error) /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":798 * child, new_offset = fields * * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") * */ } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":801 * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") * * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< * (child.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") */ __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0); if (!__pyx_t_7) { goto __pyx_L8_next_or; } else { } __pyx_t_7 = (__pyx_v_little_endian != 0); if (!__pyx_t_7) { } else { __pyx_t_6 = __pyx_t_7; goto __pyx_L7_bool_binop_done; } __pyx_L8_next_or:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":802 * * if ((child.byteorder == c'>' and little_endian) or * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< * raise ValueError(u"Non-native byte order not supported") * # One could encode it in the format string and have Cython */ __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0); if (__pyx_t_7) { } else { __pyx_t_6 = __pyx_t_7; goto __pyx_L7_bool_binop_done; } __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0); __pyx_t_6 = __pyx_t_7; __pyx_L7_bool_binop_done:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":801 * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") * * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< * (child.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") */ if (__pyx_t_6) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":803 * if ((child.byteorder == c'>' and little_endian) or * (child.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< * # One could encode it in the format string and have Cython * # complain instead, BUT: < and > in format strings also imply */ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 803, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 803, __pyx_L1_error) /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":801 * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") * * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< * (child.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") */ } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":813 * * # Output padding bytes * while offset[0] < new_offset: # <<<<<<<<<<<<<< * f[0] = 120 # "x"; pad byte * f += 1 */ while (1) { __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 813, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 813, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 813, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (!__pyx_t_6) break; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":814 * # Output padding bytes * while offset[0] < new_offset: * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<< * f += 1 * offset[0] += 1 */ (__pyx_v_f[0]) = 0x78; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":815 * while offset[0] < new_offset: * f[0] = 120 # "x"; pad byte * f += 1 # <<<<<<<<<<<<<< * offset[0] += 1 * */ __pyx_v_f = (__pyx_v_f + 1); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":816 * f[0] = 120 # "x"; pad byte * f += 1 * offset[0] += 1 # <<<<<<<<<<<<<< * * offset[0] += child.itemsize */ __pyx_t_8 = 0; (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1); } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":818 * offset[0] += 1 * * offset[0] += child.itemsize # <<<<<<<<<<<<<< * * if not PyDataType_HASFIELDS(child): */ __pyx_t_8 = 0; (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":820 * offset[0] += child.itemsize * * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< * t = child.type_num * if end - f < 5: */ __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0); if (__pyx_t_6) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":821 * * if not PyDataType_HASFIELDS(child): * t = child.type_num # <<<<<<<<<<<<<< * if end - f < 5: * raise RuntimeError(u"Format string allocated too short.") */ __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 821, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4); __pyx_t_4 = 0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":822 * if not PyDataType_HASFIELDS(child): * t = child.type_num * if end - f < 5: # <<<<<<<<<<<<<< * raise RuntimeError(u"Format string allocated too short.") * */ __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0); if (__pyx_t_6) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":823 * t = child.type_num * if end - f < 5: * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< * * # Until ticket #99 is fixed, use integers to avoid warnings */ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 823, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_Raise(__pyx_t_4, 0, 0, 0); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __PYX_ERR(1, 823, __pyx_L1_error) /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":822 * if not PyDataType_HASFIELDS(child): * t = child.type_num * if end - f < 5: # <<<<<<<<<<<<<< * raise RuntimeError(u"Format string allocated too short.") * */ } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":826 * * # Until ticket #99 is fixed, use integers to avoid warnings * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<< * elif t == NPY_UBYTE: f[0] = 66 #"B" * elif t == NPY_SHORT: f[0] = 104 #"h" */ __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_BYTE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 826, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 826, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 826, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 98; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":827 * # Until ticket #99 is fixed, use integers to avoid warnings * if t == NPY_BYTE: f[0] = 98 #"b" * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<< * elif t == NPY_SHORT: f[0] = 104 #"h" * elif t == NPY_USHORT: f[0] = 72 #"H" */ __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UBYTE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 827, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 827, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 827, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 66; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":828 * if t == NPY_BYTE: f[0] = 98 #"b" * elif t == NPY_UBYTE: f[0] = 66 #"B" * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<< * elif t == NPY_USHORT: f[0] = 72 #"H" * elif t == NPY_INT: f[0] = 105 #"i" */ __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_SHORT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 828, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 828, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 828, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 0x68; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":829 * elif t == NPY_UBYTE: f[0] = 66 #"B" * elif t == NPY_SHORT: f[0] = 104 #"h" * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<< * elif t == NPY_INT: f[0] = 105 #"i" * elif t == NPY_UINT: f[0] = 73 #"I" */ __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_USHORT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 829, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 829, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 829, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 72; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":830 * elif t == NPY_SHORT: f[0] = 104 #"h" * elif t == NPY_USHORT: f[0] = 72 #"H" * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<< * elif t == NPY_UINT: f[0] = 73 #"I" * elif t == NPY_LONG: f[0] = 108 #"l" */ __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_INT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 830, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 830, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 830, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 0x69; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":831 * elif t == NPY_USHORT: f[0] = 72 #"H" * elif t == NPY_INT: f[0] = 105 #"i" * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<< * elif t == NPY_LONG: f[0] = 108 #"l" * elif t == NPY_ULONG: f[0] = 76 #"L" */ __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UINT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 831, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 831, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 831, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 73; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":832 * elif t == NPY_INT: f[0] = 105 #"i" * elif t == NPY_UINT: f[0] = 73 #"I" * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<< * elif t == NPY_ULONG: f[0] = 76 #"L" * elif t == NPY_LONGLONG: f[0] = 113 #"q" */ __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 832, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 832, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 832, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 0x6C; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":833 * elif t == NPY_UINT: f[0] = 73 #"I" * elif t == NPY_LONG: f[0] = 108 #"l" * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<< * elif t == NPY_LONGLONG: f[0] = 113 #"q" * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" */ __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 833, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 833, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 833, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 76; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":834 * elif t == NPY_LONG: f[0] = 108 #"l" * elif t == NPY_ULONG: f[0] = 76 #"L" * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<< * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" * elif t == NPY_FLOAT: f[0] = 102 #"f" */ __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 834, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 834, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 834, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 0x71; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":835 * elif t == NPY_ULONG: f[0] = 76 #"L" * elif t == NPY_LONGLONG: f[0] = 113 #"q" * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<< * elif t == NPY_FLOAT: f[0] = 102 #"f" * elif t == NPY_DOUBLE: f[0] = 100 #"d" */ __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 835, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 835, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 835, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 81; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":836 * elif t == NPY_LONGLONG: f[0] = 113 #"q" * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<< * elif t == NPY_DOUBLE: f[0] = 100 #"d" * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" */ __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_FLOAT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 836, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 836, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 836, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 0x66; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":837 * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" * elif t == NPY_FLOAT: f[0] = 102 #"f" * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<< * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf */ __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 837, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 837, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 837, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 0x64; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":838 * elif t == NPY_FLOAT: f[0] = 102 #"f" * elif t == NPY_DOUBLE: f[0] = 100 #"d" * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<< * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd */ __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 838, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 838, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 838, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 0x67; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":839 * elif t == NPY_DOUBLE: f[0] = 100 #"d" * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<< * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg */ __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 839, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 839, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 839, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 90; (__pyx_v_f[1]) = 0x66; __pyx_v_f = (__pyx_v_f + 1); goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":840 * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<< * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg * elif t == NPY_OBJECT: f[0] = 79 #"O" */ __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 840, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 840, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 840, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 90; (__pyx_v_f[1]) = 0x64; __pyx_v_f = (__pyx_v_f + 1); goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":841 * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<< * elif t == NPY_OBJECT: f[0] = 79 #"O" * else: */ __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 841, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 841, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 841, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 90; (__pyx_v_f[1]) = 0x67; __pyx_v_f = (__pyx_v_f + 1); goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":842 * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<< * else: * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) */ __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_OBJECT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 842, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 842, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 842, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; if (__pyx_t_6) { (__pyx_v_f[0]) = 79; goto __pyx_L15; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":844 * elif t == NPY_OBJECT: f[0] = 79 #"O" * else: * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< * f += 1 * else: */ /*else*/ { __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 844, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 844, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 844, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 844, __pyx_L1_error) } __pyx_L15:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":845 * else: * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) * f += 1 # <<<<<<<<<<<<<< * else: * # Cython ignores struct boundary information ("T{...}"), */ __pyx_v_f = (__pyx_v_f + 1); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":820 * offset[0] += child.itemsize * * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< * t = child.type_num * if end - f < 5: */ goto __pyx_L13; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":849 * # Cython ignores struct boundary information ("T{...}"), * # so don't output it * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<< * return f * */ /*else*/ { __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) __PYX_ERR(1, 849, __pyx_L1_error) __pyx_v_f = __pyx_t_9; } __pyx_L13:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":794 * cdef tuple fields * * for childname in descr.names: # <<<<<<<<<<<<<< * fields = descr.fields[childname] * child, new_offset = fields */ } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":850 * # so don't output it * f = _util_dtypestring(child, f, end, offset) * return f # <<<<<<<<<<<<<< * * */ __pyx_r = __pyx_v_f; goto __pyx_L0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":785 * return PyArray_MultiIterNew(5, a, b, c, d, e) * * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< * # Recursive utility function used in __getbuffer__ to get format * # string. The new location in the format string is returned. */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_child); __Pyx_XDECREF(__pyx_v_fields); __Pyx_XDECREF(__pyx_v_childname); __Pyx_XDECREF(__pyx_v_new_offset); __Pyx_XDECREF(__pyx_v_t); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":966 * * * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< * cdef PyObject* baseptr * if base is None: */ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { PyObject *__pyx_v_baseptr; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; __Pyx_RefNannySetupContext("set_array_base", 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":968 * cdef inline void set_array_base(ndarray arr, object base): * cdef PyObject* baseptr * if base is None: # <<<<<<<<<<<<<< * baseptr = NULL * else: */ __pyx_t_1 = (__pyx_v_base == Py_None); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":969 * cdef PyObject* baseptr * if base is None: * baseptr = NULL # <<<<<<<<<<<<<< * else: * Py_INCREF(base) # important to do this before decref below! */ __pyx_v_baseptr = NULL; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":968 * cdef inline void set_array_base(ndarray arr, object base): * cdef PyObject* baseptr * if base is None: # <<<<<<<<<<<<<< * baseptr = NULL * else: */ goto __pyx_L3; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":971 * baseptr = NULL * else: * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<< * baseptr = base * Py_XDECREF(arr.base) */ /*else*/ { Py_INCREF(__pyx_v_base); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":972 * else: * Py_INCREF(base) # important to do this before decref below! * baseptr = base # <<<<<<<<<<<<<< * Py_XDECREF(arr.base) * arr.base = baseptr */ __pyx_v_baseptr = ((PyObject *)__pyx_v_base); } __pyx_L3:; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":973 * Py_INCREF(base) # important to do this before decref below! * baseptr = base * Py_XDECREF(arr.base) # <<<<<<<<<<<<<< * arr.base = baseptr * */ Py_XDECREF(__pyx_v_arr->base); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":974 * baseptr = base * Py_XDECREF(arr.base) * arr.base = baseptr # <<<<<<<<<<<<<< * * cdef inline object get_array_base(ndarray arr): */ __pyx_v_arr->base = __pyx_v_baseptr; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":966 * * * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< * cdef PyObject* baseptr * if base is None: */ /* function exit code */ __Pyx_RefNannyFinishContext(); } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":976 * arr.base = baseptr * * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< * if arr.base is NULL: * return None */ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; __Pyx_RefNannySetupContext("get_array_base", 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":977 * * cdef inline object get_array_base(ndarray arr): * if arr.base is NULL: # <<<<<<<<<<<<<< * return None * else: */ __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0); if (__pyx_t_1) { /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":978 * cdef inline object get_array_base(ndarray arr): * if arr.base is NULL: * return None # <<<<<<<<<<<<<< * else: * return arr.base */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_None); __pyx_r = Py_None; goto __pyx_L0; /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":977 * * cdef inline object get_array_base(ndarray arr): * if arr.base is NULL: # <<<<<<<<<<<<<< * return None * else: */ } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":980 * return None * else: * return arr.base # <<<<<<<<<<<<<< */ /*else*/ { __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_arr->base)); __pyx_r = ((PyObject *)__pyx_v_arr->base); goto __pyx_L0; } /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":976 * arr.base = baseptr * * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< * if arr.base is NULL: * return None */ /* function exit code */ __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":120 * cdef bint dtype_is_object * * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< * mode="c", bint allocate_buffer=True): * */ /* Python wrapper */ static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_shape = 0; Py_ssize_t __pyx_v_itemsize; PyObject *__pyx_v_format = 0; PyObject *__pyx_v_mode = 0; int __pyx_v_allocate_buffer; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0}; PyObject* values[5] = {0,0,0,0,0}; values[3] = ((PyObject *)__pyx_n_s_c); if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); __PYX_ERR(2, 120, __pyx_L3_error) } case 2: if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); __PYX_ERR(2, 120, __pyx_L3_error) } case 3: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode); if (value) { values[3] = value; kw_args--; } } case 4: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer); if (value) { values[4] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(2, 120, __pyx_L3_error) } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); values[1] = PyTuple_GET_ITEM(__pyx_args, 1); values[0] = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } __pyx_v_shape = ((PyObject*)values[0]); __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 120, __pyx_L3_error) __pyx_v_format = values[2]; __pyx_v_mode = values[3]; if (values[4]) { __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 121, __pyx_L3_error) } else { /* "View.MemoryView":121 * * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<< * * cdef int idx */ __pyx_v_allocate_buffer = ((int)1); } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 120, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) __PYX_ERR(2, 120, __pyx_L1_error) if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) { PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); __PYX_ERR(2, 120, __pyx_L1_error) } __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer); /* "View.MemoryView":120 * cdef bint dtype_is_object * * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< * mode="c", bint allocate_buffer=True): * */ /* function exit code */ goto __pyx_L0; __pyx_L1_error:; __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) { int __pyx_v_idx; Py_ssize_t __pyx_v_i; Py_ssize_t __pyx_v_dim; PyObject **__pyx_v_p; char __pyx_v_order; int __pyx_r; __Pyx_RefNannyDeclarations Py_ssize_t __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; PyObject *__pyx_t_5 = NULL; char *__pyx_t_6; int __pyx_t_7; Py_ssize_t __pyx_t_8; PyObject *__pyx_t_9 = NULL; PyObject *__pyx_t_10 = NULL; __Pyx_RefNannySetupContext("__cinit__", 0); __Pyx_INCREF(__pyx_v_format); /* "View.MemoryView":127 * cdef PyObject **p * * self.ndim = len(shape) # <<<<<<<<<<<<<< * self.itemsize = itemsize * */ if (unlikely(__pyx_v_shape == Py_None)) { PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); __PYX_ERR(2, 127, __pyx_L1_error) } __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) __PYX_ERR(2, 127, __pyx_L1_error) __pyx_v_self->ndim = ((int)__pyx_t_1); /* "View.MemoryView":128 * * self.ndim = len(shape) * self.itemsize = itemsize # <<<<<<<<<<<<<< * * if not self.ndim: */ __pyx_v_self->itemsize = __pyx_v_itemsize; /* "View.MemoryView":130 * self.itemsize = itemsize * * if not self.ndim: # <<<<<<<<<<<<<< * raise ValueError("Empty shape tuple for cython.array") * */ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0); if (__pyx_t_2) { /* "View.MemoryView":131 * * if not self.ndim: * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<< * * if itemsize <= 0: */ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 131, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(2, 131, __pyx_L1_error) /* "View.MemoryView":130 * self.itemsize = itemsize * * if not self.ndim: # <<<<<<<<<<<<<< * raise ValueError("Empty shape tuple for cython.array") * */ } /* "View.MemoryView":133 * raise ValueError("Empty shape tuple for cython.array") * * if itemsize <= 0: # <<<<<<<<<<<<<< * raise ValueError("itemsize <= 0 for cython.array") * */ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":134 * * if itemsize <= 0: * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<< * * if not isinstance(format, bytes): */ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 134, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(2, 134, __pyx_L1_error) /* "View.MemoryView":133 * raise ValueError("Empty shape tuple for cython.array") * * if itemsize <= 0: # <<<<<<<<<<<<<< * raise ValueError("itemsize <= 0 for cython.array") * */ } /* "View.MemoryView":136 * raise ValueError("itemsize <= 0 for cython.array") * * if not isinstance(format, bytes): # <<<<<<<<<<<<<< * format = format.encode('ASCII') * self._format = format # keep a reference to the byte string */ __pyx_t_2 = PyBytes_Check(__pyx_v_format); __pyx_t_4 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_4) { /* "View.MemoryView":137 * * if not isinstance(format, bytes): * format = format.encode('ASCII') # <<<<<<<<<<<<<< * self._format = format # keep a reference to the byte string * self.format = self._format */ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_format, __pyx_n_s_encode); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 137, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 137, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_5); __pyx_t_5 = 0; /* "View.MemoryView":136 * raise ValueError("itemsize <= 0 for cython.array") * * if not isinstance(format, bytes): # <<<<<<<<<<<<<< * format = format.encode('ASCII') * self._format = format # keep a reference to the byte string */ } /* "View.MemoryView":138 * if not isinstance(format, bytes): * format = format.encode('ASCII') * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<< * self.format = self._format * */ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) __PYX_ERR(2, 138, __pyx_L1_error) __pyx_t_5 = __pyx_v_format; __Pyx_INCREF(__pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __Pyx_GOTREF(__pyx_v_self->_format); __Pyx_DECREF(__pyx_v_self->_format); __pyx_v_self->_format = ((PyObject*)__pyx_t_5); __pyx_t_5 = 0; /* "View.MemoryView":139 * format = format.encode('ASCII') * self._format = format # keep a reference to the byte string * self.format = self._format # <<<<<<<<<<<<<< * * */ __pyx_t_6 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_6) && PyErr_Occurred())) __PYX_ERR(2, 139, __pyx_L1_error) __pyx_v_self->format = __pyx_t_6; /* "View.MemoryView":142 * * * self._shape = PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<< * self._strides = self._shape + self.ndim * */ __pyx_v_self->_shape = ((Py_ssize_t *)PyObject_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2))); /* "View.MemoryView":143 * * self._shape = PyObject_Malloc(sizeof(Py_ssize_t)*self.ndim*2) * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<< * * if not self._shape: */ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim); /* "View.MemoryView":145 * self._strides = self._shape + self.ndim * * if not self._shape: # <<<<<<<<<<<<<< * raise MemoryError("unable to allocate shape and strides.") * */ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0); if (__pyx_t_4) { /* "View.MemoryView":146 * * if not self._shape: * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<< * * */ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 146, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_Raise(__pyx_t_5, 0, 0, 0); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __PYX_ERR(2, 146, __pyx_L1_error) /* "View.MemoryView":145 * self._strides = self._shape + self.ndim * * if not self._shape: # <<<<<<<<<<<<<< * raise MemoryError("unable to allocate shape and strides.") * */ } /* "View.MemoryView":149 * * * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<< * if dim <= 0: * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) */ __pyx_t_7 = 0; __pyx_t_5 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_5); __pyx_t_1 = 0; for (;;) { if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_5)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_1); __Pyx_INCREF(__pyx_t_3); __pyx_t_1++; if (unlikely(0 < 0)) __PYX_ERR(2, 149, __pyx_L1_error) #else __pyx_t_3 = PySequence_ITEM(__pyx_t_5, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 149, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); #endif __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_3); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 149, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_v_dim = __pyx_t_8; __pyx_v_idx = __pyx_t_7; __pyx_t_7 = (__pyx_t_7 + 1); /* "View.MemoryView":150 * * for idx, dim in enumerate(shape): * if dim <= 0: # <<<<<<<<<<<<<< * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) * self._shape[idx] = dim */ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0); if (__pyx_t_4) { /* "View.MemoryView":151 * for idx, dim in enumerate(shape): * if dim <= 0: * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<< * self._shape[idx] = dim * */ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 151, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 151, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 151, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_10); __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9); __pyx_t_3 = 0; __pyx_t_9 = 0; __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 151, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) __PYX_ERR(2, 151, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_10); __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9); __pyx_t_9 = 0; __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 151, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; __Pyx_Raise(__pyx_t_9, 0, 0, 0); __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; __PYX_ERR(2, 151, __pyx_L1_error) /* "View.MemoryView":150 * * for idx, dim in enumerate(shape): * if dim <= 0: # <<<<<<<<<<<<<< * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) * self._shape[idx] = dim */ } /* "View.MemoryView":152 * if dim <= 0: * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) * self._shape[idx] = dim # <<<<<<<<<<<<<< * * cdef char order */ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim; /* "View.MemoryView":149 * * * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<< * if dim <= 0: * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) */ } __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; /* "View.MemoryView":155 * * cdef char order * if mode == 'fortran': # <<<<<<<<<<<<<< * order = b'F' * self.mode = u'fortran' */ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 155, __pyx_L1_error) if (__pyx_t_4) { /* "View.MemoryView":156 * cdef char order * if mode == 'fortran': * order = b'F' # <<<<<<<<<<<<<< * self.mode = u'fortran' * elif mode == 'c': */ __pyx_v_order = 'F'; /* "View.MemoryView":157 * if mode == 'fortran': * order = b'F' * self.mode = u'fortran' # <<<<<<<<<<<<<< * elif mode == 'c': * order = b'C' */ __Pyx_INCREF(__pyx_n_u_fortran); __Pyx_GIVEREF(__pyx_n_u_fortran); __Pyx_GOTREF(__pyx_v_self->mode); __Pyx_DECREF(__pyx_v_self->mode); __pyx_v_self->mode = __pyx_n_u_fortran; /* "View.MemoryView":155 * * cdef char order * if mode == 'fortran': # <<<<<<<<<<<<<< * order = b'F' * self.mode = u'fortran' */ goto __pyx_L10; } /* "View.MemoryView":158 * order = b'F' * self.mode = u'fortran' * elif mode == 'c': # <<<<<<<<<<<<<< * order = b'C' * self.mode = u'c' */ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 158, __pyx_L1_error) if (__pyx_t_4) { /* "View.MemoryView":159 * self.mode = u'fortran' * elif mode == 'c': * order = b'C' # <<<<<<<<<<<<<< * self.mode = u'c' * else: */ __pyx_v_order = 'C'; /* "View.MemoryView":160 * elif mode == 'c': * order = b'C' * self.mode = u'c' # <<<<<<<<<<<<<< * else: * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) */ __Pyx_INCREF(__pyx_n_u_c); __Pyx_GIVEREF(__pyx_n_u_c); __Pyx_GOTREF(__pyx_v_self->mode); __Pyx_DECREF(__pyx_v_self->mode); __pyx_v_self->mode = __pyx_n_u_c; /* "View.MemoryView":158 * order = b'F' * self.mode = u'fortran' * elif mode == 'c': # <<<<<<<<<<<<<< * order = b'C' * self.mode = u'c' */ goto __pyx_L10; } /* "View.MemoryView":162 * self.mode = u'c' * else: * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<< * * self.len = fill_contig_strides_array(self._shape, self._strides, */ /*else*/ { __pyx_t_5 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 162, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 162, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_5); __pyx_t_5 = 0; __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 162, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; __Pyx_Raise(__pyx_t_5, 0, 0, 0); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __PYX_ERR(2, 162, __pyx_L1_error) } __pyx_L10:; /* "View.MemoryView":164 * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) * * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<< * itemsize, self.ndim, order) * */ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order); /* "View.MemoryView":167 * itemsize, self.ndim, order) * * self.free_data = allocate_buffer # <<<<<<<<<<<<<< * self.dtype_is_object = format == b'O' * if allocate_buffer: */ __pyx_v_self->free_data = __pyx_v_allocate_buffer; /* "View.MemoryView":168 * * self.free_data = allocate_buffer * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<< * if allocate_buffer: * */ __pyx_t_5 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 168, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 168, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_self->dtype_is_object = __pyx_t_4; /* "View.MemoryView":169 * self.free_data = allocate_buffer * self.dtype_is_object = format == b'O' * if allocate_buffer: # <<<<<<<<<<<<<< * * */ __pyx_t_4 = (__pyx_v_allocate_buffer != 0); if (__pyx_t_4) { /* "View.MemoryView":172 * * * self.data = malloc(self.len) # <<<<<<<<<<<<<< * if not self.data: * raise MemoryError("unable to allocate array data.") */ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len)); /* "View.MemoryView":173 * * self.data = malloc(self.len) * if not self.data: # <<<<<<<<<<<<<< * raise MemoryError("unable to allocate array data.") * */ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0); if (__pyx_t_4) { /* "View.MemoryView":174 * self.data = malloc(self.len) * if not self.data: * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<< * * if self.dtype_is_object: */ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 174, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_Raise(__pyx_t_5, 0, 0, 0); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __PYX_ERR(2, 174, __pyx_L1_error) /* "View.MemoryView":173 * * self.data = malloc(self.len) * if not self.data: # <<<<<<<<<<<<<< * raise MemoryError("unable to allocate array data.") * */ } /* "View.MemoryView":176 * raise MemoryError("unable to allocate array data.") * * if self.dtype_is_object: # <<<<<<<<<<<<<< * p = self.data * for i in range(self.len / itemsize): */ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0); if (__pyx_t_4) { /* "View.MemoryView":177 * * if self.dtype_is_object: * p = self.data # <<<<<<<<<<<<<< * for i in range(self.len / itemsize): * p[i] = Py_None */ __pyx_v_p = ((PyObject **)__pyx_v_self->data); /* "View.MemoryView":178 * if self.dtype_is_object: * p = self.data * for i in range(self.len / itemsize): # <<<<<<<<<<<<<< * p[i] = Py_None * Py_INCREF(Py_None) */ if (unlikely(__pyx_v_itemsize == 0)) { PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); __PYX_ERR(2, 178, __pyx_L1_error) } else if (sizeof(Py_ssize_t) == sizeof(long) && (!(((Py_ssize_t)-1) > 0)) && unlikely(__pyx_v_itemsize == (Py_ssize_t)-1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) { PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); __PYX_ERR(2, 178, __pyx_L1_error) } __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize); for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) { __pyx_v_i = __pyx_t_8; /* "View.MemoryView":179 * p = self.data * for i in range(self.len / itemsize): * p[i] = Py_None # <<<<<<<<<<<<<< * Py_INCREF(Py_None) * */ (__pyx_v_p[__pyx_v_i]) = Py_None; /* "View.MemoryView":180 * for i in range(self.len / itemsize): * p[i] = Py_None * Py_INCREF(Py_None) # <<<<<<<<<<<<<< * * @cname('getbuffer') */ Py_INCREF(Py_None); } /* "View.MemoryView":176 * raise MemoryError("unable to allocate array data.") * * if self.dtype_is_object: # <<<<<<<<<<<<<< * p = self.data * for i in range(self.len / itemsize): */ } /* "View.MemoryView":169 * self.free_data = allocate_buffer * self.dtype_is_object = format == b'O' * if allocate_buffer: # <<<<<<<<<<<<<< * * */ } /* "View.MemoryView":120 * cdef bint dtype_is_object * * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<< * mode="c", bint allocate_buffer=True): * */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_9); __Pyx_XDECREF(__pyx_t_10); __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_XDECREF(__pyx_v_format); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":183 * * @cname('getbuffer') * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< * cdef int bufmode = -1 * if self.mode == u"c": */ /* Python wrapper */ static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { int __pyx_v_bufmode; int __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; char *__pyx_t_4; Py_ssize_t __pyx_t_5; int __pyx_t_6; Py_ssize_t *__pyx_t_7; __Pyx_RefNannySetupContext("__getbuffer__", 0); if (__pyx_v_info != NULL) { __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); __Pyx_GIVEREF(__pyx_v_info->obj); } /* "View.MemoryView":184 * @cname('getbuffer') * def __getbuffer__(self, Py_buffer *info, int flags): * cdef int bufmode = -1 # <<<<<<<<<<<<<< * if self.mode == u"c": * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS */ __pyx_v_bufmode = -1; /* "View.MemoryView":185 * def __getbuffer__(self, Py_buffer *info, int flags): * cdef int bufmode = -1 * if self.mode == u"c": # <<<<<<<<<<<<<< * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * elif self.mode == u"fortran": */ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 185, __pyx_L1_error) __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "View.MemoryView":186 * cdef int bufmode = -1 * if self.mode == u"c": * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<< * elif self.mode == u"fortran": * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS */ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS); /* "View.MemoryView":185 * def __getbuffer__(self, Py_buffer *info, int flags): * cdef int bufmode = -1 * if self.mode == u"c": # <<<<<<<<<<<<<< * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * elif self.mode == u"fortran": */ goto __pyx_L3; } /* "View.MemoryView":187 * if self.mode == u"c": * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * elif self.mode == u"fortran": # <<<<<<<<<<<<<< * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * if not (flags & bufmode): */ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(2, 187, __pyx_L1_error) __pyx_t_1 = (__pyx_t_2 != 0); if (__pyx_t_1) { /* "View.MemoryView":188 * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * elif self.mode == u"fortran": * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<< * if not (flags & bufmode): * raise ValueError("Can only create a buffer that is contiguous in memory.") */ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS); /* "View.MemoryView":187 * if self.mode == u"c": * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * elif self.mode == u"fortran": # <<<<<<<<<<<<<< * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * if not (flags & bufmode): */ } __pyx_L3:; /* "View.MemoryView":189 * elif self.mode == u"fortran": * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * if not (flags & bufmode): # <<<<<<<<<<<<<< * raise ValueError("Can only create a buffer that is contiguous in memory.") * info.buf = self.data */ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0); if (__pyx_t_1) { /* "View.MemoryView":190 * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * if not (flags & bufmode): * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<< * info.buf = self.data * info.len = self.len */ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 190, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(2, 190, __pyx_L1_error) /* "View.MemoryView":189 * elif self.mode == u"fortran": * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * if not (flags & bufmode): # <<<<<<<<<<<<<< * raise ValueError("Can only create a buffer that is contiguous in memory.") * info.buf = self.data */ } /* "View.MemoryView":191 * if not (flags & bufmode): * raise ValueError("Can only create a buffer that is contiguous in memory.") * info.buf = self.data # <<<<<<<<<<<<<< * info.len = self.len * info.ndim = self.ndim */ __pyx_t_4 = __pyx_v_self->data; __pyx_v_info->buf = __pyx_t_4; /* "View.MemoryView":192 * raise ValueError("Can only create a buffer that is contiguous in memory.") * info.buf = self.data * info.len = self.len # <<<<<<<<<<<<<< * info.ndim = self.ndim * info.shape = self._shape */ __pyx_t_5 = __pyx_v_self->len; __pyx_v_info->len = __pyx_t_5; /* "View.MemoryView":193 * info.buf = self.data * info.len = self.len * info.ndim = self.ndim # <<<<<<<<<<<<<< * info.shape = self._shape * info.strides = self._strides */ __pyx_t_6 = __pyx_v_self->ndim; __pyx_v_info->ndim = __pyx_t_6; /* "View.MemoryView":194 * info.len = self.len * info.ndim = self.ndim * info.shape = self._shape # <<<<<<<<<<<<<< * info.strides = self._strides * info.suboffsets = NULL */ __pyx_t_7 = __pyx_v_self->_shape; __pyx_v_info->shape = __pyx_t_7; /* "View.MemoryView":195 * info.ndim = self.ndim * info.shape = self._shape * info.strides = self._strides # <<<<<<<<<<<<<< * info.suboffsets = NULL * info.itemsize = self.itemsize */ __pyx_t_7 = __pyx_v_self->_strides; __pyx_v_info->strides = __pyx_t_7; /* "View.MemoryView":196 * info.shape = self._shape * info.strides = self._strides * info.suboffsets = NULL # <<<<<<<<<<<<<< * info.itemsize = self.itemsize * info.readonly = 0 */ __pyx_v_info->suboffsets = NULL; /* "View.MemoryView":197 * info.strides = self._strides * info.suboffsets = NULL * info.itemsize = self.itemsize # <<<<<<<<<<<<<< * info.readonly = 0 * */ __pyx_t_5 = __pyx_v_self->itemsize; __pyx_v_info->itemsize = __pyx_t_5; /* "View.MemoryView":198 * info.suboffsets = NULL * info.itemsize = self.itemsize * info.readonly = 0 # <<<<<<<<<<<<<< * * if flags & PyBUF_FORMAT: */ __pyx_v_info->readonly = 0; /* "View.MemoryView":200 * info.readonly = 0 * * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< * info.format = self.format * else: */ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); if (__pyx_t_1) { /* "View.MemoryView":201 * * if flags & PyBUF_FORMAT: * info.format = self.format # <<<<<<<<<<<<<< * else: * info.format = NULL */ __pyx_t_4 = __pyx_v_self->format; __pyx_v_info->format = __pyx_t_4; /* "View.MemoryView":200 * info.readonly = 0 * * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< * info.format = self.format * else: */ goto __pyx_L5; } /* "View.MemoryView":203 * info.format = self.format * else: * info.format = NULL # <<<<<<<<<<<<<< * * info.obj = self */ /*else*/ { __pyx_v_info->format = NULL; } __pyx_L5:; /* "View.MemoryView":205 * info.format = NULL * * info.obj = self # <<<<<<<<<<<<<< * * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") */ __Pyx_INCREF(((PyObject *)__pyx_v_self)); __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); __Pyx_GOTREF(__pyx_v_info->obj); __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = ((PyObject *)__pyx_v_self); /* "View.MemoryView":183 * * @cname('getbuffer') * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< * cdef int bufmode = -1 * if self.mode == u"c": */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) { __Pyx_GOTREF(__pyx_v_info->obj); __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL; } goto __pyx_L2; __pyx_L0:; if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) { __Pyx_GOTREF(Py_None); __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL; } __pyx_L2:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":209 * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") * * def __dealloc__(array self): # <<<<<<<<<<<<<< * if self.callback_free_data != NULL: * self.callback_free_data(self.data) */ /* Python wrapper */ static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/ static void __pyx_array___dealloc__(PyObject *__pyx_v_self) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); } static void __pyx_array___pyx_pf_15View_dot_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) { __Pyx_RefNannyDeclarations int __pyx_t_1; __Pyx_RefNannySetupContext("__dealloc__", 0); /* "View.MemoryView":210 * * def __dealloc__(array self): * if self.callback_free_data != NULL: # <<<<<<<<<<<<<< * self.callback_free_data(self.data) * elif self.free_data: */ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":211 * def __dealloc__(array self): * if self.callback_free_data != NULL: * self.callback_free_data(self.data) # <<<<<<<<<<<<<< * elif self.free_data: * if self.dtype_is_object: */ __pyx_v_self->callback_free_data(__pyx_v_self->data); /* "View.MemoryView":210 * * def __dealloc__(array self): * if self.callback_free_data != NULL: # <<<<<<<<<<<<<< * self.callback_free_data(self.data) * elif self.free_data: */ goto __pyx_L3; } /* "View.MemoryView":212 * if self.callback_free_data != NULL: * self.callback_free_data(self.data) * elif self.free_data: # <<<<<<<<<<<<<< * if self.dtype_is_object: * refcount_objects_in_slice(self.data, self._shape, */ __pyx_t_1 = (__pyx_v_self->free_data != 0); if (__pyx_t_1) { /* "View.MemoryView":213 * self.callback_free_data(self.data) * elif self.free_data: * if self.dtype_is_object: # <<<<<<<<<<<<<< * refcount_objects_in_slice(self.data, self._shape, * self._strides, self.ndim, False) */ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0); if (__pyx_t_1) { /* "View.MemoryView":214 * elif self.free_data: * if self.dtype_is_object: * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<< * self._strides, self.ndim, False) * free(self.data) */ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0); /* "View.MemoryView":213 * self.callback_free_data(self.data) * elif self.free_data: * if self.dtype_is_object: # <<<<<<<<<<<<<< * refcount_objects_in_slice(self.data, self._shape, * self._strides, self.ndim, False) */ } /* "View.MemoryView":216 * refcount_objects_in_slice(self.data, self._shape, * self._strides, self.ndim, False) * free(self.data) # <<<<<<<<<<<<<< * PyObject_Free(self._shape) * */ free(__pyx_v_self->data); /* "View.MemoryView":212 * if self.callback_free_data != NULL: * self.callback_free_data(self.data) * elif self.free_data: # <<<<<<<<<<<<<< * if self.dtype_is_object: * refcount_objects_in_slice(self.data, self._shape, */ } __pyx_L3:; /* "View.MemoryView":217 * self._strides, self.ndim, False) * free(self.data) * PyObject_Free(self._shape) # <<<<<<<<<<<<<< * * @property */ PyObject_Free(__pyx_v_self->_shape); /* "View.MemoryView":209 * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") * * def __dealloc__(array self): # <<<<<<<<<<<<<< * if self.callback_free_data != NULL: * self.callback_free_data(self.data) */ /* function exit code */ __Pyx_RefNannyFinishContext(); } /* "View.MemoryView":220 * * @property * def memview(self): # <<<<<<<<<<<<<< * return self.get_memview() * */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":221 * @property * def memview(self): * return self.get_memview() # <<<<<<<<<<<<<< * * @cname('get_memview') */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = ((struct __pyx_vtabstruct_array *)__pyx_v_self->__pyx_vtab)->get_memview(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 221, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "View.MemoryView":220 * * @property * def memview(self): # <<<<<<<<<<<<<< * return self.get_memview() * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":224 * * @cname('get_memview') * cdef get_memview(self): # <<<<<<<<<<<<<< * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE * return memoryview(self, flags, self.dtype_is_object) */ static PyObject *__pyx_array_get_memview(struct __pyx_array_obj *__pyx_v_self) { int __pyx_v_flags; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; __Pyx_RefNannySetupContext("get_memview", 0); /* "View.MemoryView":225 * @cname('get_memview') * cdef get_memview(self): * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<< * return memoryview(self, flags, self.dtype_is_object) * */ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE); /* "View.MemoryView":226 * cdef get_memview(self): * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 226, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 226, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 226, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_INCREF(((PyObject *)__pyx_v_self)); __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self)); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2); __pyx_t_1 = 0; __pyx_t_2 = 0; __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 226, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "View.MemoryView":224 * * @cname('get_memview') * cdef get_memview(self): # <<<<<<<<<<<<<< * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE * return memoryview(self, flags, self.dtype_is_object) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("View.MemoryView.array.get_memview", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":229 * * * def __getattr__(self, attr): # <<<<<<<<<<<<<< * return getattr(self.memview, attr) * */ /* Python wrapper */ static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/ static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0); __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; __Pyx_RefNannySetupContext("__getattr__", 0); /* "View.MemoryView":230 * * def __getattr__(self, attr): * return getattr(self.memview, attr) # <<<<<<<<<<<<<< * * def __getitem__(self, item): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 230, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 230, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "View.MemoryView":229 * * * def __getattr__(self, attr): # <<<<<<<<<<<<<< * return getattr(self.memview, attr) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":232 * return getattr(self.memview, attr) * * def __getitem__(self, item): # <<<<<<<<<<<<<< * return self.memview[item] * */ /* Python wrapper */ static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_array___pyx_pf_15View_dot_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; __Pyx_RefNannySetupContext("__getitem__", 0); /* "View.MemoryView":233 * * def __getitem__(self, item): * return self.memview[item] # <<<<<<<<<<<<<< * * def __setitem__(self, item, value): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 233, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 233, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "View.MemoryView":232 * return getattr(self.memview, attr) * * def __getitem__(self, item): # <<<<<<<<<<<<<< * return self.memview[item] * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":235 * return self.memview[item] * * def __setitem__(self, item, value): # <<<<<<<<<<<<<< * self.memview[item] = value * */ /* Python wrapper */ static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/ static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); __pyx_r = __pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_array___pyx_pf_15View_dot_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__setitem__", 0); /* "View.MemoryView":236 * * def __setitem__(self, item, value): * self.memview[item] = value # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 236, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) __PYX_ERR(2, 236, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":235 * return self.memview[item] * * def __setitem__(self, item, value): # <<<<<<<<<<<<<< * self.memview[item] = value * */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":240 * * @cname("__pyx_array_new") * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<< * char *mode, char *buf): * cdef array result */ static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) { struct __pyx_array_obj *__pyx_v_result = 0; struct __pyx_array_obj *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; __Pyx_RefNannySetupContext("array_cwrapper", 0); /* "View.MemoryView":244 * cdef array result * * if buf == NULL: # <<<<<<<<<<<<<< * result = array(shape, itemsize, format, mode.decode('ASCII')) * else: */ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":245 * * if buf == NULL: * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<< * else: * result = array(shape, itemsize, format, mode.decode('ASCII'), */ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 245, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 245, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 245, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 245, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_INCREF(__pyx_v_shape); __Pyx_GIVEREF(__pyx_v_shape); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape); __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4); __pyx_t_2 = 0; __pyx_t_3 = 0; __pyx_t_4 = 0; __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_array_type), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 245, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4); __pyx_t_4 = 0; /* "View.MemoryView":244 * cdef array result * * if buf == NULL: # <<<<<<<<<<<<<< * result = array(shape, itemsize, format, mode.decode('ASCII')) * else: */ goto __pyx_L3; } /* "View.MemoryView":247 * result = array(shape, itemsize, format, mode.decode('ASCII')) * else: * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<< * allocate_buffer=False) * result.data = buf */ /*else*/ { __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 247, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 247, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 247, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 247, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(__pyx_v_shape); __Pyx_GIVEREF(__pyx_v_shape); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3); __pyx_t_4 = 0; __pyx_t_5 = 0; __pyx_t_3 = 0; /* "View.MemoryView":248 * else: * result = array(shape, itemsize, format, mode.decode('ASCII'), * allocate_buffer=False) # <<<<<<<<<<<<<< * result.data = buf * */ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 248, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) __PYX_ERR(2, 248, __pyx_L1_error) /* "View.MemoryView":247 * result = array(shape, itemsize, format, mode.decode('ASCII')) * else: * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<< * allocate_buffer=False) * result.data = buf */ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)__pyx_array_type), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 247, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5); __pyx_t_5 = 0; /* "View.MemoryView":249 * result = array(shape, itemsize, format, mode.decode('ASCII'), * allocate_buffer=False) * result.data = buf # <<<<<<<<<<<<<< * * return result */ __pyx_v_result->data = __pyx_v_buf; } __pyx_L3:; /* "View.MemoryView":251 * result.data = buf * * return result # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(((PyObject *)__pyx_r)); __Pyx_INCREF(((PyObject *)__pyx_v_result)); __pyx_r = __pyx_v_result; goto __pyx_L0; /* "View.MemoryView":240 * * @cname("__pyx_array_new") * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<< * char *mode, char *buf): * cdef array result */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_result); __Pyx_XGIVEREF((PyObject *)__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":277 * cdef class Enum(object): * cdef object name * def __init__(self, name): # <<<<<<<<<<<<<< * self.name = name * def __repr__(self): */ /* Python wrapper */ static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_name = 0; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0}; PyObject* values[1] = {0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(2, 277, __pyx_L3_error) } } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { goto __pyx_L5_argtuple_error; } else { values[0] = PyTuple_GET_ITEM(__pyx_args, 0); } __pyx_v_name = values[0]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 277, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__init__", 0); /* "View.MemoryView":278 * cdef object name * def __init__(self, name): * self.name = name # <<<<<<<<<<<<<< * def __repr__(self): * return self.name */ __Pyx_INCREF(__pyx_v_name); __Pyx_GIVEREF(__pyx_v_name); __Pyx_GOTREF(__pyx_v_self->name); __Pyx_DECREF(__pyx_v_self->name); __pyx_v_self->name = __pyx_v_name; /* "View.MemoryView":277 * cdef class Enum(object): * cdef object name * def __init__(self, name): # <<<<<<<<<<<<<< * self.name = name * def __repr__(self): */ /* function exit code */ __pyx_r = 0; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":279 * def __init__(self, name): * self.name = name * def __repr__(self): # <<<<<<<<<<<<<< * return self.name * */ /* Python wrapper */ static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); __pyx_r = __pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_MemviewEnum___pyx_pf_15View_dot_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__repr__", 0); /* "View.MemoryView":280 * self.name = name * def __repr__(self): * return self.name # <<<<<<<<<<<<<< * * cdef generic = Enum("") */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_self->name); __pyx_r = __pyx_v_self->name; goto __pyx_L0; /* "View.MemoryView":279 * def __init__(self, name): * self.name = name * def __repr__(self): # <<<<<<<<<<<<<< * return self.name * */ /* function exit code */ __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":294 * * @cname('__pyx_align_pointer') * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<< * "Align pointer memory on a given boundary" * cdef Py_intptr_t aligned_p = memory */ static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) { Py_intptr_t __pyx_v_aligned_p; size_t __pyx_v_offset; void *__pyx_r; int __pyx_t_1; /* "View.MemoryView":296 * cdef void *align_pointer(void *memory, size_t alignment) nogil: * "Align pointer memory on a given boundary" * cdef Py_intptr_t aligned_p = memory # <<<<<<<<<<<<<< * cdef size_t offset * */ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory); /* "View.MemoryView":300 * * with cython.cdivision(True): * offset = aligned_p % alignment # <<<<<<<<<<<<<< * * if offset > 0: */ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment); /* "View.MemoryView":302 * offset = aligned_p % alignment * * if offset > 0: # <<<<<<<<<<<<<< * aligned_p += alignment - offset * */ __pyx_t_1 = ((__pyx_v_offset > 0) != 0); if (__pyx_t_1) { /* "View.MemoryView":303 * * if offset > 0: * aligned_p += alignment - offset # <<<<<<<<<<<<<< * * return aligned_p */ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset)); /* "View.MemoryView":302 * offset = aligned_p % alignment * * if offset > 0: # <<<<<<<<<<<<<< * aligned_p += alignment - offset * */ } /* "View.MemoryView":305 * aligned_p += alignment - offset * * return aligned_p # <<<<<<<<<<<<<< * * */ __pyx_r = ((void *)__pyx_v_aligned_p); goto __pyx_L0; /* "View.MemoryView":294 * * @cname('__pyx_align_pointer') * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<< * "Align pointer memory on a given boundary" * cdef Py_intptr_t aligned_p = memory */ /* function exit code */ __pyx_L0:; return __pyx_r; } /* "View.MemoryView":341 * cdef __Pyx_TypeInfo *typeinfo * * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<< * self.obj = obj * self.flags = flags */ /* Python wrapper */ static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_obj = 0; int __pyx_v_flags; int __pyx_v_dtype_is_object; int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); { static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0}; PyObject* values[3] = {0,0,0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); switch (pos_args) { case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); case 0: break; default: goto __pyx_L5_argtuple_error; } kw_args = PyDict_Size(__pyx_kwds); switch (pos_args) { case 0: if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--; else goto __pyx_L5_argtuple_error; case 1: if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); __PYX_ERR(2, 341, __pyx_L3_error) } case 2: if (kw_args > 0) { PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object); if (value) { values[2] = value; kw_args--; } } } if (unlikely(kw_args > 0)) { if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(2, 341, __pyx_L3_error) } } else { switch (PyTuple_GET_SIZE(__pyx_args)) { case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); values[0] = PyTuple_GET_ITEM(__pyx_args, 0); break; default: goto __pyx_L5_argtuple_error; } } __pyx_v_obj = values[0]; __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 341, __pyx_L3_error) if (values[2]) { __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 341, __pyx_L3_error) } else { __pyx_v_dtype_is_object = ((int)0); } } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(2, 341, __pyx_L3_error) __pyx_L3_error:; __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return -1; __pyx_L4_argument_unpacking_done:; __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) { int __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; int __pyx_t_3; int __pyx_t_4; __Pyx_RefNannySetupContext("__cinit__", 0); /* "View.MemoryView":342 * * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): * self.obj = obj # <<<<<<<<<<<<<< * self.flags = flags * if type(self) is memoryview or obj is not None: */ __Pyx_INCREF(__pyx_v_obj); __Pyx_GIVEREF(__pyx_v_obj); __Pyx_GOTREF(__pyx_v_self->obj); __Pyx_DECREF(__pyx_v_self->obj); __pyx_v_self->obj = __pyx_v_obj; /* "View.MemoryView":343 * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): * self.obj = obj * self.flags = flags # <<<<<<<<<<<<<< * if type(self) is memoryview or obj is not None: * __Pyx_GetBuffer(obj, &self.view, flags) */ __pyx_v_self->flags = __pyx_v_flags; /* "View.MemoryView":344 * self.obj = obj * self.flags = flags * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<< * __Pyx_GetBuffer(obj, &self.view, flags) * if self.view.obj == NULL: */ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)__pyx_memoryview_type)); __pyx_t_3 = (__pyx_t_2 != 0); if (!__pyx_t_3) { } else { __pyx_t_1 = __pyx_t_3; goto __pyx_L4_bool_binop_done; } __pyx_t_3 = (__pyx_v_obj != Py_None); __pyx_t_2 = (__pyx_t_3 != 0); __pyx_t_1 = __pyx_t_2; __pyx_L4_bool_binop_done:; if (__pyx_t_1) { /* "View.MemoryView":345 * self.flags = flags * if type(self) is memoryview or obj is not None: * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<< * if self.view.obj == NULL: * (<__pyx_buffer *> &self.view).obj = Py_None */ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) __PYX_ERR(2, 345, __pyx_L1_error) /* "View.MemoryView":346 * if type(self) is memoryview or obj is not None: * __Pyx_GetBuffer(obj, &self.view, flags) * if self.view.obj == NULL: # <<<<<<<<<<<<<< * (<__pyx_buffer *> &self.view).obj = Py_None * Py_INCREF(Py_None) */ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":347 * __Pyx_GetBuffer(obj, &self.view, flags) * if self.view.obj == NULL: * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<< * Py_INCREF(Py_None) * */ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None; /* "View.MemoryView":348 * if self.view.obj == NULL: * (<__pyx_buffer *> &self.view).obj = Py_None * Py_INCREF(Py_None) # <<<<<<<<<<<<<< * * global __pyx_memoryview_thread_locks_used */ Py_INCREF(Py_None); /* "View.MemoryView":346 * if type(self) is memoryview or obj is not None: * __Pyx_GetBuffer(obj, &self.view, flags) * if self.view.obj == NULL: # <<<<<<<<<<<<<< * (<__pyx_buffer *> &self.view).obj = Py_None * Py_INCREF(Py_None) */ } /* "View.MemoryView":344 * self.obj = obj * self.flags = flags * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<< * __Pyx_GetBuffer(obj, &self.view, flags) * if self.view.obj == NULL: */ } /* "View.MemoryView":351 * * global __pyx_memoryview_thread_locks_used * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: # <<<<<<<<<<<<<< * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] * __pyx_memoryview_thread_locks_used += 1 */ __pyx_t_1 = ((__pyx_memoryview_thread_locks_used < 8) != 0); if (__pyx_t_1) { /* "View.MemoryView":352 * global __pyx_memoryview_thread_locks_used * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] # <<<<<<<<<<<<<< * __pyx_memoryview_thread_locks_used += 1 * if self.lock is NULL: */ __pyx_v_self->lock = (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]); /* "View.MemoryView":353 * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] * __pyx_memoryview_thread_locks_used += 1 # <<<<<<<<<<<<<< * if self.lock is NULL: * self.lock = PyThread_allocate_lock() */ __pyx_memoryview_thread_locks_used = (__pyx_memoryview_thread_locks_used + 1); /* "View.MemoryView":351 * * global __pyx_memoryview_thread_locks_used * if __pyx_memoryview_thread_locks_used < THREAD_LOCKS_PREALLOCATED: # <<<<<<<<<<<<<< * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] * __pyx_memoryview_thread_locks_used += 1 */ } /* "View.MemoryView":354 * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] * __pyx_memoryview_thread_locks_used += 1 * if self.lock is NULL: # <<<<<<<<<<<<<< * self.lock = PyThread_allocate_lock() * if self.lock is NULL: */ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":355 * __pyx_memoryview_thread_locks_used += 1 * if self.lock is NULL: * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<< * if self.lock is NULL: * raise MemoryError */ __pyx_v_self->lock = PyThread_allocate_lock(); /* "View.MemoryView":356 * if self.lock is NULL: * self.lock = PyThread_allocate_lock() * if self.lock is NULL: # <<<<<<<<<<<<<< * raise MemoryError * */ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":357 * self.lock = PyThread_allocate_lock() * if self.lock is NULL: * raise MemoryError # <<<<<<<<<<<<<< * * if flags & PyBUF_FORMAT: */ PyErr_NoMemory(); __PYX_ERR(2, 357, __pyx_L1_error) /* "View.MemoryView":356 * if self.lock is NULL: * self.lock = PyThread_allocate_lock() * if self.lock is NULL: # <<<<<<<<<<<<<< * raise MemoryError * */ } /* "View.MemoryView":354 * self.lock = __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] * __pyx_memoryview_thread_locks_used += 1 * if self.lock is NULL: # <<<<<<<<<<<<<< * self.lock = PyThread_allocate_lock() * if self.lock is NULL: */ } /* "View.MemoryView":359 * raise MemoryError * * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') * else: */ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); if (__pyx_t_1) { /* "View.MemoryView":360 * * if flags & PyBUF_FORMAT: * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') # <<<<<<<<<<<<<< * else: * self.dtype_is_object = dtype_is_object */ __pyx_t_2 = (((__pyx_v_self->view.format[0]) == 'O') != 0); if (__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L11_bool_binop_done; } __pyx_t_2 = (((__pyx_v_self->view.format[1]) == '\x00') != 0); __pyx_t_1 = __pyx_t_2; __pyx_L11_bool_binop_done:; __pyx_v_self->dtype_is_object = __pyx_t_1; /* "View.MemoryView":359 * raise MemoryError * * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') * else: */ goto __pyx_L10; } /* "View.MemoryView":362 * self.dtype_is_object = (self.view.format[0] == b'O' and self.view.format[1] == b'\0') * else: * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<< * * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( */ /*else*/ { __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object; } __pyx_L10:; /* "View.MemoryView":364 * self.dtype_is_object = dtype_is_object * * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<< * &self.acquisition_count[0], sizeof(__pyx_atomic_int)) * self.typeinfo = NULL */ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int)))); /* "View.MemoryView":366 * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( * &self.acquisition_count[0], sizeof(__pyx_atomic_int)) * self.typeinfo = NULL # <<<<<<<<<<<<<< * * def __dealloc__(memoryview self): */ __pyx_v_self->typeinfo = NULL; /* "View.MemoryView":341 * cdef __Pyx_TypeInfo *typeinfo * * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<< * self.obj = obj * self.flags = flags */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":368 * self.typeinfo = NULL * * def __dealloc__(memoryview self): # <<<<<<<<<<<<<< * if self.obj is not None: * __Pyx_ReleaseBuffer(&self.view) */ /* Python wrapper */ static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/ static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); } static void __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) { int __pyx_v_i; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; int __pyx_t_3; int __pyx_t_4; PyThread_type_lock __pyx_t_5; PyThread_type_lock __pyx_t_6; __Pyx_RefNannySetupContext("__dealloc__", 0); /* "View.MemoryView":369 * * def __dealloc__(memoryview self): * if self.obj is not None: # <<<<<<<<<<<<<< * __Pyx_ReleaseBuffer(&self.view) * */ __pyx_t_1 = (__pyx_v_self->obj != Py_None); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "View.MemoryView":370 * def __dealloc__(memoryview self): * if self.obj is not None: * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<< * * cdef int i */ __Pyx_ReleaseBuffer((&__pyx_v_self->view)); /* "View.MemoryView":369 * * def __dealloc__(memoryview self): * if self.obj is not None: # <<<<<<<<<<<<<< * __Pyx_ReleaseBuffer(&self.view) * */ } /* "View.MemoryView":374 * cdef int i * global __pyx_memoryview_thread_locks_used * if self.lock != NULL: # <<<<<<<<<<<<<< * for i in range(__pyx_memoryview_thread_locks_used): * if __pyx_memoryview_thread_locks[i] is self.lock: */ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0); if (__pyx_t_2) { /* "View.MemoryView":375 * global __pyx_memoryview_thread_locks_used * if self.lock != NULL: * for i in range(__pyx_memoryview_thread_locks_used): # <<<<<<<<<<<<<< * if __pyx_memoryview_thread_locks[i] is self.lock: * __pyx_memoryview_thread_locks_used -= 1 */ __pyx_t_3 = __pyx_memoryview_thread_locks_used; for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) { __pyx_v_i = __pyx_t_4; /* "View.MemoryView":376 * if self.lock != NULL: * for i in range(__pyx_memoryview_thread_locks_used): * if __pyx_memoryview_thread_locks[i] is self.lock: # <<<<<<<<<<<<<< * __pyx_memoryview_thread_locks_used -= 1 * if i != __pyx_memoryview_thread_locks_used: */ __pyx_t_2 = (((__pyx_memoryview_thread_locks[__pyx_v_i]) == __pyx_v_self->lock) != 0); if (__pyx_t_2) { /* "View.MemoryView":377 * for i in range(__pyx_memoryview_thread_locks_used): * if __pyx_memoryview_thread_locks[i] is self.lock: * __pyx_memoryview_thread_locks_used -= 1 # <<<<<<<<<<<<<< * if i != __pyx_memoryview_thread_locks_used: * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( */ __pyx_memoryview_thread_locks_used = (__pyx_memoryview_thread_locks_used - 1); /* "View.MemoryView":378 * if __pyx_memoryview_thread_locks[i] is self.lock: * __pyx_memoryview_thread_locks_used -= 1 * if i != __pyx_memoryview_thread_locks_used: # <<<<<<<<<<<<<< * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) */ __pyx_t_2 = ((__pyx_v_i != __pyx_memoryview_thread_locks_used) != 0); if (__pyx_t_2) { /* "View.MemoryView":380 * if i != __pyx_memoryview_thread_locks_used: * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) # <<<<<<<<<<<<<< * break * else: */ __pyx_t_5 = (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]); __pyx_t_6 = (__pyx_memoryview_thread_locks[__pyx_v_i]); /* "View.MemoryView":379 * __pyx_memoryview_thread_locks_used -= 1 * if i != __pyx_memoryview_thread_locks_used: * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( # <<<<<<<<<<<<<< * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) * break */ (__pyx_memoryview_thread_locks[__pyx_v_i]) = __pyx_t_5; (__pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used]) = __pyx_t_6; /* "View.MemoryView":378 * if __pyx_memoryview_thread_locks[i] is self.lock: * __pyx_memoryview_thread_locks_used -= 1 * if i != __pyx_memoryview_thread_locks_used: # <<<<<<<<<<<<<< * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) */ } /* "View.MemoryView":381 * __pyx_memoryview_thread_locks[i], __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used] = ( * __pyx_memoryview_thread_locks[__pyx_memoryview_thread_locks_used], __pyx_memoryview_thread_locks[i]) * break # <<<<<<<<<<<<<< * else: * PyThread_free_lock(self.lock) */ goto __pyx_L6_break; /* "View.MemoryView":376 * if self.lock != NULL: * for i in range(__pyx_memoryview_thread_locks_used): * if __pyx_memoryview_thread_locks[i] is self.lock: # <<<<<<<<<<<<<< * __pyx_memoryview_thread_locks_used -= 1 * if i != __pyx_memoryview_thread_locks_used: */ } } /*else*/ { /* "View.MemoryView":383 * break * else: * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<< * * cdef char *get_item_pointer(memoryview self, object index) except NULL: */ PyThread_free_lock(__pyx_v_self->lock); } __pyx_L6_break:; /* "View.MemoryView":374 * cdef int i * global __pyx_memoryview_thread_locks_used * if self.lock != NULL: # <<<<<<<<<<<<<< * for i in range(__pyx_memoryview_thread_locks_used): * if __pyx_memoryview_thread_locks[i] is self.lock: */ } /* "View.MemoryView":368 * self.typeinfo = NULL * * def __dealloc__(memoryview self): # <<<<<<<<<<<<<< * if self.obj is not None: * __Pyx_ReleaseBuffer(&self.view) */ /* function exit code */ __Pyx_RefNannyFinishContext(); } /* "View.MemoryView":385 * PyThread_free_lock(self.lock) * * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<< * cdef Py_ssize_t dim * cdef char *itemp = self.view.buf */ static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) { Py_ssize_t __pyx_v_dim; char *__pyx_v_itemp; PyObject *__pyx_v_idx = NULL; char *__pyx_r; __Pyx_RefNannyDeclarations Py_ssize_t __pyx_t_1; PyObject *__pyx_t_2 = NULL; Py_ssize_t __pyx_t_3; PyObject *(*__pyx_t_4)(PyObject *); PyObject *__pyx_t_5 = NULL; Py_ssize_t __pyx_t_6; char *__pyx_t_7; __Pyx_RefNannySetupContext("get_item_pointer", 0); /* "View.MemoryView":387 * cdef char *get_item_pointer(memoryview self, object index) except NULL: * cdef Py_ssize_t dim * cdef char *itemp = self.view.buf # <<<<<<<<<<<<<< * * for dim, idx in enumerate(index): */ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf); /* "View.MemoryView":389 * cdef char *itemp = self.view.buf * * for dim, idx in enumerate(index): # <<<<<<<<<<<<<< * itemp = pybuffer_index(&self.view, itemp, idx, dim) * */ __pyx_t_1 = 0; if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) { __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0; __pyx_t_4 = NULL; } else { __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 389, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 389, __pyx_L1_error) } for (;;) { if (likely(!__pyx_t_4)) { if (likely(PyList_CheckExact(__pyx_t_2))) { if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(2, 389, __pyx_L1_error) #else __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 389, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); #endif } else { if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(2, 389, __pyx_L1_error) #else __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 389, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); #endif } } else { __pyx_t_5 = __pyx_t_4(__pyx_t_2); if (unlikely(!__pyx_t_5)) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); else __PYX_ERR(2, 389, __pyx_L1_error) } break; } __Pyx_GOTREF(__pyx_t_5); } __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5); __pyx_t_5 = 0; __pyx_v_dim = __pyx_t_1; __pyx_t_1 = (__pyx_t_1 + 1); /* "View.MemoryView":390 * * for dim, idx in enumerate(index): * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<< * * return itemp */ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 390, __pyx_L1_error) __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) __PYX_ERR(2, 390, __pyx_L1_error) __pyx_v_itemp = __pyx_t_7; /* "View.MemoryView":389 * cdef char *itemp = self.view.buf * * for dim, idx in enumerate(index): # <<<<<<<<<<<<<< * itemp = pybuffer_index(&self.view, itemp, idx, dim) * */ } __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "View.MemoryView":392 * itemp = pybuffer_index(&self.view, itemp, idx, dim) * * return itemp # <<<<<<<<<<<<<< * * */ __pyx_r = __pyx_v_itemp; goto __pyx_L0; /* "View.MemoryView":385 * PyThread_free_lock(self.lock) * * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<< * cdef Py_ssize_t dim * cdef char *itemp = self.view.buf */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_idx); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":395 * * * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<< * if index is Ellipsis: * return self */ /* Python wrapper */ static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/ static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) { PyObject *__pyx_v_have_slices = NULL; PyObject *__pyx_v_indices = NULL; char *__pyx_v_itemp; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; char *__pyx_t_6; __Pyx_RefNannySetupContext("__getitem__", 0); /* "View.MemoryView":396 * * def __getitem__(memoryview self, object index): * if index is Ellipsis: # <<<<<<<<<<<<<< * return self * */ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "View.MemoryView":397 * def __getitem__(memoryview self, object index): * if index is Ellipsis: * return self # <<<<<<<<<<<<<< * * have_slices, indices = _unellipsify(index, self.view.ndim) */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_self)); __pyx_r = ((PyObject *)__pyx_v_self); goto __pyx_L0; /* "View.MemoryView":396 * * def __getitem__(memoryview self, object index): * if index is Ellipsis: # <<<<<<<<<<<<<< * return self * */ } /* "View.MemoryView":399 * return self * * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<< * * cdef char *itemp */ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 399, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); if (likely(__pyx_t_3 != Py_None)) { PyObject* sequence = __pyx_t_3; #if CYTHON_COMPILING_IN_CPYTHON Py_ssize_t size = Py_SIZE(sequence); #else Py_ssize_t size = PySequence_Size(sequence); #endif if (unlikely(size != 2)) { if (size > 2) __Pyx_RaiseTooManyValuesError(2); else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); __PYX_ERR(2, 399, __pyx_L1_error) } #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); __Pyx_INCREF(__pyx_t_4); __Pyx_INCREF(__pyx_t_5); #else __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 399, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 399, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); #endif __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } else { __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(2, 399, __pyx_L1_error) } __pyx_v_have_slices = __pyx_t_4; __pyx_t_4 = 0; __pyx_v_indices = __pyx_t_5; __pyx_t_5 = 0; /* "View.MemoryView":402 * * cdef char *itemp * if have_slices: # <<<<<<<<<<<<<< * return memview_slice(self, indices) * else: */ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(2, 402, __pyx_L1_error) if (__pyx_t_2) { /* "View.MemoryView":403 * cdef char *itemp * if have_slices: * return memview_slice(self, indices) # <<<<<<<<<<<<<< * else: * itemp = self.get_item_pointer(indices) */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 403, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; /* "View.MemoryView":402 * * cdef char *itemp * if have_slices: # <<<<<<<<<<<<<< * return memview_slice(self, indices) * else: */ } /* "View.MemoryView":405 * return memview_slice(self, indices) * else: * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<< * return self.convert_item_to_object(itemp) * */ /*else*/ { __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) __PYX_ERR(2, 405, __pyx_L1_error) __pyx_v_itemp = __pyx_t_6; /* "View.MemoryView":406 * else: * itemp = self.get_item_pointer(indices) * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<< * * def __setitem__(memoryview self, object index, object value): */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 406, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; } /* "View.MemoryView":395 * * * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<< * if index is Ellipsis: * return self */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_have_slices); __Pyx_XDECREF(__pyx_v_indices); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":408 * return self.convert_item_to_object(itemp) * * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<< * have_slices, index = _unellipsify(index, self.view.ndim) * */ /* Python wrapper */ static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/ static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { PyObject *__pyx_v_have_slices = NULL; PyObject *__pyx_v_obj = NULL; int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; int __pyx_t_4; __Pyx_RefNannySetupContext("__setitem__", 0); __Pyx_INCREF(__pyx_v_index); /* "View.MemoryView":409 * * def __setitem__(memoryview self, object index, object value): * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<< * * if have_slices: */ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 409, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (likely(__pyx_t_1 != Py_None)) { PyObject* sequence = __pyx_t_1; #if CYTHON_COMPILING_IN_CPYTHON Py_ssize_t size = Py_SIZE(sequence); #else Py_ssize_t size = PySequence_Size(sequence); #endif if (unlikely(size != 2)) { if (size > 2) __Pyx_RaiseTooManyValuesError(2); else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); __PYX_ERR(2, 409, __pyx_L1_error) } #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1); __Pyx_INCREF(__pyx_t_2); __Pyx_INCREF(__pyx_t_3); #else __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 409, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 409, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); #endif __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } else { __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(2, 409, __pyx_L1_error) } __pyx_v_have_slices = __pyx_t_2; __pyx_t_2 = 0; __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3); __pyx_t_3 = 0; /* "View.MemoryView":411 * have_slices, index = _unellipsify(index, self.view.ndim) * * if have_slices: # <<<<<<<<<<<<<< * obj = self.is_slice(value) * if obj: */ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 411, __pyx_L1_error) if (__pyx_t_4) { /* "View.MemoryView":412 * * if have_slices: * obj = self.is_slice(value) # <<<<<<<<<<<<<< * if obj: * self.setitem_slice_assignment(self[index], obj) */ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 412, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v_obj = __pyx_t_1; __pyx_t_1 = 0; /* "View.MemoryView":413 * if have_slices: * obj = self.is_slice(value) * if obj: # <<<<<<<<<<<<<< * self.setitem_slice_assignment(self[index], obj) * else: */ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(2, 413, __pyx_L1_error) if (__pyx_t_4) { /* "View.MemoryView":414 * obj = self.is_slice(value) * if obj: * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<< * else: * self.setitem_slice_assign_scalar(self[index], value) */ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 414, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 414, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "View.MemoryView":413 * if have_slices: * obj = self.is_slice(value) * if obj: # <<<<<<<<<<<<<< * self.setitem_slice_assignment(self[index], obj) * else: */ goto __pyx_L4; } /* "View.MemoryView":416 * self.setitem_slice_assignment(self[index], obj) * else: * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<< * else: * self.setitem_indexed(index, value) */ /*else*/ { __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 416, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) __PYX_ERR(2, 416, __pyx_L1_error) __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 416, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } __pyx_L4:; /* "View.MemoryView":411 * have_slices, index = _unellipsify(index, self.view.ndim) * * if have_slices: # <<<<<<<<<<<<<< * obj = self.is_slice(value) * if obj: */ goto __pyx_L3; } /* "View.MemoryView":418 * self.setitem_slice_assign_scalar(self[index], value) * else: * self.setitem_indexed(index, value) # <<<<<<<<<<<<<< * * cdef is_slice(self, obj): */ /*else*/ { __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 418, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } __pyx_L3:; /* "View.MemoryView":408 * return self.convert_item_to_object(itemp) * * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<< * have_slices, index = _unellipsify(index, self.view.ndim) * */ /* function exit code */ __pyx_r = 0; goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __pyx_L0:; __Pyx_XDECREF(__pyx_v_have_slices); __Pyx_XDECREF(__pyx_v_obj); __Pyx_XDECREF(__pyx_v_index); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":420 * self.setitem_indexed(index, value) * * cdef is_slice(self, obj): # <<<<<<<<<<<<<< * if not isinstance(obj, memoryview): * try: */ static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; PyObject *__pyx_t_8 = NULL; int __pyx_t_9; __Pyx_RefNannySetupContext("is_slice", 0); __Pyx_INCREF(__pyx_v_obj); /* "View.MemoryView":421 * * cdef is_slice(self, obj): * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<< * try: * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, */ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, __pyx_memoryview_type); __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); if (__pyx_t_2) { /* "View.MemoryView":422 * cdef is_slice(self, obj): * if not isinstance(obj, memoryview): * try: # <<<<<<<<<<<<<< * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, * self.dtype_is_object) */ { __Pyx_PyThreadState_declare __Pyx_PyThreadState_assign __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5); __Pyx_XGOTREF(__pyx_t_3); __Pyx_XGOTREF(__pyx_t_4); __Pyx_XGOTREF(__pyx_t_5); /*try:*/ { /* "View.MemoryView":423 * if not isinstance(obj, memoryview): * try: * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<< * self.dtype_is_object) * except TypeError: */ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 423, __pyx_L4_error) __Pyx_GOTREF(__pyx_t_6); /* "View.MemoryView":424 * try: * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, * self.dtype_is_object) # <<<<<<<<<<<<<< * except TypeError: * return None */ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 424, __pyx_L4_error) __Pyx_GOTREF(__pyx_t_7); /* "View.MemoryView":423 * if not isinstance(obj, memoryview): * try: * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<< * self.dtype_is_object) * except TypeError: */ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 423, __pyx_L4_error) __Pyx_GOTREF(__pyx_t_8); __Pyx_INCREF(__pyx_v_obj); __Pyx_GIVEREF(__pyx_v_obj); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj); __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7); __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 423, __pyx_L4_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7); __pyx_t_7 = 0; /* "View.MemoryView":422 * cdef is_slice(self, obj): * if not isinstance(obj, memoryview): * try: # <<<<<<<<<<<<<< * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, * self.dtype_is_object) */ } __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; goto __pyx_L11_try_end; __pyx_L4_error:; __Pyx_PyThreadState_assign __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; /* "View.MemoryView":425 * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, * self.dtype_is_object) * except TypeError: # <<<<<<<<<<<<<< * return None * */ __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError); if (__pyx_t_9) { __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) __PYX_ERR(2, 425, __pyx_L6_except_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_GOTREF(__pyx_t_8); __Pyx_GOTREF(__pyx_t_6); /* "View.MemoryView":426 * self.dtype_is_object) * except TypeError: * return None # <<<<<<<<<<<<<< * * return obj */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_None); __pyx_r = Py_None; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; goto __pyx_L7_except_return; } goto __pyx_L6_except_error; __pyx_L6_except_error:; /* "View.MemoryView":422 * cdef is_slice(self, obj): * if not isinstance(obj, memoryview): * try: # <<<<<<<<<<<<<< * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, * self.dtype_is_object) */ __Pyx_PyThreadState_assign __Pyx_XGIVEREF(__pyx_t_3); __Pyx_XGIVEREF(__pyx_t_4); __Pyx_XGIVEREF(__pyx_t_5); __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); goto __pyx_L1_error; __pyx_L7_except_return:; __Pyx_PyThreadState_assign __Pyx_XGIVEREF(__pyx_t_3); __Pyx_XGIVEREF(__pyx_t_4); __Pyx_XGIVEREF(__pyx_t_5); __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5); goto __pyx_L0; __pyx_L11_try_end:; } /* "View.MemoryView":421 * * cdef is_slice(self, obj): * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<< * try: * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, */ } /* "View.MemoryView":428 * return None * * return obj # <<<<<<<<<<<<<< * * cdef setitem_slice_assignment(self, dst, src): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_obj); __pyx_r = __pyx_v_obj; goto __pyx_L0; /* "View.MemoryView":420 * self.setitem_indexed(index, value) * * cdef is_slice(self, obj): # <<<<<<<<<<<<<< * if not isinstance(obj, memoryview): * try: */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_8); __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF(__pyx_v_obj); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":430 * return obj * * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice dst_slice * cdef __Pyx_memviewslice src_slice */ static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) { __Pyx_memviewslice __pyx_v_dst_slice; __Pyx_memviewslice __pyx_v_src_slice; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_t_2; int __pyx_t_3; int __pyx_t_4; __Pyx_RefNannySetupContext("setitem_slice_assignment", 0); /* "View.MemoryView":434 * cdef __Pyx_memviewslice src_slice * * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<< * get_slice_from_memview(dst, &dst_slice)[0], * src.ndim, dst.ndim, self.dtype_is_object) */ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) __PYX_ERR(2, 434, __pyx_L1_error) /* "View.MemoryView":435 * * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<< * src.ndim, dst.ndim, self.dtype_is_object) * */ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) __PYX_ERR(2, 435, __pyx_L1_error) /* "View.MemoryView":436 * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], * get_slice_from_memview(dst, &dst_slice)[0], * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<< * * cdef setitem_slice_assign_scalar(self, memoryview dst, value): */ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 436, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 436, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 436, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(2, 436, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":434 * cdef __Pyx_memviewslice src_slice * * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<< * get_slice_from_memview(dst, &dst_slice)[0], * src.ndim, dst.ndim, self.dtype_is_object) */ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) __PYX_ERR(2, 434, __pyx_L1_error) /* "View.MemoryView":430 * return obj * * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice dst_slice * cdef __Pyx_memviewslice src_slice */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":438 * src.ndim, dst.ndim, self.dtype_is_object) * * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<< * cdef int array[128] * cdef void *tmp = NULL */ static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) { int __pyx_v_array[0x80]; void *__pyx_v_tmp; void *__pyx_v_item; __Pyx_memviewslice *__pyx_v_dst_slice; __Pyx_memviewslice __pyx_v_tmp_slice; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; int __pyx_t_3; int __pyx_t_4; char const *__pyx_t_5; PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; PyObject *__pyx_t_8 = NULL; PyObject *__pyx_t_9 = NULL; PyObject *__pyx_t_10 = NULL; PyObject *__pyx_t_11 = NULL; __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0); /* "View.MemoryView":440 * cdef setitem_slice_assign_scalar(self, memoryview dst, value): * cdef int array[128] * cdef void *tmp = NULL # <<<<<<<<<<<<<< * cdef void *item * */ __pyx_v_tmp = NULL; /* "View.MemoryView":445 * cdef __Pyx_memviewslice *dst_slice * cdef __Pyx_memviewslice tmp_slice * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<< * * if self.view.itemsize > sizeof(array): */ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice)); /* "View.MemoryView":447 * dst_slice = get_slice_from_memview(dst, &tmp_slice) * * if self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<< * tmp = PyMem_Malloc(self.view.itemsize) * if tmp == NULL: */ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0); if (__pyx_t_1) { /* "View.MemoryView":448 * * if self.view.itemsize > sizeof(array): * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<< * if tmp == NULL: * raise MemoryError */ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize); /* "View.MemoryView":449 * if self.view.itemsize > sizeof(array): * tmp = PyMem_Malloc(self.view.itemsize) * if tmp == NULL: # <<<<<<<<<<<<<< * raise MemoryError * item = tmp */ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":450 * tmp = PyMem_Malloc(self.view.itemsize) * if tmp == NULL: * raise MemoryError # <<<<<<<<<<<<<< * item = tmp * else: */ PyErr_NoMemory(); __PYX_ERR(2, 450, __pyx_L1_error) /* "View.MemoryView":449 * if self.view.itemsize > sizeof(array): * tmp = PyMem_Malloc(self.view.itemsize) * if tmp == NULL: # <<<<<<<<<<<<<< * raise MemoryError * item = tmp */ } /* "View.MemoryView":451 * if tmp == NULL: * raise MemoryError * item = tmp # <<<<<<<<<<<<<< * else: * item = array */ __pyx_v_item = __pyx_v_tmp; /* "View.MemoryView":447 * dst_slice = get_slice_from_memview(dst, &tmp_slice) * * if self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<< * tmp = PyMem_Malloc(self.view.itemsize) * if tmp == NULL: */ goto __pyx_L3; } /* "View.MemoryView":453 * item = tmp * else: * item = array # <<<<<<<<<<<<<< * * try: */ /*else*/ { __pyx_v_item = ((void *)__pyx_v_array); } __pyx_L3:; /* "View.MemoryView":455 * item = array * * try: # <<<<<<<<<<<<<< * if self.dtype_is_object: * ( item)[0] = value */ /*try:*/ { /* "View.MemoryView":456 * * try: * if self.dtype_is_object: # <<<<<<<<<<<<<< * ( item)[0] = value * else: */ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0); if (__pyx_t_1) { /* "View.MemoryView":457 * try: * if self.dtype_is_object: * ( item)[0] = value # <<<<<<<<<<<<<< * else: * self.assign_item_from_object( item, value) */ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value); /* "View.MemoryView":456 * * try: * if self.dtype_is_object: # <<<<<<<<<<<<<< * ( item)[0] = value * else: */ goto __pyx_L8; } /* "View.MemoryView":459 * ( item)[0] = value * else: * self.assign_item_from_object( item, value) # <<<<<<<<<<<<<< * * */ /*else*/ { __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 459, __pyx_L6_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; } __pyx_L8:; /* "View.MemoryView":463 * * * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<< * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, */ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":464 * * if self.view.suboffsets != NULL: * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<< * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, * item, self.dtype_is_object) */ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 464, __pyx_L6_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "View.MemoryView":463 * * * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<< * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, */ } /* "View.MemoryView":465 * if self.view.suboffsets != NULL: * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<< * item, self.dtype_is_object) * finally: */ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object); } /* "View.MemoryView":468 * item, self.dtype_is_object) * finally: * PyMem_Free(tmp) # <<<<<<<<<<<<<< * * cdef setitem_indexed(self, index, value): */ /*finally:*/ { /*normal exit:*/{ PyMem_Free(__pyx_v_tmp); goto __pyx_L7; } /*exception exit:*/{ __Pyx_PyThreadState_declare __pyx_L6_error:; __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __Pyx_PyThreadState_assign __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11); if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8); __Pyx_XGOTREF(__pyx_t_6); __Pyx_XGOTREF(__pyx_t_7); __Pyx_XGOTREF(__pyx_t_8); __Pyx_XGOTREF(__pyx_t_9); __Pyx_XGOTREF(__pyx_t_10); __Pyx_XGOTREF(__pyx_t_11); __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename; { PyMem_Free(__pyx_v_tmp); } __Pyx_PyThreadState_assign if (PY_MAJOR_VERSION >= 3) { __Pyx_XGIVEREF(__pyx_t_9); __Pyx_XGIVEREF(__pyx_t_10); __Pyx_XGIVEREF(__pyx_t_11); __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11); } __Pyx_XGIVEREF(__pyx_t_6); __Pyx_XGIVEREF(__pyx_t_7); __Pyx_XGIVEREF(__pyx_t_8); __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8); __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5; goto __pyx_L1_error; } __pyx_L7:; } /* "View.MemoryView":438 * src.ndim, dst.ndim, self.dtype_is_object) * * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<< * cdef int array[128] * cdef void *tmp = NULL */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":470 * PyMem_Free(tmp) * * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<< * cdef char *itemp = self.get_item_pointer(index) * self.assign_item_from_object(itemp, value) */ static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { char *__pyx_v_itemp; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations char *__pyx_t_1; PyObject *__pyx_t_2 = NULL; __Pyx_RefNannySetupContext("setitem_indexed", 0); /* "View.MemoryView":471 * * cdef setitem_indexed(self, index, value): * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<< * self.assign_item_from_object(itemp, value) * */ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) __PYX_ERR(2, 471, __pyx_L1_error) __pyx_v_itemp = __pyx_t_1; /* "View.MemoryView":472 * cdef setitem_indexed(self, index, value): * cdef char *itemp = self.get_item_pointer(index) * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<< * * cdef convert_item_to_object(self, char *itemp): */ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 472, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "View.MemoryView":470 * PyMem_Free(tmp) * * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<< * cdef char *itemp = self.get_item_pointer(index) * self.assign_item_from_object(itemp, value) */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":474 * self.assign_item_from_object(itemp, value) * * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< * """Only used if instantiated manually by the user, or if Cython doesn't * know how to convert the type""" */ static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) { PyObject *__pyx_v_struct = NULL; PyObject *__pyx_v_bytesitem = 0; PyObject *__pyx_v_result = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; Py_ssize_t __pyx_t_8; PyObject *__pyx_t_9 = NULL; size_t __pyx_t_10; int __pyx_t_11; int __pyx_t_12; __Pyx_RefNannySetupContext("convert_item_to_object", 0); /* "View.MemoryView":477 * """Only used if instantiated manually by the user, or if Cython doesn't * know how to convert the type""" * import struct # <<<<<<<<<<<<<< * cdef bytes bytesitem * */ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 477, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v_struct = __pyx_t_1; __pyx_t_1 = 0; /* "View.MemoryView":480 * cdef bytes bytesitem * * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<< * try: * result = struct.unpack(self.view.format, bytesitem) */ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 480, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v_bytesitem = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":481 * * bytesitem = itemp[:self.view.itemsize] * try: # <<<<<<<<<<<<<< * result = struct.unpack(self.view.format, bytesitem) * except struct.error: */ { __Pyx_PyThreadState_declare __Pyx_PyThreadState_assign __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); __Pyx_XGOTREF(__pyx_t_2); __Pyx_XGOTREF(__pyx_t_3); __Pyx_XGOTREF(__pyx_t_4); /*try:*/ { /* "View.MemoryView":482 * bytesitem = itemp[:self.view.itemsize] * try: * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<< * except struct.error: * raise ValueError("Unable to convert item to object") */ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 482, __pyx_L3_error) __Pyx_GOTREF(__pyx_t_5); __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 482, __pyx_L3_error) __Pyx_GOTREF(__pyx_t_6); __pyx_t_7 = NULL; __pyx_t_8 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) { __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5); if (likely(__pyx_t_7)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); __Pyx_INCREF(__pyx_t_7); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_5, function); __pyx_t_8 = 1; } } __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 482, __pyx_L3_error) __Pyx_GOTREF(__pyx_t_9); if (__pyx_t_7) { __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL; } __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6); __Pyx_INCREF(__pyx_v_bytesitem); __Pyx_GIVEREF(__pyx_v_bytesitem); PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem); __pyx_t_6 = 0; __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 482, __pyx_L3_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __pyx_v_result = __pyx_t_1; __pyx_t_1 = 0; /* "View.MemoryView":481 * * bytesitem = itemp[:self.view.itemsize] * try: # <<<<<<<<<<<<<< * result = struct.unpack(self.view.format, bytesitem) * except struct.error: */ } /* "View.MemoryView":486 * raise ValueError("Unable to convert item to object") * else: * if len(self.view.format) == 1: # <<<<<<<<<<<<<< * return result[0] * return result */ /*else:*/ { __pyx_t_10 = strlen(__pyx_v_self->view.format); __pyx_t_11 = ((__pyx_t_10 == 1) != 0); if (__pyx_t_11) { /* "View.MemoryView":487 * else: * if len(self.view.format) == 1: * return result[0] # <<<<<<<<<<<<<< * return result * */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 487, __pyx_L5_except_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L6_except_return; /* "View.MemoryView":486 * raise ValueError("Unable to convert item to object") * else: * if len(self.view.format) == 1: # <<<<<<<<<<<<<< * return result[0] * return result */ } /* "View.MemoryView":488 * if len(self.view.format) == 1: * return result[0] * return result # <<<<<<<<<<<<<< * * cdef assign_item_from_object(self, char *itemp, object value): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_result); __pyx_r = __pyx_v_result; goto __pyx_L6_except_return; } __pyx_L3_error:; __Pyx_PyThreadState_assign __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":483 * try: * result = struct.unpack(self.view.format, bytesitem) * except struct.error: # <<<<<<<<<<<<<< * raise ValueError("Unable to convert item to object") * else: */ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 483, __pyx_L5_except_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_12 = __Pyx_PyErr_ExceptionMatches(__pyx_t_1); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; if (__pyx_t_12) { __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) __PYX_ERR(2, 483, __pyx_L5_except_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_GOTREF(__pyx_t_5); __Pyx_GOTREF(__pyx_t_9); /* "View.MemoryView":484 * result = struct.unpack(self.view.format, bytesitem) * except struct.error: * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<< * else: * if len(self.view.format) == 1: */ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 484, __pyx_L5_except_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_Raise(__pyx_t_6, 0, 0, 0); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __PYX_ERR(2, 484, __pyx_L5_except_error) } goto __pyx_L5_except_error; __pyx_L5_except_error:; /* "View.MemoryView":481 * * bytesitem = itemp[:self.view.itemsize] * try: # <<<<<<<<<<<<<< * result = struct.unpack(self.view.format, bytesitem) * except struct.error: */ __Pyx_PyThreadState_assign __Pyx_XGIVEREF(__pyx_t_2); __Pyx_XGIVEREF(__pyx_t_3); __Pyx_XGIVEREF(__pyx_t_4); __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); goto __pyx_L1_error; __pyx_L6_except_return:; __Pyx_PyThreadState_assign __Pyx_XGIVEREF(__pyx_t_2); __Pyx_XGIVEREF(__pyx_t_3); __Pyx_XGIVEREF(__pyx_t_4); __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); goto __pyx_L0; } /* "View.MemoryView":474 * self.assign_item_from_object(itemp, value) * * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< * """Only used if instantiated manually by the user, or if Cython doesn't * know how to convert the type""" */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_9); __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF(__pyx_v_struct); __Pyx_XDECREF(__pyx_v_bytesitem); __Pyx_XDECREF(__pyx_v_result); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":490 * return result * * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< * """Only used if instantiated manually by the user, or if Cython doesn't * know how to convert the type""" */ static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) { PyObject *__pyx_v_struct = NULL; char __pyx_v_c; PyObject *__pyx_v_bytesvalue = 0; Py_ssize_t __pyx_v_i; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_t_2; int __pyx_t_3; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; Py_ssize_t __pyx_t_7; PyObject *__pyx_t_8 = NULL; PyObject *__pyx_t_9 = NULL; char *__pyx_t_10; char *__pyx_t_11; char *__pyx_t_12; char *__pyx_t_13; __Pyx_RefNannySetupContext("assign_item_from_object", 0); /* "View.MemoryView":493 * """Only used if instantiated manually by the user, or if Cython doesn't * know how to convert the type""" * import struct # <<<<<<<<<<<<<< * cdef char c * cdef bytes bytesvalue */ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 493, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_v_struct = __pyx_t_1; __pyx_t_1 = 0; /* "View.MemoryView":498 * cdef Py_ssize_t i * * if isinstance(value, tuple): # <<<<<<<<<<<<<< * bytesvalue = struct.pack(self.view.format, *value) * else: */ __pyx_t_2 = PyTuple_Check(__pyx_v_value); __pyx_t_3 = (__pyx_t_2 != 0); if (__pyx_t_3) { /* "View.MemoryView":499 * * if isinstance(value, tuple): * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<< * else: * bytesvalue = struct.pack(self.view.format, value) */ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 499, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 499, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 499, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 499, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 499, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 499, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) __PYX_ERR(2, 499, __pyx_L1_error) __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4); __pyx_t_4 = 0; /* "View.MemoryView":498 * cdef Py_ssize_t i * * if isinstance(value, tuple): # <<<<<<<<<<<<<< * bytesvalue = struct.pack(self.view.format, *value) * else: */ goto __pyx_L3; } /* "View.MemoryView":501 * bytesvalue = struct.pack(self.view.format, *value) * else: * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<< * * for i, c in enumerate(bytesvalue): */ /*else*/ { __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 501, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 501, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_5 = NULL; __pyx_t_7 = 0; if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) { __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6); if (likely(__pyx_t_5)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); __Pyx_INCREF(__pyx_t_5); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_6, function); __pyx_t_7 = 1; } } __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 501, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_8); if (__pyx_t_5) { __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __pyx_t_5 = NULL; } __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1); __Pyx_INCREF(__pyx_v_value); __Pyx_GIVEREF(__pyx_v_value); PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value); __pyx_t_1 = 0; __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 501, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) __PYX_ERR(2, 501, __pyx_L1_error) __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4); __pyx_t_4 = 0; } __pyx_L3:; /* "View.MemoryView":503 * bytesvalue = struct.pack(self.view.format, value) * * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<< * itemp[i] = c * */ __pyx_t_7 = 0; if (unlikely(__pyx_v_bytesvalue == Py_None)) { PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable"); __PYX_ERR(2, 503, __pyx_L1_error) } __Pyx_INCREF(__pyx_v_bytesvalue); __pyx_t_9 = __pyx_v_bytesvalue; __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9); __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9)); for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) { __pyx_t_10 = __pyx_t_13; __pyx_v_c = (__pyx_t_10[0]); /* "View.MemoryView":504 * * for i, c in enumerate(bytesvalue): * itemp[i] = c # <<<<<<<<<<<<<< * * @cname('getbuffer') */ __pyx_v_i = __pyx_t_7; /* "View.MemoryView":503 * bytesvalue = struct.pack(self.view.format, value) * * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<< * itemp[i] = c * */ __pyx_t_7 = (__pyx_t_7 + 1); /* "View.MemoryView":504 * * for i, c in enumerate(bytesvalue): * itemp[i] = c # <<<<<<<<<<<<<< * * @cname('getbuffer') */ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c; } __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; /* "View.MemoryView":490 * return result * * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< * """Only used if instantiated manually by the user, or if Cython doesn't * know how to convert the type""" */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_8); __Pyx_XDECREF(__pyx_t_9); __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF(__pyx_v_struct); __Pyx_XDECREF(__pyx_v_bytesvalue); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":507 * * @cname('getbuffer') * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< * if flags & PyBUF_STRIDES: * info.shape = self.view.shape */ /* Python wrapper */ static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { int __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static int __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { int __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; Py_ssize_t *__pyx_t_2; char *__pyx_t_3; void *__pyx_t_4; int __pyx_t_5; Py_ssize_t __pyx_t_6; __Pyx_RefNannySetupContext("__getbuffer__", 0); if (__pyx_v_info != NULL) { __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); __Pyx_GIVEREF(__pyx_v_info->obj); } /* "View.MemoryView":508 * @cname('getbuffer') * def __getbuffer__(self, Py_buffer *info, int flags): * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< * info.shape = self.view.shape * else: */ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0); if (__pyx_t_1) { /* "View.MemoryView":509 * def __getbuffer__(self, Py_buffer *info, int flags): * if flags & PyBUF_STRIDES: * info.shape = self.view.shape # <<<<<<<<<<<<<< * else: * info.shape = NULL */ __pyx_t_2 = __pyx_v_self->view.shape; __pyx_v_info->shape = __pyx_t_2; /* "View.MemoryView":508 * @cname('getbuffer') * def __getbuffer__(self, Py_buffer *info, int flags): * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< * info.shape = self.view.shape * else: */ goto __pyx_L3; } /* "View.MemoryView":511 * info.shape = self.view.shape * else: * info.shape = NULL # <<<<<<<<<<<<<< * * if flags & PyBUF_STRIDES: */ /*else*/ { __pyx_v_info->shape = NULL; } __pyx_L3:; /* "View.MemoryView":513 * info.shape = NULL * * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< * info.strides = self.view.strides * else: */ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0); if (__pyx_t_1) { /* "View.MemoryView":514 * * if flags & PyBUF_STRIDES: * info.strides = self.view.strides # <<<<<<<<<<<<<< * else: * info.strides = NULL */ __pyx_t_2 = __pyx_v_self->view.strides; __pyx_v_info->strides = __pyx_t_2; /* "View.MemoryView":513 * info.shape = NULL * * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<< * info.strides = self.view.strides * else: */ goto __pyx_L4; } /* "View.MemoryView":516 * info.strides = self.view.strides * else: * info.strides = NULL # <<<<<<<<<<<<<< * * if flags & PyBUF_INDIRECT: */ /*else*/ { __pyx_v_info->strides = NULL; } __pyx_L4:; /* "View.MemoryView":518 * info.strides = NULL * * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<< * info.suboffsets = self.view.suboffsets * else: */ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0); if (__pyx_t_1) { /* "View.MemoryView":519 * * if flags & PyBUF_INDIRECT: * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<< * else: * info.suboffsets = NULL */ __pyx_t_2 = __pyx_v_self->view.suboffsets; __pyx_v_info->suboffsets = __pyx_t_2; /* "View.MemoryView":518 * info.strides = NULL * * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<< * info.suboffsets = self.view.suboffsets * else: */ goto __pyx_L5; } /* "View.MemoryView":521 * info.suboffsets = self.view.suboffsets * else: * info.suboffsets = NULL # <<<<<<<<<<<<<< * * if flags & PyBUF_FORMAT: */ /*else*/ { __pyx_v_info->suboffsets = NULL; } __pyx_L5:; /* "View.MemoryView":523 * info.suboffsets = NULL * * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< * info.format = self.view.format * else: */ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0); if (__pyx_t_1) { /* "View.MemoryView":524 * * if flags & PyBUF_FORMAT: * info.format = self.view.format # <<<<<<<<<<<<<< * else: * info.format = NULL */ __pyx_t_3 = __pyx_v_self->view.format; __pyx_v_info->format = __pyx_t_3; /* "View.MemoryView":523 * info.suboffsets = NULL * * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<< * info.format = self.view.format * else: */ goto __pyx_L6; } /* "View.MemoryView":526 * info.format = self.view.format * else: * info.format = NULL # <<<<<<<<<<<<<< * * info.buf = self.view.buf */ /*else*/ { __pyx_v_info->format = NULL; } __pyx_L6:; /* "View.MemoryView":528 * info.format = NULL * * info.buf = self.view.buf # <<<<<<<<<<<<<< * info.ndim = self.view.ndim * info.itemsize = self.view.itemsize */ __pyx_t_4 = __pyx_v_self->view.buf; __pyx_v_info->buf = __pyx_t_4; /* "View.MemoryView":529 * * info.buf = self.view.buf * info.ndim = self.view.ndim # <<<<<<<<<<<<<< * info.itemsize = self.view.itemsize * info.len = self.view.len */ __pyx_t_5 = __pyx_v_self->view.ndim; __pyx_v_info->ndim = __pyx_t_5; /* "View.MemoryView":530 * info.buf = self.view.buf * info.ndim = self.view.ndim * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<< * info.len = self.view.len * info.readonly = 0 */ __pyx_t_6 = __pyx_v_self->view.itemsize; __pyx_v_info->itemsize = __pyx_t_6; /* "View.MemoryView":531 * info.ndim = self.view.ndim * info.itemsize = self.view.itemsize * info.len = self.view.len # <<<<<<<<<<<<<< * info.readonly = 0 * info.obj = self */ __pyx_t_6 = __pyx_v_self->view.len; __pyx_v_info->len = __pyx_t_6; /* "View.MemoryView":532 * info.itemsize = self.view.itemsize * info.len = self.view.len * info.readonly = 0 # <<<<<<<<<<<<<< * info.obj = self * */ __pyx_v_info->readonly = 0; /* "View.MemoryView":533 * info.len = self.view.len * info.readonly = 0 * info.obj = self # <<<<<<<<<<<<<< * * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") */ __Pyx_INCREF(((PyObject *)__pyx_v_self)); __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); __Pyx_GOTREF(__pyx_v_info->obj); __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = ((PyObject *)__pyx_v_self); /* "View.MemoryView":507 * * @cname('getbuffer') * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<< * if flags & PyBUF_STRIDES: * info.shape = self.view.shape */ /* function exit code */ __pyx_r = 0; if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) { __Pyx_GOTREF(Py_None); __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL; } __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":539 * * @property * def T(self): # <<<<<<<<<<<<<< * cdef _memoryviewslice result = memoryview_copy(self) * transpose_memslice(&result.from_slice) */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) { struct __pyx_memoryviewslice_obj *__pyx_v_result = 0; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; int __pyx_t_2; __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":540 * @property * def T(self): * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<< * transpose_memslice(&result.from_slice) * return result */ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 540, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) __PYX_ERR(2, 540, __pyx_L1_error) __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":541 * def T(self): * cdef _memoryviewslice result = memoryview_copy(self) * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<< * return result * */ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) __PYX_ERR(2, 541, __pyx_L1_error) /* "View.MemoryView":542 * cdef _memoryviewslice result = memoryview_copy(self) * transpose_memslice(&result.from_slice) * return result # <<<<<<<<<<<<<< * * @property */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_result)); __pyx_r = ((PyObject *)__pyx_v_result); goto __pyx_L0; /* "View.MemoryView":539 * * @property * def T(self): # <<<<<<<<<<<<<< * cdef _memoryviewslice result = memoryview_copy(self) * transpose_memslice(&result.from_slice) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_result); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":545 * * @property * def base(self): # <<<<<<<<<<<<<< * return self.obj * */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":546 * @property * def base(self): * return self.obj # <<<<<<<<<<<<<< * * @property */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_self->obj); __pyx_r = __pyx_v_self->obj; goto __pyx_L0; /* "View.MemoryView":545 * * @property * def base(self): # <<<<<<<<<<<<<< * return self.obj * */ /* function exit code */ __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":549 * * @property * def shape(self): # <<<<<<<<<<<<<< * return tuple([length for length in self.view.shape[:self.view.ndim]]) * */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) { Py_ssize_t __pyx_v_length; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; Py_ssize_t *__pyx_t_2; Py_ssize_t *__pyx_t_3; Py_ssize_t *__pyx_t_4; PyObject *__pyx_t_5 = NULL; __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":550 * @property * def shape(self): * return tuple([length for length in self.view.shape[:self.view.ndim]]) # <<<<<<<<<<<<<< * * @property */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 550, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = (__pyx_v_self->view.shape + __pyx_v_self->view.ndim); for (__pyx_t_4 = __pyx_v_self->view.shape; __pyx_t_4 < __pyx_t_3; __pyx_t_4++) { __pyx_t_2 = __pyx_t_4; __pyx_v_length = (__pyx_t_2[0]); __pyx_t_5 = PyInt_FromSsize_t(__pyx_v_length); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 550, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_5))) __PYX_ERR(2, 550, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 550, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "View.MemoryView":549 * * @property * def shape(self): # <<<<<<<<<<<<<< * return tuple([length for length in self.view.shape[:self.view.ndim]]) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":553 * * @property * def strides(self): # <<<<<<<<<<<<<< * if self.view.strides == NULL: * */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) { Py_ssize_t __pyx_v_stride; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; Py_ssize_t *__pyx_t_3; Py_ssize_t *__pyx_t_4; Py_ssize_t *__pyx_t_5; PyObject *__pyx_t_6 = NULL; __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":554 * @property * def strides(self): * if self.view.strides == NULL: # <<<<<<<<<<<<<< * * raise ValueError("Buffer view does not expose strides") */ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":556 * if self.view.strides == NULL: * * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<< * * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) */ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 556, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_Raise(__pyx_t_2, 0, 0, 0); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __PYX_ERR(2, 556, __pyx_L1_error) /* "View.MemoryView":554 * @property * def strides(self): * if self.view.strides == NULL: # <<<<<<<<<<<<<< * * raise ValueError("Buffer view does not expose strides") */ } /* "View.MemoryView":558 * raise ValueError("Buffer view does not expose strides") * * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) # <<<<<<<<<<<<<< * * @property */ __Pyx_XDECREF(__pyx_r); __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 558, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_4 = (__pyx_v_self->view.strides + __pyx_v_self->view.ndim); for (__pyx_t_5 = __pyx_v_self->view.strides; __pyx_t_5 < __pyx_t_4; __pyx_t_5++) { __pyx_t_3 = __pyx_t_5; __pyx_v_stride = (__pyx_t_3[0]); __pyx_t_6 = PyInt_FromSsize_t(__pyx_v_stride); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 558, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_6))) __PYX_ERR(2, 558, __pyx_L1_error) __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } __pyx_t_6 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 558, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_6; __pyx_t_6 = 0; goto __pyx_L0; /* "View.MemoryView":553 * * @property * def strides(self): # <<<<<<<<<<<<<< * if self.view.strides == NULL: * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":561 * * @property * def suboffsets(self): # <<<<<<<<<<<<<< * if self.view.suboffsets == NULL: * return (-1,) * self.view.ndim */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) { Py_ssize_t __pyx_v_suboffset; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; Py_ssize_t *__pyx_t_4; Py_ssize_t *__pyx_t_5; Py_ssize_t *__pyx_t_6; __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":562 * @property * def suboffsets(self): * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<< * return (-1,) * self.view.ndim * */ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":563 * def suboffsets(self): * if self.view.suboffsets == NULL: * return (-1,) * self.view.ndim # <<<<<<<<<<<<<< * * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) */ __Pyx_XDECREF(__pyx_r); __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 563, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PyNumber_Multiply(__pyx_tuple__15, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 563, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; /* "View.MemoryView":562 * @property * def suboffsets(self): * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<< * return (-1,) * self.view.ndim * */ } /* "View.MemoryView":565 * return (-1,) * self.view.ndim * * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) # <<<<<<<<<<<<<< * * @property */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 565, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_5 = (__pyx_v_self->view.suboffsets + __pyx_v_self->view.ndim); for (__pyx_t_6 = __pyx_v_self->view.suboffsets; __pyx_t_6 < __pyx_t_5; __pyx_t_6++) { __pyx_t_4 = __pyx_t_6; __pyx_v_suboffset = (__pyx_t_4[0]); __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_suboffset); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 565, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_2))) __PYX_ERR(2, 565, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; } __pyx_t_2 = PyList_AsTuple(((PyObject*)__pyx_t_3)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 565, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "View.MemoryView":561 * * @property * def suboffsets(self): # <<<<<<<<<<<<<< * if self.view.suboffsets == NULL: * return (-1,) * self.view.ndim */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":568 * * @property * def ndim(self): # <<<<<<<<<<<<<< * return self.view.ndim * */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":569 * @property * def ndim(self): * return self.view.ndim # <<<<<<<<<<<<<< * * @property */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 569, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "View.MemoryView":568 * * @property * def ndim(self): # <<<<<<<<<<<<<< * return self.view.ndim * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":572 * * @property * def itemsize(self): # <<<<<<<<<<<<<< * return self.view.itemsize * */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":573 * @property * def itemsize(self): * return self.view.itemsize # <<<<<<<<<<<<<< * * @property */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 573, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "View.MemoryView":572 * * @property * def itemsize(self): # <<<<<<<<<<<<<< * return self.view.itemsize * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":576 * * @property * def nbytes(self): # <<<<<<<<<<<<<< * return self.size * self.view.itemsize * */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":577 * @property * def nbytes(self): * return self.size * self.view.itemsize # <<<<<<<<<<<<<< * * @property */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 577, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 577, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 577, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; /* "View.MemoryView":576 * * @property * def nbytes(self): # <<<<<<<<<<<<<< * return self.size * self.view.itemsize * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":580 * * @property * def size(self): # <<<<<<<<<<<<<< * if self._size is None: * result = 1 */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_v_result = NULL; PyObject *__pyx_v_length = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; Py_ssize_t *__pyx_t_3; Py_ssize_t *__pyx_t_4; Py_ssize_t *__pyx_t_5; PyObject *__pyx_t_6 = NULL; __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":581 * @property * def size(self): * if self._size is None: # <<<<<<<<<<<<<< * result = 1 * */ __pyx_t_1 = (__pyx_v_self->_size == Py_None); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "View.MemoryView":582 * def size(self): * if self._size is None: * result = 1 # <<<<<<<<<<<<<< * * for length in self.view.shape[:self.view.ndim]: */ __Pyx_INCREF(__pyx_int_1); __pyx_v_result = __pyx_int_1; /* "View.MemoryView":584 * result = 1 * * for length in self.view.shape[:self.view.ndim]: # <<<<<<<<<<<<<< * result *= length * */ __pyx_t_4 = (__pyx_v_self->view.shape + __pyx_v_self->view.ndim); for (__pyx_t_5 = __pyx_v_self->view.shape; __pyx_t_5 < __pyx_t_4; __pyx_t_5++) { __pyx_t_3 = __pyx_t_5; __pyx_t_6 = PyInt_FromSsize_t((__pyx_t_3[0])); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 584, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_6); __pyx_t_6 = 0; /* "View.MemoryView":585 * * for length in self.view.shape[:self.view.ndim]: * result *= length # <<<<<<<<<<<<<< * * self._size = result */ __pyx_t_6 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 585, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_6); __pyx_t_6 = 0; } /* "View.MemoryView":587 * result *= length * * self._size = result # <<<<<<<<<<<<<< * * return self._size */ __Pyx_INCREF(__pyx_v_result); __Pyx_GIVEREF(__pyx_v_result); __Pyx_GOTREF(__pyx_v_self->_size); __Pyx_DECREF(__pyx_v_self->_size); __pyx_v_self->_size = __pyx_v_result; /* "View.MemoryView":581 * @property * def size(self): * if self._size is None: # <<<<<<<<<<<<<< * result = 1 * */ } /* "View.MemoryView":589 * self._size = result * * return self._size # <<<<<<<<<<<<<< * * def __len__(self): */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_self->_size); __pyx_r = __pyx_v_self->_size; goto __pyx_L0; /* "View.MemoryView":580 * * @property * def size(self): # <<<<<<<<<<<<<< * if self._size is None: * result = 1 */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XDECREF(__pyx_v_result); __Pyx_XDECREF(__pyx_v_length); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":591 * return self._size * * def __len__(self): # <<<<<<<<<<<<<< * if self.view.ndim >= 1: * return self.view.shape[0] */ /* Python wrapper */ static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/ static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) { Py_ssize_t __pyx_r; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static Py_ssize_t __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) { Py_ssize_t __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; __Pyx_RefNannySetupContext("__len__", 0); /* "View.MemoryView":592 * * def __len__(self): * if self.view.ndim >= 1: # <<<<<<<<<<<<<< * return self.view.shape[0] * */ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0); if (__pyx_t_1) { /* "View.MemoryView":593 * def __len__(self): * if self.view.ndim >= 1: * return self.view.shape[0] # <<<<<<<<<<<<<< * * return 0 */ __pyx_r = (__pyx_v_self->view.shape[0]); goto __pyx_L0; /* "View.MemoryView":592 * * def __len__(self): * if self.view.ndim >= 1: # <<<<<<<<<<<<<< * return self.view.shape[0] * */ } /* "View.MemoryView":595 * return self.view.shape[0] * * return 0 # <<<<<<<<<<<<<< * * def __repr__(self): */ __pyx_r = 0; goto __pyx_L0; /* "View.MemoryView":591 * return self._size * * def __len__(self): # <<<<<<<<<<<<<< * if self.view.ndim >= 1: * return self.view.shape[0] */ /* function exit code */ __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":597 * return 0 * * def __repr__(self): # <<<<<<<<<<<<<< * return "" % (self.base.__class__.__name__, * id(self)) */ /* Python wrapper */ static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; __Pyx_RefNannySetupContext("__repr__", 0); /* "View.MemoryView":598 * * def __repr__(self): * return "" % (self.base.__class__.__name__, # <<<<<<<<<<<<<< * id(self)) * */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 598, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 598, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 598, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "View.MemoryView":599 * def __repr__(self): * return "" % (self.base.__class__.__name__, * id(self)) # <<<<<<<<<<<<<< * * def __str__(self): */ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 599, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_INCREF(((PyObject *)__pyx_v_self)); __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self)); __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 599, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "View.MemoryView":598 * * def __repr__(self): * return "" % (self.base.__class__.__name__, # <<<<<<<<<<<<<< * id(self)) * */ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 598, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3); __pyx_t_1 = 0; __pyx_t_3 = 0; __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 598, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; /* "View.MemoryView":597 * return 0 * * def __repr__(self): # <<<<<<<<<<<<<< * return "" % (self.base.__class__.__name__, * id(self)) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":601 * id(self)) * * def __str__(self): # <<<<<<<<<<<<<< * return "" % (self.base.__class__.__name__,) * */ /* Python wrapper */ static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__str__ (wrapper)", 0); __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; __Pyx_RefNannySetupContext("__str__", 0); /* "View.MemoryView":602 * * def __str__(self): * return "" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 602, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 602, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 602, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 602, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1); __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 602, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "View.MemoryView":601 * id(self)) * * def __str__(self): # <<<<<<<<<<<<<< * return "" % (self.base.__class__.__name__,) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":605 * * * def is_c_contig(self): # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice *mslice * cdef __Pyx_memviewslice tmp */ /* Python wrapper */ static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0); __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) { __Pyx_memviewslice *__pyx_v_mslice; __Pyx_memviewslice __pyx_v_tmp; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("is_c_contig", 0); /* "View.MemoryView":608 * cdef __Pyx_memviewslice *mslice * cdef __Pyx_memviewslice tmp * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<< * return slice_is_contig(mslice[0], 'C', self.view.ndim) * */ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp)); /* "View.MemoryView":609 * cdef __Pyx_memviewslice tmp * mslice = get_slice_from_memview(self, &tmp) * return slice_is_contig(mslice[0], 'C', self.view.ndim) # <<<<<<<<<<<<<< * * def is_f_contig(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig((__pyx_v_mslice[0]), 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 609, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "View.MemoryView":605 * * * def is_c_contig(self): # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice *mslice * cdef __Pyx_memviewslice tmp */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":611 * return slice_is_contig(mslice[0], 'C', self.view.ndim) * * def is_f_contig(self): # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice *mslice * cdef __Pyx_memviewslice tmp */ /* Python wrapper */ static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0); __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) { __Pyx_memviewslice *__pyx_v_mslice; __Pyx_memviewslice __pyx_v_tmp; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("is_f_contig", 0); /* "View.MemoryView":614 * cdef __Pyx_memviewslice *mslice * cdef __Pyx_memviewslice tmp * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<< * return slice_is_contig(mslice[0], 'F', self.view.ndim) * */ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp)); /* "View.MemoryView":615 * cdef __Pyx_memviewslice tmp * mslice = get_slice_from_memview(self, &tmp) * return slice_is_contig(mslice[0], 'F', self.view.ndim) # <<<<<<<<<<<<<< * * def copy(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig((__pyx_v_mslice[0]), 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 615, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "View.MemoryView":611 * return slice_is_contig(mslice[0], 'C', self.view.ndim) * * def is_f_contig(self): # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice *mslice * cdef __Pyx_memviewslice tmp */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":617 * return slice_is_contig(mslice[0], 'F', self.view.ndim) * * def copy(self): # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice mslice * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS */ /* Python wrapper */ static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("copy (wrapper)", 0); __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) { __Pyx_memviewslice __pyx_v_mslice; int __pyx_v_flags; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations __Pyx_memviewslice __pyx_t_1; PyObject *__pyx_t_2 = NULL; __Pyx_RefNannySetupContext("copy", 0); /* "View.MemoryView":619 * def copy(self): * cdef __Pyx_memviewslice mslice * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<< * * slice_copy(self, &mslice) */ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS)); /* "View.MemoryView":621 * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS * * slice_copy(self, &mslice) # <<<<<<<<<<<<<< * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, * self.view.itemsize, */ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice)); /* "View.MemoryView":622 * * slice_copy(self, &mslice) * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<< * self.view.itemsize, * flags|PyBUF_C_CONTIGUOUS, */ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), ((char *)"c"), __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 622, __pyx_L1_error) __pyx_v_mslice = __pyx_t_1; /* "View.MemoryView":627 * self.dtype_is_object) * * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<< * * def copy_fortran(self): */ __Pyx_XDECREF(__pyx_r); __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 627, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "View.MemoryView":617 * return slice_is_contig(mslice[0], 'F', self.view.ndim) * * def copy(self): # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice mslice * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":629 * return memoryview_copy_from_slice(self, &mslice) * * def copy_fortran(self): # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice src, dst * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS */ /* Python wrapper */ static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0); __pyx_r = __pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_memoryview___pyx_pf_15View_dot_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) { __Pyx_memviewslice __pyx_v_src; __Pyx_memviewslice __pyx_v_dst; int __pyx_v_flags; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations __Pyx_memviewslice __pyx_t_1; PyObject *__pyx_t_2 = NULL; __Pyx_RefNannySetupContext("copy_fortran", 0); /* "View.MemoryView":631 * def copy_fortran(self): * cdef __Pyx_memviewslice src, dst * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<< * * slice_copy(self, &src) */ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS)); /* "View.MemoryView":633 * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS * * slice_copy(self, &src) # <<<<<<<<<<<<<< * dst = slice_copy_contig(&src, "fortran", self.view.ndim, * self.view.itemsize, */ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src)); /* "View.MemoryView":634 * * slice_copy(self, &src) * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<< * self.view.itemsize, * flags|PyBUF_F_CONTIGUOUS, */ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), ((char *)"fortran"), __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) __PYX_ERR(2, 634, __pyx_L1_error) __pyx_v_dst = __pyx_t_1; /* "View.MemoryView":639 * self.dtype_is_object) * * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 639, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "View.MemoryView":629 * return memoryview_copy_from_slice(self, &mslice) * * def copy_fortran(self): # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice src, dst * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":643 * * @cname('__pyx_memoryview_new') * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<< * cdef memoryview result = memoryview(o, flags, dtype_is_object) * result.typeinfo = typeinfo */ static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) { struct __pyx_memoryview_obj *__pyx_v_result = 0; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; __Pyx_RefNannySetupContext("memoryview_cwrapper", 0); /* "View.MemoryView":644 * @cname('__pyx_memoryview_new') * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<< * result.typeinfo = typeinfo * return result */ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 644, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 644, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 644, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_INCREF(__pyx_v_o); __Pyx_GIVEREF(__pyx_v_o); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2); __pyx_t_1 = 0; __pyx_t_2 = 0; __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryview_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 644, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2); __pyx_t_2 = 0; /* "View.MemoryView":645 * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): * cdef memoryview result = memoryview(o, flags, dtype_is_object) * result.typeinfo = typeinfo # <<<<<<<<<<<<<< * return result * */ __pyx_v_result->typeinfo = __pyx_v_typeinfo; /* "View.MemoryView":646 * cdef memoryview result = memoryview(o, flags, dtype_is_object) * result.typeinfo = typeinfo * return result # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_check') */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_result)); __pyx_r = ((PyObject *)__pyx_v_result); goto __pyx_L0; /* "View.MemoryView":643 * * @cname('__pyx_memoryview_new') * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<< * cdef memoryview result = memoryview(o, flags, dtype_is_object) * result.typeinfo = typeinfo */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_result); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":649 * * @cname('__pyx_memoryview_check') * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<< * return isinstance(o, memoryview) * */ static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) { int __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; __Pyx_RefNannySetupContext("memoryview_check", 0); /* "View.MemoryView":650 * @cname('__pyx_memoryview_check') * cdef inline bint memoryview_check(object o): * return isinstance(o, memoryview) # <<<<<<<<<<<<<< * * cdef tuple _unellipsify(object index, int ndim): */ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, __pyx_memoryview_type); __pyx_r = __pyx_t_1; goto __pyx_L0; /* "View.MemoryView":649 * * @cname('__pyx_memoryview_check') * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<< * return isinstance(o, memoryview) * */ /* function exit code */ __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":652 * return isinstance(o, memoryview) * * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<< * """ * Replace all ellipses with full slices and fill incomplete indices with */ static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) { PyObject *__pyx_v_tup = NULL; PyObject *__pyx_v_result = NULL; int __pyx_v_have_slices; int __pyx_v_seen_ellipsis; CYTHON_UNUSED PyObject *__pyx_v_idx = NULL; PyObject *__pyx_v_item = NULL; Py_ssize_t __pyx_v_nslices; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; Py_ssize_t __pyx_t_5; PyObject *(*__pyx_t_6)(PyObject *); PyObject *__pyx_t_7 = NULL; Py_ssize_t __pyx_t_8; int __pyx_t_9; int __pyx_t_10; PyObject *__pyx_t_11 = NULL; __Pyx_RefNannySetupContext("_unellipsify", 0); /* "View.MemoryView":657 * full slices. * """ * if not isinstance(index, tuple): # <<<<<<<<<<<<<< * tup = (index,) * else: */ __pyx_t_1 = PyTuple_Check(__pyx_v_index); __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); if (__pyx_t_2) { /* "View.MemoryView":658 * """ * if not isinstance(index, tuple): * tup = (index,) # <<<<<<<<<<<<<< * else: * tup = index */ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 658, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_INCREF(__pyx_v_index); __Pyx_GIVEREF(__pyx_v_index); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index); __pyx_v_tup = __pyx_t_3; __pyx_t_3 = 0; /* "View.MemoryView":657 * full slices. * """ * if not isinstance(index, tuple): # <<<<<<<<<<<<<< * tup = (index,) * else: */ goto __pyx_L3; } /* "View.MemoryView":660 * tup = (index,) * else: * tup = index # <<<<<<<<<<<<<< * * result = [] */ /*else*/ { __Pyx_INCREF(__pyx_v_index); __pyx_v_tup = __pyx_v_index; } __pyx_L3:; /* "View.MemoryView":662 * tup = index * * result = [] # <<<<<<<<<<<<<< * have_slices = False * seen_ellipsis = False */ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 662, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_v_result = ((PyObject*)__pyx_t_3); __pyx_t_3 = 0; /* "View.MemoryView":663 * * result = [] * have_slices = False # <<<<<<<<<<<<<< * seen_ellipsis = False * for idx, item in enumerate(tup): */ __pyx_v_have_slices = 0; /* "View.MemoryView":664 * result = [] * have_slices = False * seen_ellipsis = False # <<<<<<<<<<<<<< * for idx, item in enumerate(tup): * if item is Ellipsis: */ __pyx_v_seen_ellipsis = 0; /* "View.MemoryView":665 * have_slices = False * seen_ellipsis = False * for idx, item in enumerate(tup): # <<<<<<<<<<<<<< * if item is Ellipsis: * if not seen_ellipsis: */ __Pyx_INCREF(__pyx_int_0); __pyx_t_3 = __pyx_int_0; if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) { __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0; __pyx_t_6 = NULL; } else { __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 665, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 665, __pyx_L1_error) } for (;;) { if (likely(!__pyx_t_6)) { if (likely(PyList_CheckExact(__pyx_t_4))) { if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(2, 665, __pyx_L1_error) #else __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 665, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); #endif } else { if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(2, 665, __pyx_L1_error) #else __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 665, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); #endif } } else { __pyx_t_7 = __pyx_t_6(__pyx_t_4); if (unlikely(!__pyx_t_7)) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); else __PYX_ERR(2, 665, __pyx_L1_error) } break; } __Pyx_GOTREF(__pyx_t_7); } __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7); __pyx_t_7 = 0; __Pyx_INCREF(__pyx_t_3); __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3); __pyx_t_7 = __Pyx_PyInt_AddObjC(__pyx_t_3, __pyx_int_1, 1, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 665, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = __pyx_t_7; __pyx_t_7 = 0; /* "View.MemoryView":666 * seen_ellipsis = False * for idx, item in enumerate(tup): * if item is Ellipsis: # <<<<<<<<<<<<<< * if not seen_ellipsis: * result.extend([slice(None)] * (ndim - len(tup) + 1)) */ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis); __pyx_t_1 = (__pyx_t_2 != 0); if (__pyx_t_1) { /* "View.MemoryView":667 * for idx, item in enumerate(tup): * if item is Ellipsis: * if not seen_ellipsis: # <<<<<<<<<<<<<< * result.extend([slice(None)] * (ndim - len(tup) + 1)) * seen_ellipsis = True */ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0); if (__pyx_t_1) { /* "View.MemoryView":668 * if item is Ellipsis: * if not seen_ellipsis: * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<< * seen_ellipsis = True * else: */ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) __PYX_ERR(2, 668, __pyx_L1_error) __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 668, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); { Py_ssize_t __pyx_temp; for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) { __Pyx_INCREF(__pyx_slice__16); __Pyx_GIVEREF(__pyx_slice__16); PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__16); } } __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) __PYX_ERR(2, 668, __pyx_L1_error) __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; /* "View.MemoryView":669 * if not seen_ellipsis: * result.extend([slice(None)] * (ndim - len(tup) + 1)) * seen_ellipsis = True # <<<<<<<<<<<<<< * else: * result.append(slice(None)) */ __pyx_v_seen_ellipsis = 1; /* "View.MemoryView":667 * for idx, item in enumerate(tup): * if item is Ellipsis: * if not seen_ellipsis: # <<<<<<<<<<<<<< * result.extend([slice(None)] * (ndim - len(tup) + 1)) * seen_ellipsis = True */ goto __pyx_L7; } /* "View.MemoryView":671 * seen_ellipsis = True * else: * result.append(slice(None)) # <<<<<<<<<<<<<< * have_slices = True * else: */ /*else*/ { __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__17); if (unlikely(__pyx_t_9 == -1)) __PYX_ERR(2, 671, __pyx_L1_error) } __pyx_L7:; /* "View.MemoryView":672 * else: * result.append(slice(None)) * have_slices = True # <<<<<<<<<<<<<< * else: * if not isinstance(item, slice) and not PyIndex_Check(item): */ __pyx_v_have_slices = 1; /* "View.MemoryView":666 * seen_ellipsis = False * for idx, item in enumerate(tup): * if item is Ellipsis: # <<<<<<<<<<<<<< * if not seen_ellipsis: * result.extend([slice(None)] * (ndim - len(tup) + 1)) */ goto __pyx_L6; } /* "View.MemoryView":674 * have_slices = True * else: * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<< * raise TypeError("Cannot index with type '%s'" % type(item)) * */ /*else*/ { __pyx_t_2 = PySlice_Check(__pyx_v_item); __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0); if (__pyx_t_10) { } else { __pyx_t_1 = __pyx_t_10; goto __pyx_L9_bool_binop_done; } __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0); __pyx_t_1 = __pyx_t_10; __pyx_L9_bool_binop_done:; if (__pyx_t_1) { /* "View.MemoryView":675 * else: * if not isinstance(item, slice) and not PyIndex_Check(item): * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<< * * have_slices = have_slices or isinstance(item, slice) */ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 675, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) __PYX_ERR(2, 675, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_11); __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7); __pyx_t_7 = 0; __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 675, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; __Pyx_Raise(__pyx_t_7, 0, 0, 0); __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; __PYX_ERR(2, 675, __pyx_L1_error) /* "View.MemoryView":674 * have_slices = True * else: * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<< * raise TypeError("Cannot index with type '%s'" % type(item)) * */ } /* "View.MemoryView":677 * raise TypeError("Cannot index with type '%s'" % type(item)) * * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<< * result.append(item) * */ __pyx_t_10 = (__pyx_v_have_slices != 0); if (!__pyx_t_10) { } else { __pyx_t_1 = __pyx_t_10; goto __pyx_L11_bool_binop_done; } __pyx_t_10 = PySlice_Check(__pyx_v_item); __pyx_t_2 = (__pyx_t_10 != 0); __pyx_t_1 = __pyx_t_2; __pyx_L11_bool_binop_done:; __pyx_v_have_slices = __pyx_t_1; /* "View.MemoryView":678 * * have_slices = have_slices or isinstance(item, slice) * result.append(item) # <<<<<<<<<<<<<< * * nslices = ndim - len(result) */ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) __PYX_ERR(2, 678, __pyx_L1_error) } __pyx_L6:; /* "View.MemoryView":665 * have_slices = False * seen_ellipsis = False * for idx, item in enumerate(tup): # <<<<<<<<<<<<<< * if item is Ellipsis: * if not seen_ellipsis: */ } __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "View.MemoryView":680 * result.append(item) * * nslices = ndim - len(result) # <<<<<<<<<<<<<< * if nslices: * result.extend([slice(None)] * nslices) */ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) __PYX_ERR(2, 680, __pyx_L1_error) __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5); /* "View.MemoryView":681 * * nslices = ndim - len(result) * if nslices: # <<<<<<<<<<<<<< * result.extend([slice(None)] * nslices) * */ __pyx_t_1 = (__pyx_v_nslices != 0); if (__pyx_t_1) { /* "View.MemoryView":682 * nslices = ndim - len(result) * if nslices: * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<< * * return have_slices or nslices, tuple(result) */ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 682, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); { Py_ssize_t __pyx_temp; for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) { __Pyx_INCREF(__pyx_slice__18); __Pyx_GIVEREF(__pyx_slice__18); PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__18); } } __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) __PYX_ERR(2, 682, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "View.MemoryView":681 * * nslices = ndim - len(result) * if nslices: # <<<<<<<<<<<<<< * result.extend([slice(None)] * nslices) * */ } /* "View.MemoryView":684 * result.extend([slice(None)] * nslices) * * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<< * * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): */ __Pyx_XDECREF(__pyx_r); if (!__pyx_v_have_slices) { } else { __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 684, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = __pyx_t_4; __pyx_t_4 = 0; goto __pyx_L14_bool_binop_done; } __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 684, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = __pyx_t_4; __pyx_t_4 = 0; __pyx_L14_bool_binop_done:; __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 684, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(2, 684, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4); __pyx_t_3 = 0; __pyx_t_4 = 0; __pyx_r = ((PyObject*)__pyx_t_7); __pyx_t_7 = 0; goto __pyx_L0; /* "View.MemoryView":652 * return isinstance(o, memoryview) * * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<< * """ * Replace all ellipses with full slices and fill incomplete indices with */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_7); __Pyx_XDECREF(__pyx_t_11); __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF(__pyx_v_tup); __Pyx_XDECREF(__pyx_v_result); __Pyx_XDECREF(__pyx_v_idx); __Pyx_XDECREF(__pyx_v_item); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":686 * return have_slices or nslices, tuple(result) * * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<< * for suboffset in suboffsets[:ndim]: * if suboffset >= 0: */ static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) { Py_ssize_t __pyx_v_suboffset; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations Py_ssize_t *__pyx_t_1; Py_ssize_t *__pyx_t_2; Py_ssize_t *__pyx_t_3; int __pyx_t_4; PyObject *__pyx_t_5 = NULL; __Pyx_RefNannySetupContext("assert_direct_dimensions", 0); /* "View.MemoryView":687 * * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): * for suboffset in suboffsets[:ndim]: # <<<<<<<<<<<<<< * if suboffset >= 0: * raise ValueError("Indirect dimensions not supported") */ __pyx_t_2 = (__pyx_v_suboffsets + __pyx_v_ndim); for (__pyx_t_3 = __pyx_v_suboffsets; __pyx_t_3 < __pyx_t_2; __pyx_t_3++) { __pyx_t_1 = __pyx_t_3; __pyx_v_suboffset = (__pyx_t_1[0]); /* "View.MemoryView":688 * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): * for suboffset in suboffsets[:ndim]: * if suboffset >= 0: # <<<<<<<<<<<<<< * raise ValueError("Indirect dimensions not supported") * */ __pyx_t_4 = ((__pyx_v_suboffset >= 0) != 0); if (__pyx_t_4) { /* "View.MemoryView":689 * for suboffset in suboffsets[:ndim]: * if suboffset >= 0: * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<< * * */ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 689, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_Raise(__pyx_t_5, 0, 0, 0); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; __PYX_ERR(2, 689, __pyx_L1_error) /* "View.MemoryView":688 * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): * for suboffset in suboffsets[:ndim]: * if suboffset >= 0: # <<<<<<<<<<<<<< * raise ValueError("Indirect dimensions not supported") * */ } } /* "View.MemoryView":686 * return have_slices or nslices, tuple(result) * * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<< * for suboffset in suboffsets[:ndim]: * if suboffset >= 0: */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":696 * * @cname('__pyx_memview_slice') * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<< * cdef int new_ndim = 0, suboffset_dim = -1, dim * cdef bint negative_step */ static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) { int __pyx_v_new_ndim; int __pyx_v_suboffset_dim; int __pyx_v_dim; __Pyx_memviewslice __pyx_v_src; __Pyx_memviewslice __pyx_v_dst; __Pyx_memviewslice *__pyx_v_p_src; struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0; __Pyx_memviewslice *__pyx_v_p_dst; int *__pyx_v_p_suboffset_dim; Py_ssize_t __pyx_v_start; Py_ssize_t __pyx_v_stop; Py_ssize_t __pyx_v_step; int __pyx_v_have_start; int __pyx_v_have_stop; int __pyx_v_have_step; PyObject *__pyx_v_index = NULL; struct __pyx_memoryview_obj *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; struct __pyx_memoryview_obj *__pyx_t_4; char *__pyx_t_5; int __pyx_t_6; Py_ssize_t __pyx_t_7; PyObject *(*__pyx_t_8)(PyObject *); PyObject *__pyx_t_9 = NULL; Py_ssize_t __pyx_t_10; int __pyx_t_11; Py_ssize_t __pyx_t_12; __Pyx_RefNannySetupContext("memview_slice", 0); /* "View.MemoryView":697 * @cname('__pyx_memview_slice') * cdef memoryview memview_slice(memoryview memview, object indices): * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<< * cdef bint negative_step * cdef __Pyx_memviewslice src, dst */ __pyx_v_new_ndim = 0; __pyx_v_suboffset_dim = -1; /* "View.MemoryView":704 * * * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<< * * cdef _memoryviewslice memviewsliceobj */ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst))); /* "View.MemoryView":708 * cdef _memoryviewslice memviewsliceobj * * assert memview.view.ndim > 0 # <<<<<<<<<<<<<< * * if isinstance(memview, _memoryviewslice): */ #ifndef CYTHON_WITHOUT_ASSERTIONS if (unlikely(!Py_OptimizeFlag)) { if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) { PyErr_SetNone(PyExc_AssertionError); __PYX_ERR(2, 708, __pyx_L1_error) } } #endif /* "View.MemoryView":710 * assert memview.view.ndim > 0 * * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< * memviewsliceobj = memview * p_src = &memviewsliceobj.from_slice */ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "View.MemoryView":711 * * if isinstance(memview, _memoryviewslice): * memviewsliceobj = memview # <<<<<<<<<<<<<< * p_src = &memviewsliceobj.from_slice * else: */ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) __PYX_ERR(2, 711, __pyx_L1_error) __pyx_t_3 = ((PyObject *)__pyx_v_memview); __Pyx_INCREF(__pyx_t_3); __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3); __pyx_t_3 = 0; /* "View.MemoryView":712 * if isinstance(memview, _memoryviewslice): * memviewsliceobj = memview * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<< * else: * slice_copy(memview, &src) */ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice); /* "View.MemoryView":710 * assert memview.view.ndim > 0 * * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< * memviewsliceobj = memview * p_src = &memviewsliceobj.from_slice */ goto __pyx_L3; } /* "View.MemoryView":714 * p_src = &memviewsliceobj.from_slice * else: * slice_copy(memview, &src) # <<<<<<<<<<<<<< * p_src = &src * */ /*else*/ { __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src)); /* "View.MemoryView":715 * else: * slice_copy(memview, &src) * p_src = &src # <<<<<<<<<<<<<< * * */ __pyx_v_p_src = (&__pyx_v_src); } __pyx_L3:; /* "View.MemoryView":721 * * * dst.memview = p_src.memview # <<<<<<<<<<<<<< * dst.data = p_src.data * */ __pyx_t_4 = __pyx_v_p_src->memview; __pyx_v_dst.memview = __pyx_t_4; /* "View.MemoryView":722 * * dst.memview = p_src.memview * dst.data = p_src.data # <<<<<<<<<<<<<< * * */ __pyx_t_5 = __pyx_v_p_src->data; __pyx_v_dst.data = __pyx_t_5; /* "View.MemoryView":727 * * * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<< * cdef int *p_suboffset_dim = &suboffset_dim * cdef Py_ssize_t start, stop, step */ __pyx_v_p_dst = (&__pyx_v_dst); /* "View.MemoryView":728 * * cdef __Pyx_memviewslice *p_dst = &dst * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<< * cdef Py_ssize_t start, stop, step * cdef bint have_start, have_stop, have_step */ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim); /* "View.MemoryView":732 * cdef bint have_start, have_stop, have_step * * for dim, index in enumerate(indices): # <<<<<<<<<<<<<< * if PyIndex_Check(index): * slice_memviewslice( */ __pyx_t_6 = 0; if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) { __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0; __pyx_t_8 = NULL; } else { __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 732, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 732, __pyx_L1_error) } for (;;) { if (likely(!__pyx_t_8)) { if (likely(PyList_CheckExact(__pyx_t_3))) { if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) __PYX_ERR(2, 732, __pyx_L1_error) #else __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 732, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); #endif } else { if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break; #if CYTHON_COMPILING_IN_CPYTHON __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) __PYX_ERR(2, 732, __pyx_L1_error) #else __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 732, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); #endif } } else { __pyx_t_9 = __pyx_t_8(__pyx_t_3); if (unlikely(!__pyx_t_9)) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); else __PYX_ERR(2, 732, __pyx_L1_error) } break; } __Pyx_GOTREF(__pyx_t_9); } __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9); __pyx_t_9 = 0; __pyx_v_dim = __pyx_t_6; __pyx_t_6 = (__pyx_t_6 + 1); /* "View.MemoryView":733 * * for dim, index in enumerate(indices): * if PyIndex_Check(index): # <<<<<<<<<<<<<< * slice_memviewslice( * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], */ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0); if (__pyx_t_2) { /* "View.MemoryView":737 * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], * dim, new_ndim, p_suboffset_dim, * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<< * 0, 0, 0, # have_{start,stop,step} * False) */ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 737, __pyx_L1_error) /* "View.MemoryView":734 * for dim, index in enumerate(indices): * if PyIndex_Check(index): * slice_memviewslice( # <<<<<<<<<<<<<< * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], * dim, new_ndim, p_suboffset_dim, */ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) __PYX_ERR(2, 734, __pyx_L1_error) /* "View.MemoryView":733 * * for dim, index in enumerate(indices): * if PyIndex_Check(index): # <<<<<<<<<<<<<< * slice_memviewslice( * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], */ goto __pyx_L6; } /* "View.MemoryView":740 * 0, 0, 0, # have_{start,stop,step} * False) * elif index is None: # <<<<<<<<<<<<<< * p_dst.shape[new_ndim] = 1 * p_dst.strides[new_ndim] = 0 */ __pyx_t_2 = (__pyx_v_index == Py_None); __pyx_t_1 = (__pyx_t_2 != 0); if (__pyx_t_1) { /* "View.MemoryView":741 * False) * elif index is None: * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<< * p_dst.strides[new_ndim] = 0 * p_dst.suboffsets[new_ndim] = -1 */ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1; /* "View.MemoryView":742 * elif index is None: * p_dst.shape[new_ndim] = 1 * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<< * p_dst.suboffsets[new_ndim] = -1 * new_ndim += 1 */ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0; /* "View.MemoryView":743 * p_dst.shape[new_ndim] = 1 * p_dst.strides[new_ndim] = 0 * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<< * new_ndim += 1 * else: */ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1L; /* "View.MemoryView":744 * p_dst.strides[new_ndim] = 0 * p_dst.suboffsets[new_ndim] = -1 * new_ndim += 1 # <<<<<<<<<<<<<< * else: * start = index.start or 0 */ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1); /* "View.MemoryView":740 * 0, 0, 0, # have_{start,stop,step} * False) * elif index is None: # <<<<<<<<<<<<<< * p_dst.shape[new_ndim] = 1 * p_dst.strides[new_ndim] = 0 */ goto __pyx_L6; } /* "View.MemoryView":746 * new_ndim += 1 * else: * start = index.start or 0 # <<<<<<<<<<<<<< * stop = index.stop or 0 * step = index.step or 0 */ /*else*/ { __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 746, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 746, __pyx_L1_error) if (!__pyx_t_1) { __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; } else { __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 746, __pyx_L1_error) __pyx_t_10 = __pyx_t_12; __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; goto __pyx_L7_bool_binop_done; } __pyx_t_10 = 0; __pyx_L7_bool_binop_done:; __pyx_v_start = __pyx_t_10; /* "View.MemoryView":747 * else: * start = index.start or 0 * stop = index.stop or 0 # <<<<<<<<<<<<<< * step = index.step or 0 * */ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 747, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 747, __pyx_L1_error) if (!__pyx_t_1) { __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; } else { __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 747, __pyx_L1_error) __pyx_t_10 = __pyx_t_12; __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; goto __pyx_L9_bool_binop_done; } __pyx_t_10 = 0; __pyx_L9_bool_binop_done:; __pyx_v_stop = __pyx_t_10; /* "View.MemoryView":748 * start = index.start or 0 * stop = index.stop or 0 * step = index.step or 0 # <<<<<<<<<<<<<< * * have_start = index.start is not None */ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 748, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(2, 748, __pyx_L1_error) if (!__pyx_t_1) { __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; } else { __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 748, __pyx_L1_error) __pyx_t_10 = __pyx_t_12; __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; goto __pyx_L11_bool_binop_done; } __pyx_t_10 = 0; __pyx_L11_bool_binop_done:; __pyx_v_step = __pyx_t_10; /* "View.MemoryView":750 * step = index.step or 0 * * have_start = index.start is not None # <<<<<<<<<<<<<< * have_stop = index.stop is not None * have_step = index.step is not None */ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 750, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_1 = (__pyx_t_9 != Py_None); __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; __pyx_v_have_start = __pyx_t_1; /* "View.MemoryView":751 * * have_start = index.start is not None * have_stop = index.stop is not None # <<<<<<<<<<<<<< * have_step = index.step is not None * */ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 751, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_1 = (__pyx_t_9 != Py_None); __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; __pyx_v_have_stop = __pyx_t_1; /* "View.MemoryView":752 * have_start = index.start is not None * have_stop = index.stop is not None * have_step = index.step is not None # <<<<<<<<<<<<<< * * slice_memviewslice( */ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) __PYX_ERR(2, 752, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_9); __pyx_t_1 = (__pyx_t_9 != Py_None); __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; __pyx_v_have_step = __pyx_t_1; /* "View.MemoryView":754 * have_step = index.step is not None * * slice_memviewslice( # <<<<<<<<<<<<<< * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], * dim, new_ndim, p_suboffset_dim, */ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) __PYX_ERR(2, 754, __pyx_L1_error) /* "View.MemoryView":760 * have_start, have_stop, have_step, * True) * new_ndim += 1 # <<<<<<<<<<<<<< * * if isinstance(memview, _memoryviewslice): */ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1); } __pyx_L6:; /* "View.MemoryView":732 * cdef bint have_start, have_stop, have_step * * for dim, index in enumerate(indices): # <<<<<<<<<<<<<< * if PyIndex_Check(index): * slice_memviewslice( */ } __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; /* "View.MemoryView":762 * new_ndim += 1 * * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< * return memoryview_fromslice(dst, new_ndim, * memviewsliceobj.to_object_func, */ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "View.MemoryView":763 * * if isinstance(memview, _memoryviewslice): * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<< * memviewsliceobj.to_object_func, * memviewsliceobj.to_dtype_func, */ __Pyx_XDECREF(((PyObject *)__pyx_r)); /* "View.MemoryView":764 * if isinstance(memview, _memoryviewslice): * return memoryview_fromslice(dst, new_ndim, * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<< * memviewsliceobj.to_dtype_func, * memview.dtype_is_object) */ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); __PYX_ERR(2, 764, __pyx_L1_error) } /* "View.MemoryView":765 * return memoryview_fromslice(dst, new_ndim, * memviewsliceobj.to_object_func, * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<< * memview.dtype_is_object) * else: */ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); __PYX_ERR(2, 765, __pyx_L1_error) } /* "View.MemoryView":763 * * if isinstance(memview, _memoryviewslice): * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<< * memviewsliceobj.to_object_func, * memviewsliceobj.to_dtype_func, */ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 763, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) __PYX_ERR(2, 763, __pyx_L1_error) __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3); __pyx_t_3 = 0; goto __pyx_L0; /* "View.MemoryView":762 * new_ndim += 1 * * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< * return memoryview_fromslice(dst, new_ndim, * memviewsliceobj.to_object_func, */ } /* "View.MemoryView":768 * memview.dtype_is_object) * else: * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<< * memview.dtype_is_object) * */ /*else*/ { __Pyx_XDECREF(((PyObject *)__pyx_r)); /* "View.MemoryView":769 * else: * return memoryview_fromslice(dst, new_ndim, NULL, NULL, * memview.dtype_is_object) # <<<<<<<<<<<<<< * * */ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 768, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); /* "View.MemoryView":768 * memview.dtype_is_object) * else: * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<< * memview.dtype_is_object) * */ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) __PYX_ERR(2, 768, __pyx_L1_error) __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3); __pyx_t_3 = 0; goto __pyx_L0; } /* "View.MemoryView":696 * * @cname('__pyx_memview_slice') * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<< * cdef int new_ndim = 0, suboffset_dim = -1, dim * cdef bint negative_step */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_9); __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj); __Pyx_XDECREF(__pyx_v_index); __Pyx_XGIVEREF((PyObject *)__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":793 * * @cname('__pyx_memoryview_slice_memviewslice') * cdef int slice_memviewslice( # <<<<<<<<<<<<<< * __Pyx_memviewslice *dst, * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, */ static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) { Py_ssize_t __pyx_v_new_shape; int __pyx_v_negative_step; int __pyx_r; int __pyx_t_1; int __pyx_t_2; int __pyx_t_3; /* "View.MemoryView":813 * cdef bint negative_step * * if not is_slice: # <<<<<<<<<<<<<< * * if start < 0: */ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0); if (__pyx_t_1) { /* "View.MemoryView":815 * if not is_slice: * * if start < 0: # <<<<<<<<<<<<<< * start += shape * if not 0 <= start < shape: */ __pyx_t_1 = ((__pyx_v_start < 0) != 0); if (__pyx_t_1) { /* "View.MemoryView":816 * * if start < 0: * start += shape # <<<<<<<<<<<<<< * if not 0 <= start < shape: * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) */ __pyx_v_start = (__pyx_v_start + __pyx_v_shape); /* "View.MemoryView":815 * if not is_slice: * * if start < 0: # <<<<<<<<<<<<<< * start += shape * if not 0 <= start < shape: */ } /* "View.MemoryView":817 * if start < 0: * start += shape * if not 0 <= start < shape: # <<<<<<<<<<<<<< * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) * else: */ __pyx_t_1 = (0 <= __pyx_v_start); if (__pyx_t_1) { __pyx_t_1 = (__pyx_v_start < __pyx_v_shape); } __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); if (__pyx_t_2) { /* "View.MemoryView":818 * start += shape * if not 0 <= start < shape: * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<< * else: * */ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, ((char *)"Index out of bounds (axis %d)"), __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) __PYX_ERR(2, 818, __pyx_L1_error) /* "View.MemoryView":817 * if start < 0: * start += shape * if not 0 <= start < shape: # <<<<<<<<<<<<<< * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) * else: */ } /* "View.MemoryView":813 * cdef bint negative_step * * if not is_slice: # <<<<<<<<<<<<<< * * if start < 0: */ goto __pyx_L3; } /* "View.MemoryView":821 * else: * * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<< * * if have_step and step == 0: */ /*else*/ { __pyx_t_1 = ((__pyx_v_have_step != 0) != 0); if (__pyx_t_1) { } else { __pyx_t_2 = __pyx_t_1; goto __pyx_L6_bool_binop_done; } __pyx_t_1 = ((__pyx_v_step < 0) != 0); __pyx_t_2 = __pyx_t_1; __pyx_L6_bool_binop_done:; __pyx_v_negative_step = __pyx_t_2; /* "View.MemoryView":823 * negative_step = have_step != 0 and step < 0 * * if have_step and step == 0: # <<<<<<<<<<<<<< * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) * */ __pyx_t_1 = (__pyx_v_have_step != 0); if (__pyx_t_1) { } else { __pyx_t_2 = __pyx_t_1; goto __pyx_L9_bool_binop_done; } __pyx_t_1 = ((__pyx_v_step == 0) != 0); __pyx_t_2 = __pyx_t_1; __pyx_L9_bool_binop_done:; if (__pyx_t_2) { /* "View.MemoryView":824 * * if have_step and step == 0: * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<< * * */ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, ((char *)"Step may not be zero (axis %d)"), __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) __PYX_ERR(2, 824, __pyx_L1_error) /* "View.MemoryView":823 * negative_step = have_step != 0 and step < 0 * * if have_step and step == 0: # <<<<<<<<<<<<<< * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) * */ } /* "View.MemoryView":827 * * * if have_start: # <<<<<<<<<<<<<< * if start < 0: * start += shape */ __pyx_t_2 = (__pyx_v_have_start != 0); if (__pyx_t_2) { /* "View.MemoryView":828 * * if have_start: * if start < 0: # <<<<<<<<<<<<<< * start += shape * if start < 0: */ __pyx_t_2 = ((__pyx_v_start < 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":829 * if have_start: * if start < 0: * start += shape # <<<<<<<<<<<<<< * if start < 0: * start = 0 */ __pyx_v_start = (__pyx_v_start + __pyx_v_shape); /* "View.MemoryView":830 * if start < 0: * start += shape * if start < 0: # <<<<<<<<<<<<<< * start = 0 * elif start >= shape: */ __pyx_t_2 = ((__pyx_v_start < 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":831 * start += shape * if start < 0: * start = 0 # <<<<<<<<<<<<<< * elif start >= shape: * if negative_step: */ __pyx_v_start = 0; /* "View.MemoryView":830 * if start < 0: * start += shape * if start < 0: # <<<<<<<<<<<<<< * start = 0 * elif start >= shape: */ } /* "View.MemoryView":828 * * if have_start: * if start < 0: # <<<<<<<<<<<<<< * start += shape * if start < 0: */ goto __pyx_L12; } /* "View.MemoryView":832 * if start < 0: * start = 0 * elif start >= shape: # <<<<<<<<<<<<<< * if negative_step: * start = shape - 1 */ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0); if (__pyx_t_2) { /* "View.MemoryView":833 * start = 0 * elif start >= shape: * if negative_step: # <<<<<<<<<<<<<< * start = shape - 1 * else: */ __pyx_t_2 = (__pyx_v_negative_step != 0); if (__pyx_t_2) { /* "View.MemoryView":834 * elif start >= shape: * if negative_step: * start = shape - 1 # <<<<<<<<<<<<<< * else: * start = shape */ __pyx_v_start = (__pyx_v_shape - 1); /* "View.MemoryView":833 * start = 0 * elif start >= shape: * if negative_step: # <<<<<<<<<<<<<< * start = shape - 1 * else: */ goto __pyx_L14; } /* "View.MemoryView":836 * start = shape - 1 * else: * start = shape # <<<<<<<<<<<<<< * else: * if negative_step: */ /*else*/ { __pyx_v_start = __pyx_v_shape; } __pyx_L14:; /* "View.MemoryView":832 * if start < 0: * start = 0 * elif start >= shape: # <<<<<<<<<<<<<< * if negative_step: * start = shape - 1 */ } __pyx_L12:; /* "View.MemoryView":827 * * * if have_start: # <<<<<<<<<<<<<< * if start < 0: * start += shape */ goto __pyx_L11; } /* "View.MemoryView":838 * start = shape * else: * if negative_step: # <<<<<<<<<<<<<< * start = shape - 1 * else: */ /*else*/ { __pyx_t_2 = (__pyx_v_negative_step != 0); if (__pyx_t_2) { /* "View.MemoryView":839 * else: * if negative_step: * start = shape - 1 # <<<<<<<<<<<<<< * else: * start = 0 */ __pyx_v_start = (__pyx_v_shape - 1); /* "View.MemoryView":838 * start = shape * else: * if negative_step: # <<<<<<<<<<<<<< * start = shape - 1 * else: */ goto __pyx_L15; } /* "View.MemoryView":841 * start = shape - 1 * else: * start = 0 # <<<<<<<<<<<<<< * * if have_stop: */ /*else*/ { __pyx_v_start = 0; } __pyx_L15:; } __pyx_L11:; /* "View.MemoryView":843 * start = 0 * * if have_stop: # <<<<<<<<<<<<<< * if stop < 0: * stop += shape */ __pyx_t_2 = (__pyx_v_have_stop != 0); if (__pyx_t_2) { /* "View.MemoryView":844 * * if have_stop: * if stop < 0: # <<<<<<<<<<<<<< * stop += shape * if stop < 0: */ __pyx_t_2 = ((__pyx_v_stop < 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":845 * if have_stop: * if stop < 0: * stop += shape # <<<<<<<<<<<<<< * if stop < 0: * stop = 0 */ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape); /* "View.MemoryView":846 * if stop < 0: * stop += shape * if stop < 0: # <<<<<<<<<<<<<< * stop = 0 * elif stop > shape: */ __pyx_t_2 = ((__pyx_v_stop < 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":847 * stop += shape * if stop < 0: * stop = 0 # <<<<<<<<<<<<<< * elif stop > shape: * stop = shape */ __pyx_v_stop = 0; /* "View.MemoryView":846 * if stop < 0: * stop += shape * if stop < 0: # <<<<<<<<<<<<<< * stop = 0 * elif stop > shape: */ } /* "View.MemoryView":844 * * if have_stop: * if stop < 0: # <<<<<<<<<<<<<< * stop += shape * if stop < 0: */ goto __pyx_L17; } /* "View.MemoryView":848 * if stop < 0: * stop = 0 * elif stop > shape: # <<<<<<<<<<<<<< * stop = shape * else: */ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0); if (__pyx_t_2) { /* "View.MemoryView":849 * stop = 0 * elif stop > shape: * stop = shape # <<<<<<<<<<<<<< * else: * if negative_step: */ __pyx_v_stop = __pyx_v_shape; /* "View.MemoryView":848 * if stop < 0: * stop = 0 * elif stop > shape: # <<<<<<<<<<<<<< * stop = shape * else: */ } __pyx_L17:; /* "View.MemoryView":843 * start = 0 * * if have_stop: # <<<<<<<<<<<<<< * if stop < 0: * stop += shape */ goto __pyx_L16; } /* "View.MemoryView":851 * stop = shape * else: * if negative_step: # <<<<<<<<<<<<<< * stop = -1 * else: */ /*else*/ { __pyx_t_2 = (__pyx_v_negative_step != 0); if (__pyx_t_2) { /* "View.MemoryView":852 * else: * if negative_step: * stop = -1 # <<<<<<<<<<<<<< * else: * stop = shape */ __pyx_v_stop = -1L; /* "View.MemoryView":851 * stop = shape * else: * if negative_step: # <<<<<<<<<<<<<< * stop = -1 * else: */ goto __pyx_L19; } /* "View.MemoryView":854 * stop = -1 * else: * stop = shape # <<<<<<<<<<<<<< * * if not have_step: */ /*else*/ { __pyx_v_stop = __pyx_v_shape; } __pyx_L19:; } __pyx_L16:; /* "View.MemoryView":856 * stop = shape * * if not have_step: # <<<<<<<<<<<<<< * step = 1 * */ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0); if (__pyx_t_2) { /* "View.MemoryView":857 * * if not have_step: * step = 1 # <<<<<<<<<<<<<< * * */ __pyx_v_step = 1; /* "View.MemoryView":856 * stop = shape * * if not have_step: # <<<<<<<<<<<<<< * step = 1 * */ } /* "View.MemoryView":861 * * with cython.cdivision(True): * new_shape = (stop - start) // step # <<<<<<<<<<<<<< * * if (stop - start) - step * new_shape: */ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step); /* "View.MemoryView":863 * new_shape = (stop - start) // step * * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<< * new_shape += 1 * */ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0); if (__pyx_t_2) { /* "View.MemoryView":864 * * if (stop - start) - step * new_shape: * new_shape += 1 # <<<<<<<<<<<<<< * * if new_shape < 0: */ __pyx_v_new_shape = (__pyx_v_new_shape + 1); /* "View.MemoryView":863 * new_shape = (stop - start) // step * * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<< * new_shape += 1 * */ } /* "View.MemoryView":866 * new_shape += 1 * * if new_shape < 0: # <<<<<<<<<<<<<< * new_shape = 0 * */ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":867 * * if new_shape < 0: * new_shape = 0 # <<<<<<<<<<<<<< * * */ __pyx_v_new_shape = 0; /* "View.MemoryView":866 * new_shape += 1 * * if new_shape < 0: # <<<<<<<<<<<<<< * new_shape = 0 * */ } /* "View.MemoryView":870 * * * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<< * dst.shape[new_ndim] = new_shape * dst.suboffsets[new_ndim] = suboffset */ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step); /* "View.MemoryView":871 * * dst.strides[new_ndim] = stride * step * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<< * dst.suboffsets[new_ndim] = suboffset * */ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape; /* "View.MemoryView":872 * dst.strides[new_ndim] = stride * step * dst.shape[new_ndim] = new_shape * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<< * * */ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset; } __pyx_L3:; /* "View.MemoryView":875 * * * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<< * dst.data += start * stride * else: */ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":876 * * if suboffset_dim[0] < 0: * dst.data += start * stride # <<<<<<<<<<<<<< * else: * dst.suboffsets[suboffset_dim[0]] += start * stride */ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride)); /* "View.MemoryView":875 * * * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<< * dst.data += start * stride * else: */ goto __pyx_L23; } /* "View.MemoryView":878 * dst.data += start * stride * else: * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<< * * if suboffset >= 0: */ /*else*/ { __pyx_t_3 = (__pyx_v_suboffset_dim[0]); (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride)); } __pyx_L23:; /* "View.MemoryView":880 * dst.suboffsets[suboffset_dim[0]] += start * stride * * if suboffset >= 0: # <<<<<<<<<<<<<< * if not is_slice: * if new_ndim == 0: */ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":881 * * if suboffset >= 0: * if not is_slice: # <<<<<<<<<<<<<< * if new_ndim == 0: * dst.data = ( dst.data)[0] + suboffset */ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0); if (__pyx_t_2) { /* "View.MemoryView":882 * if suboffset >= 0: * if not is_slice: * if new_ndim == 0: # <<<<<<<<<<<<<< * dst.data = ( dst.data)[0] + suboffset * else: */ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":883 * if not is_slice: * if new_ndim == 0: * dst.data = ( dst.data)[0] + suboffset # <<<<<<<<<<<<<< * else: * _err_dim(IndexError, "All dimensions preceding dimension %d " */ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset); /* "View.MemoryView":882 * if suboffset >= 0: * if not is_slice: * if new_ndim == 0: # <<<<<<<<<<<<<< * dst.data = ( dst.data)[0] + suboffset * else: */ goto __pyx_L26; } /* "View.MemoryView":885 * dst.data = ( dst.data)[0] + suboffset * else: * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<< * "must be indexed and not sliced", dim) * else: */ /*else*/ { /* "View.MemoryView":886 * else: * _err_dim(IndexError, "All dimensions preceding dimension %d " * "must be indexed and not sliced", dim) # <<<<<<<<<<<<<< * else: * suboffset_dim[0] = new_ndim */ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, ((char *)"All dimensions preceding dimension %d must be indexed and not sliced"), __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) __PYX_ERR(2, 885, __pyx_L1_error) } __pyx_L26:; /* "View.MemoryView":881 * * if suboffset >= 0: * if not is_slice: # <<<<<<<<<<<<<< * if new_ndim == 0: * dst.data = ( dst.data)[0] + suboffset */ goto __pyx_L25; } /* "View.MemoryView":888 * "must be indexed and not sliced", dim) * else: * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<< * * return 0 */ /*else*/ { (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim; } __pyx_L25:; /* "View.MemoryView":880 * dst.suboffsets[suboffset_dim[0]] += start * stride * * if suboffset >= 0: # <<<<<<<<<<<<<< * if not is_slice: * if new_ndim == 0: */ } /* "View.MemoryView":890 * suboffset_dim[0] = new_ndim * * return 0 # <<<<<<<<<<<<<< * * */ __pyx_r = 0; goto __pyx_L0; /* "View.MemoryView":793 * * @cname('__pyx_memoryview_slice_memviewslice') * cdef int slice_memviewslice( # <<<<<<<<<<<<<< * __Pyx_memviewslice *dst, * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, */ /* function exit code */ __pyx_L1_error:; { #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); #endif __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename); #ifdef WITH_THREAD PyGILState_Release(__pyx_gilstate_save); #endif } __pyx_r = -1; __pyx_L0:; return __pyx_r; } /* "View.MemoryView":896 * * @cname('__pyx_pybuffer_index') * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<< * Py_ssize_t dim) except NULL: * cdef Py_ssize_t shape, stride, suboffset = -1 */ static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) { Py_ssize_t __pyx_v_shape; Py_ssize_t __pyx_v_stride; Py_ssize_t __pyx_v_suboffset; Py_ssize_t __pyx_v_itemsize; char *__pyx_v_resultp; char *__pyx_r; __Pyx_RefNannyDeclarations Py_ssize_t __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; __Pyx_RefNannySetupContext("pybuffer_index", 0); /* "View.MemoryView":898 * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, * Py_ssize_t dim) except NULL: * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<< * cdef Py_ssize_t itemsize = view.itemsize * cdef char *resultp */ __pyx_v_suboffset = -1L; /* "View.MemoryView":899 * Py_ssize_t dim) except NULL: * cdef Py_ssize_t shape, stride, suboffset = -1 * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<< * cdef char *resultp * */ __pyx_t_1 = __pyx_v_view->itemsize; __pyx_v_itemsize = __pyx_t_1; /* "View.MemoryView":902 * cdef char *resultp * * if view.ndim == 0: # <<<<<<<<<<<<<< * shape = view.len / itemsize * stride = itemsize */ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":903 * * if view.ndim == 0: * shape = view.len / itemsize # <<<<<<<<<<<<<< * stride = itemsize * else: */ if (unlikely(__pyx_v_itemsize == 0)) { PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero"); __PYX_ERR(2, 903, __pyx_L1_error) } else if (sizeof(Py_ssize_t) == sizeof(long) && (!(((Py_ssize_t)-1) > 0)) && unlikely(__pyx_v_itemsize == (Py_ssize_t)-1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) { PyErr_SetString(PyExc_OverflowError, "value too large to perform division"); __PYX_ERR(2, 903, __pyx_L1_error) } __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize); /* "View.MemoryView":904 * if view.ndim == 0: * shape = view.len / itemsize * stride = itemsize # <<<<<<<<<<<<<< * else: * shape = view.shape[dim] */ __pyx_v_stride = __pyx_v_itemsize; /* "View.MemoryView":902 * cdef char *resultp * * if view.ndim == 0: # <<<<<<<<<<<<<< * shape = view.len / itemsize * stride = itemsize */ goto __pyx_L3; } /* "View.MemoryView":906 * stride = itemsize * else: * shape = view.shape[dim] # <<<<<<<<<<<<<< * stride = view.strides[dim] * if view.suboffsets != NULL: */ /*else*/ { __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]); /* "View.MemoryView":907 * else: * shape = view.shape[dim] * stride = view.strides[dim] # <<<<<<<<<<<<<< * if view.suboffsets != NULL: * suboffset = view.suboffsets[dim] */ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]); /* "View.MemoryView":908 * shape = view.shape[dim] * stride = view.strides[dim] * if view.suboffsets != NULL: # <<<<<<<<<<<<<< * suboffset = view.suboffsets[dim] * */ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0); if (__pyx_t_2) { /* "View.MemoryView":909 * stride = view.strides[dim] * if view.suboffsets != NULL: * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<< * * if index < 0: */ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]); /* "View.MemoryView":908 * shape = view.shape[dim] * stride = view.strides[dim] * if view.suboffsets != NULL: # <<<<<<<<<<<<<< * suboffset = view.suboffsets[dim] * */ } } __pyx_L3:; /* "View.MemoryView":911 * suboffset = view.suboffsets[dim] * * if index < 0: # <<<<<<<<<<<<<< * index += view.shape[dim] * if index < 0: */ __pyx_t_2 = ((__pyx_v_index < 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":912 * * if index < 0: * index += view.shape[dim] # <<<<<<<<<<<<<< * if index < 0: * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) */ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim])); /* "View.MemoryView":913 * if index < 0: * index += view.shape[dim] * if index < 0: # <<<<<<<<<<<<<< * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) * */ __pyx_t_2 = ((__pyx_v_index < 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":914 * index += view.shape[dim] * if index < 0: * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<< * * if index >= shape: */ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 914, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 914, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 914, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 914, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_Raise(__pyx_t_4, 0, 0, 0); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __PYX_ERR(2, 914, __pyx_L1_error) /* "View.MemoryView":913 * if index < 0: * index += view.shape[dim] * if index < 0: # <<<<<<<<<<<<<< * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) * */ } /* "View.MemoryView":911 * suboffset = view.suboffsets[dim] * * if index < 0: # <<<<<<<<<<<<<< * index += view.shape[dim] * if index < 0: */ } /* "View.MemoryView":916 * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) * * if index >= shape: # <<<<<<<<<<<<<< * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) * */ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0); if (__pyx_t_2) { /* "View.MemoryView":917 * * if index >= shape: * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<< * * resultp = bufp + index * stride */ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 917, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 917, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 917, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 917, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(2, 917, __pyx_L1_error) /* "View.MemoryView":916 * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) * * if index >= shape: # <<<<<<<<<<<<<< * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) * */ } /* "View.MemoryView":919 * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) * * resultp = bufp + index * stride # <<<<<<<<<<<<<< * if suboffset >= 0: * resultp = ( resultp)[0] + suboffset */ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride)); /* "View.MemoryView":920 * * resultp = bufp + index * stride * if suboffset >= 0: # <<<<<<<<<<<<<< * resultp = ( resultp)[0] + suboffset * */ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":921 * resultp = bufp + index * stride * if suboffset >= 0: * resultp = ( resultp)[0] + suboffset # <<<<<<<<<<<<<< * * return resultp */ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset); /* "View.MemoryView":920 * * resultp = bufp + index * stride * if suboffset >= 0: # <<<<<<<<<<<<<< * resultp = ( resultp)[0] + suboffset * */ } /* "View.MemoryView":923 * resultp = ( resultp)[0] + suboffset * * return resultp # <<<<<<<<<<<<<< * * */ __pyx_r = __pyx_v_resultp; goto __pyx_L0; /* "View.MemoryView":896 * * @cname('__pyx_pybuffer_index') * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<< * Py_ssize_t dim) except NULL: * cdef Py_ssize_t shape, stride, suboffset = -1 */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":929 * * @cname('__pyx_memslice_transpose') * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<< * cdef int ndim = memslice.memview.view.ndim * */ static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) { int __pyx_v_ndim; Py_ssize_t *__pyx_v_shape; Py_ssize_t *__pyx_v_strides; int __pyx_v_i; int __pyx_v_j; int __pyx_r; int __pyx_t_1; Py_ssize_t *__pyx_t_2; long __pyx_t_3; Py_ssize_t __pyx_t_4; Py_ssize_t __pyx_t_5; int __pyx_t_6; int __pyx_t_7; int __pyx_t_8; /* "View.MemoryView":930 * @cname('__pyx_memslice_transpose') * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<< * * cdef Py_ssize_t *shape = memslice.shape */ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim; __pyx_v_ndim = __pyx_t_1; /* "View.MemoryView":932 * cdef int ndim = memslice.memview.view.ndim * * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<< * cdef Py_ssize_t *strides = memslice.strides * */ __pyx_t_2 = __pyx_v_memslice->shape; __pyx_v_shape = __pyx_t_2; /* "View.MemoryView":933 * * cdef Py_ssize_t *shape = memslice.shape * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<< * * */ __pyx_t_2 = __pyx_v_memslice->strides; __pyx_v_strides = __pyx_t_2; /* "View.MemoryView":937 * * cdef int i, j * for i in range(ndim / 2): # <<<<<<<<<<<<<< * j = ndim - 1 - i * strides[i], strides[j] = strides[j], strides[i] */ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2); for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) { __pyx_v_i = __pyx_t_1; /* "View.MemoryView":938 * cdef int i, j * for i in range(ndim / 2): * j = ndim - 1 - i # <<<<<<<<<<<<<< * strides[i], strides[j] = strides[j], strides[i] * shape[i], shape[j] = shape[j], shape[i] */ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i); /* "View.MemoryView":939 * for i in range(ndim / 2): * j = ndim - 1 - i * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<< * shape[i], shape[j] = shape[j], shape[i] * */ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]); __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]); (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4; (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5; /* "View.MemoryView":940 * j = ndim - 1 - i * strides[i], strides[j] = strides[j], strides[i] * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<< * * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: */ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]); __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]); (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5; (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4; /* "View.MemoryView":942 * shape[i], shape[j] = shape[j], shape[i] * * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<< * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") * */ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0); if (!__pyx_t_7) { } else { __pyx_t_6 = __pyx_t_7; goto __pyx_L6_bool_binop_done; } __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0); __pyx_t_6 = __pyx_t_7; __pyx_L6_bool_binop_done:; if (__pyx_t_6) { /* "View.MemoryView":943 * * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<< * * return 1 */ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, ((char *)"Cannot transpose memoryview with indirect dimensions")); if (unlikely(__pyx_t_8 == -1)) __PYX_ERR(2, 943, __pyx_L1_error) /* "View.MemoryView":942 * shape[i], shape[j] = shape[j], shape[i] * * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<< * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") * */ } } /* "View.MemoryView":945 * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") * * return 1 # <<<<<<<<<<<<<< * * */ __pyx_r = 1; goto __pyx_L0; /* "View.MemoryView":929 * * @cname('__pyx_memslice_transpose') * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<< * cdef int ndim = memslice.memview.view.ndim * */ /* function exit code */ __pyx_L1_error:; { #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); #endif __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename); #ifdef WITH_THREAD PyGILState_Release(__pyx_gilstate_save); #endif } __pyx_r = 0; __pyx_L0:; return __pyx_r; } /* "View.MemoryView":962 * cdef int (*to_dtype_func)(char *, object) except 0 * * def __dealloc__(self): # <<<<<<<<<<<<<< * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) * */ /* Python wrapper */ static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/ static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); } static void __pyx_memoryviewslice___pyx_pf_15View_dot_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__dealloc__", 0); /* "View.MemoryView":963 * * def __dealloc__(self): * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<< * * cdef convert_item_to_object(self, char *itemp): */ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1); /* "View.MemoryView":962 * cdef int (*to_dtype_func)(char *, object) except 0 * * def __dealloc__(self): # <<<<<<<<<<<<<< * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) * */ /* function exit code */ __Pyx_RefNannyFinishContext(); } /* "View.MemoryView":965 * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) * * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< * if self.to_object_func != NULL: * return self.to_object_func(itemp) */ static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; __Pyx_RefNannySetupContext("convert_item_to_object", 0); /* "View.MemoryView":966 * * cdef convert_item_to_object(self, char *itemp): * if self.to_object_func != NULL: # <<<<<<<<<<<<<< * return self.to_object_func(itemp) * else: */ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":967 * cdef convert_item_to_object(self, char *itemp): * if self.to_object_func != NULL: * return self.to_object_func(itemp) # <<<<<<<<<<<<<< * else: * return memoryview.convert_item_to_object(self, itemp) */ __Pyx_XDECREF(__pyx_r); __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 967, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; /* "View.MemoryView":966 * * cdef convert_item_to_object(self, char *itemp): * if self.to_object_func != NULL: # <<<<<<<<<<<<<< * return self.to_object_func(itemp) * else: */ } /* "View.MemoryView":969 * return self.to_object_func(itemp) * else: * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<< * * cdef assign_item_from_object(self, char *itemp, object value): */ /*else*/ { __Pyx_XDECREF(__pyx_r); __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 969, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_r = __pyx_t_2; __pyx_t_2 = 0; goto __pyx_L0; } /* "View.MemoryView":965 * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) * * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<< * if self.to_object_func != NULL: * return self.to_object_func(itemp) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":971 * return memoryview.convert_item_to_object(self, itemp) * * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< * if self.to_dtype_func != NULL: * self.to_dtype_func(itemp, value) */ static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; __Pyx_RefNannySetupContext("assign_item_from_object", 0); /* "View.MemoryView":972 * * cdef assign_item_from_object(self, char *itemp, object value): * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<< * self.to_dtype_func(itemp, value) * else: */ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":973 * cdef assign_item_from_object(self, char *itemp, object value): * if self.to_dtype_func != NULL: * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<< * else: * memoryview.assign_item_from_object(self, itemp, value) */ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) __PYX_ERR(2, 973, __pyx_L1_error) /* "View.MemoryView":972 * * cdef assign_item_from_object(self, char *itemp, object value): * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<< * self.to_dtype_func(itemp, value) * else: */ goto __pyx_L3; } /* "View.MemoryView":975 * self.to_dtype_func(itemp, value) * else: * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<< * * @property */ /*else*/ { __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 975, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } __pyx_L3:; /* "View.MemoryView":971 * return memoryview.convert_item_to_object(self, itemp) * * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<< * if self.to_dtype_func != NULL: * self.to_dtype_func(itemp, value) */ /* function exit code */ __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":978 * * @property * def base(self): # <<<<<<<<<<<<<< * return self.from_object * */ /* Python wrapper */ static PyObject *__pyx_pw_15View_dot_MemoryView_16_memoryviewslice_4base_1__get__(PyObject *__pyx_v_self); /*proto*/ static PyObject *__pyx_pw_15View_dot_MemoryView_16_memoryviewslice_4base_1__get__(PyObject *__pyx_v_self) { PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); __pyx_r = __pyx_pf_15View_dot_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self)); /* function exit code */ __Pyx_RefNannyFinishContext(); return __pyx_r; } static PyObject *__pyx_pf_15View_dot_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) { PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__get__", 0); /* "View.MemoryView":979 * @property * def base(self): * return self.from_object # <<<<<<<<<<<<<< * * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_v_self->from_object); __pyx_r = __pyx_v_self->from_object; goto __pyx_L0; /* "View.MemoryView":978 * * @property * def base(self): # <<<<<<<<<<<<<< * return self.from_object * */ /* function exit code */ __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":985 * * @cname('__pyx_memoryview_fromslice') * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<< * int ndim, * object (*to_object_func)(char *), */ static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) { struct __pyx_memoryviewslice_obj *__pyx_v_result = 0; Py_ssize_t __pyx_v_suboffset; PyObject *__pyx_v_length = NULL; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; __Pyx_TypeInfo *__pyx_t_4; Py_buffer __pyx_t_5; Py_ssize_t *__pyx_t_6; Py_ssize_t *__pyx_t_7; Py_ssize_t *__pyx_t_8; Py_ssize_t __pyx_t_9; __Pyx_RefNannySetupContext("memoryview_fromslice", 0); /* "View.MemoryView":993 * cdef _memoryviewslice result * * if memviewslice.memview == Py_None: # <<<<<<<<<<<<<< * return None * */ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0); if (__pyx_t_1) { /* "View.MemoryView":994 * * if memviewslice.memview == Py_None: * return None # <<<<<<<<<<<<<< * * */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(Py_None); __pyx_r = Py_None; goto __pyx_L0; /* "View.MemoryView":993 * cdef _memoryviewslice result * * if memviewslice.memview == Py_None: # <<<<<<<<<<<<<< * return None * */ } /* "View.MemoryView":999 * * * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<< * * result.from_slice = memviewslice */ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 999, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 999, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_INCREF(Py_None); __Pyx_GIVEREF(Py_None); PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None); __Pyx_INCREF(__pyx_int_0); __Pyx_GIVEREF(__pyx_int_0); PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0); __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2); __pyx_t_2 = 0; __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_memoryviewslice_type), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 999, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2); __pyx_t_2 = 0; /* "View.MemoryView":1001 * result = _memoryviewslice(None, 0, dtype_is_object) * * result.from_slice = memviewslice # <<<<<<<<<<<<<< * __PYX_INC_MEMVIEW(&memviewslice, 1) * */ __pyx_v_result->from_slice = __pyx_v_memviewslice; /* "View.MemoryView":1002 * * result.from_slice = memviewslice * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<< * * result.from_object = ( memviewslice.memview).base */ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1); /* "View.MemoryView":1004 * __PYX_INC_MEMVIEW(&memviewslice, 1) * * result.from_object = ( memviewslice.memview).base # <<<<<<<<<<<<<< * result.typeinfo = memviewslice.memview.typeinfo * */ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1004, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __Pyx_GOTREF(__pyx_v_result->from_object); __Pyx_DECREF(__pyx_v_result->from_object); __pyx_v_result->from_object = __pyx_t_2; __pyx_t_2 = 0; /* "View.MemoryView":1005 * * result.from_object = ( memviewslice.memview).base * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<< * * result.view = memviewslice.memview.view */ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo; __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4; /* "View.MemoryView":1007 * result.typeinfo = memviewslice.memview.typeinfo * * result.view = memviewslice.memview.view # <<<<<<<<<<<<<< * result.view.buf = memviewslice.data * result.view.ndim = ndim */ __pyx_t_5 = __pyx_v_memviewslice.memview->view; __pyx_v_result->__pyx_base.view = __pyx_t_5; /* "View.MemoryView":1008 * * result.view = memviewslice.memview.view * result.view.buf = memviewslice.data # <<<<<<<<<<<<<< * result.view.ndim = ndim * (<__pyx_buffer *> &result.view).obj = Py_None */ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data); /* "View.MemoryView":1009 * result.view = memviewslice.memview.view * result.view.buf = memviewslice.data * result.view.ndim = ndim # <<<<<<<<<<<<<< * (<__pyx_buffer *> &result.view).obj = Py_None * Py_INCREF(Py_None) */ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim; /* "View.MemoryView":1010 * result.view.buf = memviewslice.data * result.view.ndim = ndim * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<< * Py_INCREF(Py_None) * */ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None; /* "View.MemoryView":1011 * result.view.ndim = ndim * (<__pyx_buffer *> &result.view).obj = Py_None * Py_INCREF(Py_None) # <<<<<<<<<<<<<< * * result.flags = PyBUF_RECORDS */ Py_INCREF(Py_None); /* "View.MemoryView":1013 * Py_INCREF(Py_None) * * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<< * * result.view.shape = result.from_slice.shape */ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS; /* "View.MemoryView":1015 * result.flags = PyBUF_RECORDS * * result.view.shape = result.from_slice.shape # <<<<<<<<<<<<<< * result.view.strides = result.from_slice.strides * */ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape); /* "View.MemoryView":1016 * * result.view.shape = result.from_slice.shape * result.view.strides = result.from_slice.strides # <<<<<<<<<<<<<< * * */ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides); /* "View.MemoryView":1019 * * * result.view.suboffsets = NULL # <<<<<<<<<<<<<< * for suboffset in result.from_slice.suboffsets[:ndim]: * if suboffset >= 0: */ __pyx_v_result->__pyx_base.view.suboffsets = NULL; /* "View.MemoryView":1020 * * result.view.suboffsets = NULL * for suboffset in result.from_slice.suboffsets[:ndim]: # <<<<<<<<<<<<<< * if suboffset >= 0: * result.view.suboffsets = result.from_slice.suboffsets */ __pyx_t_7 = (__pyx_v_result->from_slice.suboffsets + __pyx_v_ndim); for (__pyx_t_8 = __pyx_v_result->from_slice.suboffsets; __pyx_t_8 < __pyx_t_7; __pyx_t_8++) { __pyx_t_6 = __pyx_t_8; __pyx_v_suboffset = (__pyx_t_6[0]); /* "View.MemoryView":1021 * result.view.suboffsets = NULL * for suboffset in result.from_slice.suboffsets[:ndim]: * if suboffset >= 0: # <<<<<<<<<<<<<< * result.view.suboffsets = result.from_slice.suboffsets * break */ __pyx_t_1 = ((__pyx_v_suboffset >= 0) != 0); if (__pyx_t_1) { /* "View.MemoryView":1022 * for suboffset in result.from_slice.suboffsets[:ndim]: * if suboffset >= 0: * result.view.suboffsets = result.from_slice.suboffsets # <<<<<<<<<<<<<< * break * */ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets); /* "View.MemoryView":1023 * if suboffset >= 0: * result.view.suboffsets = result.from_slice.suboffsets * break # <<<<<<<<<<<<<< * * result.view.len = result.view.itemsize */ goto __pyx_L5_break; /* "View.MemoryView":1021 * result.view.suboffsets = NULL * for suboffset in result.from_slice.suboffsets[:ndim]: * if suboffset >= 0: # <<<<<<<<<<<<<< * result.view.suboffsets = result.from_slice.suboffsets * break */ } } __pyx_L5_break:; /* "View.MemoryView":1025 * break * * result.view.len = result.view.itemsize # <<<<<<<<<<<<<< * for length in result.view.shape[:ndim]: * result.view.len *= length */ __pyx_t_9 = __pyx_v_result->__pyx_base.view.itemsize; __pyx_v_result->__pyx_base.view.len = __pyx_t_9; /* "View.MemoryView":1026 * * result.view.len = result.view.itemsize * for length in result.view.shape[:ndim]: # <<<<<<<<<<<<<< * result.view.len *= length * */ __pyx_t_7 = (__pyx_v_result->__pyx_base.view.shape + __pyx_v_ndim); for (__pyx_t_8 = __pyx_v_result->__pyx_base.view.shape; __pyx_t_8 < __pyx_t_7; __pyx_t_8++) { __pyx_t_6 = __pyx_t_8; __pyx_t_2 = PyInt_FromSsize_t((__pyx_t_6[0])); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1026, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_2); __pyx_t_2 = 0; /* "View.MemoryView":1027 * result.view.len = result.view.itemsize * for length in result.view.shape[:ndim]: * result.view.len *= length # <<<<<<<<<<<<<< * * result.to_object_func = to_object_func */ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_result->__pyx_base.view.len); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1027, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_t_2, __pyx_v_length); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1027, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_t_3); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(2, 1027, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_v_result->__pyx_base.view.len = __pyx_t_9; } /* "View.MemoryView":1029 * result.view.len *= length * * result.to_object_func = to_object_func # <<<<<<<<<<<<<< * result.to_dtype_func = to_dtype_func * */ __pyx_v_result->to_object_func = __pyx_v_to_object_func; /* "View.MemoryView":1030 * * result.to_object_func = to_object_func * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<< * * return result */ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func; /* "View.MemoryView":1032 * result.to_dtype_func = to_dtype_func * * return result # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_get_slice_from_memoryview') */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_result)); __pyx_r = ((PyObject *)__pyx_v_result); goto __pyx_L0; /* "View.MemoryView":985 * * @cname('__pyx_memoryview_fromslice') * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<< * int ndim, * object (*to_object_func)(char *), */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_result); __Pyx_XDECREF(__pyx_v_length); __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":1035 * * @cname('__pyx_memoryview_get_slice_from_memoryview') * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<< * __Pyx_memviewslice *mslice): * cdef _memoryviewslice obj */ static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) { struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0; __Pyx_memviewslice *__pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *__pyx_t_3 = NULL; __Pyx_RefNannySetupContext("get_slice_from_memview", 0); /* "View.MemoryView":1038 * __Pyx_memviewslice *mslice): * cdef _memoryviewslice obj * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< * obj = memview * return &obj.from_slice */ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "View.MemoryView":1039 * cdef _memoryviewslice obj * if isinstance(memview, _memoryviewslice): * obj = memview # <<<<<<<<<<<<<< * return &obj.from_slice * else: */ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) __PYX_ERR(2, 1039, __pyx_L1_error) __pyx_t_3 = ((PyObject *)__pyx_v_memview); __Pyx_INCREF(__pyx_t_3); __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3); __pyx_t_3 = 0; /* "View.MemoryView":1040 * if isinstance(memview, _memoryviewslice): * obj = memview * return &obj.from_slice # <<<<<<<<<<<<<< * else: * slice_copy(memview, mslice) */ __pyx_r = (&__pyx_v_obj->from_slice); goto __pyx_L0; /* "View.MemoryView":1038 * __Pyx_memviewslice *mslice): * cdef _memoryviewslice obj * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< * obj = memview * return &obj.from_slice */ } /* "View.MemoryView":1042 * return &obj.from_slice * else: * slice_copy(memview, mslice) # <<<<<<<<<<<<<< * return mslice * */ /*else*/ { __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice); /* "View.MemoryView":1043 * else: * slice_copy(memview, mslice) * return mslice # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_slice_copy') */ __pyx_r = __pyx_v_mslice; goto __pyx_L0; } /* "View.MemoryView":1035 * * @cname('__pyx_memoryview_get_slice_from_memoryview') * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<< * __Pyx_memviewslice *mslice): * cdef _memoryviewslice obj */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_3); __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0, 0); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_obj); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":1046 * * @cname('__pyx_memoryview_slice_copy') * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<< * cdef int dim * cdef (Py_ssize_t*) shape, strides, suboffsets */ static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) { int __pyx_v_dim; Py_ssize_t *__pyx_v_shape; Py_ssize_t *__pyx_v_strides; Py_ssize_t *__pyx_v_suboffsets; __Pyx_RefNannyDeclarations Py_ssize_t *__pyx_t_1; int __pyx_t_2; int __pyx_t_3; Py_ssize_t __pyx_t_4; __Pyx_RefNannySetupContext("slice_copy", 0); /* "View.MemoryView":1050 * cdef (Py_ssize_t*) shape, strides, suboffsets * * shape = memview.view.shape # <<<<<<<<<<<<<< * strides = memview.view.strides * suboffsets = memview.view.suboffsets */ __pyx_t_1 = __pyx_v_memview->view.shape; __pyx_v_shape = __pyx_t_1; /* "View.MemoryView":1051 * * shape = memview.view.shape * strides = memview.view.strides # <<<<<<<<<<<<<< * suboffsets = memview.view.suboffsets * */ __pyx_t_1 = __pyx_v_memview->view.strides; __pyx_v_strides = __pyx_t_1; /* "View.MemoryView":1052 * shape = memview.view.shape * strides = memview.view.strides * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<< * * dst.memview = <__pyx_memoryview *> memview */ __pyx_t_1 = __pyx_v_memview->view.suboffsets; __pyx_v_suboffsets = __pyx_t_1; /* "View.MemoryView":1054 * suboffsets = memview.view.suboffsets * * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<< * dst.data = memview.view.buf * */ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview); /* "View.MemoryView":1055 * * dst.memview = <__pyx_memoryview *> memview * dst.data = memview.view.buf # <<<<<<<<<<<<<< * * for dim in range(memview.view.ndim): */ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf); /* "View.MemoryView":1057 * dst.data = memview.view.buf * * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<< * dst.shape[dim] = shape[dim] * dst.strides[dim] = strides[dim] */ __pyx_t_2 = __pyx_v_memview->view.ndim; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_dim = __pyx_t_3; /* "View.MemoryView":1058 * * for dim in range(memview.view.ndim): * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<< * dst.strides[dim] = strides[dim] * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 */ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]); /* "View.MemoryView":1059 * for dim in range(memview.view.ndim): * dst.shape[dim] = shape[dim] * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<< * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 * */ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]); /* "View.MemoryView":1060 * dst.shape[dim] = shape[dim] * dst.strides[dim] = strides[dim] * dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_copy_object') */ if ((__pyx_v_suboffsets != 0)) { __pyx_t_4 = (__pyx_v_suboffsets[__pyx_v_dim]); } else { __pyx_t_4 = -1L; } (__pyx_v_dst->suboffsets[__pyx_v_dim]) = __pyx_t_4; } /* "View.MemoryView":1046 * * @cname('__pyx_memoryview_slice_copy') * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<< * cdef int dim * cdef (Py_ssize_t*) shape, strides, suboffsets */ /* function exit code */ __Pyx_RefNannyFinishContext(); } /* "View.MemoryView":1063 * * @cname('__pyx_memoryview_copy_object') * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<< * "Create a new memoryview object" * cdef __Pyx_memviewslice memviewslice */ static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) { __Pyx_memviewslice __pyx_v_memviewslice; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("memoryview_copy", 0); /* "View.MemoryView":1066 * "Create a new memoryview object" * cdef __Pyx_memviewslice memviewslice * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<< * return memoryview_copy_from_slice(memview, &memviewslice) * */ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice)); /* "View.MemoryView":1067 * cdef __Pyx_memviewslice memviewslice * slice_copy(memview, &memviewslice) * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_copy_object_from_slice') */ __Pyx_XDECREF(__pyx_r); __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1067, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; /* "View.MemoryView":1063 * * @cname('__pyx_memoryview_copy_object') * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<< * "Create a new memoryview object" * cdef __Pyx_memviewslice memviewslice */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":1070 * * @cname('__pyx_memoryview_copy_object_from_slice') * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<< * """ * Create a new memoryview object from a given memoryview object and slice. */ static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) { PyObject *(*__pyx_v_to_object_func)(char *); int (*__pyx_v_to_dtype_func)(char *, PyObject *); PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations int __pyx_t_1; int __pyx_t_2; PyObject *(*__pyx_t_3)(char *); int (*__pyx_t_4)(char *, PyObject *); PyObject *__pyx_t_5 = NULL; __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0); /* "View.MemoryView":1077 * cdef int (*to_dtype_func)(char *, object) except 0 * * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< * to_object_func = (<_memoryviewslice> memview).to_object_func * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func */ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type); __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { /* "View.MemoryView":1078 * * if isinstance(memview, _memoryviewslice): * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<< * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func * else: */ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func; __pyx_v_to_object_func = __pyx_t_3; /* "View.MemoryView":1079 * if isinstance(memview, _memoryviewslice): * to_object_func = (<_memoryviewslice> memview).to_object_func * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<< * else: * to_object_func = NULL */ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func; __pyx_v_to_dtype_func = __pyx_t_4; /* "View.MemoryView":1077 * cdef int (*to_dtype_func)(char *, object) except 0 * * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<< * to_object_func = (<_memoryviewslice> memview).to_object_func * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func */ goto __pyx_L3; } /* "View.MemoryView":1081 * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func * else: * to_object_func = NULL # <<<<<<<<<<<<<< * to_dtype_func = NULL * */ /*else*/ { __pyx_v_to_object_func = NULL; /* "View.MemoryView":1082 * else: * to_object_func = NULL * to_dtype_func = NULL # <<<<<<<<<<<<<< * * return memoryview_fromslice(memviewslice[0], memview.view.ndim, */ __pyx_v_to_dtype_func = NULL; } __pyx_L3:; /* "View.MemoryView":1084 * to_dtype_func = NULL * * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<< * to_object_func, to_dtype_func, * memview.dtype_is_object) */ __Pyx_XDECREF(__pyx_r); /* "View.MemoryView":1086 * return memoryview_fromslice(memviewslice[0], memview.view.ndim, * to_object_func, to_dtype_func, * memview.dtype_is_object) # <<<<<<<<<<<<<< * * */ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 1084, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "View.MemoryView":1070 * * @cname('__pyx_memoryview_copy_object_from_slice') * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<< * """ * Create a new memoryview object from a given memoryview object and slice. */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); __Pyx_RefNannyFinishContext(); return __pyx_r; } /* "View.MemoryView":1092 * * * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<< * if arg < 0: * return -arg */ static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) { Py_ssize_t __pyx_r; int __pyx_t_1; /* "View.MemoryView":1093 * * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: * if arg < 0: # <<<<<<<<<<<<<< * return -arg * else: */ __pyx_t_1 = ((__pyx_v_arg < 0) != 0); if (__pyx_t_1) { /* "View.MemoryView":1094 * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: * if arg < 0: * return -arg # <<<<<<<<<<<<<< * else: * return arg */ __pyx_r = (-__pyx_v_arg); goto __pyx_L0; /* "View.MemoryView":1093 * * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: * if arg < 0: # <<<<<<<<<<<<<< * return -arg * else: */ } /* "View.MemoryView":1096 * return -arg * else: * return arg # <<<<<<<<<<<<<< * * @cname('__pyx_get_best_slice_order') */ /*else*/ { __pyx_r = __pyx_v_arg; goto __pyx_L0; } /* "View.MemoryView":1092 * * * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<< * if arg < 0: * return -arg */ /* function exit code */ __pyx_L0:; return __pyx_r; } /* "View.MemoryView":1099 * * @cname('__pyx_get_best_slice_order') * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<< * """ * Figure out the best memory access order for a given slice. */ static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) { int __pyx_v_i; Py_ssize_t __pyx_v_c_stride; Py_ssize_t __pyx_v_f_stride; char __pyx_r; int __pyx_t_1; int __pyx_t_2; int __pyx_t_3; /* "View.MemoryView":1104 * """ * cdef int i * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<< * cdef Py_ssize_t f_stride = 0 * */ __pyx_v_c_stride = 0; /* "View.MemoryView":1105 * cdef int i * cdef Py_ssize_t c_stride = 0 * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<< * * for i in range(ndim - 1, -1, -1): */ __pyx_v_f_stride = 0; /* "View.MemoryView":1107 * cdef Py_ssize_t f_stride = 0 * * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< * if mslice.shape[i] > 1: * c_stride = mslice.strides[i] */ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1L; __pyx_t_1-=1) { __pyx_v_i = __pyx_t_1; /* "View.MemoryView":1108 * * for i in range(ndim - 1, -1, -1): * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< * c_stride = mslice.strides[i] * break */ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0); if (__pyx_t_2) { /* "View.MemoryView":1109 * for i in range(ndim - 1, -1, -1): * if mslice.shape[i] > 1: * c_stride = mslice.strides[i] # <<<<<<<<<<<<<< * break * */ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]); /* "View.MemoryView":1110 * if mslice.shape[i] > 1: * c_stride = mslice.strides[i] * break # <<<<<<<<<<<<<< * * for i in range(ndim): */ goto __pyx_L4_break; /* "View.MemoryView":1108 * * for i in range(ndim - 1, -1, -1): * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< * c_stride = mslice.strides[i] * break */ } } __pyx_L4_break:; /* "View.MemoryView":1112 * break * * for i in range(ndim): # <<<<<<<<<<<<<< * if mslice.shape[i] > 1: * f_stride = mslice.strides[i] */ __pyx_t_1 = __pyx_v_ndim; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3; /* "View.MemoryView":1113 * * for i in range(ndim): * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< * f_stride = mslice.strides[i] * break */ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0); if (__pyx_t_2) { /* "View.MemoryView":1114 * for i in range(ndim): * if mslice.shape[i] > 1: * f_stride = mslice.strides[i] # <<<<<<<<<<<<<< * break * */ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]); /* "View.MemoryView":1115 * if mslice.shape[i] > 1: * f_stride = mslice.strides[i] * break # <<<<<<<<<<<<<< * * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): */ goto __pyx_L7_break; /* "View.MemoryView":1113 * * for i in range(ndim): * if mslice.shape[i] > 1: # <<<<<<<<<<<<<< * f_stride = mslice.strides[i] * break */ } } __pyx_L7_break:; /* "View.MemoryView":1117 * break * * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<< * return 'C' * else: */ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0); if (__pyx_t_2) { /* "View.MemoryView":1118 * * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): * return 'C' # <<<<<<<<<<<<<< * else: * return 'F' */ __pyx_r = 'C'; goto __pyx_L0; /* "View.MemoryView":1117 * break * * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<< * return 'C' * else: */ } /* "View.MemoryView":1120 * return 'C' * else: * return 'F' # <<<<<<<<<<<<<< * * @cython.cdivision(True) */ /*else*/ { __pyx_r = 'F'; goto __pyx_L0; } /* "View.MemoryView":1099 * * @cname('__pyx_get_best_slice_order') * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<< * """ * Figure out the best memory access order for a given slice. */ /* function exit code */ __pyx_L0:; return __pyx_r; } /* "View.MemoryView":1123 * * @cython.cdivision(True) * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<< * char *dst_data, Py_ssize_t *dst_strides, * Py_ssize_t *src_shape, Py_ssize_t *dst_shape, */ static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) { CYTHON_UNUSED Py_ssize_t __pyx_v_i; CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent; Py_ssize_t __pyx_v_dst_extent; Py_ssize_t __pyx_v_src_stride; Py_ssize_t __pyx_v_dst_stride; int __pyx_t_1; int __pyx_t_2; int __pyx_t_3; Py_ssize_t __pyx_t_4; Py_ssize_t __pyx_t_5; /* "View.MemoryView":1130 * * cdef Py_ssize_t i * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<< * cdef Py_ssize_t dst_extent = dst_shape[0] * cdef Py_ssize_t src_stride = src_strides[0] */ __pyx_v_src_extent = (__pyx_v_src_shape[0]); /* "View.MemoryView":1131 * cdef Py_ssize_t i * cdef Py_ssize_t src_extent = src_shape[0] * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<< * cdef Py_ssize_t src_stride = src_strides[0] * cdef Py_ssize_t dst_stride = dst_strides[0] */ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]); /* "View.MemoryView":1132 * cdef Py_ssize_t src_extent = src_shape[0] * cdef Py_ssize_t dst_extent = dst_shape[0] * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<< * cdef Py_ssize_t dst_stride = dst_strides[0] * */ __pyx_v_src_stride = (__pyx_v_src_strides[0]); /* "View.MemoryView":1133 * cdef Py_ssize_t dst_extent = dst_shape[0] * cdef Py_ssize_t src_stride = src_strides[0] * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<< * * if ndim == 1: */ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]); /* "View.MemoryView":1135 * cdef Py_ssize_t dst_stride = dst_strides[0] * * if ndim == 1: # <<<<<<<<<<<<<< * if (src_stride > 0 and dst_stride > 0 and * src_stride == itemsize == dst_stride): */ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0); if (__pyx_t_1) { /* "View.MemoryView":1136 * * if ndim == 1: * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< * src_stride == itemsize == dst_stride): * memcpy(dst_data, src_data, itemsize * dst_extent) */ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0); if (__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L5_bool_binop_done; } __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0); if (__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L5_bool_binop_done; } /* "View.MemoryView":1137 * if ndim == 1: * if (src_stride > 0 and dst_stride > 0 and * src_stride == itemsize == dst_stride): # <<<<<<<<<<<<<< * memcpy(dst_data, src_data, itemsize * dst_extent) * else: */ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize); if (__pyx_t_2) { __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride)); } __pyx_t_3 = (__pyx_t_2 != 0); __pyx_t_1 = __pyx_t_3; __pyx_L5_bool_binop_done:; /* "View.MemoryView":1136 * * if ndim == 1: * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< * src_stride == itemsize == dst_stride): * memcpy(dst_data, src_data, itemsize * dst_extent) */ if (__pyx_t_1) { /* "View.MemoryView":1138 * if (src_stride > 0 and dst_stride > 0 and * src_stride == itemsize == dst_stride): * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<< * else: * for i in range(dst_extent): */ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent)); /* "View.MemoryView":1136 * * if ndim == 1: * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<< * src_stride == itemsize == dst_stride): * memcpy(dst_data, src_data, itemsize * dst_extent) */ goto __pyx_L4; } /* "View.MemoryView":1140 * memcpy(dst_data, src_data, itemsize * dst_extent) * else: * for i in range(dst_extent): # <<<<<<<<<<<<<< * memcpy(dst_data, src_data, itemsize) * src_data += src_stride */ /*else*/ { __pyx_t_4 = __pyx_v_dst_extent; for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { __pyx_v_i = __pyx_t_5; /* "View.MemoryView":1141 * else: * for i in range(dst_extent): * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<< * src_data += src_stride * dst_data += dst_stride */ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize); /* "View.MemoryView":1142 * for i in range(dst_extent): * memcpy(dst_data, src_data, itemsize) * src_data += src_stride # <<<<<<<<<<<<<< * dst_data += dst_stride * else: */ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride); /* "View.MemoryView":1143 * memcpy(dst_data, src_data, itemsize) * src_data += src_stride * dst_data += dst_stride # <<<<<<<<<<<<<< * else: * for i in range(dst_extent): */ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride); } } __pyx_L4:; /* "View.MemoryView":1135 * cdef Py_ssize_t dst_stride = dst_strides[0] * * if ndim == 1: # <<<<<<<<<<<<<< * if (src_stride > 0 and dst_stride > 0 and * src_stride == itemsize == dst_stride): */ goto __pyx_L3; } /* "View.MemoryView":1145 * dst_data += dst_stride * else: * for i in range(dst_extent): # <<<<<<<<<<<<<< * _copy_strided_to_strided(src_data, src_strides + 1, * dst_data, dst_strides + 1, */ /*else*/ { __pyx_t_4 = __pyx_v_dst_extent; for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { __pyx_v_i = __pyx_t_5; /* "View.MemoryView":1146 * else: * for i in range(dst_extent): * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<< * dst_data, dst_strides + 1, * src_shape + 1, dst_shape + 1, */ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize); /* "View.MemoryView":1150 * src_shape + 1, dst_shape + 1, * ndim - 1, itemsize) * src_data += src_stride # <<<<<<<<<<<<<< * dst_data += dst_stride * */ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride); /* "View.MemoryView":1151 * ndim - 1, itemsize) * src_data += src_stride * dst_data += dst_stride # <<<<<<<<<<<<<< * * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, */ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride); } } __pyx_L3:; /* "View.MemoryView":1123 * * @cython.cdivision(True) * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<< * char *dst_data, Py_ssize_t *dst_strides, * Py_ssize_t *src_shape, Py_ssize_t *dst_shape, */ /* function exit code */ } /* "View.MemoryView":1153 * dst_data += dst_stride * * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< * __Pyx_memviewslice *dst, * int ndim, size_t itemsize) nogil: */ static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) { /* "View.MemoryView":1156 * __Pyx_memviewslice *dst, * int ndim, size_t itemsize) nogil: * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<< * src.shape, dst.shape, ndim, itemsize) * */ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize); /* "View.MemoryView":1153 * dst_data += dst_stride * * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< * __Pyx_memviewslice *dst, * int ndim, size_t itemsize) nogil: */ /* function exit code */ } /* "View.MemoryView":1160 * * @cname('__pyx_memoryview_slice_get_size') * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<< * "Return the size of the memory occupied by the slice in number of bytes" * cdef int i */ static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) { int __pyx_v_i; Py_ssize_t __pyx_v_size; Py_ssize_t __pyx_r; Py_ssize_t __pyx_t_1; int __pyx_t_2; int __pyx_t_3; /* "View.MemoryView":1163 * "Return the size of the memory occupied by the slice in number of bytes" * cdef int i * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<< * * for i in range(ndim): */ __pyx_t_1 = __pyx_v_src->memview->view.itemsize; __pyx_v_size = __pyx_t_1; /* "View.MemoryView":1165 * cdef Py_ssize_t size = src.memview.view.itemsize * * for i in range(ndim): # <<<<<<<<<<<<<< * size *= src.shape[i] * */ __pyx_t_2 = __pyx_v_ndim; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3; /* "View.MemoryView":1166 * * for i in range(ndim): * size *= src.shape[i] # <<<<<<<<<<<<<< * * return size */ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i])); } /* "View.MemoryView":1168 * size *= src.shape[i] * * return size # <<<<<<<<<<<<<< * * @cname('__pyx_fill_contig_strides_array') */ __pyx_r = __pyx_v_size; goto __pyx_L0; /* "View.MemoryView":1160 * * @cname('__pyx_memoryview_slice_get_size') * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<< * "Return the size of the memory occupied by the slice in number of bytes" * cdef int i */ /* function exit code */ __pyx_L0:; return __pyx_r; } /* "View.MemoryView":1171 * * @cname('__pyx_fill_contig_strides_array') * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<< * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, * int ndim, char order) nogil: */ static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) { int __pyx_v_idx; Py_ssize_t __pyx_r; int __pyx_t_1; int __pyx_t_2; int __pyx_t_3; /* "View.MemoryView":1180 * cdef int idx * * if order == 'F': # <<<<<<<<<<<<<< * for idx in range(ndim): * strides[idx] = stride */ __pyx_t_1 = ((__pyx_v_order == 'F') != 0); if (__pyx_t_1) { /* "View.MemoryView":1181 * * if order == 'F': * for idx in range(ndim): # <<<<<<<<<<<<<< * strides[idx] = stride * stride = stride * shape[idx] */ __pyx_t_2 = __pyx_v_ndim; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_idx = __pyx_t_3; /* "View.MemoryView":1182 * if order == 'F': * for idx in range(ndim): * strides[idx] = stride # <<<<<<<<<<<<<< * stride = stride * shape[idx] * else: */ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride; /* "View.MemoryView":1183 * for idx in range(ndim): * strides[idx] = stride * stride = stride * shape[idx] # <<<<<<<<<<<<<< * else: * for idx in range(ndim - 1, -1, -1): */ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx])); } /* "View.MemoryView":1180 * cdef int idx * * if order == 'F': # <<<<<<<<<<<<<< * for idx in range(ndim): * strides[idx] = stride */ goto __pyx_L3; } /* "View.MemoryView":1185 * stride = stride * shape[idx] * else: * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< * strides[idx] = stride * stride = stride * shape[idx] */ /*else*/ { for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1L; __pyx_t_2-=1) { __pyx_v_idx = __pyx_t_2; /* "View.MemoryView":1186 * else: * for idx in range(ndim - 1, -1, -1): * strides[idx] = stride # <<<<<<<<<<<<<< * stride = stride * shape[idx] * */ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride; /* "View.MemoryView":1187 * for idx in range(ndim - 1, -1, -1): * strides[idx] = stride * stride = stride * shape[idx] # <<<<<<<<<<<<<< * * return stride */ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx])); } } __pyx_L3:; /* "View.MemoryView":1189 * stride = stride * shape[idx] * * return stride # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_copy_data_to_temp') */ __pyx_r = __pyx_v_stride; goto __pyx_L0; /* "View.MemoryView":1171 * * @cname('__pyx_fill_contig_strides_array') * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<< * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, * int ndim, char order) nogil: */ /* function exit code */ __pyx_L0:; return __pyx_r; } /* "View.MemoryView":1192 * * @cname('__pyx_memoryview_copy_data_to_temp') * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< * __Pyx_memviewslice *tmpslice, * char order, */ static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) { int __pyx_v_i; void *__pyx_v_result; size_t __pyx_v_itemsize; size_t __pyx_v_size; void *__pyx_r; Py_ssize_t __pyx_t_1; int __pyx_t_2; int __pyx_t_3; struct __pyx_memoryview_obj *__pyx_t_4; int __pyx_t_5; /* "View.MemoryView":1203 * cdef void *result * * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<< * cdef size_t size = slice_get_size(src, ndim) * */ __pyx_t_1 = __pyx_v_src->memview->view.itemsize; __pyx_v_itemsize = __pyx_t_1; /* "View.MemoryView":1204 * * cdef size_t itemsize = src.memview.view.itemsize * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<< * * result = malloc(size) */ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim); /* "View.MemoryView":1206 * cdef size_t size = slice_get_size(src, ndim) * * result = malloc(size) # <<<<<<<<<<<<<< * if not result: * _err(MemoryError, NULL) */ __pyx_v_result = malloc(__pyx_v_size); /* "View.MemoryView":1207 * * result = malloc(size) * if not result: # <<<<<<<<<<<<<< * _err(MemoryError, NULL) * */ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0); if (__pyx_t_2) { /* "View.MemoryView":1208 * result = malloc(size) * if not result: * _err(MemoryError, NULL) # <<<<<<<<<<<<<< * * */ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) __PYX_ERR(2, 1208, __pyx_L1_error) /* "View.MemoryView":1207 * * result = malloc(size) * if not result: # <<<<<<<<<<<<<< * _err(MemoryError, NULL) * */ } /* "View.MemoryView":1211 * * * tmpslice.data = result # <<<<<<<<<<<<<< * tmpslice.memview = src.memview * for i in range(ndim): */ __pyx_v_tmpslice->data = ((char *)__pyx_v_result); /* "View.MemoryView":1212 * * tmpslice.data = result * tmpslice.memview = src.memview # <<<<<<<<<<<<<< * for i in range(ndim): * tmpslice.shape[i] = src.shape[i] */ __pyx_t_4 = __pyx_v_src->memview; __pyx_v_tmpslice->memview = __pyx_t_4; /* "View.MemoryView":1213 * tmpslice.data = result * tmpslice.memview = src.memview * for i in range(ndim): # <<<<<<<<<<<<<< * tmpslice.shape[i] = src.shape[i] * tmpslice.suboffsets[i] = -1 */ __pyx_t_3 = __pyx_v_ndim; for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) { __pyx_v_i = __pyx_t_5; /* "View.MemoryView":1214 * tmpslice.memview = src.memview * for i in range(ndim): * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<< * tmpslice.suboffsets[i] = -1 * */ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]); /* "View.MemoryView":1215 * for i in range(ndim): * tmpslice.shape[i] = src.shape[i] * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<< * * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, */ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1L; } /* "View.MemoryView":1217 * tmpslice.suboffsets[i] = -1 * * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<< * ndim, order) * */ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order); /* "View.MemoryView":1221 * * * for i in range(ndim): # <<<<<<<<<<<<<< * if tmpslice.shape[i] == 1: * tmpslice.strides[i] = 0 */ __pyx_t_3 = __pyx_v_ndim; for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) { __pyx_v_i = __pyx_t_5; /* "View.MemoryView":1222 * * for i in range(ndim): * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<< * tmpslice.strides[i] = 0 * */ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0); if (__pyx_t_2) { /* "View.MemoryView":1223 * for i in range(ndim): * if tmpslice.shape[i] == 1: * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<< * * if slice_is_contig(src[0], order, ndim): */ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0; /* "View.MemoryView":1222 * * for i in range(ndim): * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<< * tmpslice.strides[i] = 0 * */ } } /* "View.MemoryView":1225 * tmpslice.strides[i] = 0 * * if slice_is_contig(src[0], order, ndim): # <<<<<<<<<<<<<< * memcpy(result, src.data, size) * else: */ __pyx_t_2 = (__pyx_memviewslice_is_contig((__pyx_v_src[0]), __pyx_v_order, __pyx_v_ndim) != 0); if (__pyx_t_2) { /* "View.MemoryView":1226 * * if slice_is_contig(src[0], order, ndim): * memcpy(result, src.data, size) # <<<<<<<<<<<<<< * else: * copy_strided_to_strided(src, tmpslice, ndim, itemsize) */ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size); /* "View.MemoryView":1225 * tmpslice.strides[i] = 0 * * if slice_is_contig(src[0], order, ndim): # <<<<<<<<<<<<<< * memcpy(result, src.data, size) * else: */ goto __pyx_L9; } /* "View.MemoryView":1228 * memcpy(result, src.data, size) * else: * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<< * * return result */ /*else*/ { copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize); } __pyx_L9:; /* "View.MemoryView":1230 * copy_strided_to_strided(src, tmpslice, ndim, itemsize) * * return result # <<<<<<<<<<<<<< * * */ __pyx_r = __pyx_v_result; goto __pyx_L0; /* "View.MemoryView":1192 * * @cname('__pyx_memoryview_copy_data_to_temp') * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<< * __Pyx_memviewslice *tmpslice, * char order, */ /* function exit code */ __pyx_L1_error:; { #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); #endif __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename); #ifdef WITH_THREAD PyGILState_Release(__pyx_gilstate_save); #endif } __pyx_r = NULL; __pyx_L0:; return __pyx_r; } /* "View.MemoryView":1235 * * @cname('__pyx_memoryview_err_extents') * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<< * Py_ssize_t extent2) except -1 with gil: * raise ValueError("got differing extents in dimension %d (got %d and %d)" % */ static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); #endif __Pyx_RefNannySetupContext("_err_extents", 0); /* "View.MemoryView":1238 * Py_ssize_t extent2) except -1 with gil: * raise ValueError("got differing extents in dimension %d (got %d and %d)" % * (i, extent1, extent2)) # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_err_dim') */ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1238, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1238, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1238, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 1238, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3); __pyx_t_1 = 0; __pyx_t_2 = 0; __pyx_t_3 = 0; /* "View.MemoryView":1237 * cdef int _err_extents(int i, Py_ssize_t extent1, * Py_ssize_t extent2) except -1 with gil: * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<< * (i, extent1, extent2)) * */ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1237, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 1237, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1237, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_Raise(__pyx_t_3, 0, 0, 0); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(2, 1237, __pyx_L1_error) /* "View.MemoryView":1235 * * @cname('__pyx_memoryview_err_extents') * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<< * Py_ssize_t extent2) except -1 with gil: * raise ValueError("got differing extents in dimension %d (got %d and %d)" % */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __Pyx_RefNannyFinishContext(); #ifdef WITH_THREAD PyGILState_Release(__pyx_gilstate_save); #endif return __pyx_r; } /* "View.MemoryView":1241 * * @cname('__pyx_memoryview_err_dim') * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<< * raise error(msg.decode('ascii') % dim) * */ static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) { int __pyx_r; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); #endif __Pyx_RefNannySetupContext("_err_dim", 0); __Pyx_INCREF(__pyx_v_error); /* "View.MemoryView":1242 * @cname('__pyx_memoryview_err_dim') * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_err') */ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1242, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1242, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(2, 1242, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_INCREF(__pyx_v_error); __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) { __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); if (likely(__pyx_t_2)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); __Pyx_INCREF(__pyx_t_2); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_3, function); } } if (!__pyx_t_2) { __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1242, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_GOTREF(__pyx_t_1); } else { __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(2, 1242, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __pyx_t_2 = NULL; __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4); __pyx_t_4 = 0; __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 1242, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; } __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_Raise(__pyx_t_1, 0, 0, 0); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __PYX_ERR(2, 1242, __pyx_L1_error) /* "View.MemoryView":1241 * * @cname('__pyx_memoryview_err_dim') * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<< * raise error(msg.decode('ascii') % dim) * */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __Pyx_XDECREF(__pyx_v_error); __Pyx_RefNannyFinishContext(); #ifdef WITH_THREAD PyGILState_Release(__pyx_gilstate_save); #endif return __pyx_r; } /* "View.MemoryView":1245 * * @cname('__pyx_memoryview_err') * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<< * if msg != NULL: * raise error(msg.decode('ascii')) */ static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) { int __pyx_r; __Pyx_RefNannyDeclarations int __pyx_t_1; PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); #endif __Pyx_RefNannySetupContext("_err", 0); __Pyx_INCREF(__pyx_v_error); /* "View.MemoryView":1246 * @cname('__pyx_memoryview_err') * cdef int _err(object error, char *msg) except -1 with gil: * if msg != NULL: # <<<<<<<<<<<<<< * raise error(msg.decode('ascii')) * else: */ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0); if (__pyx_t_1) { /* "View.MemoryView":1247 * cdef int _err(object error, char *msg) except -1 with gil: * if msg != NULL: * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<< * else: * raise error */ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) __PYX_ERR(2, 1247, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_INCREF(__pyx_v_error); __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL; if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) { __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); if (likely(__pyx_t_5)) { PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); __Pyx_INCREF(__pyx_t_5); __Pyx_INCREF(function); __Pyx_DECREF_SET(__pyx_t_4, function); } } if (!__pyx_t_5) { __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1247, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_GOTREF(__pyx_t_2); } else { __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(2, 1247, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL; __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3); __pyx_t_3 = 0; __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(2, 1247, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; } __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_Raise(__pyx_t_2, 0, 0, 0); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __PYX_ERR(2, 1247, __pyx_L1_error) /* "View.MemoryView":1246 * @cname('__pyx_memoryview_err') * cdef int _err(object error, char *msg) except -1 with gil: * if msg != NULL: # <<<<<<<<<<<<<< * raise error(msg.decode('ascii')) * else: */ } /* "View.MemoryView":1249 * raise error(msg.decode('ascii')) * else: * raise error # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_copy_contents') */ /*else*/ { __Pyx_Raise(__pyx_v_error, 0, 0, 0); __PYX_ERR(2, 1249, __pyx_L1_error) } /* "View.MemoryView":1245 * * @cname('__pyx_memoryview_err') * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<< * if msg != NULL: * raise error(msg.decode('ascii')) */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = -1; __Pyx_XDECREF(__pyx_v_error); __Pyx_RefNannyFinishContext(); #ifdef WITH_THREAD PyGILState_Release(__pyx_gilstate_save); #endif return __pyx_r; } /* "View.MemoryView":1252 * * @cname('__pyx_memoryview_copy_contents') * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<< * __Pyx_memviewslice dst, * int src_ndim, int dst_ndim, */ static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) { void *__pyx_v_tmpdata; size_t __pyx_v_itemsize; int __pyx_v_i; char __pyx_v_order; int __pyx_v_broadcasting; int __pyx_v_direct_copy; __Pyx_memviewslice __pyx_v_tmp; int __pyx_v_ndim; int __pyx_r; Py_ssize_t __pyx_t_1; int __pyx_t_2; int __pyx_t_3; int __pyx_t_4; int __pyx_t_5; void *__pyx_t_6; int __pyx_t_7; /* "View.MemoryView":1260 * Check for overlapping memory and verify the shapes. * """ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<< * cdef size_t itemsize = src.memview.view.itemsize * cdef int i */ __pyx_v_tmpdata = NULL; /* "View.MemoryView":1261 * """ * cdef void *tmpdata = NULL * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<< * cdef int i * cdef char order = get_best_order(&src, src_ndim) */ __pyx_t_1 = __pyx_v_src.memview->view.itemsize; __pyx_v_itemsize = __pyx_t_1; /* "View.MemoryView":1263 * cdef size_t itemsize = src.memview.view.itemsize * cdef int i * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<< * cdef bint broadcasting = False * cdef bint direct_copy = False */ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim); /* "View.MemoryView":1264 * cdef int i * cdef char order = get_best_order(&src, src_ndim) * cdef bint broadcasting = False # <<<<<<<<<<<<<< * cdef bint direct_copy = False * cdef __Pyx_memviewslice tmp */ __pyx_v_broadcasting = 0; /* "View.MemoryView":1265 * cdef char order = get_best_order(&src, src_ndim) * cdef bint broadcasting = False * cdef bint direct_copy = False # <<<<<<<<<<<<<< * cdef __Pyx_memviewslice tmp * */ __pyx_v_direct_copy = 0; /* "View.MemoryView":1268 * cdef __Pyx_memviewslice tmp * * if src_ndim < dst_ndim: # <<<<<<<<<<<<<< * broadcast_leading(&src, src_ndim, dst_ndim) * elif dst_ndim < src_ndim: */ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0); if (__pyx_t_2) { /* "View.MemoryView":1269 * * if src_ndim < dst_ndim: * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<< * elif dst_ndim < src_ndim: * broadcast_leading(&dst, dst_ndim, src_ndim) */ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim); /* "View.MemoryView":1268 * cdef __Pyx_memviewslice tmp * * if src_ndim < dst_ndim: # <<<<<<<<<<<<<< * broadcast_leading(&src, src_ndim, dst_ndim) * elif dst_ndim < src_ndim: */ goto __pyx_L3; } /* "View.MemoryView":1270 * if src_ndim < dst_ndim: * broadcast_leading(&src, src_ndim, dst_ndim) * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<< * broadcast_leading(&dst, dst_ndim, src_ndim) * */ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0); if (__pyx_t_2) { /* "View.MemoryView":1271 * broadcast_leading(&src, src_ndim, dst_ndim) * elif dst_ndim < src_ndim: * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<< * * cdef int ndim = max(src_ndim, dst_ndim) */ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim); /* "View.MemoryView":1270 * if src_ndim < dst_ndim: * broadcast_leading(&src, src_ndim, dst_ndim) * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<< * broadcast_leading(&dst, dst_ndim, src_ndim) * */ } __pyx_L3:; /* "View.MemoryView":1273 * broadcast_leading(&dst, dst_ndim, src_ndim) * * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<< * * for i in range(ndim): */ __pyx_t_3 = __pyx_v_dst_ndim; __pyx_t_4 = __pyx_v_src_ndim; if (((__pyx_t_3 > __pyx_t_4) != 0)) { __pyx_t_5 = __pyx_t_3; } else { __pyx_t_5 = __pyx_t_4; } __pyx_v_ndim = __pyx_t_5; /* "View.MemoryView":1275 * cdef int ndim = max(src_ndim, dst_ndim) * * for i in range(ndim): # <<<<<<<<<<<<<< * if src.shape[i] != dst.shape[i]: * if src.shape[i] == 1: */ __pyx_t_5 = __pyx_v_ndim; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3; /* "View.MemoryView":1276 * * for i in range(ndim): * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<< * if src.shape[i] == 1: * broadcasting = True */ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0); if (__pyx_t_2) { /* "View.MemoryView":1277 * for i in range(ndim): * if src.shape[i] != dst.shape[i]: * if src.shape[i] == 1: # <<<<<<<<<<<<<< * broadcasting = True * src.strides[i] = 0 */ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0); if (__pyx_t_2) { /* "View.MemoryView":1278 * if src.shape[i] != dst.shape[i]: * if src.shape[i] == 1: * broadcasting = True # <<<<<<<<<<<<<< * src.strides[i] = 0 * else: */ __pyx_v_broadcasting = 1; /* "View.MemoryView":1279 * if src.shape[i] == 1: * broadcasting = True * src.strides[i] = 0 # <<<<<<<<<<<<<< * else: * _err_extents(i, dst.shape[i], src.shape[i]) */ (__pyx_v_src.strides[__pyx_v_i]) = 0; /* "View.MemoryView":1277 * for i in range(ndim): * if src.shape[i] != dst.shape[i]: * if src.shape[i] == 1: # <<<<<<<<<<<<<< * broadcasting = True * src.strides[i] = 0 */ goto __pyx_L7; } /* "View.MemoryView":1281 * src.strides[i] = 0 * else: * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<< * * if src.suboffsets[i] >= 0: */ /*else*/ { __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) __PYX_ERR(2, 1281, __pyx_L1_error) } __pyx_L7:; /* "View.MemoryView":1276 * * for i in range(ndim): * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<< * if src.shape[i] == 1: * broadcasting = True */ } /* "View.MemoryView":1283 * _err_extents(i, dst.shape[i], src.shape[i]) * * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<< * _err_dim(ValueError, "Dimension %d is not direct", i) * */ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0); if (__pyx_t_2) { /* "View.MemoryView":1284 * * if src.suboffsets[i] >= 0: * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<< * * if slices_overlap(&src, &dst, ndim, itemsize): */ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, ((char *)"Dimension %d is not direct"), __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) __PYX_ERR(2, 1284, __pyx_L1_error) /* "View.MemoryView":1283 * _err_extents(i, dst.shape[i], src.shape[i]) * * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<< * _err_dim(ValueError, "Dimension %d is not direct", i) * */ } } /* "View.MemoryView":1286 * _err_dim(ValueError, "Dimension %d is not direct", i) * * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<< * * if not slice_is_contig(src, order, ndim): */ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0); if (__pyx_t_2) { /* "View.MemoryView":1288 * if slices_overlap(&src, &dst, ndim, itemsize): * * if not slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<< * order = get_best_order(&dst, ndim) * */ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0)) != 0); if (__pyx_t_2) { /* "View.MemoryView":1289 * * if not slice_is_contig(src, order, ndim): * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<< * * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) */ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim); /* "View.MemoryView":1288 * if slices_overlap(&src, &dst, ndim, itemsize): * * if not slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<< * order = get_best_order(&dst, ndim) * */ } /* "View.MemoryView":1291 * order = get_best_order(&dst, ndim) * * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<< * src = tmp * */ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) __PYX_ERR(2, 1291, __pyx_L1_error) __pyx_v_tmpdata = __pyx_t_6; /* "View.MemoryView":1292 * * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) * src = tmp # <<<<<<<<<<<<<< * * if not broadcasting: */ __pyx_v_src = __pyx_v_tmp; /* "View.MemoryView":1286 * _err_dim(ValueError, "Dimension %d is not direct", i) * * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<< * * if not slice_is_contig(src, order, ndim): */ } /* "View.MemoryView":1294 * src = tmp * * if not broadcasting: # <<<<<<<<<<<<<< * * */ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0); if (__pyx_t_2) { /* "View.MemoryView":1297 * * * if slice_is_contig(src, 'C', ndim): # <<<<<<<<<<<<<< * direct_copy = slice_is_contig(dst, 'C', ndim) * elif slice_is_contig(src, 'F', ndim): */ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, 'C', __pyx_v_ndim) != 0); if (__pyx_t_2) { /* "View.MemoryView":1298 * * if slice_is_contig(src, 'C', ndim): * direct_copy = slice_is_contig(dst, 'C', ndim) # <<<<<<<<<<<<<< * elif slice_is_contig(src, 'F', ndim): * direct_copy = slice_is_contig(dst, 'F', ndim) */ __pyx_v_direct_copy = __pyx_memviewslice_is_contig(__pyx_v_dst, 'C', __pyx_v_ndim); /* "View.MemoryView":1297 * * * if slice_is_contig(src, 'C', ndim): # <<<<<<<<<<<<<< * direct_copy = slice_is_contig(dst, 'C', ndim) * elif slice_is_contig(src, 'F', ndim): */ goto __pyx_L12; } /* "View.MemoryView":1299 * if slice_is_contig(src, 'C', ndim): * direct_copy = slice_is_contig(dst, 'C', ndim) * elif slice_is_contig(src, 'F', ndim): # <<<<<<<<<<<<<< * direct_copy = slice_is_contig(dst, 'F', ndim) * */ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, 'F', __pyx_v_ndim) != 0); if (__pyx_t_2) { /* "View.MemoryView":1300 * direct_copy = slice_is_contig(dst, 'C', ndim) * elif slice_is_contig(src, 'F', ndim): * direct_copy = slice_is_contig(dst, 'F', ndim) # <<<<<<<<<<<<<< * * if direct_copy: */ __pyx_v_direct_copy = __pyx_memviewslice_is_contig(__pyx_v_dst, 'F', __pyx_v_ndim); /* "View.MemoryView":1299 * if slice_is_contig(src, 'C', ndim): * direct_copy = slice_is_contig(dst, 'C', ndim) * elif slice_is_contig(src, 'F', ndim): # <<<<<<<<<<<<<< * direct_copy = slice_is_contig(dst, 'F', ndim) * */ } __pyx_L12:; /* "View.MemoryView":1302 * direct_copy = slice_is_contig(dst, 'F', ndim) * * if direct_copy: # <<<<<<<<<<<<<< * * refcount_copying(&dst, dtype_is_object, ndim, False) */ __pyx_t_2 = (__pyx_v_direct_copy != 0); if (__pyx_t_2) { /* "View.MemoryView":1304 * if direct_copy: * * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<< * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) * refcount_copying(&dst, dtype_is_object, ndim, True) */ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0); /* "View.MemoryView":1305 * * refcount_copying(&dst, dtype_is_object, ndim, False) * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<< * refcount_copying(&dst, dtype_is_object, ndim, True) * free(tmpdata) */ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim)); /* "View.MemoryView":1306 * refcount_copying(&dst, dtype_is_object, ndim, False) * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<< * free(tmpdata) * return 0 */ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1); /* "View.MemoryView":1307 * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) * refcount_copying(&dst, dtype_is_object, ndim, True) * free(tmpdata) # <<<<<<<<<<<<<< * return 0 * */ free(__pyx_v_tmpdata); /* "View.MemoryView":1308 * refcount_copying(&dst, dtype_is_object, ndim, True) * free(tmpdata) * return 0 # <<<<<<<<<<<<<< * * if order == 'F' == get_best_order(&dst, ndim): */ __pyx_r = 0; goto __pyx_L0; /* "View.MemoryView":1302 * direct_copy = slice_is_contig(dst, 'F', ndim) * * if direct_copy: # <<<<<<<<<<<<<< * * refcount_copying(&dst, dtype_is_object, ndim, False) */ } /* "View.MemoryView":1294 * src = tmp * * if not broadcasting: # <<<<<<<<<<<<<< * * */ } /* "View.MemoryView":1310 * return 0 * * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<< * * */ __pyx_t_2 = (__pyx_v_order == 'F'); if (__pyx_t_2) { __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim)); } __pyx_t_7 = (__pyx_t_2 != 0); if (__pyx_t_7) { /* "View.MemoryView":1313 * * * transpose_memslice(&src) # <<<<<<<<<<<<<< * transpose_memslice(&dst) * */ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) __PYX_ERR(2, 1313, __pyx_L1_error) /* "View.MemoryView":1314 * * transpose_memslice(&src) * transpose_memslice(&dst) # <<<<<<<<<<<<<< * * refcount_copying(&dst, dtype_is_object, ndim, False) */ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) __PYX_ERR(2, 1314, __pyx_L1_error) /* "View.MemoryView":1310 * return 0 * * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<< * * */ } /* "View.MemoryView":1316 * transpose_memslice(&dst) * * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<< * copy_strided_to_strided(&src, &dst, ndim, itemsize) * refcount_copying(&dst, dtype_is_object, ndim, True) */ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0); /* "View.MemoryView":1317 * * refcount_copying(&dst, dtype_is_object, ndim, False) * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<< * refcount_copying(&dst, dtype_is_object, ndim, True) * */ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize); /* "View.MemoryView":1318 * refcount_copying(&dst, dtype_is_object, ndim, False) * copy_strided_to_strided(&src, &dst, ndim, itemsize) * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<< * * free(tmpdata) */ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1); /* "View.MemoryView":1320 * refcount_copying(&dst, dtype_is_object, ndim, True) * * free(tmpdata) # <<<<<<<<<<<<<< * return 0 * */ free(__pyx_v_tmpdata); /* "View.MemoryView":1321 * * free(tmpdata) * return 0 # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_broadcast_leading') */ __pyx_r = 0; goto __pyx_L0; /* "View.MemoryView":1252 * * @cname('__pyx_memoryview_copy_contents') * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<< * __Pyx_memviewslice dst, * int src_ndim, int dst_ndim, */ /* function exit code */ __pyx_L1_error:; { #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); #endif __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename); #ifdef WITH_THREAD PyGILState_Release(__pyx_gilstate_save); #endif } __pyx_r = -1; __pyx_L0:; return __pyx_r; } /* "View.MemoryView":1324 * * @cname('__pyx_memoryview_broadcast_leading') * cdef void broadcast_leading(__Pyx_memviewslice *mslice, # <<<<<<<<<<<<<< * int ndim, * int ndim_other) nogil: */ static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim, int __pyx_v_ndim_other) { int __pyx_v_i; int __pyx_v_offset; int __pyx_t_1; int __pyx_t_2; /* "View.MemoryView":1328 * int ndim_other) nogil: * cdef int i * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<< * * for i in range(ndim - 1, -1, -1): */ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim); /* "View.MemoryView":1330 * cdef int offset = ndim_other - ndim * * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<< * mslice.shape[i + offset] = mslice.shape[i] * mslice.strides[i + offset] = mslice.strides[i] */ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1L; __pyx_t_1-=1) { __pyx_v_i = __pyx_t_1; /* "View.MemoryView":1331 * * for i in range(ndim - 1, -1, -1): * mslice.shape[i + offset] = mslice.shape[i] # <<<<<<<<<<<<<< * mslice.strides[i + offset] = mslice.strides[i] * mslice.suboffsets[i + offset] = mslice.suboffsets[i] */ (__pyx_v_mslice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->shape[__pyx_v_i]); /* "View.MemoryView":1332 * for i in range(ndim - 1, -1, -1): * mslice.shape[i + offset] = mslice.shape[i] * mslice.strides[i + offset] = mslice.strides[i] # <<<<<<<<<<<<<< * mslice.suboffsets[i + offset] = mslice.suboffsets[i] * */ (__pyx_v_mslice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->strides[__pyx_v_i]); /* "View.MemoryView":1333 * mslice.shape[i + offset] = mslice.shape[i] * mslice.strides[i + offset] = mslice.strides[i] * mslice.suboffsets[i + offset] = mslice.suboffsets[i] # <<<<<<<<<<<<<< * * for i in range(offset): */ (__pyx_v_mslice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_mslice->suboffsets[__pyx_v_i]); } /* "View.MemoryView":1335 * mslice.suboffsets[i + offset] = mslice.suboffsets[i] * * for i in range(offset): # <<<<<<<<<<<<<< * mslice.shape[i] = 1 * mslice.strides[i] = mslice.strides[0] */ __pyx_t_1 = __pyx_v_offset; for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { __pyx_v_i = __pyx_t_2; /* "View.MemoryView":1336 * * for i in range(offset): * mslice.shape[i] = 1 # <<<<<<<<<<<<<< * mslice.strides[i] = mslice.strides[0] * mslice.suboffsets[i] = -1 */ (__pyx_v_mslice->shape[__pyx_v_i]) = 1; /* "View.MemoryView":1337 * for i in range(offset): * mslice.shape[i] = 1 * mslice.strides[i] = mslice.strides[0] # <<<<<<<<<<<<<< * mslice.suboffsets[i] = -1 * */ (__pyx_v_mslice->strides[__pyx_v_i]) = (__pyx_v_mslice->strides[0]); /* "View.MemoryView":1338 * mslice.shape[i] = 1 * mslice.strides[i] = mslice.strides[0] * mslice.suboffsets[i] = -1 # <<<<<<<<<<<<<< * * */ (__pyx_v_mslice->suboffsets[__pyx_v_i]) = -1L; } /* "View.MemoryView":1324 * * @cname('__pyx_memoryview_broadcast_leading') * cdef void broadcast_leading(__Pyx_memviewslice *mslice, # <<<<<<<<<<<<<< * int ndim, * int ndim_other) nogil: */ /* function exit code */ } /* "View.MemoryView":1346 * * @cname('__pyx_memoryview_refcount_copying') * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<< * int ndim, bint inc) nogil: * */ static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) { int __pyx_t_1; /* "View.MemoryView":1350 * * * if dtype_is_object: # <<<<<<<<<<<<<< * refcount_objects_in_slice_with_gil(dst.data, dst.shape, * dst.strides, ndim, inc) */ __pyx_t_1 = (__pyx_v_dtype_is_object != 0); if (__pyx_t_1) { /* "View.MemoryView":1351 * * if dtype_is_object: * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<< * dst.strides, ndim, inc) * */ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc); /* "View.MemoryView":1350 * * * if dtype_is_object: # <<<<<<<<<<<<<< * refcount_objects_in_slice_with_gil(dst.data, dst.shape, * dst.strides, ndim, inc) */ } /* "View.MemoryView":1346 * * @cname('__pyx_memoryview_refcount_copying') * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<< * int ndim, bint inc) nogil: * */ /* function exit code */ } /* "View.MemoryView":1355 * * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< * Py_ssize_t *strides, int ndim, * bint inc) with gil: */ static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) { __Pyx_RefNannyDeclarations #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); #endif __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0); /* "View.MemoryView":1358 * Py_ssize_t *strides, int ndim, * bint inc) with gil: * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<< * * @cname('__pyx_memoryview_refcount_objects_in_slice') */ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc); /* "View.MemoryView":1355 * * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< * Py_ssize_t *strides, int ndim, * bint inc) with gil: */ /* function exit code */ __Pyx_RefNannyFinishContext(); #ifdef WITH_THREAD PyGILState_Release(__pyx_gilstate_save); #endif } /* "View.MemoryView":1361 * * @cname('__pyx_memoryview_refcount_objects_in_slice') * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< * Py_ssize_t *strides, int ndim, bint inc): * cdef Py_ssize_t i */ static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) { CYTHON_UNUSED Py_ssize_t __pyx_v_i; __Pyx_RefNannyDeclarations Py_ssize_t __pyx_t_1; Py_ssize_t __pyx_t_2; int __pyx_t_3; __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0); /* "View.MemoryView":1365 * cdef Py_ssize_t i * * for i in range(shape[0]): # <<<<<<<<<<<<<< * if ndim == 1: * if inc: */ __pyx_t_1 = (__pyx_v_shape[0]); for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) { __pyx_v_i = __pyx_t_2; /* "View.MemoryView":1366 * * for i in range(shape[0]): * if ndim == 1: # <<<<<<<<<<<<<< * if inc: * Py_INCREF(( data)[0]) */ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0); if (__pyx_t_3) { /* "View.MemoryView":1367 * for i in range(shape[0]): * if ndim == 1: * if inc: # <<<<<<<<<<<<<< * Py_INCREF(( data)[0]) * else: */ __pyx_t_3 = (__pyx_v_inc != 0); if (__pyx_t_3) { /* "View.MemoryView":1368 * if ndim == 1: * if inc: * Py_INCREF(( data)[0]) # <<<<<<<<<<<<<< * else: * Py_DECREF(( data)[0]) */ Py_INCREF((((PyObject **)__pyx_v_data)[0])); /* "View.MemoryView":1367 * for i in range(shape[0]): * if ndim == 1: * if inc: # <<<<<<<<<<<<<< * Py_INCREF(( data)[0]) * else: */ goto __pyx_L6; } /* "View.MemoryView":1370 * Py_INCREF(( data)[0]) * else: * Py_DECREF(( data)[0]) # <<<<<<<<<<<<<< * else: * refcount_objects_in_slice(data, shape + 1, strides + 1, */ /*else*/ { Py_DECREF((((PyObject **)__pyx_v_data)[0])); } __pyx_L6:; /* "View.MemoryView":1366 * * for i in range(shape[0]): * if ndim == 1: # <<<<<<<<<<<<<< * if inc: * Py_INCREF(( data)[0]) */ goto __pyx_L5; } /* "View.MemoryView":1372 * Py_DECREF(( data)[0]) * else: * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<< * ndim - 1, inc) * */ /*else*/ { /* "View.MemoryView":1373 * else: * refcount_objects_in_slice(data, shape + 1, strides + 1, * ndim - 1, inc) # <<<<<<<<<<<<<< * * data += strides[0] */ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc); } __pyx_L5:; /* "View.MemoryView":1375 * ndim - 1, inc) * * data += strides[0] # <<<<<<<<<<<<<< * * */ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0])); } /* "View.MemoryView":1361 * * @cname('__pyx_memoryview_refcount_objects_in_slice') * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< * Py_ssize_t *strides, int ndim, bint inc): * cdef Py_ssize_t i */ /* function exit code */ __Pyx_RefNannyFinishContext(); } /* "View.MemoryView":1381 * * @cname('__pyx_memoryview_slice_assign_scalar') * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<< * size_t itemsize, void *item, * bint dtype_is_object) nogil: */ static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) { /* "View.MemoryView":1384 * size_t itemsize, void *item, * bint dtype_is_object) nogil: * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<< * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, * itemsize, item) */ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0); /* "View.MemoryView":1385 * bint dtype_is_object) nogil: * refcount_copying(dst, dtype_is_object, ndim, False) * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<< * itemsize, item) * refcount_copying(dst, dtype_is_object, ndim, True) */ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item); /* "View.MemoryView":1387 * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, * itemsize, item) * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<< * * */ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1); /* "View.MemoryView":1381 * * @cname('__pyx_memoryview_slice_assign_scalar') * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<< * size_t itemsize, void *item, * bint dtype_is_object) nogil: */ /* function exit code */ } /* "View.MemoryView":1391 * * @cname('__pyx_memoryview__slice_assign_scalar') * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< * Py_ssize_t *strides, int ndim, * size_t itemsize, void *item) nogil: */ static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) { CYTHON_UNUSED Py_ssize_t __pyx_v_i; Py_ssize_t __pyx_v_stride; Py_ssize_t __pyx_v_extent; int __pyx_t_1; Py_ssize_t __pyx_t_2; Py_ssize_t __pyx_t_3; /* "View.MemoryView":1395 * size_t itemsize, void *item) nogil: * cdef Py_ssize_t i * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<< * cdef Py_ssize_t extent = shape[0] * */ __pyx_v_stride = (__pyx_v_strides[0]); /* "View.MemoryView":1396 * cdef Py_ssize_t i * cdef Py_ssize_t stride = strides[0] * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<< * * if ndim == 1: */ __pyx_v_extent = (__pyx_v_shape[0]); /* "View.MemoryView":1398 * cdef Py_ssize_t extent = shape[0] * * if ndim == 1: # <<<<<<<<<<<<<< * for i in range(extent): * memcpy(data, item, itemsize) */ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0); if (__pyx_t_1) { /* "View.MemoryView":1399 * * if ndim == 1: * for i in range(extent): # <<<<<<<<<<<<<< * memcpy(data, item, itemsize) * data += stride */ __pyx_t_2 = __pyx_v_extent; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3; /* "View.MemoryView":1400 * if ndim == 1: * for i in range(extent): * memcpy(data, item, itemsize) # <<<<<<<<<<<<<< * data += stride * else: */ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize); /* "View.MemoryView":1401 * for i in range(extent): * memcpy(data, item, itemsize) * data += stride # <<<<<<<<<<<<<< * else: * for i in range(extent): */ __pyx_v_data = (__pyx_v_data + __pyx_v_stride); } /* "View.MemoryView":1398 * cdef Py_ssize_t extent = shape[0] * * if ndim == 1: # <<<<<<<<<<<<<< * for i in range(extent): * memcpy(data, item, itemsize) */ goto __pyx_L3; } /* "View.MemoryView":1403 * data += stride * else: * for i in range(extent): # <<<<<<<<<<<<<< * _slice_assign_scalar(data, shape + 1, strides + 1, * ndim - 1, itemsize, item) */ /*else*/ { __pyx_t_2 = __pyx_v_extent; for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) { __pyx_v_i = __pyx_t_3; /* "View.MemoryView":1404 * else: * for i in range(extent): * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<< * ndim - 1, itemsize, item) * data += stride */ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item); /* "View.MemoryView":1406 * _slice_assign_scalar(data, shape + 1, strides + 1, * ndim - 1, itemsize, item) * data += stride # <<<<<<<<<<<<<< * * */ __pyx_v_data = (__pyx_v_data + __pyx_v_stride); } } __pyx_L3:; /* "View.MemoryView":1391 * * @cname('__pyx_memoryview__slice_assign_scalar') * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< * Py_ssize_t *strides, int ndim, * size_t itemsize, void *item) nogil: */ /* function exit code */ } static struct __pyx_vtabstruct_array __pyx_vtable_array; static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_array_obj *p; PyObject *o; if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { o = (*t->tp_alloc)(t, 0); } else { o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); } if (unlikely(!o)) return 0; p = ((struct __pyx_array_obj *)o); p->__pyx_vtab = __pyx_vtabptr_array; p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None); p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None); if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) { Py_DECREF(o); o = 0; } return o; } static void __pyx_tp_dealloc_array(PyObject *o) { struct __pyx_array_obj *p = (struct __pyx_array_obj *)o; #if PY_VERSION_HEX >= 0x030400a1 if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) { if (PyObject_CallFinalizerFromDealloc(o)) return; } #endif { PyObject *etype, *eval, *etb; PyErr_Fetch(&etype, &eval, &etb); ++Py_REFCNT(o); __pyx_array___dealloc__(o); --Py_REFCNT(o); PyErr_Restore(etype, eval, etb); } Py_CLEAR(p->mode); Py_CLEAR(p->_format); (*Py_TYPE(o)->tp_free)(o); } static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) { PyObject *r; PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); Py_DECREF(x); return r; } static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) { if (v) { return __pyx_array___setitem__(o, i, v); } else { PyErr_Format(PyExc_NotImplementedError, "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name); return -1; } } static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) { PyObject *v = PyObject_GenericGetAttr(o, n); if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); v = __pyx_array___getattr__(o, n); } return v; } static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_5array_7memview_1__get__(o); } static PyMethodDef __pyx_methods_array[] = { {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0}, {0, 0, 0, 0} }; static struct PyGetSetDef __pyx_getsets_array[] = { {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, (char *)0, 0}, {0, 0, 0, 0, 0} }; static PySequenceMethods __pyx_tp_as_sequence_array = { 0, /*sq_length*/ 0, /*sq_concat*/ 0, /*sq_repeat*/ __pyx_sq_item_array, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ 0, /*sq_contains*/ 0, /*sq_inplace_concat*/ 0, /*sq_inplace_repeat*/ }; static PyMappingMethods __pyx_tp_as_mapping_array = { 0, /*mp_length*/ __pyx_array___getitem__, /*mp_subscript*/ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/ }; static PyBufferProcs __pyx_tp_as_buffer_array = { #if PY_MAJOR_VERSION < 3 0, /*bf_getreadbuffer*/ #endif #if PY_MAJOR_VERSION < 3 0, /*bf_getwritebuffer*/ #endif #if PY_MAJOR_VERSION < 3 0, /*bf_getsegcount*/ #endif #if PY_MAJOR_VERSION < 3 0, /*bf_getcharbuffer*/ #endif __pyx_array_getbuffer, /*bf_getbuffer*/ 0, /*bf_releasebuffer*/ }; static PyTypeObject __pyx_type___pyx_array = { PyVarObject_HEAD_INIT(0, 0) "lsh.cMinhash.array", /*tp_name*/ sizeof(struct __pyx_array_obj), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_array, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif 0, /*tp_repr*/ 0, /*tp_as_number*/ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ __pyx_tp_getattro_array, /*tp_getattro*/ 0, /*tp_setattro*/ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/ 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_array, /*tp_methods*/ 0, /*tp_members*/ __pyx_getsets_array, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_array, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { struct __pyx_MemviewEnum_obj *p; PyObject *o; if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { o = (*t->tp_alloc)(t, 0); } else { o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); } if (unlikely(!o)) return 0; p = ((struct __pyx_MemviewEnum_obj *)o); p->name = Py_None; Py_INCREF(Py_None); return o; } static void __pyx_tp_dealloc_Enum(PyObject *o) { struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; #if PY_VERSION_HEX >= 0x030400a1 if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { if (PyObject_CallFinalizerFromDealloc(o)) return; } #endif PyObject_GC_UnTrack(o); Py_CLEAR(p->name); (*Py_TYPE(o)->tp_free)(o); } static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) { int e; struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; if (p->name) { e = (*v)(p->name, a); if (e) return e; } return 0; } static int __pyx_tp_clear_Enum(PyObject *o) { PyObject* tmp; struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o; tmp = ((PyObject*)p->name); p->name = Py_None; Py_INCREF(Py_None); Py_XDECREF(tmp); return 0; } static PyMethodDef __pyx_methods_Enum[] = { {0, 0, 0, 0} }; static PyTypeObject __pyx_type___pyx_MemviewEnum = { PyVarObject_HEAD_INIT(0, 0) "lsh.cMinhash.Enum", /*tp_name*/ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_Enum, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif __pyx_MemviewEnum___repr__, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_Enum, /*tp_traverse*/ __pyx_tp_clear_Enum, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_Enum, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ __pyx_MemviewEnum___init__, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_Enum, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview; static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_memoryview_obj *p; PyObject *o; if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { o = (*t->tp_alloc)(t, 0); } else { o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); } if (unlikely(!o)) return 0; p = ((struct __pyx_memoryview_obj *)o); p->__pyx_vtab = __pyx_vtabptr_memoryview; p->obj = Py_None; Py_INCREF(Py_None); p->_size = Py_None; Py_INCREF(Py_None); p->_array_interface = Py_None; Py_INCREF(Py_None); p->view.obj = NULL; if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) { Py_DECREF(o); o = 0; } return o; } static void __pyx_tp_dealloc_memoryview(PyObject *o) { struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; #if PY_VERSION_HEX >= 0x030400a1 if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { if (PyObject_CallFinalizerFromDealloc(o)) return; } #endif PyObject_GC_UnTrack(o); { PyObject *etype, *eval, *etb; PyErr_Fetch(&etype, &eval, &etb); ++Py_REFCNT(o); __pyx_memoryview___dealloc__(o); --Py_REFCNT(o); PyErr_Restore(etype, eval, etb); } Py_CLEAR(p->obj); Py_CLEAR(p->_size); Py_CLEAR(p->_array_interface); (*Py_TYPE(o)->tp_free)(o); } static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) { int e; struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; if (p->obj) { e = (*v)(p->obj, a); if (e) return e; } if (p->_size) { e = (*v)(p->_size, a); if (e) return e; } if (p->_array_interface) { e = (*v)(p->_array_interface, a); if (e) return e; } if (p->view.obj) { e = (*v)(p->view.obj, a); if (e) return e; } return 0; } static int __pyx_tp_clear_memoryview(PyObject *o) { PyObject* tmp; struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o; tmp = ((PyObject*)p->obj); p->obj = Py_None; Py_INCREF(Py_None); Py_XDECREF(tmp); tmp = ((PyObject*)p->_size); p->_size = Py_None; Py_INCREF(Py_None); Py_XDECREF(tmp); tmp = ((PyObject*)p->_array_interface); p->_array_interface = Py_None; Py_INCREF(Py_None); Py_XDECREF(tmp); Py_CLEAR(p->view.obj); return 0; } static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) { PyObject *r; PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); Py_DECREF(x); return r; } static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) { if (v) { return __pyx_memoryview___setitem__(o, i, v); } else { PyErr_Format(PyExc_NotImplementedError, "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name); return -1; } } static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_10memoryview_1T_1__get__(o); } static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_10memoryview_4base_1__get__(o); } static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_10memoryview_5shape_1__get__(o); } static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_10memoryview_7strides_1__get__(o); } static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_10memoryview_10suboffsets_1__get__(o); } static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_10memoryview_4ndim_1__get__(o); } static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_10memoryview_8itemsize_1__get__(o); } static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_10memoryview_6nbytes_1__get__(o); } static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_10memoryview_4size_1__get__(o); } static PyMethodDef __pyx_methods_memoryview[] = { {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0}, {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0}, {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0}, {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0}, {0, 0, 0, 0} }; static struct PyGetSetDef __pyx_getsets_memoryview[] = { {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, (char *)0, 0}, {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, (char *)0, 0}, {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, (char *)0, 0}, {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, (char *)0, 0}, {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, (char *)0, 0}, {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, (char *)0, 0}, {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, (char *)0, 0}, {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, (char *)0, 0}, {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, (char *)0, 0}, {0, 0, 0, 0, 0} }; static PySequenceMethods __pyx_tp_as_sequence_memoryview = { __pyx_memoryview___len__, /*sq_length*/ 0, /*sq_concat*/ 0, /*sq_repeat*/ __pyx_sq_item_memoryview, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ 0, /*sq_contains*/ 0, /*sq_inplace_concat*/ 0, /*sq_inplace_repeat*/ }; static PyMappingMethods __pyx_tp_as_mapping_memoryview = { __pyx_memoryview___len__, /*mp_length*/ __pyx_memoryview___getitem__, /*mp_subscript*/ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/ }; static PyBufferProcs __pyx_tp_as_buffer_memoryview = { #if PY_MAJOR_VERSION < 3 0, /*bf_getreadbuffer*/ #endif #if PY_MAJOR_VERSION < 3 0, /*bf_getwritebuffer*/ #endif #if PY_MAJOR_VERSION < 3 0, /*bf_getsegcount*/ #endif #if PY_MAJOR_VERSION < 3 0, /*bf_getcharbuffer*/ #endif __pyx_memoryview_getbuffer, /*bf_getbuffer*/ 0, /*bf_releasebuffer*/ }; static PyTypeObject __pyx_type___pyx_memoryview = { PyVarObject_HEAD_INIT(0, 0) "lsh.cMinhash.memoryview", /*tp_name*/ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif __pyx_memoryview___repr__, /*tp_repr*/ 0, /*tp_as_number*/ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ __pyx_memoryview___str__, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ __pyx_tp_traverse_memoryview, /*tp_traverse*/ __pyx_tp_clear_memoryview, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods_memoryview, /*tp_methods*/ 0, /*tp_members*/ __pyx_getsets_memoryview, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new_memoryview, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice; static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) { struct __pyx_memoryviewslice_obj *p; PyObject *o = __pyx_tp_new_memoryview(t, a, k); if (unlikely(!o)) return 0; p = ((struct __pyx_memoryviewslice_obj *)o); p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice; p->from_object = Py_None; Py_INCREF(Py_None); p->from_slice.memview = NULL; return o; } static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) { struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; #if PY_VERSION_HEX >= 0x030400a1 if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { if (PyObject_CallFinalizerFromDealloc(o)) return; } #endif PyObject_GC_UnTrack(o); { PyObject *etype, *eval, *etb; PyErr_Fetch(&etype, &eval, &etb); ++Py_REFCNT(o); __pyx_memoryviewslice___dealloc__(o); --Py_REFCNT(o); PyErr_Restore(etype, eval, etb); } Py_CLEAR(p->from_object); PyObject_GC_Track(o); __pyx_tp_dealloc_memoryview(o); } static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) { int e; struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e; if (p->from_object) { e = (*v)(p->from_object, a); if (e) return e; } return 0; } static int __pyx_tp_clear__memoryviewslice(PyObject *o) { PyObject* tmp; struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o; __pyx_tp_clear_memoryview(o); tmp = ((PyObject*)p->from_object); p->from_object = Py_None; Py_INCREF(Py_None); Py_XDECREF(tmp); __PYX_XDEC_MEMVIEW(&p->from_slice, 1); return 0; } static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) { return __pyx_pw_15View_dot_MemoryView_16_memoryviewslice_4base_1__get__(o); } static PyMethodDef __pyx_methods__memoryviewslice[] = { {0, 0, 0, 0} }; static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = { {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, (char *)0, 0}, {0, 0, 0, 0, 0} }; static PyTypeObject __pyx_type___pyx_memoryviewslice = { PyVarObject_HEAD_INIT(0, 0) "lsh.cMinhash._memoryviewslice", /*tp_name*/ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/ 0, /*tp_itemsize*/ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #endif #if PY_MAJOR_VERSION >= 3 0, /*tp_as_async*/ #endif #if CYTHON_COMPILING_IN_PYPY __pyx_memoryview___repr__, /*tp_repr*/ #else 0, /*tp_repr*/ #endif 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ #if CYTHON_COMPILING_IN_PYPY __pyx_memoryview___str__, /*tp_str*/ #else 0, /*tp_str*/ #endif 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ "Internal class for passing memoryview slices to Python", /*tp_doc*/ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/ __pyx_tp_clear__memoryviewslice, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_methods__memoryviewslice, /*tp_methods*/ 0, /*tp_members*/ __pyx_getsets__memoryviewslice, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ __pyx_tp_new__memoryviewslice, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static PyMethodDef __pyx_methods[] = { {0, 0, 0, 0} }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef __pyx_moduledef = { #if PY_VERSION_HEX < 0x03020000 { PyObject_HEAD_INIT(NULL) NULL, 0, NULL }, #else PyModuleDef_HEAD_INIT, #endif "cMinhash", 0, /* m_doc */ -1, /* m_size */ __pyx_methods /* m_methods */, NULL, /* m_reload */ NULL, /* m_traverse */ NULL, /* m_clear */ NULL /* m_free */ }; #endif static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_ASCII, __pyx_k_ASCII, sizeof(__pyx_k_ASCII), 0, 0, 1, 1}, {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0}, {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0}, {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0}, {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1}, {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0}, {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0}, {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0}, {&__pyx_n_s_INT32_MAX, __pyx_k_INT32_MAX, sizeof(__pyx_k_INT32_MAX), 0, 0, 1, 1}, {&__pyx_n_s_INT64_MAX, __pyx_k_INT64_MAX, sizeof(__pyx_k_INT64_MAX), 0, 0, 1, 1}, {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1}, {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0}, {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0}, {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0}, {&__pyx_kp_s_Matti_Lyra, __pyx_k_Matti_Lyra, sizeof(__pyx_k_Matti_Lyra), 0, 0, 1, 0}, {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1}, {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0}, {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0}, {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0}, {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1}, {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0}, {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0}, {&__pyx_kp_s_Users_miro_projects_LSH_lsh_cMi, __pyx_k_Users_miro_projects_LSH_lsh_cMi, sizeof(__pyx_k_Users_miro_projects_LSH_lsh_cMi), 0, 0, 1, 0}, {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1}, {&__pyx_n_s_author, __pyx_k_author, sizeof(__pyx_k_author), 0, 0, 1, 1}, {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1}, {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1}, {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1}, {&__pyx_n_s_c_str, __pyx_k_c_str, sizeof(__pyx_k_c_str), 0, 0, 1, 1}, {&__pyx_n_s_char_ngram, __pyx_k_char_ngram, sizeof(__pyx_k_char_ngram), 0, 0, 1, 1}, {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1}, {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0}, {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0}, {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1}, {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1}, {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1}, {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1}, {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1}, {&__pyx_n_s_fingerprint, __pyx_k_fingerprint, sizeof(__pyx_k_fingerprint), 0, 0, 1, 1}, {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1}, {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1}, {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1}, {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0}, {&__pyx_n_s_hash, __pyx_k_hash, sizeof(__pyx_k_hash), 0, 0, 1, 1}, {&__pyx_n_s_hashes, __pyx_k_hashes, sizeof(__pyx_k_hashes), 0, 0, 1, 1}, {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1}, {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1}, {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0}, {&__pyx_n_s_lsh_cMinhash, __pyx_k_lsh_cMinhash, sizeof(__pyx_k_lsh_cMinhash), 0, 0, 1, 1}, {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, {&__pyx_n_s_mem_view, __pyx_k_mem_view, sizeof(__pyx_k_mem_view), 0, 0, 1, 1}, {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1}, {&__pyx_n_s_minhash, __pyx_k_minhash, sizeof(__pyx_k_minhash), 0, 0, 1, 1}, {&__pyx_n_s_minhash_32, __pyx_k_minhash_32, sizeof(__pyx_k_minhash_32), 0, 0, 1, 1}, {&__pyx_n_s_minhash_64, __pyx_k_minhash_64, sizeof(__pyx_k_minhash_64), 0, 0, 1, 1}, {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1}, {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1}, {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0}, {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0}, {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1}, {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, {&__pyx_n_s_num_seeds, __pyx_k_num_seeds, sizeof(__pyx_k_num_seeds), 0, 0, 1, 1}, {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1}, {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1}, {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1}, {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, {&__pyx_n_s_s, __pyx_k_s, sizeof(__pyx_k_s), 0, 0, 1, 1}, {&__pyx_n_s_seeds, __pyx_k_seeds, sizeof(__pyx_k_seeds), 0, 0, 1, 1}, {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1}, {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1}, {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1}, {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1}, {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1}, {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0}, {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0}, {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0}, {&__pyx_n_s_strlen, __pyx_k_strlen, sizeof(__pyx_k_strlen), 0, 0, 1, 1}, {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1}, {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, {&__pyx_n_s_uint32, __pyx_k_uint32, sizeof(__pyx_k_uint32), 0, 0, 1, 1}, {&__pyx_n_s_uint64, __pyx_k_uint64, sizeof(__pyx_k_uint64), 0, 0, 1, 1}, {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0}, {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0}, {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0}, {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1}, {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0} }; static int __Pyx_InitCachedBuiltins(void) { __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 43, __pyx_L1_error) __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 218, __pyx_L1_error) __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(1, 799, __pyx_L1_error) __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(2, 146, __pyx_L1_error) __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) __PYX_ERR(2, 149, __pyx_L1_error) __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) __PYX_ERR(2, 396, __pyx_L1_error) __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(2, 425, __pyx_L1_error) __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) __PYX_ERR(2, 599, __pyx_L1_error) __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(2, 818, __pyx_L1_error) return 0; __pyx_L1_error:; return -1; } static int __Pyx_InitCachedConstants(void) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":218 * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< * * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) */ __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 218, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple_); __Pyx_GIVEREF(__pyx_tuple_); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":222 * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< * * info.buf = PyArray_DATA(self) */ __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 222, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__2); __Pyx_GIVEREF(__pyx_tuple__2); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":259 * if ((descr.byteorder == c'>' and little_endian) or * (descr.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< * if t == NPY_BYTE: f = "b" * elif t == NPY_UBYTE: f = "B" */ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(1, 259, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__3); __Pyx_GIVEREF(__pyx_tuple__3); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":799 * * if (end - f) - (new_offset - offset[0]) < 15: * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< * * if ((child.byteorder == c'>' and little_endian) or */ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 799, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__4); __Pyx_GIVEREF(__pyx_tuple__4); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":803 * if ((child.byteorder == c'>' and little_endian) or * (child.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< * # One could encode it in the format string and have Cython * # complain instead, BUT: < and > in format strings also imply */ __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 803, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__5); __Pyx_GIVEREF(__pyx_tuple__5); /* "../../anaconda3/envs/skimit-extract/lib/python3.5/site-packages/Cython/Includes/numpy/__init__.pxd":823 * t = child.type_num * if end - f < 5: * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< * * # Until ticket #99 is fixed, use integers to avoid warnings */ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 823, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__6); __Pyx_GIVEREF(__pyx_tuple__6); /* "View.MemoryView":131 * * if not self.ndim: * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<< * * if itemsize <= 0: */ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(2, 131, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__7); __Pyx_GIVEREF(__pyx_tuple__7); /* "View.MemoryView":134 * * if itemsize <= 0: * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<< * * if not isinstance(format, bytes): */ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(2, 134, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__8); __Pyx_GIVEREF(__pyx_tuple__8); /* "View.MemoryView":137 * * if not isinstance(format, bytes): * format = format.encode('ASCII') # <<<<<<<<<<<<<< * self._format = format # keep a reference to the byte string * self.format = self._format */ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_n_s_ASCII); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(2, 137, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__9); __Pyx_GIVEREF(__pyx_tuple__9); /* "View.MemoryView":146 * * if not self._shape: * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<< * * */ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(2, 146, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__10); __Pyx_GIVEREF(__pyx_tuple__10); /* "View.MemoryView":174 * self.data = malloc(self.len) * if not self.data: * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<< * * if self.dtype_is_object: */ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(2, 174, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__11); __Pyx_GIVEREF(__pyx_tuple__11); /* "View.MemoryView":190 * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS * if not (flags & bufmode): * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<< * info.buf = self.data * info.len = self.len */ __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(2, 190, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__12); __Pyx_GIVEREF(__pyx_tuple__12); /* "View.MemoryView":484 * result = struct.unpack(self.view.format, bytesitem) * except struct.error: * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<< * else: * if len(self.view.format) == 1: */ __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(2, 484, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__13); __Pyx_GIVEREF(__pyx_tuple__13); /* "View.MemoryView":556 * if self.view.strides == NULL: * * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<< * * return tuple([stride for stride in self.view.strides[:self.view.ndim]]) */ __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(2, 556, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__14); __Pyx_GIVEREF(__pyx_tuple__14); /* "View.MemoryView":563 * def suboffsets(self): * if self.view.suboffsets == NULL: * return (-1,) * self.view.ndim # <<<<<<<<<<<<<< * * return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) */ __pyx_tuple__15 = PyTuple_New(1); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(2, 563, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__15); __Pyx_INCREF(__pyx_int_neg_1); __Pyx_GIVEREF(__pyx_int_neg_1); PyTuple_SET_ITEM(__pyx_tuple__15, 0, __pyx_int_neg_1); __Pyx_GIVEREF(__pyx_tuple__15); /* "View.MemoryView":668 * if item is Ellipsis: * if not seen_ellipsis: * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<< * seen_ellipsis = True * else: */ __pyx_slice__16 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__16)) __PYX_ERR(2, 668, __pyx_L1_error) __Pyx_GOTREF(__pyx_slice__16); __Pyx_GIVEREF(__pyx_slice__16); /* "View.MemoryView":671 * seen_ellipsis = True * else: * result.append(slice(None)) # <<<<<<<<<<<<<< * have_slices = True * else: */ __pyx_slice__17 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__17)) __PYX_ERR(2, 671, __pyx_L1_error) __Pyx_GOTREF(__pyx_slice__17); __Pyx_GIVEREF(__pyx_slice__17); /* "View.MemoryView":682 * nslices = ndim - len(result) * if nslices: * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<< * * return have_slices or nslices, tuple(result) */ __pyx_slice__18 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__18)) __PYX_ERR(2, 682, __pyx_L1_error) __Pyx_GOTREF(__pyx_slice__18); __Pyx_GIVEREF(__pyx_slice__18); /* "View.MemoryView":689 * for suboffset in suboffsets[:ndim]: * if suboffset >= 0: * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<< * * */ __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(2, 689, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__19); __Pyx_GIVEREF(__pyx_tuple__19); /* "lsh/cMinhash.pyx":21 * * @cython.boundscheck(False) # turn of bounds-checking for entire function * def minhash_64(char* c_str, int strlen, # <<<<<<<<<<<<<< * np.ndarray[dtype=np.uint32_t, ndim=1] seeds not None, * int char_ngram): */ __pyx_tuple__20 = PyTuple_Pack(12, __pyx_n_s_c_str, __pyx_n_s_strlen, __pyx_n_s_seeds, __pyx_n_s_char_ngram, __pyx_n_s_num_seeds, __pyx_n_s_fingerprint, __pyx_n_s_INT64_MAX, __pyx_n_s_hashes, __pyx_n_s_minhash, __pyx_n_s_mem_view, __pyx_n_s_i, __pyx_n_s_s); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(0, 21, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__20); __Pyx_GIVEREF(__pyx_tuple__20); __pyx_codeobj__21 = (PyObject*)__Pyx_PyCode_New(4, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_miro_projects_LSH_lsh_cMi, __pyx_n_s_minhash_64, 21, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__21)) __PYX_ERR(0, 21, __pyx_L1_error) /* "lsh/cMinhash.pyx":60 * * @cython.boundscheck(False) # turn of bounds-checking for entire function * def minhash_32(char* c_str, int strlen, # <<<<<<<<<<<<<< * np.ndarray[dtype=np.uint32_t, ndim=1] seeds not None, * int char_ngram): */ __pyx_tuple__22 = PyTuple_Pack(12, __pyx_n_s_c_str, __pyx_n_s_strlen, __pyx_n_s_seeds, __pyx_n_s_char_ngram, __pyx_n_s_num_seeds, __pyx_n_s_fingerprint, __pyx_n_s_INT32_MAX, __pyx_n_s_hash, __pyx_n_s_minhash, __pyx_n_s_mem_view, __pyx_n_s_i, __pyx_n_s_s); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 60, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__22); __Pyx_GIVEREF(__pyx_tuple__22); __pyx_codeobj__23 = (PyObject*)__Pyx_PyCode_New(4, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__22, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_miro_projects_LSH_lsh_cMi, __pyx_n_s_minhash_32, 60, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__23)) __PYX_ERR(0, 60, __pyx_L1_error) /* "View.MemoryView":282 * return self.name * * cdef generic = Enum("") # <<<<<<<<<<<<<< * cdef strided = Enum("") # default * cdef indirect = Enum("") */ __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__24)) __PYX_ERR(2, 282, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__24); __Pyx_GIVEREF(__pyx_tuple__24); /* "View.MemoryView":283 * * cdef generic = Enum("") * cdef strided = Enum("") # default # <<<<<<<<<<<<<< * cdef indirect = Enum("") * */ __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(2, 283, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__25); __Pyx_GIVEREF(__pyx_tuple__25); /* "View.MemoryView":284 * cdef generic = Enum("") * cdef strided = Enum("") # default * cdef indirect = Enum("") # <<<<<<<<<<<<<< * * */ __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(2, 284, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__26); __Pyx_GIVEREF(__pyx_tuple__26); /* "View.MemoryView":287 * * * cdef contiguous = Enum("") # <<<<<<<<<<<<<< * cdef indirect_contiguous = Enum("") * */ __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(2, 287, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__27); __Pyx_GIVEREF(__pyx_tuple__27); /* "View.MemoryView":288 * * cdef contiguous = Enum("") * cdef indirect_contiguous = Enum("") # <<<<<<<<<<<<<< * * */ __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(2, 288, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__28); __Pyx_GIVEREF(__pyx_tuple__28); __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; __Pyx_RefNannyFinishContext(); return -1; } static int __Pyx_InitGlobals(void) { if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) __PYX_ERR(0, 1, __pyx_L1_error) return 0; __pyx_L1_error:; return -1; } #if PY_MAJOR_VERSION < 3 PyMODINIT_FUNC initcMinhash(void); /*proto*/ PyMODINIT_FUNC initcMinhash(void) #else PyMODINIT_FUNC PyInit_cMinhash(void); /*proto*/ PyMODINIT_FUNC PyInit_cMinhash(void) #endif { PyObject *__pyx_t_1 = NULL; static PyThread_type_lock __pyx_t_2[8]; __Pyx_RefNannyDeclarations #if CYTHON_REFNANNY __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); if (!__Pyx_RefNanny) { PyErr_Clear(); __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); if (!__Pyx_RefNanny) Py_FatalError("failed to import 'refnanny' module"); } #endif __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_cMinhash(void)", 0); if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) #ifdef __Pyx_CyFunction_USED if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif #ifdef __Pyx_FusedFunction_USED if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif #ifdef __Pyx_Coroutine_USED if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif #ifdef __Pyx_Generator_USED if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif #ifdef __Pyx_StopAsyncIteration_USED if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif /*--- Library function declarations ---*/ /*--- Threads initialization code ---*/ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS #ifdef WITH_THREAD /* Python build with threading support? */ PyEval_InitThreads(); #endif #endif /*--- Module creation code ---*/ #if PY_MAJOR_VERSION < 3 __pyx_m = Py_InitModule4("cMinhash", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); #else __pyx_m = PyModule_Create(&__pyx_moduledef); #endif if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) Py_INCREF(__pyx_d); __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) #if CYTHON_COMPILING_IN_PYPY Py_INCREF(__pyx_b); #endif if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); /*--- Initialize various global constants etc. ---*/ if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif if (__pyx_module_is_main_lsh__cMinhash) { if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) } #if PY_MAJOR_VERSION >= 3 { PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) if (!PyDict_GetItemString(modules, "lsh.cMinhash")) { if (unlikely(PyDict_SetItemString(modules, "lsh.cMinhash", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) } } #endif /*--- Builtin init code ---*/ if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) /*--- Constants init code ---*/ if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) /*--- Global init code ---*/ generic = Py_None; Py_INCREF(Py_None); strided = Py_None; Py_INCREF(Py_None); indirect = Py_None; Py_INCREF(Py_None); contiguous = Py_None; Py_INCREF(Py_None); indirect_contiguous = Py_None; Py_INCREF(Py_None); /*--- Variable export code ---*/ /*--- Function export code ---*/ /*--- Type init code ---*/ __pyx_vtabptr_array = &__pyx_vtable_array; __pyx_vtable_array.get_memview = (PyObject *(*)(struct __pyx_array_obj *))__pyx_array_get_memview; if (PyType_Ready(&__pyx_type___pyx_array) < 0) __PYX_ERR(2, 103, __pyx_L1_error) __pyx_type___pyx_array.tp_print = 0; if (__Pyx_SetVtable(__pyx_type___pyx_array.tp_dict, __pyx_vtabptr_array) < 0) __PYX_ERR(2, 103, __pyx_L1_error) __pyx_array_type = &__pyx_type___pyx_array; if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) __PYX_ERR(2, 275, __pyx_L1_error) __pyx_type___pyx_MemviewEnum.tp_print = 0; __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum; __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview; __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer; __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice; __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment; __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar; __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed; __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object; __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object; if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) __PYX_ERR(2, 326, __pyx_L1_error) __pyx_type___pyx_memoryview.tp_print = 0; if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) __PYX_ERR(2, 326, __pyx_L1_error) __pyx_memoryview_type = &__pyx_type___pyx_memoryview; __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice; __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview; __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object; __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object; __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type; if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) __PYX_ERR(2, 951, __pyx_L1_error) __pyx_type___pyx_memoryviewslice.tp_print = 0; if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) __PYX_ERR(2, 951, __pyx_L1_error) __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice; /*--- Type import code ---*/ __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", #if CYTHON_COMPILING_IN_PYPY sizeof(PyTypeObject), #else sizeof(PyHeapTypeObject), #endif 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) __PYX_ERR(3, 9, __pyx_L1_error) __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) __PYX_ERR(1, 155, __pyx_L1_error) __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) __PYX_ERR(1, 168, __pyx_L1_error) __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) __PYX_ERR(1, 172, __pyx_L1_error) __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) __PYX_ERR(1, 181, __pyx_L1_error) __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) __PYX_ERR(1, 861, __pyx_L1_error) /*--- Variable import code ---*/ /*--- Function import code ---*/ /*--- Execution code ---*/ #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) #endif /* "lsh/cMinhash.pyx":4 * # distutils: sources = lsh/MurmurHash3.cpp * * __author__ = "Matti Lyra" # <<<<<<<<<<<<<< * * cimport cython */ if (PyDict_SetItem(__pyx_d, __pyx_n_s_author, __pyx_kp_s_Matti_Lyra) < 0) __PYX_ERR(0, 4, __pyx_L1_error) /* "lsh/cMinhash.pyx":10 * from libc.stdlib cimport malloc * from libc.stdint cimport uint32_t, int32_t, uint64_t * import numpy as np # <<<<<<<<<<<<<< * cimport numpy as np * */ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 10, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "lsh/cMinhash.pyx":21 * * @cython.boundscheck(False) # turn of bounds-checking for entire function * def minhash_64(char* c_str, int strlen, # <<<<<<<<<<<<<< * np.ndarray[dtype=np.uint32_t, ndim=1] seeds not None, * int char_ngram): */ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3lsh_8cMinhash_1minhash_64, NULL, __pyx_n_s_lsh_cMinhash); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 21, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_minhash_64, __pyx_t_1) < 0) __PYX_ERR(0, 21, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "lsh/cMinhash.pyx":60 * * @cython.boundscheck(False) # turn of bounds-checking for entire function * def minhash_32(char* c_str, int strlen, # <<<<<<<<<<<<<< * np.ndarray[dtype=np.uint32_t, ndim=1] seeds not None, * int char_ngram): */ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3lsh_8cMinhash_3minhash_32, NULL, __pyx_n_s_lsh_cMinhash); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 60, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_minhash_32, __pyx_t_1) < 0) __PYX_ERR(0, 60, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "lsh/cMinhash.pyx":1 * # distutils: language = c++ # <<<<<<<<<<<<<< * # distutils: sources = lsh/MurmurHash3.cpp * */ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":207 * info.obj = self * * __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<< * * def __dealloc__(array self): */ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), ((char *)"getbuffer(obj, view, flags)")); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 207, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) __PYX_ERR(2, 207, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; PyType_Modified(__pyx_array_type); /* "View.MemoryView":282 * return self.name * * cdef generic = Enum("") # <<<<<<<<<<<<<< * cdef strided = Enum("") # default * cdef indirect = Enum("") */ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 282, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(generic); __Pyx_DECREF_SET(generic, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":283 * * cdef generic = Enum("") * cdef strided = Enum("") # default # <<<<<<<<<<<<<< * cdef indirect = Enum("") * */ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 283, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(strided); __Pyx_DECREF_SET(strided, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":284 * cdef generic = Enum("") * cdef strided = Enum("") # default * cdef indirect = Enum("") # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 284, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(indirect); __Pyx_DECREF_SET(indirect, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":287 * * * cdef contiguous = Enum("") # <<<<<<<<<<<<<< * cdef indirect_contiguous = Enum("") * */ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 287, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(contiguous); __Pyx_DECREF_SET(contiguous, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":288 * * cdef contiguous = Enum("") * cdef indirect_contiguous = Enum("") # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_MemviewEnum_type), __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 288, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_XGOTREF(indirect_contiguous); __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = 0; /* "View.MemoryView":312 * * DEF THREAD_LOCKS_PREALLOCATED = 8 * cdef int __pyx_memoryview_thread_locks_used = 0 # <<<<<<<<<<<<<< * cdef PyThread_type_lock[THREAD_LOCKS_PREALLOCATED] __pyx_memoryview_thread_locks = [ * PyThread_allocate_lock(), */ __pyx_memoryview_thread_locks_used = 0; /* "View.MemoryView":313 * DEF THREAD_LOCKS_PREALLOCATED = 8 * cdef int __pyx_memoryview_thread_locks_used = 0 * cdef PyThread_type_lock[THREAD_LOCKS_PREALLOCATED] __pyx_memoryview_thread_locks = [ # <<<<<<<<<<<<<< * PyThread_allocate_lock(), * PyThread_allocate_lock(), */ __pyx_t_2[0] = PyThread_allocate_lock(); __pyx_t_2[1] = PyThread_allocate_lock(); __pyx_t_2[2] = PyThread_allocate_lock(); __pyx_t_2[3] = PyThread_allocate_lock(); __pyx_t_2[4] = PyThread_allocate_lock(); __pyx_t_2[5] = PyThread_allocate_lock(); __pyx_t_2[6] = PyThread_allocate_lock(); __pyx_t_2[7] = PyThread_allocate_lock(); memcpy(&(__pyx_memoryview_thread_locks[0]), __pyx_t_2, sizeof(__pyx_memoryview_thread_locks[0]) * (8)); /* "View.MemoryView":535 * info.obj = self * * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), ((char *)"getbuffer(obj, view, flags)")); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 535, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) __PYX_ERR(2, 535, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; PyType_Modified(__pyx_memoryview_type); /* "View.MemoryView":981 * return self.from_object * * __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<< * * */ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), ((char *)"getbuffer(obj, view, flags)")); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 981, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) __PYX_ERR(2, 981, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; PyType_Modified(__pyx_memoryviewslice_type); /* "View.MemoryView":1391 * * @cname('__pyx_memoryview__slice_assign_scalar') * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<< * Py_ssize_t *strides, int ndim, * size_t itemsize, void *item) nogil: */ /*--- Wrapped vars code ---*/ goto __pyx_L0; __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_1); if (__pyx_m) { if (__pyx_d) { __Pyx_AddTraceback("init lsh.cMinhash", __pyx_clineno, __pyx_lineno, __pyx_filename); } Py_DECREF(__pyx_m); __pyx_m = 0; } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ImportError, "init lsh.cMinhash"); } __pyx_L0:; __Pyx_RefNannyFinishContext(); #if PY_MAJOR_VERSION < 3 return; #else return __pyx_m; #endif } /* --- Runtime support code --- */ /* Refnanny */ #if CYTHON_REFNANNY static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { PyObject *m = NULL, *p = NULL; void *r = NULL; m = PyImport_ImportModule((char *)modname); if (!m) goto end; p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); if (!p) goto end; r = PyLong_AsVoidPtr(p); end: Py_XDECREF(p); Py_XDECREF(m); return (__Pyx_RefNannyAPIStruct *)r; } #endif /* GetBuiltinName */ static PyObject *__Pyx_GetBuiltinName(PyObject *name) { PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); if (unlikely(!result)) { PyErr_Format(PyExc_NameError, #if PY_MAJOR_VERSION >= 3 "name '%U' is not defined", name); #else "name '%.200s' is not defined", PyString_AS_STRING(name)); #endif } return result; } /* RaiseArgTupleInvalid */ static void __Pyx_RaiseArgtupleInvalid( const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found) { Py_ssize_t num_expected; const char *more_or_less; if (num_found < num_min) { num_expected = num_min; more_or_less = "at least"; } else { num_expected = num_max; more_or_less = "at most"; } if (exact) { more_or_less = "exactly"; } PyErr_Format(PyExc_TypeError, "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", func_name, more_or_less, num_expected, (num_expected == 1) ? "" : "s", num_found); } /* RaiseDoubleKeywords */ static void __Pyx_RaiseDoubleKeywordsError( const char* func_name, PyObject* kw_name) { PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "%s() got multiple values for keyword argument '%U'", func_name, kw_name); #else "%s() got multiple values for keyword argument '%s'", func_name, PyString_AsString(kw_name)); #endif } /* ParseKeywords */ static int __Pyx_ParseOptionalKeywords( PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name) { PyObject *key = 0, *value = 0; Py_ssize_t pos = 0; PyObject*** name; PyObject*** first_kw_arg = argnames + num_pos_args; while (PyDict_Next(kwds, &pos, &key, &value)) { name = first_kw_arg; while (*name && (**name != key)) name++; if (*name) { values[name-argnames] = value; continue; } name = first_kw_arg; #if PY_MAJOR_VERSION < 3 if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { while (*name) { if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) && _PyString_Eq(**name, key)) { values[name-argnames] = value; break; } name++; } if (*name) continue; else { PyObject*** argname = argnames; while (argname != first_kw_arg) { if ((**argname == key) || ( (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) && _PyString_Eq(**argname, key))) { goto arg_passed_twice; } argname++; } } } else #endif if (likely(PyUnicode_Check(key))) { while (*name) { int cmp = (**name == key) ? 0 : #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : #endif PyUnicode_Compare(**name, key); if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; if (cmp == 0) { values[name-argnames] = value; break; } name++; } if (*name) continue; else { PyObject*** argname = argnames; while (argname != first_kw_arg) { int cmp = (**argname == key) ? 0 : #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : #endif PyUnicode_Compare(**argname, key); if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; if (cmp == 0) goto arg_passed_twice; argname++; } } } else goto invalid_keyword_type; if (kwds2) { if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; } else { goto invalid_keyword; } } return 0; arg_passed_twice: __Pyx_RaiseDoubleKeywordsError(function_name, key); goto bad; invalid_keyword_type: PyErr_Format(PyExc_TypeError, "%.200s() keywords must be strings", function_name); goto bad; invalid_keyword: PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION < 3 "%.200s() got an unexpected keyword argument '%.200s'", function_name, PyString_AsString(key)); #else "%s() got an unexpected keyword argument '%U'", function_name, key); #endif bad: return -1; } /* ArgTypeTest */ static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) { PyErr_Format(PyExc_TypeError, "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", name, type->tp_name, Py_TYPE(obj)->tp_name); } static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, const char *name, int exact) { if (unlikely(!type)) { PyErr_SetString(PyExc_SystemError, "Missing type object"); return 0; } if (none_allowed && obj == Py_None) return 1; else if (exact) { if (likely(Py_TYPE(obj) == type)) return 1; #if PY_MAJOR_VERSION == 2 else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; #endif } else { if (likely(PyObject_TypeCheck(obj, type))) return 1; } __Pyx_RaiseArgumentTypeInvalid(name, obj, type); return 0; } /* BufferFormatCheck */ static CYTHON_INLINE int __Pyx_IsLittleEndian(void) { unsigned int n = 1; return *(unsigned char*)(&n) != 0; } static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, __Pyx_BufFmt_StackElem* stack, __Pyx_TypeInfo* type) { stack[0].field = &ctx->root; stack[0].parent_offset = 0; ctx->root.type = type; ctx->root.name = "buffer dtype"; ctx->root.offset = 0; ctx->head = stack; ctx->head->field = &ctx->root; ctx->fmt_offset = 0; ctx->head->parent_offset = 0; ctx->new_packmode = '@'; ctx->enc_packmode = '@'; ctx->new_count = 1; ctx->enc_count = 0; ctx->enc_type = 0; ctx->is_complex = 0; ctx->is_valid_array = 0; ctx->struct_alignment = 0; while (type->typegroup == 'S') { ++ctx->head; ctx->head->field = type->fields; ctx->head->parent_offset = 0; type = type->fields->type; } } static int __Pyx_BufFmt_ParseNumber(const char** ts) { int count; const char* t = *ts; if (*t < '0' || *t > '9') { return -1; } else { count = *t++ - '0'; while (*t >= '0' && *t < '9') { count *= 10; count += *t++ - '0'; } } *ts = t; return count; } static int __Pyx_BufFmt_ExpectNumber(const char **ts) { int number = __Pyx_BufFmt_ParseNumber(ts); if (number == -1) PyErr_Format(PyExc_ValueError,\ "Does not understand character buffer dtype format string ('%c')", **ts); return number; } static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { PyErr_Format(PyExc_ValueError, "Unexpected format string character: '%c'", ch); } static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { switch (ch) { case 'c': return "'char'"; case 'b': return "'signed char'"; case 'B': return "'unsigned char'"; case 'h': return "'short'"; case 'H': return "'unsigned short'"; case 'i': return "'int'"; case 'I': return "'unsigned int'"; case 'l': return "'long'"; case 'L': return "'unsigned long'"; case 'q': return "'long long'"; case 'Q': return "'unsigned long long'"; case 'f': return (is_complex ? "'complex float'" : "'float'"); case 'd': return (is_complex ? "'complex double'" : "'double'"); case 'g': return (is_complex ? "'complex long double'" : "'long double'"); case 'T': return "a struct"; case 'O': return "Python object"; case 'P': return "a pointer"; case 's': case 'p': return "a string"; case 0: return "end"; default: return "unparseable format string"; } } static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { switch (ch) { case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; case 'h': case 'H': return 2; case 'i': case 'I': case 'l': case 'L': return 4; case 'q': case 'Q': return 8; case 'f': return (is_complex ? 8 : 4); case 'd': return (is_complex ? 16 : 8); case 'g': { PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); return 0; } case 'O': case 'P': return sizeof(void*); default: __Pyx_BufFmt_RaiseUnexpectedChar(ch); return 0; } } static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { switch (ch) { case 'c': case 'b': case 'B': case 's': case 'p': return 1; case 'h': case 'H': return sizeof(short); case 'i': case 'I': return sizeof(int); case 'l': case 'L': return sizeof(long); #ifdef HAVE_LONG_LONG case 'q': case 'Q': return sizeof(PY_LONG_LONG); #endif case 'f': return sizeof(float) * (is_complex ? 2 : 1); case 'd': return sizeof(double) * (is_complex ? 2 : 1); case 'g': return sizeof(long double) * (is_complex ? 2 : 1); case 'O': case 'P': return sizeof(void*); default: { __Pyx_BufFmt_RaiseUnexpectedChar(ch); return 0; } } } typedef struct { char c; short x; } __Pyx_st_short; typedef struct { char c; int x; } __Pyx_st_int; typedef struct { char c; long x; } __Pyx_st_long; typedef struct { char c; float x; } __Pyx_st_float; typedef struct { char c; double x; } __Pyx_st_double; typedef struct { char c; long double x; } __Pyx_st_longdouble; typedef struct { char c; void *x; } __Pyx_st_void_p; #ifdef HAVE_LONG_LONG typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; #endif static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { switch (ch) { case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); #ifdef HAVE_LONG_LONG case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); #endif case 'f': return sizeof(__Pyx_st_float) - sizeof(float); case 'd': return sizeof(__Pyx_st_double) - sizeof(double); case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); default: __Pyx_BufFmt_RaiseUnexpectedChar(ch); return 0; } } /* These are for computing the padding at the end of the struct to align on the first member of the struct. This will probably the same as above, but we don't have any guarantees. */ typedef struct { short x; char c; } __Pyx_pad_short; typedef struct { int x; char c; } __Pyx_pad_int; typedef struct { long x; char c; } __Pyx_pad_long; typedef struct { float x; char c; } __Pyx_pad_float; typedef struct { double x; char c; } __Pyx_pad_double; typedef struct { long double x; char c; } __Pyx_pad_longdouble; typedef struct { void *x; char c; } __Pyx_pad_void_p; #ifdef HAVE_LONG_LONG typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; #endif static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { switch (ch) { case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); #ifdef HAVE_LONG_LONG case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); #endif case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); default: __Pyx_BufFmt_RaiseUnexpectedChar(ch); return 0; } } static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { switch (ch) { case 'c': return 'H'; case 'b': case 'h': case 'i': case 'l': case 'q': case 's': case 'p': return 'I'; case 'B': case 'H': case 'I': case 'L': case 'Q': return 'U'; case 'f': case 'd': case 'g': return (is_complex ? 'C' : 'R'); case 'O': return 'O'; case 'P': return 'P'; default: { __Pyx_BufFmt_RaiseUnexpectedChar(ch); return 0; } } } static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { if (ctx->head == NULL || ctx->head->field == &ctx->root) { const char* expected; const char* quote; if (ctx->head == NULL) { expected = "end"; quote = ""; } else { expected = ctx->head->field->type->name; quote = "'"; } PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch, expected %s%s%s but got %s", quote, expected, quote, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); } else { __Pyx_StructField* field = ctx->head->field; __Pyx_StructField* parent = (ctx->head - 1)->field; PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), parent->type->name, field->name); } } static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { char group; size_t size, offset, arraysize = 1; if (ctx->enc_type == 0) return 0; if (ctx->head->field->type->arraysize[0]) { int i, ndim = 0; if (ctx->enc_type == 's' || ctx->enc_type == 'p') { ctx->is_valid_array = ctx->head->field->type->ndim == 1; ndim = 1; if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { PyErr_Format(PyExc_ValueError, "Expected a dimension of size %zu, got %zu", ctx->head->field->type->arraysize[0], ctx->enc_count); return -1; } } if (!ctx->is_valid_array) { PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", ctx->head->field->type->ndim, ndim); return -1; } for (i = 0; i < ctx->head->field->type->ndim; i++) { arraysize *= ctx->head->field->type->arraysize[i]; } ctx->is_valid_array = 0; ctx->enc_count = 1; } group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); do { __Pyx_StructField* field = ctx->head->field; __Pyx_TypeInfo* type = field->type; if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); } else { size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); } if (ctx->enc_packmode == '@') { size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); size_t align_mod_offset; if (align_at == 0) return -1; align_mod_offset = ctx->fmt_offset % align_at; if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; if (ctx->struct_alignment == 0) ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, ctx->is_complex); } if (type->size != size || type->typegroup != group) { if (type->typegroup == 'C' && type->fields != NULL) { size_t parent_offset = ctx->head->parent_offset + field->offset; ++ctx->head; ctx->head->field = type->fields; ctx->head->parent_offset = parent_offset; continue; } if ((type->typegroup == 'H' || group == 'H') && type->size == size) { } else { __Pyx_BufFmt_RaiseExpected(ctx); return -1; } } offset = ctx->head->parent_offset + field->offset; if (ctx->fmt_offset != offset) { PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); return -1; } ctx->fmt_offset += size; if (arraysize) ctx->fmt_offset += (arraysize - 1) * size; --ctx->enc_count; while (1) { if (field == &ctx->root) { ctx->head = NULL; if (ctx->enc_count != 0) { __Pyx_BufFmt_RaiseExpected(ctx); return -1; } break; } ctx->head->field = ++field; if (field->type == NULL) { --ctx->head; field = ctx->head->field; continue; } else if (field->type->typegroup == 'S') { size_t parent_offset = ctx->head->parent_offset + field->offset; if (field->type->fields->type == NULL) continue; field = field->type->fields; ++ctx->head; ctx->head->field = field; ctx->head->parent_offset = parent_offset; break; } else { break; } } } while (ctx->enc_count); ctx->enc_type = 0; ctx->is_complex = 0; return 0; } static CYTHON_INLINE PyObject * __pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) { const char *ts = *tsp; int i = 0, number; int ndim = ctx->head->field->type->ndim; ; ++ts; if (ctx->new_count != 1) { PyErr_SetString(PyExc_ValueError, "Cannot handle repeated arrays in format string"); return NULL; } if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; while (*ts && *ts != ')') { switch (*ts) { case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; default: break; } number = __Pyx_BufFmt_ExpectNumber(&ts); if (number == -1) return NULL; if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) return PyErr_Format(PyExc_ValueError, "Expected a dimension of size %zu, got %d", ctx->head->field->type->arraysize[i], number); if (*ts != ',' && *ts != ')') return PyErr_Format(PyExc_ValueError, "Expected a comma in format string, got '%c'", *ts); if (*ts == ',') ts++; i++; } if (i != ndim) return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", ctx->head->field->type->ndim, i); if (!*ts) { PyErr_SetString(PyExc_ValueError, "Unexpected end of format string, expected ')'"); return NULL; } ctx->is_valid_array = 1; ctx->new_count = 1; *tsp = ++ts; return Py_None; } static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { int got_Z = 0; while (1) { switch(*ts) { case 0: if (ctx->enc_type != 0 && ctx->head == NULL) { __Pyx_BufFmt_RaiseExpected(ctx); return NULL; } if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; if (ctx->head != NULL) { __Pyx_BufFmt_RaiseExpected(ctx); return NULL; } return ts; case ' ': case '\r': case '\n': ++ts; break; case '<': if (!__Pyx_IsLittleEndian()) { PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); return NULL; } ctx->new_packmode = '='; ++ts; break; case '>': case '!': if (__Pyx_IsLittleEndian()) { PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); return NULL; } ctx->new_packmode = '='; ++ts; break; case '=': case '@': case '^': ctx->new_packmode = *ts++; break; case 'T': { const char* ts_after_sub; size_t i, struct_count = ctx->new_count; size_t struct_alignment = ctx->struct_alignment; ctx->new_count = 1; ++ts; if (*ts != '{') { PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); return NULL; } if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; ctx->enc_type = 0; ctx->enc_count = 0; ctx->struct_alignment = 0; ++ts; ts_after_sub = ts; for (i = 0; i != struct_count; ++i) { ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); if (!ts_after_sub) return NULL; } ts = ts_after_sub; if (struct_alignment) ctx->struct_alignment = struct_alignment; } break; case '}': { size_t alignment = ctx->struct_alignment; ++ts; if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; ctx->enc_type = 0; if (alignment && ctx->fmt_offset % alignment) { ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); } } return ts; case 'x': if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; ctx->fmt_offset += ctx->new_count; ctx->new_count = 1; ctx->enc_count = 0; ctx->enc_type = 0; ctx->enc_packmode = ctx->new_packmode; ++ts; break; case 'Z': got_Z = 1; ++ts; if (*ts != 'f' && *ts != 'd' && *ts != 'g') { __Pyx_BufFmt_RaiseUnexpectedChar('Z'); return NULL; } case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': case 'l': case 'L': case 'q': case 'Q': case 'f': case 'd': case 'g': case 'O': case 'p': if (ctx->enc_type == *ts && got_Z == ctx->is_complex && ctx->enc_packmode == ctx->new_packmode) { ctx->enc_count += ctx->new_count; ctx->new_count = 1; got_Z = 0; ++ts; break; } case 's': if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; ctx->enc_count = ctx->new_count; ctx->enc_packmode = ctx->new_packmode; ctx->enc_type = *ts; ctx->is_complex = got_Z; ++ts; ctx->new_count = 1; got_Z = 0; break; case ':': ++ts; while(*ts != ':') ++ts; ++ts; break; case '(': if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; break; default: { int number = __Pyx_BufFmt_ExpectNumber(&ts); if (number == -1) return NULL; ctx->new_count = (size_t)number; } } } } static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) { buf->buf = NULL; buf->obj = NULL; buf->strides = __Pyx_zeros; buf->shape = __Pyx_zeros; buf->suboffsets = __Pyx_minusones; } static CYTHON_INLINE int __Pyx_GetBufferAndValidate( Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack) { if (obj == Py_None || obj == NULL) { __Pyx_ZeroBuffer(buf); return 0; } buf->buf = NULL; if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail; if (buf->ndim != nd) { PyErr_Format(PyExc_ValueError, "Buffer has wrong number of dimensions (expected %d, got %d)", nd, buf->ndim); goto fail; } if (!cast) { __Pyx_BufFmt_Context ctx; __Pyx_BufFmt_Init(&ctx, stack, dtype); if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; } if ((unsigned)buf->itemsize != dtype->size) { PyErr_Format(PyExc_ValueError, "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", buf->itemsize, (buf->itemsize > 1) ? "s" : "", dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); goto fail; } if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; return 0; fail:; __Pyx_ZeroBuffer(buf); return -1; } static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { if (info->buf == NULL) return; if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; __Pyx_ReleaseBuffer(info); } /* GetModuleGlobalName */ static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { PyObject *result; #if CYTHON_COMPILING_IN_CPYTHON result = PyDict_GetItem(__pyx_d, name); if (likely(result)) { Py_INCREF(result); } else { #else result = PyObject_GetItem(__pyx_d, name); if (!result) { PyErr_Clear(); #endif result = __Pyx_GetBuiltinName(name); } return result; } /* PyObjectCall */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { PyObject *result; ternaryfunc call = func->ob_type->tp_call; if (unlikely(!call)) return PyObject_Call(func, arg, kw); if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) return NULL; result = (*call)(func, arg, kw); Py_LeaveRecursiveCall(); if (unlikely(!result) && unlikely(!PyErr_Occurred())) { PyErr_SetString( PyExc_SystemError, "NULL result without error in PyObject_Call"); } return result; } #endif /* ExtTypeTest */ static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { if (unlikely(!type)) { PyErr_SetString(PyExc_SystemError, "Missing type object"); return 0; } if (likely(PyObject_TypeCheck(obj, type))) return 1; PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", Py_TYPE(obj)->tp_name, type->tp_name); return 0; } /* MemviewSliceInit */ static int __Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview, int ndim, __Pyx_memviewslice *memviewslice, int memview_is_new_reference) { __Pyx_RefNannyDeclarations int i, retval=-1; Py_buffer *buf = &memview->view; __Pyx_RefNannySetupContext("init_memviewslice", 0); if (!buf) { PyErr_SetString(PyExc_ValueError, "buf is NULL."); goto fail; } else if (memviewslice->memview || memviewslice->data) { PyErr_SetString(PyExc_ValueError, "memviewslice is already initialized!"); goto fail; } if (buf->strides) { for (i = 0; i < ndim; i++) { memviewslice->strides[i] = buf->strides[i]; } } else { Py_ssize_t stride = buf->itemsize; for (i = ndim - 1; i >= 0; i--) { memviewslice->strides[i] = stride; stride *= buf->shape[i]; } } for (i = 0; i < ndim; i++) { memviewslice->shape[i] = buf->shape[i]; if (buf->suboffsets) { memviewslice->suboffsets[i] = buf->suboffsets[i]; } else { memviewslice->suboffsets[i] = -1; } } memviewslice->memview = memview; memviewslice->data = (char *)buf->buf; if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) { Py_INCREF(memview); } retval = 0; goto no_fail; fail: memviewslice->memview = 0; memviewslice->data = 0; retval = -1; no_fail: __Pyx_RefNannyFinishContext(); return retval; } static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) { va_list vargs; char msg[200]; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, fmt); #else va_start(vargs); #endif vsnprintf(msg, 200, fmt, vargs); Py_FatalError(msg); va_end(vargs); } static CYTHON_INLINE int __pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count, PyThread_type_lock lock) { int result; PyThread_acquire_lock(lock, 1); result = (*acquisition_count)++; PyThread_release_lock(lock); return result; } static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count, PyThread_type_lock lock) { int result; PyThread_acquire_lock(lock, 1); result = (*acquisition_count)--; PyThread_release_lock(lock); return result; } static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno) { int first_time; struct __pyx_memoryview_obj *memview = memslice->memview; if (!memview || (PyObject *) memview == Py_None) return; if (__pyx_get_slice_count(memview) < 0) __pyx_fatalerror("Acquisition count is %d (line %d)", __pyx_get_slice_count(memview), lineno); first_time = __pyx_add_acquisition_count(memview) == 0; if (first_time) { if (have_gil) { Py_INCREF((PyObject *) memview); } else { PyGILState_STATE _gilstate = PyGILState_Ensure(); Py_INCREF((PyObject *) memview); PyGILState_Release(_gilstate); } } } static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno) { int last_time; struct __pyx_memoryview_obj *memview = memslice->memview; if (!memview ) { return; } else if ((PyObject *) memview == Py_None) { memslice->memview = NULL; return; } if (__pyx_get_slice_count(memview) <= 0) __pyx_fatalerror("Acquisition count is %d (line %d)", __pyx_get_slice_count(memview), lineno); last_time = __pyx_sub_acquisition_count(memview) == 1; memslice->data = NULL; if (last_time) { if (have_gil) { Py_CLEAR(memslice->memview); } else { PyGILState_STATE _gilstate = PyGILState_Ensure(); Py_CLEAR(memslice->memview); PyGILState_Release(_gilstate); } } else { memslice->memview = NULL; } } /* PyErrFetchRestore */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; tmp_type = tstate->curexc_type; tmp_value = tstate->curexc_value; tmp_tb = tstate->curexc_traceback; tstate->curexc_type = type; tstate->curexc_value = value; tstate->curexc_traceback = tb; Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); } static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { *type = tstate->curexc_type; *value = tstate->curexc_value; *tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; } #endif /* RaiseException */ #if PY_MAJOR_VERSION < 3 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, CYTHON_UNUSED PyObject *cause) { __Pyx_PyThreadState_declare Py_XINCREF(type); if (!value || value == Py_None) value = NULL; else Py_INCREF(value); if (!tb || tb == Py_None) tb = NULL; else { Py_INCREF(tb); if (!PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "raise: arg 3 must be a traceback or None"); goto raise_error; } } if (PyType_Check(type)) { #if CYTHON_COMPILING_IN_PYPY if (!value) { Py_INCREF(Py_None); value = Py_None; } #endif PyErr_NormalizeException(&type, &value, &tb); } else { if (value) { PyErr_SetString(PyExc_TypeError, "instance exception may not have a separate value"); goto raise_error; } value = type; type = (PyObject*) Py_TYPE(type); Py_INCREF(type); if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { PyErr_SetString(PyExc_TypeError, "raise: exception class must be a subclass of BaseException"); goto raise_error; } } __Pyx_PyThreadState_assign __Pyx_ErrRestore(type, value, tb); return; raise_error: Py_XDECREF(value); Py_XDECREF(type); Py_XDECREF(tb); return; } #else static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { PyObject* owned_instance = NULL; if (tb == Py_None) { tb = 0; } else if (tb && !PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "raise: arg 3 must be a traceback or None"); goto bad; } if (value == Py_None) value = 0; if (PyExceptionInstance_Check(type)) { if (value) { PyErr_SetString(PyExc_TypeError, "instance exception may not have a separate value"); goto bad; } value = type; type = (PyObject*) Py_TYPE(value); } else if (PyExceptionClass_Check(type)) { PyObject *instance_class = NULL; if (value && PyExceptionInstance_Check(value)) { instance_class = (PyObject*) Py_TYPE(value); if (instance_class != type) { int is_subclass = PyObject_IsSubclass(instance_class, type); if (!is_subclass) { instance_class = NULL; } else if (unlikely(is_subclass == -1)) { goto bad; } else { type = instance_class; } } } if (!instance_class) { PyObject *args; if (!value) args = PyTuple_New(0); else if (PyTuple_Check(value)) { Py_INCREF(value); args = value; } else args = PyTuple_Pack(1, value); if (!args) goto bad; owned_instance = PyObject_Call(type, args, NULL); Py_DECREF(args); if (!owned_instance) goto bad; value = owned_instance; if (!PyExceptionInstance_Check(value)) { PyErr_Format(PyExc_TypeError, "calling %R should have returned an instance of " "BaseException, not %R", type, Py_TYPE(value)); goto bad; } } } else { PyErr_SetString(PyExc_TypeError, "raise: exception class must be a subclass of BaseException"); goto bad; } #if PY_VERSION_HEX >= 0x03030000 if (cause) { #else if (cause && cause != Py_None) { #endif PyObject *fixed_cause; if (cause == Py_None) { fixed_cause = NULL; } else if (PyExceptionClass_Check(cause)) { fixed_cause = PyObject_CallObject(cause, NULL); if (fixed_cause == NULL) goto bad; } else if (PyExceptionInstance_Check(cause)) { fixed_cause = cause; Py_INCREF(fixed_cause); } else { PyErr_SetString(PyExc_TypeError, "exception causes must derive from " "BaseException"); goto bad; } PyException_SetCause(value, fixed_cause); } PyErr_SetObject(type, value); if (tb) { #if CYTHON_COMPILING_IN_PYPY PyObject *tmp_type, *tmp_value, *tmp_tb; PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); Py_INCREF(tb); PyErr_Restore(tmp_type, tmp_value, tb); Py_XDECREF(tmp_tb); #else PyThreadState *tstate = PyThreadState_GET(); PyObject* tmp_tb = tstate->curexc_traceback; if (tb != tmp_tb) { Py_INCREF(tb); tstate->curexc_traceback = tb; Py_XDECREF(tmp_tb); } #endif } bad: Py_XDECREF(owned_instance); return; } #endif /* RaiseTooManyValuesToUnpack */ static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { PyErr_Format(PyExc_ValueError, "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); } /* RaiseNeedMoreValuesToUnpack */ static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { PyErr_Format(PyExc_ValueError, "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", index, (index == 1) ? "" : "s"); } /* RaiseNoneIterError */ static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); } /* BytesEquals */ static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { #if CYTHON_COMPILING_IN_PYPY return PyObject_RichCompareBool(s1, s2, equals); #else if (s1 == s2) { return (equals == Py_EQ); } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { const char *ps1, *ps2; Py_ssize_t length = PyBytes_GET_SIZE(s1); if (length != PyBytes_GET_SIZE(s2)) return (equals == Py_NE); ps1 = PyBytes_AS_STRING(s1); ps2 = PyBytes_AS_STRING(s2); if (ps1[0] != ps2[0]) { return (equals == Py_NE); } else if (length == 1) { return (equals == Py_EQ); } else { int result = memcmp(ps1, ps2, (size_t)length); return (equals == Py_EQ) ? (result == 0) : (result != 0); } } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { return (equals == Py_NE); } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { return (equals == Py_NE); } else { int result; PyObject* py_result = PyObject_RichCompare(s1, s2, equals); if (!py_result) return -1; result = __Pyx_PyObject_IsTrue(py_result); Py_DECREF(py_result); return result; } #endif } /* UnicodeEquals */ static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { #if CYTHON_COMPILING_IN_PYPY return PyObject_RichCompareBool(s1, s2, equals); #else #if PY_MAJOR_VERSION < 3 PyObject* owned_ref = NULL; #endif int s1_is_unicode, s2_is_unicode; if (s1 == s2) { goto return_eq; } s1_is_unicode = PyUnicode_CheckExact(s1); s2_is_unicode = PyUnicode_CheckExact(s2); #if PY_MAJOR_VERSION < 3 if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { owned_ref = PyUnicode_FromObject(s2); if (unlikely(!owned_ref)) return -1; s2 = owned_ref; s2_is_unicode = 1; } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { owned_ref = PyUnicode_FromObject(s1); if (unlikely(!owned_ref)) return -1; s1 = owned_ref; s1_is_unicode = 1; } else if (((!s2_is_unicode) & (!s1_is_unicode))) { return __Pyx_PyBytes_Equals(s1, s2, equals); } #endif if (s1_is_unicode & s2_is_unicode) { Py_ssize_t length; int kind; void *data1, *data2; if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) return -1; length = __Pyx_PyUnicode_GET_LENGTH(s1); if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { goto return_ne; } kind = __Pyx_PyUnicode_KIND(s1); if (kind != __Pyx_PyUnicode_KIND(s2)) { goto return_ne; } data1 = __Pyx_PyUnicode_DATA(s1); data2 = __Pyx_PyUnicode_DATA(s2); if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { goto return_ne; } else if (length == 1) { goto return_eq; } else { int result = memcmp(data1, data2, (size_t)(length * kind)); #if PY_MAJOR_VERSION < 3 Py_XDECREF(owned_ref); #endif return (equals == Py_EQ) ? (result == 0) : (result != 0); } } else if ((s1 == Py_None) & s2_is_unicode) { goto return_ne; } else if ((s2 == Py_None) & s1_is_unicode) { goto return_ne; } else { int result; PyObject* py_result = PyObject_RichCompare(s1, s2, equals); if (!py_result) return -1; result = __Pyx_PyObject_IsTrue(py_result); Py_DECREF(py_result); return result; } return_eq: #if PY_MAJOR_VERSION < 3 Py_XDECREF(owned_ref); #endif return (equals == Py_EQ); return_ne: #if PY_MAJOR_VERSION < 3 Py_XDECREF(owned_ref); #endif return (equals == Py_NE); #endif } /* None */ static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) { Py_ssize_t q = a / b; Py_ssize_t r = a - q*b; q -= ((r != 0) & ((r ^ b) < 0)); return q; } /* GetAttr */ static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { #if CYTHON_COMPILING_IN_CPYTHON #if PY_MAJOR_VERSION >= 3 if (likely(PyUnicode_Check(n))) #else if (likely(PyString_Check(n))) #endif return __Pyx_PyObject_GetAttrStr(o, n); #endif return PyObject_GetAttr(o, n); } /* decode_c_string */ static CYTHON_INLINE PyObject* __Pyx_decode_c_string( const char* cstring, Py_ssize_t start, Py_ssize_t stop, const char* encoding, const char* errors, PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { Py_ssize_t length; if (unlikely((start < 0) | (stop < 0))) { size_t slen = strlen(cstring); if (unlikely(slen > (size_t) PY_SSIZE_T_MAX)) { PyErr_SetString(PyExc_OverflowError, "c-string too long to convert to Python"); return NULL; } length = (Py_ssize_t) slen; if (start < 0) { start += length; if (start < 0) start = 0; } if (stop < 0) stop += length; } length = stop - start; if (unlikely(length <= 0)) return PyUnicode_FromUnicode(NULL, 0); cstring += start; if (decode_func) { return decode_func(cstring, length, errors); } else { return PyUnicode_Decode(cstring, length, encoding, errors); } } /* SaveResetException */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { *type = tstate->curexc_type; *value = tstate->curexc_value; *tb = tstate->curexc_traceback; Py_XINCREF(*type); Py_XINCREF(*value); Py_XINCREF(*tb); } static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; tmp_type = tstate->curexc_type; tmp_value = tstate->curexc_value; tmp_tb = tstate->curexc_traceback; tstate->curexc_type = type; tstate->curexc_value = value; tstate->curexc_traceback = tb; Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); } #endif /* PyErrExceptionMatches */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err) { PyObject *exc_type = tstate->curexc_type; if (exc_type == err) return 1; if (unlikely(!exc_type)) return 0; return PyErr_GivenExceptionMatches(exc_type, err); } #endif /* GetException */ #if CYTHON_COMPILING_IN_CPYTHON static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { #else static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { #endif PyObject *local_type, *local_value, *local_tb; #if CYTHON_COMPILING_IN_CPYTHON PyObject *tmp_type, *tmp_value, *tmp_tb; local_type = tstate->curexc_type; local_value = tstate->curexc_value; local_tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; #else PyErr_Fetch(&local_type, &local_value, &local_tb); #endif PyErr_NormalizeException(&local_type, &local_value, &local_tb); #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(tstate->curexc_type)) #else if (unlikely(PyErr_Occurred())) #endif goto bad; #if PY_MAJOR_VERSION >= 3 if (local_tb) { if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) goto bad; } #endif Py_XINCREF(local_tb); Py_XINCREF(local_type); Py_XINCREF(local_value); *type = local_type; *value = local_value; *tb = local_tb; #if CYTHON_COMPILING_IN_CPYTHON tmp_type = tstate->curexc_type; tmp_value = tstate->curexc_value; tmp_tb = tstate->curexc_traceback; tstate->curexc_type = local_type; tstate->curexc_value = local_value; tstate->curexc_traceback = local_tb; Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); #else PyErr_SetExcInfo(local_type, local_value, local_tb); #endif return 0; bad: *type = 0; *value = 0; *tb = 0; Py_XDECREF(local_type); Py_XDECREF(local_value); Py_XDECREF(local_tb); return -1; } /* SwapException */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; tmp_type = tstate->curexc_type; tmp_value = tstate->curexc_value; tmp_tb = tstate->curexc_traceback; tstate->curexc_type = *type; tstate->curexc_value = *value; tstate->curexc_traceback = *tb; *type = tmp_type; *value = tmp_value; *tb = tmp_tb; } #else static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); PyErr_SetExcInfo(*type, *value, *tb); *type = tmp_type; *value = tmp_value; *tb = tmp_tb; } #endif /* Import */ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { PyObject *empty_list = 0; PyObject *module = 0; PyObject *global_dict = 0; PyObject *empty_dict = 0; PyObject *list; #if PY_VERSION_HEX < 0x03030000 PyObject *py_import; py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); if (!py_import) goto bad; #endif if (from_list) list = from_list; else { empty_list = PyList_New(0); if (!empty_list) goto bad; list = empty_list; } global_dict = PyModule_GetDict(__pyx_m); if (!global_dict) goto bad; empty_dict = PyDict_New(); if (!empty_dict) goto bad; { #if PY_MAJOR_VERSION >= 3 if (level == -1) { if (strchr(__Pyx_MODULE_NAME, '.')) { #if PY_VERSION_HEX < 0x03030000 PyObject *py_level = PyInt_FromLong(1); if (!py_level) goto bad; module = PyObject_CallFunctionObjArgs(py_import, name, global_dict, empty_dict, list, py_level, NULL); Py_DECREF(py_level); #else module = PyImport_ImportModuleLevelObject( name, global_dict, empty_dict, list, 1); #endif if (!module) { if (!PyErr_ExceptionMatches(PyExc_ImportError)) goto bad; PyErr_Clear(); } } level = 0; } #endif if (!module) { #if PY_VERSION_HEX < 0x03030000 PyObject *py_level = PyInt_FromLong(level); if (!py_level) goto bad; module = PyObject_CallFunctionObjArgs(py_import, name, global_dict, empty_dict, list, py_level, NULL); Py_DECREF(py_level); #else module = PyImport_ImportModuleLevelObject( name, global_dict, empty_dict, list, level); #endif } } bad: #if PY_VERSION_HEX < 0x03030000 Py_XDECREF(py_import); #endif Py_XDECREF(empty_list); Py_XDECREF(empty_dict); return module; } /* GetItemInt */ static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { PyObject *r; if (!j) return NULL; r = PyObject_GetItem(o, j); Py_DECREF(j); return r; } static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { #if CYTHON_COMPILING_IN_CPYTHON if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o); if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) { PyObject *r = PyList_GET_ITEM(o, i); Py_INCREF(r); return r; } return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); #else return PySequence_GetItem(o, i); #endif } static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { #if CYTHON_COMPILING_IN_CPYTHON if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o); if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, i); Py_INCREF(r); return r; } return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); #else return PySequence_GetItem(o, i); #endif } static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { #if CYTHON_COMPILING_IN_CPYTHON if (is_list || PyList_CheckExact(o)) { Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) { PyObject *r = PyList_GET_ITEM(o, n); Py_INCREF(r); return r; } } else if (PyTuple_CheckExact(o)) { Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, n); Py_INCREF(r); return r; } } else { PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; if (likely(m && m->sq_item)) { if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { Py_ssize_t l = m->sq_length(o); if (likely(l >= 0)) { i += l; } else { if (!PyErr_ExceptionMatches(PyExc_OverflowError)) return NULL; PyErr_Clear(); } } return m->sq_item(o, i); } } #else if (is_list || PySequence_Check(o)) { return PySequence_GetItem(o, i); } #endif return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); } /* PyIntBinop */ #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx_PyInt_AddObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, CYTHON_UNUSED int inplace) { #if PY_MAJOR_VERSION < 3 if (likely(PyInt_CheckExact(op1))) { const long b = intval; long x; long a = PyInt_AS_LONG(op1); x = (long)((unsigned long)a + b); if (likely((x^a) >= 0 || (x^b) >= 0)) return PyInt_FromLong(x); return PyLong_Type.tp_as_number->nb_add(op1, op2); } #endif #if CYTHON_USE_PYLONG_INTERNALS && PY_MAJOR_VERSION >= 3 if (likely(PyLong_CheckExact(op1))) { const long b = intval; long a, x; const PY_LONG_LONG llb = intval; PY_LONG_LONG lla, llx; const digit* digits = ((PyLongObject*)op1)->ob_digit; const Py_ssize_t size = Py_SIZE(op1); if (likely(__Pyx_sst_abs(size) <= 1)) { a = likely(size) ? digits[0] : 0; if (size == -1) a = -a; } else { switch (size) { case -2: if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); break; } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { lla = -(PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); goto long_long; } case 2: if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); break; } else if (8 * sizeof(PY_LONG_LONG) - 1 > 2 * PyLong_SHIFT) { lla = (PY_LONG_LONG) (((((unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); goto long_long; } case -3: if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); break; } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { lla = -(PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); goto long_long; } case 3: if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); break; } else if (8 * sizeof(PY_LONG_LONG) - 1 > 3 * PyLong_SHIFT) { lla = (PY_LONG_LONG) (((((((unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); goto long_long; } case -4: if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); break; } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { lla = -(PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); goto long_long; } case 4: if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])); break; } else if (8 * sizeof(PY_LONG_LONG) - 1 > 4 * PyLong_SHIFT) { lla = (PY_LONG_LONG) (((((((((unsigned PY_LONG_LONG)digits[3]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[2]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[1]) << PyLong_SHIFT) | (unsigned PY_LONG_LONG)digits[0])); goto long_long; } default: return PyLong_Type.tp_as_number->nb_add(op1, op2); } } x = a + b; return PyLong_FromLong(x); long_long: llx = lla + llb; return PyLong_FromLongLong(llx); } #endif if (PyFloat_CheckExact(op1)) { const long b = intval; double a = PyFloat_AS_DOUBLE(op1); double result; PyFPE_START_PROTECT("add", return NULL) result = ((double)a) + (double)b; PyFPE_END_PROTECT(result) return PyFloat_FromDouble(result); } return (inplace ? PyNumber_InPlaceAdd : PyNumber_Add)(op1, op2); } #endif /* None */ static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) { PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname); } /* None */ static CYTHON_INLINE long __Pyx_div_long(long a, long b) { long q = a / b; long r = a - q*b; q -= ((r != 0) & ((r ^ b) < 0)); return q; } /* WriteUnraisableException */ static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename, int full_traceback, CYTHON_UNUSED int nogil) { PyObject *old_exc, *old_val, *old_tb; PyObject *ctx; __Pyx_PyThreadState_declare #ifdef WITH_THREAD PyGILState_STATE state; if (nogil) state = PyGILState_Ensure(); #ifdef _MSC_VER else state = (PyGILState_STATE)-1; #endif #endif __Pyx_PyThreadState_assign __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); if (full_traceback) { Py_XINCREF(old_exc); Py_XINCREF(old_val); Py_XINCREF(old_tb); __Pyx_ErrRestore(old_exc, old_val, old_tb); PyErr_PrintEx(1); } #if PY_MAJOR_VERSION < 3 ctx = PyString_FromString(name); #else ctx = PyUnicode_FromString(name); #endif __Pyx_ErrRestore(old_exc, old_val, old_tb); if (!ctx) { PyErr_WriteUnraisable(Py_None); } else { PyErr_WriteUnraisable(ctx); Py_DECREF(ctx); } #ifdef WITH_THREAD if (nogil) PyGILState_Release(state); #endif } /* PyObjectCallMethO */ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { PyObject *self, *result; PyCFunction cfunc; cfunc = PyCFunction_GET_FUNCTION(func); self = PyCFunction_GET_SELF(func); if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) return NULL; result = cfunc(self, arg); Py_LeaveRecursiveCall(); if (unlikely(!result) && unlikely(!PyErr_Occurred())) { PyErr_SetString( PyExc_SystemError, "NULL result without error in PyObject_Call"); } return result; } #endif /* PyObjectCallOneArg */ #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { PyObject *result; PyObject *args = PyTuple_New(1); if (unlikely(!args)) return NULL; Py_INCREF(arg); PyTuple_SET_ITEM(args, 0, arg); result = __Pyx_PyObject_Call(func, args, NULL); Py_DECREF(args); return result; } static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { #ifdef __Pyx_CyFunction_USED if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) { #else if (likely(PyCFunction_Check(func))) { #endif if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { return __Pyx_PyObject_CallMethO(func, arg); } } return __Pyx__PyObject_CallOneArg(func, arg); } #else static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { PyObject *result; PyObject *args = PyTuple_Pack(1, arg); if (unlikely(!args)) return NULL; result = __Pyx_PyObject_Call(func, args, NULL); Py_DECREF(args); return result; } #endif /* SetVTable */ static int __Pyx_SetVtable(PyObject *dict, void *vtable) { #if PY_VERSION_HEX >= 0x02070000 PyObject *ob = PyCapsule_New(vtable, 0, 0); #else PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); #endif if (!ob) goto bad; if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0) goto bad; Py_DECREF(ob); return 0; bad: Py_XDECREF(ob); return -1; } /* CodeObjectCache */ static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { int start = 0, mid = 0, end = count - 1; if (end >= 0 && code_line > entries[end].code_line) { return count; } while (start < end) { mid = start + (end - start) / 2; if (code_line < entries[mid].code_line) { end = mid; } else if (code_line > entries[mid].code_line) { start = mid + 1; } else { return mid; } } if (code_line <= entries[mid].code_line) { return mid; } else { return mid + 1; } } static PyCodeObject *__pyx_find_code_object(int code_line) { PyCodeObject* code_object; int pos; if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { return NULL; } pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { return NULL; } code_object = __pyx_code_cache.entries[pos].code_object; Py_INCREF(code_object); return code_object; } static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { int pos, i; __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; if (unlikely(!code_line)) { return; } if (unlikely(!entries)) { entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); if (likely(entries)) { __pyx_code_cache.entries = entries; __pyx_code_cache.max_count = 64; __pyx_code_cache.count = 1; entries[0].code_line = code_line; entries[0].code_object = code_object; Py_INCREF(code_object); } return; } pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { PyCodeObject* tmp = entries[pos].code_object; entries[pos].code_object = code_object; Py_DECREF(tmp); return; } if (__pyx_code_cache.count == __pyx_code_cache.max_count) { int new_max = __pyx_code_cache.max_count + 64; entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); if (unlikely(!entries)) { return; } __pyx_code_cache.entries = entries; __pyx_code_cache.max_count = new_max; } for (i=__pyx_code_cache.count; i>pos; i--) { entries[i] = entries[i-1]; } entries[pos].code_line = code_line; entries[pos].code_object = code_object; __pyx_code_cache.count++; Py_INCREF(code_object); } /* AddTraceback */ #include "compile.h" #include "frameobject.h" #include "traceback.h" static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( const char *funcname, int c_line, int py_line, const char *filename) { PyCodeObject *py_code = 0; PyObject *py_srcfile = 0; PyObject *py_funcname = 0; #if PY_MAJOR_VERSION < 3 py_srcfile = PyString_FromString(filename); #else py_srcfile = PyUnicode_FromString(filename); #endif if (!py_srcfile) goto bad; if (c_line) { #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); #else py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); #endif } else { #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromString(funcname); #else py_funcname = PyUnicode_FromString(funcname); #endif } if (!py_funcname) goto bad; py_code = __Pyx_PyCode_New( 0, 0, 0, 0, 0, __pyx_empty_bytes, /*PyObject *code,*/ __pyx_empty_tuple, /*PyObject *consts,*/ __pyx_empty_tuple, /*PyObject *names,*/ __pyx_empty_tuple, /*PyObject *varnames,*/ __pyx_empty_tuple, /*PyObject *freevars,*/ __pyx_empty_tuple, /*PyObject *cellvars,*/ py_srcfile, /*PyObject *filename,*/ py_funcname, /*PyObject *name,*/ py_line, __pyx_empty_bytes /*PyObject *lnotab*/ ); Py_DECREF(py_srcfile); Py_DECREF(py_funcname); return py_code; bad: Py_XDECREF(py_srcfile); Py_XDECREF(py_funcname); return NULL; } static void __Pyx_AddTraceback(const char *funcname, int c_line, int py_line, const char *filename) { PyCodeObject *py_code = 0; PyFrameObject *py_frame = 0; py_code = __pyx_find_code_object(c_line ? c_line : py_line); if (!py_code) { py_code = __Pyx_CreateCodeObjectForTraceback( funcname, c_line, py_line, filename); if (!py_code) goto bad; __pyx_insert_code_object(c_line ? c_line : py_line, py_code); } py_frame = PyFrame_New( PyThreadState_GET(), /*PyThreadState *tstate,*/ py_code, /*PyCodeObject *code,*/ __pyx_d, /*PyObject *globals,*/ 0 /*PyObject *locals*/ ); if (!py_frame) goto bad; py_frame->f_lineno = py_line; PyTraceBack_Here(py_frame); bad: Py_XDECREF(py_code); Py_XDECREF(py_frame); } #if PY_MAJOR_VERSION < 3 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags); if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags); if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags); PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); return -1; } static void __Pyx_ReleaseBuffer(Py_buffer *view) { PyObject *obj = view->obj; if (!obj) return; if (PyObject_CheckBuffer(obj)) { PyBuffer_Release(view); return; } if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; } Py_DECREF(obj); view->obj = NULL; } #endif /* MemviewSliceIsContig */ static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice mvs, char order, int ndim) { int i, index, step, start; Py_ssize_t itemsize = mvs.memview->view.itemsize; if (order == 'F') { step = 1; start = 0; } else { step = -1; start = ndim - 1; } for (i = 0; i < ndim; i++) { index = start + step * i; if (mvs.suboffsets[index] >= 0 || mvs.strides[index] != itemsize) return 0; itemsize *= mvs.shape[index]; } return 1; } /* OverlappingSlices */ static void __pyx_get_array_memory_extents(__Pyx_memviewslice *slice, void **out_start, void **out_end, int ndim, size_t itemsize) { char *start, *end; int i; start = end = slice->data; for (i = 0; i < ndim; i++) { Py_ssize_t stride = slice->strides[i]; Py_ssize_t extent = slice->shape[i]; if (extent == 0) { *out_start = *out_end = start; return; } else { if (stride > 0) end += stride * (extent - 1); else start += stride * (extent - 1); } } *out_start = start; *out_end = end + itemsize; } static int __pyx_slices_overlap(__Pyx_memviewslice *slice1, __Pyx_memviewslice *slice2, int ndim, size_t itemsize) { void *start1, *end1, *start2, *end2; __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize); __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize); return (start1 < end2) && (start2 < end1); } /* Capsule */ static CYTHON_INLINE PyObject * __pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig) { PyObject *cobj; #if PY_VERSION_HEX >= 0x02070000 cobj = PyCapsule_New(p, sig, NULL); #else cobj = PyCObject_FromVoidPtr(p, NULL); #endif return cobj; } /* CIntFromPyVerify */ #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) #define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) #define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ {\ func_type value = func_value;\ if (sizeof(target_type) < sizeof(func_type)) {\ if (unlikely(value != (func_type) (target_type) value)) {\ func_type zero = 0;\ if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ return (target_type) -1;\ if (is_unsigned && unlikely(value < zero))\ goto raise_neg_overflow;\ else\ goto raise_overflow;\ }\ }\ return (target_type) value;\ } /* CIntToPy */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint32_t(uint32_t value) { const uint32_t neg_one = (uint32_t) -1, const_zero = (uint32_t) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(uint32_t) < sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(uint32_t) <= sizeof(unsigned long)) { return PyLong_FromUnsignedLong((unsigned long) value); } else if (sizeof(uint32_t) <= sizeof(unsigned PY_LONG_LONG)) { return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); } } else { if (sizeof(uint32_t) <= sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(uint32_t) <= sizeof(PY_LONG_LONG)) { return PyLong_FromLongLong((PY_LONG_LONG) value); } } { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; return _PyLong_FromByteArray(bytes, sizeof(uint32_t), little, !is_unsigned); } } /* CIntToPy */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { const long neg_one = (long) -1, const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(long) < sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(long) <= sizeof(unsigned long)) { return PyLong_FromUnsignedLong((unsigned long) value); } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); } } else { if (sizeof(long) <= sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { return PyLong_FromLongLong((PY_LONG_LONG) value); } } { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; return _PyLong_FromByteArray(bytes, sizeof(long), little, !is_unsigned); } } /* None */ #if CYTHON_CCOMPLEX #ifdef __cplusplus static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { return ::std::complex< float >(x, y); } #else static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { return x + y*(__pyx_t_float_complex)_Complex_I; } #endif #else static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { __pyx_t_float_complex z; z.real = x; z.imag = y; return z; } #endif /* None */ #if CYTHON_CCOMPLEX #else static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) { return (a.real == b.real) && (a.imag == b.imag); } static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) { __pyx_t_float_complex z; z.real = a.real + b.real; z.imag = a.imag + b.imag; return z; } static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) { __pyx_t_float_complex z; z.real = a.real - b.real; z.imag = a.imag - b.imag; return z; } static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) { __pyx_t_float_complex z; z.real = a.real * b.real - a.imag * b.imag; z.imag = a.real * b.imag + a.imag * b.real; return z; } static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) { __pyx_t_float_complex z; float denom = b.real * b.real + b.imag * b.imag; z.real = (a.real * b.real + a.imag * b.imag) / denom; z.imag = (a.imag * b.real - a.real * b.imag) / denom; return z; } static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) { __pyx_t_float_complex z; z.real = -a.real; z.imag = -a.imag; return z; } static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) { return (a.real == 0) && (a.imag == 0); } static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) { __pyx_t_float_complex z; z.real = a.real; z.imag = -a.imag; return z; } #if 1 static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) { #if !defined(HAVE_HYPOT) || defined(_MSC_VER) return sqrtf(z.real*z.real + z.imag*z.imag); #else return hypotf(z.real, z.imag); #endif } static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) { __pyx_t_float_complex z; float r, lnr, theta, z_r, z_theta; if (b.imag == 0 && b.real == (int)b.real) { if (b.real < 0) { float denom = a.real * a.real + a.imag * a.imag; a.real = a.real / denom; a.imag = -a.imag / denom; b.real = -b.real; } switch ((int)b.real) { case 0: z.real = 1; z.imag = 0; return z; case 1: return a; case 2: z = __Pyx_c_prodf(a, a); return __Pyx_c_prodf(a, a); case 3: z = __Pyx_c_prodf(a, a); return __Pyx_c_prodf(z, a); case 4: z = __Pyx_c_prodf(a, a); return __Pyx_c_prodf(z, z); } } if (a.imag == 0) { if (a.real == 0) { return a; } r = a.real; theta = 0; } else { r = __Pyx_c_absf(a); theta = atan2f(a.imag, a.real); } lnr = logf(r); z_r = expf(lnr * b.real - theta * b.imag); z_theta = theta * b.real + lnr * b.imag; z.real = z_r * cosf(z_theta); z.imag = z_r * sinf(z_theta); return z; } #endif #endif /* None */ #if CYTHON_CCOMPLEX #ifdef __cplusplus static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { return ::std::complex< double >(x, y); } #else static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { return x + y*(__pyx_t_double_complex)_Complex_I; } #endif #else static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { __pyx_t_double_complex z; z.real = x; z.imag = y; return z; } #endif /* None */ #if CYTHON_CCOMPLEX #else static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) { return (a.real == b.real) && (a.imag == b.imag); } static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) { __pyx_t_double_complex z; z.real = a.real + b.real; z.imag = a.imag + b.imag; return z; } static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) { __pyx_t_double_complex z; z.real = a.real - b.real; z.imag = a.imag - b.imag; return z; } static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) { __pyx_t_double_complex z; z.real = a.real * b.real - a.imag * b.imag; z.imag = a.real * b.imag + a.imag * b.real; return z; } static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) { __pyx_t_double_complex z; double denom = b.real * b.real + b.imag * b.imag; z.real = (a.real * b.real + a.imag * b.imag) / denom; z.imag = (a.imag * b.real - a.real * b.imag) / denom; return z; } static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) { __pyx_t_double_complex z; z.real = -a.real; z.imag = -a.imag; return z; } static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) { return (a.real == 0) && (a.imag == 0); } static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) { __pyx_t_double_complex z; z.real = a.real; z.imag = -a.imag; return z; } #if 1 static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) { #if !defined(HAVE_HYPOT) || defined(_MSC_VER) return sqrt(z.real*z.real + z.imag*z.imag); #else return hypot(z.real, z.imag); #endif } static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) { __pyx_t_double_complex z; double r, lnr, theta, z_r, z_theta; if (b.imag == 0 && b.real == (int)b.real) { if (b.real < 0) { double denom = a.real * a.real + a.imag * a.imag; a.real = a.real / denom; a.imag = -a.imag / denom; b.real = -b.real; } switch ((int)b.real) { case 0: z.real = 1; z.imag = 0; return z; case 1: return a; case 2: z = __Pyx_c_prod(a, a); return __Pyx_c_prod(a, a); case 3: z = __Pyx_c_prod(a, a); return __Pyx_c_prod(z, a); case 4: z = __Pyx_c_prod(a, a); return __Pyx_c_prod(z, z); } } if (a.imag == 0) { if (a.real == 0) { return a; } r = a.real; theta = 0; } else { r = __Pyx_c_abs(a); theta = atan2(a.imag, a.real); } lnr = log(r); z_r = exp(lnr * b.real - theta * b.imag); z_theta = theta * b.real + lnr * b.imag; z.real = z_r * cos(z_theta); z.imag = z_r * sin(z_theta); return z; } #endif #endif /* CIntToPy */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { const int neg_one = (int) -1, const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(int) < sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(int) <= sizeof(unsigned long)) { return PyLong_FromUnsignedLong((unsigned long) value); } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); } } else { if (sizeof(int) <= sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { return PyLong_FromLongLong((PY_LONG_LONG) value); } } { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; return _PyLong_FromByteArray(bytes, sizeof(int), little, !is_unsigned); } } /* CIntToPy */ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value) { const enum NPY_TYPES neg_one = (enum NPY_TYPES) -1, const_zero = (enum NPY_TYPES) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof(enum NPY_TYPES) < sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned long)) { return PyLong_FromUnsignedLong((unsigned long) value); } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned PY_LONG_LONG)) { return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); } } else { if (sizeof(enum NPY_TYPES) <= sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof(enum NPY_TYPES) <= sizeof(PY_LONG_LONG)) { return PyLong_FromLongLong((PY_LONG_LONG) value); } } { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; return _PyLong_FromByteArray(bytes, sizeof(enum NPY_TYPES), little, !is_unsigned); } } /* MemviewSliceCopyTemplate */ static __Pyx_memviewslice __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, const char *mode, int ndim, size_t sizeof_dtype, int contig_flag, int dtype_is_object) { __Pyx_RefNannyDeclarations int i; __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } }; struct __pyx_memoryview_obj *from_memview = from_mvs->memview; Py_buffer *buf = &from_memview->view; PyObject *shape_tuple = NULL; PyObject *temp_int = NULL; struct __pyx_array_obj *array_obj = NULL; struct __pyx_memoryview_obj *memview_obj = NULL; __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0); for (i = 0; i < ndim; i++) { if (from_mvs->suboffsets[i] >= 0) { PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with " "indirect dimensions (axis %d)", i); goto fail; } } shape_tuple = PyTuple_New(ndim); if (unlikely(!shape_tuple)) { goto fail; } __Pyx_GOTREF(shape_tuple); for(i = 0; i < ndim; i++) { temp_int = PyInt_FromSsize_t(from_mvs->shape[i]); if(unlikely(!temp_int)) { goto fail; } else { PyTuple_SET_ITEM(shape_tuple, i, temp_int); temp_int = NULL; } } array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL); if (unlikely(!array_obj)) { goto fail; } __Pyx_GOTREF(array_obj); memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new( (PyObject *) array_obj, contig_flag, dtype_is_object, from_mvs->memview->typeinfo); if (unlikely(!memview_obj)) goto fail; if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0)) goto fail; if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim, dtype_is_object) < 0)) goto fail; goto no_fail; fail: __Pyx_XDECREF(new_mvs.memview); new_mvs.memview = NULL; new_mvs.data = NULL; no_fail: __Pyx_XDECREF(shape_tuple); __Pyx_XDECREF(temp_int); __Pyx_XDECREF(array_obj); __Pyx_RefNannyFinishContext(); return new_mvs; } /* CIntFromPy */ static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { const int neg_one = (int) -1, const_zero = (int) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { if (sizeof(int) < sizeof(long)) { __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { goto raise_neg_overflow; } return (int) val; } } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (int) 0; case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) case 2: if (8 * sizeof(int) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); } } break; case 3: if (8 * sizeof(int) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); } } break; case 4: if (8 * sizeof(int) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); } } break; } #endif #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } #else { int result = PyObject_RichCompareBool(x, Py_False, Py_LT); if (unlikely(result < 0)) return (int) -1; if (unlikely(result == 1)) goto raise_neg_overflow; } #endif if (sizeof(int) <= sizeof(unsigned long)) { __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) } } else { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (int) 0; case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) case -2: if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case 2: if (8 * sizeof(int) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case -3: if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case 3: if (8 * sizeof(int) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case -4: if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; case 4: if (8 * sizeof(int) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); } } break; } #endif if (sizeof(int) <= sizeof(long)) { __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) } } { #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) PyErr_SetString(PyExc_RuntimeError, "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); #else int val; PyObject *v = __Pyx_PyNumber_IntOrLong(x); #if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } #endif if (likely(v)) { int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; int ret = _PyLong_AsByteArray((PyLongObject *)v, bytes, sizeof(val), is_little, !is_unsigned); Py_DECREF(v); if (likely(!ret)) return val; } #endif return (int) -1; } } else { int val; PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); if (!tmp) return (int) -1; val = __Pyx_PyInt_As_int(tmp); Py_DECREF(tmp); return val; } raise_overflow: PyErr_SetString(PyExc_OverflowError, "value too large to convert to int"); return (int) -1; raise_neg_overflow: PyErr_SetString(PyExc_OverflowError, "can't convert negative value to int"); return (int) -1; } /* CIntFromPy */ static CYTHON_INLINE uint32_t __Pyx_PyInt_As_uint32_t(PyObject *x) { const uint32_t neg_one = (uint32_t) -1, const_zero = (uint32_t) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { if (sizeof(uint32_t) < sizeof(long)) { __PYX_VERIFY_RETURN_INT(uint32_t, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { goto raise_neg_overflow; } return (uint32_t) val; } } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (uint32_t) 0; case 1: __PYX_VERIFY_RETURN_INT(uint32_t, digit, digits[0]) case 2: if (8 * sizeof(uint32_t) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(uint32_t) >= 2 * PyLong_SHIFT) { return (uint32_t) (((((uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0])); } } break; case 3: if (8 * sizeof(uint32_t) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(uint32_t) >= 3 * PyLong_SHIFT) { return (uint32_t) (((((((uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0])); } } break; case 4: if (8 * sizeof(uint32_t) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(uint32_t) >= 4 * PyLong_SHIFT) { return (uint32_t) (((((((((uint32_t)digits[3]) << PyLong_SHIFT) | (uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0])); } } break; } #endif #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } #else { int result = PyObject_RichCompareBool(x, Py_False, Py_LT); if (unlikely(result < 0)) return (uint32_t) -1; if (unlikely(result == 1)) goto raise_neg_overflow; } #endif if (sizeof(uint32_t) <= sizeof(unsigned long)) { __PYX_VERIFY_RETURN_INT_EXC(uint32_t, unsigned long, PyLong_AsUnsignedLong(x)) } else if (sizeof(uint32_t) <= sizeof(unsigned PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(uint32_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) } } else { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (uint32_t) 0; case -1: __PYX_VERIFY_RETURN_INT(uint32_t, sdigit, (sdigit) (-(sdigit)digits[0])) case 1: __PYX_VERIFY_RETURN_INT(uint32_t, digit, +digits[0]) case -2: if (8 * sizeof(uint32_t) - 1 > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(uint32_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(uint32_t) - 1 > 2 * PyLong_SHIFT) { return (uint32_t) (((uint32_t)-1)*(((((uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0]))); } } break; case 2: if (8 * sizeof(uint32_t) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(uint32_t) - 1 > 2 * PyLong_SHIFT) { return (uint32_t) ((((((uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0]))); } } break; case -3: if (8 * sizeof(uint32_t) - 1 > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(uint32_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(uint32_t) - 1 > 3 * PyLong_SHIFT) { return (uint32_t) (((uint32_t)-1)*(((((((uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0]))); } } break; case 3: if (8 * sizeof(uint32_t) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(uint32_t) - 1 > 3 * PyLong_SHIFT) { return (uint32_t) ((((((((uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0]))); } } break; case -4: if (8 * sizeof(uint32_t) - 1 > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(uint32_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(uint32_t) - 1 > 4 * PyLong_SHIFT) { return (uint32_t) (((uint32_t)-1)*(((((((((uint32_t)digits[3]) << PyLong_SHIFT) | (uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0]))); } } break; case 4: if (8 * sizeof(uint32_t) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(uint32_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(uint32_t) - 1 > 4 * PyLong_SHIFT) { return (uint32_t) ((((((((((uint32_t)digits[3]) << PyLong_SHIFT) | (uint32_t)digits[2]) << PyLong_SHIFT) | (uint32_t)digits[1]) << PyLong_SHIFT) | (uint32_t)digits[0]))); } } break; } #endif if (sizeof(uint32_t) <= sizeof(long)) { __PYX_VERIFY_RETURN_INT_EXC(uint32_t, long, PyLong_AsLong(x)) } else if (sizeof(uint32_t) <= sizeof(PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(uint32_t, PY_LONG_LONG, PyLong_AsLongLong(x)) } } { #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) PyErr_SetString(PyExc_RuntimeError, "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); #else uint32_t val; PyObject *v = __Pyx_PyNumber_IntOrLong(x); #if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } #endif if (likely(v)) { int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; int ret = _PyLong_AsByteArray((PyLongObject *)v, bytes, sizeof(val), is_little, !is_unsigned); Py_DECREF(v); if (likely(!ret)) return val; } #endif return (uint32_t) -1; } } else { uint32_t val; PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); if (!tmp) return (uint32_t) -1; val = __Pyx_PyInt_As_uint32_t(tmp); Py_DECREF(tmp); return val; } raise_overflow: PyErr_SetString(PyExc_OverflowError, "value too large to convert to uint32_t"); return (uint32_t) -1; raise_neg_overflow: PyErr_SetString(PyExc_OverflowError, "can't convert negative value to uint32_t"); return (uint32_t) -1; } /* CIntFromPy */ static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) { const char neg_one = (char) -1, const_zero = (char) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { if (sizeof(char) < sizeof(long)) { __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { goto raise_neg_overflow; } return (char) val; } } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (char) 0; case 1: __PYX_VERIFY_RETURN_INT(char, digit, digits[0]) case 2: if (8 * sizeof(char) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(char) >= 2 * PyLong_SHIFT) { return (char) (((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); } } break; case 3: if (8 * sizeof(char) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(char) >= 3 * PyLong_SHIFT) { return (char) (((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); } } break; case 4: if (8 * sizeof(char) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(char) >= 4 * PyLong_SHIFT) { return (char) (((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0])); } } break; } #endif #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } #else { int result = PyObject_RichCompareBool(x, Py_False, Py_LT); if (unlikely(result < 0)) return (char) -1; if (unlikely(result == 1)) goto raise_neg_overflow; } #endif if (sizeof(char) <= sizeof(unsigned long)) { __PYX_VERIFY_RETURN_INT_EXC(char, unsigned long, PyLong_AsUnsignedLong(x)) } else if (sizeof(char) <= sizeof(unsigned PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(char, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) } } else { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (char) 0; case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, (sdigit) (-(sdigit)digits[0])) case 1: __PYX_VERIFY_RETURN_INT(char, digit, +digits[0]) case -2: if (8 * sizeof(char) - 1 > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(char) - 1 > 2 * PyLong_SHIFT) { return (char) (((char)-1)*(((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); } } break; case 2: if (8 * sizeof(char) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(char) - 1 > 2 * PyLong_SHIFT) { return (char) ((((((char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); } } break; case -3: if (8 * sizeof(char) - 1 > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(char) - 1 > 3 * PyLong_SHIFT) { return (char) (((char)-1)*(((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); } } break; case 3: if (8 * sizeof(char) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(char) - 1 > 3 * PyLong_SHIFT) { return (char) ((((((((char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); } } break; case -4: if (8 * sizeof(char) - 1 > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(char, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(char) - 1 > 4 * PyLong_SHIFT) { return (char) (((char)-1)*(((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); } } break; case 4: if (8 * sizeof(char) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(char, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(char) - 1 > 4 * PyLong_SHIFT) { return (char) ((((((((((char)digits[3]) << PyLong_SHIFT) | (char)digits[2]) << PyLong_SHIFT) | (char)digits[1]) << PyLong_SHIFT) | (char)digits[0]))); } } break; } #endif if (sizeof(char) <= sizeof(long)) { __PYX_VERIFY_RETURN_INT_EXC(char, long, PyLong_AsLong(x)) } else if (sizeof(char) <= sizeof(PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(char, PY_LONG_LONG, PyLong_AsLongLong(x)) } } { #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) PyErr_SetString(PyExc_RuntimeError, "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); #else char val; PyObject *v = __Pyx_PyNumber_IntOrLong(x); #if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } #endif if (likely(v)) { int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; int ret = _PyLong_AsByteArray((PyLongObject *)v, bytes, sizeof(val), is_little, !is_unsigned); Py_DECREF(v); if (likely(!ret)) return val; } #endif return (char) -1; } } else { char val; PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); if (!tmp) return (char) -1; val = __Pyx_PyInt_As_char(tmp); Py_DECREF(tmp); return val; } raise_overflow: PyErr_SetString(PyExc_OverflowError, "value too large to convert to char"); return (char) -1; raise_neg_overflow: PyErr_SetString(PyExc_OverflowError, "can't convert negative value to char"); return (char) -1; } /* CIntFromPy */ static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { const long neg_one = (long) -1, const_zero = (long) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { if (sizeof(long) < sizeof(long)) { __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { goto raise_neg_overflow; } return (long) val; } } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (long) 0; case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) case 2: if (8 * sizeof(long) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); } } break; case 3: if (8 * sizeof(long) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); } } break; case 4: if (8 * sizeof(long) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); } } break; } #endif #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } #else { int result = PyObject_RichCompareBool(x, Py_False, Py_LT); if (unlikely(result < 0)) return (long) -1; if (unlikely(result == 1)) goto raise_neg_overflow; } #endif if (sizeof(long) <= sizeof(unsigned long)) { __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) } } else { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return (long) 0; case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) case -2: if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case 2: if (8 * sizeof(long) > 1 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case -3: if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case 3: if (8 * sizeof(long) > 2 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case -4: if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; case 4: if (8 * sizeof(long) > 3 * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); } } break; } #endif if (sizeof(long) <= sizeof(long)) { __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) } } { #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) PyErr_SetString(PyExc_RuntimeError, "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); #else long val; PyObject *v = __Pyx_PyNumber_IntOrLong(x); #if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } #endif if (likely(v)) { int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; int ret = _PyLong_AsByteArray((PyLongObject *)v, bytes, sizeof(val), is_little, !is_unsigned); Py_DECREF(v); if (likely(!ret)) return val; } #endif return (long) -1; } } else { long val; PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); if (!tmp) return (long) -1; val = __Pyx_PyInt_As_long(tmp); Py_DECREF(tmp); return val; } raise_overflow: PyErr_SetString(PyExc_OverflowError, "value too large to convert to long"); return (long) -1; raise_neg_overflow: PyErr_SetString(PyExc_OverflowError, "can't convert negative value to long"); return (long) -1; } /* TypeInfoCompare */ static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b) { int i; if (!a || !b) return 0; if (a == b) return 1; if (a->size != b->size || a->typegroup != b->typegroup || a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) { if (a->typegroup == 'H' || b->typegroup == 'H') { return a->size == b->size; } else { return 0; } } if (a->ndim) { for (i = 0; i < a->ndim; i++) if (a->arraysize[i] != b->arraysize[i]) return 0; } if (a->typegroup == 'S') { if (a->flags != b->flags) return 0; if (a->fields || b->fields) { if (!(a->fields && b->fields)) return 0; for (i = 0; a->fields[i].type && b->fields[i].type; i++) { __Pyx_StructField *field_a = a->fields + i; __Pyx_StructField *field_b = b->fields + i; if (field_a->offset != field_b->offset || !__pyx_typeinfo_cmp(field_a->type, field_b->type)) return 0; } return !a->fields[i].type && !b->fields[i].type; } } return 1; } /* MemviewSliceValidateAndInit */ static int __pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec) { if (buf->shape[dim] <= 1) return 1; if (buf->strides) { if (spec & __Pyx_MEMVIEW_CONTIG) { if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) { if (buf->strides[dim] != sizeof(void *)) { PyErr_Format(PyExc_ValueError, "Buffer is not indirectly contiguous " "in dimension %d.", dim); goto fail; } } else if (buf->strides[dim] != buf->itemsize) { PyErr_SetString(PyExc_ValueError, "Buffer and memoryview are not contiguous " "in the same dimension."); goto fail; } } if (spec & __Pyx_MEMVIEW_FOLLOW) { Py_ssize_t stride = buf->strides[dim]; if (stride < 0) stride = -stride; if (stride < buf->itemsize) { PyErr_SetString(PyExc_ValueError, "Buffer and memoryview are not contiguous " "in the same dimension."); goto fail; } } } else { if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) { PyErr_Format(PyExc_ValueError, "C-contiguous buffer is not contiguous in " "dimension %d", dim); goto fail; } else if (spec & (__Pyx_MEMVIEW_PTR)) { PyErr_Format(PyExc_ValueError, "C-contiguous buffer is not indirect in " "dimension %d", dim); goto fail; } else if (buf->suboffsets) { PyErr_SetString(PyExc_ValueError, "Buffer exposes suboffsets but no strides"); goto fail; } } return 1; fail: return 0; } static int __pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec) { if (spec & __Pyx_MEMVIEW_DIRECT) { if (buf->suboffsets && buf->suboffsets[dim] >= 0) { PyErr_Format(PyExc_ValueError, "Buffer not compatible with direct access " "in dimension %d.", dim); goto fail; } } if (spec & __Pyx_MEMVIEW_PTR) { if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) { PyErr_Format(PyExc_ValueError, "Buffer is not indirectly accessible " "in dimension %d.", dim); goto fail; } } return 1; fail: return 0; } static int __pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag) { int i; if (c_or_f_flag & __Pyx_IS_F_CONTIG) { Py_ssize_t stride = 1; for (i = 0; i < ndim; i++) { if (stride * buf->itemsize != buf->strides[i] && buf->shape[i] > 1) { PyErr_SetString(PyExc_ValueError, "Buffer not fortran contiguous."); goto fail; } stride = stride * buf->shape[i]; } } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) { Py_ssize_t stride = 1; for (i = ndim - 1; i >- 1; i--) { if (stride * buf->itemsize != buf->strides[i] && buf->shape[i] > 1) { PyErr_SetString(PyExc_ValueError, "Buffer not C contiguous."); goto fail; } stride = stride * buf->shape[i]; } } return 1; fail: return 0; } static int __Pyx_ValidateAndInit_memviewslice( int *axes_specs, int c_or_f_flag, int buf_flags, int ndim, __Pyx_TypeInfo *dtype, __Pyx_BufFmt_StackElem stack[], __Pyx_memviewslice *memviewslice, PyObject *original_obj) { struct __pyx_memoryview_obj *memview, *new_memview; __Pyx_RefNannyDeclarations Py_buffer *buf; int i, spec = 0, retval = -1; __Pyx_BufFmt_Context ctx; int from_memoryview = __pyx_memoryview_check(original_obj); __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0); if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *) original_obj)->typeinfo)) { memview = (struct __pyx_memoryview_obj *) original_obj; new_memview = NULL; } else { memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new( original_obj, buf_flags, 0, dtype); new_memview = memview; if (unlikely(!memview)) goto fail; } buf = &memview->view; if (buf->ndim != ndim) { PyErr_Format(PyExc_ValueError, "Buffer has wrong number of dimensions (expected %d, got %d)", ndim, buf->ndim); goto fail; } if (new_memview) { __Pyx_BufFmt_Init(&ctx, stack, dtype); if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; } if ((unsigned) buf->itemsize != dtype->size) { PyErr_Format(PyExc_ValueError, "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) " "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)", buf->itemsize, (buf->itemsize > 1) ? "s" : "", dtype->name, dtype->size, (dtype->size > 1) ? "s" : ""); goto fail; } for (i = 0; i < ndim; i++) { spec = axes_specs[i]; if (!__pyx_check_strides(buf, i, ndim, spec)) goto fail; if (!__pyx_check_suboffsets(buf, i, ndim, spec)) goto fail; } if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag)) goto fail; if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice, new_memview != NULL) == -1)) { goto fail; } retval = 0; goto no_fail; fail: Py_XDECREF(new_memview); retval = -1; no_fail: __Pyx_RefNannyFinishContext(); return retval; } /* ObjectToMemviewSlice */ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn_uint64_t(PyObject *obj) { __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; __Pyx_BufFmt_StackElem stack[1]; int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) }; int retcode; if (obj == Py_None) { result.memview = (struct __pyx_memoryview_obj *) Py_None; return result; } retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0, PyBUF_RECORDS, 1, &__Pyx_TypeInfo_nn_uint64_t, stack, &result, obj); if (unlikely(retcode == -1)) goto __pyx_fail; return result; __pyx_fail: result.memview = NULL; result.data = NULL; return result; } /* ObjectToMemviewSlice */ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn_uint32_t(PyObject *obj) { __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } }; __Pyx_BufFmt_StackElem stack[1]; int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) }; int retcode; if (obj == Py_None) { result.memview = (struct __pyx_memoryview_obj *) Py_None; return result; } retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0, PyBUF_RECORDS, 1, &__Pyx_TypeInfo_nn_uint32_t, stack, &result, obj); if (unlikely(retcode == -1)) goto __pyx_fail; return result; __pyx_fail: result.memview = NULL; result.data = NULL; return result; } /* CheckBinaryVersion */ static int __Pyx_check_binary_version(void) { char ctversion[4], rtversion[4]; PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { char message[200]; PyOS_snprintf(message, sizeof(message), "compiletime version %s of module '%.100s' " "does not match runtime version %s", ctversion, __Pyx_MODULE_NAME, rtversion); return PyErr_WarnEx(NULL, message, 1); } return 0; } /* ModuleImport */ #ifndef __PYX_HAVE_RT_ImportModule #define __PYX_HAVE_RT_ImportModule static PyObject *__Pyx_ImportModule(const char *name) { PyObject *py_name = 0; PyObject *py_module = 0; py_name = __Pyx_PyIdentifier_FromString(name); if (!py_name) goto bad; py_module = PyImport_Import(py_name); Py_DECREF(py_name); return py_module; bad: Py_XDECREF(py_name); return 0; } #endif /* TypeImport */ #ifndef __PYX_HAVE_RT_ImportType #define __PYX_HAVE_RT_ImportType static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict) { PyObject *py_module = 0; PyObject *result = 0; PyObject *py_name = 0; char warning[200]; Py_ssize_t basicsize; #ifdef Py_LIMITED_API PyObject *py_basicsize; #endif py_module = __Pyx_ImportModule(module_name); if (!py_module) goto bad; py_name = __Pyx_PyIdentifier_FromString(class_name); if (!py_name) goto bad; result = PyObject_GetAttr(py_module, py_name); Py_DECREF(py_name); py_name = 0; Py_DECREF(py_module); py_module = 0; if (!result) goto bad; if (!PyType_Check(result)) { PyErr_Format(PyExc_TypeError, "%.200s.%.200s is not a type object", module_name, class_name); goto bad; } #ifndef Py_LIMITED_API basicsize = ((PyTypeObject *)result)->tp_basicsize; #else py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); if (!py_basicsize) goto bad; basicsize = PyLong_AsSsize_t(py_basicsize); Py_DECREF(py_basicsize); py_basicsize = 0; if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) goto bad; #endif if (!strict && (size_t)basicsize > size) { PyOS_snprintf(warning, sizeof(warning), "%s.%s size changed, may indicate binary incompatibility. Expected %zd, got %zd", module_name, class_name, basicsize, size); if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; } else if ((size_t)basicsize != size) { PyErr_Format(PyExc_ValueError, "%.200s.%.200s has the wrong size, try recompiling. Expected %zd, got %zd", module_name, class_name, basicsize, size); goto bad; } return (PyTypeObject *)result; bad: Py_XDECREF(py_module); Py_XDECREF(result); return NULL; } #endif /* InitStrings */ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { #if PY_MAJOR_VERSION < 3 if (t->is_unicode) { *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); } else if (t->intern) { *t->p = PyString_InternFromString(t->s); } else { *t->p = PyString_FromStringAndSize(t->s, t->n - 1); } #else if (t->is_unicode | t->is_str) { if (t->intern) { *t->p = PyUnicode_InternFromString(t->s); } else if (t->encoding) { *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); } else { *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); } } else { *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); } #endif if (!*t->p) return -1; ++t; } return 0; } static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); } static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) { Py_ssize_t ignore; return __Pyx_PyObject_AsStringAndSize(o, &ignore); } static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { #if CYTHON_COMPILING_IN_CPYTHON && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) if ( #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII __Pyx_sys_getdefaultencoding_not_ascii && #endif PyUnicode_Check(o)) { #if PY_VERSION_HEX < 0x03030000 char* defenc_c; PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); if (!defenc) return NULL; defenc_c = PyBytes_AS_STRING(defenc); #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII { char* end = defenc_c + PyBytes_GET_SIZE(defenc); char* c; for (c = defenc_c; c < end; c++) { if ((unsigned char) (*c) >= 128) { PyUnicode_AsASCIIString(o); return NULL; } } } #endif *length = PyBytes_GET_SIZE(defenc); return defenc_c; #else if (__Pyx_PyUnicode_READY(o) == -1) return NULL; #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII if (PyUnicode_IS_ASCII(o)) { *length = PyUnicode_GET_LENGTH(o); return PyUnicode_AsUTF8(o); } else { PyUnicode_AsASCIIString(o); return NULL; } #else return PyUnicode_AsUTF8AndSize(o, length); #endif #endif } else #endif #if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) if (PyByteArray_Check(o)) { *length = PyByteArray_GET_SIZE(o); return PyByteArray_AS_STRING(o); } else #endif { char* result; int r = PyBytes_AsStringAndSize(o, &result, length); if (unlikely(r < 0)) { return NULL; } else { return result; } } } static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { int is_true = x == Py_True; if (is_true | (x == Py_False) | (x == Py_None)) return is_true; else return PyObject_IsTrue(x); } static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { PyNumberMethods *m; const char *name = NULL; PyObject *res = NULL; #if PY_MAJOR_VERSION < 3 if (PyInt_Check(x) || PyLong_Check(x)) #else if (PyLong_Check(x)) #endif return __Pyx_NewRef(x); m = Py_TYPE(x)->tp_as_number; #if PY_MAJOR_VERSION < 3 if (m && m->nb_int) { name = "int"; res = PyNumber_Int(x); } else if (m && m->nb_long) { name = "long"; res = PyNumber_Long(x); } #else if (m && m->nb_int) { name = "int"; res = PyNumber_Long(x); } #endif if (res) { #if PY_MAJOR_VERSION < 3 if (!PyInt_Check(res) && !PyLong_Check(res)) { #else if (!PyLong_Check(res)) { #endif PyErr_Format(PyExc_TypeError, "__%.4s__ returned non-%.4s (type %.200s)", name, name, Py_TYPE(res)->tp_name); Py_DECREF(res); return NULL; } } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "an integer is required"); } return res; } static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { Py_ssize_t ival; PyObject *x; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_CheckExact(b))) { if (sizeof(Py_ssize_t) >= sizeof(long)) return PyInt_AS_LONG(b); else return PyInt_AsSsize_t(x); } #endif if (likely(PyLong_CheckExact(b))) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)b)->ob_digit; const Py_ssize_t size = Py_SIZE(b); if (likely(__Pyx_sst_abs(size) <= 1)) { ival = likely(size) ? digits[0] : 0; if (size == -1) ival = -ival; return ival; } else { switch (size) { case 2: if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case -2: if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case 3: if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case -3: if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case 4: if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; case -4: if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); } break; } } #endif return PyLong_AsSsize_t(b); } x = PyNumber_Index(b); if (!x) return -1; ival = PyInt_AsSsize_t(x); Py_DECREF(x); return ival; } static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { return PyInt_FromSize_t(ival); } #endif /* Py_PYTHON_H */ ================================================ FILE: llm-train/megatron/gpt2/data/download.py ================================================ # Code taken in large part from https://github.com/jcpeterson/openwebtext from __future__ import print_function import io import time import json import tarfile import warnings import argparse import os import os.path as op from glob import glob from hashlib import sha256 import multiprocessing as mpl from tqdm import tqdm import sqlite3 import tldextract # for backward compatibility from six.moves.urllib.request import urlopen from utils import mkdir, chunks, extract_month, linecount from scrapers import bs4_scraper, newspaper_scraper, raw_scraper parser = argparse.ArgumentParser() parser.add_argument("url_file", type=str) parser.add_argument( "--save_uncompressed", action="store_true", default=True, #default=False, help="whether to save the raw txt files to disk", ) parser.add_argument( "--output_dir", type=str, default="scraped", help="which folder in the working directory to use for output", ) parser.add_argument( "--n_procs", type=int, default=10, help="how many processes (cores) to use for parallel scraping", ) parser.add_argument( "--timeout", type=int, default=-1, help="maximum scrape time for a single URL; -1 means no limit", ) parser.add_argument( "--max_urls", type=int, default=-1, help="maximum # of URLs to scrape; mostly for debugging", ) parser.add_argument( "--chunk_size", type=int, default=100, help="how many URLs to scrape before saving to archive", ) parser.add_argument( "--scraper", type=str, default="newspaper", choices=["raw", "bs4", "newspaper"], help="which text/content scraper to use; raw is html", ) parser.add_argument( "--compress", action="store_true", default=False, help="whether to output scraped content as compressed archives", ) parser.add_argument( "--compress_fmt", type=str, default="xz", choices=["xz", "bz2", "gz"], help="which archive format to use", ) parser.add_argument( "--scraper_memoize", action="store_true", default=False, help="whether to use cache for newspaper", ) parser.add_argument( "--show_warnings", action="store_true", default=False, #default=True, help="whether to show warnings in general during scraping", ) parser.add_argument( "--sqlite_meta", action="store_true", default=False, #default=True, help="whether to use sqlite for storing meta. if false, json will be used instead", ) args = parser.parse_args() if not args.show_warnings: # avoid lots of datetime warnings warnings.filterwarnings("ignore") def load_urls(fh, max_urls=-1): url_entries = enumerate(fh) if max_urls != -1: url_entries = list(url_entries)[:max_urls] return url_entries def vet_link(link): # check if server responds with non-200 status code or link points to a # non-html file link_type, link_status = "", -1 try: info = urlopen(link) link_type = info.headers["Content-Type"] link_status = info.status except: pass # we want "text/html" only! is_good_link = False if "text/html" in link_type and link_status == 200: is_good_link = True return is_good_link, link_type def download( url_entry, scraper=args.scraper, save_uncompressed=args.save_uncompressed, memoize=args.scraper_memoize, arch_meta=not args.sqlite_meta ): uid, url = url_entry url = url.strip() fid = "{:07d}-{}".format(uid, sha256(url.encode()).hexdigest()) data_dir = mkdir(op.join(args.output_dir, "data")) text_fp = op.join(data_dir, "{}.txt".format(fid)) if arch_meta: meta_dir = mkdir(op.join(args.output_dir, "meta")) meta_fp = op.join(meta_dir, "{}.json".format(fid)) # already downloaded! if op.exists(text_fp): return # is_good_link, link_type = vet_link(url) # if not is_good_link: # return if scraper == "bs4": scrape = bs4_scraper elif scraper == "newspaper": scrape = newspaper_scraper elif scraper == "raw": scrape = raw_scraper text, meta = scrape(url, memoize) ext = tldextract.extract(url) domain = '.'.join([x for x in ext if x]) meta["domain"] = domain if text is None or text.strip() == "": return ("", meta, fid, uid) if save_uncompressed: with open(text_fp, "w") as out: out.write(text) if arch_meta: with open(meta_fp, "w") as out: json.dump(meta, out) return (text, meta, fid, uid) def archive_chunk(cid, cdata, out_dir, fmt, arch_meta): mkdir(out_dir) texts, metas, fids, uids = zip(*cdata) data_tar = op.join(out_dir, "{}_data.{}".format(cid, fmt)) if arch_meta: meta_tar = op.join(out_dir, "{}_meta.{}".format(cid, fmt)) tar_fps, texts, exts = [data_tar, meta_tar], [texts, metas], ["txt", "json"] else: tar_fps, texts, exts = [data_tar], [texts], ["txt"] doc_count = 0 docs_counted = False for tar_fp, txts, ext in zip(tar_fps, texts, exts): with tarfile.open(tar_fp, "w:" + fmt) as tar: for f, fid in zip(txts, fids): if f == "": continue else: if not docs_counted: doc_count += 1 if ext == "json": f = json.dumps(f) f = f.encode("utf-8") t = tarfile.TarInfo("{}.{}".format(fid, ext)) t.size = len(f) tar.addfile(t, io.BytesIO(f)) docs_counted = True return doc_count def load_state(url_file): ckptfile = url_file + '.ckpt' if op.exists(ckptfile): with open(ckptfile) as fp: r = fp.read() if r == '': return 0 else: return int(r) else: return 0 def save_state(url_file, cid): ckptfile = url_file + '.ckpt' with open(ckptfile, 'w') as fp: fp.write(str(cid)) def sqlite_conn(): conn = sqlite3.connect('metadata.db') conn.execute(''' CREATE TABLE IF NOT EXISTS metadata ( fid char(64) not null primary key, url varchar(2048) not null, domain varchar(255) not null, word_count int null, elapsed int null, scraper varchar(255) not null, success boolean not null ); ''') conn.execute(''' CREATE INDEX IF NOT EXISTS ix_meta_url ON metadata(url); ''') conn.execute(''' CREATE INDEX IF NOT EXISTS ix_meta_domain ON metadata(domain); ''') return conn if __name__ == "__main__": if args.sqlite_meta: conn = sqlite_conn() cur = conn.cursor() start_elem = load_state(args.url_file) start_chnk = start_elem // args.chunk_size # URLs we haven't scraped yet (if first run, all URLs in file) with open(args.url_file) as fh: url_entries = load_urls(fh, args.max_urls) pool = mpl.Pool(args.n_procs) total = linecount(args.url_file)//args.chunk_size print('Total chunks: ', total) chunk_iterator = tqdm(enumerate(chunks(url_entries, args.chunk_size, start_elem)), total=total) # display already-downloaded chunks on progress bar chunk_iterator.update(start_chnk) # process one "chunk" of args.chunk_size URLs at a time for i, chunk in chunk_iterator: cid = start_chnk + i + 1 if cid == 100: break tqdm.write("Downloading chunk {}".format(cid)) t1 = time.time() if args.timeout > 0: # imap as iterator allows .next() w/ timeout. # ordered version doesn't seem to work correctly. # for some reason, you CANNOT track j or chunk[j] in the loop, # so don't add anything else to the loop below! # confusingly, chunksize below is unrelated to our chunk_size chunk_iter = pool.imap_unordered(download, chunk, chunksize=1) cdata = [] for j in range(len(chunk)): try: result = chunk_iter.next(timeout=args.timeout) cdata.append(result) except mpl.TimeoutError: tqdm.write(" --- Timeout Error --- ") else: cdata = list(pool.imap(download, chunk, chunksize=1)) tqdm.write("{} / {} downloads timed out".format(len(chunk) - len(cdata), len(chunk))) tqdm.write("Chunk time: {} seconds".format(time.time() - t1)) # write metadata to sqlite if args.sqlite_meta: for text, meta, fid, _ in filter(lambda x: x, cdata): if text: params = ( fid, meta["url"], meta["domain"], meta["elapsed"], meta["word_count"], meta["scraper"], True ) else: params = ( fid, meta["url"], meta["domain"], None, None, meta["scraper"], False ) cur.execute("insert or ignore into metadata (fid, url, domain, elapsed, word_count, scraper, success) values (?, ?, ?, ?, ?, ?, ?)", params) conn.commit() # archive and save this chunk to file if args.compress: tqdm.write("Compressing...") t2 = time.time() count = archive_chunk(cid, cdata, args.output_dir, args.compress_fmt, not args.sqlite_meta) tqdm.write("Archive created in {} seconds".format(time.time() - t2)) tqdm.write("{} out of {} URLs yielded content\n".format(len(list(filter(lambda x: x and x[0], cdata))), len(chunk))) save_state(args.url_file, cid * args.chunk_size) print("Done!") ================================================ FILE: llm-train/megatron/gpt2/data/file_utils.py ================================================ """ Utilities for working with the local dataset cache. This file is adapted from the AllenNLP library at https://github.com/allenai/allennlp Copyright by the AllenNLP authors. """ from __future__ import (absolute_import, division, print_function, unicode_literals) import json import logging import os import shutil import tempfile from functools import wraps from hashlib import sha256 import sys from io import open import boto3 import requests from botocore.exceptions import ClientError from tqdm import tqdm try: from urllib.parse import urlparse except ImportError: from urlparse import urlparse try: from pathlib import Path PYTORCH_PRETRAINED_BERT_CACHE = Path(os.getenv('PYTORCH_PRETRAINED_BERT_CACHE', Path.home() / '.pytorch_pretrained_bert')) except (AttributeError, ImportError): PYTORCH_PRETRAINED_BERT_CACHE = os.getenv('PYTORCH_PRETRAINED_BERT_CACHE', os.path.join(os.path.expanduser("~"), '.pytorch_pretrained_bert')) logger = logging.getLogger(__name__) # pylint: disable=invalid-name def url_to_filename(url, etag=None): """ Convert `url` into a hashed filename in a repeatable way. If `etag` is specified, append its hash to the url's, delimited by a period. """ url_bytes = url.encode('utf-8') url_hash = sha256(url_bytes) filename = url_hash.hexdigest() if etag: etag_bytes = etag.encode('utf-8') etag_hash = sha256(etag_bytes) filename += '.' + etag_hash.hexdigest() return filename def filename_to_url(filename, cache_dir=None): """ Return the url and etag (which may be ``None``) stored for `filename`. Raise ``EnvironmentError`` if `filename` or its stored metadata do not exist. """ if cache_dir is None: cache_dir = PYTORCH_PRETRAINED_BERT_CACHE if sys.version_info[0] == 3 and isinstance(cache_dir, Path): cache_dir = str(cache_dir) cache_path = os.path.join(cache_dir, filename) if not os.path.exists(cache_path): raise EnvironmentError("file {} not found".format(cache_path)) meta_path = cache_path + '.json' if not os.path.exists(meta_path): raise EnvironmentError("file {} not found".format(meta_path)) with open(meta_path, encoding="utf-8") as meta_file: metadata = json.load(meta_file) url = metadata['url'] etag = metadata['etag'] return url, etag def cached_path(url_or_filename, cache_dir=None): """ Given something that might be a URL (or might be a local path), determine which. If it's a URL, download the file and cache it, and return the path to the cached file. If it's already a local path, make sure the file exists and then return the path. """ if cache_dir is None: cache_dir = PYTORCH_PRETRAINED_BERT_CACHE if sys.version_info[0] == 3 and isinstance(url_or_filename, Path): url_or_filename = str(url_or_filename) if sys.version_info[0] == 3 and isinstance(cache_dir, Path): cache_dir = str(cache_dir) parsed = urlparse(url_or_filename) if parsed.scheme in ('http', 'https', 's3'): # URL, so get it from the cache (downloading if necessary) return get_from_cache(url_or_filename, cache_dir) elif os.path.exists(url_or_filename): # File, and it exists. return url_or_filename elif parsed.scheme == '': # File, but it doesn't exist. raise EnvironmentError("file {} not found".format(url_or_filename)) else: # Something unknown raise ValueError("unable to parse {} as a URL or as a local path".format(url_or_filename)) def split_s3_path(url): """Split a full s3 path into the bucket name and path.""" parsed = urlparse(url) if not parsed.netloc or not parsed.path: raise ValueError("bad s3 path {}".format(url)) bucket_name = parsed.netloc s3_path = parsed.path # Remove '/' at beginning of path. if s3_path.startswith("/"): s3_path = s3_path[1:] return bucket_name, s3_path def s3_request(func): """ Wrapper function for s3 requests in order to create more helpful error messages. """ @wraps(func) def wrapper(url, *args, **kwargs): try: return func(url, *args, **kwargs) except ClientError as exc: if int(exc.response["Error"]["Code"]) == 404: raise EnvironmentError("file {} not found".format(url)) else: raise return wrapper @s3_request def s3_etag(url): """Check ETag on S3 object.""" s3_resource = boto3.resource("s3") bucket_name, s3_path = split_s3_path(url) s3_object = s3_resource.Object(bucket_name, s3_path) return s3_object.e_tag @s3_request def s3_get(url, temp_file): """Pull a file directly from S3.""" s3_resource = boto3.resource("s3") bucket_name, s3_path = split_s3_path(url) s3_resource.Bucket(bucket_name).download_fileobj(s3_path, temp_file) def http_get(url, temp_file): req = requests.get(url, stream=True) content_length = req.headers.get('Content-Length') total = int(content_length) if content_length is not None else None progress = tqdm(unit="B", total=total) for chunk in req.iter_content(chunk_size=1024): if chunk: # filter out keep-alive new chunks progress.update(len(chunk)) temp_file.write(chunk) progress.close() def get_from_cache(url, cache_dir=None): """ Given a URL, look for the corresponding dataset in the local cache. If it's not there, download it. Then return the path to the cached file. """ if cache_dir is None: cache_dir = PYTORCH_PRETRAINED_BERT_CACHE if sys.version_info[0] == 3 and isinstance(cache_dir, Path): cache_dir = str(cache_dir) if not os.path.exists(cache_dir): os.makedirs(cache_dir) # Get eTag to add to filename, if it exists. if url.startswith("s3://"): etag = s3_etag(url) else: response = requests.head(url, allow_redirects=True) if response.status_code != 200: raise IOError("HEAD request failed for url {} with status code {}" .format(url, response.status_code)) etag = response.headers.get("ETag") filename = url_to_filename(url, etag) # get cache path to put the file cache_path = os.path.join(cache_dir, filename) if not os.path.exists(cache_path): # Download to temporary file, then copy to cache dir once finished. # Otherwise you get corrupt cache entries if the download gets interrupted. with tempfile.NamedTemporaryFile() as temp_file: logger.info("%s not found in cache, downloading to %s", url, temp_file.name) # GET file object if url.startswith("s3://"): s3_get(url, temp_file) else: http_get(url, temp_file) # we are copying the file before closing it, so flush to avoid truncation temp_file.flush() # shutil.copyfileobj() starts at the current position, so go to the start temp_file.seek(0) logger.info("copying %s to cache at %s", temp_file.name, cache_path) with open(cache_path, 'wb') as cache_file: shutil.copyfileobj(temp_file, cache_file) logger.info("creating metadata file for %s", cache_path) meta = {'url': url, 'etag': etag} meta_path = cache_path + '.json' with open(meta_path, 'w', encoding="utf-8") as meta_file: json.dump(meta, meta_file) logger.info("removing temp file %s", temp_file.name) return cache_path def read_set_from_file(filename): ''' Extract a de-duped collection (set) of text from a file. Expected file format is one item per line. ''' collection = set() with open(filename, 'r', encoding='utf-8') as file_: for line in file_: collection.add(line.rstrip()) return collection def get_file_extension(path, dot=True, lower=True): ext = os.path.splitext(path)[1] ext = ext if dot else ext[1:] return ext.lower() if lower else ext ================================================ FILE: llm-train/megatron/gpt2/data/merge_data.py ================================================ import glob import sys import json import argparse if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument("--data_path", type=str, default=".", help="path where all the json files are located") parser.add_argument("--output_file", type=str, default="merged_output.json", help="filename where the merged json should go") args = parser.parse_args() data_path = args.data_path out_file = args.output_file text_files = glob.glob(data_path + '/*.txt') counter = 0 with open(out_file, 'w') as outfile: for fname in text_files: counter += 1 if counter % 1024 == 0: print("Merging at ", counter, flush=True) with open(fname, 'r') as infile: for row in infile: tmp = {} tmp['text'] = row outfile.write(json.dumps(tmp)) outfile.write('\n') print("Merged file", out_file, flush=True) ================================================ FILE: llm-train/megatron/gpt2/gpt-data-preprocess.md ================================================ ## 数据下载 修改`lsh/cMinhash.cpp`文件: - 将exc_type改为curexc_type - 将exc_value改为curexc_value - 将exc_traceback改为curexc_traceback ``` > python setup.py install running install /usr/local/lib/python3.8/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools. warnings.warn( /usr/local/lib/python3.8/dist-packages/setuptools/command/easy_install.py:144: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools. warnings.warn( running bdist_egg running egg_info writing lsh.egg-info/PKG-INFO writing dependency_links to lsh.egg-info/dependency_links.txt writing requirements to lsh.egg-info/requires.txt writing top-level names to lsh.egg-info/top_level.txt reading manifest file 'lsh.egg-info/SOURCES.txt' adding license file 'LICENSE' writing manifest file 'lsh.egg-info/SOURCES.txt' installing library code to build/bdist.linux-x86_64/egg running install_lib running build_py running build_ext building 'lsh.cMinhash' extension x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/local/lib/python3.8/dist-packages/numpy/core/include -I/usr/include/python3.8 -c lsh/cMinhash.cpp -o build/temp.linux-x86_64-3.8/lsh/cMinhash.o In file included from /usr/local/lib/python3.8/dist-packages/numpy/core/include/numpy/ndarraytypes.h:1960, from /usr/local/lib/python3.8/dist-packages/numpy/core/include/numpy/ndarrayobject.h:12, from /usr/local/lib/python3.8/dist-packages/numpy/core/include/numpy/arrayobject.h:5, from lsh/cMinhash.cpp:304: ... creating dist creating 'dist/lsh-0.3.0-py3.8-linux-x86_64.egg' and adding 'build/bdist.linux-x86_64/egg' to it removing 'build/bdist.linux-x86_64/egg' (and everything under it) Processing lsh-0.3.0-py3.8-linux-x86_64.egg creating /usr/local/lib/python3.8/dist-packages/lsh-0.3.0-py3.8-linux-x86_64.egg Extracting lsh-0.3.0-py3.8-linux-x86_64.egg to /usr/local/lib/python3.8/dist-packages Adding lsh 0.3.0 to easy-install.pth file Installed /usr/local/lib/python3.8/dist-packages/lsh-0.3.0-py3.8-linux-x86_64.egg Processing dependencies for lsh==0.3.0 Searching for Cython==0.29.34 Best match: Cython 0.29.34 Adding Cython 0.29.34 to easy-install.pth file Installing cygdb script to /usr/local/bin Installing cython script to /usr/local/bin Installing cythonize script to /usr/local/bin Using /usr/local/lib/python3.8/dist-packages Searching for numpy==1.22.2 Best match: numpy 1.22.2 Adding numpy 1.22.2 to easy-install.pth file Installing f2py script to /usr/local/bin Installing f2py3 script to /usr/local/bin Installing f2py3.8 script to /usr/local/bin Using /usr/local/lib/python3.8/dist-packages Finished processing dependencies for lsh==0.3.0 ``` ### 下载URL ``` 下载地址:https://mega.nz/folder/EZZD0YwJ#9_PlEQzdMVLaNdKv_ICNVQ/folder/cc4RgQQZ ``` ``` > python3 blacklist_urls.py ./urls clean_urls.txt remove blacklisted urls .. > found 1 files [MALFORMED URL]: http://ama [DOMAIN BLACKLIST]: http://plotholes-comic.tumblr.com/post/2559612220/gee-i-sure-hope-tumblr-doesnt-resize-my-comic-so [DOMAIN BLACKLIST]: http://reicow.tumblr.com/ [DOMAIN BLACKLIST]: http://www.explosm.net/comics/2281/ ... [DOMAIN BLACKLIST]: http://pencilholder.tumblr.com/post/2553331442/coffee [DOMAIN BLACKLIST]: http://www.liveleak.com/view?i=897_1293900770 [DOMAIN BLACKLIST]: http://christiannightmares.tumblr.com/post/2556591356/christian-nightmares-10-favorite-worst-video [DOMAIN BLACKLIST]: http://memegenerator.net/Foul-Bachelor-Frog/ImageMacro/4823906/Toilet-Clogged-Shit-in-trash-bag-and-throw-it-in-dumpster [DOMAIN BLACKLIST]: http://www.liveleak.com/view?i=77d_1293476512 [DOMAIN BLACKLIST]: http://sati1984.tumblr.com/post/2525789905/hungarian-media-authority-punishes-radio-for-playing [DOMAIN BLACKLIST]: http://ihearttrains.tumblr.com/post/2144304367/i-was-out-for-a-late-night-bike-ride-saw-this-cp [DOMAIN BLACKLIST]: http://www.amazon.com/gp/product/0765342294?ie=UTF8&tag=reddit2-20 [DOMAIN BLACKLIST]: http://www.amazon.com/gp/product/B000K7VHPA?ie=UTF8&tag=reddit2-20 [DOMAIN BLACKLIST]: http://www.amazon.com/gp/product/B000MEYKD2?ie=UTF8&tag=reddit2-20 [DOMAIN BLACKLIST]: http://dancingalonetopony.tumblr.com/ [DOMAIN BLACKLIST]: http://christiannightmares.tumblr.com/post/2571743396/christian-woman-advertising-the-rapture-on-the [MALFORMED URL]: http://paris [DOMAIN BLACKLIST]: http://www.quickmeme.com/Musically-Oblivious-8th-Grader/Ha/animal-collective-no-i-dont-collect-beanie-babbies/ [DOMAIN BLACKLIST]: http://www.dailymotion.com/video/xeizh2_tvxsgr-manufactured-landscapes_people ... [DOMAIN BLACKLIST]: http://www.explosm.net/comics/2284/ [DOMAIN BLACKLIST]: http://img411.imageshack.us/i/54398042.png/ [DOMAIN BLACKLIST]: http://www.liveleak.com/view?i=d3a_1293898955 [DOMAIN BLACKLIST]: http://s1221.photobucket.com/albums/dd473/Tuekiira/?action=view¤t=untitled.jpg [DOMAIN BLACKLIST]: http://www.amazon.com/Stainless-Steel-Rat-Returns-ebook/dp/B003P2WO6S [DOMAIN BLACKLIST]: http://onlythebrightest.tumblr.com/post/1683441156 [DOMAIN BLACKLIST]: http://www.dailymotion.com/video/xg5www_bag-raiders-sunlight_music [DOMAIN BLACKLIST]: http://www.liveleak.com/view?i=7f8_1286326027 [DOMAIN BLACKLIST]: http://nypl.tumblr.com/post/2586612741/in-honor-of-fantasy-king-j-r-r-tolkiens [EXTENTION BLACKLIST]: http://phil.caint.com/reddit/RedditIrelandWhereAreYouFrom.xls [DOMAIN BLACKLIST]: http://christiannightmares.tumblr.com/post/2601211787/church-sign-the-peter-in-me-found-at [DOMAIN BLACKLIST]: http://s401.photobucket.com/albums/pp94/theaudiopervjr/?action=view¤t=bestcoastfallon.mp4 [DOMAIN BLACKLIST]: http://www.google.co.uk/images?q=pokebra&hl=en&client=firefox-a&hs=fra&rls=org.mozilla:en-GB:official&prmd=ivns&source=lnms&tbs=isch:1&ei=j58jTee5NeqShAeurPG2Dg&sa=X&oi=mode_link&ct=mode&ved=0CA0Q_AU&biw=1219&bih=752 [MALFORMED URL]: http://opendesktop.org/content/show.php/Egg Window Manager?content=136862 [DOMAIN BLACKLIST]: http://glitterfarm.tumblr.com/post/2556658380/via-iloveawk [DOMAIN BLACKLIST]: http://qkme.me/I2 [DOMAIN BLACKLIST]: http://www.liveleak.com/view?i=e27_1294160320 [DOMAIN BLACKLIST]: http://www.liveleak.com/view?i=604_1294163370 [DOMAIN BLACKLIST]: http://glitterfarm.tumblr.com/post/2545229659/fuckyeahradicalcartoons-best-political-cartoons [DOMAIN BLACKLIST]: http://ryan-a.tumblr.com/post/1325972211/nif01 [DOMAIN BLACKLIST]: http://www.google.co.uk/url?sa=t&source=web&cd=2&sqi=2&ved=0CCgQtwIwAQ&url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Db3wT71l4B7c&rct=j&q=what%27s%20mk%20ultra&ei=u2QjTd-EEcWbhQfciv22Dg&usg=AFQjCNHCVya6KzeCOKaXLDlbpdKZzXs5Vw&sig2=voZA0Ips3wKjOQgRd1Dvrw&cad=rja [DOMAIN BLACKLIST]: http://www.amazon.com/review/R3FK6MTPT1CZW8/ref=cm_cr_pr_perm?&tag=reddit2-20 [DOMAIN BLACKLIST]: http://maps.google.ca/maps?f=q&source=s_q&hl=en&geocode=&q=&sll=45.641048,-73.840313&sspn=0.097454,0.288391&gl=ca&ie=UTF8&ll=45.635332,-73.501292&spn=0.006091,0.018024&t=k&z=17 [DOMAIN BLACKLIST]: http://www.dailymotion.com/video/x9fsm_actiekatten_shortfilms [DOMAIN BLACKLIST]: http://www.amazon.com/gp/product/B000FA5R5S/ref=kinw_myk_ro_title [DOMAIN BLACKLIST]: http://memegenerator.net/Philosoraptor/ImageMacro/4928670/Why-arent-hemorrhoids-called-asteroids- [DOMAIN BLACKLIST]: http://www.amazon.com/gp/product/B000FA5MUI/ref=kinw_myk_ro_title [DOMAIN BLACKLIST]: http://qkme.me/EH [DOMAIN BLACKLIST]: http://qkme.me/IK [DOMAIN BLACKLIST]: http://www.liveleak.com/view?i=f85_1294099720 [DOMAIN BLACKLIST]: http://troyatnight.tumblr.com/post/2595553006/the-snow-melted-and-then-froze-the-rubble-into-a [DOMAIN BLACKLIST]: http://fuckyeahblackguyonseinfeld.tumblr.com/ [DOMAIN BLACKLIST]: http://www.liveleak.com/view?i=2d8_1294085921 [DOMAIN BLACKLIST]: http://explosm.net/comics/2285 [DOMAIN BLACKLIST]: http://lobstertoes.tumblr.com/post/2517807815/where-can-i-buy [DOMAIN BLACKLIST]: http://img809.imageshack.us/slideshow/webplayer.php?id=img20110103102932.jpg [DOMAIN BLACKLIST]: http://accook365.tumblr.com/ ... [DOMAIN BLACKLIST]: http://www.quickmeme.com/meme/BEy/ [DOMAIN BLACKLIST]: http://www.google.ca/images?q=chris+evans&um=1&hl=en&biw=1503&bih=652&tbs=isch:1&tbas=0&source=lnt&sa=X&ei=MAtGTdjkKoT68Aa3zay-AQ&ved=0CAYQpwUoAA [DOMAIN BLACKLIST]: http://cgi.ebay.co.uk/Final-Fantasy-VIII-Boxset-Collectors-PS1-RARE-VGC-/150552089322?pt=UK_VintageComputing_RL&hash=item230d9a92ea FINAL | time elapsed (s): 1.34 | number of urls: 71958 | domain blacklisted: 1477 | extention blacklisted: 1 | short urls (<=8): 0 | malformed urls: 40 | duplicate urls: 0 > writing cleaned up url list to clean_urls.txt done :-) ``` ``` > head -n10 clean_urls.txt http://theopenend.com/2011/01/13/toe-short-story-the-mosquito-song-%e2%80%93-ch-15/ http://www.readplatform.com/james-blake-55-min-boiler-room-mix/ http://www.mg.co.za/article/2011-01-13-violent-clashes-spread-to-centre-of-tunisian-capital http://www.playtankworld.com/ http://www.meetup.com/Suffolk-County-Drinkers/ http://www.insanemusclegirls.com/video/doing-what-she-does-best---being-hot/ http://www.mattbors.com/archives/717.html http://www.nfl.com/videos/nfl-cant-miss-plays/09000d5d81d8d049/Lynch-s-amazing-TD-seals-upset-of-defending-champs http://www.reuters.com/article/idUSTRE70B26A20110112?feedType=RSS&feedName=topNews&utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+reuters/topNews+(News+/+US+/+Top+News) http://mikeos.berlios.de/write-your-own-os.html ``` ### 合并数据 ```python import glob import sys import json import argparse if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument("--data_path", type=str, default=".", help="path where all the json files are located") parser.add_argument("--output_file", type=str, default="merged_output.json", help="filename where the merged json should go") args = parser.parse_args() data_path = args.data_path out_file = args.output_file text_files = glob.glob(data_path + '/*.txt') counter = 0 with open(out_file, 'w') as outfile: for fname in text_files: counter += 1 if counter % 1024 == 0: print("Merging at ", counter, flush=True) with open(fname, 'r') as infile: for row in infile: tmp = {} tmp['text'] = row outfile.write(json.dumps(tmp)) outfile.write('\n') print("Merged file", out_file, flush=True) ``` ``` > python3 Megatron-LM/tools/openwebtext/merge_data.py --data_path /workspace/code/scraped/data --output_file /workspace/data/merged_output.json Merging at 1024 Merging at 2048 Merged file /workspace/data/merged_output.json ``` ``` > head -n10 /workspace/data/merged_output.json {"text": "With every new year, it's murder for Neal Smither and his crew.\n"} {"text": "\n"} {"text": "Suicide, too.\n"} {"text": "\n"} {"text": "As owner of Crime Scene Cleaners, Smither's job is to clean up the bloody messes left behind when people kill each other or themselves - and those first few weeks after Jan. 1 are his busiest time of year.\n"} {"text": "\n"} {"text": "All that holiday frivolity and togetherness may sound good in songs and movies, and a lot of people do indeed get mighty joyful - but experts say there is also a dark flip side of sadness, rage and depression that flares between Thanksgiving and post-New Year's.\n"} {"text": "\n"} {"text": "Most people hold their feelings together during the run-up to the new year, but once the holiday letdown sets it in, calls to suicide hot lines nearly double and homicides hit their highest rate of the year. Police officers, crisis counselors and people like Smither put in some long days and nights.\n"} {"text": "\n"} ``` ## 数据预处理 ### 清洗数据 执行一下cleanup_dataset.py来把tokens数量少于128的文本都删掉。 ``` cd Megatron-LM/tools/openwebtext/ python3 cleanup_dataset.py /workspace/data/merged_output.json /workspace/data/merged_cleand.json ``` 执行 ftfy、英语检测并删除少于 128 个标记的文档。 此步骤可以分片并在分片上运行。 ``` > python3 cleanup_dataset.py /workspace/data/merged_output.json /workspace/data/merged_cleand.json building gpt2 dataset ... will be reading /workspace/data/merged_output.json and will write the results to /workspace/data/merged_cleand.json > filtering /workspace/data/merged_output.json 100%|████████████████████████████████████████████████████████████████████████████████████████████| 1042301/1042301 [00:02<00:00, 457699.45B/s] 100%|██████████████████████████████████████████████████████████████████████████████████████████████| 456318/456318 [00:03<00:00, 131743.88B/s] > GPT2 tokenizer with 50257 vocab size and eod token 50256 ... [small document, skipping]: {'text': "With every new year, it's murder for Neal Smither and his crew.\n"} skipping {"text": "\n"} No features in text. [non-english text] {'text': 'Suicide, too.\n'} skipping {"text": "\n"} No features in text. [non-english text] {'text': 'Pin\n'} skipping {"text": "\n"} No features in text. [non-english text] {'text': 'Tweet'} [FINAL] | elapsed time: 156.46 | documents: 78802 | fixed text: 7891 | non-english: 4536 | non-english chars: 410257 | small docs: 30227 | small docs chars: 5717430 ``` ``` wc -l merged_output.json 78802 merged_output.json wc -l merged_cleand.json 2456 merged_cleand.json ``` 可以使用 cleanup_fix_dataset.py 完成其他清理(例如,删除少于 512 个字符的文档或特定于数据集的清理,如故事、真实新闻数据集)。 可以通过运行 python cleanup_fix_dataset.py --help 找到更多详细信息。 2. 使用 LSH 查找可能的重复项并将其存储在文件中以供以后处理。 该代码支持保存和加载指纹(fingerprints)以进行重复数据删除,并且还支持多线程以加快处理速度。 更多详细信息可以通过 python find_duplicates.py --help 找到。 ``` python find_duplicates.py --inputs /workspace/data/merged_cleand.json merged_cleand_id --output /workspace/data/output_possible_duplicate_urls ``` 3. 基于相似性度量,在函数 is_similar 中定义(默认值:0.9),对相似的 URL 进行分组。 基本上,对于每一组,我们只应保留一个网址并删除其余的网址。 ``` python group_duplicate_urls.py ``` 4. 删除上一步中检测到的类似文档。 python remove_group_duplicates.py <包含相似文档的文件> <已清理的数据文件> <包含去重数据的输出文件> 5. Shuffle the dataset. ``` # shuf -o train_data.json shuf /workspace/data/merged_cleand.json -o /workspace/data/train_data.json ``` ### 数据预处理 ``` python tools/preprocess_data.py \ --input /workspace/data/train_data.json \ --output-prefix /workspace/data/my-gpt2 \ --vocab-file /workspace/model/gpt2-vocab/gpt2-vocab.json\ --dataset-impl mmap \ --tokenizer-type GPT2BPETokenizer \ --merge-file /workspace/model/gpt2-vocab/gpt2-merges.txt \ --append-eod \ --workers 20 \ --chunk-size 25 ``` ``` python tools/preprocess_data.py \ > --input /workspace/data/train_data.json \ > --output-prefix /workspace/data/my-gpt2 \ > --vocab-file /workspace/model/gpt2-vocab/gpt2-vocab.json\ > --dataset-impl mmap \ > --tokenizer-type GPT2BPETokenizer \ > --merge-file /workspace/model/gpt2-vocab/gpt2-merges.txt \ > --append-eod \ > --workers 20 \ > --chunk-size 25 Opening /workspace/data/train_data.json > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > building GPT2BPETokenizer tokenizer ... > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) Vocab size: 50257 Output prefix: /workspace/data/my-gpt2 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) Time to startup: 0.30323338508605957 > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) Processed 100 documents (599.5023090743549 docs/s, 0.5155917905295792 MB/s). Processed 200 documents (823.8866599553122 docs/s, 0.880650182925332 MB/s). Processed 300 documents (1185.4008987366815 docs/s, 1.200331609341586 MB/s). Processed 400 documents (1533.1571463558173 docs/s, 1.6700295716317035 MB/s). Processed 500 documents (1870.0427840484517 docs/s, 1.9969574995140202 MB/s). Processed 600 documents (2187.427117123695 docs/s, 2.3795959237741595 MB/s). Processed 700 documents (2152.781409317778 docs/s, 2.606610975177864 MB/s). Processed 800 documents (2387.7960244711426 docs/s, 2.818861025855241 MB/s). Processed 900 documents (2608.6323398315217 docs/s, 3.0303661882286277 MB/s). Processed 1000 documents (2838.3195442776887 docs/s, 3.2176144414924934 MB/s). Processed 1100 documents (3016.585243380653 docs/s, 3.4106741220407777 MB/s). Processed 1200 documents (3236.0855769694435 docs/s, 3.7339411377043383 MB/s). Processed 1300 documents (3475.8398763827417 docs/s, 3.935396723301203 MB/s). Processed 1400 documents (3684.5816116836872 docs/s, 4.222750560810705 MB/s). Processed 1500 documents (3880.979581765468 docs/s, 4.3926025538214795 MB/s). Processed 1600 documents (3418.7934424893274 docs/s, 3.8987457589126513 MB/s). Processed 1700 documents (3574.7781279422925 docs/s, 4.042231645357657 MB/s). Processed 1800 documents (3738.2444121277663 docs/s, 4.194224887440415 MB/s). Processed 1900 documents (3886.3553392670174 docs/s, 4.393378761729153 MB/s). Processed 2000 documents (4044.6050768939995 docs/s, 4.54716435296795 MB/s). Processed 2100 documents (4221.569306909339 docs/s, 4.692880733997719 MB/s). Processed 2200 documents (4398.378779031662 docs/s, 4.835040337476316 MB/s). Processed 2300 documents (4568.910999317048 docs/s, 5.0245360709512354 MB/s). Processed 2400 documents (4740.355416123744 docs/s, 5.179960433973664 MB/s). Done! Now finalizing. ``` ## 模型训练 example/pretrain_gpt.sh 脚本使用单卡 GPU 运行 345M 参数的 GPT 模型进行预训练。 如上所述,单 GPU 训练主要用于调试目的,因为代码针对分布式训练进行了优化。 它遵循与之前的 BERT 脚本基本相同的格式,但有一些显着的差异:使用的tokenization方案是 BPE(需要merge表和 json 词汇文件)而不是 WordPiece,模型架构允许更长的序列(请注意, 最大位置嵌入必须大于或等于最大序列长度),并且 --lr-decay-style 已设置为余弦衰减。 请注意,--data-path 现在包含在预处理中添加的附加 _text_document 后缀,但不包含文件扩展名。 源文件 `arguments.py` 中描述了更多命令行参数。 `example/pretrain_gpt.sh` 可以按照与 BERT 描述相同的方式启动。 设置环境变量并进行任何其他修改,使用适当的安装启动容器,然后运行脚本。 ``` ``` ================================================ FILE: llm-train/megatron/gpt2/merge_ck_and_inference/README.md ================================================ - checkpoint_loader_megatron.py - checkpoint_saver_megatron.py ``` margs.vocab_file = '/workspace/model/gpt2-vocab/gpt2-vocab.json' margs.merge_file = '/workspace/model/gpt2-vocab/gpt2-merges.txt' ``` ================================================ FILE: llm-train/megatron/gpt2/merge_ck_and_inference/checkpoint_loader_megatron.py ================================================ import json import os import sys import types import torch def add_arguments(parser): group = parser.add_argument_group(title='Megatron loader') group.add_argument('--true-vocab-size', type=int, default=None, help='original size of vocab, if specified will trim padding from embedding table.') group.add_argument('--vocab-file', type=str, default=None, help='Path to the vocab file. If specified will use this to get vocab size and ' 'trim padding from the embedding table.') group.add_argument('--megatron-path', type=str, default=None, help='Base directory of deepspeed repository') def _load_checkpoint(queue, args): # Search in directory above this sys.path.append(os.path.abspath( os.path.join(os.path.dirname(__file__), os.path.pardir))) if args.megatron_path is not None: sys.path.insert(0, args.megatron_path) #args.vocab_file = '/workspace/model/gpt2-vocab/gpt2-vocab.json' try: from megatron.arguments import parse_args, validate_args from megatron.global_vars import set_args, set_global_variables from megatron.checkpointing import load_args_from_checkpoint, load_checkpoint from megatron.model import module from megatron.core import mpu from megatron.core.enums import ModelType from megatron import fused_kernels except ModuleNotFoundError: print("Unable to import Megatron, please specify the path to Megatron using --megatron-path. Exiting.") queue.put("exit") exit(1) # We want all arguments to come from us sys.argv = ['script.py', '--no-masked-softmax-fusion', '--no-bias-gelu-fusion', '--no-bias-dropout-fusion', '--no-async-tensor-model-parallel-allreduce', '--use-cpu-initialization', '--micro-batch-size', '1', '--no-load-optim', '--no-load-rng', '--no-save-optim', '--no-save-rng', '--no-initialization', '--load', args.load_dir ] margs = parse_args() print(margs) margs.vocab_file = '/workspace/model/gpt2-vocab/gpt2-vocab.json' margs.merge_file = '/workspace/model/gpt2-vocab/gpt2-merges.txt' margs, checkpoint_args = load_args_from_checkpoint(margs) #print(margs) # Arguments do sanity checks on the world size, but we don't care, # so trick it into thinking we are plenty of processes margs.world_size = margs.tensor_model_parallel_size * margs.pipeline_model_parallel_size margs = validate_args(margs) def check_for_arg(arg_name, default=None): if getattr(margs, arg_name, None) is None: if default is not None: setattr(margs, arg_name, default) else: print(f"Checkpoint does not specify the argument {arg_name}. Exiting.") print(f"Arguments: {margs}") queue.put("exit") exit(1) check_for_arg('tensor_model_parallel_size') check_for_arg('pipeline_model_parallel_size') check_for_arg('num_layers') check_for_arg('hidden_size') check_for_arg('seq_length') check_for_arg('num_attention_heads') check_for_arg('max_position_embeddings') check_for_arg('add_position_embedding', True) check_for_arg('use_rotary_position_embeddings', False) check_for_arg('tokenizer_type') check_for_arg('iteration') check_for_arg('bert_binary_head') check_for_arg('disable_bias_linear', False) check_for_arg('params_dtype') check_for_arg('swiglu', False) # Determine how to make our models if args.model_type == 'GPT': from pretrain_gpt import model_provider margs.model_type = ModelType.encoder_or_decoder elif args.model_type == 'BERT': from pretrain_bert import model_provider margs.model_type = ModelType.encoder_or_decoder else: raise Exception(f'unrecognized model type: {args.model_type}') # supress warning about torch.distributed not being initialized module.MegatronModule.embedding_warning_printed = True consumed_train_samples = None consumed_valid_samples = None def get_models(count, dtype): nonlocal consumed_train_samples nonlocal consumed_valid_samples model_array_len = margs.virtual_pipeline_model_parallel_size if model_array_len is None: model_array_len = 1 models = [[] for _ in range(model_array_len)] pre_process = mpu.is_pipeline_first_stage() post_process = mpu.is_pipeline_last_stage() for rank in range(count): mpu.set_tensor_model_parallel_rank(rank) if margs.virtual_pipeline_model_parallel_size is not None: model_ = [] for i in range(margs.virtual_pipeline_model_parallel_size): mpu.set_virtual_pipeline_model_parallel_rank(i) # Set pre_process and post_process only after virtual rank is set. pre_process = mpu.is_pipeline_first_stage() post_process = mpu.is_pipeline_last_stage() this_model = model_provider( pre_process=pre_process, post_process=post_process ).to(dtype) model_.append(this_model) else: pre_process = mpu.is_pipeline_first_stage() post_process = mpu.is_pipeline_last_stage() model_rank = 0 model_ = [model_provider(pre_process, post_process).to(dtype)] margs.consumed_train_samples = 0 margs.consumed_valid_samples = 0 load_checkpoint(model_, None, None) if consumed_train_samples is not None: assert(margs.consumed_train_samples == consumed_train_samples) else: consumed_train_samples = margs.consumed_train_samples if consumed_valid_samples is not None: assert(margs.consumed_valid_samples == consumed_valid_samples) else: consumed_valid_samples = margs.consumed_valid_samples for vp_rank in range(model_array_len): models[vp_rank].append(model_[vp_rank]) return models set_global_variables(margs) mpu.set_tensor_model_parallel_world_size(margs.tensor_model_parallel_size) mpu.set_pipeline_model_parallel_world_size(margs.pipeline_model_parallel_size) mpu.set_virtual_pipeline_model_parallel_world_size(margs.virtual_pipeline_model_parallel_size) fused_kernels.load(margs) # Get true (non-padded) vocab size if args.true_vocab_size is not None: true_vocab_size = args.true_vocab_size elif args.vocab_file is not None: vocab = json.load(open(args.vocab_file)) true_vocab_size = len(vocab) if args.true_vocab_size is not None and true_vocab_size != args.true_vocab_size: print("Both --true-vocab-size and --vocab-file specified and the vocab size does not match, aborting.") queue.put("exit") exit(1) else: true_vocab_size = None # short aliases tp_size = margs.tensor_model_parallel_size pp_size = margs.pipeline_model_parallel_size vp_size = margs.virtual_pipeline_model_parallel_size if vp_size is None: vp_size = 1 # metadata md = types.SimpleNamespace() md.model_type = args.model_type md.num_layers = margs.num_layers md.hidden_size = margs.hidden_size md.seq_length = margs.seq_length md.num_attention_heads = margs.num_attention_heads md.max_position_embeddings = margs.max_position_embeddings md.tokenizer_type = margs.tokenizer_type md.iteration = margs.iteration md.params_dtype = margs.params_dtype md.bert_binary_head = margs.bert_binary_head md.output_layer = margs.untie_embeddings_and_output_weights md.position_embeddings = margs.add_position_embedding md.linear_bias = margs.add_bias_linear md.swiglu = margs.swiglu md.previous_tensor_parallel_size = margs.tensor_model_parallel_size md.previous_pipeline_parallel_size = margs.pipeline_model_parallel_size md.true_vocab_size = true_vocab_size md.make_vocab_size_divisible_by = margs.make_vocab_size_divisible_by md.checkpoint_args = checkpoint_args # Get first pipe stage mpu.set_pipeline_model_parallel_rank(0) all_models = [get_models(tp_size, md.params_dtype)] models = all_models[0][0] md.consumed_train_samples = consumed_train_samples md.consumed_valid_samples = consumed_valid_samples queue.put(md) def queue_put(name, msg): print(f"sending {name}") msg["name"] = name queue.put(msg) # Send embeddings message = { "word embeddings": torch.cat( [models[tp_rank].language_model.embedding.word_embeddings.weight.data for tp_rank in range(tp_size)], dim = 0) } if md.position_embeddings: message["position embeddings"] = models[0].language_model.embedding.position_embeddings.weight.data queue_put("embeddings", message) total_layer_num = 0 for vp_rank in range(vp_size): mpu.set_virtual_pipeline_model_parallel_rank(vp_rank) for pp_rank in range(pp_size): if pp_rank > 0: mpu.set_pipeline_model_parallel_rank(pp_rank) if vp_rank == 0: all_models.append(get_models(tp_size, md.params_dtype)) models = all_models[pp_rank][vp_rank] for layer_num in range(len(models[0].language_model.encoder.layers)): message = {} # Get non-parallel tensors from tp_rank 0 layer = models[0].language_model.encoder.layers[layer_num] message["input layernorm weight"] = layer.input_layernorm.weight.data message["input layernorm bias"] = layer.input_layernorm.bias.data message["post layernorm weight"] = layer.post_attention_layernorm.weight.data message["post layernorm bias"] = layer.post_attention_layernorm.bias.data if md.linear_bias: message["dense bias"] = layer.self_attention.dense.bias.data message["mlp l1 bias"] = layer.mlp.dense_4h_to_h.bias.data # Grab all parallel tensors for this layer qkv_weight = [] qkv_bias = [] dense_weight = [] mlp_l0_weight = [] mlp_l0_bias = [] mlp_l1_weight = [] for tp_rank, model in enumerate(models): layer = model.language_model.encoder.layers[layer_num] qkv_weight.append(layer.self_attention.query_key_value.weight.data) dense_weight.append(layer.self_attention.dense.weight.data) mlp_l0_weight.append(layer.mlp.dense_h_to_4h.weight.data) mlp_l1_weight.append(layer.mlp.dense_4h_to_h.weight.data) if md.linear_bias: qkv_bias.append(layer.self_attention.query_key_value.bias.data) mlp_l0_bias.append(layer.mlp.dense_h_to_4h.bias.data) # Handle gated linear units if md.swiglu: # concat all the first halves ('W's) and all the second halves ('V's) for tp_rank in range(tp_size): mlp_l0_weight[tp_rank] = torch.chunk(mlp_l0_weight[tp_rank], 2, dim=0) message["mlp l0 weight W"] = torch.cat([w[0] for w in mlp_l0_weight], dim=0) message["mlp l0 weight V"] = torch.cat([w[1] for w in mlp_l0_weight], dim=0) else: message["mlp l0 weight"] = torch.cat(mlp_l0_weight, dim=0) # simple concat of the rest message["qkv weight"] = torch.cat(qkv_weight, dim=0) message["dense weight"] = torch.cat(dense_weight, dim=1) message["mlp l1 weight"] = torch.cat(mlp_l1_weight, dim=1) if md.linear_bias: message["qkv bias"] = torch.cat(qkv_bias, dim=0) if md.swiglu: for tp_rank in range(tp_size): mlp_l0_bias[tp_rank] = torch.chunk(mlp_l0_bias[tp_rank], 2, dim=0) message["mlp l0 bias W"] = torch.cat([b[0] for b in mlp_l0_bias],dim=0) message["mlp l0 bias V"] = torch.cat([b[1] for b in mlp_l0_bias],dim=0) else: message["mlp l0 bias"] = torch.cat(mlp_l0_bias, dim=0) queue_put(f"transformer layer {total_layer_num}", message) total_layer_num = total_layer_num + 1 # Send final layernorm from tp_rank 0 message = { "weight": models[0].language_model.encoder.final_layernorm.weight.data, "bias": models[0].language_model.encoder.final_layernorm.bias.data } queue_put("final layernorm", message) if md.output_layer: message = { "weight": torch.cat( [models[tp_rank].language_model.output_layer.weight.data for tp_rank in range(tp_size)], dim = 0) } queue_put("output layer", message) # Send BERT lm head and binary head if it exists if md.model_type == 'BERT': message = { "weight": models[0].language_model.pooler.dense.weight.data, "bias": models[0].language_model.pooler.dense.bias.data } queue_put("pooler", message) message = { "dense weight": models[0].lm_head.dense.weight.data, "dense bias": models[0].lm_head.dense.bias.data, "layernorm weight": models[0].lm_head.layernorm.weight.data, "layernorm bias": models[0].lm_head.layernorm.bias.data } queue_put("lm head", message) if md.bert_binary_head: message = { "weight": models[0].binary_head.weight.data, "bias": models[0].binary_head.bias.data } queue_put("binary head", message) queue.put("done") def load_checkpoint(queue, args): try: _load_checkpoint(queue, args) except: queue.put("exit") raise ================================================ FILE: llm-train/megatron/gpt2/merge_ck_and_inference/checkpoint_saver_megatron.py ================================================ import argparse from collections.abc import Mapping import concurrent.futures import os import sys import torch def add_arguments(parser): group = parser.add_argument_group(title='Megatron saver') group.add_argument('--megatron-path', type=str, default=None, help='Base directory of Megatron repository') group.add_argument('--target-tensor-parallel-size', type=int, help='Target tensor model parallel size, defaults to the tensor parallel size ' 'in the input checkpoint if provided by the loader, otherwise to 1') group.add_argument('--target-pipeline-parallel-size', type=int, help='Target tensor model parallel size, default to the pipeline parall size ' 'in the input checkpoint if provided by the loader, otherwise to 1') def save_checkpoint(queue, args): # Search in directory above this sys.path.append(os.path.abspath( os.path.join(os.path.dirname(__file__), os.path.pardir))) if args.megatron_path is not None: sys.path.insert(0, args.megatron_path) try: from megatron.arguments import (parse_args, validate_args) from megatron.checkpointing import save_checkpoint from megatron.global_vars import set_global_variables, get_args from megatron.core.enums import ModelType from megatron.tokenizer.tokenizer import _vocab_size_with_padding from megatron import fused_kernels from megatron.core import mpu except ModuleNotFoundError: print("Unable to import Megatron, please specify the path to Megatron using --megatron-path. Exiting.") exit(1) def queue_get(name=None): val = queue.get() if val == "exit": print("Loader exited, exiting saver") exit(1) if name is not None and args.checking and val["name"] != name: val_name = val["name"] print(f'Unexpected message. Expecting "{name}" but got "{val_name}". Exiting saver.') exit(1) if name is not None: print(f"received {name}") return val def check_message(msg): if not args.checking: return msg_name = msg.pop("name") if len(msg.keys()) > 0: print(f"Unexpected values in {msg_name}:") for key in msg.keys(): print(f" {key}") print(f"Exiting. If you want to ignore this, use the argument --no-checking.") exit(1) md = queue_get() if args.target_tensor_parallel_size is None: if hasattr(md, 'previous_tensor_parallel_size'): args.target_tensor_parallel_size = md.previous_tensor_parallel_size else: print("loader did not provide a tensor parallel size and --target-tensor-parallel-size not provided on command line. " "Default to 1.") args.target_tensor_parallel_size = 1 if args.target_pipeline_parallel_size is None: if hasattr(md, 'previous_pipeline_parallel_size'): args.target_pipeline_parallel_size = md.previous_pipeline_parallel_size else: print("loader did not provide a pipeline parallel size and --target-pipeline-parallel-size not provided on command line. " "Default to 1.") args.target_pipeline_parallel_size = 1 # Arguments do sanity checks on the world size, but we don't care, # so trick it into thinking we are plenty of processes if args.target_tensor_parallel_size is not None and args.target_pipeline_parallel_size is not None: os.environ["WORLD_SIZE"] = f'{args.target_tensor_parallel_size * args.target_pipeline_parallel_size}' # We want all arguments to come from us sys.argv = ['script.py', '--num-layers', str(md.num_layers), '--hidden-size', str(md.hidden_size), '--seq-length', str(md.seq_length), '--num-attention-heads', str(md.num_attention_heads), '--max-position-embeddings', str(md.max_position_embeddings), '--tokenizer-type', str(md.tokenizer_type), '--tensor-model-parallel-size', str(args.target_tensor_parallel_size), '--pipeline-model-parallel-size', str(args.target_pipeline_parallel_size), '--no-masked-softmax-fusion', '--no-bias-gelu-fusion', '--no-bias-dropout-fusion', '--no-async-tensor-model-parallel-allreduce', '--use-cpu-initialization', '--micro-batch-size', '1', '--no-load-optim', '--no-load-rng', '--no-save-optim', '--no-save-rng', '--no-initialization', '--save-interval', '1', '--save', args.save_dir ] if md.make_vocab_size_divisible_by is not None: sys.argv.extend(['--make-vocab-size-divisible-by', str(md.make_vocab_size_divisible_by)]) if md.params_dtype == torch.float16: sys.argv.append('--fp16') elif md.params_dtype == torch.bfloat16: sys.argv.append('--bf16') if md.output_layer: sys.argv.append('--untie-embeddings-and-output-weights') if not md.position_embeddings: sys.argv.append('--no-position-embedding') if not md.linear_bias: sys.argv.append('--disable-bias-linear') if md.model_type == 'BERT' and not md.bert_binary_head: sys.argv.append('--bert-no-binary-head') margs = parse_args() margs.vocab_file = '/workspace/model/gpt2-vocab/gpt2-vocab.json' margs.merge_file = '/workspace/model/gpt2-vocab/gpt2-merges.txt' if hasattr (md, 'checkpoint_args'): # These are arguments that we are either changing, or cause problems for validation if they are set # Note that some of these deal with T5 so will need to be changed if we support T5. args_to_keep = ['tensor_model_parallel_size', 'pipeline_model_parallel_size', 'params_dtype', 'num_layers_per_virtual_pipeline_stage', 'virtual_pipeline_model_parallel_size', 'masked_softmax_fusion', 'bias_gelu_fusion', 'bias_dropout_fusion', 'sequence_parallel', 'async_tensor_model_parallel_allreduce', 'no_load_optim', 'no_load_rng', 'no_save_optim', 'no_save_rng', 'vocab_file', 'tokenizer_model', 'save_interval', 'save', 'perform_initialization', 'use_cpu_initialization', 'encoder_num_layers', 'encoder_seq_length', 'distribute_saved_activations', 'train_iters', 'lr_decay_iters', 'lr_warmup_iters', 'lr_warmup_fraction', 'start_weight_decay', 'end_weight_decay'] for arg, value in vars(md.checkpoint_args).items(): if arg in args_to_keep: continue if not hasattr(margs, arg): print(f"Checkpoint had argument {arg} but new arguments does not have this.") continue if getattr(margs, arg) != value: print(f"Overwriting default {arg} value {getattr(margs, arg)} with value from checkpoint {value}.") setattr(margs, arg, value) validate_args(margs) set_global_variables(margs) # margs = megatron args margs = get_args() if hasattr(md, 'consumed_train_samples'): margs.consumed_train_samples = md.consumed_train_samples margs.consumed_valid_samples = md.consumed_valid_samples print(f"Setting consumed_train_samples to {margs.consumed_train_samples}" f" and consumed_valid_samples to {margs.consumed_valid_samples}") else: print("consumed_train_samples not provided.") # Determine how to make our models if md.model_type == 'GPT': from pretrain_gpt import model_provider margs.model_type = ModelType.encoder_or_decoder elif md.model_type == 'BERT': from pretrain_bert import model_provider margs.model_type = ModelType.encoder_or_decoder else: raise Exception(f'unrecognized model type: {args.model_type}') def get_models(count, dtype, pre_process, post_process): models = [model_provider(pre_process, post_process).to(dtype) for _ in range(count)] return models # fake initializing distributed mpu.set_tensor_model_parallel_world_size(args.target_tensor_parallel_size) mpu.set_pipeline_model_parallel_world_size(args.target_pipeline_parallel_size) mpu.set_tensor_model_parallel_rank(0) mpu.set_pipeline_model_parallel_rank(0) fused_kernels.load(margs) # Embeddings #----------- embeddings_msg = queue_get("embeddings") if md.position_embeddings: pos_embed = embeddings_msg.pop("position embeddings") orig_word_embed = embeddings_msg.pop("word embeddings") check_message(embeddings_msg) # Deal with padding if md.true_vocab_size is not None: # figure out what our padded vocab size is orig_vocab_size = orig_word_embed.shape[0] margs.padded_vocab_size = _vocab_size_with_padding(md.true_vocab_size, margs) # Cut out extra padding we don't need if orig_vocab_size > margs.padded_vocab_size: full_word_embed = orig_word_embed[0:margs.padded_vocab_size,:] # Expanding embedding to larger size by replicating final entry elif orig_vocab_size < margs.padded_vocab_size: padding_size = margs.padded_vocab_size - orig_vocab_size full_word_embed = torch.cat(( orig_word_embed, orig_word_embed[-1].unsqueeze(0).expand(padding_size, -1))) # Same size! else: full_word_embed = orig_word_embed else: print("Original vocab size not specified, leaving embedding table as-is. " "If you've changed the tensor parallel size this could cause problems.") margs.padded_vocab_size = orig_word_embed.shape[0] full_word_embed = orig_word_embed # Split into new tensor model parallel sizes out_word_embed = torch.chunk(full_word_embed, args.target_tensor_parallel_size, dim=0) # Make models for first pipeline stage and fill in embeddings mpu.set_pipeline_model_parallel_rank(0) post_process = args.target_pipeline_parallel_size == 1 models = get_models(args.target_tensor_parallel_size, md.params_dtype, True, post_process) for tp_rank, model in enumerate(models): model.language_model.embedding.word_embeddings.weight.data.copy_(out_word_embed[tp_rank]) if md.position_embeddings: model.language_model.embedding.position_embeddings.weight.data.copy_(pos_embed) else: assert not hasattr(model.language_model.embedding, "position_embeddings") # Transformer layers #------------------- total_layer_num = 0 for pp_rank in range(args.target_pipeline_parallel_size): # For later pipeline parallel ranks, make the new models if pp_rank > 0: mpu.set_pipeline_model_parallel_rank(pp_rank) post_process = pp_rank == args.target_pipeline_parallel_size - 1 models = get_models(args.target_tensor_parallel_size, md.params_dtype, False, post_process) for layer in range(len(models[0].language_model.encoder.layers)): msg = queue_get(f"transformer layer {total_layer_num}") # duplicated tensors input_layernorm_weight = msg.pop("input layernorm weight") input_layernorm_bias = msg.pop("input layernorm bias") post_layernorm_weight = msg.pop("post layernorm weight") post_layernorm_bias = msg.pop("post layernorm bias") if md.linear_bias: dense_bias = msg.pop("dense bias") mlp_l1_bias = msg.pop("mlp l1 bias") # Split up the parallel tensors qkv_weight = torch.chunk(msg.pop("qkv weight"), args.target_tensor_parallel_size, dim=0) dense_weight = torch.chunk(msg.pop("dense weight"), args.target_tensor_parallel_size, dim=1) mlp_l1_weight = torch.chunk(msg.pop("mlp l1 weight"), args.target_tensor_parallel_size, dim=1) # Special handling for swiglu if md.swiglu: mlp_l0_weight_W = torch.chunk(msg.pop("mlp l0 weight W"), args.target_tensor_parallel_size, dim=0) mlp_l0_weight_V = torch.chunk(msg.pop("mlp l0 weight V"), args.target_tensor_parallel_size, dim=0) mlp_l0_weight = [torch.cat(weights, dim=0) for weights in zip(mlp_l0_weight_W, mlp_l0_weight_V)] else: mlp_l0_weight = torch.chunk(msg.pop("mlp l0 weight"), args.target_tensor_parallel_size, dim=0) if md.linear_bias: qkv_bias = torch.chunk(msg.pop("qkv bias"), args.target_tensor_parallel_size, dim=0) if md.swiglu: mlp_l0_bias_W = torch.chunk(msg.pop("mlp l0 bias W"), args.target_tensor_parallel_size, dim=0) mlp_l0_bias_V = torch.chunk(msg.pop("mlp l0 bias V"), args.target_tensor_parallel_size, dim=0) mlp_l0_bias = [torch.cat(bias, dim=0) for bias in zip(mlp_l0_bias_W, mlp_l0_bias_V)] else: mlp_l0_bias = torch.chunk(msg.pop("mlp l0 bias"), args.target_tensor_parallel_size, dim=0) # Save them to the model for tp_rank in range(args.target_tensor_parallel_size): l = models[tp_rank].language_model.encoder.layers[layer] l.input_layernorm.weight.data.copy_(input_layernorm_weight) l.input_layernorm.bias.data.copy_(input_layernorm_bias) l.self_attention.query_key_value.weight.data.copy_(qkv_weight[tp_rank]) l.self_attention.dense.weight.data.copy_(dense_weight[tp_rank]) l.post_attention_layernorm.weight.data.copy_(post_layernorm_weight) l.post_attention_layernorm.bias.data.copy_(post_layernorm_bias) l.mlp.dense_h_to_4h.weight.data.copy_(mlp_l0_weight[tp_rank]) l.mlp.dense_4h_to_h.weight.data.copy_(mlp_l1_weight[tp_rank]) if md.linear_bias: l.self_attention.query_key_value.bias.data.copy_(qkv_bias[tp_rank]) l.self_attention.dense.bias.data.copy_(dense_bias) l.mlp.dense_h_to_4h.bias.data.copy_(mlp_l0_bias[tp_rank]) l.mlp.dense_4h_to_h.bias.data.copy_(mlp_l1_bias) total_layer_num = total_layer_num + 1 check_message(msg) if post_process: msg = queue_get("final layernorm") final_layernorm_weight = msg.pop("weight") final_layernorm_bias = msg.pop("bias") for tp_rank in range(args.target_tensor_parallel_size): models[tp_rank].language_model.encoder.final_layernorm.weight.data.copy_(final_layernorm_weight) models[tp_rank].language_model.encoder.final_layernorm.bias.data.copy_(final_layernorm_bias) if pp_rank != 0 and not md.output_layer: # Copy word embeddings to final pipeline rank models[tp_rank].word_embeddings.weight.data.copy_(out_word_embed[tp_rank]) del final_layernorm_weight del final_layernorm_bias check_message(msg) if md.output_layer: msg = queue_get("output layer") if not hasattr(models[0].language_model, 'output_layer'): print("ERROR: got an output layer, but model does not have one") exit(1) output_layer_weight = torch.chunk(msg.pop("weight"), args.target_tensor_parallel_size, dim=0) for tp_rank in range(args.target_tensor_parallel_size): models[tp_rank].language_model.output_layer.weight.data.copy_(output_layer_weight[tp_rank]) del output_layer_weight check_message(msg) msg = queue_get() if msg != "done" and msg["name"] == "pooler": if not hasattr(models[0].language_model, 'pooler'): print("ERROR: got a pooler, but model does not have one") exit(1) print("received pooler") pooler_weight = msg.pop("weight") pooler_bias = msg.pop("bias") for tp_rank in range(args.target_tensor_parallel_size): models[tp_rank].language_model.pooler.dense.weight.data.copy_(pooler_weight) models[tp_rank].language_model.pooler.dense.bias.data.copy_(pooler_bias) del pooler_weight del pooler_bias check_message(msg) msg = queue_get() if msg != "done" and msg["name"] == "lm head": if not hasattr(models[0], 'lm_head'): print("ERROR: got an lm head, but model does not have one") exit(1) print("received lm head") lm_head_dense_weight = msg.pop("dense weight") lm_head_dense_bias = msg.pop("dense bias") lm_head_layernorm_weight = msg.pop("layernorm weight") lm_head_layernorm_bias = msg.pop("layernorm bias") for tp_rank in range(args.target_tensor_parallel_size): models[tp_rank].lm_head.dense.weight.data.copy_(lm_head_dense_weight) models[tp_rank].lm_head.dense.bias.data.copy_(lm_head_dense_bias) models[tp_rank].lm_head.layernorm.weight.data.copy_(lm_head_layernorm_weight) models[tp_rank].lm_head.layernorm.bias.data.copy_(lm_head_layernorm_bias) check_message(msg) msg = queue_get() if msg != "done" and msg["name"] == "binary head": if not hasattr(models[0], 'binary_head'): print("ERROR: got a binary head, but model does not have one") exit(1) print("received binary head") binary_head_weight = msg.pop("weight") binary_head_bias = msg.pop("bias") for tp_rank in range(args.target_tensor_parallel_size): models[tp_rank].binary_head.weight.data.copy_(binary_head_weight) models[tp_rank].binary_head.bias.data.copy_(binary_head_bias) check_message(msg) msg = queue_get() if msg != "done": print("ERROR: got some more data but was expecting to be done") for tp_rank in range(args.target_tensor_parallel_size): mpu.set_tensor_model_parallel_rank(tp_rank) save_checkpoint(md.iteration, [models[tp_rank]], None, None) print("Done!") ================================================ FILE: llm-train/megatron/gpt2/merge_ck_and_inference/checkpoint_util.py ================================================ import argparse import importlib import torch.multiprocessing as mp import os import sys # A loader is a python file with at least two functions # - add_arguments - takes in a parser and adds any arguments needed # - load_checkpoint - takes in the queue and parsed arguments # A saver is similar but has save_checkpoint instead of # load_checkpoint # The loader and saver process are each given a queue, the loader # should load the checkpoint and send the weights in messages in the # following order, the saver should receive them in this order and # save the checkpoints. A message consists of a python dictionary with # a "name" for error checking and an entry for each tensor as # indicated below. Note that the weight sent over the queue are the # full model weights, nothing split. # If the loader ever sends "exit" to the queue, that means something # went wrong and it is exiting. # - Metadata Namespace with the following attributes: # model_type - GPT, BERT, T5, etc. (Part of protocol to allow this to be deduced later instead of given on command line) # num_layers - Number of transformer layers # hidden_size # seq_length # num_attention_heads # max_position_embeddings # tokenizer_type # iteration # params_dtype # bert_binary_head - Used only if model_type is BERT # previous_tensor_parallel_size - Optional # previous_pipeline_parallel_size - Optional # true_vocab_size # make_vocab_size_divisble_by # consumed_train_samples # consumed_valid_samples # messages # { # "name": "embeddings" # "position embeddings" # "word embeddings" # } # (for each transformer layer): # { # "name": "transformer layer N" # "input layernorm weight" # "input layernorm bias" # "qkv weight" # "qkv bias" # "dense weight" # "dense bias" # "post layernorm weight" # "post layernorm bias" # "mlp l0 weight" # "mlp l0 bias" # "mlp l1 weight" # "mlp l1 bias" # } # { # "name": "final layer norm" # "weight" # "bias" # } # if present (i.e. for BERT): # { # "name": "pooler" # "weight" # "bias" # } # { # "name": "lm head" # "dense weight" # "dense bias" # "layernorm weight" # "layernorm bias" # } # { # "name": "binary head" # "weight" # "bias" # } # - "done" def load_plugin(plugin_type, name): module_name = f"checkpoint_{plugin_type}_{name}" try: plugin = importlib.import_module(module_name) except ModuleNotFoundError: module_name = name try: plugin = importlib.import_module(module_name) except ModuleNotFoundError: sys.exit(f"Unable to load {plugin_type} plugin {name}. Exiting.") if not hasattr(plugin, 'add_arguments'): sys.exit(f"{module_name} module is not a plugin. Exiting.") print(f"Loaded {module_name} as the {plugin_type}.") return plugin def main(): import argparse parser = argparse.ArgumentParser(description="Megatron Checkpoint Utility Arguments", allow_abbrev=False, conflict_handler='resolve') parser.add_argument('--model-type', type=str, required=True, choices=['GPT', 'BERT'], help='Type of the model') parser.add_argument('--loader', type=str, default='megatron', help='Module name to load checkpoint, should be on python path') parser.add_argument('--saver', type=str, default='megatron', help='Module name to save checkpoint, shdoul be on python path') parser.add_argument('--load-dir', type=str, required=True, help='Directory to load model checkpoint from') parser.add_argument('--save-dir', type=str, required=True, help='Directory to save model checkpoint to') parser.add_argument('--max-queue-size', type=int, default=50, help='Maximum number of tensors in the queue') parser.add_argument('--no-checking', action='store_false', help='Do not perform checking on the name and ordering of weights', dest='checking') known_args, _ = parser.parse_known_args() loader = load_plugin('loader', known_args.loader) saver = load_plugin('saver', known_args.saver) loader.add_arguments(parser) saver.add_arguments(parser) args = parser.parse_args() queue = mp.Queue(maxsize=args.max_queue_size) print("Starting saver...") saver_proc = mp.Process(target=saver.save_checkpoint, args=(queue, args)) saver_proc.start() print("Starting loader...") loader.load_checkpoint(queue, args) print("Waiting for saver to complete...") saver_proc.join() if __name__ == '__main__': main() ================================================ FILE: llm-train/megatron/gpt2/merge_ck_and_inference/eval_gpt2_lambada.sh ================================================ TASK="LAMBADA" export MASTER_ADDR=localhost export MASTER_PORT=12355 export CUDA_DEVICE_MAX_CONNECTIONS=1 VALID_DATA=/workspace/data/lambada_test.jsonl VOCAB_FILE=/workspace/model/gpt2-vocab/gpt2-vocab.json MERGE_FILE=/workspace/model/gpt2-vocab/gpt2-merges.txt CHECKPOINT_PATH=/workspace/model/megatron-models/345m-init-mp-out COMMON_TASK_ARGS="--num-layers 24 \ --hidden-size 1024 \ --num-attention-heads 16 \ --seq-length 1024 \ --max-position-embeddings 1024 \ --fp16 \ --vocab-file $VOCAB_FILE" python tasks/main.py \ --task $TASK \ $COMMON_TASK_ARGS \ --valid-data $VALID_DATA \ --tokenizer-type GPT2BPETokenizer \ --strict-lambada \ --merge-file $MERGE_FILE \ --load $CHECKPOINT_PATH \ --micro-batch-size 8 \ --log-interval 10 \ --no-load-optim \ --no-load-rng ================================================ FILE: llm-train/megatron/gpt2/merge_ck_and_inference/run_text_generation_server.py ================================================ # Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. """Sample Generate GPT""" import os import sys sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) import socket from megatron import get_args from megatron import print_rank_0 from megatron.core import mpu from megatron.checkpointing import load_checkpoint from megatron.initialize import initialize_megatron from megatron.model import GPTModel from megatron.training import get_model from megatron.text_generation_server import MegatronServer from megatron.text_generation import generate_and_post_process from megatron.text_generation import beam_search_and_post_process import torch def model_provider(pre_process=True, post_process=True): """Build the model.""" print_rank_0('building GPT model ...') model = GPTModel(num_tokentypes=0, parallel_output=False, pre_process=pre_process, post_process=post_process) return model def add_text_generate_args(parser): group = parser.add_argument_group(title='text generation') group.add_argument("--temperature", type=float, default=1.0, help='Sampling temperature.') group.add_argument("--top_p", type=float, default=0.0, help='Top p sampling.') group.add_argument("--top_k", type=int, default=0, help='Top k sampling.') group.add_argument("--out-seq-length", type=int, default=1024, help='Size of the output generated text.') return parser if __name__ == "__main__": initialize_megatron(extra_args_provider=add_text_generate_args, args_defaults={'tokenizer_type': 'GPT2BPETokenizer', 'no_load_rng': True, 'no_load_optim': True}) args = get_args() if args.num_layers_per_virtual_pipeline_stage is not None: print("Interleaved pipeline schedule is not yet supported for text generation.") exit() # Set up model and load checkpoint model = get_model(model_provider, wrap_with_ddp=False) if args.load is not None: _ = load_checkpoint(model, None, None) assert len(model) == 1, "Above condition should have caught this" model = model[0] if mpu.is_pipeline_first_stage() and mpu.get_tensor_model_parallel_rank() == 0: server = MegatronServer(model) server.run("0.0.0.0") while True: choice = torch.cuda.LongTensor(1) torch.distributed.broadcast(choice, 0) if choice[0].item() == 0: try: generate_and_post_process(model) except ValueError as ve: pass elif choice[0].item() == 1: try: beam_search_and_post_process(model) except ValueError as ve: pass ================================================ FILE: llm-train/megatron/gpt2/merge_ck_and_inference/run_text_generation_server_345M.sh ================================================ #!/bin/bash # This example will start serving the 345M model. DISTRIBUTED_ARGS="--nproc_per_node 1 \ --nnodes 1 \ --node_rank 0 \ --master_addr localhost \ --master_port 6000" #CHECKPOINT= #VOCAB_FILE= #MERGE_FILE= CHECKPOINT=/workspace/model/megatron-models/345m-init-mp-out VOCAB_FILE=/workspace/model/gpt2-vocab/gpt2-vocab.json MERGE_FILE=/workspace/model/gpt2-vocab/gpt2-merges.txt export CUDA_DEVICE_MAX_CONNECTIONS=1 pip install flask-restful torchrun $DISTRIBUTED_ARGS tools/run_text_generation_server.py \ --tensor-model-parallel-size 1 \ --pipeline-model-parallel-size 1 \ --num-layers 24 \ --hidden-size 1024 \ --load ${CHECKPOINT} \ --num-attention-heads 16 \ --max-position-embeddings 1024 \ --tokenizer-type GPT2BPETokenizer \ --fp16 \ --micro-batch-size 1 \ --seq-length 1024 \ --out-seq-length 1024 \ --temperature 1.0 \ --vocab-file $VOCAB_FILE \ --merge-file $MERGE_FILE \ --top_p 0.9 \ --seed 42 ================================================ FILE: llm-train/megatron/gpt2/merge_ck_and_inference/run_text_generation_server_345M_2tp_2dp.sh ================================================ #!/bin/bash # This example will start serving the 345M model that is partitioned 8 way tensor parallel DISTRIBUTED_ARGS="--nproc_per_node 4 \ --nnodes 1 \ --node_rank 0 \ --master_addr localhost \ --master_port 6000" #CHECKPOINT= #VOCAB_FILE= #MERGE_FILE= VOCAB_FILE=/workspace/model/gpt2-vocab/gpt2-vocab.json MERGE_FILE=/workspace/model/gpt2-vocab/gpt2-merges.txt CHECKPOINT=/workspace/model/megatron-models/345m-init-mp export CUDA_DEVICE_MAX_CONNECTIONS=1 pip install flask-restful #python -m torch.distributed.launch torchrun $DISTRIBUTED_ARGS tools/run_text_generation_server.py \ --tensor-model-parallel-size 2 \ --pipeline-model-parallel-size 2 \ --num-layers 24 \ --hidden-size 1024 \ --load ${CHECKPOINT} \ --num-attention-heads 16 \ --max-position-embeddings 1024 \ --tokenizer-type GPT2BPETokenizer \ --fp16 \ --micro-batch-size 1 \ --seq-length 1024 \ --out-seq-length 1024 \ --temperature 1.0 \ --vocab-file $VOCAB_FILE \ --merge-file $MERGE_FILE \ --top_p 0.9 \ --seed 42 ================================================ FILE: llm-train/megatron/gpt2/merge_ck_and_inference/run_text_generation_server_345M_4_tensor_parallel.sh ================================================ #!/bin/bash # This example will start serving the 345M model that is partitioned 8 way tensor parallel DISTRIBUTED_ARGS="--nproc_per_node 4 \ --nnodes 1 \ --node_rank 0 \ --master_addr localhost \ --master_port 6000" #CHECKPOINT= #VOCAB_FILE= #MERGE_FILE= VOCAB_FILE=/workspace/model/gpt2-vocab/gpt2-vocab.json MERGE_FILE=/workspace/model/gpt2-vocab/gpt2-merges.txt CHECKPOINT=/workspace/model/megatron-models/345m-init-4tp pip install flask-restful export CUDA_DEVICE_MAX_CONNECTIONS=1 #python -m torch.distributed.launch torchrun $DISTRIBUTED_ARGS tools/run_text_generation_server.py \ --tensor-model-parallel-size 4 \ --pipeline-model-parallel-size 1 \ --num-layers 24 \ --hidden-size 1024 \ --load ${CHECKPOINT} \ --num-attention-heads 16 \ --max-position-embeddings 1024 \ --tokenizer-type GPT2BPETokenizer \ --fp16 \ --micro-batch-size 1 \ --seq-length 1024 \ --out-seq-length 1024 \ --temperature 1.0 \ --vocab-file $VOCAB_FILE \ --merge-file $MERGE_FILE \ --top_p 0.9 \ --seed 42 ================================================ FILE: llm-train/megatron/gpt2/merge_ck_and_inference/text_generation_cli.py ================================================ # Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. import sys import json import requests if __name__ == "__main__": url = sys.argv[1] url = 'http://' + url + '/api' headers = {'Content-Type': 'application/json'} while True: sentence = input("Enter prompt: ") tokens_to_generate = int(eval(input("Enter number of tokens to generate: "))) data = {"prompts": [sentence], "tokens_to_generate": tokens_to_generate} response = requests.put(url, data=json.dumps(data), headers=headers) if response.status_code != 200: print(f"Error {response.status_code}: {response.json()['message']}") else: print("Megatron Response: ") print(response.json()['text'][0]) ================================================ FILE: llm-train/megatron/gpt2/model_merge_eval_inference.md ================================================ ## 权重合并 ``` python tools/checkpoint_util.py \ --model-type GPT \ --load-dir /workspace/model/megatron-models/345m-init-mp\ --save-dir /workspace/model/megatron-models/345m-init-mp-out \ --target-tensor-parallel-size 1 \ --target-pipeline-parallel-size 1 ```
详细输出:

``` > tree -h /workspace/model/megatron-models/345m-init-mp-out /workspace/model/megatron-models/345m-init-mp-out ├── [4.0K] iter_0005000 │ └── [4.0K] mp_rank_00 │ └── [1.3G] model_optim_rng.pt └── [ 4] latest_checkpointed_iteration.txt 2 directories, 2 files ```

详细输出:

``` > python tools/checkpoint_util.py --model-type GPT --load-dir /workspace/model/megatron-models/345m-init-mp --save-dir /workspace/model/megatron-models/345m-init-mp-out --target-tensor-parallel-size 1 --target-pipeline-parallel-size 1 Loaded checkpoint_loader_megatron as the loader. Loaded checkpoint_saver_megatron as the saver. Starting saver... Starting loader... Namespace(DDP_impl='local', accumulate_allreduce_grads_in_fp32=False, adam_beta1=0.9, adam_beta2=0.999, adam_eps=1e-08, add_bias_linear=True, add_position_embedding=True, adlr_autoresume=False, adlr_autoresume_interval=1000, apply_layernorm_1p=False, apply_query_key_layer_scaling=True, apply_residual_connection_post_layernorm=False, async_tensor_model_parallel_allreduce=False, attention_dropout=0.1, attention_softmax_in_fp32=False, barrier_with_L1_time=True, batch_size=None, bert_binary_head=True, bert_embedder_type='megatron', bert_load=None, bf16=False, bias_dropout_fusion=False, bias_gelu_fusion=False, biencoder_projection_dim=0, biencoder_shared_query_context_model=False, block_data_path=None, checkpoint_activations=False, classes_fraction=1.0, clip_grad=1.0, data_cache_path=None, data_impl='infer', data_parallel_random_init=False, data_path=None, data_per_class_fraction=1.0, data_sharding=True, dataloader_type=None, decoder_num_layers=None, decoder_seq_length=None, dino_bottleneck_size=256, dino_freeze_last_layer=1, dino_head_hidden_size=2048, dino_local_crops_number=10, dino_local_img_size=96, dino_norm_last_layer=False, dino_teacher_temp=0.07, dino_warmup_teacher_temp=0.04, dino_warmup_teacher_temp_epochs=30, distribute_saved_activations=False, distributed_backend='nccl', distributed_timeout_minutes=10, embedding_path=None, empty_unused_memory_level=0, encoder_num_layers=None, encoder_seq_length=None, end_weight_decay=None, eod_mask_loss=False, eval_interval=1000, eval_iters=100, evidence_data_path=None, exit_duration_in_mins=None, exit_interval=None, exit_on_missing_checkpoint=False, exit_signal_handler=False, ffn_hidden_size=None, finetune=False, fp16=False, fp16_lm_cross_entropy=False, fp32_residual_connection=False, fp8_amax_compute_algo='most_recent', fp8_amax_history_len=1, fp8_e4m3=False, fp8_hybrid=False, fp8_interval=1, fp8_margin=0, fp8_wgrad=True, global_batch_size=None, gradient_accumulation_fusion=True, head_lr_mult=1.0, hidden_dropout=0.1, hidden_size=None, hysteresis=2, ict_head_size=None, ict_load=None, img_h=224, img_w=224, indexer_batch_size=128, indexer_log_interval=1000, inference_batch_times_seqlen_threshold=512, init_method_std=0.02, init_method_xavier_uniform=False, initial_loss_scale=4294967296, iter_per_epoch=1250, kv_channels=None, layernorm_epsilon=1e-05, lazy_mpu_init=None, load='/workspace/model/megatron-models/345m-init-mp', local_rank=None, log_batch_size_to_tensorboard=False, log_interval=100, log_learning_rate_to_tensorboard=True, log_loss_scale_to_tensorboard=True, log_memory_to_tensorboard=False, log_num_zeros_in_grad=False, log_params_norm=False, log_timers_to_tensorboard=False, log_validation_ppl_to_tensorboard=False, log_world_size_to_tensorboard=False, loss_scale=None, loss_scale_window=1000, lr=None, lr_decay_iters=None, lr_decay_samples=None, lr_decay_style='linear', lr_warmup_fraction=None, lr_warmup_iters=0, lr_warmup_samples=0, make_vocab_size_divisible_by=128, mask_factor=1.0, mask_prob=0.15, mask_type='random', masked_softmax_fusion=False, max_position_embeddings=None, max_tokens_to_oom=12000, merge_file=None, micro_batch_size=1, min_loss_scale=1.0, min_lr=0.0, mmap_warmup=False, model_parallel_size=None, no_load_optim=True, no_load_rng=True, no_persist_layer_norm=False, no_save_optim=True, no_save_rng=True, num_attention_heads=None, num_channels=3, num_classes=1000, num_experts=None, num_layers=None, num_layers_per_virtual_pipeline_stage=None, num_workers=2, onnx_safe=None, openai_gelu=False, optimizer='adam', output_bert_embeddings=False, overlap_p2p_comm=False, override_opt_param_scheduler=False, patch_dim=16, perform_initialization=False, pipeline_model_parallel_size=1, pipeline_model_parallel_split_rank=None, query_in_block_prob=0.1, rampup_batch_size=None, rank=0, recompute_activations=False, recompute_granularity=None, recompute_method=None, recompute_num_layers=1, reset_attention_mask=False, reset_position_ids=False, retriever_report_topk_accuracies=[], retriever_score_scaling=False, retriever_seq_length=256, retro_add_retriever=False, retro_cyclic_train_iters=None, retro_encoder_attention_dropout=0.1, retro_encoder_hidden_dropout=0.1, retro_encoder_layers=2, retro_num_neighbors=2, retro_num_retrieved_chunks=2, retro_return_doc_ids=False, retro_workdir=None, rotary_percent=1.0, sample_rate=1.0, save=None, save_interval=None, scatter_gather_tensors_in_pipeline=True, seed=1234, seq_length=None, sequence_parallel=False, sgd_momentum=0.9, short_seq_prob=0.1, split='969, 30, 1', squared_relu=False, standalone_embedding_stage=False, start_weight_decay=None, swiglu=False, swin_backbone_type='tiny', tensor_model_parallel_size=1, tensorboard_dir=None, tensorboard_log_interval=1, tensorboard_queue_size=1000, test_data_path=None, timing_log_level=0, timing_log_option='minmax', titles_data_path=None, tokenizer_model=None, tokenizer_type=None, train_data_path=None, train_iters=None, train_samples=None, transformer_impl='local', untie_embeddings_and_output_weights=False, use_checkpoint_args=False, use_checkpoint_opt_param_scheduler=False, use_contiguous_buffers_in_local_ddp=True, use_cpu_initialization=True, use_distributed_optimizer=False, use_flash_attn=False, use_one_sent_docs=False, use_ring_exchange_p2p=False, use_rotary_position_embeddings=False, valid_data_path=None, vision_backbone_type='vit', vision_pretraining=False, vision_pretraining_type='classify', vocab_extra_ids=0, vocab_file=None, vocab_size=None, warmup=None, weight_decay=0.01, weight_decay_incr_style='constant', world_size=1) Setting num_layers to 24 from checkpoint Setting hidden_size to 1024 from checkpoint Setting ffn_hidden_size to 4096 from checkpoint Setting seq_length to 1024 from checkpoint Setting num_attention_heads to 16 from checkpoint Setting kv_channels to 64 from checkpoint Setting max_position_embeddings to 1024 from checkpoint Setting add_position_embedding to True from checkpoint Setting use_rotary_position_embeddings to False from checkpoint Setting rotary_percent to 1.0 from checkpoint Setting add_bias_linear to True from checkpoint Setting swiglu to False from checkpoint Setting untie_embeddings_and_output_weights to False from checkpoint Setting apply_layernorm_1p to False from checkpoint Setting tokenizer_type to GPT2BPETokenizer from checkpoint Setting padded_vocab_size to 50432 from checkpoint Setting tensor_model_parallel_size to 2 from checkpoint Setting pipeline_model_parallel_size to 2 from checkpoint Checkpoint did not provide arguments virtual_pipeline_model_parallel_size Checkpoint did not provide arguments num_layers_per_virtual_pipeline_stage using world size: 4, data-parallel-size: 1, tensor-model-parallel size: 2, pipeline-model-parallel size: 2 setting global batch size to 1 using torch.float32 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... False attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. False bias_gelu_fusion ................................ False biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... infer data_parallel_random_init ....................... False data_parallel_size .............................. 1 data_path ....................................... None data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 100 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ False fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 1 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 iteration ....................................... 5000 kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m-init-mp local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 100 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. None lr_decay_iters .................................. None lr_decay_samples ................................ None lr_decay_style .................................. linear lr_warmup_fraction .............................. None lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... False max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 1 min_loss_scale .................................. 1.0 min_lr .......................................... 0.0 mmap_warmup ..................................... False no_load_optim ................................... True no_load_rng ..................................... True no_persist_layer_norm ........................... False no_save_optim ................................... True no_save_rng ..................................... True num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False padded_vocab_size ............................... 50432 params_dtype .................................... torch.float32 patch_dim ....................................... 16 perform_initialization .......................... False pipeline_model_parallel_size .................... 2 pipeline_model_parallel_split_rank .............. None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ None save_interval ................................... None scatter_gather_tensors_in_pipeline .............. True seed ............................................ 1234 seq_length ...................................... 1024 sequence_parallel ............................... False sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 split ........................................... 969, 30, 1 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 swiglu .......................................... False swin_backbone_type .............................. tiny tensor_model_parallel_size ...................... 2 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer train_data_path ................................. None train_iters ..................................... None train_samples ................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 2 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... True use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 4 -------------------- end of arguments --------------------- setting number of micro-batches to constant 1 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 175 dummy tokens (new size: 50432) building GPT model ... loading checkpoint from /workspace/model/megatron-models/345m-init-mp at iteration 5000 checkpoint version 3.0 successfully loaded checkpoint from /workspace/model/megatron-models/345m-init-mp at iteration 5000 building GPT model ... loading checkpoint from /workspace/model/megatron-models/345m-init-mp at iteration 5000 checkpoint version 3.0 successfully loaded checkpoint from /workspace/model/megatron-models/345m-init-mp at iteration 5000 Overwriting default ffn_hidden_size value None with value from checkpoint 4096. Overwriting default kv_channels value None with value from checkpoint 64. Overwriting default micro_batch_size value 1 with value from checkpoint 4. Overwriting default global_batch_size value None with value from checkpoint 16. Overwriting default dataloader_type value None with value from checkpoint single. Overwriting default lr value None with value from checkpoint 0.00015. Overwriting default lr_decay_style value linear with value from checkpoint cosine. Overwriting default min_lr value 0.0 with value from checkpoint 1e-05. Overwriting default load value None with value from checkpoint /workspace/model/megatron-models/345m-init-mp. Overwriting default fp16 value False with value from checkpoint True. Overwriting default local_rank value None with value from checkpoint 0. Overwriting default eval_iters value 100 with value from checkpoint 10. Overwriting default data_path value None with value from checkpoint ['/workspace/data/my-gpt2_text_document']. Overwriting default split value 969, 30, 1 with value from checkpoint 700,200,100. Overwriting default data_impl value infer with value from checkpoint mmap. Overwriting default world_size value 1 with value from checkpoint 4. Checkpoint had argument transformer_pipeline_model_parallel_size but new arguments does not have this. Checkpoint had argument data_parallel_size but new arguments does not have this. Checkpoint had argument consumed_train_samples but new arguments does not have this. Checkpoint had argument consumed_valid_samples but new arguments does not have this. Checkpoint had argument variable_seq_lengths but new arguments does not have this. Checkpoint had argument padded_vocab_size but new arguments does not have this. Checkpoint had argument model_type but new arguments does not have this. Checkpoint had argument allow_transformer_engine but new arguments does not have this. Checkpoint had argument iteration but new arguments does not have this. Checkpoint had argument do_train but new arguments does not have this. Checkpoint had argument do_valid but new arguments does not have this. Checkpoint had argument do_test but new arguments does not have this. Checkpoint had argument curr_iteration but new arguments does not have this. using world size: 4, data-parallel-size: 4, tensor-model-parallel size: 1, pipeline-model-parallel size: 1 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... False attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. False bias_gelu_fusion ................................ False biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... mmap data_parallel_random_init ....................... False data_parallel_size .............................. 4 data_path ....................................... ['/workspace/data/my-gpt2_text_document'] data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 10 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 16 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m-init-mp local_rank ...................................... 0 log_batch_size_to_tensorboard ................... False log_interval .................................... 100 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. 0.00015 lr_decay_iters .................................. None lr_decay_samples ................................ None lr_decay_style .................................. cosine lr_warmup_fraction .............................. None lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... False max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 4 min_loss_scale .................................. 1.0 min_lr .......................................... 1e-05 mmap_warmup ..................................... False no_load_optim ................................... True no_load_rng ..................................... True no_persist_layer_norm ........................... False no_save_optim ................................... True no_save_rng ..................................... True num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 patch_dim ....................................... 16 perform_initialization .......................... False pipeline_model_parallel_size .................... 1 pipeline_model_parallel_split_rank .............. None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ /workspace/model/megatron-models/345m-init-mp-out save_interval ................................... 1 scatter_gather_tensors_in_pipeline .............. True seed ............................................ 1234 seq_length ...................................... 1024 sequence_parallel ............................... False sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 split ........................................... 700,200,100 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 swiglu .......................................... False swin_backbone_type .............................. tiny tensor_model_parallel_size ...................... 1 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer train_data_path ................................. None train_iters ..................................... None train_samples ................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 1 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... True use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 4 -------------------- end of arguments --------------------- setting number of micro-batches to constant 1 > building GPT2BPETokenizer tokenizer ... sending embeddings sending transformer layer 0 sending transformer layer 1 > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) Setting consumed_train_samples to 80000 and consumed_valid_samples to 960 sending transformer layer 2 ... sending transformer layer 11 building GPT model ... loading checkpoint from /workspace/model/megatron-models/345m-init-mp at iteration 5000 received embeddings > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) building GPT model ... received transformer layer 0 ... received transformer layer 11 checkpoint version 3.0 successfully loaded checkpoint from /workspace/model/megatron-models/345m-init-mp at iteration 5000 building GPT model ... loading checkpoint from /workspace/model/megatron-models/345m-init-mp at iteration 5000 checkpoint version 3.0 successfully loaded checkpoint from /workspace/model/megatron-models/345m-init-mp at iteration 5000 sending transformer layer 12 sending transformer layer 13 sending transformer layer 14 sending transformer layer 15 received transformer layer 12 received transformer layer 13 sending transformer layer 16 sending transformer layer 17 sending transformer layer 18 received transformer layer 14 sending transformer layer 19 sending transformer layer 20 sending transformer layer 21 sending transformer layer 22 received transformer layer 15 received transformer layer 16 received transformer layer 17 sending transformer layer 23 sending final layernorm received transformer layer 18 Waiting for saver to complete... received transformer layer 19 received transformer layer 20 received transformer layer 21 received transformer layer 22 received transformer layer 23 received final layernorm saving checkpoint at iteration 5000 to /workspace/model/megatron-models/345m-init-mp-out successfully saved checkpoint at iteration 5000 to /workspace/model/megatron-models/345m-init-mp-out Done! ```

``` python tools/checkpoint_util.py \ --model-type GPT \ --load-dir /workspace/model/megatron-models/345m-init-mp\ --save-dir /workspace/model/megatron-models/345m-init-mp-out-2tp \ --target-tensor-parallel-size 2 \ --target-pipeline-parallel-size 1 ``` ``` tree -h /workspace/model/megatron-models/345m-init-mp-out-2tp /workspace/model/megatron-models/345m-init-mp-out-2tp ├── [4.0K] iter_0005000 │ ├── [4.0K] mp_rank_00 │ │ └── [680M] model_optim_rng.pt │ └── [4.0K] mp_rank_01 │ └── [680M] model_optim_rng.pt └── [ 4] latest_checkpointed_iteration.txt 3 directories, 3 files ``` ``` python tools/checkpoint_util.py \ --model-type GPT \ --load-dir /workspace/model/megatron-models/345m-init-mp\ --save-dir /workspace/model/megatron-models/345m-init-mp-out-4pp \ --target-tensor-parallel-size 1 \ --target-pipeline-parallel-size 4 ``` ``` tree -h /workspace/model/megatron-models/345m-init-mp-out-4pp /workspace/model/megatron-models/345m-init-mp-out-4pp ├── [4.0K] iter_0005000 │ ├── [4.0K] mp_rank_00_000 │ │ └── [489M] model_optim_rng.pt │ ├── [4.0K] mp_rank_00_001 │ │ └── [288M] model_optim_rng.pt │ ├── [4.0K] mp_rank_00_002 │ │ └── [288M] model_optim_rng.pt │ └── [4.0K] mp_rank_00_003 │ └── [485M] model_optim_rng.pt └── [ 4] latest_checkpointed_iteration.txt ``` ## 模型服务 ``` pip install flask -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn pip install flask-restful -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn ``` ``` vim examples/run_text_generation_server_345M.sh ``` 启动服务:
详细输出:

``` > sh examples/run_text_generation_server_345M.sh Looking in indexes: https://pypi.org/simple, https://pypi.ngc.nvidia.com Requirement already satisfied: flask-restful in /usr/local/lib/python3.8/dist-packages (0.3.10) Requirement already satisfied: aniso8601>=0.82 in /usr/local/lib/python3.8/dist-packages (from flask-restful) (9.0.1) Requirement already satisfied: pytz in /usr/local/lib/python3.8/dist-packages (from flask-restful) (2023.3) Requirement already satisfied: six>=1.3.0 in /usr/local/lib/python3.8/dist-packages (from flask-restful) (1.16.0) Requirement already satisfied: Flask>=0.8 in /usr/local/lib/python3.8/dist-packages (from flask-restful) (2.3.2) Requirement already satisfied: itsdangerous>=2.1.2 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (2.1.2) Requirement already satisfied: importlib-metadata>=3.6.0 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (6.3.0) Requirement already satisfied: Jinja2>=3.1.2 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (3.1.2) Requirement already satisfied: Werkzeug>=2.3.3 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (2.3.6) Requirement already satisfied: blinker>=1.6.2 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (1.6.2) Requirement already satisfied: click>=8.1.3 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (8.1.3) Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.8/dist-packages (from importlib-metadata>=3.6.0->Flask>=0.8->flask-restful) (3.15.0) Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.8/dist-packages (from Jinja2>=3.1.2->Flask>=0.8->flask-restful) (2.1.2) WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv WARNING: You are using pip version 21.2.4; however, version 23.2.1 is available. You should consider upgrading via the '/usr/bin/python -m pip install --upgrade pip' command. using world size: 1, data-parallel-size: 1, tensor-model-parallel size: 1, pipeline-model-parallel size: 1 WARNING: overriding default arguments for tokenizer_type:GPT2BPETokenizer with tokenizer_type:GPT2BPETokenizer setting global batch size to 1 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... True attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. True bias_gelu_fusion ................................ True biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... infer data_parallel_random_init ....................... False data_parallel_size .............................. 1 data_path ....................................... None data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 100 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 1 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m-init-mp-out local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 100 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. None lr_decay_iters .................................. None lr_decay_samples ................................ None lr_decay_style .................................. linear lr_warmup_fraction .............................. None lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... True max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 1 min_loss_scale .................................. 1.0 min_lr .......................................... 0.0 mmap_warmup ..................................... False no_load_optim ................................... True no_load_rng ..................................... True no_persist_layer_norm ........................... False no_save_optim ................................... None no_save_rng ..................................... None num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam out_seq_length .................................. 1024 output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 patch_dim ....................................... 16 perform_initialization .......................... True pipeline_model_parallel_size .................... 1 pipeline_model_parallel_split_rank .............. None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ None save_interval ................................... None scatter_gather_tensors_in_pipeline .............. True seed ............................................ 42 seq_length ...................................... 1024 sequence_parallel ............................... False sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 split ........................................... 969, 30, 1 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 swiglu .......................................... False swin_backbone_type .............................. tiny temperature ..................................... 1.0 tensor_model_parallel_size ...................... 1 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer top_k ........................................... 0 top_p ........................................... 0.9 train_data_path ................................. None train_iters ..................................... None train_samples ................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 1 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... None use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 1 -------------------- end of arguments --------------------- setting number of micro-batches to constant 1 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > initializing torch distributed ... > initialized tensor model parallel with size 1 > initialized pipeline model parallel with size 1 > setting random seeds to 42 ... > compiling dataset index builder ... make: Entering directory '/workspace/code/Megatron-LM/megatron/data' make: Nothing to be done for 'default'. make: Leaving directory '/workspace/code/Megatron-LM/megatron/data' >>> done with dataset index builder. Compilation time: 0.237 seconds > compiling and loading fused kernels ... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_upper_triang_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_upper_triang_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_softmax_cuda... >>> done with compiling and loading fused kernels. Compilation time: 1.632 seconds building GPT model ... > number of parameters on (tensor, pipeline) model parallel rank (0, 0): 354871296 loading checkpoint from /workspace/model/megatron-models/345m-init-mp-out at iteration 5000 checkpoint version 3.0 successfully loaded checkpoint from /workspace/model/megatron-models/345m-init-mp-out at iteration 5000 * Serving Flask app 'megatron.text_generation_server' * Debug mode: off WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 * Running on http://192.168.78.1:5000 Press CTRL+C to quit request IP: 127.0.0.1 {"prompts": ["Hello world"], "tokens_to_generate": 1} start time: 2023-07-23 16:00:12.738873 127.0.0.1 - - [23/Jul/2023 16:00:14] "PUT /api HTTP/1.1" 200 - request IP: 127.0.0.1 {"prompts": ["hello"], "tokens_to_generate": 5} start time: 2023-07-23 16:02:46.352169 127.0.0.1 - - [23/Jul/2023 16:02:47] "PUT /api HTTP/1.1" 200 - request IP: 127.0.0.1 {"prompts": ["world"], "tokens_to_generate": 2} start time: 2023-07-23 16:03:23.518545 127.0.0.1 - - [23/Jul/2023 16:03:23] "PUT /api HTTP/1.1" 200 - ```

``` > curl 'http://localhost:5000/api' -X 'PUT' -H 'Content-Type: application/json; charset=UTF-8' -d '{"prompts":["Hello world"], "tokens_to_generate":1}' {"logprobs":null,"segments":[["Hello"," world",","]],"text":["Hello world,"]} ```
详细输出:

``` > python tools/text_generation_cli.py localhost:5000 Enter prompt: hello Enter number of tokens to generate: 5 Megatron Response: hello! Until that protagonist receive Enter prompt: world Enter number of tokens to generate: 2 Megatron Response: worldboarding- Enter prompt: ```

### 4TP
详细输出:

``` > sh examples/run_text_generation_server_345M_4_tensor_parallel.sh Looking in indexes: https://pypi.org/simple, https://pypi.ngc.nvidia.com Requirement already satisfied: flask-restful in /usr/local/lib/python3.8/dist-packages (0.3.10) Requirement already satisfied: six>=1.3.0 in /usr/local/lib/python3.8/dist-packages (from flask-restful) (1.16.0) Requirement already satisfied: pytz in /usr/local/lib/python3.8/dist-packages (from flask-restful) (2023.3) Requirement already satisfied: aniso8601>=0.82 in /usr/local/lib/python3.8/dist-packages (from flask-restful) (9.0.1) Requirement already satisfied: Flask>=0.8 in /usr/local/lib/python3.8/dist-packages (from flask-restful) (2.3.2) Requirement already satisfied: blinker>=1.6.2 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (1.6.2) Requirement already satisfied: Werkzeug>=2.3.3 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (2.3.6) Requirement already satisfied: importlib-metadata>=3.6.0 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (6.3.0) Requirement already satisfied: click>=8.1.3 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (8.1.3) Requirement already satisfied: itsdangerous>=2.1.2 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (2.1.2) Requirement already satisfied: Jinja2>=3.1.2 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (3.1.2) Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.8/dist-packages (from importlib-metadata>=3.6.0->Flask>=0.8->flask-restful) (3.15.0) Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.8/dist-packages (from Jinja2>=3.1.2->Flask>=0.8->flask-restful) (2.1.2) WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv WARNING: You are using pip version 21.2.4; however, version 23.2.1 is available. You should consider upgrading via the '/usr/bin/python -m pip install --upgrade pip' command. WARNING:torch.distributed.run: ***************************************** Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. ***************************************** using world size: 4, data-parallel-size: 1, tensor-model-parallel size: 4, pipeline-model-parallel size: 1 WARNING: overriding default arguments for tokenizer_type:GPT2BPETokenizer with tokenizer_type:GPT2BPETokenizer setting global batch size to 1 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... True attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. True bias_gelu_fusion ................................ True biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... infer data_parallel_random_init ....................... False data_parallel_size .............................. 1 data_path ....................................... None data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 100 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 1 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m-init-4tp local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 100 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. None lr_decay_iters .................................. None lr_decay_samples ................................ None lr_decay_style .................................. linear lr_warmup_fraction .............................. None lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... True max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 1 min_loss_scale .................................. 1.0 min_lr .......................................... 0.0 mmap_warmup ..................................... False no_load_optim ................................... True no_load_rng ..................................... True no_persist_layer_norm ........................... False no_save_optim ................................... None no_save_rng ..................................... None num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam out_seq_length .................................. 1024 output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 patch_dim ....................................... 16 perform_initialization .......................... True pipeline_model_parallel_size .................... 1 pipeline_model_parallel_split_rank .............. None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ None save_interval ................................... None scatter_gather_tensors_in_pipeline .............. True seed ............................................ 42 seq_length ...................................... 1024 sequence_parallel ............................... False sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 split ........................................... 969, 30, 1 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 swiglu .......................................... False swin_backbone_type .............................. tiny temperature ..................................... 1.0 tensor_model_parallel_size ...................... 4 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer top_k ........................................... 0 top_p ........................................... 0.9 train_data_path ................................. None train_iters ..................................... None train_samples ................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 1 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... None use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 4 -------------------- end of arguments --------------------- setting number of micro-batches to constant 1 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 431 dummy tokens (new size: 50688) > initializing torch distributed ... > initialized tensor model parallel with size 4 > initialized pipeline model parallel with size 1 > setting random seeds to 42 ... > compiling dataset index builder ... make: Entering directory '/workspace/code/Megatron-LM/megatron/data' make: Nothing to be done for 'default'. make: Leaving directory '/workspace/code/Megatron-LM/megatron/data' >>> done with dataset index builder. Compilation time: 0.185 seconds > compiling and loading fused kernels ... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_upper_triang_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_upper_triang_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_softmax_cuda... >>> done with compiling and loading fused kernels. Compilation time: 3.342 seconds building GPT model ... > number of parameters on (tensor, pipeline) model parallel rank (2, 0): 89714688 > number of parameters on (tensor, pipeline) model parallel rank (3, 0): 89714688 > number of parameters on (tensor, pipeline) model parallel rank (0, 0): 89714688 > number of parameters on (tensor, pipeline) model parallel rank (1, 0): 89714688 loading checkpoint from /workspace/model/megatron-models/345m-init-4tp at iteration 2000 checkpoint version 3.0 successfully loaded checkpoint from /workspace/model/megatron-models/345m-init-4tp at iteration 2000 * Serving Flask app 'megatron.text_generation_server' * Debug mode: off WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 * Running on http://192.168.78.1:5000 Press CTRL+C to quit request IP: 127.0.0.1 {"prompts": ["Hello world"], "tokens_to_generate": 1} start time: 2023-07-24 08:02:14.824674 127.0.0.1 - - [24/Jul/2023 08:02:18] "PUT /api HTTP/1.1" 200 - ```

详细输出:

``` +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 1844443 C /usr/bin/python 788MiB | | 1 N/A N/A 1844444 C /usr/bin/python 788MiB | | 2 N/A N/A 1844445 C /usr/bin/python 788MiB | | 3 N/A N/A 1844446 C /usr/bin/python 788MiB | +-----------------------------------------------------------------------------+ ```

### 2TP+2PP
详细输出:

``` sh examples/run_text_generation_server_345M_2tp_2dp.sh Looking in indexes: https://pypi.org/simple, https://pypi.ngc.nvidia.com Requirement already satisfied: flask-restful in /usr/local/lib/python3.8/dist-packages (0.3.10) Requirement already satisfied: six>=1.3.0 in /usr/local/lib/python3.8/dist-packages (from flask-restful) (1.16.0) Requirement already satisfied: pytz in /usr/local/lib/python3.8/dist-packages (from flask-restful) (2023.3) Requirement already satisfied: aniso8601>=0.82 in /usr/local/lib/python3.8/dist-packages (from flask-restful) (9.0.1) Requirement already satisfied: Flask>=0.8 in /usr/local/lib/python3.8/dist-packages (from flask-restful) (2.3.2) Requirement already satisfied: Jinja2>=3.1.2 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (3.1.2) Requirement already satisfied: Werkzeug>=2.3.3 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (2.3.6) Requirement already satisfied: blinker>=1.6.2 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (1.6.2) Requirement already satisfied: click>=8.1.3 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (8.1.3) Requirement already satisfied: importlib-metadata>=3.6.0 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (6.3.0) Requirement already satisfied: itsdangerous>=2.1.2 in /usr/local/lib/python3.8/dist-packages (from Flask>=0.8->flask-restful) (2.1.2) Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.8/dist-packages (from importlib-metadata>=3.6.0->Flask>=0.8->flask-restful) (3.15.0) Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.8/dist-packages (from Jinja2>=3.1.2->Flask>=0.8->flask-restful) (2.1.2) WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv WARNING: You are using pip version 21.2.4; however, version 23.2.1 is available. You should consider upgrading via the '/usr/bin/python -m pip install --upgrade pip' command. WARNING:torch.distributed.run: ***************************************** Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. ***************************************** using world size: 4, data-parallel-size: 1, tensor-model-parallel size: 2, pipeline-model-parallel size: 2 WARNING: overriding default arguments for tokenizer_type:GPT2BPETokenizer with tokenizer_type:GPT2BPETokenizer setting global batch size to 1 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... True attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. True bias_gelu_fusion ................................ True biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... infer data_parallel_random_init ....................... False data_parallel_size .............................. 1 data_path ....................................... None data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 100 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 1 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m-init-mp local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 100 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. None lr_decay_iters .................................. None lr_decay_samples ................................ None lr_decay_style .................................. linear lr_warmup_fraction .............................. None lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... True max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 1 min_loss_scale .................................. 1.0 min_lr .......................................... 0.0 mmap_warmup ..................................... False no_load_optim ................................... True no_load_rng ..................................... True no_persist_layer_norm ........................... False no_save_optim ................................... None no_save_rng ..................................... None num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam out_seq_length .................................. 1024 output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 patch_dim ....................................... 16 perform_initialization .......................... True pipeline_model_parallel_size .................... 2 pipeline_model_parallel_split_rank .............. None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ None save_interval ................................... None scatter_gather_tensors_in_pipeline .............. True seed ............................................ 42 seq_length ...................................... 1024 sequence_parallel ............................... False sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 split ........................................... 969, 30, 1 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 swiglu .......................................... False swin_backbone_type .............................. tiny temperature ..................................... 1.0 tensor_model_parallel_size ...................... 2 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer top_k ........................................... 0 top_p ........................................... 0.9 train_data_path ................................. None train_iters ..................................... None train_samples ................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 2 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... None use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 4 -------------------- end of arguments --------------------- setting number of micro-batches to constant 1 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 175 dummy tokens (new size: 50432) > initializing torch distributed ... > initialized tensor model parallel with size 2 > initialized pipeline model parallel with size 2 > setting random seeds to 42 ... > compiling dataset index builder ... make: Entering directory '/workspace/code/Megatron-LM/megatron/data' make: Nothing to be done for 'default'. make: Leaving directory '/workspace/code/Megatron-LM/megatron/data' >>> done with dataset index builder. Compilation time: 0.206 seconds > compiling and loading fused kernels ... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_upper_triang_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_upper_triang_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_softmax_cuda... >>> done with compiling and loading fused kernels. Compilation time: 3.460 seconds building GPT model ... > number of parameters on (tensor, pipeline) model parallel rank (0, 0): 102483968 > number of parameters on (tensor, pipeline) model parallel rank (0, 1): 101437440 > number of parameters on (tensor, pipeline) model parallel rank (1, 1): 101437440 > number of parameters on (tensor, pipeline) model parallel rank (1, 0): 102483968 loading checkpoint from /workspace/model/megatron-models/345m-init-mp at iteration 5000 checkpoint version 3.0 successfully loaded checkpoint from /workspace/model/megatron-models/345m-init-mp at iteration 5000 * Serving Flask app 'megatron.text_generation_server' * Debug mode: off WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 * Running on http://192.168.78.1:5000 Press CTRL+C to quit request IP: 127.0.0.1 {"prompts": ["hello"], "tokens_to_generate": 5} start time: 2023-07-24 08:11:43.956061 [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) 127.0.0.1 - - [24/Jul/2023 08:11:53] "PUT /api HTTP/1.1" 200 - ```

详细输出:

``` +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 1869409 C /usr/bin/python 1222MiB | | 1 N/A N/A 1869410 C /usr/bin/python 1222MiB | | 2 N/A N/A 1869411 C /usr/bin/python 1222MiB | | 3 N/A N/A 1869412 C /usr/bin/python 1222MiB | +-----------------------------------------------------------------------------+ ```

## 模型评估 ``` git clone https://github.com/NVIDIA/Megatron-LM.git git checkout 6ef5bdc ```
详细输出:

``` > sh eval_gpt2_lambada.sh using world size: 1, data-parallel-size: 1, tensor-model-parallel size: 1, pipeline-model-parallel size: 1 setting global batch size to 8 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... True attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. True bias_gelu_fusion ................................ True biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... infer data_parallel_random_init ....................... False data_parallel_size .............................. 1 data_path ....................................... None data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None embedding_weights_in_fp32 ....................... False empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False epochs .......................................... None eval_interval ................................... 1000 eval_iters ...................................... 100 eval_micro_batch_size ........................... None evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False faiss_match ..................................... string faiss_topk_retrievals ........................... 100 faiss_use_gpu ................................... False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 8 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 keep_last ....................................... False kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m-init-mp-out local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 10 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. None lr_decay_iters .................................. None lr_decay_samples ................................ None lr_decay_style .................................. linear lr_warmup_fraction .............................. None lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... True max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 8 min_loss_scale .................................. 1.0 min_lr .......................................... 0.0 mmap_warmup ..................................... False no_load_optim ................................... True no_load_rng ..................................... True no_persist_layer_norm ........................... False no_save_optim ................................... None no_save_rng ..................................... None num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam output_bert_embeddings .......................... False overlap_p2p_comm ................................ False overlapping_eval ................................ 32 override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 patch_dim ....................................... 16 perform_initialization .......................... True pipeline_model_parallel_size .................... 1 pipeline_model_parallel_split_rank .............. None position_embedding_type ......................... learned_absolute pretrained_checkpoint ........................... None profile ......................................... False profile_ranks ................................... [0] profile_step_end ................................ 12 profile_step_start .............................. 10 qa_data_dev ..................................... None qa_data_test .................................... None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ None save_interval ................................... None scatter_gather_tensors_in_pipeline .............. True seed ............................................ 1234 seq_length ...................................... 1024 sequence_parallel ............................... False sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 skip_train ...................................... False split ........................................... 969, 30, 1 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 strict_lambada .................................. True swiglu .......................................... False swin_backbone_type .............................. tiny task ............................................ LAMBADA tensor_model_parallel_size ...................... 1 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer train_data ...................................... None train_data_path ................................. None train_hard_neg .................................. 0 train_iters ..................................... None train_samples ................................... None train_with_neg .................................. False transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 1 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... None use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False val_av_rank_hard_neg ............................ 30 val_av_rank_other_neg ........................... 30 valid_data ...................................... ['/workspace/data/lambada_test.jsonl'] valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 1 -------------------- end of arguments --------------------- setting number of micro-batches to constant 1 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > initializing torch distributed ... > initialized tensor model parallel with size 1 > initialized pipeline model parallel with size 1 > setting random seeds to 1234 ... > compiling dataset index builder ... make: Entering directory '/workspace/code/bak/Megatron-LM/megatron/data' g++ -O3 -Wall -shared -std=c++11 -fPIC -fdiagnostics-color -I/usr/include/python3.8 -I/usr/local/lib/python3.8/dist-packages/pybind11/include helpers.cpp -o helpers.cpython-38-x86_64-linux-gnu.so make: Leaving directory '/workspace/code/bak/Megatron-LM/megatron/data' >>> done with dataset index builder. Compilation time: 13.399 seconds > compiling and loading fused kernels ... >>> done with compiling and loading fused kernels. Compilation time: 1.411 seconds building GPT model ... > number of parameters on (tensor, pipeline) model parallel rank (0, 0): 354871296 loading checkpoint from /workspace/model/megatron-models/345m-init-mp-out at iteration 5000 checkpoint version 3.0 successfully loaded checkpoint from /workspace/model/megatron-models/345m-init-mp-out at iteration 5000 > building lambada dataset from /workspace/data/lambada_test.jsonl ... > found 5153 samples. > working on iteration: 0 > working on iteration: 10 > working on iteration: 20 > working on iteration: 30 ... > working on iteration: 640 -------------------------------------------------------------------------------------------------------------------- validation results on LAMBADA | number correct: 0.0000E+00 | total examples: 5.1530E+03 | avg accuracy: 0.0000E+00 -------------------------------------------------------------------------------------------------------------------- done :-) ```

================================================ FILE: llm-train/megatron/gpt2/model_train.md ================================================ ### 单机单卡
详细输出:

``` CUDA_VISIBLE_DEVICES=3 sh examples/pretrain_gpt.sh using world size: 1, data-parallel-size: 1, tensor-model-parallel size: 1, pipeline-model-parallel size: 1 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... True attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. True bias_gelu_fusion ................................ True biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... mmap data_parallel_random_init ....................... False data_parallel_size .............................. 1 data_path ....................................... ['/workspace/data/my-gpt2_text_document'] data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 10 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 2 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 100 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. 0.00015 lr_decay_iters .................................. 320000 lr_decay_samples ................................ None lr_decay_style .................................. cosine lr_warmup_fraction .............................. 0.01 lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... True max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 1 min_loss_scale .................................. 1.0 min_lr .......................................... 1e-05 mmap_warmup ..................................... False no_load_optim ................................... None no_load_rng ..................................... None no_persist_layer_norm ........................... False no_save_optim ................................... None no_save_rng ..................................... None num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 patch_dim ....................................... 16 perform_initialization .......................... True pipeline_model_parallel_size .................... 1 pipeline_model_parallel_split_rank .............. None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ /workspace/model/megatron-models/345m save_interval ................................... 10000 scatter_gather_tensors_in_pipeline .............. True seed ............................................ 1234 seq_length ...................................... 1024 sequence_parallel ............................... False sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 split ........................................... 700,200,100 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 swiglu .......................................... False swin_backbone_type .............................. tiny tensor_model_parallel_size ...................... 1 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer train_data_path ................................. None train_iters ..................................... 5000 train_samples ................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 1 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... None use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 1 -------------------- end of arguments --------------------- setting number of micro-batches to constant 2 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > initializing torch distributed ... > initialized tensor model parallel with size 1 > initialized pipeline model parallel with size 1 > setting random seeds to 1234 ... > compiling dataset index builder ... make: Entering directory '/workspace/code/Megatron-LM/megatron/data' make: Nothing to be done for 'default'. make: Leaving directory '/workspace/code/Megatron-LM/megatron/data' >>> done with dataset index builder. Compilation time: 0.221 seconds > compiling and loading fused kernels ... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_upper_triang_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_upper_triang_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_softmax_cuda... >>> done with compiling and loading fused kernels. Compilation time: 1.348 seconds time to initialize megatron (seconds): 3.520 [after megatron is initialized] datetime: 2023-07-16 10:56:55 building GPT model ... > number of parameters on (tensor, pipeline) model parallel rank (0, 0): 354871296 > learning rate decay style: cosine loading checkpoint from /workspace/model/megatron-models/345m at iteration 5000 checkpoint version 3.0 > using checkpoint value 0.00015 for learning rate > using checkpoint value 1e-05 for minimum learning rate > using checkpoint value 6400.0 for warmup iterations > using checkpoint value 640000 for total number of iterations > using checkpoint value cosine for learning rate decay style > using checkpoint value 0.01 for start weight decay > using checkpoint value 0.01 for end weight decay > using checkpoint value 10000 for total number of weight decay iterations > using checkpoint value constant for weight decay incr style successfully loaded checkpoint from /workspace/model/megatron-models/345m at iteration 5000 /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( (min, max) time across ranks (ms): load-checkpoint ................................: (4542.10, 4542.10) [after model, optimizer, and learning rate scheduler are built] datetime: 2023-07-16 10:57:00 > building train, validation, and test datasets ... > datasets target sizes (minimum size): train: 10000 validation: 120 test: 20 > building train, validation, and test datasets for GPT ... Single data path provided for train, valid & test data_prefix: ['/workspace/data/my-gpt2_text_document'] > building dataset index ... reading sizes... reading pointers... reading document index... creating numpy buffer of mmap... creating memory view of numpy buffer... > finished creating indexed dataset in 0.003545 seconds number of documents: 2456 > dataset split: train: document indices in [0, 1719) total of 1719 documents validation: document indices in [1719, 2210) total of 491 documents test: document indices in [2210, 2456) total of 246 documents > loading doc-idx mapping from /workspace/data/index-cache/3c048217962a127246af1e2322a522e7_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/3c048217962a127246af1e2322a522e7_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/3c048217962a127246af1e2322a522e7_shuffle_idx.npy loaded indexed file in 0.006 seconds total number of samples: 10411 total number of epochs: 23 > loading doc-idx mapping from /workspace/data/index-cache/c96454bddc79ae7749ebb071e254a5ab_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/c96454bddc79ae7749ebb071e254a5ab_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/c96454bddc79ae7749ebb071e254a5ab_shuffle_idx.npy loaded indexed file in 0.005 seconds total number of samples: 222 total number of epochs: 2 > loading doc-idx mapping from /workspace/data/index-cache/c3c889117317b1643e4d407b279b17a5_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/c3c889117317b1643e4d407b279b17a5_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/c3c889117317b1643e4d407b279b17a5_shuffle_idx.npy loaded indexed file in 0.005 seconds total number of samples: 54 total number of epochs: 1 > finished creating GPT datasets ... [after dataloaders are built] datetime: 2023-07-16 10:57:01 done with setup ... (min, max) time across ranks (ms): model-and-optimizer-setup ......................: (4690.91, 4690.91) train/valid/test-data-iterators-setup ..........: (669.89, 669.89) training ... [before the start of training step] datetime: 2023-07-16 10:57:01 [after training is done] datetime: 2023-07-16 10:57:01 ------------------------------------------------------------------------------------------------------------------ validation loss at the end of training for val data | lm loss value: 5.741563E+00 | lm loss PPL: 3.115511E+02 | ------------------------------------------------------------------------------------------------------------------ saving checkpoint at iteration 5000 to /workspace/model/megatron-models/345m successfully saved checkpoint at iteration 5000 to /workspace/model/megatron-models/345m ------------------------------------------------------------------------------------------------------------------- validation loss at the end of training for test data | lm loss value: 6.015863E+00 | lm loss PPL: 4.098796E+02 | ------------------------------------------------------------------------------------------------------------------- ```

输出权重: ``` > tree -h 345m 345m ├── [4.0K] iter_0005000 │ └── [4.0K] mp_rank_00 │ └── [4.6G] model_optim_rng.pt ├── [ 4] latest_checkpointed_iteration.txt └── [4.0K] release └── [4.0K] mp_rank_00 └── [677M] model_optim_rng.pt 4 directories, 3 files > cat 345m/latest_checkpointed_iteration.txt 5000 ``` ### 单机多卡(4DP) 模型显存占用: ``` +-----------------------------------------------------------------------------+ | NVIDIA-SMI 525.105.17 Driver Version: 525.105.17 CUDA Version: 12.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 NVIDIA A800 80G... Off | 00000000:17:00.0 Off | 0 | | N/A 49C P0 183W / 300W | 9661MiB / 81920MiB | 71% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 1 NVIDIA A800 80G... Off | 00000000:31:00.0 Off | 0 | | N/A 50C P0 136W / 300W | 9661MiB / 81920MiB | 67% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 2 NVIDIA A800 80G... Off | 00000000:B1:00.0 Off | 0 | | N/A 49C P0 202W / 300W | 9663MiB / 81920MiB | 65% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 3 NVIDIA A800 80G... Off | 00000000:CA:00.0 Off | 0 | | N/A 50C P0 227W / 300W | 9663MiB / 81920MiB | 64% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 3227288 C /usr/bin/python 9652MiB | | 1 N/A N/A 3227289 C /usr/bin/python 9652MiB | | 2 N/A N/A 3227290 C /usr/bin/python 9652MiB | | 3 N/A N/A 3227291 C /usr/bin/python 9652MiB | +-----------------------------------------------------------------------------+ ``` 模型权重输出: ``` > tree -h /workspace/model/megatron-models/345m-init /workspace/model/megatron-models/345m-init ├── [4.0K] iter_0005000 │ └── [4.0K] mp_rank_00 │ └── [4.6G] model_optim_rng.pt └── [ 4] latest_checkpointed_iteration.txt 2 directories, 2 files > cat /workspace/model/megatron-models/345m-init/latest_checkpointed_iteration.txt 5000 ```
详细输出:

``` sh examples/pretrain_gpt_distributed.sh WARNING:torch.distributed.run: ***************************************** Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. ***************************************** using world size: 4, data-parallel-size: 4, tensor-model-parallel size: 1, pipeline-model-parallel size: 1 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... True attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. True bias_gelu_fusion ................................ True biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... mmap data_parallel_random_init ....................... False data_parallel_size .............................. 4 data_path ....................................... ['/workspace/data/my-gpt2_text_document'] data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 10 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 8 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m-init local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 100 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. 0.00015 lr_decay_iters .................................. 320000 lr_decay_samples ................................ None lr_decay_style .................................. cosine lr_warmup_fraction .............................. 0.01 lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... True max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 1 min_loss_scale .................................. 1.0 min_lr .......................................... 1e-05 mmap_warmup ..................................... False no_load_optim ................................... None no_load_rng ..................................... None no_persist_layer_norm ........................... False no_save_optim ................................... None no_save_rng ..................................... None num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 patch_dim ....................................... 16 perform_initialization .......................... True pipeline_model_parallel_size .................... 1 pipeline_model_parallel_split_rank .............. None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ /workspace/model/megatron-models/345m-init save_interval ................................... 10000 scatter_gather_tensors_in_pipeline .............. True seed ............................................ 1234 seq_length ...................................... 1024 sequence_parallel ............................... False sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 split ........................................... 700,200,100 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 swiglu .......................................... False swin_backbone_type .............................. tiny tensor_model_parallel_size ...................... 1 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer train_data_path ................................. None train_iters ..................................... 5000 train_samples ................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 1 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... None use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 4 -------------------- end of arguments --------------------- setting number of micro-batches to constant 2 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > initializing torch distributed ... > initialized tensor model parallel with size 1 > initialized pipeline model parallel with size 1 > setting random seeds to 1234 ... > compiling dataset index builder ... make: Entering directory '/workspace/code/Megatron-LM/megatron/data' make: Nothing to be done for 'default'. make: Leaving directory '/workspace/code/Megatron-LM/megatron/data' >>> done with dataset index builder. Compilation time: 0.211 seconds > compiling and loading fused kernels ... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_upper_triang_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_upper_triang_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_softmax_cuda... >>> done with compiling and loading fused kernels. Compilation time: 3.180 seconds time to initialize megatron (seconds): 5.824 [after megatron is initialized] datetime: 2023-07-16 11:34:42 building GPT model ... > number of parameters on (tensor, pipeline) model parallel rank (0, 0): 354871296 > learning rate decay style: cosine WARNING: could not find the metadata file /workspace/model/megatron-models/345m-init/latest_checkpointed_iteration.txt will not load any checkpoints and will start from random /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( (min, max) time across ranks (ms): load-checkpoint ................................: (1.15, 1.15) [after model, optimizer, and learning rate scheduler are built] datetime: 2023-07-16 11:34:42 > building train, validation, and test datasets ... > datasets target sizes (minimum size): train: 40000 validation: 480 test: 80 > building train, validation, and test datasets for GPT ... Single data path provided for train, valid & test data_prefix: ['/workspace/data/my-gpt2_text_document'] > building dataset index ... reading sizes... reading pointers... reading document index... creating numpy buffer of mmap... creating memory view of numpy buffer... > finished creating indexed dataset in 0.002571 seconds number of documents: 2456 > dataset split: train: document indices in [0, 1719) total of 1719 documents validation: document indices in [1719, 2210) total of 491 documents test: document indices in [2210, 2456) total of 246 documents > loading doc-idx mapping from /workspace/data/index-cache/c5fd135211a7052c502ac43f60ef9c1d_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/c5fd135211a7052c502ac43f60ef9c1d_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/c5fd135211a7052c502ac43f60ef9c1d_shuffle_idx.npy loaded indexed file in 0.004 seconds total number of samples: 40286 total number of epochs: 89 > loading doc-idx mapping from /workspace/data/index-cache/1a0ccca19f4fd634c52ef32cb52a4d6f_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/1a0ccca19f4fd634c52ef32cb52a4d6f_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/1a0ccca19f4fd634c52ef32cb52a4d6f_shuffle_idx.npy loaded indexed file in 0.003 seconds total number of samples: 555 total number of epochs: 5 > loading doc-idx mapping from /workspace/data/index-cache/f1583c0457c0ee9c3ecb3c068b3badd8_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/f1583c0457c0ee9c3ecb3c068b3badd8_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/f1583c0457c0ee9c3ecb3c068b3badd8_shuffle_idx.npy loaded indexed file in 0.002 seconds total number of samples: 108 total number of epochs: 2 > finished creating GPT datasets ... [after dataloaders are built] datetime: 2023-07-16 11:34:57 done with setup ... (min, max) time across ranks (ms): model-and-optimizer-setup ......................: (222.27, 225.22) train/valid/test-data-iterators-setup ..........: (14590.46, 14646.38) training ... [before the start of training step] datetime: 2023-07-16 11:34:57 iteration 100/ 5000 | consumed samples: 800 | elapsed time per iteration (ms): 296.8 | learning rate: 3.937E-06 | global batch size: 8 | lm loss: 9.729805E+00 | loss scale: 131072.0 | grad norm: 5.703 | number of skipped iterations: 16 | number of nan iterations: 0 | [Rank 0] (after 100 iterations) memory (MB) | allocated: 6816.88818359375 | max allocated: 8696.8515625 | reserved: 8786.0 | max reserved: 8786.0 ... iteration 1000/ 5000 | consumed samples: 8000 | elapsed time per iteration (ms): 283.9 | learning rate: 4.608E-05 | global batch size: 8 | lm loss: 5.544420E+00 | loss scale: 65536.0 | grad norm: 2.475 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 1000 | lm loss value: 6.439325E+00 | lm loss PPL: 6.259840E+02 | ------------------------------------------------------------------------------------------------ iteration 1100/ 5000 | consumed samples: 8800 | elapsed time per iteration (ms): 291.7 | learning rate: 5.077E-05 | global batch size: 8 | lm loss: 5.352916E+00 | loss scale: 65536.0 | grad norm: 1.765 | number of skipped iterations: 0 | number of nan iterations: 0 | ... iteration 2000/ 5000 | consumed samples: 16000 | elapsed time per iteration (ms): 292.5 | learning rate: 9.295E-05 | global batch size: 8 | lm loss: 3.812283E+00 | loss scale: 131072.0 | grad norm: 2.040 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 2000 | lm loss value: 6.188880E+00 | lm loss PPL: 4.873002E+02 | ------------------------------------------------------------------------------------------------ iteration 2100/ 5000 | consumed samples: 16800 | elapsed time per iteration (ms): 373.8 | learning rate: 9.764E-05 | global batch size: 8 | lm loss: 3.435059E+00 | loss scale: 131072.0 | grad norm: 2.342 | number of skipped iterations: 0 | number of nan iterations: 0 | ... iteration 2900/ 5000 | consumed samples: 23200 | elapsed time per iteration (ms): 531.2 | learning rate: 1.351E-04 | global batch size: 8 | lm loss: 1.052763E+00 | loss scale: 262144.0 | grad norm: 1.846 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 3000/ 5000 | consumed samples: 24000 | elapsed time per iteration (ms): 290.9 | learning rate: 1.398E-04 | global batch size: 8 | lm loss: 8.640376E-01 | loss scale: 262144.0 | grad norm: 2.122 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 3000 | lm loss value: 6.826255E+00 | lm loss PPL: 9.217327E+02 | ------------------------------------------------------------------------------------------------ iteration 3100/ 5000 | consumed samples: 24800 | elapsed time per iteration (ms): 289.2 | learning rate: 1.445E-04 | global batch size: 8 | lm loss: 7.523526E-01 | loss scale: 262144.0 | grad norm: 2.145 | number of skipped iterations: 0 | number of nan iterations: 0 | ... iteration 4000/ 5000 | consumed samples: 32000 | elapsed time per iteration (ms): 286.2 | learning rate: 1.500E-04 | global batch size: 8 | lm loss: 2.821585E-01 | loss scale: 262144.0 | grad norm: 1.031 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 4000 | lm loss value: 7.609839E+00 | lm loss PPL: 2.017953E+03 | ------------------------------------------------------------------------------------------------ iteration 4100/ 5000 | consumed samples: 32800 | elapsed time per iteration (ms): 290.9 | learning rate: 1.500E-04 | global batch size: 8 | lm loss: 2.681582E-01 | loss scale: 262144.0 | grad norm: 1.052 | number of skipped iterations: 0 | number of nan iterations: 0 | ... iteration 4800/ 5000 | consumed samples: 38400 | elapsed time per iteration (ms): 318.3 | learning rate: 1.500E-04 | global batch size: 8 | lm loss: 1.533272E-01 | loss scale: 131072.0 | grad norm: 0.655 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 4900/ 5000 | consumed samples: 39200 | elapsed time per iteration (ms): 288.0 | learning rate: 1.500E-04 | global batch size: 8 | lm loss: 1.449491E-01 | loss scale: 131072.0 | grad norm: 0.657 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 5000/ 5000 | consumed samples: 40000 | elapsed time per iteration (ms): 287.0 | learning rate: 1.500E-04 | global batch size: 8 | lm loss: 1.350079E-01 | loss scale: 131072.0 | grad norm: 0.706 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 5000 | lm loss value: 8.208897E+00 | lm loss PPL: 3.673487E+03 | ------------------------------------------------------------------------------------------------ [after training is done] datetime: 2023-07-16 12:03:49 saving checkpoint at iteration 5000 to /workspace/model/megatron-models/345m-init ------------------------------------------------------------------------------------------------------------------ validation loss at the end of training for val data | lm loss value: 8.165035E+00 | lm loss PPL: 3.515845E+03 | ------------------------------------------------------------------------------------------------------------------ successfully saved checkpoint at iteration 5000 to /workspace/model/megatron-models/345m-init ------------------------------------------------------------------------------------------------------------------- validation loss at the end of training for test data | lm loss value: 8.428315E+00 | lm loss PPL: 4.574786E+03 | ------------------------------------------------------------------------------------------------------------------- ```

### 模型并行(2TP+2DP)
显存使用:

``` +-----------------------------------------------------------------------------+ | NVIDIA-SMI 525.105.17 Driver Version: 525.105.17 CUDA Version: 12.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 NVIDIA A800 80G... Off | 00000000:17:00.0 Off | 0 | | N/A 54C P0 142W / 300W | 8732MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 1 NVIDIA A800 80G... Off | 00000000:31:00.0 Off | 0 | | N/A 53C P0 210W / 300W | 8732MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 2 NVIDIA A800 80G... Off | 00000000:B1:00.0 Off | 0 | | N/A 55C P0 290W / 300W | 6828MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 3 NVIDIA A800 80G... Off | 00000000:CA:00.0 Off | 0 | | N/A 55C P0 284W / 300W | 7078MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 3448098 C /usr/bin/python 8732MiB | | 1 N/A N/A 3448099 C /usr/bin/python 8732MiB | | 2 N/A N/A 3448100 C /usr/bin/python 6828MiB | | 3 N/A N/A 3448101 C /usr/bin/python 7078MiB | +-----------------------------------------------------------------------------+ ```

模型权重输出:

``` tree -h 345m-init-mp 345m-init-mp ├── [4.0K] iter_0002000 │ ├── [4.0K] mp_rank_00_000 │ │ └── [1.3G] model_optim_rng.pt │ ├── [4.0K] mp_rank_00_001 │ │ └── [1.3G] model_optim_rng.pt │ ├── [4.0K] mp_rank_01_000 │ │ └── [1.3G] model_optim_rng.pt │ └── [4.0K] mp_rank_01_001 │ └── [1.3G] model_optim_rng.pt ├── [4.0K] iter_0004000 │ ├── [4.0K] mp_rank_00_000 │ │ └── [1.3G] model_optim_rng.pt │ ├── [4.0K] mp_rank_00_001 │ │ └── [1.3G] model_optim_rng.pt │ ├── [4.0K] mp_rank_01_000 │ │ └── [1.3G] model_optim_rng.pt │ └── [4.0K] mp_rank_01_001 │ └── [1.3G] model_optim_rng.pt ├── [4.0K] iter_0005000 │ ├── [4.0K] mp_rank_00_000 │ │ └── [1.3G] model_optim_rng.pt │ ├── [4.0K] mp_rank_00_001 │ │ └── [1.3G] model_optim_rng.pt │ ├── [4.0K] mp_rank_01_000 │ │ └── [1.3G] model_optim_rng.pt │ └── [4.0K] mp_rank_01_001 │ └── [1.3G] model_optim_rng.pt └── [ 4] latest_checkpointed_iteration.txt 15 directories, 13 files ```

详细日志输出:

``` > sh examples/pretrain_gpt_distributed_with_mp.sh WARNING:torch.distributed.run: ***************************************** Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. ***************************************** using world size: 4, data-parallel-size: 1, tensor-model-parallel size: 2, pipeline-model-parallel size: 2 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... False attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. True bias_gelu_fusion ................................ True biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... mmap data_parallel_random_init ....................... False data_parallel_size .............................. 1 data_path ....................................... ['/workspace/data/my-gpt2_text_document'] data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 10 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 16 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m-init-mp local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 100 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. 0.00015 lr_decay_iters .................................. 320000 lr_decay_samples ................................ None lr_decay_style .................................. cosine lr_warmup_fraction .............................. 0.01 lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... True max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 4 min_loss_scale .................................. 1.0 min_lr .......................................... 1e-05 mmap_warmup ..................................... False no_load_optim ................................... None no_load_rng ..................................... None no_persist_layer_norm ........................... False no_save_optim ................................... None no_save_rng ..................................... None num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 patch_dim ....................................... 16 perform_initialization .......................... True pipeline_model_parallel_size .................... 2 pipeline_model_parallel_split_rank .............. None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ /workspace/model/megatron-models/345m-init-mp save_interval ................................... 2000 scatter_gather_tensors_in_pipeline .............. True seed ............................................ 1234 seq_length ...................................... 1024 sequence_parallel ............................... True sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 split ........................................... 700,200,100 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 swiglu .......................................... False swin_backbone_type .............................. tiny tensor_model_parallel_size ...................... 2 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer train_data_path ................................. None train_iters ..................................... 5000 train_samples ................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 2 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... None use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 4 -------------------- end of arguments --------------------- setting number of micro-batches to constant 4 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 175 dummy tokens (new size: 50432) > initializing torch distributed ... > initialized tensor model parallel with size 2 > initialized pipeline model parallel with size 2 > setting random seeds to 1234 ... > compiling dataset index builder ... make: Entering directory '/workspace/code/Megatron-LM/megatron/data' make: Nothing to be done for 'default'. make: Leaving directory '/workspace/code/Megatron-LM/megatron/data' >>> done with dataset index builder. Compilation time: 0.209 seconds > compiling and loading fused kernels ... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_upper_triang_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_upper_triang_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_softmax_cuda... >>> done with compiling and loading fused kernels. Compilation time: 4.125 seconds time to initialize megatron (seconds): 7.305 [after megatron is initialized] datetime: 2023-07-16 12:25:38 building GPT model ... > number of parameters on (tensor, pipeline) model parallel rank (1, 0): 102483968 > number of parameters on (tensor, pipeline) model parallel rank (1, 1): 101437440 > number of parameters on (tensor, pipeline) model parallel rank (0, 0): 102483968 > number of parameters on (tensor, pipeline) model parallel rank (0, 1): 101437440 > learning rate decay style: cosine WARNING: could not find the metadata file /workspace/model/megatron-models/345m-init-mp/latest_checkpointed_iteration.txt will not load any checkpoints and will start from random /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( (min, max) time across ranks (ms): load-checkpoint ................................: (6.90, 7.03) [after model, optimizer, and learning rate scheduler are built] datetime: 2023-07-16 12:25:39 > building train, validation, and test datasets ... > datasets target sizes (minimum size): train: 80000 validation: 960 test: 160 > building train, validation, and test datasets for GPT ... Single data path provided for train, valid & test data_prefix: ['/workspace/data/my-gpt2_text_document'] > building dataset index ... reading sizes... reading pointers... reading document index... creating numpy buffer of mmap... creating memory view of numpy buffer... > finished creating indexed dataset in 0.003472 seconds number of documents: 2456 > dataset split: train: document indices in [0, 1719) total of 1719 documents validation: document indices in [1719, 2210) total of 491 documents test: document indices in [2210, 2456) total of 246 documents > WARNING: could not find index map files, building the indices on rank 0 ... > last epoch number of samples (335) is smaller than 80% of number of samples per epoch (452), setting separate_last_epoch to True > elasped time to build and save doc-idx mapping (seconds): 0.026260 using: number of documents: 1719 number of epochs: 177 sequence length: 1024 total number of samples: 80118 > elasped time to build and save sample-idx mapping (seconds): 0.010997 > building shuffle index with split [0, 79665) and [79665, 80118) ... > elasped time to build and save shuffle-idx mapping (seconds): 0.008945 > loading doc-idx mapping from /workspace/data/index-cache/3780b1a26d534c9d9a1da4ab04f13381_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/3780b1a26d534c9d9a1da4ab04f13381_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/3780b1a26d534c9d9a1da4ab04f13381_shuffle_idx.npy loaded indexed file in 0.008 seconds total number of samples: 80119 total number of epochs: 177 > WARNING: could not find index map files, building the indices on rank 0 ... > last epoch number of samples (74) is smaller than 80% of number of samples per epoch (110), setting separate_last_epoch to True > elasped time to build and save doc-idx mapping (seconds): 0.005155 using: number of documents: 491 number of epochs: 9 sequence length: 1024 total number of samples: 997 > elasped time to build and save sample-idx mapping (seconds): 0.004258 > building shuffle index with split [0, 886) and [886, 997) ... > elasped time to build and save shuffle-idx mapping (seconds): 0.005074 > loading doc-idx mapping from /workspace/data/index-cache/ae23c587dd8002d7491a754ac381df77_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/ae23c587dd8002d7491a754ac381df77_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/ae23c587dd8002d7491a754ac381df77_shuffle_idx.npy loaded indexed file in 0.005 seconds total number of samples: 998 total number of epochs: 9 > loading doc-idx mapping from /workspace/data/index-cache/5eb65247febbee0dc5f98a246cfebfae_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/5eb65247febbee0dc5f98a246cfebfae_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/5eb65247febbee0dc5f98a246cfebfae_shuffle_idx.npy loaded indexed file in 0.003 seconds total number of samples: 161 total number of epochs: 3 > finished creating GPT datasets ... [after dataloaders are built] datetime: 2023-07-16 12:25:43 done with setup ... training ... (min, max) time across ranks (ms): model-and-optimizer-setup ......................: (593.04, 601.19) train/valid/test-data-iterators-setup ..........: (4026.38, 4324.57) [before the start of training step] datetime: 2023-07-16 12:25:43 [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:3071: UserWarning: torch.distributed._reduce_scatter_base is a private function and will be deprecated. Please use torch.distributed.reduce_scatter_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:3071: UserWarning: torch.distributed._reduce_scatter_base is a private function and will be deprecated. Please use torch.distributed.reduce_scatter_tensor instead. warnings.warn( [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:3071: UserWarning: torch.distributed._reduce_scatter_base is a private function and will be deprecated. Please use torch.distributed.reduce_scatter_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:3071: UserWarning: torch.distributed._reduce_scatter_base is a private function and will be deprecated. Please use torch.distributed.reduce_scatter_tensor instead. warnings.warn( [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) iteration 100/ 5000 | consumed samples: 1600 | elapsed time per iteration (ms): 858.6 | learning rate: 3.984E-06 | global batch size: 16 | lm loss: 9.674668E+00 | loss scale: 262144.0 | grad norm: 3.750 | number of skipped iterations: 15 | number of nan iterations: 0 | [Rank 3] (after 100 iterations) memory (MB) | allocated: 2029.29443359375 | max allocated: 5373.49560546875 | reserved: 5968.0 | max reserved: 5968.0 [Rank 2] (after 100 iterations) memory (MB) | allocated: 2029.29443359375 | max allocated: 5373.49560546875 | reserved: 5718.0 | max reserved: 5718.0 [Rank 1] (after 100 iterations) memory (MB) | allocated: 2040.25830078125 | max allocated: 7253.22705078125 | reserved: 7622.0 | max reserved: 7622.0 [Rank 0] (after 100 iterations) memory (MB) | allocated: 2040.25830078125 | max allocated: 7253.22705078125 | reserved: 7622.0 | max reserved: 7622.0 iteration 200/ 5000 | consumed samples: 3200 | elapsed time per iteration (ms): 1082.6 | learning rate: 8.672E-06 | global batch size: 16 | lm loss: 8.440352E+00 | loss scale: 262144.0 | grad norm: 3.089 | number of skipped iterations: 0 | number of nan iterations: 0 | ... iteration 1000/ 5000 | consumed samples: 16000 | elapsed time per iteration (ms): 1109.8 | learning rate: 4.617E-05 | global batch size: 16 | lm loss: 5.200860E+00 | loss scale: 262144.0 | grad norm: 1.947 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 1000 | lm loss value: 6.329505E+00 | lm loss PPL: 5.608791E+02 | ------------------------------------------------------------------------------------------------ iteration 1100/ 5000 | consumed samples: 17600 | elapsed time per iteration (ms): 839.6 | learning rate: 5.086E-05 | global batch size: 16 | lm loss: 5.015918E+00 | loss scale: 524288.0 | grad norm: 1.851 | number of skipped iterations: 0 | number of nan iterations: 0 | ... iteration 2000/ 5000 | consumed samples: 32000 | elapsed time per iteration (ms): 1031.7 | learning rate: 9.295E-05 | global batch size: 16 | lm loss: 2.117708E+00 | loss scale: 262144.0 | grad norm: 3.088 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 2000 | lm loss value: 6.586888E+00 | lm loss PPL: 7.255198E+02 | ------------------------------------------------------------------------------------------------ saving checkpoint at iteration 2000 to /workspace/model/megatron-models/345m-init-mp ... ```

### 模型并行(4TP) 显存占用: ``` +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 3895346 C /usr/bin/python 4236MiB | | 1 N/A N/A 3895347 C /usr/bin/python 4176MiB | | 2 N/A N/A 3895348 C /usr/bin/python 4168MiB | | 3 N/A N/A 3895349 C /usr/bin/python 4176MiB | +-----------------------------------------------------------------------------+ ```
详细输出

``` > sh pretrain_gpt_distributed_with_4tp.sh WARNING:torch.distributed.run: ***************************************** Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. ***************************************** using world size: 4, data-parallel-size: 1, tensor-model-parallel size: 4, pipeline-model-parallel size: 1 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... False attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. True bias_gelu_fusion ................................ True biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... mmap data_parallel_random_init ....................... False data_parallel_size .............................. 1 data_path ....................................... ['/workspace/data/my-gpt2_text_document'] data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 10 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 8 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m-init-4tp local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 100 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. 0.00015 lr_decay_iters .................................. 320000 lr_decay_samples ................................ None lr_decay_style .................................. cosine lr_warmup_fraction .............................. 0.01 lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... True max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 2 min_loss_scale .................................. 1.0 min_lr .......................................... 1e-05 mmap_warmup ..................................... False no_load_optim ................................... None no_load_rng ..................................... None no_persist_layer_norm ........................... False no_save_optim ................................... None no_save_rng ..................................... None num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 patch_dim ....................................... 16 perform_initialization .......................... True pipeline_model_parallel_size .................... 1 pipeline_model_parallel_split_rank .............. None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ /workspace/model/megatron-models/345m-init-4tp save_interval ................................... 1000 scatter_gather_tensors_in_pipeline .............. True seed ............................................ 1234 seq_length ...................................... 1024 sequence_parallel ............................... True sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 split ........................................... 700,200,100 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 swiglu .......................................... False swin_backbone_type .............................. tiny tensor_model_parallel_size ...................... 4 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer train_data_path ................................. None train_iters ..................................... 2000 train_samples ................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 1 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... None use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 4 -------------------- end of arguments --------------------- setting number of micro-batches to constant 4 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 431 dummy tokens (new size: 50688) > initializing torch distributed ... > initialized tensor model parallel with size 4 > initialized pipeline model parallel with size 1 > setting random seeds to 1234 ... > compiling dataset index builder ... make: Entering directory '/workspace/code/Megatron-LM/megatron/data' make: Nothing to be done for 'default'. make: Leaving directory '/workspace/code/Megatron-LM/megatron/data' >>> done with dataset index builder. Compilation time: 0.198 seconds > compiling and loading fused kernels ... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_upper_triang_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_upper_triang_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_softmax_cuda... >>> done with compiling and loading fused kernels. Compilation time: 3.127 seconds time to initialize megatron (seconds): 5.792 [after megatron is initialized] datetime: 2023-07-16 14:05:13 building GPT model ... > number of parameters on (tensor, pipeline) model parallel rank (2, 0): 89714688 > number of parameters on (tensor, pipeline) model parallel rank (3, 0): 89714688 > number of parameters on (tensor, pipeline) model parallel rank (0, 0): 89714688 > number of parameters on (tensor, pipeline) model parallel rank (1, 0): 89714688 > learning rate decay style: cosine WARNING: could not find the metadata file /workspace/model/megatron-models/345m-init-4tp/latest_checkpointed_iteration.txt will not load any checkpoints and will start from random /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( (min, max) time across ranks (ms): load-checkpoint ................................: (6.91, 7.08) [after model, optimizer, and learning rate scheduler are built] datetime: 2023-07-16 14:05:14 > building train, validation, and test datasets ... > datasets target sizes (minimum size): train: 16000 validation: 240 test: 80 > building train, validation, and test datasets for GPT ... Single data path provided for train, valid & test data_prefix: ['/workspace/data/my-gpt2_text_document'] > building dataset index ... reading sizes... reading pointers... reading document index... creating numpy buffer of mmap... creating memory view of numpy buffer... > finished creating indexed dataset in 0.002060 seconds number of documents: 2456 > dataset split: train: document indices in [0, 1719) total of 1719 documents validation: document indices in [1719, 2210) total of 491 documents test: document indices in [2210, 2456) total of 246 documents > WARNING: could not find index map files, building the indices on rank 0 ... > last epoch number of samples (158) is smaller than 80% of number of samples per epoch (452), setting separate_last_epoch to True > elasped time to build and save doc-idx mapping (seconds): 0.008389 using: number of documents: 1719 number of epochs: 36 sequence length: 1024 total number of samples: 16295 > elasped time to build and save sample-idx mapping (seconds): 0.005391 > building shuffle index with split [0, 15842) and [15842, 16295) ... > elasped time to build and save shuffle-idx mapping (seconds): 0.004106 > loading doc-idx mapping from /workspace/data/index-cache/09a6ab12e4c21658eefabc732b2e110b_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/09a6ab12e4c21658eefabc732b2e110b_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/09a6ab12e4c21658eefabc732b2e110b_shuffle_idx.npy loaded indexed file in 0.007 seconds total number of samples: 16296 total number of epochs: 36 > WARNING: could not find index map files, building the indices on rank 0 ... > last epoch number of samples (19) is smaller than 80% of number of samples per epoch (110), setting separate_last_epoch to True > elasped time to build and save doc-idx mapping (seconds): 0.003765 using: number of documents: 491 number of epochs: 3 sequence length: 1024 total number of samples: 332 > elasped time to build and save sample-idx mapping (seconds): 0.003097 > building shuffle index with split [0, 221) and [221, 332) ... > elasped time to build and save shuffle-idx mapping (seconds): 0.002940 > loading doc-idx mapping from /workspace/data/index-cache/2d16c1014278a21da8aa7bdfcf0f1e3f_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/2d16c1014278a21da8aa7bdfcf0f1e3f_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/2d16c1014278a21da8aa7bdfcf0f1e3f_shuffle_idx.npy loaded indexed file in 0.004 seconds total number of samples: 333 total number of epochs: 3 > loading doc-idx mapping from /workspace/data/index-cache/f1583c0457c0ee9c3ecb3c068b3badd8_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/f1583c0457c0ee9c3ecb3c068b3badd8_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/f1583c0457c0ee9c3ecb3c068b3badd8_shuffle_idx.npy loaded indexed file in 0.003 seconds total number of samples: 108 total number of epochs: 2 > finished creating GPT datasets ... [after dataloaders are built] datetime: 2023-07-16 14:05:15 done with setup ... training ... (min, max) time across ranks (ms): model-and-optimizer-setup ......................: (480.17, 494.89) train/valid/test-data-iterators-setup ..........: (965.72, 1189.60) [before the start of training step] datetime: 2023-07-16 14:05:15 /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:3071: UserWarning: torch.distributed._reduce_scatter_base is a private function and will be deprecated. Please use torch.distributed.reduce_scatter_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:3071: UserWarning: torch.distributed._reduce_scatter_base is a private function and will be deprecated. Please use torch.distributed.reduce_scatter_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:3071: UserWarning: torch.distributed._reduce_scatter_base is a private function and will be deprecated. Please use torch.distributed.reduce_scatter_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:3071: UserWarning: torch.distributed._reduce_scatter_base is a private function and will be deprecated. Please use torch.distributed.reduce_scatter_tensor instead. warnings.warn( iteration 100/ 2000 | consumed samples: 800 | elapsed time per iteration (ms): 2946.0 | learning rate: 3.984E-06 | global batch size: 8 | lm loss: 9.654853E+00 | loss scale: 262144.0 | grad norm: 3.700 | number of skipped iterations: 15 | number of nan iterations: 0 | [Rank 0] (after 100 iterations) memory (MB) | allocated: 1772.68505859375 | max allocated: 3059.67138671875 | reserved: 3394.0 | max reserved: 3394.0 [Rank 2] (after 100 iterations) memory (MB) | allocated: 1794.56005859375 | max allocated: 3081.17138671875 | reserved: 3390.0 | max reserved: 3390.0 [Rank 3] (after 100 iterations) memory (MB) | allocated: 1795.06005859375 | max allocated: 3081.67138671875 | reserved: 3398.0 | max reserved: 3398.0 [Rank 1] (after 100 iterations) memory (MB) | allocated: 1774.18505859375 | max allocated: 3065.67138671875 | reserved: 3398.0 | max reserved: 3398.0 iteration 200/ 2000 | consumed samples: 1600 | elapsed time per iteration (ms): 2435.9 | learning rate: 8.672E-06 | global batch size: 8 | lm loss: 8.503224E+00 | loss scale: 262144.0 | grad norm: 3.291 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 300/ 2000 | consumed samples: 2400 | elapsed time per iteration (ms): 2710.7 | learning rate: 1.331E-05 | global batch size: 8 | lm loss: 7.670080E+00 | loss scale: 131072.0 | grad norm: 3.704 | number of skipped iterations: 1 | number of nan iterations: 0 | iteration 400/ 2000 | consumed samples: 3200 | elapsed time per iteration (ms): 2848.5 | learning rate: 1.800E-05 | global batch size: 8 | lm loss: 6.967275E+00 | loss scale: 131072.0 | grad norm: 2.357 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 500/ 2000 | consumed samples: 4000 | elapsed time per iteration (ms): 2842.7 | learning rate: 2.269E-05 | global batch size: 8 | lm loss: 6.564229E+00 | loss scale: 131072.0 | grad norm: 2.356 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 600/ 2000 | consumed samples: 4800 | elapsed time per iteration (ms): 2519.6 | learning rate: 2.737E-05 | global batch size: 8 | lm loss: 6.246951E+00 | loss scale: 131072.0 | grad norm: 2.799 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 700/ 2000 | consumed samples: 5600 | elapsed time per iteration (ms): 2552.9 | learning rate: 3.206E-05 | global batch size: 8 | lm loss: 6.112354E+00 | loss scale: 131072.0 | grad norm: 1.943 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 800/ 2000 | consumed samples: 6400 | elapsed time per iteration (ms): 2701.1 | learning rate: 3.675E-05 | global batch size: 8 | lm loss: 5.886550E+00 | loss scale: 131072.0 | grad norm: 2.176 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 900/ 2000 | consumed samples: 7200 | elapsed time per iteration (ms): 2993.7 | learning rate: 4.144E-05 | global batch size: 8 | lm loss: 5.670854E+00 | loss scale: 131072.0 | grad norm: 2.356 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1000/ 2000 | consumed samples: 8000 | elapsed time per iteration (ms): 2642.9 | learning rate: 4.612E-05 | global batch size: 8 | lm loss: 5.564718E+00 | loss scale: 131072.0 | grad norm: 2.031 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 1000 | lm loss value: 6.319978E+00 | lm loss PPL: 5.555609E+02 | ------------------------------------------------------------------------------------------------ saving checkpoint at iteration 1000 to /workspace/model/megatron-models/345m-init-4tp successfully saved checkpoint at iteration 1000 to /workspace/model/megatron-models/345m-init-4tp (min, max) time across ranks (ms): save-checkpoint ................................: (33544.92, 33545.12) iteration 1100/ 2000 | consumed samples: 8800 | elapsed time per iteration (ms): 3176.9 | learning rate: 5.081E-05 | global batch size: 8 | lm loss: 5.373973E+00 | loss scale: 131072.0 | grad norm: 1.966 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1200/ 2000 | consumed samples: 9600 | elapsed time per iteration (ms): 2297.0 | learning rate: 5.550E-05 | global batch size: 8 | lm loss: 5.235421E+00 | loss scale: 131072.0 | grad norm: 1.634 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1300/ 2000 | consumed samples: 10400 | elapsed time per iteration (ms): 2666.7 | learning rate: 6.019E-05 | global batch size: 8 | lm loss: 5.050657E+00 | loss scale: 262144.0 | grad norm: 2.018 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1400/ 2000 | consumed samples: 11200 | elapsed time per iteration (ms): 2774.4 | learning rate: 6.487E-05 | global batch size: 8 | lm loss: 4.977434E+00 | loss scale: 262144.0 | grad norm: 1.856 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1500/ 2000 | consumed samples: 12000 | elapsed time per iteration (ms): 2950.4 | learning rate: 6.956E-05 | global batch size: 8 | lm loss: 4.809360E+00 | loss scale: 262144.0 | grad norm: 1.659 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1600/ 2000 | consumed samples: 12800 | elapsed time per iteration (ms): 2292.5 | learning rate: 7.425E-05 | global batch size: 8 | lm loss: 4.620577E+00 | loss scale: 262144.0 | grad norm: 1.759 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1700/ 2000 | consumed samples: 13600 | elapsed time per iteration (ms): 2957.8 | learning rate: 7.894E-05 | global batch size: 8 | lm loss: 4.447711E+00 | loss scale: 262144.0 | grad norm: 1.743 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1800/ 2000 | consumed samples: 14400 | elapsed time per iteration (ms): 2407.2 | learning rate: 8.362E-05 | global batch size: 8 | lm loss: 4.211063E+00 | loss scale: 262144.0 | grad norm: 1.733 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1900/ 2000 | consumed samples: 15200 | elapsed time per iteration (ms): 2554.1 | learning rate: 8.831E-05 | global batch size: 8 | lm loss: 3.968034E+00 | loss scale: 262144.0 | grad norm: 1.993 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 2000/ 2000 | consumed samples: 16000 | elapsed time per iteration (ms): 3024.0 | learning rate: 9.300E-05 | global batch size: 8 | lm loss: 3.732524E+00 | loss scale: 262144.0 | grad norm: 1.874 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 2000 | lm loss value: 6.237787E+00 | lm loss PPL: 5.117247E+02 | ------------------------------------------------------------------------------------------------ saving checkpoint at iteration 2000 to /workspace/model/megatron-models/345m-init-4tp successfully saved checkpoint at iteration 2000 to /workspace/model/megatron-models/345m-init-4tp (min, max) time across ranks (ms): save-checkpoint ................................: (52793.38, 52793.87) [after training is done] datetime: 2023-07-16 15:36:49 saving checkpoint at iteration 2000 to /workspace/model/megatron-models/345m-init-4tp ------------------------------------------------------------------------------------------------------------------ validation loss at the end of training for val data | lm loss value: 6.296053E+00 | lm loss PPL: 5.424267E+02 | ------------------------------------------------------------------------------------------------------------------ successfully saved checkpoint at iteration 2000 to /workspace/model/megatron-models/345m-init-4tp ------------------------------------------------------------------------------------------------------------------- validation loss at the end of training for test data | lm loss value: 6.454095E+00 | lm loss PPL: 6.352988E+02 | ------------------------------------------------------------------------------------------------------------------- ```

详细输出

``` tree -h /workspace/model/megatron-models/345m-init-4tp /workspace/model/megatron-models/345m-init-4tp ├── [4.0K] iter_0001000 │ ├── [4.0K] mp_rank_00 │ │ └── [1.2G] model_optim_rng.pt │ ├── [4.0K] mp_rank_01 │ │ └── [1.2G] model_optim_rng.pt │ ├── [4.0K] mp_rank_02 │ │ └── [1.2G] model_optim_rng.pt │ └── [4.0K] mp_rank_03 │ └── [1.2G] model_optim_rng.pt ├── [4.0K] iter_0002000 │ ├── [4.0K] mp_rank_00 │ │ └── [1.2G] model_optim_rng.pt │ ├── [4.0K] mp_rank_01 │ │ └── [1.2G] model_optim_rng.pt │ ├── [4.0K] mp_rank_02 │ │ └── [1.2G] model_optim_rng.pt │ └── [4.0K] mp_rank_03 │ └── [1.2G] model_optim_rng.pt └── [ 4] latest_checkpointed_iteration.txt 10 directories, 9 files > cat /workspace/model/megatron-models/345m-init-4tp/latest_checkpointed_iteration.txt 2000 ```

### 模型并行(4PP)
详细输出

``` > nohup sh examples/pretrain_gpt_distributed_with_pp4.sh >gpt-pp4.log & WARNING:torch.distributed.run: ***************************************** Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. ***************************************** using world size: 4, data-parallel-size: 1, tensor-model-parallel size: 1, pipeline-model-parallel size: 4 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.999 adam_eps ........................................ 1e-08 add_bias_linear ................................. True add_position_embedding .......................... True adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... True apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... True attention_dropout ............................... 0.1 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. True bias_gelu_fusion ................................ True biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 consumed_train_samples .......................... 0 consumed_valid_samples .......................... 0 data_cache_path ................................. None data_impl ....................................... mmap data_parallel_random_init ....................... False data_parallel_size .............................. 1 data_path ....................................... ['/workspace/data/my-gpt2_text_document'] data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 embedding_path .................................. None empty_unused_memory_level ....................... 0 encoder_num_layers .............................. 24 encoder_seq_length .............................. 1024 end_weight_decay ................................ 0.01 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 10 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False ffn_hidden_size ................................. 4096 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 8 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.1 hidden_size ..................................... 1024 hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 kv_channels ..................................... 64 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ /workspace/model/megatron-models/345m-init-4pp local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 100 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. 0.00015 lr_decay_iters .................................. 320000 lr_decay_samples ................................ None lr_decay_style .................................. cosine lr_warmup_fraction .............................. 0.01 lr_warmup_iters ................................. 0 lr_warmup_samples ............................... 0 make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... True max_position_embeddings ......................... 1024 max_tokens_to_oom ............................... 12000 merge_file ...................................... /workspace/model/gpt2-vocab/gpt2-merges.txt micro_batch_size ................................ 2 min_loss_scale .................................. 1.0 min_lr .......................................... 1e-05 mmap_warmup ..................................... False no_load_optim ................................... None no_load_rng ..................................... None no_persist_layer_norm ........................... False no_save_optim ................................... None no_save_rng ..................................... None num_attention_heads ............................. 16 num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... None num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 patch_dim ....................................... 16 perform_initialization .......................... True pipeline_model_parallel_size .................... 4 pipeline_model_parallel_split_rank .............. None query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 reset_attention_mask ............................ False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ /workspace/model/megatron-models/345m-init-4pp save_interval ................................... 1000 scatter_gather_tensors_in_pipeline .............. True seed ............................................ 1234 seq_length ...................................... 1024 sequence_parallel ............................... False sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 split ........................................... 700,200,100 squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.01 swiglu .......................................... False swin_backbone_type .............................. tiny tensor_model_parallel_size ...................... 1 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. None tokenizer_type .................................. GPT2BPETokenizer train_data_path ................................. None train_iters ..................................... 2000 train_samples ................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 4 untie_embeddings_and_output_weights ............. False use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... None use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... /workspace/model/gpt2-vocab/gpt2-vocab.json vocab_size ...................................... None weight_decay .................................... 0.01 weight_decay_incr_style ......................... constant world_size ...................................... 4 -------------------- end of arguments --------------------- setting number of micro-batches to constant 4 > building GPT2BPETokenizer tokenizer ... > padded vocab (size: 50257) with 47 dummy tokens (new size: 50304) > initializing torch distributed ... > initialized tensor model parallel with size 1 > initialized pipeline model parallel with size 4 > setting random seeds to 1234 ... > compiling dataset index builder ... make: Entering directory '/workspace/code/Megatron-LM/megatron/data' make: Nothing to be done for 'default'. make: Leaving directory '/workspace/code/Megatron-LM/megatron/data' >>> done with dataset index builder. Compilation time: 0.204 seconds > compiling and loading fused kernels ... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_upper_triang_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_upper_triang_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-LM/megatron/fused_kernels/build/build.ninja... Building extension module scaled_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_softmax_cuda... >>> done with compiling and loading fused kernels. Compilation time: 4.538 seconds time to initialize megatron (seconds): 7.707 [after megatron is initialized] datetime: 2023-07-17 01:14:01 building GPT model ... > number of parameters on (tensor, pipeline) model parallel rank (0, 1): 75577344 > number of parameters on (tensor, pipeline) model parallel rank (0, 2): 75577344 > number of parameters on (tensor, pipeline) model parallel rank (0, 3): 127090688 > number of parameters on (tensor, pipeline) model parallel rank (0, 0): 128137216 > learning rate decay style: cosine WARNING: could not find the metadata file /workspace/model/megatron-models/345m-init-4pp/latest_checkpointed_iteration.txt will not load any checkpoints and will start from random /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( /usr/local/lib/python3.8/dist-packages/torch/distributed/distributed_c10d.py:2603: UserWarning: torch.distributed._all_gather_base is a private function and will be deprecated. Please use torch.distributed.all_gather_into_tensor instead. warnings.warn( (min, max) time across ranks (ms): load-checkpoint ................................: (6.23, 6.92) [after model, optimizer, and learning rate scheduler are built] datetime: 2023-07-17 01:14:01 > building train, validation, and test datasets ... > datasets target sizes (minimum size): train: 16000 validation: 240 test: 80 > building train, validation, and test datasets for GPT ... Single data path provided for train, valid & test data_prefix: ['/workspace/data/my-gpt2_text_document'] > building dataset index ... reading sizes... reading pointers... reading document index... creating numpy buffer of mmap... creating memory view of numpy buffer... > finished creating indexed dataset in 0.002993 seconds number of documents: 2456 > dataset split: train: document indices in [0, 1719) total of 1719 documents validation: document indices in [1719, 2210) total of 491 documents test: document indices in [2210, 2456) total of 246 documents > loading doc-idx mapping from /workspace/data/index-cache/09a6ab12e4c21658eefabc732b2e110b_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/09a6ab12e4c21658eefabc732b2e110b_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/09a6ab12e4c21658eefabc732b2e110b_shuffle_idx.npy loaded indexed file in 0.004 seconds total number of samples: 16296 total number of epochs: 36 > loading doc-idx mapping from /workspace/data/index-cache/2d16c1014278a21da8aa7bdfcf0f1e3f_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/2d16c1014278a21da8aa7bdfcf0f1e3f_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/2d16c1014278a21da8aa7bdfcf0f1e3f_shuffle_idx.npy loaded indexed file in 0.003 seconds total number of samples: 333 total number of epochs: 3 > loading doc-idx mapping from /workspace/data/index-cache/f1583c0457c0ee9c3ecb3c068b3badd8_doc_idx.npy > loading sample-idx mapping from /workspace/data/index-cache/f1583c0457c0ee9c3ecb3c068b3badd8_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/index-cache/f1583c0457c0ee9c3ecb3c068b3badd8_shuffle_idx.npy loaded indexed file in 0.002 seconds total number of samples: 108 total number of epochs: 2 > finished creating GPT datasets ... [after dataloaders are built] datetime: 2023-07-17 01:14:04 done with setup ... (min, max) time across ranks (ms): model-and-optimizer-setup ......................: (455.86, 465.76) train/valid/test-data-iterators-setup ..........: (2100.27, 2154.09) training ... [before the start of training step] datetime: 2023-07-17 01:14:04 [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [Rank 2] (after 100 iterations) memory (MB) | allocated: 1529.77783203125 | max allocated: 4104.89501953125 | reserved: 4170.0 | max reserved: 4170.0 [Rank 0] (after 100 iterations) memory (MB) | allocated: 2524.27783203125 | max allocated: 7643.34033203125 | reserved: 7766.0 | max reserved: 7766.0 [Rank 1] (after 100 iterations) memory (MB) | allocated: 1529.77783203125 | max allocated: 5477.08251953125 | reserved: 5498.0 | max reserved: 5498.0 iteration 100/ 2000 | consumed samples: 800 | elapsed time per iteration (ms): 452.0 | learning rate: 3.984E-06 | global batch size: 8 | lm loss: 9.682818E+00 | loss scale: 262144.0 | grad norm: 3.606 | number of skipped iterations: 15 | number of nan iterations: 0 | [Rank 3] (after 100 iterations) memory (MB) | allocated: 2513.31787109375 | max allocated: 4390.34521484375 | reserved: 4522.0 | max reserved: 4522.0 iteration 200/ 2000 | consumed samples: 1600 | elapsed time per iteration (ms): 311.9 | learning rate: 8.672E-06 | global batch size: 8 | lm loss: 8.489280E+00 | loss scale: 262144.0 | grad norm: 4.001 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 300/ 2000 | consumed samples: 2400 | elapsed time per iteration (ms): 399.3 | learning rate: 1.336E-05 | global batch size: 8 | lm loss: 7.642234E+00 | loss scale: 262144.0 | grad norm: 4.426 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 400/ 2000 | consumed samples: 3200 | elapsed time per iteration (ms): 382.2 | learning rate: 1.805E-05 | global batch size: 8 | lm loss: 6.942851E+00 | loss scale: 262144.0 | grad norm: 2.279 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 500/ 2000 | consumed samples: 4000 | elapsed time per iteration (ms): 376.9 | learning rate: 2.273E-05 | global batch size: 8 | lm loss: 6.551709E+00 | loss scale: 262144.0 | grad norm: 2.192 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 600/ 2000 | consumed samples: 4800 | elapsed time per iteration (ms): 379.9 | learning rate: 2.742E-05 | global batch size: 8 | lm loss: 6.246989E+00 | loss scale: 262144.0 | grad norm: 2.499 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 700/ 2000 | consumed samples: 5600 | elapsed time per iteration (ms): 344.4 | learning rate: 3.211E-05 | global batch size: 8 | lm loss: 6.110545E+00 | loss scale: 262144.0 | grad norm: 1.982 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 800/ 2000 | consumed samples: 6400 | elapsed time per iteration (ms): 392.7 | learning rate: 3.680E-05 | global batch size: 8 | lm loss: 5.888660E+00 | loss scale: 262144.0 | grad norm: 1.912 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 900/ 2000 | consumed samples: 7200 | elapsed time per iteration (ms): 380.3 | learning rate: 4.148E-05 | global batch size: 8 | lm loss: 5.673041E+00 | loss scale: 262144.0 | grad norm: 2.449 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1000/ 2000 | consumed samples: 8000 | elapsed time per iteration (ms): 381.1 | learning rate: 4.617E-05 | global batch size: 8 | lm loss: 5.564542E+00 | loss scale: 262144.0 | grad norm: 2.265 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 1000 | lm loss value: 6.355064E+00 | lm loss PPL: 5.753991E+02 | ------------------------------------------------------------------------------------------------ saving checkpoint at iteration 1000 to /workspace/model/megatron-models/345m-init-4pp successfully saved checkpoint at iteration 1000 to /workspace/model/megatron-models/345m-init-4pp (min, max) time across ranks (ms): save-checkpoint ................................: (32390.20, 32392.97) iteration 1100/ 2000 | consumed samples: 8800 | elapsed time per iteration (ms): 665.5 | learning rate: 5.086E-05 | global batch size: 8 | lm loss: 5.377799E+00 | loss scale: 524288.0 | grad norm: 1.871 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1200/ 2000 | consumed samples: 9600 | elapsed time per iteration (ms): 392.0 | learning rate: 5.555E-05 | global batch size: 8 | lm loss: 5.238356E+00 | loss scale: 524288.0 | grad norm: 1.560 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1300/ 2000 | consumed samples: 10400 | elapsed time per iteration (ms): 381.3 | learning rate: 6.023E-05 | global batch size: 8 | lm loss: 5.050917E+00 | loss scale: 524288.0 | grad norm: 2.267 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1400/ 2000 | consumed samples: 11200 | elapsed time per iteration (ms): 382.2 | learning rate: 6.492E-05 | global batch size: 8 | lm loss: 4.976177E+00 | loss scale: 524288.0 | grad norm: 1.927 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1500/ 2000 | consumed samples: 12000 | elapsed time per iteration (ms): 383.2 | learning rate: 6.961E-05 | global batch size: 8 | lm loss: 4.809005E+00 | loss scale: 524288.0 | grad norm: 1.670 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1600/ 2000 | consumed samples: 12800 | elapsed time per iteration (ms): 379.0 | learning rate: 7.430E-05 | global batch size: 8 | lm loss: 4.620012E+00 | loss scale: 524288.0 | grad norm: 1.684 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1700/ 2000 | consumed samples: 13600 | elapsed time per iteration (ms): 318.1 | learning rate: 7.898E-05 | global batch size: 8 | lm loss: 4.443442E+00 | loss scale: 524288.0 | grad norm: 1.676 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1800/ 2000 | consumed samples: 14400 | elapsed time per iteration (ms): 405.2 | learning rate: 8.367E-05 | global batch size: 8 | lm loss: 4.210877E+00 | loss scale: 524288.0 | grad norm: 1.578 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 1900/ 2000 | consumed samples: 15200 | elapsed time per iteration (ms): 379.4 | learning rate: 8.836E-05 | global batch size: 8 | lm loss: 3.972883E+00 | loss scale: 524288.0 | grad norm: 1.674 | number of skipped iterations: 0 | number of nan iterations: 0 | iteration 2000/ 2000 | consumed samples: 16000 | elapsed time per iteration (ms): 385.6 | learning rate: 9.305E-05 | global batch size: 8 | lm loss: 3.723653E+00 | loss scale: 524288.0 | grad norm: 1.719 | number of skipped iterations: 0 | number of nan iterations: 0 | ------------------------------------------------------------------------------------------------ validation loss at iteration 2000 | lm loss value: 6.176825E+00 | lm loss PPL: 4.814607E+02 | ------------------------------------------------------------------------------------------------ saving checkpoint at iteration 2000 to /workspace/model/megatron-models/345m-init-4pp successfully saved checkpoint at iteration 2000 to /workspace/model/megatron-models/345m-init-4pp (min, max) time across ranks (ms): save-checkpoint ................................: (59290.87, 59295.51) [after training is done] datetime: 2023-07-17 01:28:11 saving checkpoint at iteration 2000 to /workspace/model/megatron-models/345m-init-4pp ------------------------------------------------------------------------------------------------------------------ validation loss at the end of training for val data | lm loss value: 6.235375E+00 | lm loss PPL: 5.104922E+02 | ------------------------------------------------------------------------------------------------------------------ successfully saved checkpoint at iteration 2000 to /workspace/model/megatron-models/345m-init-4pp ------------------------------------------------------------------------------------------------------------------- validation loss at the end of training for test data | lm loss value: 6.396670E+00 | lm loss PPL: 5.998441E+02 | ------------------------------------------------------------------------------------------------------------------- ```

模型权重输出:

``` > tree -h /workspace/model/megatron-models/345m-init-4pp /workspace/model/megatron-models/345m-init-4pp ├── [4.0K] iter_0001000 │ ├── [4.0K] mp_rank_00_000 │ │ └── [1.7G] model_optim_rng.pt │ ├── [4.0K] mp_rank_00_001 │ │ └── [1009M] model_optim_rng.pt │ ├── [4.0K] mp_rank_00_002 │ │ └── [1009M] model_optim_rng.pt │ └── [4.0K] mp_rank_00_003 │ └── [1.7G] model_optim_rng.pt ├── [4.0K] iter_0002000 │ ├── [4.0K] mp_rank_00_000 │ │ └── [1.7G] model_optim_rng.pt │ ├── [4.0K] mp_rank_00_001 │ │ └── [1009M] model_optim_rng.pt │ ├── [4.0K] mp_rank_00_002 │ │ └── [1009M] model_optim_rng.pt │ └── [4.0K] mp_rank_00_003 │ └── [1.7G] model_optim_rng.pt └── [ 4] latest_checkpointed_iteration.txt 10 directories, 9 files > cat /workspace/model/megatron-models/345m-init-4pp/latest_checkpointed_iteration.txt 2000 ```

显存占用: ``` +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 2630871 C /usr/bin/python 8680MiB | | 1 N/A N/A 2630872 C /usr/bin/python 6408MiB | | 2 N/A N/A 2630873 C /usr/bin/python 5080MiB | | 3 N/A N/A 2630874 C /usr/bin/python 5436MiB | +-----------------------------------------------------------------------------+ ``` ================================================ FILE: llm-train/megatron/gpt2/requirements.txt ================================================ absl-py==1.4.0 aiohttp @ file:///rapids/aiohttp-3.8.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl aiosignal @ file:///rapids/aiosignal-1.3.1-py3-none-any.whl apex==0.1 argon2-cffi==21.3.0 argon2-cffi-bindings==21.2.0 asttokens==2.2.1 astunparse==1.6.3 async-timeout @ file:///rapids/async_timeout-4.0.2-py3-none-any.whl attrs==22.2.0 audioread==3.0.0 backcall==0.2.0 beautifulsoup4==4.12.2 bleach==6.0.0 blis==0.7.9 boto3==1.26.162 botocore==1.29.162 bs4==0.0.1 cachetools==5.3.0 catalogue==2.0.8 certifi==2022.12.7 cffi==1.15.1 charset-normalizer==3.1.0 click==8.1.3 cloudpickle @ file:///rapids/cloudpickle-2.2.1-py3-none-any.whl cmake==3.24.1.1 comm==0.1.3 confection==0.0.4 contourpy==1.0.7 cssselect==1.2.0 cubinlinker @ file:///rapids/cubinlinker-0.2.2%2B2.g5f51201-cp38-cp38-linux_x86_64.whl cuda-python @ file:///rapids/cuda_python-12.1.0rc5%2B1.g808384c-cp38-cp38-linux_x86_64.whl cudf @ file:///rapids/cudf-23.2.0-cp38-cp38-linux_x86_64.whl cugraph @ file:///rapids/cugraph-23.2.0-cp38-cp38-linux_x86_64.whl cugraph-dgl @ file:///rapids/cugraph_dgl-23.2.0-py3-none-any.whl cugraph-service-client @ file:///rapids/cugraph_service_client-23.2.0-py3-none-any.whl cugraph-service-server @ file:///rapids/cugraph_service_server-23.2.0-py3-none-any.whl cuml @ file:///rapids/cuml-23.2.0-cp38-cp38-linux_x86_64.whl cupy-cuda12x @ file:///rapids/cupy_cuda12x-12.0.0b3-cp38-cp38-linux_x86_64.whl cycler==0.11.0 cymem==2.0.7 Cython==0.29.34 dask @ file:///rapids/dask-2023.1.1-py3-none-any.whl dask-cuda @ file:///rapids/dask_cuda-23.2.0-py3-none-any.whl dask-cudf @ file:///rapids/dask_cudf-23.2.0-py3-none-any.whl debugpy==1.6.7 decorator==5.1.1 defusedxml==0.7.1 distributed @ file:///rapids/distributed-2023.1.1-py3-none-any.whl exceptiongroup==1.1.1 execnet==1.9.0 executing==1.2.0 expecttest==0.1.3 fastjsonschema==2.16.3 fastrlock @ file:///rapids/fastrlock-0.8.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_24_x86_64.whl feedfinder2==0.0.4 feedparser==6.0.10 filelock==3.11.0 flash-attn @ git+https://github.com/ksivaman/flash-attention.git@7f1c81a5f33e18f22d1e2ba42681f0743bf58b92 fonttools==4.39.3 frozenlist @ file:///rapids/frozenlist-1.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl fsspec @ file:///rapids/fsspec-2023.4.0-py3-none-any.whl ftfy==6.1.1 gast==0.4.0 google-auth==2.17.3 google-auth-oauthlib==0.4.6 graphsurgeon @ file:///workspace/TensorRT-8.6.1.2/graphsurgeon/graphsurgeon-0.4.6-py2.py3-none-any.whl grpcio==1.53.0 HeapDict @ file:///rapids/HeapDict-1.0.1-py3-none-any.whl htmlmin==0.1.12 hypothesis==5.35.1 idna==3.4 importlib-metadata==6.3.0 importlib-resources==5.12.0 iniconfig==2.0.0 intel-openmp==2021.4.0 ipykernel==6.22.0 ipython==8.12.0 ipython-genutils==0.2.0 jedi==0.18.2 jieba3k==0.35.1 Jinja2==3.1.2 jmespath==1.0.1 joblib==1.2.0 json5==0.9.11 jsonschema==4.17.3 jupyter-tensorboard @ git+https://github.com/cliffwoolley/jupyter_tensorboard.git@ffa7e26138b82549453306e06b535a9ac36db17a jupyter_client==8.2.0 jupyter_core==5.3.0 jupyterlab==2.3.2 jupyterlab-pygments==0.2.2 jupyterlab-server==1.2.0 jupytext==1.14.5 kiwisolver==1.4.4 langcodes==3.3.0 langdetect==1.0.9 librosa==0.9.2 lit==16.0.1 llvmlite==0.39.1 locket @ file:///rapids/locket-1.0.0-py2.py3-none-any.whl lxml==4.9.2 Markdown==3.4.3 markdown-it-py==2.2.0 MarkupSafe==2.1.2 matplotlib==3.7.1 matplotlib-inline==0.1.6 mdit-py-plugins==0.3.5 mdurl==0.1.2 mistune==2.0.5 mkl==2021.1.1 mkl-devel==2021.1.1 mkl-include==2021.1.1 mock==5.0.1 mpmath==1.3.0 msgpack @ file:///rapids/msgpack-1.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl multidict @ file:///rapids/multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl murmurhash==1.0.9 nbclient==0.7.3 nbconvert==7.3.1 nbformat==5.8.0 nest-asyncio==1.5.6 networkx==2.6.3 newspaper3k==0.2.8 nltk==3.8.1 notebook==6.4.10 numba @ file:///rapids/numba-0.56.4%2B1.g536eedd6e-cp38-cp38-linux_x86_64.whl numpy==1.22.2 nvidia-dali-cuda110==1.24.0 nvidia-pyindex==1.0.9 nvtx @ file:///rapids/nvtx-0.2.5-cp38-cp38-linux_x86_64.whl oauthlib==3.2.2 onnx @ file:///opt/pytorch/pytorch/third_party/onnx opencv @ file:///opencv-4.6.0/modules/python/package packaging @ file:///rapids/packaging-23.0-py3-none-any.whl pandas @ file:///rapids/pandas-1.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl pandocfilters==1.5.0 parso==0.8.3 partd @ file:///rapids/partd-1.3.0-py3-none-any.whl pathy==0.10.1 pexpect==4.8.0 pickleshare==0.7.5 Pillow @ file:///tmp/pillow-simd pkgutil_resolve_name==1.3.10 platformdirs==3.2.0 pluggy==1.0.0 ply @ file:///rapids/ply-3.11-py2.py3-none-any.whl polygraphy==0.46.2 pooch==1.7.0 preshed==3.0.8 prettytable==3.7.0 prometheus-client==0.16.0 prompt-toolkit==3.0.38 protobuf==3.20.3 psutil==5.9.4 ptxcompiler @ file:///rapids/ptxcompiler-0.7.0%2B27.gb446f00-cp38-cp38-linux_x86_64.whl ptyprocess==0.7.0 pure-eval==0.2.2 pyarrow @ file:///rapids/pyarrow-10.0.1.dev0%2Bga6eabc2b.d20230410-cp38-cp38-linux_x86_64.whl pyasn1==0.4.8 pyasn1-modules==0.2.8 pybind11==2.10.4 pycocotools @ git+https://github.com/nvidia/cocoapi.git@8b8fd68576675c3ee77402e61672d65a7d826ddf#subdirectory=PythonAPI pycparser==2.21 pydantic==1.10.7 Pygments==2.15.0 pylibcugraph @ file:///rapids/pylibcugraph-23.2.0-cp38-cp38-linux_x86_64.whl pylibcugraphops @ file:///rapids/pylibcugraphops-23.2.0-cp38-cp38-linux_x86_64.whl pylibraft @ file:///rapids/pylibraft-23.2.0-cp38-cp38-linux_x86_64.whl pynvml @ file:///rapids/pynvml-11.4.1-py3-none-any.whl pyparsing==3.0.9 pyrsistent==0.19.3 pytest==7.3.1 pytest-rerunfailures==11.1.2 pytest-shard==0.1.2 pytest-xdist==3.2.1 python-dateutil==2.8.2 python-hostlist==1.23.0 pytorch-quantization==2.1.2 pytz @ file:///rapids/pytz-2023.3-py2.py3-none-any.whl PyYAML==6.0 pyzmq==25.0.2 raft-dask @ file:///rapids/raft_dask-23.2.0-cp38-cp38-linux_x86_64.whl regex==2023.3.23 requests==2.28.2 requests-file==1.5.1 requests-oauthlib==1.3.1 resampy==0.4.2 rmm @ file:///rapids/rmm-23.2.0-cp38-cp38-linux_x86_64.whl rsa==4.9 s3transfer==0.6.1 scikit-learn @ file:///rapids/scikit_learn-1.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl scipy @ file:///rapids/scipy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl seaborn @ file:///rapids/seaborn-0.12.2-py3-none-any.whl Send2Trash==1.8.0 sentencepiece==0.1.99 sgmllib3k==1.0.0 six==1.16.0 smart-open==6.3.0 sortedcontainers==2.4.0 soundfile==0.12.1 soupsieve==2.4 spacy==3.5.2 spacy-legacy==3.0.12 spacy-loggers==1.0.4 sphinx-glpi-theme==0.3 srsly==2.4.6 stack-data==0.6.2 strings-udf @ file:///rapids/strings_udf-23.2.0-cp38-cp38-linux_x86_64.whl sympy==1.11.1 tbb==2021.9.0 tblib @ file:///rapids/tblib-1.7.0-py2.py3-none-any.whl tensorboard==2.9.0 tensorboard-data-server==0.6.1 tensorboard-plugin-wit==1.8.1 tensorrt @ file:///workspace/TensorRT-8.6.1.2/python/tensorrt-8.6.1-cp38-none-linux_x86_64.whl terminado==0.17.1 thinc==8.1.9 threadpoolctl==3.1.0 thriftpy2 @ file:///rapids/thriftpy2-0.4.16-cp38-cp38-linux_x86_64.whl tinycss2==1.2.1 tinysegmenter==0.3 tldextract==3.4.4 toml==0.10.2 tomli==2.0.1 toolz @ file:///rapids/toolz-0.12.0-py3-none-any.whl torch==2.1.0a0+fe05266 torch-tensorrt @ file:///opt/pytorch/torch_tensorrt/py/dist/torch_tensorrt-1.4.0.dev0-cp38-cp38-linux_x86_64.whl torchtext @ git+https://github.com/pytorch/text@fae8e8cabf7adcbbc2f09c0520216288fd53f33b torchvision @ file:///opt/pytorch/vision tornado==6.2 tqdm==4.65.0 traitlets==5.9.0 transformer-engine @ git+https://github.com/NVIDIA/TransformerEngine.git@770e968b073c4712f03bcc1a84eb564bf7067997 treelite @ file:///rapids/treelite-3.1.0-cp38-cp38-linux_x86_64.whl treelite-runtime @ file:///rapids/treelite_runtime-3.1.0-cp38-cp38-linux_x86_64.whl triton @ file:///tmp/dist/triton-2.0.0-cp38-cp38-linux_x86_64.whl typer==0.7.0 types-dataclasses==0.6.6 typing_extensions==4.5.0 ucx-py @ file:///rapids/ucx_py-0.30.0-cp38-cp38-linux_x86_64.whl uff @ file:///workspace/TensorRT-8.6.1.2/uff/uff-0.6.9-py2.py3-none-any.whl urllib3==1.26.15 wasabi==1.1.1 wcwidth==0.2.6 webencodings==0.5.1 Werkzeug==2.2.3 xdoctest==1.0.2 xgboost @ file:///rapids/xgboost-1.7.1-cp38-cp38-linux_x86_64.whl yarl @ file:///rapids/yarl-1.8.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl zict @ file:///rapids/zict-2.2.0-py2.py3-none-any.whl zipp==3.15.0 ================================================ FILE: llm-train/megatron/gpt2/train/pretrain_gpt.sh ================================================ #!/bin/bash # Runs the "345M" parameter model export CUDA_DEVICE_MAX_CONNECTIONS=1 #CHECKPOINT_PATH= #VOCAB_FILE=/gpt2-vocab.json #MERGE_FILE=/gpt2-merges.txt #DATA_PATH=_text_document CHECKPOINT_PATH=/workspace/model/megatron-models/345m VOCAB_FILE=/workspace/model/gpt2-vocab/gpt2-vocab.json MERGE_FILE=/workspace/model/gpt2-vocab/gpt2-merges.txt #DATA_PATH=/workspace/data/merged_cleand.json DATA_PATH=/workspace/data/my-gpt2_text_document MODEL_PATH=/workspace/model/megatron-models/output GPT_ARGS=" --num-layers 24 \ --hidden-size 1024 \ --num-attention-heads 16 \ --seq-length 1024 \ --max-position-embeddings 1024 \ --micro-batch-size 1 \ --global-batch-size 2 \ --lr 0.00015 \ --train-iters 5000 \ --lr-decay-iters 320000 \ --lr-decay-style cosine \ --min-lr 1.0e-5 \ --weight-decay 1e-2 \ --lr-warmup-fraction .01 \ --clip-grad 1.0 \ --fp16 " DATA_ARGS=" --data-path $DATA_PATH \ --vocab-file $VOCAB_FILE \ --merge-file $MERGE_FILE \ --data-impl mmap \ --split 700,200,100 " OUTPUT_ARGS=" --log-interval 100 \ --save-interval 10000 \ --eval-interval 1000 \ --eval-iters 10 " torchrun pretrain_gpt.py \ $GPT_ARGS \ $DATA_ARGS \ $OUTPUT_ARGS \ --save $MODEL_PATH \ --load $CHECKPOINT_PATH ================================================ FILE: llm-train/megatron/gpt2/train/pretrain_gpt_distributed.sh ================================================ #!/bin/bash # Runs the "345M" parameter model export CUDA_DEVICE_MAX_CONNECTIONS=1 GPUS_PER_NODE=4 # Change for multinode config MASTER_ADDR=localhost MASTER_PORT=6008 NNODES=1 NODE_RANK=0 WORLD_SIZE=$(($GPUS_PER_NODE*$NNODES)) #CHECKPOINT_PATH= #VOCAB_FILE=/gpt2-vocab.json #MERGE_FILE=/gpt2-merges.txt #DATA_PATH=_text_document CHECKPOINT_PATH=/workspace/model/megatron-models/345m-init VOCAB_FILE=/workspace/model/gpt2-vocab/gpt2-vocab.json MERGE_FILE=/workspace/model/gpt2-vocab/gpt2-merges.txt DATA_PATH=/workspace/data/my-gpt2_text_document MODEL_PATH=/workspace/model/megatron-models/345m-init DISTRIBUTED_ARGS=" --nproc_per_node $GPUS_PER_NODE \ --nnodes $NNODES \ --node_rank $NODE_RANK \ --master_addr $MASTER_ADDR \ --master_port $MASTER_PORT " GPT_ARGS=" --num-layers 24 \ --hidden-size 1024 \ --num-attention-heads 16 \ --seq-length 1024 \ --max-position-embeddings 1024 \ --micro-batch-size 1 \ --global-batch-size 8 \ --lr 0.00015 \ --train-iters 5000 \ --lr-decay-iters 320000 \ --lr-decay-style cosine \ --min-lr 1.0e-5 \ --weight-decay 1e-2 \ --lr-warmup-fraction .01 \ --clip-grad 1.0 \ --fp16 " DATA_ARGS=" --data-path $DATA_PATH \ --vocab-file $VOCAB_FILE \ --merge-file $MERGE_FILE \ --data-impl mmap \ --split 700,200,100 " OUTPUT_ARGS=" --log-interval 100 \ --save-interval 10000 \ --eval-interval 1000 \ --eval-iters 10 " torchrun $DISTRIBUTED_ARGS pretrain_gpt.py \ $GPT_ARGS \ $DATA_ARGS \ $OUTPUT_ARGS \ --distributed-backend nccl \ --save $CHECKPOINT_PATH \ --load $CHECKPOINT_PATH ================================================ FILE: llm-train/megatron/gpt2/train/pretrain_gpt_distributed_with_4pp.sh ================================================ #!/bin/bash # Runs the "345M" parameter model export CUDA_DEVICE_MAX_CONNECTIONS=1 GPUS_PER_NODE=4 # Change for multinode config MASTER_ADDR=localhost MASTER_PORT=6069 NNODES=1 NODE_RANK=0 WORLD_SIZE=$(($GPUS_PER_NODE*$NNODES)) #CHECKPOINT_PATH= #VOCAB_FILE=/gpt2-vocab.json #MERGE_FILE=/gpt2-merges.txt #DATA_PATH=_text_document CHECKPOINT_PATH=/workspace/model/megatron-models/345m-init-4pp VOCAB_FILE=/workspace/model/gpt2-vocab/gpt2-vocab.json MERGE_FILE=/workspace/model/gpt2-vocab/gpt2-merges.txt DATA_PATH=/workspace/data/my-gpt2_text_document MODEL_PATH=/workspace/model/megatron-models/345m-init-4pp DISTRIBUTED_ARGS=" --nproc_per_node $GPUS_PER_NODE \ --nnodes $NNODES \ --node_rank $NODE_RANK \ --master_addr $MASTER_ADDR \ --master_port $MASTER_PORT " GPT_ARGS=" --tensor-model-parallel-size 1 \ --pipeline-model-parallel-size 4 \ --sequence-parallel \ --num-layers 24 \ --hidden-size 1024 \ --num-attention-heads 16 \ --seq-length 1024 \ --max-position-embeddings 1024 \ --micro-batch-size 2 \ --global-batch-size 8 \ --lr 0.00015 \ --train-iters 2000 \ --lr-decay-iters 320000 \ --lr-decay-style cosine \ --min-lr 1.0e-5 \ --weight-decay 1e-2 \ --lr-warmup-fraction .01 \ --clip-grad 1.0 \ --fp16 " DATA_ARGS=" --data-path $DATA_PATH \ --vocab-file $VOCAB_FILE \ --merge-file $MERGE_FILE \ --data-impl mmap \ --split 700,200,100 " OUTPUT_ARGS=" --log-interval 100 \ --save-interval 1000 \ --eval-interval 1000 \ --eval-iters 10 " torchrun $DISTRIBUTED_ARGS pretrain_gpt.py \ $GPT_ARGS \ $DATA_ARGS \ $OUTPUT_ARGS \ --distributed-backend nccl \ --save $MODEL_PATH \ --load $CHECKPOINT_PATH ================================================ FILE: llm-train/megatron/gpt2/train/pretrain_gpt_distributed_with_4tp.sh ================================================ #!/bin/bash # Runs the "345M" parameter model export CUDA_DEVICE_MAX_CONNECTIONS=1 GPUS_PER_NODE=4 # Change for multinode config MASTER_ADDR=localhost MASTER_PORT=6069 NNODES=1 NODE_RANK=0 WORLD_SIZE=$(($GPUS_PER_NODE*$NNODES)) #CHECKPOINT_PATH= #VOCAB_FILE=/gpt2-vocab.json #MERGE_FILE=/gpt2-merges.txt #DATA_PATH=_text_document CHECKPOINT_PATH=/workspace/model/megatron-models/345m-init-4tp VOCAB_FILE=/workspace/model/gpt2-vocab/gpt2-vocab.json MERGE_FILE=/workspace/model/gpt2-vocab/gpt2-merges.txt DATA_PATH=/workspace/data/my-gpt2_text_document MODEL_PATH=/workspace/model/megatron-models/345m-init-4tp DISTRIBUTED_ARGS=" --nproc_per_node $GPUS_PER_NODE \ --nnodes $NNODES \ --node_rank $NODE_RANK \ --master_addr $MASTER_ADDR \ --master_port $MASTER_PORT " GPT_ARGS=" --tensor-model-parallel-size 4 \ --pipeline-model-parallel-size 1 \ --sequence-parallel \ --num-layers 24 \ --hidden-size 1024 \ --num-attention-heads 16 \ --seq-length 1024 \ --max-position-embeddings 1024 \ --micro-batch-size 2 \ --global-batch-size 8 \ --lr 0.00015 \ --train-iters 2000 \ --lr-decay-iters 320000 \ --lr-decay-style cosine \ --min-lr 1.0e-5 \ --weight-decay 1e-2 \ --lr-warmup-fraction .01 \ --clip-grad 1.0 \ --fp16 " DATA_ARGS=" --data-path $DATA_PATH \ --vocab-file $VOCAB_FILE \ --merge-file $MERGE_FILE \ --data-impl mmap \ --split 700,200,100 " OUTPUT_ARGS=" --log-interval 100 \ --save-interval 1000 \ --eval-interval 1000 \ --eval-iters 10 " torchrun $DISTRIBUTED_ARGS pretrain_gpt.py \ $GPT_ARGS \ $DATA_ARGS \ $OUTPUT_ARGS \ --distributed-backend nccl \ --save $MODEL_PATH \ --load $CHECKPOINT_PATH ================================================ FILE: llm-train/megatron/gpt2/train/pretrain_gpt_distributed_with_mp.sh ================================================ #!/bin/bash # Runs the "345M" parameter model export CUDA_DEVICE_MAX_CONNECTIONS=1 GPUS_PER_NODE=4 # Change for multinode config MASTER_ADDR=localhost MASTER_PORT=6069 NNODES=1 NODE_RANK=0 WORLD_SIZE=$(($GPUS_PER_NODE*$NNODES)) #CHECKPOINT_PATH= #VOCAB_FILE=/gpt2-vocab.json #MERGE_FILE=/gpt2-merges.txt #DATA_PATH=_text_document CHECKPOINT_PATH=/workspace/model/megatron-models/345m-init-mp VOCAB_FILE=/workspace/model/gpt2-vocab/gpt2-vocab.json MERGE_FILE=/workspace/model/gpt2-vocab/gpt2-merges.txt DATA_PATH=/workspace/data/my-gpt2_text_document MODEL_PATH=/workspace/model/megatron-models/345m-init-mp DISTRIBUTED_ARGS=" --nproc_per_node $GPUS_PER_NODE \ --nnodes $NNODES \ --node_rank $NODE_RANK \ --master_addr $MASTER_ADDR \ --master_port $MASTER_PORT " GPT_ARGS=" --tensor-model-parallel-size 2 \ --pipeline-model-parallel-size 2 \ --sequence-parallel \ --num-layers 24 \ --hidden-size 1024 \ --num-attention-heads 16 \ --seq-length 1024 \ --max-position-embeddings 1024 \ --micro-batch-size 4 \ --global-batch-size 16 \ --lr 0.00015 \ --train-iters 5000 \ --lr-decay-iters 320000 \ --lr-decay-style cosine \ --min-lr 1.0e-5 \ --weight-decay 1e-2 \ --lr-warmup-fraction .01 \ --clip-grad 1.0 \ --fp16 " DATA_ARGS=" --data-path $DATA_PATH \ --vocab-file $VOCAB_FILE \ --merge-file $MERGE_FILE \ --data-impl mmap \ --split 700,200,100 " OUTPUT_ARGS=" --log-interval 100 \ --save-interval 2000 \ --eval-interval 1000 \ --eval-iters 10 " torchrun $DISTRIBUTED_ARGS pretrain_gpt.py \ $GPT_ARGS \ $DATA_ARGS \ $OUTPUT_ARGS \ --distributed-backend nccl \ --save $MODEL_PATH \ --load $CHECKPOINT_PATH ================================================ FILE: llm-train/megatron/megatron.drawio ================================================ 7Vxbc9o4FP41nuk+hPEd+xEI7T50p53tzDbdF0bYwqgVllcWAfrrV7LlK3IICbcQyAyRju46R985OpLQrNFi/YmCZP4XCSHWTD1ca9a9Zpq+7fJvQdjkBMf3c0JEUZiTjIrwDf2GkqhL6hKFMG1kZIRghpImMSBxDAPWoAFKyaqZbUZws9UERHCL8C0AeJv6HYVsnlM9s1/R/4QomhctG64c3wIUmeVI0jkIyapGssaaNaKEsDy0WI8gFnNXzEte7mNHatkxCmP2nALe6uHL49d/aTT4Mvz5+5/p6Mv31Z2V1/II8FIOWDNdzOsbJhSKTrONnAn3v6Xo6XAKgl8RJcs4vAsIJlSzBjwfjaYfTMfRRB9G/LsV/kNErGHGgJjdzcAC4U1ektcMFkmWaFk2/98DSYJhukkZXCyRyL+VpVlbmgmNqMvveQmruspDkRwKowDFkyhLxXnax2yEeQ7JoXKwJmdWIoLLBf6MZhCjGIqKIEULyCAf9D2W5K8VbbiaIwa/JSAQRVd8PXDanC0wjxk8yGWU8W5kxfM4xiBJ0TRrVQyJwmBJU/QI/4b5qDIqWTLR0qgUcb3scp39UiIeIWVwXSNJcfgECe8n3fAsMtXUpWjKtdmX0VUl6EaRZV4TcteXRCAXV1RWXckfD0gR3EMc7fcgjruGtLtPPyGbCoFOBc6QmCh7lA1WpKaZQHb00dB7jqqTCxgBRkncy1YOiqOuhXNbTsVycg1n53Lqn3Q5+Ze3nE4gusUYp3RPKeV8Zk0RS/kS+MUlJZuJ+5hkYjtDGLdIAKMo5tGAS08mukJqELciBjJhgcJQNKOU6Wy+YSglMcIgTQ8I8m4T5EvQr4ml6SvE0jyWVFrG1szDkBtdMkoom5OIxACPK2prjqo8nwlJJLO4aLGNtCDBkpEmK+EasYda+IeoqufI2P1a1pxFNrumPyVLGsAnxmhITSYG9iSXKMSAcYRqGq6KKZdFvxIkNFDBXctpctdpc40BGkEmS1WMG1AKNrVsiciQdrdj+812LKNlbO7IX/Srkpu8B5UUlXPycsEyus0HXjUQu4Q5oClkDchbstmdt7+WbsGjXuJWLdQCRlmJKBITugC4mbySi0+k23k1WSLmcg3pncBCoYdV5QVy3UkQGmRFZqyZiPjqiWXlerJuJnIdH6czXmVReVyB7orQsNl2vfjR9IWc5U51UXLr1YaO2LFOEkoe+UaT7qcpdhgodUXB1dvMC2AQbGkVnjL1HNs5Ft57CjPEVpkhR8N7fWv+Toj3eq9fgPyPWtLBAd+5NsA3zwDgzg3A82RpSN4g/DkQnjt3uNCgcMJgyiYhYIBLSXpNsO74jfVoKGC9MMpOA+uGfxZYj3nfHwrsFpGaIS+iFbBnsU09VnMuvBbupVs7R9unMvaPohf2hXPXbqkN62n7vZ3f8E8B/+754N8xShxqBN+5BrC9CvVtv6YB2qrxvBqg8PAfFecd8afCeTf7aLnntkbPP8fBf0fhxlF5cY4G/8UJ2Jngv4zk8G/uxP/Tun/6z1QPpnVo9fA6nd6/IfANgS8WgTstbT37HAZp+0bL9HG3kdY8qaVtmed0oJwIMb1r858027HbtzMuwmHudcL9fgeEYnFmnxI2molyfV4QXgkXwSQhKRM+ggCm6fW5CCx/G7jUB9BHsxGNA8nX7T7HoQ7FeeFY2csnj5DarLAqQ8QwzDLsu/twgiSQAkbozkFvpQQkTgkG6R5FeAsg2KeNBYzxXozolFzwQeyVZDmrMm2tSob1ni6EuOsSjliFFTzlLLyx9c2yFcWIoRtDr4ehnB2/4Q6G7r6NdLtJV1gyfssYPv9NOtN9K1uwLg/ZLgfZy7dupvlcZ9fBz8hfx1Pz3e5+Mg2UodaksjHe+v7H0FuwYahw47ROcvsssPHCM9JXQID1XAgwLwsCDvX+5QYBF3161vbpmvbZkaH7qtO1S96kJnoh4vKApkvG8e76FJCp8MCV9+pPI2YKD+/Y1TxfG/S1sacNDM0bdc1xbT6f/8CBig0CqHYO0lHO63WGmnMv6uIKS24iOt9YHGITYbWYYWwzQ3UPtn0gcDheKJ7jvBNeGFbrPpHpnJkZluKtwNjWhmPNvxfMGDqav73nu8oXQk7rGah1dt4odKNgia55ljbua76tDbzrXChO+52NQoOclhfdd/Ku3U6pW8j5IxFAAcbi9w3evKXitI7BVQaxUtCOd8mh++rR7ayw1uAJzwovupPlA/WAUNgrluYkZYDBrgV687vvgAW7tU9WXX1yVKjwAsc7j1Y/fpLfaKl+QcYa/w8=7Vzfb+I4EP5rkO4eQEmcH+SxtL29l54q9aR9XJnEhGhNzBlT2v3rz04ciGNDaUsIbF1VbTJjT+L55rM9NmYAbhcv3yhczh9IivDAc9KXAbgbeF7sh/yvELxWgiCOK0FG87QSuTvBU/4LSaEjpes8RSulICMEs3ypChNSFChhigxSSjZqsRnB6lOXMEOa4CmBWJd+z1M2r6RjL9rJ/0Z5Nq+f7IayfQtYF5YtWc1hSjYNEbgfgFtKCKuuFi+3CAvf1X5JV99/TR5+uDQD7If3CGhwNxlWxv56T5VtEygq2GlN1+55hngtHSYby15rD1KyLlIkrDgDMNnMc4aeljAR2g0PGS6bswXmdy6/3DpJlJ3lGN8STGhpCKQQjWeJKMQo+YkamjAZo+mMa45saf3WiDL00sBZtvwbIgvE6CsvUmvHEkQZxW4g7ze7mAh9KZs346GuCGUcZlvbO1/zC+nu97je+ZquB3Hvrgdel67HcIrwBCY/s9JG7euCFLzyJIWreWnW1VFCges7wgThT8qZcJgbmECbeI5TFpyRgjXks/KnSzDjFo9CHUzgGMD0nc7A7LQL+53BDNyLA9NEzBAz4bYlLBRQw//WYuSdJJXHbriSZtM/+JvxX/50p3H1p7gUjnSEj4czuMjxa1WHG4KLZakEwBeRgPAzYnkCNY1qZFVOdYQJ11u+tHTVWwplQegCYlW9kb4Uer96z1KJEWOIDlciYIrMWJ9Dy4YQ51lRqRMeE4iq6pzHeiHNO41XK5WMwmI140Zr8zyQ6wIbQlP16c3q0y0Lhi2fe/5462vPj3fXQcPzab5aYii9nhc4bzx4hglkzReqweVXmfifudtA4HFVxUKl+RzXu6KW57SoFenUcj0DtcLOuknLLMssI7PAVTELhJfGLN8yyzLLyCz/qpgVeJfGrOD9zNK4sqPGXhoc4sB+ArwV/YdCf3/cHw76AxG/N16NwVpGqRavQSfx2s6L3DRAkSkRisMIwPDNpKur+A/ba0S9x3+oxX/mnBQLnl96iXFZKA2nYdAfFu35s29YNDovFpGOhXuZ/Xh7htS/78a67z65RnMtcdweU/vHIrZj6jnH1G6Sq2sdUvsP/3rJ02ZrNltTmXpdyZo2QXJ7Z5ZpH8YyyzIr6yatPNv0uX9m2V0xyywjs8KrYpaWDPXPrA/sitls6OPZUGSzocuK/5PsXclhRY4p5gHFkuRokozPQRJOkXHqm0gy9qYgvJyVX8/wSc0zk+QD21CWJB2TJP7SJGnnKBdAEn2vyuYoNkcRu8rOVScpF0AtfevRJildfgzCtVnKZRFA3z/WoEBFeiNOiw3Mn83/cMeBUuV4me61hlcCg1NqGUUYsvy5acvsKfmER5Lz19udu/BVUEDb2SuypgmStXb+1gzFte/2GWKQZohphkrgts3+BJam/eevhWXQynAi74NYtg21z0t1DGWN3CEoq86tPnjpDdoHbZai3OIlE0dPR7x33iRzSNkIFgVh3Mek+CHqyJHjDqMZq/vFR7LKRQEuphVEk6VoKaL3zzwaVgPDYR4qjfLbYex0OT93AgWZoL5vRFhkiDC3sz7UM610WrBKsNxwFKm9oh+DkRdrkPEZz8iJdNiAG42CroDTl+juHjXoxFRJxauGYTvVEg7h8z98IxWLPE1F9QlFfCIIp6Upp0ambEYwGQR3wtaakWqyWMG0/wTbniNw5z7Z5jtgFIVqL2s83KZj2e6MTwekvoz0rwXyLW56akcaen2jaFrnuOh+tCto2mmCc2SaALrDxpQonxwbV8emNwzaacEWlObZ+vPOM/Rc7dH2cm/teaidHDBk3Oft5PQk7eEYEN/v6eNhN62uqOsv6vdfnHugclUMDR90NX3HRWcQ1vFiITx+4au1qdI7hHrK9g9JkT6mXTSKytLN4RXNcwM+bu+igb4R13M9gbh+zsgifhrEfcMRvxMhzm93Xw1WLbntvl8N3P8PnZPfT4MwEMf/GhJ9MAGqczwqYy4xJiYzmW+kluOHKxTLMWB/vWW0A9yD0Zfm+rnrXe57V4v4efskaZm+iAi45dpRa5GV5bre7UKdPegGcOd5A0hkFg3IGcE2O4KGtqZ1FkE1C0QhOGblHDJRFMBwxqiUopmHxYLPq5Y0gQuwZZRf0l0WYTrQpXs/8g1kSWoqOwvdX05NsO6kSmkkmgkigUV8KQQOVt76wHvtjC7P/HOVvO32JIjfvwiu2TGGmyHZ+i9Pzi1IKPDfqV/Dh/1HVeCRbVxGw6pOZKCf2AfKa61XAhjm/RJcnc6wlOKgJijDuC6Y5fq9MicHdiVca2WwM3JLURcR9CVtizw2aYawLSnrvY3aL8VSzLm6OcrUxUEitD+m9Uurzll/tbcgckDZqXc6y1K3pVfW8fS9GReAmKmmk+EvNKOV0cJkHnVVhpbWXMcNOPkm34gE3w== ================================================ FILE: llm-train/megatron/project.md ================================================ ## 项目结构 ``` . ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs # 文档 ├── examples # 训练样例 ├── images ├── megatron # Megatron 核心 ├── pretrain_bert.py ├── pretrain_gpt.py ├── pretrain_gpt_core.py ├── pretrain_ict.py ├── pretrain_retro.py ├── pretrain_t5.py ├── pretrain_vision_classify.py ├── pretrain_vision_dino.py ├── pretrain_vision_inpaint.py ├── setup.py ├── tasks # 任务示例 ├── tests # 单元测试 └── tools # 工具,合并权重、合并数据集等 ``` ### megatron ``` megatron ├── __init__.py ├── arguments.py ├── checkpointing.py ├── core # Megatron Core │   ├── README.md │   ├── __init__.py │   ├── enums.py │   ├── fusions │   │   ├── __init__.py │   │   ├── fused_bias_dropout.py │   │   ├── fused_bias_gelu.py │   │   ├── fused_layer_norm.py │   │   └── fused_softmax.py │   ├── model_parallel_config.py # Megatron Core 基础配置 │   ├── models │   │   ├── __init__.py │   │   ├── common │   │   │   └── rotary_pos_embedding.py │   │   └── gpt │   │   ├── __init__.py │   │   ├── gpt_embedding.py │   │   └── gpt_model.py │   ├── package_info.py │   ├── parallel_state.py │   ├── pipeline_parallel # 流水线并行核心模块 │   │   ├── __init__.py │   │   ├── p2p_communication.py │   │   └── schedules.py │   ├── requirements.txt │   ├── tensor_parallel # 张量并行核心模块 │   │   ├── __init__.py │   │   ├── cross_entropy.py │   │   ├── data.py │   │   ├── layers.py │   │   ├── mappings.py │   │   ├── random.py │   │   └── utils.py │   ├── transformer │   │   ├── __init__.py │   │   ├── attention.py │   │   ├── core_attention.py │   │   ├── custom_layers │   │   │   └── transformer_engine.py │   │   ├── enums.py │   │   ├── mlp.py │   │   ├── module.py │   │   ├── transformer_block.py │   │   ├── transformer_config.py │   │   ├── transformer_layer.py │   │   └── utils.py │   └── utils.py ├── data │   ├── Makefile │   ├── __init__.py │   ├── autoaugment.py │   ├── bert_dataset.py │   ├── biencoder_dataset_utils.py │   ├── blendable_dataset.py │   ├── data_samplers.py │   ├── dataset_utils.py │   ├── gpt_dataset.py │   ├── helpers.cpp │   ├── ict_dataset.py │   ├── image_folder.py │   ├── indexed_dataset.py │   ├── multimodal_dataset.py │   ├── orqa_wiki_dataset.py │   ├── realm_dataset_utils.py │   ├── realm_index.py │   ├── t5_dataset.py │   ├── test │   │   ├── test_indexed_dataset.py │   │   └── test_preprocess_data.sh │   └── vit_dataset.py ├── dist_signal_handler.py ├── fp16_deprecated │   └── loss_scaler.py ├── fused_kernels │   ├── __init__.py │   ├── compat.h │   ├── tests │   │   ├── __init__.py │   │   └── test_fused_kernels.py │   └── type_shim.h ├── global_vars.py ├── indexer.py ├── initialize.py ├── memory.py ├── microbatches.py ├── model │   ├── __init__.py │   ├── bert_model.py │   ├── biencoder_model.py │   ├── classification.py │   ├── distributed.py │   ├── enums.py │   ├── fused_bias_gelu.py │   ├── fused_layer_norm.py │   ├── fused_softmax.py │   ├── gpt_model.py │   ├── language_model.py │   ├── module.py │   ├── multiple_choice.py │   ├── realm_model.py │   ├── t5_model.py │   ├── transformer.py │   ├── utils.py │   └── vision │   ├── classification.py │   ├── dino.py │   ├── esvit_swin_backbone.py │   ├── inpainting.py │   ├── knn_monitor.py │   ├── mit_backbone.py │   ├── swin_backbone.py │   ├── utils.py │   └── vit_backbone.py ├── mpu │   └── tests │   ├── __init__.py │   ├── commons.py │   ├── test_cross_entropy.py │   ├── test_data.py │   ├── test_initialize.py │   ├── test_layers.py │   └── test_random.py ├── optimizer │   ├── __init__.py │   ├── clip_grads.py │   ├── distrib_optimizer.py │   ├── grad_scaler.py │   └── optimizer.py ├── optimizer_param_scheduler.py ├── static │   └── index.html ├── text_generation │   ├── __init__.py │   ├── api.py │   ├── beam_utils.py │   ├── communication.py │   ├── forward_step.py │   ├── generation.py │   ├── sampling.py │   └── tokenization.py ├── text_generation_server.py ├── timers.py ├── tokenizer │   ├── __init__.py │   ├── bert_tokenization.py │   ├── gpt2_tokenization.py │   └── tokenizer.py ├── training.py └── utils.py ``` ### tools ``` tools ├── bert_embedding │   ├── __init__.py │   ├── dataset.py │   ├── embed.py │   ├── external_libs.py │   ├── huggingface.py │   └── utils.py ├── checkpoint_loader_megatron.py ├── checkpoint_saver_megatron.py ├── checkpoint_util.py ├── linter.py ├── merge_datasets.py ├── openwebtext │   ├── README.md │   ├── add_id.py │   ├── blacklist_urls.py │   ├── cleanup_dataset.py │   ├── cleanup_fix_dataset.py │   ├── filter_ngrams.py │   ├── find_duplicates.py │   ├── group_duplicate_url.py │   ├── merge_jsons.py │   └── remove_group_duplicates.py ├── preprocess_data.py ├── preprocess_data_nmt.py ├── preprocess_mmdata.py ├── retro │   ├── README.md │   ├── cli │   │   ├── __init__.py │   │   ├── __main__.py │   │   └── cli.py │   ├── db │   │   ├── __init__.py │   │   ├── build.py │   │   ├── dataset.py │   │   └── utils.py │   ├── examples │   │   ├── preprocess_data.sh │   │   └── pretrain_model.sh │   ├── external_libs.py │   ├── index │   │   ├── __init__.py │   │   ├── build.py │   │   ├── factory.py │   │   ├── index.py │   │   ├── indexes │   │   │   ├── __init__.py │   │   │   ├── faiss_base.py │   │   │   └── faiss_par_add.py │   │   └── utils.py │   ├── main.py │   ├── query │   │   ├── __init__.py │   │   ├── chunk_dataset.py │   │   ├── query.py │   │   ├── retro_dataset.py │   │   └── utils.py │   └── utils.py ├── run_text_generation_server.py └── text_generation_cli.py ``` ### tasks ``` tasks ├── data_utils.py ├── ensemble_classifier.py ├── eval_utils.py ├── finetune_utils.py ├── glue │   ├── data.py │   ├── finetune.py │   ├── mnli.py │   └── qqp.py ├── main.py ├── msdp │   ├── README.md │   ├── evaluate.py │   ├── main.py │   ├── metrics.py │   ├── preprocessing.py │   └── prompt.py ├── orqa │   ├── README.md │   ├── evaluate_orqa.py │   ├── evaluate_utils.py │   ├── supervised │   │   ├── data.py │   │   ├── eval_utils.py │   │   └── finetune.py │   └── unsupervised │   ├── nq.py │   ├── qa_utils.py │   └── tokenizers.py ├── race │   ├── data.py │   └── finetune.py ├── vision │   ├── classification │   │   ├── classification.py │   │   └── eval_utils.py │   ├── finetune_utils.py │   ├── main.py │   └── segmentation │   ├── cityscapes.py │   ├── data.py │   ├── finetune_segformer.py │   ├── finetune_setr.py │   ├── metrics.py │   ├── seg_heads.py │   ├── seg_models.py │   ├── transforms.py │   └── utils.py └── zeroshot_gpt ├── datasets.py ├── detokenizer.py └── evaluate.py ``` ### examples ``` examples ├── detxoify_lm │   ├── README.md │   ├── annotations │   │   ├── filter-selfgeneration.py │   │   ├── perspective_api_annotate.py │   │   └── preprocess.sh │   ├── finetune_gpt.py │   ├── finetune_gpt_distributed-1.3b.sh │   ├── generate-1.3b.sh │   ├── generate_samples_gpt.py │   ├── perspective_api.py │   └── self_generation │   └── selfgenerate-1.3b-unconditional.sh ├── evaluate_retriever_nq.sh ├── evaluate_zeroshot_gpt.sh ├── finetune_mnli_distributed.sh ├── finetune_race_distributed.sh ├── finetune_retriever_distributed.sh ├── merge_mp_bert.sh ├── msdp │   ├── README.md │   ├── data_processing.sh │   ├── eval_knwl_generation.sh │   ├── eval_resp_generation.sh │   ├── prep_resp_gen.sh │   ├── prompt_knwl_gen.sh │   └── prompt_resp_gen.sh ├── pretrain_bert.sh ├── pretrain_bert_distributed.sh ├── pretrain_bert_distributed_with_mp.sh ├── pretrain_gpt.sh ├── pretrain_gpt3_175B.sh ├── pretrain_gpt_distributed.sh ├── pretrain_gpt_distributed_with_mp.sh ├── pretrain_ict.sh ├── pretrain_t5.sh ├── pretrain_t5_distributed.sh ├── pretrain_t5_distributed_with_mp.sh ├── run_text_generation_server_345M.sh ├── run_text_generation_server_345M_8_tensor_parallel.sh └── sc21 ├── CONFIG.sh ├── README.md ├── SBATCH.sh ├── SRUN.sh ├── run_figure_11.sh ├── run_figure_12.sh ├── run_figure_13.sh ├── run_figure_14.sh ├── run_figure_15.sh ├── run_figure_16.sh ├── run_figure_17.sh ├── run_figure_18.sh └── run_table_1.sh ``` ### tests-单元测试 ``` tests ├── __init__.py ├── functional_tests │   ├── __init__.py │   ├── python_test_utils │   │   ├── __init__.py │   │   ├── check_slurm_job_completion.py │   │   ├── get_test_results_from_tensorboard_logs.py │   │   ├── test_ci_pipeline.py │   │   └── test_resume_checkpoint_pipeline.py │   ├── shell_test_utils │   │   └── jobwait.sh │   ├── test_results │   │   ├── bert │   │   │   ├── bert_tp1_pp2_1nodes_50steps.json │   │   │   ├── bert_tp1_pp4_1nodes_50steps.json │   │   │   ├── bert_tp2_pp2_1nodes_50steps.json │   │   │   └── bert_tp4_pp1_1nodes_50steps.json │   │   └── gpt3 │   │   ├── gpt3_tp1_pp2_1nodes_50steps.json │   │   ├── gpt3_tp1_pp4_1nodes_50steps.json │   │   ├── gpt3_tp2_pp2_1nodes_50steps.json │   │   └── gpt3_tp4_pp1_1nodes_50steps.json │   └── test_scripts │   ├── bert │   │   ├── pretrain_bert_distributed_resume_checkpoint_test.sh │   │   ├── pretrain_bert_distributed_test.sh │   │   ├── sbatch_bert_distributed_resume_checkpoint_test.sh │   │   └── sbatch_bert_distributed_test.sh │   └── gpt3 │   ├── pretrain_gpt3_distributed_resume_checkpoint_test.sh │   ├── pretrain_gpt3_distributed_test.sh │   ├── sbatch_gpt3_distributed_resume_checkpoint_test.sh │   └── sbatch_gpt3_distributed_test.sh ├── models │   ├── __init__.py │   ├── test_gpt_embedding.py │   └── test_gpt_model.py ├── pipeline_parallel │   ├── __init__.py │   └── test_schedules.py ├── tensor_parallel │   └── __int__.py ├── transformer │   ├── __init__.py │   ├── test_core_attention.py │   ├── test_module.py │   ├── test_parallel_attention.py │   ├── test_parallel_mlp.py │   ├── test_parallel_transformer_block.py │   ├── test_parallel_transformer_layer.py │   └── test_transformer_config.py └── unit_tests ├── __init__.py ├── conftest.py ├── tensor_parallel │   ├── test_cross_entropy.py │   ├── test_data.py │   ├── test_mappings.py │   ├── test_random.py │   └── test_tensor_parallel_utils.py ├── test_basic.py ├── test_parallel_state.py ├── test_utilities.py └── test_utils.py ``` ================================================ FILE: llm-train/megatron/source-code.md ================================================ ## pretrain_gpt ### train_valid_test_datasets_provider ### model_provider ### data_post_process --- ## megatron.training ### pretrain ``` 构建数据集 from megatron.data.gpt_dataset import build_train_valid_test_datasets 预训练函数 from megatron.training import pretrain Main training program. This function will run the followings in the order provided: 1) initialize Megatron. 2) setup model, optimizer and lr schedule using the model_provider. 3) call train_val_test_data_provider to get train/val/test datasets. 4) train the modle using the forward_step_func. ``` 初始化 Megatron 1. 定义模型的切割框架 2. 在此框架上,初始化进程,分配GPU,设置进程组(DP/TP/PP) --- ### setup_model_and_optimizer Model, optimizer, and learning rate. 设置模型及优化器 ### build_train_valid_test_data_iterators 构建预训练数据迭代器 ### train 训练 ### get_model: 构建模型 --- ## megatron.initialize ### initialize_megatron ### _initialize_distributed 1. 设置分布式环境:初始化进程,分配GPU,并设置进程大组(group) 2. 制定DP/TP/PP分组策略,设置进程子组(subgroup) 3. 设置DeepSpeed ZeRO-R,对activation进行优化 - 初始化进程组:torch.distributed.init_process_group - 设置张量模型并行、流水线模型并行和数据并行通信器:mpu.initialize_model_parallel ## megatron.core.parallel_state ### initialize_model_parallel:初始化模型数据并行组 假设我们总共有 16 个 GPU,用 g0 ... g15 表示,我们使用 2 个 GPU 来张量并行,使用 4 个 GPU 来流水线并行。 当前函数将创建 8 个张量模型并行组、4 个流水线模型并行组和 8 个数据并行组,如下所示: - 8 个数据并行组:[g0, g2], [g1, g3], [g4, g6], [g5, g7], [g8, g10], [g9, g11], [g12, g14], [g13, g15] - 8 个张量模型并行组:[g0,g1],[g2,g3],[g4,g5],[g6,g7],[g8,g9],[g10,g11],[g12,g13],[g14,g15] - 4 个管道模型并行组:[g0、g4、g8、g12]、[g1、g5、g9、g13]、[g2、g6、g10、g14]、[g3、g7、g11、g15] --- ## megatron.model.gpt_model ### GPTModel ## megatron.model.module ### MegatronModule Megatron 针对 torch.nn.Module 的特定扩展以支持流水线。 ### Float16Module ## megatron.model.transformer ### ParallelTransformer ### ParallelTransformerLayer 一个 transformer 层 Transformer 层接受大小为 [s, b, h] 的输入并返回相同大小的输出。 ### ParallelAttention 并行自注意力层抽象类。 ### ParallelMLP 并行 MLP 层。 ## megatron.model.language_model ### TransformerLanguageModel Transformer 语言模型 ### Embedding 语言模型 Embedding ## megatron.core.tensor_parallel.cross_entropy ### _VocabParallelCrossEntropy 计算交叉熵。 ## megatron.core.tensor_parallel.layers ### VocabParallelEmbedding ### ColumnParallelLinear 列并行线性层 ### RowParallelLinear 行并行线性层 ### _initialize_affine_weight_gpu 初始化 GPU 上模型并行的仿射权重。 ## megatron.core.tensor_parallel.mappings ### copy_to_tensor_model_parallel_region ### _CopyToModelParallelRegion 将输入传递到模型并行区域。 ### gather_from_tensor_model_parallel_region ### _GatherFromModelParallelRegion 从模型并行区域收集输入拼接在一起。 ### _ScatterToModelParallelRegion 分割输入并仅将相应的chuck保留到rank中 ### _ReduceFromModelParallelRegion All-reduce来自模型并行区域的输入 ## megatron.core.model_parallel_config ### ModelParallelConfig Megatron Core 基础配置 --- ## megatron.training ### build_train_valid_test_datasets(build_train_valid_test_datasets_provider) 构建预训练数据集 ## megatron.data.data_samplers ### build_pretraining_data_loader(dataset, consumed_samples) 给定一个数据集构建数据加载器 ================================================ FILE: llm-train/megatron-deepspeed/README.md ================================================ ## 微软 - [Megatron-DeepSpeed](https://github.com/microsoft/Megatron-DeepSpeed) - 目前,已支持llama/llama2 模型转换: - https://github.com/microsoft/Megatron-DeepSpeed/tree/main/tools/convert_checkpoint - https://github.com/huggingface/transformers/tree/main/src/transformers/models/megatron_gpt2 ## bigscience - [Megatron-DeepSpeed](https://github.com/bigscience-workshop/Megatron-DeepSpeed) - 训练过程:https://github.com/bigscience-workshop/bigscience - https://huggingface.co/blog/zh/bloom-megatron-deepspeed - 支持bloom - 未支持序列并行 ================================================ FILE: llm-train/megatron-deepspeed/bigscience/bloom-note.md ================================================ ================================================ FILE: llm-train/megatron-deepspeed/bloom-megatron-deepspeed.md ================================================ 参考: - https://huggingface.co/blog/zh/bloom-megatron-deepspeed - https://github.com/huggingface/blog/blob/main/zh/bloom-megatron-deepspeed.md 训练硬件: - GPU: 384 张 NVIDIA A100 80GB GPU (48 个节点) + 32 张备用 GPU - 每个节点 8 张 GPU,4 条 NVLink 卡间互联,4 条 OmniPath(高速互连网络技术)链路 - CPU: AMD EPYC 7543 32 核处理器 - CPU 内存: 每个节点 512GB - GPU 显存: 每个节点 640GB - 节点间连接: 使用 Omni-Path Architecture (OPA) 网卡,网络拓扑为无阻塞胖树 - NCCL - 通信网络: 一个完全专用的子网 - 磁盘 IO 网络: GPFS 与其他节点和用户共享 数据集: - 41.5TB 经过大量去重和清洗的文本,包含 46 种语言,最终转换为 350B 个词元 - 模型的词汇表含 250,680 个词元 DeepSpeed 团队通过将 DeepSpeed 库中的 ZeRO 分片和流水线并行 (Pipeline Parallelism) 与 Megatron-LM 中的张量并行 (Tensor Parallelism) 相结合,开发了一种基于 3D 并行的方案。 下表列出了我们在训练 BLOOM 时各采用了两个框架的哪些组件 | 组件 | DeepSpeed | Megatron-LM | | :---- | :---- | :---- | | [ZeRO 数据并行](#zero-data-parallelism) | 是 | | | [张量并行](#tensor-parallelism) | | 是 | | [流水线并行](#pipeline-parallelism) | 是 | | | [BF16 优化器](#bf16optimizer) | 是 | | | [CUDA 融合核函数](#fused-cuda-kernels) | | 是 | | [DataLoader](#datasets) | | 是 | 请注意,Megatron-LM 和 DeepSpeed 都有流水线并行和 BF16 优化器实现,但我们使用 DeepSpeed 的实现,因为它们集成进了 ZeRO。 Megatron-DeepSpeed 实现了 3D 并行以允许大模型以非常有效的方式进行训练。我们简要讨论一下有哪些 3D 组件。 1. 数据并行 (Data Parallelism,DP) - 相同的设置和模型被复制多份,每份每次都被馈送不同的一份数据。处理是并行完成的,所有份在每个训练步结束时同步。 2. 张量并行 (Tensor Parallelism,TP) - 每个张量都被分成多个块,因此张量的每个分片都位于其指定的 GPU 上,而不是让整个张量驻留在单个 GPU 上。在处理过程中,每个分片在不同的 GPU 上分别并行处理,结果在步骤结束时同步。这就是所谓的水平并行,因为是做的水平拆分。 3. 流水线并行 (Pipeline Parallelism,PP) - 模型在多个 GPU 上垂直 (即按层) 拆分,因此只有一个或多个模型层放置在单个 GPU 上。每个 GPU 并行处理流水线的不同阶段,并处理 batch 的一部分数据。 4. 零冗余优化器 (Zero Redundancy Optimizer,ZeRO) - 也执行与 TP 相类似的张量分片,但整个张量会及时重建以进行前向或反向计算,因此不需要修改模型。它还支持各种卸载技术以补偿有限的 GPU 内存。 需要特别考虑的是: 由于前向和后向传播中每层都有两个 all reduce,因此 TP 需要设备间有非常快速的互联。因此,除非你有一个非常快的网络,否则不建议跨多个节点进行 TP。我们训练 BLOOM 的硬件配置中,节点间的速度比 PCIe 慢很多。实际上,如果节点有 4 个 GPU,则最高 TP 度设为 4 比较好。如果需要 TP 度为 8,则需要使用至少有 8 个 GPU 的节点。 虽然 Megatron-LM 和 DeepSpeed 都有自己的 PP 协议实现,但 Megatron-DeepSpeed 使用的是 DeepSpeed 实现,因为它与 DeepSpeed 的其他功能集成在一起。 词嵌入矩阵的大小 虽然通常词嵌入矩阵比 transfomer 块所需的内存更少,但在 BLOOM 有 250k 词汇表的情况下,嵌入层需要 7.2GB 的 bf16 权重,而 transfomer 块仅为 4.9GB。 因此,我们不得不让 Megatron-Deepspeed 将嵌入层视为一个 transfomer 块。所以我们有一个 **72 级的流水线**,其中 2 个是专门用于嵌入的 (第一个和最后一个)。 这使得我们可以平衡 GPU 的内存消耗。如果我们不这样做,我们就会让第一级和最后一级消耗很大的 GPU 内存,而 95% 的 GPU 内存使用会很少,因此训练将很不高效。 ## DP+PP 了解 DP rank 0 是看不见 GPU2 的, DP rank 1 是看不到 GPU3 的。对于 DP 而言,只有 GPU 0 和 1,并向它们馈送数据。GPU0 使用 PP “秘密地” 将它的一些负载卸载到 GPU2。同样地, GPU1 也会得到 GPU3 的帮助。 由于每个维度至少需要 2 个 GPU,因此这儿至少需要 4 个 GPU。 ## DP+PP+TP 为了更高效地训练,可以将 PP、TP 和 DP 相结合,称为 3D 并行。 由于每个维度至少需要 2 个 GPU,因此在这里你至少需要 8 个 GPU 才能实现完整的 3D 并行。 ## ZeRO DP+PP+TP DeepSpeed 的主要功能之一是 ZeRO,它是 DP 的超级可伸缩增强版,我们在 ZeRO 数据并行 一节中已经讨论过了。通常它是一个独立的功能,不需要 PP 或 TP。但它也可以与 PP、TP 结合使用。 当 ZeRO-DP 与 PP (以及 TP) 结合时,它通常只启用 ZeRO 阶段 1,它只对优化器状态进行分片。ZeRO 阶段 2 还会对梯度进行分片,阶段 3 也对模型权重进行分片。 虽然理论上可以将 ZeRO 阶段 2 与 流水线并行 一起使用,但它会对性能产生不良影响。每个 micro batch 都需要一个额外的 reduce-scatter 通信来在分片之前聚合梯度,这会增加潜在的显著通信开销。根据流水线并行的性质,我们会使用小的 micro batch ,并把重点放在算术强度 (micro batch size) 与最小化流水线气泡 (micro batch 的数量) 两者间折衷。因此,增加的通信开销会损害流水线并行。 此外,由于 PP,层数已经比正常情况下少,因此并不会节省很多内存。PP 已经将梯度大小减少了 1/PP,因此在此基础之上的梯度分片和纯 DP 相比节省不了多少内存。 ZeRO 阶段 3 也可用于训练这种规模的模型,但是,它需要的通信量比 DeepSpeed 3D 并行更多。一年前,在对我们的环境进行仔细评估后,我们发现 Megatron-DeepSpeed 3D 并行性表现最佳。此后,ZeRO 阶段 3 的性能有了显著提高,如果我们今天要对其进行重新评估,也许我们会选择阶段 3。 ## BF16Optimizer 用 FP16 训练巨型 LLM 模型是一个禁忌。 我们已经通过花费几个月的时间 训练 104B 模型 自证了这一点,你可以从 Tensorboard 发现,彻头彻尾地失败了。在与不断发散的 lm-loss 作斗争的过程中,我们学到了很多: ![104B-fail](https://huggingface.co/blog/assets/86_bloom_megatron_deepspeed/104b-lm-loss.png) 我们也从 Megatron-LM 和 DeepSpeed 团队那里得到了相同的建议,在他们训得 530B 模型 后。最近发布的 OPT-175B 也报告说他们在 FP16 上训练得非常艰难。 所以早在一月份,我们就知道我们要在支持 BF16 格式的 A100 上进行训练。Olatunji Ruwase 开发了一个用来训练 BLOOM 的 BF16Optimizer。 如果您不熟悉这种数据格式,请查看它的 位布局。BF16 格式的关键是它的指数位数与 FP32 相同,因此不会溢出,但 FP16 经常溢出!FP16 的最大数值范围为 64k,您只能进行较小数的乘法。例如你可以做 250*250=62500,但如果你尝试 255*255=65025,你就会溢出,这是导致训练出现问题的主要原因。这意味着你的权重必须保持很小。一种称为损失缩放 (loss scaling) 的技术有助于缓解这个问题,但是当模型变得非常大时,FP16 较小的数值范围仍然是一个问题。 BF16 没有这个问题,你可以很容易地做 10_000*10_000=100_000_000, 完全没问题。 当然,由于 BF16 和 FP16 的大小相同,均为 2 个字节,因此,没有免费的午餐,当使用 BF16 时,代价就是它的精度非常差。然而,你应该还记得我们在训练时采用的随机梯度下降法及其变体,该方法有点像蹒跚而行,如果你这步没有找到完美的方向其实没关系,你会在接下来的步骤中纠正自己。 无论使用 BF16 还是 FP16,都有一个权重副本始终在 FP32 中 —— 这是由优化器更新的内容。因此 16 位格式仅用于计算,优化器以全精度更新 FP32 权重,然后将它们转换为 16 位格式以用于下一次迭代。 所有 PyTorch 组件都已更新,以确保它们在 FP32 中执行任何累加,因此不会发生精度损失。 一个关键问题是梯度累积,它是流水线并行的主要特征之一,因为每个 micro batch 处理的梯度都会累积。在 FP32 中实现梯度累积以保证训练的精确性至关重要,这正是 BF16Optimizer 所做的。 除了其他改进之外,我们认为使用 BF16 混合精度训练将潜在的噩梦变成了一个相对平稳的过程,这可以从以下 lm 损失图中看出: ![176B - 损失](https://huggingface.co/blog/assets/86_bloom_megatron_deepspeed/176b-lm-loss.png) ## CUDA 融合核函数 为了快速高效地训练 BLOOM,有必要使用 Megatron-LM 提供的几个自定义 CUDA 融合核函数。特别地,有一个 LayerNorm 的融合核函数以及用于融合缩放、掩码和 softmax 这些操作的各种组合的核函数。Bias Add 也通过 PyTorch 的 JIT 功能与 GeLU 融合。这些操作都是瓶颈在内存的,因此将它们融合在一起以达到最大化每次显存读取后的计算量非常重要。因此,例如,在执行瓶颈在内存的 GeLU 操作时同时执行 Bias Add,运行时间并不会增加。这些核函数都可以在 [Megatron-LM repository](https://github.com/NVIDIA/Megatron-LM) 代码库 中找到。 ## 数据集 Megatron-LM 的另一个重要特性是高效的数据加载器。在首次训练启动前,每个数据集中的每个样本都被分成固定序列长度 (BLOOM 为 2048) 的样本,并创建索引以对每个样本进行编号。基于训练超参,我们会确定每个数据集所需要参与的 epoch 数,并基于此创建一个有序的样本索引列表,然后打乱它。举个例子,如果一个数据集中有 10 个样本并应参与 2 个 epoch 的训练,则系统首先按 [0, ..., 9, 0, ..., 9] 顺序排好样本索引,然后打乱该顺序为数据集创建最终的全局顺序。请注意,这意味着训练不会简单地遍历整个数据集然后重复,你有可能在看到另一个样本之前看到同一个样本两次,但在训练结束时模型将只看到每个样本两次。这有助于确保整个训练过程中的训练曲线平滑。这些索引,包括每个样本在原始数据集中的偏移量,被保存到一个文件中,以避免每次开始训练时都重新计算它们。最后,可以将其中几个数据集以不同的权重混合到训练最终使用的数据中。 ## 嵌入 LayerNorm 在我们努力阻止 104B 模型发散的过程中,我们发现在第一个层词嵌入层之后添加一个额外的 LayerNorm 可以使训练更加稳定。 该洞察来自对 bitsandbytes 的实验,[bitsandbytes](https://github.com/facebookresearch/bitsandbytes) 有一个 `StableEmbedding` 操作,它是一个带有 LayerNorm 的普通嵌入,其使用均匀 xavier 函数来初始化。 ## 位置编码 基于论文 [Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation](https://arxiv.org/abs/2108.12409),我们还用 AliBi 替换了普通的位置嵌入,它允许外推比训练模型的输入序列更长的输入序列。因此,即使我们训练时使用长度为 2048 的序列,模型也可以在推理过程中处理更长的序列。 ## 训练中的困难 在训练开始之前,有很多问题需要弄清楚。特别是,我们发现了几个问题,这些问题只有在我们开始在 48 个节点上进行训练后才会出现,而不会在小规模时出现。例如,需要设 CUDA_LAUNCH_BLOCKING=1 来防止框架挂起,我们需要将优化器组分成更小的组,否则框架会再次挂起。 训练期间遇到的主要问题类型是硬件故障。由于这是一个拥有大约 400 个 GPU 的新集群,平均每周我们会遇到 1-2 个 GPU 故障。我们每 3 小时 (100 次迭代) 保存一个检查点。因此,我们每周因硬件崩溃平均损失 1.5 小时的训练成果。Jean Zay 系统管理员随后将更换有故障的 GPU 并恢复节点。与此同时,我们有备用节点可供使用。 我们还遇到过多次导致 5-10 小时停机的各种其他问题,其中一些与 PyTorch 中的死锁错误有关,另一些则是由于磁盘空间不足。 另一个问题是 SLURM 并非设计为供一组人使用。SLURM 作业由单个用户拥有,如果他们不在身边,则该组的其他成员无法对正在运行的作业执行任何操作。我们制定了一个终止方案,允许组中的其他用户终止当前进程,而不需要启动该进程的用户在场。这在 90% 的问题上都很有效。如果 SLURM 设计者读到这篇文章,请添加一个 Unix 组的概念,这样一个 SLURM 作业就可以由一个组拥有。 ================================================ FILE: llm-train/megatron-deepspeed/microsoft/H800多机多卡训练坑点.md ================================================ CUDA 11.8 及以上 多机多卡:torchrun - https://pytorch.org/docs/stable/elastic/run.html For multi-node training you need to specify: --rdzv-id: A unique job id (shared by all nodes participating in the job) --rdzv-backend: An implementation of torch.distributed.elastic.rendezvous.RendezvousHandler --rdzv-endpoint: The endpoint where the rendezvous backend is running; usually in form host:port. 心跳检测失败 - The node 'xxx' has failed to send a keep-alive heartbeat to the rendezvous 'xxx' due to an error of type RendezvousConnectionError. - https://github.com/pytorch/pytorch/issues/76287 ================================================ FILE: llm-train/megatron-deepspeed/microsoft/README.md ================================================ ## 测试环境 DeepSpeed v0.9.5 ## 验证案例及结果 验证了 GPT-3 预训练的以下情况(同步之前/之后匹配训练/校验曲线、检查点保存/加载工作): - 使用 DeepSpeed ZeRO stage 1 - 使用 DeepSpeed ZeRO stage 1 和 Megatron-LM 的张量并行 - 使用 DeepSpeed ZeRO stage 1、Megatron-LM 的张量并行和 DeepSpeed 的流水线并行(即 3D 并行性) 此外,下面是同步前后的性能/收敛性比较。 ## Flash attention - https://github.com/Dao-AILab/flash-attention ## Rotary Positional Embedding (RoPE) ## 模型转换 ``` PYTHONPATH=/workspace/code/Megatron-DeepSpeed-llama-20230815 \ python tools/convert_checkpoint/deepspeed_to_megatron.py --target_tp 1 --target_pp 1 \ --input_folder /workspace/code/Megatron-DeepSpeed-llama-20230815/tmp/global_step2500 \ --output_folder /workspace/output/llama-7b-megatron-pretrain > tree -h workspace/output/llama-7b-megatron-pretrain workspace/output/llama-7b-megatron-pretrain ├── [ 32] iter_0002500 │   └── [ 40] mp_rank_00 │   └── [ 12G] model_optim_rng.pt └── [ 4] latest_checkpointed_iteration.txt cd /hf/transformers PYTHONPATH=/workspace/code/Megatron-DeepSpeed-llama-20230815 \ python src/transformers/models/megatron_gpt2/convert_megatron_gpt2_checkpoint.py \ /workspace/output/llama-7b-megatron-pretrain/iter_0002500/mp_rank_00/model_optim_rng.pt ``` ## LLaMA-7B ``` +-----------------------------------------------------------------------------+ | NVIDIA-SMI 525.125.06 Driver Version: 525.125.06 CUDA Version: 12.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 NVIDIA A800 80G... On | 00000000:34:00.0 Off | 0 | | N/A 64C P0 89W / 300W | 80407MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 1 NVIDIA A800 80G... On | 00000000:35:00.0 Off | 0 | | N/A 66C P0 93W / 300W | 73999MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 2 NVIDIA A800 80G... On | 00000000:36:00.0 Off | 0 | | N/A 66C P0 91W / 300W | 74149MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 3 NVIDIA A800 80G... On | 00000000:37:00.0 Off | 0 | | N/A 68C P0 98W / 300W | 73987MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 4 NVIDIA A800 80G... On | 00000000:9B:00.0 Off | 0 | | N/A 71C P0 299W / 300W | 59741MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 5 NVIDIA A800 80G... On | 00000000:9C:00.0 Off | 0 | | N/A 71C P0 289W / 300W | 59787MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 6 NVIDIA A800 80G... On | 00000000:9D:00.0 Off | 0 | | N/A 69C P0 262W / 300W | 59829MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 7 NVIDIA A800 80G... On | 00000000:9E:00.0 Off | 0 | | N/A 69C P0 308W / 300W | 59743MiB / 81920MiB | 100% Default | | | | Enabled* | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 5260 C /usr/bin/python 80404MiB | | 1 N/A N/A 5261 C /usr/bin/python 73996MiB | | 2 N/A N/A 5262 C /usr/bin/python 74146MiB | | 3 N/A N/A 5265 C /usr/bin/python 73984MiB | | 4 N/A N/A 5266 C /usr/bin/python 59738MiB | | 5 N/A N/A 5267 C /usr/bin/python 59784MiB | | 6 N/A N/A 5268 C /usr/bin/python 59826MiB | | 7 N/A N/A 5269 C /usr/bin/python 59740MiB | +-----------------------------------------------------------------------------+ ``` ## LLaMA-13B ``` +-----------------------------------------------------------------------------+ | NVIDIA-SMI 525.125.06 Driver Version: 525.125.06 CUDA Version: 12.1 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 NVIDIA A800 80G... On | 00000000:34:00.0 Off | 0 | | N/A 62C P0 89W / 300W | 71639MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 1 NVIDIA A800 80G... On | 00000000:35:00.0 Off | 0 | | N/A 65C P0 92W / 300W | 77801MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 2 NVIDIA A800 80G... On | 00000000:36:00.0 Off | 0 | | N/A 65C P0 90W / 300W | 77847MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 3 NVIDIA A800 80G... On | 00000000:37:00.0 Off | 0 | | N/A 69C P0 209W / 300W | 77761MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 4 NVIDIA A800 80G... On | 00000000:9B:00.0 Off | 0 | | N/A 70C P0 236W / 300W | 58423MiB / 81920MiB | 99% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 5 NVIDIA A800 80G... On | 00000000:9C:00.0 Off | 0 | | N/A 71C P0 156W / 300W | 63465MiB / 81920MiB | 99% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 6 NVIDIA A800 80G... On | 00000000:9D:00.0 Off | 0 | | N/A 66C P0 228W / 300W | 57581MiB / 81920MiB | 100% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ | 7 NVIDIA A800 80G... On | 00000000:9E:00.0 Off | 0 | | N/A 66C P0 174W / 300W | 57079MiB / 81920MiB | 99% Default | | | | Disabled | +-------------------------------+----------------------+----------------------+ ``` ================================================ FILE: llm-train/megatron-deepspeed/microsoft/llama-note.md ================================================ ``` docker run -dt --name nvidia_pytorch_env --restart=always --gpus all \ --network=host \ --shm-size 4G \ -v /home/guodong.li/workspace:/workspace \ -w /workspace \ nvcr.io/nvidia/pytorch:23.04-py3 \ /bin/bash docker exec -it nvidia_pytorch_env bash ``` ``` pip install sentencepiece pip install transformers pip install deepspeed==0.9.5 pip install einops==0.6.1 pip uninstall -y flash-attn && pip install flash-attn --no-build-isolation ```
训练日志详细输出

``` > bash examples_deepspeed/pretrain_llama_distributed.sh + BASE_PATH=./tmp + DS_CONFIG=./tmp/deepspeed.json + DATASET_1=/workspace/data/gpt2-data/my-gpt2_text_document + DATASET_2=/workspace/data/gpt2-data/my-gpt2-1_text_document + DATASET='1 /workspace/data/gpt2-data/my-gpt2_text_document 2 /workspace/data/gpt2-data/my-gpt2-1_text_document' + CHECKPOINT_PATH=./tmp + TOKENIZER_PATH=/workspace/model/llama-tokenizer/tokenizer.model + TP=2 + PP=2 + ZERO_STAGE=0 + GPUS_PER_NODE=8 + MASTER_ADDR=localhost + MASTER_PORT=6000 + NNODES=1 + NODE_RANK=0 + HIDDEN_SIZE=2048 + FFN_HIDDEN_SIZE=5504 + NUM_LAYERS=24 + NUM_HEADS=16 + SEQ_LENGTH=2048 + MICRO_BATCH_SIZE=4 + GLOBAL_BATCH_SIZE=32 + TRAIN_STEPS=2500 + LR=3e-4 + MIN_LR=3e-5 + LR_WARMUP_STEPS=2000 + WEIGHT_DECAY=0.1 + GRAD_CLIP=1 + cat + ds_args= + ds_args=' --deepspeed ' + ds_args=' --deepspeed_config=./tmp/deepspeed.json --deepspeed ' + ds_args=' --zero-stage=0 --deepspeed_config=./tmp/deepspeed.json --deepspeed ' + ds_args=' --deepspeed-activation-checkpointing --zero-stage=0 --deepspeed_config=./tmp/deepspeed.json --deepspeed ' + DISTRIBUTED_ARGS='--nproc_per_node 8 --nnodes 1 --node_rank 0 --master_addr localhost --master_port 6000' + torchrun --nproc_per_node 8 --nnodes 1 --node_rank 0 --master_addr localhost --master_port 6000 pretrain_gpt.py --tensor-model-parallel-size 2 --pipeline-model-parallel-size 2 --num-layers 24 --hidden-size 2048 --ffn-hidden-size 5504 --num-attention-heads 16 --micro-batch-size 4 --global-batch-size 32 --seq-length 2048 --max-position-embeddings 2048 --train-iters 2500 --save ./tmp --load ./tmp --data-path 1 /workspace/data/gpt2-data/my-gpt2_text_document 2 /workspace/data/gpt2-data/my-gpt2-1_text_document --data-impl mmap --tokenizer-type GPTSentencePieceTokenizer --tokenizer-model /workspace/model/llama-tokenizer/tokenizer.model --split 900,50,50 --distributed-backend nccl --lr 3e-4 --lr-decay-style cosine --min-lr 3e-5 --weight-decay 0.1 --clip-grad 1 --lr-warmup-iters 2000 --optimizer adam --adam-beta1 0.9 --adam-beta2 0.95 --log-interval 1 --save-interval 10000 --eval-interval 1000 --eval-iters 10 --fp16 --no-query-key-layer-scaling --attention-dropout 0 --hidden-dropout 0 --use-rotary-position-embeddings --untie-embeddings-and-output-weights --swiglu --normalization rmsnorm --disable-bias-linear --deepspeed-activation-checkpointing --zero-stage=0 --deepspeed_config=./tmp/deepspeed.json --deepspeed ... -------------------------------------------------- DeepSpeed C++/CUDA extension op report -------------------------------------------------- ... async_io ............... [NO] ....... [NO] cpu_adagrad ............ [NO] ....... [OKAY] cpu_adam ............... [NO] ....... [OKAY] fused_adam ............. [NO] ....... [OKAY] fused_lamb ............. [NO] ....... [OKAY] quantizer .............. [NO] ....... [OKAY] random_ltd ............. [NO] ....... [OKAY] ... -------------------------------------------------- DeepSpeed general environment info: torch install path ............... ['/usr/local/lib/python3.8/dist-packages/torch'] torch version .................... 2.1.0a0+fe05266 deepspeed install path ........... ['/usr/local/lib/python3.8/dist-packages/deepspeed'] deepspeed info ................... 0.9.5, unknown, unknown torch cuda version ............... 12.1 torch hip version ................ None nvcc version ..................... 12.1 deepspeed wheel compiled w. ...... torch 2.1, cuda 12.1 using world size: 8, data-parallel-size: 2, tensor-model-parallel size: 2, pipeline-model-parallel size: 2 using torch.float16 for parameters ... ------------------------ arguments ------------------------ accumulate_allreduce_grads_in_fp32 .............. False adam_beta1 ...................................... 0.9 adam_beta2 ...................................... 0.95 adam_eps ........................................ 1e-08 add_bias_linear ................................. False add_position_embedding .......................... False adlr_autoresume ................................. False adlr_autoresume_interval ........................ 1000 aml_data_download_path .......................... None apply_layernorm_1p .............................. False apply_query_key_layer_scaling ................... False apply_residual_connection_post_layernorm ........ False async_tensor_model_parallel_allreduce ........... False attention_dropout ............................... 0.0 attention_softmax_in_fp32 ....................... False barrier_with_L1_time ............................ True bert_binary_head ................................ True bert_embedder_type .............................. megatron bert_load ....................................... None bf16 ............................................ False bias_dropout_fusion ............................. True bias_gelu_fusion ................................ False biencoder_projection_dim ........................ 0 biencoder_shared_query_context_model ............ False block_data_path ................................. None checkpoint_activations .......................... False checkpoint_in_cpu ............................... False checkpoint_num_layers ........................... 1 classes_fraction ................................ 1.0 clip_grad ....................................... 1.0 compression_training ............................ False consumed_train_samples .......................... 0 consumed_train_tokens ........................... 0 consumed_valid_samples .......................... 0 contigious_checkpointing ........................ False cpu_optimizer ................................... False cpu_torch_adam .................................. False create_moe_param_group .......................... False curriculum_learning_legacy ...................... False data_cache_path ................................. None data_efficiency_curriculum_learning ............. False data_impl ....................................... mmap data_parallel_random_init ....................... False data_parallel_size .............................. 2 data_path ....................................... ['1', '/workspace/data/gpt2-data/my-gpt2_text_document', '2', '/workspace/data/gpt2-data/my-gpt2-1_text_document'] data_per_class_fraction ......................... 1.0 data_sharding ................................... True dataloader_type ................................. single DDP_impl ........................................ local decoder_num_layers .............................. None decoder_seq_length .............................. None deepscale ....................................... False deepscale_config ................................ None deepspeed ....................................... True deepspeed_activation_checkpointing .............. True deepspeed_config ................................ ./tmp/deepspeed.json deepspeed_mpi ................................... False dino_bottleneck_size ............................ 256 dino_freeze_last_layer .......................... 1 dino_head_hidden_size ........................... 2048 dino_local_crops_number ......................... 10 dino_local_img_size ............................. 96 dino_norm_last_layer ............................ False dino_teacher_temp ............................... 0.07 dino_warmup_teacher_temp ........................ 0.04 dino_warmup_teacher_temp_epochs ................. 30 distribute_checkpointed_activations ............. False distribute_saved_activations .................... False distributed_backend ............................. nccl distributed_timeout_minutes ..................... 10 ds_inference .................................... False ds_pipeline_enabled ............................. True embedding_path .................................. None embedding_weights_in_fp32 ....................... False empty_unused_memory_level ....................... 0 enable_expert_tensor_parallelism ................ False encoder_num_layers .............................. 24 encoder_seq_length .............................. 2048 end_weight_decay ................................ 0.1 eod_mask_loss ................................... False eval_interval ................................... 1000 eval_iters ...................................... 10 evidence_data_path .............................. None exit_duration_in_mins ........................... None exit_interval ................................... None exit_on_missing_checkpoint ...................... False exit_signal_handler ............................. False expert_interval ................................. 2 ffn_hidden_size ................................. 5504 finetune ........................................ False fp16 ............................................ True fp16_lm_cross_entropy ........................... False fp32_residual_connection ........................ False fp8_amax_compute_algo ........................... most_recent fp8_amax_history_len ............................ 1 fp8_e4m3 ........................................ False fp8_hybrid ...................................... False fp8_interval .................................... 1 fp8_margin ...................................... 0 fp8_wgrad ....................................... True global_batch_size ............................... 32 gradient_accumulation_fusion .................... True head_lr_mult .................................... 1.0 hidden_dropout .................................. 0.0 hidden_size ..................................... 2048 hidden_size_teacher ............................. None hysteresis ...................................... 2 ict_head_size ................................... None ict_load ........................................ None img_h ........................................... 224 img_w ........................................... 224 indexer_batch_size .............................. 128 indexer_log_interval ............................ 1000 inference ....................................... False inference_batch_times_seqlen_threshold .......... 512 init_method_std ................................. 0.02 init_method_xavier_uniform ...................... False initial_loss_scale .............................. 4294967296 iter_per_epoch .................................. 1250 kd .............................................. False kd_alpha_ce ..................................... 1 kd_beta_ce ...................................... 1 kd_temp ......................................... 1.0 kv_channels ..................................... 128 layernorm_epsilon ............................... 1e-05 lazy_mpu_init ................................... None load ............................................ ./tmp load_teacher .................................... None local_rank ...................................... None log_batch_size_to_tensorboard ................... False log_interval .................................... 1 log_learning_rate_to_tensorboard ................ True log_loss_scale_to_tensorboard ................... True log_memory_to_tensorboard ....................... False log_num_zeros_in_grad ........................... False log_optimizer_states_to_tensorboard ............. False log_params_norm ................................. False log_timers_to_tensorboard ....................... False log_validation_ppl_to_tensorboard ............... False log_world_size_to_tensorboard ................... False loss_scale ...................................... None loss_scale_window ............................... 1000 lr .............................................. 0.0003 lr_decay_iters .................................. None lr_decay_samples ................................ None lr_decay_style .................................. cosine lr_decay_tokens ................................. None lr_warmup_fraction .............................. None lr_warmup_iters ................................. 2000 lr_warmup_samples ............................... 0 lr_warmup_tokens ................................ None make_vocab_size_divisible_by .................... 128 mask_factor ..................................... 1.0 mask_prob ....................................... 0.15 mask_type ....................................... random masked_softmax_fusion ........................... True max_position_embeddings ......................... 2048 max_tokens_to_oom ............................... 12000 memory_centric_tiled_linear ..................... False merge_file ...................................... None micro_batch_size ................................ 4 min_loss_scale .................................. 1.0 min_lr .......................................... 3e-05 mlp_type ........................................ standard mmap_warmup ..................................... False moe_eval_capacity_factor ........................ 1.0 moe_expert_parallel_size ........................ 1 moe_loss_coeff .................................. 0.1 moe_min_capacity ................................ 4 moe_token_dropping .............................. True moe_train_capacity_factor ....................... 1.0 mos ............................................. False no_load_lr_state ................................ False no_load_optim ................................... None no_load_rng ..................................... None no_persist_layer_norm ........................... False no_pipeline_parallel ............................ False no_save_optim ................................... None no_save_rng ..................................... None normalization ................................... rmsnorm num_attention_heads ............................. 16 num_attention_heads_teacher ..................... None num_channels .................................... 3 num_classes ..................................... 1000 num_experts ..................................... [1] num_experts_switch .............................. None num_experts_teacher ............................. [1] num_key_value_heads ............................. 16 num_layers ...................................... 24 num_layers_per_virtual_pipeline_stage ........... None num_layers_teacher .............................. None num_workers ..................................... 2 onnx_safe ....................................... None openai_gelu ..................................... False optimizer ....................................... adam output_bert_embeddings .......................... False overlap_p2p_comm ................................ False override_opt_param_scheduler .................... False params_dtype .................................... torch.float16 partition_activations ........................... False patch_dim ....................................... 16 perform_initialization .......................... True pipeline_model_parallel_size .................... 2 pipeline_model_parallel_split_rank .............. None profile_backward ................................ False query_in_block_prob ............................. 0.1 rampup_batch_size ............................... None random_ltd ...................................... False rank ............................................ 0 recompute_granularity ........................... None recompute_method ................................ None recompute_num_layers ............................ 1 remote_device ................................... none reset_attention_mask ............................ False reset_iteration ................................. False reset_position_ids .............................. False retriever_report_topk_accuracies ................ [] retriever_score_scaling ......................... False retriever_seq_length ............................ 256 retro_add_retriever ............................. False retro_cyclic_train_iters ........................ None retro_encoder_attention_dropout ................. 0.1 retro_encoder_hidden_dropout .................... 0.1 retro_encoder_layers ............................ 2 retro_num_neighbors ............................. 2 retro_num_retrieved_chunks ...................... 2 retro_return_doc_ids ............................ False retro_workdir ................................... None return_data_index ............................... False rotary_percent .................................. 1.0 sample_rate ..................................... 1.0 save ............................................ ./tmp save_interval ................................... 10000 scatter_gather_tensors_in_pipeline .............. True scattered_embeddings ............................ False seed ............................................ 1234 seq_length ...................................... 2048 sequence_parallel ............................... False sgd_momentum .................................... 0.9 short_seq_prob .................................. 0.1 skip_train ...................................... False split ........................................... 900,50,50 split_transformers .............................. False squared_relu .................................... False standalone_embedding_stage ...................... False start_weight_decay .............................. 0.1 swiglu .......................................... True swin_backbone_type .............................. tiny synchronize_each_layer .......................... False tensor_model_parallel_size ...................... 2 tensorboard_dir ................................. None tensorboard_log_interval ........................ 1 tensorboard_queue_size .......................... 1000 test_data_path .................................. None tile_factor ..................................... 1 timing_log_level ................................ 0 timing_log_option ............................... minmax titles_data_path ................................ None tokenizer_model ................................. /workspace/model/llama-tokenizer/tokenizer.model tokenizer_type .................................. GPTSentencePieceTokenizer topk ............................................ 1 train_data_exact_num_epochs ..................... None train_data_path ................................. None train_desc_path ................................. None train_doc_idx_path .............................. None train_idx_path .................................. None train_iters ..................................... 2500 train_sample_idx_path ........................... None train_samples ................................... None train_shuffle_idx_path .......................... None train_tokens .................................... None transformer_impl ................................ local transformer_pipeline_model_parallel_size ........ 2 untie_embeddings_and_output_weights ............. True use_checkpoint_args ............................. False use_checkpoint_opt_param_scheduler .............. False use_contiguous_buffers_in_local_ddp ............. True use_cpu_initialization .......................... None use_distributed_optimizer ....................... False use_flash_attn .................................. False use_one_sent_docs ............................... False use_pin_memory .................................. False use_ring_exchange_p2p ........................... False use_rotary_position_embeddings .................. True use_tutel ....................................... False valid_data_path ................................. None variable_seq_lengths ............................ False virtual_pipeline_model_parallel_size ............ None vision_backbone_type ............................ vit vision_pretraining .............................. False vision_pretraining_type ......................... classify vocab_extra_ids ................................. 0 vocab_file ...................................... None vocab_size ...................................... None weight_decay .................................... 0.1 weight_decay_incr_style ......................... constant world_size ...................................... 8 zero_allgather_bucket_size ...................... 0.0 zero_contigious_gradients ....................... False zero_reduce_bucket_size ......................... 0.0 zero_reduce_scatter ............................. False zero_stage ...................................... 0 -------------------- end of arguments --------------------- setting number of micro-batches to constant 4 > building GPTSentencePieceTokenizer tokenizer ... > padded vocab (size: 32000) with 0 dummy tokens (new size: 32000) > initializing torch distributed ... ... > initialized tensor model parallel with size 2 > initialized pipeline model parallel with size 2 > setting random seeds to 1234 ... > initializing model parallel cuda seeds on global rank 0, model parallel rank 0, and data parallel rank 0 with model parallel seed: 3952 and data parallel seed: 1234 > compiling dataset index builder ... make: Entering directory '/workspace/code/Megatron-DeepSpeed-llama-20230815/megatron/data' make: Nothing to be done for 'default'. make: Leaving directory '/workspace/code/Megatron-DeepSpeed-llama-20230815/megatron/data' >>> done with dataset index builder. Compilation time: 0.211 seconds > compiling and loading fused kernels ... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-DeepSpeed-llama-20230815/megatron/fused_kernels/build/build.ninja... Building extension module scaled_upper_triang_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_upper_triang_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-DeepSpeed-llama-20230815/megatron/fused_kernels/build/build.ninja... Building extension module scaled_masked_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_masked_softmax_cuda... Detected CUDA files, patching ldflags Emitting ninja build file /workspace/code/Megatron-DeepSpeed-llama-20230815/megatron/fused_kernels/build/build.ninja... Building extension module scaled_softmax_cuda... Allowing ninja to set a default number of workers... (overridable by setting the environment variable MAX_JOBS=N) ninja: no work to do. Loading extension module scaled_softmax_cuda... >>> done with compiling and loading fused kernels. Compilation time: 5.323 seconds time to initialize megatron (seconds): 9.579 [after megatron is initialized] datetime: 2023-08-15 06:31:34 building GPT model ... [2023-08-15 06:31:34,678] [INFO] [utils.py:785:see_memory_usage] Before Building Model [2023-08-15 06:31:34,679] [INFO] [utils.py:786:see_memory_usage] MA 0.0 GB Max_MA 0.73 GB CA 0.0 GB Max_CA 1 GB [2023-08-15 06:31:34,680] [INFO] [utils.py:793:see_memory_usage] CPU Virtual Memory: used = 53.28 GB, percent = 5.3% SEED_LAYERS=False BASE_SEED=1234 SEED_FN=None Using topology: {ProcessCoord(pipe=0, data=0, model=0): 0, ProcessCoord(pipe=0, data=0, model=1): 1, ProcessCoord(pipe=0, data=1, model=0): 2, ProcessCoord(pipe=0, data=1, model=1): 3, ProcessCoord(pipe=1, data=0, model=0): 4, ProcessCoord(pipe=1, data=0, model=1): 5, ProcessCoord(pipe=1, data=1, model=0): 6, ProcessCoord(pipe=1, data=1, model=1): 7} [2023-08-15 06:31:34,817] [INFO] [module.py:358:_partition_layers] Partitioning pipeline stages with method type:transformer stage=0 layers=14 0: _to_float16 1: EmbeddingPipe 2: ParallelTransformerLayerPipe 3: ParallelTransformerLayerPipe 4: ParallelTransformerLayerPipe 5: ParallelTransformerLayerPipe 6: ParallelTransformerLayerPipe 7: ParallelTransformerLayerPipe 8: ParallelTransformerLayerPipe 9: ParallelTransformerLayerPipe 10: ParallelTransformerLayerPipe 11: ParallelTransformerLayerPipe 12: ParallelTransformerLayerPipe 13: ParallelTransformerLayerPipe stage=1 layers=15 14: ParallelTransformerLayerPipe 15: ParallelTransformerLayerPipe 16: ParallelTransformerLayerPipe 17: ParallelTransformerLayerPipe 18: ParallelTransformerLayerPipe 19: ParallelTransformerLayerPipe 20: ParallelTransformerLayerPipe 21: ParallelTransformerLayerPipe 22: ParallelTransformerLayerPipe 23: ParallelTransformerLayerPipe 24: ParallelTransformerLayerPipe 25: ParallelTransformerLayerPipe 26: MixedFusedRMSNorm 27: LMHeadPipe 28: float16_to_fp32 loss: CrossEntropy > number of parameters on (tensor, pipeline) model parallel rank (0, 1): 336381952 > number of parameters on (tensor, pipeline) model parallel rank (1, 0): 336379904 > number of parameters on (tensor, pipeline) model parallel rank (1, 1): 336381952 [2023-08-15 06:31:34,957] [INFO] [utils.py:785:see_memory_usage] After Building Model [2023-08-15 06:31:34,958] [INFO] [utils.py:786:see_memory_usage] MA 0.65 GB Max_MA 0.66 GB CA 0.68 GB Max_CA 1 GB [2023-08-15 06:31:34,958] [INFO] [utils.py:793:see_memory_usage] CPU Virtual Memory: used = 53.4 GB, percent = 5.3% > number of parameters on (tensor, pipeline) model parallel rank (0, 0): 336379904 > learning rate decay style: cosine DeepSpeed is enabled. [2023-08-15 06:31:34,960] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed info: version=0.9.5, git-hash=unknown, git-branch=unknown [2023-08-15 06:31:35,566] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed Flops Profiler Enabled: False [2023-08-15 06:31:35,566] [INFO] [logging.py:96:log_dist] [Rank 0] Removing param_group that has no 'params' in the client Optimizer [2023-08-15 06:31:35,566] [INFO] [logging.py:96:log_dist] [Rank 0] Using client Optimizer as basic optimizer [2023-08-15 06:31:35,567] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed Basic Optimizer = FusedAdam [2023-08-15 06:31:35,567] [INFO] [logging.py:96:log_dist] [Rank 0] Creating fp16 optimizer with dynamic loss scale [2023-08-15 06:31:35,631] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed Final Optimizer = FusedAdam [2023-08-15 06:31:35,631] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed using client LR scheduler [2023-08-15 06:31:35,631] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed LR Scheduler = [2023-08-15 06:31:35,631] [INFO] [logging.py:96:log_dist] [Rank 0] step=0, skipped=0, lr=[0.0, 0.0], mom=[(0.9, 0.95), (0.9, 0.95)] [2023-08-15 06:31:35,632] [INFO] [config.py:960:print] DeepSpeedEngine configuration: [2023-08-15 06:31:35,632] [INFO] [config.py:964:print] activation_checkpointing_config { "partition_activations": false, "contiguous_memory_optimization": false, "cpu_checkpointing": false, "number_checkpoints": null, "synchronize_checkpoint_boundary": false, "profile": false } [2023-08-15 06:31:35,632] [INFO] [config.py:964:print] aio_config ................... {'block_size': 1048576, 'queue_depth': 8, 'thread_count': 1, 'single_submit': False, 'overlap_events': True} [2023-08-15 06:31:35,632] [INFO] [config.py:964:print] amp_enabled .................. False [2023-08-15 06:31:35,632] [INFO] [config.py:964:print] amp_params ................... False [2023-08-15 06:31:35,632] [INFO] [config.py:964:print] autotuning_config ............ { "enabled": false, "start_step": null, "end_step": null, "metric_path": null, "arg_mappings": null, "metric": "throughput", "model_info": null, "results_dir": "autotuning_results", "exps_dir": "autotuning_exps", "overwrite": true, "fast": true, "start_profile_step": 3, "end_profile_step": 5, "tuner_type": "gridsearch", "tuner_early_stopping": 5, "tuner_num_trials": 50, "model_info_path": null, "mp_size": 1, "max_train_batch_size": null, "min_train_batch_size": 1, "max_train_micro_batch_size_per_gpu": 1.024000e+03, "min_train_micro_batch_size_per_gpu": 1, "num_tuning_micro_batch_sizes": 3 } [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] bfloat16_enabled ............. False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] checkpoint_parallel_write_pipeline False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] checkpoint_tag_validation_enabled True [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] checkpoint_tag_validation_fail False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] comms_config ................. [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] communication_data_type ...... None [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] compression_config ........... {'weight_quantization': {'shared_parameters': {'enabled': False, 'quantizer_kernel': False, 'schedule_offset': 0, 'quantize_groups': 1, 'quantize_verbose': False, 'quantization_type': 'symmetric', 'quantize_weight_in_forward': False, 'rounding': 'nearest', 'fp16_mixed_quantize': False, 'quantize_change_ratio': 0.001}, 'different_groups': {}}, 'activation_quantization': {'shared_parameters': {'enabled': False, 'quantization_type': 'symmetric', 'range_calibration': 'dynamic', 'schedule_offset': 1000}, 'different_groups': {}}, 'sparse_pruning': {'shared_parameters': {'enabled': False, 'method': 'l1', 'schedule_offset': 1000}, 'different_groups': {}}, 'row_pruning': {'shared_parameters': {'enabled': False, 'method': 'l1', 'schedule_offset': 1000}, 'different_groups': {}}, 'head_pruning': {'shared_parameters': {'enabled': False, 'method': 'topk', 'schedule_offset': 1000}, 'different_groups': {}}, 'channel_pruning': {'shared_parameters': {'enabled': False, 'method': 'l1', 'schedule_offset': 1000}, 'different_groups': {}}, 'layer_reduction': {'enabled': False}} [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] curriculum_enabled_legacy .... False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] curriculum_params_legacy ..... False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] data_efficiency_config ....... {'enabled': False, 'seed': 1234, 'data_sampling': {'enabled': False, 'num_epochs': 1000, 'num_workers': 0, 'curriculum_learning': {'enabled': False}}, 'data_routing': {'enabled': False, 'random_ltd': {'enabled': False, 'layer_token_lr_schedule': {'enabled': False}}}} [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] data_efficiency_enabled ...... False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] dataloader_drop_last ......... False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] disable_allgather ............ False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] dump_state ................... False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] dynamic_loss_scale_args ...... {'init_scale': 65536, 'scale_window': 1000, 'delayed_shift': 2, 'consecutive_hysteresis': False, 'min_scale': 1} [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] eigenvalue_enabled ........... False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] eigenvalue_gas_boundary_resolution 1 [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] eigenvalue_layer_name ........ bert.encoder.layer [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] eigenvalue_layer_num ......... 0 [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] eigenvalue_max_iter .......... 100 [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] eigenvalue_stability ......... 1e-06 [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] eigenvalue_tol ............... 0.01 [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] eigenvalue_verbose ........... False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] elasticity_enabled ........... False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] flops_profiler_config ........ { "enabled": false, "recompute_fwd_factor": 0.0, "profile_step": 1, "module_depth": -1, "top_modules": 1, "detailed": true, "output_file": null } [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] fp16_auto_cast ............... False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] fp16_enabled ................. True [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] fp16_master_weights_and_gradients False [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] global_rank .................. 0 [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] grad_accum_dtype ............. None [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] gradient_accumulation_steps .. 4 [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] gradient_clipping ............ 0.0 [2023-08-15 06:31:35,633] [INFO] [config.py:964:print] gradient_predivide_factor .... 1.0 [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] hybrid_engine ................ enabled=False max_out_tokens=512 inference_tp_size=1 release_inference_cache=False pin_parameters=True tp_gather_partition_size=8 [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] initial_dynamic_scale ........ 65536 [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] load_universal_checkpoint .... False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] loss_scale ................... 0 [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] memory_breakdown ............. False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] mics_hierarchial_params_gather False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] mics_shard_size .............. -1 [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] monitor_config ............... tensorboard=TensorBoardConfig(enabled=False, output_path='', job_name='DeepSpeedJobName') wandb=WandbConfig(enabled=False, group=None, team=None, project='deepspeed') csv_monitor=CSVConfig(enabled=False, output_path='', job_name='DeepSpeedJobName') enabled=False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] nebula_config ................ { "enabled": false, "persistent_storage_path": null, "persistent_time_interval": 100, "num_of_version_in_retention": 2, "enable_nebula_load": true, "load_path": null } [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] optimizer_legacy_fusion ...... False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] optimizer_name ............... None [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] optimizer_params ............. None [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] pipeline ..................... {'stages': 'auto', 'partition': 'best', 'seed_layers': False, 'activation_checkpoint_interval': 0} [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] pld_enabled .................. False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] pld_params ................... False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] prescale_gradients ........... False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] scheduler_name ............... None [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] scheduler_params ............. None [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] sparse_attention ............. None [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] sparse_gradients_enabled ..... False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] steps_per_print .............. 1 [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] train_batch_size ............. 32 [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] train_micro_batch_size_per_gpu 4 [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] use_node_local_storage ....... False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] wall_clock_breakdown ......... False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] world_size ................... 2 [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] zero_allow_untested_optimizer False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] zero_config .................. stage=0 contiguous_gradients=True reduce_scatter=True reduce_bucket_size=500,000,000 allgather_partitions=True allgather_bucket_size=500,000,000 overlap_comm=False load_from_fp32_weights=True elastic_checkpoint=False offload_param=None offload_optimizer=None sub_group_size=1,000,000,000 cpu_offload_param=None cpu_offload_use_pin_memory=None cpu_offload=None prefetch_bucket_size=50,000,000 param_persistence_threshold=100,000 model_persistence_threshold=sys.maxsize max_live_parameters=1,000,000,000 max_reuse_distance=1,000,000,000 gather_16bit_weights_on_model_save=False stage3_gather_fp16_weights_on_model_save=False ignore_unused_parameters=True legacy_stage1=False round_robin_gradients=False mics_shard_size=-1 mics_hierarchical_params_gather=False memory_efficient_linear=True [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] zero_enabled ................. False [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] zero_force_ds_cpu_optimizer .. True [2023-08-15 06:31:35,634] [INFO] [config.py:964:print] zero_optimization_stage ...... 0 [2023-08-15 06:31:35,634] [INFO] [config.py:950:print_user_config] json = { "train_batch_size": 32, "train_micro_batch_size_per_gpu": 4, "steps_per_print": 1, "zero_optimization": { "stage": 0 }, "fp16": { "enabled": true, "auto_cast": false, "loss_scale": 0, "initial_scale_power": 16, "loss_scale_window": 1000, "hysteresis": 2, "consecutive_hysteresis": false, "min_loss_scale": 1 } } [2023-08-15 06:31:35,634] [INFO] [engine.py:83:__init__] CONFIG: micro_batches=4 micro_batch_size=4 [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [W ProcessGroupNCCL.cpp:1692] Warning: 0NCCL_AVOID_RECORD_STREAMS=1 has no effect for point-to-point collectives. (function operator()) [2023-08-15 06:31:36,508] [INFO] [engine.py:138:__init__] RANK=0 STAGE=0 LAYERS=14 [0, 14) STAGE_PARAMS=336379904 (336.380M) TOTAL_PARAMS=1345523712 (1345.524M) UNIQUE_PARAMS=1345523712 (1345.524M) [2023-08-15 06:31:36,508] [INFO] [engine.py:138:__init__] RANK=1 STAGE=0 LAYERS=14 [0, 14) STAGE_PARAMS=336379904 (336.380M) TOTAL_PARAMS=1345523712 (1345.524M) UNIQUE_PARAMS=1345523712 (1345.524M) [2023-08-15 06:31:36,508] [INFO] [engine.py:138:__init__] RANK=4 STAGE=1 LAYERS=15 [14, 29) STAGE_PARAMS=336381952 (336.382M) TOTAL_PARAMS=1345523712 (1345.524M) UNIQUE_PARAMS=1345523712 (1345.524M) [2023-08-15 06:31:36,509] [INFO] [engine.py:138:__init__] RANK=5 STAGE=1 LAYERS=15 [14, 29) STAGE_PARAMS=336381952 (336.382M) TOTAL_PARAMS=1345523712 (1345.524M) UNIQUE_PARAMS=1345523712 (1345.524M) ... (min, max) time across ranks (ms): load-checkpoint ................................: (1.04, 1.37) [after model, optimizer, and learning rate scheduler are built] datetime: 2023-08-15 06:31:36 > building train, validation, and test datasets ... > datasets target sizes (minimum size): train: 80000 validation: 960 test: 320 > building train, validation, and test datasets for GPT ... Single data path provided for train, valid & test > building dataset index ... reading sizes... reading pointers... reading document index... creating numpy buffer of mmap... creating memory view of numpy buffer... > finished creating indexed dataset in 0.000625 seconds number of documents: 2456 > dataset split: train: document indices in [0, 2210) total of 2210 documents validation: document indices in [2210, 2333) total of 123 documents test: document indices in [2333, 2456) total of 123 documents ... > loading doc-idx mapping from /workspace/data/gpt2-data/index-cache/adec68d4b8dc51ef702dcac7f462e93b_doc_idx.npy > loading sample-idx mapping from /workspace/data/gpt2-data/index-cache/adec68d4b8dc51ef702dcac7f462e93b_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/gpt2-data/index-cache/adec68d4b8dc51ef702dcac7f462e93b_shuffle_idx.npy loaded indexed file in 0.002 seconds total number of samples: 113 total number of epochs: 9 > building dataset index ... reading sizes... reading pointers... reading document index... creating numpy buffer of mmap... creating memory view of numpy buffer... > finished creating indexed dataset in 0.000503 seconds number of documents: 2456 > dataset split: train: document indices in [0, 2210) total of 2210 documents validation: document indices in [2210, 2333) total of 123 documents test: document indices in [2333, 2456) total of 123 documents > loading doc-idx mapping from /workspace/data/gpt2-data/index-cache/1a4c392debaeae4aaefe3a720974d6cf_doc_idx.npy > loading sample-idx mapping from /workspace/data/gpt2-data/index-cache/1a4c392debaeae4aaefe3a720974d6cf_sample_idx.npy > loading shuffle-idx mapping from /workspace/data/gpt2-data/index-cache/1a4c392debaeae4aaefe3a720974d6cf_shuffle_idx.npy loaded indexed file in 0.002 seconds total number of samples: 53810 total number of epochs: 191 ... > building indices for blendable datasets ... > sample ratios: dataset 0, input: 0.333333, achieved: 0.333333 dataset 1, input: 0.666667, achieved: 0.666667 > elapsed time for building blendable dataset indices: 0.00 (sec) > size of blendable dataset: 80400 samples > building indices for blendable datasets ... > sample ratios: dataset 0, input: 0.333333, achieved: 0.333333 dataset 1, input: 0.666667, achieved: 0.666667 > elapsed time for building blendable dataset indices: 0.00 (sec) > size of blendable dataset: 966 samples > building indices for blendable datasets ... > sample ratios: dataset 0, input: 0.333333, achieved: 0.334365 dataset 1, input: 0.666667, achieved: 0.665635 > elapsed time for building blendable dataset indices: 0.00 (sec) > size of blendable dataset: 323 samples > finished creating GPT datasets ... [after dataloaders are built] datetime: 2023-08-15 06:31:38 done with setup ... (min, max) time across ranks (ms): model-and-optimizer-setup ......................: (2449.71, 2515.91) train/valid/test-data-iterators-setup ..........: (1430.08, 1704.59) training ... [before the start of training step] datetime: 2023-08-15 06:31:38 ... [2023-08-15 06:31:42,452] [INFO] [logging.py:96:log_dist] [Rank 0] step=1, skipped=1, lr=[0.0, 0.0], mom=[(0.9, 0.95), (0.9, 0.95)] [2023-08-15 06:31:42,452] [INFO] [fused_optimizer.py:363:_update_scale] Reducing dynamic loss scale from 65536 to 32768.0 steps: 1 loss: 10.6554 iter time (s): 4.218 samples/sec: 7.586 iteration 1/ 2500 | consumed samples: 32 | consumed tokens: 65536 | elapsed time per iteration (ms): 4220.8 | learning rate: 0.000E+00 | global batch size: 32 | lm loss: 1.065542E+01 | loss scale: 32768.0 | grad norm: 0.000 | num zeros: 0.0 | actual seqlen: 2048 | number of skipped iterations: 0 | number of nan iterations: 0 | samples per second: 7.582 | TFLOPs: 16.98 | [2023-08-15 06:31:44,231] [INFO] [logging.py:96:log_dist] [Rank 0] step=2, skipped=1, lr=[1.5e-07, 1.5e-07], mom=[(0.9, 0.95), (0.9, 0.95)] steps: 2 loss: 10.6521 iter time (s): 1.337 samples/sec: 23.934 iteration 2/ 2500 | consumed samples: 64 | consumed tokens: 131072 | elapsed time per iteration (ms): 1346.3 | learning rate: 1.500E-07 | global batch size: 32 | lm loss: 1.065210E+01 | loss scale: 32768.0 | grad norm: 14.113 | num zeros: 0.0 | actual seqlen: 2048 | number of skipped iterations: 0 | number of nan iterations: 0 | samples per second: 23.769 | TFLOPs: 53.25 | [2023-08-15 06:31:45,481] [INFO] [logging.py:96:log_dist] [Rank 0] step=3, skipped=1, lr=[3e-07, 3e-07], mom=[(0.9, 0.95), (0.9, 0.95)] steps: 3 loss: 10.6457 iter time (s): 1.246 samples/sec: 25.683 iteration 3/ 2500 | consumed samples: 96 | consumed tokens: 196608 | elapsed time per iteration (ms): 1250.2 | learning rate: 3.000E-07 | global batch size: 32 | lm loss: 1.064566E+01 | loss scale: 32768.0 | grad norm: 14.740 | num zeros: 0.0 | actual seqlen: 2048 | number of skipped iterations: 0 | number of nan iterations: 0 | samples per second: 25.596 | TFLOPs: 57.34 | ... steps: 2498 loss: 12.6747 iter time (s): 1.206 samples/sec: 26.538 iteration 2498/ 2500 | consumed samples: 79936 | consumed tokens: 163708928 | elapsed time per iteration (ms): 1210.3 | learning rate: 1.371E-04 | global batch size: 32 | lm loss: 1.267467E+01 | loss scale: 1.0 | grad norm: 2.265 | num zeros: 0.0 | actual seqlen: 2048 | number of skipped iterations: 0 | number of nan iterations: 0 | samples per second: 26.440 | TFLOPs: 59.23 | [2023-08-15 07:22:30,556] [INFO] [logging.py:96:log_dist] [Rank 0] Overflow detected. Skipping step. Attempted loss scale: 1, reducing to 1 [2023-08-15 07:22:30,556] [INFO] [logging.py:96:log_dist] [Rank 0] step=2499, skipped=1585, lr=[0.0001371, 0.0001371], mom=[(0.9, 0.95), (0.9, 0.95)] steps: 2499 loss: 13.4013 iter time (s): 1.202 samples/sec: 26.614 iteration 2499/ 2500 | consumed samples: 79968 | consumed tokens: 163774464 | elapsed time per iteration (ms): 1205.4 | learning rate: 1.371E-04 | global batch size: 32 | lm loss: 1.340131E+01 | loss scale: 1.0 | grad norm: 2.265 | num zeros: 0.0 | actual seqlen: 2048 | number of skipped iterations: 0 | number of nan iterations: 0 | samples per second: 26.546 | TFLOPs: 59.47 | [2023-08-15 07:22:31,763] [INFO] [fused_optimizer.py:363:_update_scale] Reducing dynamic loss scale from 1 to 1 ... [2023-08-15 07:22:31,763] [INFO] [fused_optimizer.py:363:_update_scale] Reducing dynamic loss scale from 1 to 1 [2023-08-15 07:22:31,763] [INFO] [logging.py:96:log_dist] [Rank 0] Overflow detected. Skipping step. Attempted loss scale: 1, reducing to 1 [2023-08-15 07:22:31,764] [INFO] [logging.py:96:log_dist] [Rank 0] step=2500, skipped=1586, lr=[0.0001371, 0.0001371], mom=[(0.9, 0.95), (0.9, 0.95)] steps: 2500 loss: 12.5495 iter time (s): 1.200 samples/sec: 26.671 iteration 2500/ 2500 | consumed samples: 80000 | consumed tokens: 163840000 | elapsed time per iteration (ms): 1206.4 | learning rate: 1.371E-04 | global batch size: 32 | lm loss: 1.254951E+01 | loss scale: 1.0 | grad norm: 2.265 | num zeros: 0.0 | actual seqlen: 2048 | number of skipped iterations: 0 | number of nan iterations: 0 | samples per second: 26.526 | TFLOPs: 59.42 | [after training is done] datetime: 2023-08-15 07:22:31 saving checkpoint at iteration 2500 to ./tmp [2023-08-15 07:22:31,767] [INFO] [logging.py:96:log_dist] [Rank 0] [Torch] Checkpoint global_step2500 is about to be saved! [2023-08-15 07:22:31,774] [INFO] [torch_checkpoint_engine.py:21:save] [Torch] Saving ./tmp/global_step2500/layer_14-model_01-model_states.pt... [2023-08-15 07:22:31,774] [INFO] [torch_checkpoint_engine.py:21:save] [Torch] Saving ./tmp/global_step2500/layer_01-model_01-model_states.pt... [2023-08-15 07:22:31,774] [INFO] [torch_checkpoint_engine.py:33:commit] [Torch] Checkpoint global_step2500 is ready now! [2023-08-15 07:22:31,774] [INFO] [torch_checkpoint_engine.py:33:commit] [Torch] Checkpoint global_step2500 is ready now! [2023-08-15 07:22:31,775] [INFO] [torch_checkpoint_engine.py:21:save] [Torch] Saving ./tmp/global_step2500/layer_14-model_00-model_states.pt... ... [2023-08-15 07:22:32,255] [INFO] [torch_checkpoint_engine.py:21:save] [Torch] Saving ./tmp/global_step2500/layer_27-model_00-model_states.pt... [2023-08-15 07:22:32,273] [INFO] [torch_checkpoint_engine.py:21:save] [Torch] Saving ./tmp/global_step2500/layer_26-model_01-model_states.pt... [2023-08-15 07:22:32,273] [INFO] [torch_checkpoint_engine.py:23:save] [Torch] Saved ./tmp/global_step2500/layer_26-model_01-model_states.pt. [2023-08-15 07:22:32,273] [INFO] [torch_checkpoint_engine.py:21:save] [Torch] Saving ./tmp/global_step2500/layer_27-model_01-model_states.pt... ... [2023-08-15 07:22:32,448] [INFO] [torch_checkpoint_engine.py:21:save] [Torch] Saving ./tmp/global_step2500/mp_rank_00_model_states.pt... [2023-08-15 07:22:35,824] [INFO] [torch_checkpoint_engine.py:23:save] [Torch] Saved ./tmp/global_step2500/mp_rank_02_model_states.pt. [2023-08-15 07:22:35,824] [INFO] [torch_checkpoint_engine.py:33:commit] [Torch] Checkpoint global_step2500 is ready now! [2023-08-15 07:22:35,987] [INFO] [torch_checkpoint_engine.py:23:save] [Torch] Saved ./tmp/global_step2500/mp_rank_01_model_states.pt. [2023-08-15 07:22:35,988] [INFO] [torch_checkpoint_engine.py:33:commit] [Torch] Checkpoint global_step2500 is ready now! [2023-08-15 07:22:36,380] [INFO] [torch_checkpoint_engine.py:23:save] [Torch] Saved ./tmp/global_step2500/mp_rank_03_model_states.pt. [2023-08-15 07:22:36,380] [INFO] [torch_checkpoint_engine.py:33:commit] [Torch] Checkpoint global_step2500 is ready now! [2023-08-15 07:22:37,720] [INFO] [torch_checkpoint_engine.py:23:save] [Torch] Saved ./tmp/global_step2500/mp_rank_00_model_states.pt. [2023-08-15 07:22:37,720] [INFO] [torch_checkpoint_engine.py:33:commit] [Torch] Checkpoint global_step2500 is ready now! successfully saved checkpoint at iteration 2500 to ./tmp Evaluating iter 1/10 ... Evaluating iter 10/10 Evaluating iter 1/10 --------------------------------------------------------------------------------------------------------------------------------------- validation loss at iteration 2500 on 320-sample draw from validation set | lm loss value: 1.360287E+01 | lm loss PPL: 8.084497E+05 | --------------------------------------------------------------------------------------------------------------------------------------- Evaluating iter 2/10 ... Evaluating iter 10/10 --------------------------------------------------------------------------------------------------------------------------------- validation loss at iteration 2500 on 320-sample draw from test set | lm loss value: 1.495915E+01 | lm loss PPL: 3.138158E+06 | --------------------------------------------------------------------------------------------------------------------------------- ```

``` > ls -al -R --block-size=M tmp/ tmp/: total 1M drwxr-xr-x 3 root root 1M Aug 15 07:22 . drwxr-xr-x 13 root root 1M Aug 15 06:07 .. -rw-r--r-- 1 root root 1M Aug 15 06:31 deepspeed.json drwxr-xr-x 2 root root 1M Aug 15 07:22 global_step2500 -rw-r--r-- 1 root root 1M Aug 15 07:22 latest -rw-r--r-- 1 root root 1M Aug 15 07:22 latest_checkpointed_iteration.txt tmp/global_step2500: total 17986M drwxr-xr-x 2 root root 1M Aug 15 07:22 . drwxr-xr-x 3 root root 1M Aug 15 07:22 .. -rw-r--r-- 1 root root 63M Aug 15 07:22 layer_01-model_00-model_states.pt -rw-r--r-- 1 root root 63M Aug 15 07:22 layer_01-model_01-model_states.pt ... -rw-r--r-- 1 root root 63M Aug 15 07:22 layer_27-model_00-model_states.pt -rw-r--r-- 1 root root 63M Aug 15 07:22 layer_27-model_01-model_states.pt -rw-r--r-- 1 root root 3855M Aug 15 07:22 mp_rank_00_model_states.pt -rw-r--r-- 1 root root 3855M Aug 15 07:22 mp_rank_01_model_states.pt -rw-r--r-- 1 root root 3855M Aug 15 07:22 mp_rank_02_model_states.pt -rw-r--r-- 1 root root 3855M Aug 15 07:22 mp_rank_03_model_states.pt ``` ================================================ FILE: llm-train/megatron-deepspeed/microsoft/pip.conf ================================================ # This file has been autogenerated or modified by NVIDIA PyIndex. # In case you need to modify your PIP configuration, please be aware that # some configuration files may have a priority order. Here are the following # files that may exists in your machine by order of priority: # # [Priority 1] Site level configuration files # 1. `/usr/pip.conf` # # [Priority 2] User level configuration files # 1. `/root/.config/pip/pip.conf` # 2. `/root/.pip/pip.conf` # # [Priority 3] Global level configuration files # 1. `/etc/pip.conf` # 2. `/etc/xdg/pip/pip.conf` [global] index-url = http://nexus3.xxx.com/repository/pypi/simple [install] trusted-host = nexus3.xxx.com timeout = 90 no-cache-dir = true ================================================ FILE: llm-train/megatron-deepspeed/microsoft/pretrain_llama2_13b_distributed_fp16.sh ================================================ # This example script is contributed by external user https://github.com/nrailgun set -ex ###################################### # Change the below configurations here BASE_PATH=./tmp DS_CONFIG=${BASE_PATH}/deepspeed.json DATASET_1="/workspace/data/gpt2-data/my-gpt2_text_document" DATASET_2="/workspace/data/gpt2-data/my-gpt2-1_text_document" DATASET="1 ${DATASET_1} 2 ${DATASET_2}" CHECKPOINT_PATH=./tmp TOKENIZER_PATH=/workspace/model/llama2-tokenizer/tokenizer.model # offical llama tokenizer.model TP=4 PP=2 ZERO_STAGE=0 GPUS_PER_NODE=8 MASTER_ADDR=localhost MASTER_PORT=6000 NNODES=1 NODE_RANK=0 HIDDEN_SIZE=5120 # e.g. llama-13b: 5120 FFN_HIDDEN_SIZE=13824 # e.g. llama-13b: 13824 NUM_LAYERS=40 # e.g. llama-13b: 40 NUM_HEADS=40 # e.g. llama-13b: 40 SEQ_LENGTH=2048 NUM_KV_HEADS=40 # llama2 70B uses GQA MICRO_BATCH_SIZE=1 GLOBAL_BATCH_SIZE=4 # e.g. llama: 4M tokens TRAIN_STEPS=1000 # e.g. llama: 1T tokens / 4M tokens_per_batch = 250000 steps LR=3e-4 MIN_LR=3e-5 LR_WARMUP_STEPS=500 WEIGHT_DECAY=0.1 GRAD_CLIP=1 # Below configuration required for llama model as per llama paper # --no-query-key-layer-scaling \ # --attention-dropout 0 \ # --hidden-dropout 0 \ # --use-rotary-position-embeddings \ # --untie-embeddings-and-output-weights \ # --swiglu \ # --normalization rmsnorm \ # --disable-bias-linear \ ###################################### cat < $DS_CONFIG { "train_batch_size" : $GLOBAL_BATCH_SIZE, "train_micro_batch_size_per_gpu": $MICRO_BATCH_SIZE, "steps_per_print": 1, "zero_optimization": { "stage": $ZERO_STAGE }, "fp16": { "enabled": true, "auto_cast": false, "loss_scale": 0, "initial_scale_power": 16, "loss_scale_window": 1000, "hysteresis": 2, "consecutive_hysteresis": false, "min_loss_scale": 1 } } EOT ds_args="" ds_args=" --deepspeed ${ds_args}" ds_args=" --deepspeed_config=$DS_CONFIG ${ds_args}" ds_args=" --zero-stage=$ZERO_STAGE ${ds_args}" ds_args=" --deepspeed-activation-checkpointing ${ds_args}" DISTRIBUTED_ARGS="--nproc_per_node $GPUS_PER_NODE --nnodes $NNODES --node_rank $NODE_RANK --master_addr $MASTER_ADDR --master_port $MASTER_PORT" torchrun $DISTRIBUTED_ARGS \ pretrain_gpt.py \ --tensor-model-parallel-size $TP \ --pipeline-model-parallel-size $PP \ --num-layers $NUM_LAYERS \ --hidden-size $HIDDEN_SIZE \ --ffn-hidden-size $FFN_HIDDEN_SIZE \ --num-attention-heads $NUM_HEADS \ --micro-batch-size $MICRO_BATCH_SIZE \ --global-batch-size $GLOBAL_BATCH_SIZE \ --seq-length $SEQ_LENGTH \ --max-position-embeddings $SEQ_LENGTH \ --train-iters $TRAIN_STEPS \ --save $CHECKPOINT_PATH \ --load $CHECKPOINT_PATH \ --data-path $DATASET \ --data-impl mmap \ --tokenizer-type GPTSentencePieceTokenizer \ --tokenizer-model $TOKENIZER_PATH \ --split 900,50,50 \ --distributed-backend nccl \ --lr $LR \ --lr-decay-style cosine \ --min-lr $MIN_LR \ --weight-decay $WEIGHT_DECAY \ --clip-grad $GRAD_CLIP \ --lr-warmup-iters $LR_WARMUP_STEPS \ --optimizer adam \ --adam-beta1 0.9 \ --adam-beta2 0.95 \ --log-interval 1 \ --save-interval 10000 \ --eval-interval 1000 \ --eval-iters 10 \ --fp16 \ --no-query-key-layer-scaling \ --attention-dropout 0 \ --hidden-dropout 0 \ --use-rotary-position-embeddings \ --untie-embeddings-and-output-weights \ --swiglu \ --normalization rmsnorm \ --disable-bias-linear \ --num-key-value-heads $NUM_KV_HEADS \ $ds_args ================================================ FILE: llm-train/megatron-deepspeed/microsoft/pretrain_llama2_distributed.sh ================================================ #!/bin/bash # This example script is contributed by external user https://github.com/nrailgun set -ex ###################################### # Change the below configurations here BASE_PATH=./tmp DS_CONFIG=${BASE_PATH}/deepspeed.json DATASET_1="/workspace/data/gpt2-data/my-gpt2_text_document" DATASET_2="/workspace/data/gpt2-data/my-gpt2-1_text_document" DATASET="1 ${DATASET_1} 2 ${DATASET_2}" CHECKPOINT_PATH=./tmp TOKENIZER_PATH=/workspace/model/llama2-tokenizer/tokenizer.model # offical llama tokenizer.model TP=2 PP=2 ZERO_STAGE=0 GPUS_PER_NODE=8 MASTER_ADDR=localhost MASTER_PORT=6000 NNODES=1 NODE_RANK=0 HIDDEN_SIZE=2048 # e.g. llama-13b: 5120 FFN_HIDDEN_SIZE=5504 # e.g. llama-13b: 13824 NUM_LAYERS=24 # e.g. llama-13b: 40 NUM_HEADS=16 # e.g. llama-13b: 40 SEQ_LENGTH=2048 NUM_KV_HEADS=4 # llama2 70B uses GQA MICRO_BATCH_SIZE=4 GLOBAL_BATCH_SIZE=32 # e.g. llama: 4M tokens TRAIN_STEPS=2500 # e.g. llama: 1T tokens / 4M tokens_per_batch = 250000 steps LR=3e-4 MIN_LR=3e-5 LR_WARMUP_STEPS=2000 WEIGHT_DECAY=0.1 GRAD_CLIP=1 # Below configuration required for llama model as per llama paper # --no-query-key-layer-scaling \ # --attention-dropout 0 \ # --hidden-dropout 0 \ # --use-rotary-position-embeddings \ # --untie-embeddings-and-output-weights \ # --swiglu \ # --normalization rmsnorm \ # --disable-bias-linear \ ###################################### cat < $DS_CONFIG { "train_batch_size" : $GLOBAL_BATCH_SIZE, "train_micro_batch_size_per_gpu": $MICRO_BATCH_SIZE, "steps_per_print": 1, "zero_optimization": { "stage": $ZERO_STAGE }, "bf16": { "enabled": true } } EOT ds_args="" ds_args=" --deepspeed ${ds_args}" ds_args=" --deepspeed_config=$DS_CONFIG ${ds_args}" ds_args=" --zero-stage=$ZERO_STAGE ${ds_args}" ds_args=" --deepspeed-activation-checkpointing ${ds_args}" DISTRIBUTED_ARGS="--nproc_per_node $GPUS_PER_NODE --nnodes $NNODES --node_rank $NODE_RANK --master_addr $MASTER_ADDR --master_port $MASTER_PORT" torchrun $DISTRIBUTED_ARGS \ pretrain_gpt.py \ --tensor-model-parallel-size $TP \ --pipeline-model-parallel-size $PP \ --num-layers $NUM_LAYERS \ --hidden-size $HIDDEN_SIZE \ --ffn-hidden-size $FFN_HIDDEN_SIZE \ --num-attention-heads $NUM_HEADS \ --micro-batch-size $MICRO_BATCH_SIZE \ --global-batch-size $GLOBAL_BATCH_SIZE \ --seq-length $SEQ_LENGTH \ --max-position-embeddings $SEQ_LENGTH \ --train-iters $TRAIN_STEPS \ --save $CHECKPOINT_PATH \ --load $CHECKPOINT_PATH \ --data-path $DATASET \ --data-impl mmap \ --tokenizer-type GPTSentencePieceTokenizer \ --tokenizer-model $TOKENIZER_PATH \ --split 900,50,50 \ --distributed-backend nccl \ --lr $LR \ --lr-decay-style cosine \ --min-lr $MIN_LR \ --weight-decay $WEIGHT_DECAY \ --clip-grad $GRAD_CLIP \ --lr-warmup-iters $LR_WARMUP_STEPS \ --optimizer adam \ --adam-beta1 0.9 \ --adam-beta2 0.95 \ --log-interval 1 \ --save-interval 10000 \ --eval-interval 1000 \ --eval-iters 10 \ --bf16 \ --no-query-key-layer-scaling \ --attention-dropout 0 \ --hidden-dropout 0 \ --use-rotary-position-embeddings \ --untie-embeddings-and-output-weights \ --swiglu \ --normalization rmsnorm \ --disable-bias-linear \ --num-key-value-heads $NUM_KV_HEADS \ $ds_args ================================================ FILE: llm-train/megatron-deepspeed/microsoft/pretrain_llama_13b_distributed_fp16.sh ================================================ #!/bin/bash # This example script is contributed by external user https://github.com/LydiaXiaohongLi set -ex ###################################### # Change the below configurations here BASE_PATH=./tmp DS_CONFIG=${BASE_PATH}/deepspeed.json DATASET_1="/workspace/data/gpt2-data/my-gpt2_text_document" DATASET_2="/workspace/data/gpt2-data/my-gpt2-1_text_document" DATASET="1 ${DATASET_1} 2 ${DATASET_2}" CHECKPOINT_PATH=./tmp TOKENIZER_PATH=/workspace/model/llama-tokenizer/tokenizer.model # offical llama tokenizer.model TP=4 PP=2 ZERO_STAGE=0 GPUS_PER_NODE=8 MASTER_ADDR=localhost MASTER_PORT=6000 NNODES=1 NODE_RANK=0 HIDDEN_SIZE=5120 # e.g. llama-13b: 5120 FFN_HIDDEN_SIZE=13824 # e.g. llama-13b: 13824 NUM_LAYERS=40 # e.g. llama-13b: 40 NUM_HEADS=40 # e.g. llama-13b: 40 SEQ_LENGTH=2048 MICRO_BATCH_SIZE=4 GLOBAL_BATCH_SIZE=16 # e.g. llama: 4M tokens TRAIN_STEPS=2500 # e.g. llama: 1T tokens / 4M tokens_per_batch = 250000 steps LR=3e-4 MIN_LR=3e-5 LR_WARMUP_STEPS=2000 WEIGHT_DECAY=0.1 GRAD_CLIP=1 # Below configuration required for llama model as per llama paper # --no-query-key-layer-scaling \ # --attention-dropout 0 \ # --hidden-dropout 0 \ # --use-rotary-position-embeddings \ # --untie-embeddings-and-output-weights \ # --swiglu \ # --normalization rmsnorm \ # --disable-bias-linear \ ###################################### cat < $DS_CONFIG { "train_batch_size" : $GLOBAL_BATCH_SIZE, "train_micro_batch_size_per_gpu": $MICRO_BATCH_SIZE, "steps_per_print": 1, "zero_optimization": { "stage": $ZERO_STAGE }, "fp16": { "enabled": true, "auto_cast": false, "loss_scale": 0, "initial_scale_power": 16, "loss_scale_window": 1000, "hysteresis": 2, "consecutive_hysteresis": false, "min_loss_scale": 1 } } EOT ds_args="" ds_args=" --deepspeed ${ds_args}" ds_args=" --deepspeed_config=$DS_CONFIG ${ds_args}" ds_args=" --zero-stage=$ZERO_STAGE ${ds_args}" ds_args=" --deepspeed-activation-checkpointing ${ds_args}" DISTRIBUTED_ARGS="--nproc_per_node $GPUS_PER_NODE --nnodes $NNODES --node_rank $NODE_RANK --master_addr $MASTER_ADDR --master_port $MASTER_PORT" torchrun $DISTRIBUTED_ARGS \ pretrain_gpt.py \ --tensor-model-parallel-size $TP \ --pipeline-model-parallel-size $PP \ --num-layers $NUM_LAYERS \ --hidden-size $HIDDEN_SIZE \ --ffn-hidden-size $FFN_HIDDEN_SIZE \ --num-attention-heads $NUM_HEADS \ --micro-batch-size $MICRO_BATCH_SIZE \ --global-batch-size $GLOBAL_BATCH_SIZE \ --seq-length $SEQ_LENGTH \ --max-position-embeddings $SEQ_LENGTH \ --train-iters $TRAIN_STEPS \ --save $CHECKPOINT_PATH \ --load $CHECKPOINT_PATH \ --data-path $DATASET \ --data-impl mmap \ --tokenizer-type GPTSentencePieceTokenizer \ --tokenizer-model $TOKENIZER_PATH \ --split 900,50,50 \ --distributed-backend nccl \ --lr $LR \ --lr-decay-style cosine \ --min-lr $MIN_LR \ --weight-decay $WEIGHT_DECAY \ --clip-grad $GRAD_CLIP \ --lr-warmup-iters $LR_WARMUP_STEPS \ --optimizer adam \ --adam-beta1 0.9 \ --adam-beta2 0.95 \ --log-interval 1 \ --save-interval 10000 \ --eval-interval 1000 \ --eval-iters 10 \ --fp16 \ --no-query-key-layer-scaling \ --attention-dropout 0 \ --hidden-dropout 0 \ --use-rotary-position-embeddings \ --untie-embeddings-and-output-weights \ --swiglu \ --normalization rmsnorm \ --disable-bias-linear \ $ds_args ================================================ FILE: llm-train/megatron-deepspeed/microsoft/pretrain_llama_7b_distributed_fp16.sh ================================================ #!/bin/bash # This example script is contributed by external user https://github.com/LydiaXiaohongLi set -ex ###################################### # Change the below configurations here BASE_PATH=./tmp DS_CONFIG=${BASE_PATH}/deepspeed.json DATASET_1="/workspace/data/gpt2-data/my-gpt2_text_document" DATASET_2="/workspace/data/gpt2-data/my-gpt2-1_text_document" DATASET="1 ${DATASET_1} 2 ${DATASET_2}" CHECKPOINT_PATH=./tmp TOKENIZER_PATH=/workspace/model/llama-tokenizer/tokenizer.model # offical llama tokenizer.model TP=2 PP=2 ZERO_STAGE=0 GPUS_PER_NODE=8 MASTER_ADDR=localhost MASTER_PORT=6000 NNODES=1 NODE_RANK=0 HIDDEN_SIZE=4096 # e.g. llama-13b: 5120 FFN_HIDDEN_SIZE=11008 # e.g. llama-13b: 13824 NUM_LAYERS=32 # e.g. llama-13b: 40 NUM_HEADS=32 # e.g. llama-13b: 40 SEQ_LENGTH=2048 MICRO_BATCH_SIZE=4 GLOBAL_BATCH_SIZE=32 # e.g. llama: 4M tokens TRAIN_STEPS=2500 # e.g. llama: 1T tokens / 4M tokens_per_batch = 250000 steps LR=3e-4 MIN_LR=3e-5 LR_WARMUP_STEPS=2000 WEIGHT_DECAY=0.1 GRAD_CLIP=1 # Below configuration required for llama model as per llama paper # --no-query-key-layer-scaling \ # --attention-dropout 0 \ # --hidden-dropout 0 \ # --use-rotary-position-embeddings \ # --untie-embeddings-and-output-weights \ # --swiglu \ # --normalization rmsnorm \ # --disable-bias-linear \ ###################################### cat < $DS_CONFIG { "train_batch_size" : $GLOBAL_BATCH_SIZE, "train_micro_batch_size_per_gpu": $MICRO_BATCH_SIZE, "steps_per_print": 1, "zero_optimization": { "stage": $ZERO_STAGE }, "fp16": { "enabled": true, "auto_cast": false, "loss_scale": 0, "initial_scale_power": 16, "loss_scale_window": 1000, "hysteresis": 2, "consecutive_hysteresis": false, "min_loss_scale": 1 } } EOT ds_args="" ds_args=" --deepspeed ${ds_args}" ds_args=" --deepspeed_config=$DS_CONFIG ${ds_args}" ds_args=" --zero-stage=$ZERO_STAGE ${ds_args}" ds_args=" --deepspeed-activation-checkpointing ${ds_args}" DISTRIBUTED_ARGS="--nproc_per_node $GPUS_PER_NODE --nnodes $NNODES --node_rank $NODE_RANK --master_addr $MASTER_ADDR --master_port $MASTER_PORT" torchrun $DISTRIBUTED_ARGS \ pretrain_gpt.py \ --tensor-model-parallel-size $TP \ --pipeline-model-parallel-size $PP \ --num-layers $NUM_LAYERS \ --hidden-size $HIDDEN_SIZE \ --ffn-hidden-size $FFN_HIDDEN_SIZE \ --num-attention-heads $NUM_HEADS \ --micro-batch-size $MICRO_BATCH_SIZE \ --global-batch-size $GLOBAL_BATCH_SIZE \ --seq-length $SEQ_LENGTH \ --max-position-embeddings $SEQ_LENGTH \ --train-iters $TRAIN_STEPS \ --save $CHECKPOINT_PATH \ --load $CHECKPOINT_PATH \ --data-path $DATASET \ --data-impl mmap \ --tokenizer-type GPTSentencePieceTokenizer \ --tokenizer-model $TOKENIZER_PATH \ --split 900,50,50 \ --distributed-backend nccl \ --lr $LR \ --lr-decay-style cosine \ --min-lr $MIN_LR \ --weight-decay $WEIGHT_DECAY \ --clip-grad $GRAD_CLIP \ --lr-warmup-iters $LR_WARMUP_STEPS \ --optimizer adam \ --adam-beta1 0.9 \ --adam-beta2 0.95 \ --log-interval 1 \ --save-interval 10000 \ --eval-interval 1000 \ --eval-iters 10 \ --fp16 \ --no-query-key-layer-scaling \ --attention-dropout 0 \ --hidden-dropout 0 \ --use-rotary-position-embeddings \ --untie-embeddings-and-output-weights \ --swiglu \ --normalization rmsnorm \ --disable-bias-linear \ $ds_args ================================================ FILE: llm-train/megatron-deepspeed/microsoft/pretrain_llama_distributed_fp16.sh ================================================ #!/bin/bash # This example script is contributed by external user https://github.com/LydiaXiaohongLi set -ex ###################################### # Change the below configurations here BASE_PATH=./tmp DS_CONFIG=${BASE_PATH}/deepspeed.json DATASET_1="/workspace/data/gpt2-data/my-gpt2_text_document" DATASET_2="/workspace/data/gpt2-data/my-gpt2-1_text_document" DATASET="1 ${DATASET_1} 2 ${DATASET_2}" CHECKPOINT_PATH=./tmp TOKENIZER_PATH=/workspace/model/llama-tokenizer/tokenizer.model # offical llama tokenizer.model TP=2 PP=2 ZERO_STAGE=0 GPUS_PER_NODE=8 MASTER_ADDR=localhost MASTER_PORT=6000 NNODES=1 NODE_RANK=0 HIDDEN_SIZE=2048 # e.g. llama-13b: 5120 FFN_HIDDEN_SIZE=5504 # e.g. llama-13b: 13824 NUM_LAYERS=24 # e.g. llama-13b: 40 NUM_HEADS=16 # e.g. llama-13b: 40 SEQ_LENGTH=2048 MICRO_BATCH_SIZE=4 GLOBAL_BATCH_SIZE=32 # e.g. llama: 4M tokens TRAIN_STEPS=2500 # e.g. llama: 1T tokens / 4M tokens_per_batch = 250000 steps LR=3e-4 MIN_LR=3e-5 LR_WARMUP_STEPS=2000 WEIGHT_DECAY=0.1 GRAD_CLIP=1 # Below configuration required for llama model as per llama paper # --no-query-key-layer-scaling \ # --attention-dropout 0 \ # --hidden-dropout 0 \ # --use-rotary-position-embeddings \ # --untie-embeddings-and-output-weights \ # --swiglu \ # --normalization rmsnorm \ # --disable-bias-linear \ ###################################### cat < $DS_CONFIG { "train_batch_size" : $GLOBAL_BATCH_SIZE, "train_micro_batch_size_per_gpu": $MICRO_BATCH_SIZE, "steps_per_print": 1, "zero_optimization": { "stage": $ZERO_STAGE }, "fp16": { "enabled": true, "auto_cast": false, "loss_scale": 0, "initial_scale_power": 16, "loss_scale_window": 1000, "hysteresis": 2, "consecutive_hysteresis": false, "min_loss_scale": 1 } } EOT ds_args="" ds_args=" --deepspeed ${ds_args}" ds_args=" --deepspeed_config=$DS_CONFIG ${ds_args}" ds_args=" --zero-stage=$ZERO_STAGE ${ds_args}" ds_args=" --deepspeed-activation-checkpointing ${ds_args}" DISTRIBUTED_ARGS="--nproc_per_node $GPUS_PER_NODE --nnodes $NNODES --node_rank $NODE_RANK --master_addr $MASTER_ADDR --master_port $MASTER_PORT" torchrun $DISTRIBUTED_ARGS \ pretrain_gpt.py \ --tensor-model-parallel-size $TP \ --pipeline-model-parallel-size $PP \ --num-layers $NUM_LAYERS \ --hidden-size $HIDDEN_SIZE \ --ffn-hidden-size $FFN_HIDDEN_SIZE \ --num-attention-heads $NUM_HEADS \ --micro-batch-size $MICRO_BATCH_SIZE \ --global-batch-size $GLOBAL_BATCH_SIZE \ --seq-length $SEQ_LENGTH \ --max-position-embeddings $SEQ_LENGTH \ --train-iters $TRAIN_STEPS \ --save $CHECKPOINT_PATH \ --load $CHECKPOINT_PATH \ --data-path $DATASET \ --data-impl mmap \ --tokenizer-type GPTSentencePieceTokenizer \ --tokenizer-model $TOKENIZER_PATH \ --split 900,50,50 \ --distributed-backend nccl \ --lr $LR \ --lr-decay-style cosine \ --min-lr $MIN_LR \ --weight-decay $WEIGHT_DECAY \ --clip-grad $GRAD_CLIP \ --lr-warmup-iters $LR_WARMUP_STEPS \ --optimizer adam \ --adam-beta1 0.9 \ --adam-beta2 0.95 \ --log-interval 1 \ --save-interval 10000 \ --eval-interval 1000 \ --eval-iters 10 \ --fp16 \ --no-query-key-layer-scaling \ --attention-dropout 0 \ --hidden-dropout 0 \ --use-rotary-position-embeddings \ --untie-embeddings-and-output-weights \ --swiglu \ --normalization rmsnorm \ --disable-bias-linear \ $ds_args ================================================ FILE: llm-train/megatron-deepspeed/microsoft/slurm/README.md ================================================ ``` srun -p h800-ib-1 --mpi=pmix_v3 -N 2 --gres=gpu:8 env ``` ================================================ FILE: llm-train/megatron-deepspeed/microsoft/slurm/llama-multinode-ib.sh ================================================ #!/bin/bash #SBATCH --job-name=megatron-multinode-ib #作业名称 #SBATCH --partition=h800-ib-2 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.out #日志 #SBATCH -N 2 # 指定机器数量 #SBATCH --gres=gpu:8 #每台机器使用四张卡 #SBATCH -c 80 export NCCL_DEBUG=info export NCCL_IB_DISABLE=0 export NCCL_IB_HCA=mlx5_0 export NCCL_PXN_DISABLE=1 export NCCL_IB_TIMEOUT=22 export NCCL_IB_RETRY_CNT=13 export NCCL_IB_PCI_RELAXED_ORDERING=1 MASTER_HOST=$(scontrol show hostnames "$SLURM_JOB_NODELIST"|head -1) MASTER_ADDR=$(srun --nodes=1 --ntasks=1 -w "$MASTER_HOST" hostname --ip-address|awk '{print $1}') #从中获取一个IP作为通信IP MASTER_PORT=$(expr 10000 + $(echo -n $SLURM_JOBID|tail -c 4)) #master通信端口 echo "$MASTER_HOST --- ""$MASTER_ADDR --- ""$MASTER_PORT" ENDPOINT_URL=$MASTER_HOST:$MASTER_PORT srun --mpi=pmix_v3 singularity run --nv \ --pwd /workspace/code/Megatron-DeepSpeed-llama-20230815 \ -B /data/hpc/home/guodong.li/workspace:/workspace:rw \ megatron-deepspeed-v1.sif \ torchrun --nnodes 2 --nproc-per-node 8 --rdzv-id=$SLURM_JOBID --rdzv-backend=c10d --rdzv-endpoint=$ENDPOINT_URL pretrain_gpt.py --tensor-model-parallel-size 2 --pipeline-model-parallel-size 2 --num-layers 32 --hidden-size 4096 --ffn-hidden-size 11008 --num-attention-heads 32 --micro-batch-size 2 --global-batch-size 32 --seq-length 2048 --max-position-embeddings 2048 --train-iters 1500 --save ./tmp-model-7b --load ./tmp-model-7b --data-path 1 /workspace/data/gpt2-data/my-gpt2_text_document 2 /workspace/data/gpt2-data/my-gpt2-1_text_document --data-impl mmap --tokenizer-type GPTSentencePieceTokenizer --tokenizer-model /workspace/model/llama-tokenizer/tokenizer.model --split 900,50,50 --distributed-backend nccl --lr 3e-4 --lr-decay-style cosine --min-lr 3e-5 --weight-decay 0.1 --clip-grad 1 --lr-warmup-iters 500 --optimizer adam --adam-beta1 0.9 --adam-beta2 0.95 --log-interval 1 --save-interval 10000 --eval-interval 1000 --eval-iters 10 --fp16 --no-query-key-layer-scaling --attention-dropout 0 --hidden-dropout 0 --use-rotary-position-embeddings --untie-embeddings-and-output-weights --swiglu --normalization rmsnorm --disable-bias-linear --deepspeed-activation-checkpointing --zero-stage=0 --deepspeed_config=./tmp/deepspeed.json --deepspeed ================================================ FILE: llm-train/megatron-deepspeed/microsoft/slurm/megatron-deepspeed-multinode-ib-part2-30b-fp16.slurm ================================================ #!/bin/bash #SBATCH --job-name=megatron-multinode-ib-30b-2 #作业名称 #SBATCH --partition=h800-ib-2 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.out #日志 #SBATCH -N 4 # 指定机器数量 #SBATCH -c 80 #SBATCH --gres=gpu:8 #每台机器使用四张卡 export NCCL_DEBUG=info export NCCL_IB_DISABLE=0 export NCCL_IB_HCA=mlx5_0 export NCCL_PXN_DISABLE=1 export NCCL_IB_TIMEOUT=22 export NCCL_IB_RETRY_CNT=13 export NCCL_IB_PCI_RELAXED_ORDERING=1 #export NCCL_IB_DISABLE=1 #export NCCL_SOCKET_IFNAME=bond0 MASTER_HOST=$(scontrol show hostnames "$SLURM_JOB_NODELIST"|head -1) MASTER_ADDR=$(srun --nodes=1 --ntasks=1 -w "$MASTER_HOST" hostname --ip-address|awk '{print $1}') #从中获取一个IP作为通信IP MASTER_PORT=$(expr 10000 + $(echo -n $SLURM_JOBID|tail -c 4)) #master通信端口 ENDPOINT_URL=$MASTER_HOST:$MASTER_PORT echo "$MASTER_HOST --- ""$MASTER_ADDR --- ""$MASTER_PORT" srun --mpi=pmix_v3 singularity run --nv \ --pwd /workspace/code/Megatron-DeepSpeed-llama-20230815 \ -B /data/hpc/home/guodong.li/workspace:/workspace:rw \ megatron-deepspeed-v1.sif \ torchrun --nnodes 4 --nproc_per_node 8 --rdzv_id=$SLURM_JOBID --rdzv_backend=c10d --rdzv_endpoint=$ENDPOINT_URL pretrain_gpt.py --tensor-model-parallel-size 4 --pipeline-model-parallel-size 8 --num-layers 60 --hidden-size 6656 --ffn-hidden-size 17920 --num-attention-heads 52 --micro-batch-size 2 --global-batch-size 8 --seq-length 2048 --max-position-embeddings 2048 --train-iters 1500 --save ./tmp-llama-30b --load ./tmp-llama-30b --data-path 1 /workspace/data/gpt2-data/my-gpt2_text_document 2 /workspace/data/gpt2-data/my-gpt2-1_text_document --data-impl mmap --tokenizer-type GPTSentencePieceTokenizer --tokenizer-model /workspace/model/llama-tokenizer/tokenizer.model --split 900,50,50 --distributed-backend nccl --lr 3e-4 --lr-decay-style cosine --min-lr 3e-5 --weight-decay 0.1 --clip-grad 1 --lr-warmup-iters 500 --optimizer adam --adam-beta1 0.9 --adam-beta2 0.95 --log-interval 1 --save-interval 2000 --eval-interval 1000 --eval-iters 10 --fp16 --no-query-key-layer-scaling --attention-dropout 0 --hidden-dropout 0 --use-rotary-position-embeddings --untie-embeddings-and-output-weights --swiglu --normalization rmsnorm --disable-bias-linear --deepspeed-activation-checkpointing --zero-stage=0 --deepspeed_config=./tmp/deepspeed.json --deepspeed ================================================ FILE: llm-train/megatron-deepspeed/microsoft/slurm/megatron-deepspeed-multinode-ib-part2-65b-fp16.slurm ================================================ #!/bin/bash #SBATCH --job-name=megatron-multinode-ib-30b-2 #作业名称 #SBATCH --partition=h800-ib-2 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.out #日志 #SBATCH -N 8 # 指定机器数量 #SBATCH -c 80 #SBATCH --gres=gpu:8 #每台机器使用四张卡 export NCCL_DEBUG=info #export NCCL_IB_DISABLE=0 #export NCCL_IB_HCA=mlx5_0 #export NCCL_PXN_DISABLE=1 #export NCCL_IB_TIMEOUT=22 #export NCCL_IB_RETRY_CNT=13 #export NCCL_IB_PCI_RELAXED_ORDERING=1 export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 MASTER_HOST=$(scontrol show hostnames "$SLURM_JOB_NODELIST"|head -1) MASTER_ADDR=$(srun --nodes=1 --ntasks=1 -w "$MASTER_HOST" hostname --ip-address|awk '{print $1}') #从中获取一个IP作为通信IP MASTER_PORT=$(expr 10000 + $(echo -n $SLURM_JOBID|tail -c 4)) #master通信端口 ENDPOINT_URL=$MASTER_HOST:$MASTER_PORT echo "$MASTER_HOST --- ""$MASTER_ADDR --- ""$MASTER_PORT" srun --mpi=pmix_v3 singularity run --nv \ --pwd /workspace/code/Megatron-DeepSpeed-llama-20230815 \ -B /data/hpc/home/guodong.li/workspace:/workspace:rw \ megatron-deepspeed-v4-gcc.sif \ torchrun --nnodes 8 --nproc_per_node 8 --rdzv_id=$SLURM_JOBID --rdzv_backend=c10d --rdzv_endpoint=$ENDPOINT_URL pretrain_gpt.py --tensor-model-parallel-size 16 --pipeline-model-parallel-size 4 --num-layers 80 --hidden-size 8192 --ffn-hidden-size 22016 --num-attention-heads 64 --micro-batch-size 1 --global-batch-size 8 --seq-length 2048 --max-position-embeddings 2048 --train-iters 1500 --save ./tmp-llama-65b --load ./tmp-llama-65b --data-path 1 /workspace/data/gpt2-data/my-gpt2_text_document 2 /workspace/data/gpt2-data/my-gpt2-1_text_document --data-impl mmap --tokenizer-type GPTSentencePieceTokenizer --tokenizer-model /workspace/model/llama-tokenizer/tokenizer.model --split 900,50,50 --distributed-backend nccl --lr 3e-4 --lr-decay-style cosine --min-lr 3e-5 --weight-decay 0.1 --clip-grad 1 --lr-warmup-iters 500 --optimizer adam --adam-beta1 0.9 --adam-beta2 0.95 --log-interval 1 --save-interval 2000 --eval-interval 1000 --eval-iters 10 --fp16 --no-query-key-layer-scaling --attention-dropout 0 --hidden-dropout 0 --use-rotary-position-embeddings --untie-embeddings-and-output-weights --swiglu --normalization rmsnorm --disable-bias-linear --deepspeed-activation-checkpointing --zero-stage=0 --deepspeed_config=./tmp/deepspeed.json --deepspeed ================================================ FILE: llm-train/megatron-deepspeed/microsoft/代码.md ================================================ ``` from deepspeed.accelerator import get_accelerator get_accelerator().device_name() == 'cuda': ``` ================================================ FILE: llm-train/megatron-deepspeed/microsoft/环境准备.md ================================================ ``` docker run -it --gpus all --network=host \ --shm-size 4G \ -v /data/hpc/home/guodong.li/:/workspaces \ -w /workspace/stanford_alpaca/ \ harbor.aip.io/base/pytorch:2.0.1-py310-11.8-cudnn8-devel-centos7 \ /bin/bash yum install ninja-build yum install which yum -y install devtoolset-9 source /opt/rh/devtoolset-9/enable apex pip install sentencepiece pip install transformers pip install deepspeed pip install einops==0.6.1 yum install git pip install flash-attn==1.0.4 pip install pybind11 yum -y install libibverbs docker commit -m="megatron-deepspeed" -a="liguodong" 8bcb92d326cb harbor.maip.io/base/megatron-deepspeed:v2 docker run -it --gpus all --network=host \ --shm-size 16G \ -v /data/hpc/home/guodong.li/workspace:/workspace \ -w /workspace/code/Megatron-DeepSpeed-llama-20230815 \ harbor.aip.io/base/megatron-deepspeed:v2 \ /bin/bash ``` - docker环境变量配置不生效/ect/profile的解决方法: https://www.jb51.net/server/2960751gz.htm ## 本地 ``` conda create -n megatron-deepspeed-venv python=3.9 -y pip install torch pip install numpy pip install py-cpuinfo pip install psutil sudo pip install deepspeed ``` ================================================ FILE: llm-train/megatron-deepspeed/microsoft/训练日志分析.md ================================================ ## fp16 `megatron/training.py` 日志: ``` FusedAdam ( Parameter Group 0 betas: (0.9, 0.95) bias_correction: True eps: 1e-08 lr: 0.0 lr_mult: 1.0 name: wd_no_scale_lr step: 1 wd_mult: 1.0 weight_decay: 0.1 Parameter Group 1 betas: (0.9, 0.95) bias_correction: True eps: 1e-08 lr: 0.0 lr_mult: 1.0 name: no_wd_no_scale_lr step: 1 wd_mult: 0.0 weight_decay: 0.0 ) ``` ================================================ FILE: llm-train/megatron-deepspeed/microsoft/项目结构-202312228.md ================================================ ``` . ├── CODEOWNERS ├── LICENSE ├── MANIFEST.in ├── README.md ├── SECURITY.md ├── dataset │   ├── README.md │   ├── download_books.sh │   ├── download_ckpt.sh │   └── download_vocab.sh ├── docs │   ├── distrib_optimizer.md │   └── images │   └── distrib_optimizer │   ├── data_flow.png │   └── sharding_scheme.png ├── examples │   ├── README.md │   ├── detxoify_lm │   │   ├── README.md │   │   ├── annotations │   │   │   ├── filter-selfgeneration.py │   │   │   ├── perspective_api_annotate.py │   │   │   └── preprocess.sh │   │   ├── finetune_gpt.py │   │   ├── finetune_gpt_distributed-1.3b.sh │   │   ├── generate-1.3b.sh │   │   ├── generate_samples_gpt.py │   │   ├── perspective_api.py │   │   └── self_generation │   │   └── selfgenerate-1.3b-unconditional.sh │   ├── evaluate_retriever_nq.sh │   ├── evaluate_zeroshot_gpt.sh │   ├── finetune_mnli_distributed.sh │   ├── finetune_race_distributed.sh │   ├── finetune_retriever_distributed.sh │   ├── merge_mp_bert.sh │   ├── msdp │   │   ├── README.md │   │   ├── data_processing.sh │   │   ├── eval_knwl_generation.sh │   │   ├── eval_resp_generation.sh │   │   ├── prep_resp_gen.sh │   │   ├── prompt_knwl_gen.sh │   │   └── prompt_resp_gen.sh │   ├── pretrain_bert.sh │   ├── pretrain_bert_distributed.sh │   ├── pretrain_bert_distributed_with_mp.sh │   ├── pretrain_gpt.sh │   ├── pretrain_gpt3_175B.sh │   ├── pretrain_gpt_distributed.sh │   ├── pretrain_gpt_distributed_with_mp.sh │   ├── pretrain_ict.sh │   ├── pretrain_t5.sh │   ├── pretrain_t5_distributed.sh │   ├── pretrain_t5_distributed_with_mp.sh │   ├── run_text_generation_server_345M.sh │   ├── run_text_generation_server_345M_8_tensor_parallel.sh │   └── sc21 │   ├── CONFIG.sh │   ├── README.md │   ├── SBATCH.sh │   ├── SRUN.sh │   ├── run_figure_11.sh │   ├── run_figure_12.sh │   ├── run_figure_13.sh │   ├── run_figure_14.sh │   ├── run_figure_15.sh │   ├── run_figure_16.sh │   ├── run_figure_17.sh │   ├── run_figure_18.sh │   └── run_table_1.sh ├── examples_deepspeed │   ├── MoE │   │   ├── ds_config_gpt_TEMPLATE.json │   │   ├── ds_config_gpt_Zero2_TEMPLATE.json │   │   ├── ds_evalharness.sh │   │   ├── ds_pretrain_gpt_1.3B_MoE128.sh │   │   ├── ds_pretrain_gpt_1.3B_PR-MoE64or128.sh │   │   ├── ds_pretrain_gpt_1.3B_PR-MoE64or128_MoS.sh │   │   ├── ds_pretrain_gpt_1.3B_dense.sh │   │   ├── ds_pretrain_gpt_1.3B_dense_cl.sh │   │   ├── ds_pretrain_gpt_125M_MoE64.sh │   │   ├── ds_pretrain_gpt_125M_dense_cl.sh │   │   ├── ds_pretrain_gpt_350M_MoE128.sh │   │   ├── ds_pretrain_gpt_350M_PR-MoE32or64.sh │   │   ├── ds_pretrain_gpt_350M_PR-MoE32or64_MoS.sh │   │   ├── ds_pretrain_gpt_350M_dense.sh │   │   ├── ds_pretrain_gpt_6.7B_dense.sh │   │   └── readme_evalharness.md │   ├── README.md │   ├── azure │   │   ├── README.md │   │   ├── run-175b.sh │   │   ├── run-1t.sh │   │   └── run-benchmark-model.sh │   ├── azureml │   │   ├── Dockerfile.dockerfile │   │   ├── README.md │   │   ├── aml_submit.py │   │   └── prepare_dataset.py │   ├── bert_with_pile │   │   ├── README.md │   │   ├── ds_config_bert_TEMPLATE.json │   │   ├── ds_finetune_bert_mnli.sh │   │   ├── ds_finetune_bert_qqp.sh │   │   ├── ds_finetune_bert_race.sh │   │   ├── ds_pretrain_bert.sh │   │   └── prepare_pile_data.py │   ├── compression │   │   ├── 125M-Int8-test-64gpu-distilled-group48.sh │   │   ├── 125M-L10-Int8-test-64gpu-distilled-group48.sh │   │   ├── 125M-L12-Int8-test-64gpu-distilled-group48.sh │   │   ├── ds_config_gpt_TEMPLATE.json │   │   ├── ds_config_gpt_TEMPLATE_compression.json │   │   ├── ds_evalharness.sh │   │   ├── ds_pretrain_gpt_1.3B_dense_cl_kd.sh │   │   ├── ds_pretrain_gpt_125M_dense_cl_kd.sh │   │   ├── ds_pretrain_gpt_125M_dense_kd.sh │   │   └── ds_pretrain_gpt_350M_dense_kd.sh │   ├── curriculum_learning │   │   ├── README.md │   │   ├── ds_config_gpt_slw_TEMPLATE.json │   │   ├── ds_pretrain_gpt2.sh │   │   ├── ds_pretrain_gpt_1.3B_rope_slw.sh │   │   ├── ds_train.sh │   │   ├── ds_zero_stage_1_config_baseline.json │   │   └── ds_zero_stage_1_config_curriculum_fixed_linear.json │   ├── data_efficiency │   │   ├── README.md │   │   ├── analyze_data.py │   │   ├── bert │   │   │   ├── ds_analyze_bert_data_map.sh │   │   │   ├── ds_analyze_bert_data_reduce.sh │   │   │   ├── finetune │   │   │   │   ├── ds_config_bert_TEMPLATE.json │   │   │   │   ├── ds_finetune_bert_mnli.sh │   │   │   │   ├── ds_finetune_bert_qqp.sh │   │   │   │   ├── ds_finetune_bert_race.sh │   │   │   │   └── ds_finetune_gather_result.py │   │   │   ├── finetune_glue │   │   │   │   ├── ds_config_bert_TEMPLATE.json │   │   │   │   ├── ds_finetune_bert_glue.sh │   │   │   │   ├── ds_finetune_bert_glue_run.sh │   │   │   │   └── ds_finetune_gather_result.py │   │   │   ├── pile_data_download_preprocess.py │   │   │   └── pretrain │   │   │   ├── ds_config_bert_1clmetric_TEMPLATE.json │   │   │   ├── ds_config_bert_2clmetrics_TEMPLATE.json │   │   │   ├── ds_pretrain_bert_336M_base_script.sh │   │   │   └── ds_pretrain_bert_336M_run.sh │   │   └── gpt │   │   ├── ds_analyze_gpt_data_map.sh │   │   ├── ds_analyze_gpt_data_reduce.sh │   │   ├── eval │   │   │   ├── ds_config_eval_dummy.json │   │   │   ├── ds_evalharness_1gpu.sh │   │   │   ├── ds_evalharness_gather_result.py │   │   │   ├── ds_evalharness_parallel_run.sh │   │   │   └── ds_evalharness_parallel_run_10shot.sh │   │   └── pretrain │   │   ├── ds_config_gpt_1clmetric_TEMPLATE.json │   │   ├── ds_config_gpt_2clmetrics_TEMPLATE.json │   │   ├── ds_pretrain_gpt_1.3B_dense_base_script.sh │   │   └── ds_pretrain_gpt_1.3B_dense_run.sh │   ├── deepspeed4science │   │   └── megatron_long_seq_support │   │   ├── README.md │   │   ├── ds_config_gpt_TEMPLATE.json │   │   ├── host_file │   │   ├── pretrain_gpt_1.3B_seq_parallel.sh │   │   └── pretrain_gpt_30B_seq_parallel.sh │   ├── generate_text.sh │   ├── offload_pp │   │   ├── README.md │   │   ├── ds_config_gpt_TEMPLATE.json │   │   ├── ds_pretrain_gpt_350M.sh │   │   └── twin-offload.png │   ├── pretrain_llama2_distributed.sh │   ├── pretrain_llama_distributed.sh │   ├── rebase │   │   ├── README.md │   │   ├── ds_config_gpt_TEMPLATE.json │   │   ├── ds_config_gpt_slw_TEMPLATE.json │   │   ├── ds_pretrain_gpt_1.3B.sh │   │   ├── ds_pretrain_gpt_1.3B_megatron_checkpointing.sh │   │   ├── ds_pretrain_gpt_1.3B_rope.sh │   │   ├── ds_pretrain_gpt_1.3B_rope_slw.sh │   │   ├── ds_pretrain_gpt_125M.sh │   │   ├── ds_pretrain_gpt_125M_flashattn.sh │   │   └── ds_pretrain_gpt_13B.sh │   ├── run_deepspeed_example.sh │   ├── sequence_parallel │   │   ├── README.md │   │   ├── ds_config_gpt_TEMPLATE.json │   │   ├── ds_pretrain_gpt_1.3B_seq_parallel_32k.sh │   │   └── ds_pretrain_gpt_30B_seq_parallel_32k.sh │   └── universal_checkpointing │   ├── README.md │   ├── ds_config.json │   ├── run_bf16.sh │   ├── run_fp16.sh │   ├── run_universal_bf16.sh │   └── run_universal_fp16.sh ├── images │   ├── Achieved_petaFLOPs.png │   └── cases_april2021.png ├── megatron │   ├── __init__.py │   ├── arguments.py │   ├── checkpointing.py │   ├── core │   │   ├── README.md │   │   ├── __init__.py │   │   ├── enums.py │   │   ├── fusions │   │   │   ├── __init__.py │   │   │   ├── fused_bias_dropout.py │   │   │   ├── fused_bias_gelu.py │   │   │   ├── fused_layer_norm.py │   │   │   └── fused_softmax.py │   │   ├── model_parallel_config.py │   │   ├── models │   │   │   ├── __init__.py │   │   │   └── gpt │   │   │   ├── __init__.py │   │   │   ├── gpt_embedding.py │   │   │   └── gpt_model.py │   │   ├── package_info.py │   │   ├── parallel_state.py │   │   ├── pipeline_parallel │   │   │   ├── __init__.py │   │   │   ├── p2p_communication.py │   │   │   └── schedules.py │   │   ├── requirements.txt │   │   ├── sequence_parallel │   │   │   ├── __init__.py │   │   │   └── cross_entropy.py │   │   ├── tensor_parallel │   │   │   ├── __init__.py │   │   │   ├── cross_entropy.py │   │   │   ├── data.py │   │   │   ├── layers.py │   │   │   ├── mappings.py │   │   │   ├── random.py │   │   │   └── utils.py │   │   ├── transformer │   │   │   ├── __init__.py │   │   │   ├── attention.py │   │   │   ├── core_attention.py │   │   │   ├── custom_layers │   │   │   │   └── transformer_engine.py │   │   │   ├── enums.py │   │   │   ├── mlp.py │   │   │   ├── module.py │   │   │   ├── transformer_block.py │   │   │   ├── transformer_config.py │   │   │   ├── transformer_layer.py │   │   │   └── utils.py │   │   └── utils.py │   ├── data │   │   ├── Makefile │   │   ├── __init__.py │   │   ├── autoaugment.py │   │   ├── bert_dataset.py │   │   ├── biencoder_dataset_utils.py │   │   ├── blendable_dataset.py │   │   ├── data_samplers.py │   │   ├── dataset_utils.py │   │   ├── gpt_dataset.py ### build_train_valid_test_datasets 构建训练校验测试集 │   │   ├── helpers.cpp │   │   ├── ict_dataset.py │   │   ├── image_folder.py │   │   ├── indexed_dataset.py │   │   ├── orqa_wiki_dataset.py │   │   ├── realm_dataset_utils.py │   │   ├── realm_index.py │   │   ├── t5_dataset.py │   │   ├── test │   │   │   ├── test_indexed_dataset.py │   │   │   └── test_preprocess_data.sh │   │   └── vit_dataset.py │   ├── dist_signal_handler.py │   ├── enums.py │   ├── fp16_deprecated │   │   └── loss_scaler.py │   ├── fused_kernels │   │   ├── __init__.py │   │   ├── compat.h │   │   ├── scaled_masked_softmax.cpp │   │   ├── scaled_masked_softmax.h │   │   ├── scaled_masked_softmax_cuda.cu │   │   ├── scaled_softmax.cpp │   │   ├── scaled_softmax_cuda.cu │   │   ├── scaled_upper_triang_masked_softmax.cpp │   │   ├── scaled_upper_triang_masked_softmax.h │   │   ├── scaled_upper_triang_masked_softmax_cuda.cu │   │   ├── tests │   │   │   ├── __init__.py │   │   │   └── test_fused_kernels.py │   │   └── type_shim.h │   ├── global_vars.py │   ├── indexer.py │   ├── initialize.py │   ├── memory.py │   ├── microbatches.py │   ├── model │   │   ├── __init__.py │   │   ├── bert_model.py │   │   ├── biencoder_model.py │   │   ├── classification.py │   │   ├── distributed.py │   │   ├── enums.py │   │   ├── fused_bias_gelu.py │   │   ├── fused_layer_norm.py │   │   ├── fused_softmax.py │   │   ├── gpt_model.py │   │   ├── language_model.py │   │   ├── module.py │   │   ├── multiple_choice.py │   │   ├── realm_model.py │   │   ├── rmsnorm.py │   │   ├── rotary_pos_embedding.py │   │   ├── t5_model.py │   │   ├── transformer.py │   │   ├── utils.py │   │   └── vision │   │   ├── __init__.py │   │   ├── classification.py │   │   ├── dino.py │   │   ├── esvit_swin_backbone.py │   │   ├── inpainting.py │   │   ├── knn_monitor.py │   │   ├── mit_backbone.py │   │   ├── swin_backbone.py │   │   ├── utils.py │   │   └── vit_backbone.py │   ├── mpu │   │   └── tests │   │   ├── __init__.py │   │   ├── commons.py │   │   ├── test_cross_entropy.py │   │   ├── test_data.py │   │   ├── test_initialize.py │   │   ├── test_layers.py │   │   └── test_random.py │   ├── optimizer │   │   ├── __init__.py │   │   ├── clip_grads.py │   │   ├── distrib_optimizer.py │   │   ├── grad_scaler.py │   │   └── optimizer.py │   ├── optimizer_param_scheduler.py ### OptimizerParamScheduler 学习率衰减和权重衰减 incr 函数。 │   ├── p2p_communication.py │   ├── static │   │   └── index.html │   ├── text_generation │   │   ├── __init__.py │   │   ├── api.py │   │   ├── beam_utils.py │   │   ├── communication.py │   │   ├── forward_step.py │   │   ├── generation.py │   │   ├── sampling.py │   │   └── tokenization.py │   ├── text_generation_server.py │   ├── text_generation_utils.py │   ├── timers.py │   ├── tokenizer │   │   ├── __init__.py │   │   ├── bert_tokenization.py │   │   ├── gpt2_tokenization.py │   │   └── tokenizer.py │   ├── training.py ### pretrain(): 训练主函数 │   └── utils.py ├── pretrain_bert.py ├── pretrain_gpt.py ### train_valid_test_datasets_provider : 构建训练测试校验数据集 ### model_provider:根据流水线并行度和张量并行度构建模型 ### git_ds_info():打印megatron代码及分支 ├── pretrain_gpt_core.py ├── pretrain_ict.py ├── pretrain_retro.py ├── pretrain_t5.py ├── pretrain_vision_classify.py ├── pretrain_vision_dino.py ├── pretrain_vision_inpaint.py ├── setup.py ├── tasks │   ├── data_utils.py │   ├── ensemble_classifier.py │   ├── eval_harness │   │   ├── download.py │   │   ├── evaluate.py │   │   └── report-to-csv.py │   ├── eval_utils.py │   ├── finetune_utils.py │   ├── glue │   │   ├── cola.py │   │   ├── data.py │   │   ├── finetune.py │   │   ├── mnli.py │   │   ├── mrpc.py │   │   ├── qnli.py │   │   ├── qqp.py │   │   ├── rte.py │   │   ├── sst2.py │   │   └── stsb.py │   ├── main.py │   ├── msdp │   │   ├── README.md │   │   ├── evaluate.py │   │   ├── main.py │   │   ├── metrics.py │   │   ├── preprocessing.py │   │   └── prompt.py │   ├── orqa │   │   ├── README.md │   │   ├── evaluate_orqa.py │   │   ├── evaluate_utils.py │   │   ├── supervised │   │   │   ├── data.py │   │   │   ├── eval_utils.py │   │   │   └── finetune.py │   │   └── unsupervised │   │   ├── nq.py │   │   ├── qa_utils.py │   │   └── tokenizers.py │   ├── race │   │   ├── data.py │   │   └── finetune.py │   ├── vision │   │   ├── classification │   │   │   ├── classification.py │   │   │   └── eval_utils.py │   │   ├── finetune_utils.py │   │   ├── main.py │   │   └── segmentation │   │   ├── cityscapes.py │   │   ├── data.py │   │   ├── finetune_segformer.py │   │   ├── finetune_setr.py │   │   ├── metrics.py │   │   ├── seg_heads.py │   │   ├── seg_models.py │   │   ├── transforms.py │   │   └── utils.py │   └── zeroshot_gpt │   ├── datasets.py │   ├── detokenizer.py │   └── evaluate.py ├── tests │   ├── __init__.py │   ├── conftest.py │   ├── functional_tests │   │   ├── __init__.py │   │   ├── python_test_utils │   │   │   ├── __init__.py │   │   │   ├── check_slurm_job_completion.py │   │   │   ├── get_test_results_from_tensorboard_logs.py │   │   │   ├── test_ci_pipeline.py │   │   │   └── test_resume_checkpoint_pipeline.py │   │   ├── shell_test_utils │   │   │   └── jobwait.sh │   │   ├── test_results │   │   │   ├── bert │   │   │   │   ├── bert_tp1_pp2_1nodes_50steps.json │   │   │   │   ├── bert_tp1_pp4_1nodes_50steps.json │   │   │   │   ├── bert_tp2_pp2_1nodes_50steps.json │   │   │   │   └── bert_tp4_pp1_1nodes_50steps.json │   │   │   └── gpt3 │   │   │   ├── gpt3_tp1_pp2_1nodes_50steps.json │   │   │   ├── gpt3_tp1_pp4_1nodes_50steps.json │   │   │   ├── gpt3_tp2_pp2_1nodes_50steps.json │   │   │   └── gpt3_tp4_pp1_1nodes_50steps.json │   │   └── test_scripts │   │   ├── bert │   │   │   ├── pretrain_bert_distributed_resume_checkpoint_test.sh │   │   │   ├── pretrain_bert_distributed_test.sh │   │   │   ├── sbatch_bert_distributed_resume_checkpoint_test.sh │   │   │   └── sbatch_bert_distributed_test.sh │   │   └── gpt3 │   │   ├── pretrain_gpt3_distributed_resume_checkpoint_test.sh │   │   ├── pretrain_gpt3_distributed_test.sh │   │   ├── sbatch_gpt3_distributed_resume_checkpoint_test.sh │   │   └── sbatch_gpt3_distributed_test.sh │   ├── models │   │   ├── __init__.py │   │   ├── test_gpt_embedding.py │   │   └── test_gpt_model.py │   ├── pipeline_parallel │   │   ├── __init__.py │   │   └── test_schedules.py │   ├── run_megatron.py │   ├── tensor_parallel │   │   └── __int__.py │   ├── test_megatron.py │   ├── transformer │   │   ├── __init__.py │   │   ├── test_core_attention.py │   │   ├── test_module.py │   │   ├── test_parallel_attention.py │   │   ├── test_parallel_mlp.py │   │   ├── test_parallel_transformer_block.py │   │   ├── test_parallel_transformer_layer.py │   │   └── test_transformer_config.py │   └── unit_tests │   ├── __init__.py │   ├── tensor_parallel │   │   ├── test_cross_entropy.py │   │   ├── test_data.py │   │   ├── test_mappings.py │   │   ├── test_random.py │   │   └── test_tensor_parallel_utils.py │   ├── test_basic.py │   ├── test_parallel_state.py │   ├── test_utilities.py │   └── test_utils.py └── tools ├── __init__.py ├── bert_embedding │   ├── __init__.py │   ├── dataset.py │   ├── embed.py │   ├── external_libs.py │   ├── huggingface.py │   └── utils.py ├── checkpoint_loader_megatron.py ├── checkpoint_saver_megatron.py ├── checkpoint_util.py ├── convert_checkpoint │   ├── README.md │   ├── deepspeed_checkpoint.py │   ├── deepspeed_to_megatron.py │   ├── deepspeed_to_transformers.py │   ├── inspect_checkpoint.py │   └── inspect_deepspeed_checkpoint.py ├── generate_samples_gpt.py ├── linter.py ├── merge_datasets.py ├── openwebtext │   ├── README.md │   ├── add_id.py │   ├── blacklist_urls.py │   ├── cleanup_dataset.py │   ├── cleanup_fix_dataset.py │   ├── filter_ngrams.py │   ├── find_duplicates.py │   ├── group_duplicate_url.py │   ├── merge_jsons.py │   └── remove_group_duplicates.py ├── preprocess_data.py ├── preprocess_data_nmt.py ├── retro │   ├── README.md │   ├── __init__.py │   ├── cli │   │   ├── __init__.py │   │   ├── __main__.py │   │   └── cli.py │   ├── db │   │   ├── __init__.py │   │   ├── build.py │   │   ├── dataset.py │   │   └── utils.py │   ├── examples │   │   ├── get_dataset_configs.sh │   │   ├── get_preprocess_cmd.sh │   │   ├── preprocess_data.sh │   │   └── pretrain_model.sh │   ├── external_libs.py │   ├── index │   │   ├── __init__.py │   │   ├── build.py │   │   ├── factory.py │   │   ├── index.py │   │   ├── indexes │   │   │   ├── __init__.py │   │   │   ├── faiss_base.py │   │   │   └── faiss_par_add.py │   │   └── utils.py │   ├── main.py │   ├── query │   │   ├── __init__.py │   │   ├── chunk_dataset.py │   │   ├── query.py │   │   ├── retro_dataset.py │   │   └── utils.py │   └── utils.py ├── run_text_generation_server.py └── text_generation_cli.py ``` ================================================ FILE: llm-train/megatron-deepspeed/source-code.md ================================================ ``` build_train_valid_test_datasets 单数据集 _build_train_valid_test_datasets 多数据集 ``` ================================================ FILE: llm-train/paddle/README.md ================================================ ``` nvidia-docker pull registry.baidubce.com/paddlepaddle/paddle:2.5.1-gpu-cuda11.7-cudnn8.4-trt8.4 docker run -dt \ --name paddle \ --restart=always \ --gpus all \ --network=host \ --shm-size 4G \ -v /home/guodong.li/workspace:/paddle \ registry.baidubce.com/paddlepaddle/paddle:2.5.1-gpu-cuda11.7-cudnn8.4-trt8.4 \ /bin/bash ``` ``` docker exec -it paddle bash ``` ``` sudo docker run -it --rm \ --gpus all \ --network=host \ --shm-size 4G \ -v /home/guodong.li/workspace:/workspace \ registry.baidubce.com/paddlepaddle/paddle:2.5.1-gpu-cuda11.7-cudnn8.4-trt8.4 \ /bin/bash ``` CUDA 工具包 11.7 配合 cuDNN v8.4.1, 如需使用 PaddleTensorRT 推理,需配合 TensorRT8.4.2.4 如需使用分布式多卡环境,需配合 NCCL>=2.7 GPU 运算能力超过 3.5 的硬件设备 ``` conda create -n paddle python=3.8 -y conda activate paddle ``` ``` python -m pip install paddlepaddle-gpu==2.5.1.post117 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html ``` ``` import paddle paddle.utils.run_check() ``` ``` python3 -m pip uninstall paddlepaddle-gpu ``` --- ## 安装develop版本 ``` python -m pip install paddlepaddle==0.0.0 -f https://www.paddlepaddle.org.cn/whl/linux/cpu-mkl/develop.html python -m pip install paddlepaddle==0.0.0 -f https://www.paddlepaddle.org.cn/whl/mac/cpu/develop.html pip install --pre --upgrade paddlenlp -f https://www.paddlepaddle.org.cn/whl/paddlenlp.html sudo pip install --pre --upgrade paddlenlp -f https://www.paddlepaddle.org.cn/whl/paddlenlp.html ``` ================================================ FILE: llm-train/paddle/paddlenlp/README.md ================================================ ## PaddleNLP - https://hub.docker.com/r/paddlecloud/paddlenlp - https://github.com/PaddlePaddle/PaddleNLP/tree/develop/llm - pytorch转paddle: https://github.com/PaddlePaddle/PaddleNLP/blob/v2.6.1/docs/community/contribute_models/convert_pytorch_to_paddle.rst ``` pip install --upgrade paddlenlp==2.6.1 -i https://pypi.org/simple sudo pip install --pre --upgrade paddlenlp -f https://www.paddlepaddle.org.cn/whl/paddlenlp.html ``` ``` docker run --name dev \ --runtime=nvidia \ -v $PWD:/mnt \ -p 8888:8888 \ -it \ paddlecloud/paddlenlp:develop-gpu-cuda10.2-cudnn7-cdd682 \ /bin/bash ``` --- ## 支持的模型 ``` bigscience/bloom-560m bigscience/bloomz-560m/ ``` ### bloom ``` https://bj.bcebos.com/paddlenlp/models/community/bigscience/bloomz-560m/tokenizer_config.json ``` ``` from paddlenlp.transformers.bloom.tokenizer import BloomTokenizer tokenizer = BloomTokenizer.from_pretrained("bigscience/bloomz-560m") ``` ## 推理 ``` import paddlenlp from pprint import pprint from paddlenlp import Taskflow schema = ['时间', '选手', '赛事名称'] # Define the schema for entity extraction ie = Taskflow('information_extraction', schema=schema) pprint(ie("2月8日上午北京冬奥会自由式滑雪女子大跳台决赛中中国选手谷爱凌以188.25分获得金牌!")) ``` ``` https://bj.bcebos.com/paddlenlp/taskflow/information_extraction/uie_base_v1.1/model_state.pdparams /Users/liguodong/.paddlenlp/taskflow/information_extraction/uie-base/model_state.pdparams ``` --- ``` from paddlenlp.transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("bigscience/bloomz-560m") model = AutoModelForCausalLM.from_pretrained("bigscience/bloomz-560m", dtype="float32") input_features = tokenizer("你好!请自我介绍一下。", return_tensors="pd") outputs = model.generate(**input_features, max_length=128) tokenizer.batch_decode(outputs[0]) tokenizer = AutoTokenizer.from_pretrained("bigscience/bloom-560m", from_hf_hub=True) tokenizer = AutoTokenizer.from_pretrained("ziqingyang/chinese-llama-7b", from_hf_hub=True) model = AutoModelForCausalLM.from_pretrained("bigscience/bloom-560m", dtype="float32",from_aistudio = False, from_hf_hub=True, convert_from_torch=True) tokenizer = AutoTokenizer.from_pretrained("bigscience/bloom-560m", from_hf_hub=True) ``` ### 动态图推理 ``` # 预训练&SFT动态图模型推理 python predictor.py \ --model_name_or_path meta-llama/Llama-2-7b-chat \ --batch_size 1 \ --data_file ./data/dev.json \ --dtype "float16" \ --mode "dynamic" ``` ### 静态图推理 ``` # 首先需要运行一下命令将动态图导出为静态图 # LoRA需要先合并参数,详见3.7LoRA参数合并 # Prefix Tuning暂不支持 python export_model.py \ --model_name_or_path meta-llama/Llama-2-7b-chat \ --output_path ./inference \ --dtype float16 # 静态图模型推理 python predictor.py \ --model_name_or_path inference \ --batch_size 1 \ --data_file ./data/dev.json \ --dtype "float16" \ --mode "static" ``` ## Flask & Gradio UI服务化部署 ``` python -m paddle.distributed.launch --gpus "0,1,2,3,4,5,6,7" flask_server.py \ --model_name_or_path meta-llama/Llama-2-7b-chat \ --port 8010 \ --flask_port 8011 \ --src_length 1024 \ --dtype "float16" ``` ## 量化 量化算法可以将模型权重和激活转为更低比特数值类型表示,能够有效减少显存占用和计算开销。 下面我们提供GPTQ和PaddleSlim自研的PTQ策略,分别实现WINT4和W8A8量化。 - https://github.com/PaddlePaddle/PaddleSlim/blob/develop/docs/zh_cn/tutorials/quant/advanced_quantization.md ``` https://www.paddlepaddle.org.cn/whl/linux/gpu/develop.html python -m pip install paddlepaddle-gpu==0.0.0.post117 -f https://www.paddlepaddle.org.cn/whl/linux/gpu/develop.html 安装发布版本: pip install paddleslim 安装develop版本: git clone https://github.com/PaddlePaddle/PaddleSlim.git & cd PaddleSlim python setup.py install 验证安装:安装完成后您可以使用 python 或 python3 进入 python 解释器,输入import paddleslim, 没有报错则说明安装成功。 ``` ``` # PTQ 量化 python finetune_generation.py ./llama/ptq_argument.json # GPTQ 量化 python finetune_generation.py ./llama/gptq_argument.json ``` ================================================ FILE: llm-train/paddle/paddlenlp/baichuan2/README.md ================================================ ``` from paddlenlp.transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("baichuan-inc/Baichuan2-7B-Base") model = AutoModelForCausalLM.from_pretrained("baichuan-inc/Baichuan2-7B-Base", dtype="float16") ``` ================================================ FILE: llm-train/paddle/paddlenlp/bloom/README.md ================================================ ``` cd /home/guodong.li/virtual-venv virtualenv -p /usr/bin/python3.10 paddle-venv-py310-cu117 source /home/guodong.li/virtual-venv/paddle-venv-py310-cu117/bin/activate ``` ``` from paddlenlp.transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("bigscience/bloomz-560m") model = AutoModelForCausalLM.from_pretrained("bigscience/bloomz-560m", dtype="float16") from paddlenlp.transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("/home/guodong.li/.paddlenlp/models/bigscience/bloomz-560m") model = AutoModelForCausalLM.from_pretrained("/home/guodong.li/.paddlenlp/models/bigscience/bloomz-560m", dtype="float16") input_features = tokenizer("hi, my name is", return_tensors="pd") outputs = model.generate(**input_features, max_length=128) tokenizer.batch_decode(outputs[0]) ``` ``` python -u -m paddle.distributed.launch --gpus "0,1,2,3" finetune_generation.py ./bloom/sft_argument.json ``` ================================================ FILE: llm-train/paddle/paddlenlp/bloom/sft_argument.json ================================================ { "model_name_or_path": "/home/guodong.li/.paddlenlp/models/bigscience/bloomz-560m", "dataset_name_or_path": "/home/guodong.li/workspace/data/AdvertiseGen", "output_dir": "./checkpoints/bloom_sft_ckpts", "per_device_train_batch_size": 100, "gradient_accumulation_steps": 100, "per_device_eval_batch_size": 8, "eval_accumulation_steps":16, "num_train_epochs": 3, "learning_rate": 3e-05, "warmup_steps": 30, "logging_steps": 1, "evaluation_strategy": "epoch", "save_strategy": "epoch", "src_length": 1024, "max_length": 2048, "fp16": true, "fp16_opt_level": "O2", "do_train": true, "do_eval": true, "disable_tqdm": true, "load_best_model_at_end": true, "eval_with_do_generation": false, "metric_for_best_model": "accuracy", "recompute": true, "save_total_limit": 1, "tensor_parallel_degree": 4, "pipeline_parallel_degree": 1 } ================================================ FILE: llm-train/peft/LoRA-QLoRA.md ================================================ - LORA: https://github.com/baichuan-inc/Baichuan2/blob/main/fine-tune/fine-tune.py ``` from peft import LoraConfig, TaskType, get_peft_model peft_config = LoraConfig( task_type=TaskType.CAUSAL_LM, target_modules=["W_pack"], inference_mode=False, r=1, lora_alpha=32, lora_dropout=0.1, ) model.enable_input_require_grads() model = get_peft_model(model, peft_config) model.print_trainable_parameters() ``` ## 4bit/8bit/16bit对应的线程层类 ``` from transformers import AutoTokenizer, BitsAndBytesConfig from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training import torch from transformers import ( set_seed, HfArgumentParser, TrainingArguments, AutoModelForCausalLM ) device_map = {'': 0} model = AutoModelForCausalLM.from_pretrained( "/home/guodong.li/workspace/model/bloom-2b6-zh", device_map=device_map, load_in_4bit=True, torch_dtype=torch.float16, trust_remote_code=True, quantization_config=BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_compute_dtype=torch.float16, bnb_4bit_use_double_quant=True, bnb_4bit_quant_type="nf4", llm_int8_threshold=6.0, llm_int8_has_fp16_weight=False, ), ) print(model) BloomForCausalLM( (transformer): BloomModel( (word_embeddings): Embedding(46145, 2560) (word_embeddings_layernorm): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) (h): ModuleList( (0): BloomBlock( (input_layernorm): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) (self_attention): BloomAttention( (query_key_value): Linear4bit(in_features=2560, out_features=7680, bias=True) (dense): Linear4bit(in_features=2560, out_features=2560, bias=True) (attention_dropout): Dropout(p=0.0, inplace=False) ) (post_attention_layernorm): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) (mlp): BloomMLP( (dense_h_to_4h): Linear4bit(in_features=2560, out_features=10240, bias=True) (gelu_impl): BloomGelu() (dense_4h_to_h): Linear4bit(in_features=10240, out_features=2560, bias=True) ) ) (29): BloomBlock( ... ) ) (ln_f): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) ) (lm_head): Linear(in_features=2560, out_features=46145, bias=False) ) from transformers import AutoTokenizer, BitsAndBytesConfig from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training import torch from transformers import ( set_seed, HfArgumentParser, TrainingArguments, AutoModelForCausalLM ) device_map = {'': 0} model = AutoModelForCausalLM.from_pretrained( "/home/guodong.li/workspace/model/bloom-2b6-zh", device_map=device_map, load_in_8bit=True, torch_dtype=torch.float16, ) print(model) BloomForCausalLM( (transformer): BloomModel( (word_embeddings): Embedding(46145, 2560) (word_embeddings_layernorm): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) (h): ModuleList( (0): BloomBlock( (input_layernorm): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) (self_attention): BloomAttention( (query_key_value): Linear8bitLt(in_features=2560, out_features=7680, bias=True) (dense): Linear8bitLt(in_features=2560, out_features=2560, bias=True) (attention_dropout): Dropout(p=0.0, inplace=False) ) (post_attention_layernorm): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) (mlp): BloomMLP( (dense_h_to_4h): Linear8bitLt(in_features=2560, out_features=10240, bias=True) (gelu_impl): BloomGelu() (dense_4h_to_h): Linear8bitLt(in_features=10240, out_features=2560, bias=True) ) ) ... (29): BloomBlock( ... ) ) (ln_f): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) ) (lm_head): Linear(in_features=2560, out_features=46145, bias=False) ) from transformers import AutoTokenizer, BitsAndBytesConfig from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training import torch from transformers import ( set_seed, HfArgumentParser, TrainingArguments, AutoModelForCausalLM ) device_map = {'': 0} model = AutoModelForCausalLM.from_pretrained( "/home/guodong.li/workspace/model/bloom-2b6-zh", device_map=device_map, torch_dtype=torch.float16, ) print(model) BloomForCausalLM( (transformer): BloomModel( (word_embeddings): Embedding(46145, 2560) (word_embeddings_layernorm): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) (h): ModuleList( (0): BloomBlock( (input_layernorm): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) (self_attention): BloomAttention( (query_key_value): Linear(in_features=2560, out_features=7680, bias=True) (dense): Linear(in_features=2560, out_features=2560, bias=True) (attention_dropout): Dropout(p=0.0, inplace=False) ) (post_attention_layernorm): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) (mlp): BloomMLP( (dense_h_to_4h): Linear(in_features=2560, out_features=10240, bias=True) (gelu_impl): BloomGelu() (dense_4h_to_h): Linear(in_features=10240, out_features=2560, bias=True) ) ) (29): BloomBlock( ... ) ) (ln_f): LayerNorm((2560,), eps=1e-05, elementwise_affine=True) ) (lm_head): Linear(in_features=2560, out_features=46145, bias=False) ) ``` ## 是否进行计算梯度 ``` train_loss = lw[0] * loss0 + lw[1] * loss1 + lw[2] * loss2 # loss backward for name, parms in model.named_parameters(): print('\nBefore backward\n') print('-->name:', name) print('-->para:', parms) print('-->grad_requirs:',parms.requires_grad) print('-->grad_value:',parms.grad) print("===========================") # train_loss.backward() # for name, parms in model.named_parameters(): print('\nAfter backward\n') print('-->name:', name) print('-->para:', parms) print('-->grad_requirs:',parms.requires_grad) print('-->grad_value:',parms.grad) print("===========================") ``` ================================================ FILE: llm-train/peft/PEFT-API.md ================================================ - prepare_model_for_int8_training 用途(deprecated, 直接使用 prepare_model_for_kbit_training): ``` 将所有非 int8 模块转换为全精度 (fp32) 以确保稳定性 在输入嵌入层添加一个前向钩子(forward hook)来计算输入隐藏状态的梯度 启用梯度检查点以提高内存效率的训练 ``` --- - prepare_model_for_kbit_training 用途: ``` 处理量化模型以用于训练。 1-转换 layernorm 为 fp32 2-使输出嵌入层计算梯度 3-转换lm head 为 fp32 ``` 参数: - use_gradient_checkpointing:如果为 True,则使用梯度检查点来节省内存,但代价是向后传递速度较慢。 本质是减少内存消耗的一种方式,以时间或者计算换内存 gradient_checkpointing(梯度检查点)是一种用于减少深度学习模型中内存消耗的技术。在训练深度神经网络时,反向传播算法需要在前向传播和反向传播之间存储中间计算结果,以便计算梯度并更新模型参数。这些中间结果的存储会占用大量的内存,特别是当模型非常深或参数量很大时。 梯度检查点技术通过在前向传播期间临时丢弃一些中间结果,仅保留必要的信息,以减少内存使用量。在反向传播过程中,只需要重新计算被丢弃的中间结果,而不需要存储所有的中间结果,从而节省内存空间。 实现梯度检查点的一种常见方法是将某些层或操作标记为检查点。在前向传播期间,被标记为检查点的层将计算并缓存中间结果。然后,在反向传播过程中,这些层将重新计算其所需的中间结果,以便计算梯度。 具体来说,在完整的正向传播中,函数将以 torch.no_grad() 方式运行,即不存储中间激活。同时,在完整正向传播过程中,每遇到检查点则保存输入tensor和函数参数。等到反向传播时,把每个检查点看成一个局部阶段,在局部阶段中取出保存的输入tensor和函数参数,并再次计算局部阶段内函数的前向传播过程,跟踪每个神经元的激活值,然后使用这些激活值计算梯度。 --- ================================================ FILE: llm-train/peft/Prefix-Tuning.md ================================================ ``` from peft import PrefixEncoder, PrefixTuningConfig config = PrefixTuningConfig( peft_type="PREFIX_TUNING", task_type="SEQ_2_SEQ_LM", num_virtual_tokens=20, token_dim=768, num_transformer_submodules=1, num_attention_heads=12, num_layers=12, encoder_hidden_size=768, ) prefix_encoder = PrefixEncoder(config) ``` https://huggingface.co/JackFram/llama-68m ================================================ FILE: llm-train/peft/Prompt-Tuning.md ================================================ 引入库: ``` from peft import get_peft_config, get_peft_model, PromptTuningInit, PromptTuningConfig, TaskType, PeftType ``` 创建Prompt Tuning配置: ``` model_name_or_path = "/data/nfs/llm/model/bloomz-560m" tokenizer_name_or_path = "/data/nfs/llm/model/bloomz-560m" peft_config = PromptTuningConfig( task_type=TaskType.CAUSAL_LM, prompt_tuning_init=PromptTuningInit.TEXT, num_virtual_tokens=8, prompt_tuning_init_text="Classify if the tweet is a complaint or not:", tokenizer_name_or_path=model_name_or_path, ) ``` 创建基础模型并通过get_peft_model包装基础模型: ``` # creating model model = AutoModelForCausalLM.from_pretrained(model_name_or_path) model = get_peft_model(model, peft_config) model.print_trainable_parameters() ``` 训练的参数量如下: ``` trainable params: 8,192 || all params: 559,222,784 || trainable%: 0.0014648902430985358 ``` ``` ``` ``` ``` ================================================ FILE: llm-train/peft/README.md ================================================ ## 环境 ``` cd /home/guodong.li/virtual-venv virtualenv -p /usr/bin/python3.10 peft-venv-py310-cu117 source /home/guodong.li/virtual-venv/peft-venv-py310-cu117/bin/activate pip install torch-1.13.1+cu117-cp310-cp310-linux_x86_64.whl pip install torchvision-0.14.1+cu117-cp310-cp310-linux_x86_64.whl git clone https://github.com/huggingface/peft cd peft git checkout 42ab106 pip install -e . pip install datasets pip install jupyterlab pip install deepspeed ``` 生成配置文件: ``` > jupyter lab --generate-config Writing default config to: /home/guodong.li/.jupyter/jupyter_lab_config.py ``` 对密码进行加密: ``` from jupyter_server.auth import passwd; passwd() ``` 修改配置文件: ``` c.ServerApp.allow_origin = '*' c.ServerApp.allow_remote_access = True c.ServerApp.ip = '0.0.0.0' c.ServerApp.open_browser = False c.ServerApp.password = '加密后的密码' c.ServerApp.port = 9999 ``` 启动: ``` jupyter lab --allow-root nohup jupyter lab --allow-root > jupyterlab.log 2>&1 & ``` # 任务类型 - 因果语言模型(Causal Language Modeling) - 条件生成(Conditional Generation) - 序列分类(Sequence Classification):整个序列输出一个标签。 - Token 分类(Token Classification):每个 Token 输出一个标签。 - 文本-图像生成(Text-to-Image Generation) - 图像分类(Image Classification) - 序列到序列语言模型(Seq2Seq LM) - 问答任务(Question Answering):返回给定问题的答案。常见的问答任务有两种类型: - 提取:从给定的上下文中提取答案。 - 摘要:从上下文中生成正确回答问题的答案。 以下是一些常见 NLP 任务: - 序列分类(Sequence Classification),对整个句子进行分类。如: 获取评论的情绪,检测电子邮件是否为垃圾邮件,确定句子在语法上是否正确或两个句子在逻辑上是否相关等 - Token分类(Token Classification),对句子中的每个词进行分类。如: 识别句子的语法成分(名词、动词、形容词)或命名实体(人、地点、组织)。 - **生成文本内容**: 用自动生成的文本完成提示,用屏蔽词填充文本中的空白 - **从文本中提取答案**: 给定问题和上下文,根据上下文中提供的信息提取问题的答案 - **从输入文本生成新句子**: 将文本翻译成另一种语言,总结文本 ## 高效微调 ### 大模型参数高效微调技术实战(二)-Prompt Tuning ### 大模型参数高效微调技术实战(三)-P-Tuning LSTM: ``` PeftModelForCausalLM( (base_model): BloomForCausalLM( (transformer): BloomModel( (word_embeddings): Embedding(250880, 1024) (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True) (h): ModuleList( (0): BloomBlock( (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True) (self_attention): BloomAttention( (query_key_value): Linear(in_features=1024, out_features=3072, bias=True) (dense): Linear(in_features=1024, out_features=1024, bias=True) (attention_dropout): Dropout(p=0.0, inplace=False) ) (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True) (mlp): BloomMLP( (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True) (gelu_impl): BloomGelu() (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True) ) ) ... (23): BloomBlock( ... ) ) (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True) ) (lm_head): Linear(in_features=1024, out_features=250880, bias=False) ) (prompt_encoder): ModuleDict( (default): PromptEncoder( (embedding): Embedding(20, 1024) (lstm_head): LSTM(1024, 128, num_layers=2, batch_first=True, bidirectional=True) (mlp_head): Sequential( (0): Linear(in_features=256, out_features=256, bias=True) (1): ReLU() (2): Linear(in_features=256, out_features=1024, bias=True) ) ) ) (word_embeddings): Embedding(250880, 1024) ) ``` ### 大模型参数高效微调技术实战(四)-Prefix Tuning ### 大模型参数高效微调技术实战(三)-LoRA
详细输出:

``` > accelerate launch --config_file accelerate_ds_zero3_cpu_offload_config.yaml peft_lora_clm_accelerate_ds_zero3_offload.py [2023-07-18 18:07:40,939] [INFO] [real_accelerator.py:133:get_accelerator] Setting ds_accelerator to cuda (auto detect) [2023-07-18 18:07:43,645] [INFO] [real_accelerator.py:133:get_accelerator] Setting ds_accelerator to cuda (auto detect) [2023-07-18 18:07:45,313] [WARNING] [comm.py:152:init_deepspeed_backend] NCCL backend in DeepSpeed not yet implemented [2023-07-18 18:07:45,313] [INFO] [comm.py:616:init_distributed] cdb=None [2023-07-18 18:07:45,313] [INFO] [comm.py:643:init_distributed] Initializing TorchBackend in DeepSpeed with backend nccl Found cached dataset raft (/home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84) 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 731.03it/s] Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-fa180e92c989bf46.arrow Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-923041e0448cc3ac.arrow Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-85bb53e2cdd61aab.arrow Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-954cbf329129cf3b.arrow [2023-07-18 18:07:48,082] [INFO] [partition_parameters.py:326:__exit__] finished initializing model with 0.82B parameters trainable params: 786,432 || all params: 560,001,024 || trainable%: 0.14043402892063284 [2023-07-18 18:07:49,237] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed info: version=0.10.0, git-hash=unknown, git-branch=unknown [2023-07-18 18:07:49,293] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed Flops Profiler Enabled: False [2023-07-18 18:07:49,294] [INFO] [logging.py:96:log_dist] [Rank 0] Removing param_group that has no 'params' in the client Optimizer [2023-07-18 18:07:49,294] [INFO] [logging.py:96:log_dist] [Rank 0] Using client Optimizer as basic optimizer [2023-07-18 18:07:49,311] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed Basic Optimizer = AdamW [2023-07-18 18:07:49,311] [INFO] [utils.py:54:is_zero_supported_optimizer] Checking ZeRO support for optimizer=AdamW type= [2023-07-18 18:07:49,311] [INFO] [logging.py:96:log_dist] [Rank 0] Creating fp16 ZeRO stage 3 optimizer, MiCS is enabled False, Hierarchical params gather False [2023-07-18 18:07:49,311] [INFO] [logging.py:96:log_dist] [Rank 0] Creating torch.float32 ZeRO stage 3 optimizer [2023-07-18 18:07:49,375] [INFO] [utils.py:785:see_memory_usage] Stage 3 initialize beginning [2023-07-18 18:07:49,376] [INFO] [utils.py:786:see_memory_usage] MA 3.04 GB Max_MA 4.95 GB CA 5.95 GB Max_CA 6 GB [2023-07-18 18:07:49,376] [INFO] [utils.py:793:see_memory_usage] CPU Virtual Memory: used = 39.9 GB, percent = 4.0% [2023-07-18 18:07:49,379] [INFO] [stage3.py:117:__init__] Reduce bucket size 500,000,000 [2023-07-18 18:07:49,379] [INFO] [stage3.py:118:__init__] Prefetch bucket size 50,000,000 [2023-07-18 18:07:49,437] [INFO] [utils.py:785:see_memory_usage] DeepSpeedZeRoOffload initialize [begin] ... [2023-07-18 18:07:50,074] [INFO] [utils.py:786:see_memory_usage] MA 4.92 GB Max_MA 4.92 GB CA 4.94 GB Max_CA 5 GB [2023-07-18 18:07:50,074] [INFO] [utils.py:793:see_memory_usage] CPU Virtual Memory: used = 39.9 GB, percent = 4.0% [2023-07-18 18:07:50,074] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed Final Optimizer = AdamW [2023-07-18 18:07:50,074] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed using client LR scheduler [2023-07-18 18:07:50,074] [INFO] [logging.py:96:log_dist] [Rank 0] DeepSpeed LR Scheduler = None [2023-07-18 18:07:50,074] [INFO] [logging.py:96:log_dist] [Rank 0] step=0, skipped=0, lr=[0.003], mom=[(0.9, 0.999)] [2023-07-18 18:07:50,075] [INFO] [config.py:960:print] DeepSpeedEngine configuration: [2023-07-18 18:07:50,075] [INFO] [config.py:964:print] activation_checkpointing_config { "partition_activations": false, "contiguous_memory_optimization": false, "cpu_checkpointing": false, "number_checkpoints": null, "synchronize_checkpoint_boundary": false, "profile": false } [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] aio_config ................... {'block_size': 1048576, 'queue_depth': 8, 'thread_count': 1, 'single_submit': False, 'overlap_events': True} [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] amp_enabled .................. False [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] amp_params ................... False [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] autotuning_config ............ { "enabled": false, "start_step": null, "end_step": null, "metric_path": null, "arg_mappings": null, "metric": "throughput", "model_info": null, "results_dir": "autotuning_results", "exps_dir": "autotuning_exps", "overwrite": true, "fast": true, "start_profile_step": 3, "end_profile_step": 5, "tuner_type": "gridsearch", "tuner_early_stopping": 5, "tuner_num_trials": 50, "model_info_path": null, "mp_size": 1, "max_train_batch_size": null, "min_train_batch_size": 1, "max_train_micro_batch_size_per_gpu": 1.024000e+03, "min_train_micro_batch_size_per_gpu": 1, "num_tuning_micro_batch_sizes": 3 } [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] bfloat16_enabled ............. False [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] checkpoint_parallel_write_pipeline False [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] checkpoint_tag_validation_enabled True [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] checkpoint_tag_validation_fail False [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] comms_config ................. [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] communication_data_type ...... None [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] compression_config ........... {'weight_quantization': {'shared_parameters': {'enabled': False, 'quantizer_kernel': False, 'schedule_offset': 0, 'quantize_groups': 1, 'quantize_verbose': False, 'quantization_type': 'symmetric', 'quantize_weight_in_forward': False, 'rounding': 'nearest', 'fp16_mixed_quantize': False, 'quantize_change_ratio': 0.001}, 'different_groups': {}}, 'activation_quantization': {'shared_parameters': {'enabled': False, 'quantization_type': 'symmetric', 'range_calibration': 'dynamic', 'schedule_offset': 1000}, 'different_groups': {}}, 'sparse_pruning': {'shared_parameters': {'enabled': False, 'method': 'l1', 'schedule_offset': 1000}, 'different_groups': {}}, 'row_pruning': {'shared_parameters': {'enabled': False, 'method': 'l1', 'schedule_offset': 1000}, 'different_groups': {}}, 'head_pruning': {'shared_parameters': {'enabled': False, 'method': 'topk', 'schedule_offset': 1000}, 'different_groups': {}}, 'channel_pruning': {'shared_parameters': {'enabled': False, 'method': 'l1', 'schedule_offset': 1000}, 'different_groups': {}}, 'layer_reduction': {'enabled': False}} [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] curriculum_enabled_legacy .... False [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] curriculum_params_legacy ..... False [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] data_efficiency_config ....... {'enabled': False, 'seed': 1234, 'data_sampling': {'enabled': False, 'num_epochs': 1000, 'num_workers': 0, 'curriculum_learning': {'enabled': False}}, 'data_routing': {'enabled': False, 'random_ltd': {'enabled': False, 'layer_token_lr_schedule': {'enabled': False}}}} [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] data_efficiency_enabled ...... False [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] dataloader_drop_last ......... False [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] disable_allgather ............ False [2023-07-18 18:07:50,076] [INFO] [config.py:964:print] dump_state ................... False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] dynamic_loss_scale_args ...... None [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] eigenvalue_enabled ........... False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] eigenvalue_gas_boundary_resolution 1 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] eigenvalue_layer_name ........ bert.encoder.layer [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] eigenvalue_layer_num ......... 0 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] eigenvalue_max_iter .......... 100 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] eigenvalue_stability ......... 1e-06 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] eigenvalue_tol ............... 0.01 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] eigenvalue_verbose ........... False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] elasticity_enabled ........... False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] flops_profiler_config ........ { "enabled": false, "recompute_fwd_factor": 0.0, "profile_step": 1, "module_depth": -1, "top_modules": 1, "detailed": true, "output_file": null } [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] fp16_auto_cast ............... None [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] fp16_enabled ................. False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] fp16_master_weights_and_gradients False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] global_rank .................. 0 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] grad_accum_dtype ............. None [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] gradient_accumulation_steps .. 1 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] gradient_clipping ............ 1.0 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] gradient_predivide_factor .... 1.0 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] hybrid_engine ................ enabled=False max_out_tokens=512 inference_tp_size=1 release_inference_cache=False pin_parameters=True tp_gather_partition_size=8 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] initial_dynamic_scale ........ 65536 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] load_universal_checkpoint .... False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] loss_scale ................... 0 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] memory_breakdown ............. False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] mics_hierarchial_params_gather False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] mics_shard_size .............. -1 [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] monitor_config ............... tensorboard=TensorBoardConfig(enabled=False, output_path='', job_name='DeepSpeedJobName') wandb=WandbConfig(enabled=False, group=None, team=None, project='deepspeed') csv_monitor=CSVConfig(enabled=False, output_path='', job_name='DeepSpeedJobName') enabled=False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] nebula_config ................ { "enabled": false, "persistent_storage_path": null, "persistent_time_interval": 100, "num_of_version_in_retention": 2, "enable_nebula_load": true, "load_path": null } [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] optimizer_legacy_fusion ...... False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] optimizer_name ............... None [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] optimizer_params ............. None [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] pipeline ..................... {'stages': 'auto', 'partition': 'best', 'seed_layers': False, 'activation_checkpoint_interval': 0} [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] pld_enabled .................. False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] pld_params ................... False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] prescale_gradients ........... False [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] scheduler_name ............... None [2023-07-18 18:07:50,077] [INFO] [config.py:964:print] scheduler_params ............. None [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] sparse_attention ............. None [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] sparse_gradients_enabled ..... False [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] steps_per_print .............. inf [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] train_batch_size ............. 8 [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] train_micro_batch_size_per_gpu 8 [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] use_node_local_storage ....... False [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] wall_clock_breakdown ......... False [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] world_size ................... 1 [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] zero_allow_untested_optimizer True [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] zero_config .................. stage=3 contiguous_gradients=True reduce_scatter=True reduce_bucket_size=500,000,000 allgather_partitions=True allgather_bucket_size=500,000,000 overlap_comm=True load_from_fp32_weights=True elastic_checkpoint=False offload_param=DeepSpeedZeroOffloadParamConfig(device='none', nvme_path=None, buffer_count=5, buffer_size=100,000,000, max_in_cpu=1,000,000,000, pin_memory=False) offload_optimizer=DeepSpeedZeroOffloadOptimizerConfig(device='none', nvme_path=None, buffer_count=4, pin_memory=False, pipeline=False, pipeline_read=False, pipeline_write=False, fast_init=False) sub_group_size=1,000,000,000 cpu_offload_param=None cpu_offload_use_pin_memory=None cpu_offload=None prefetch_bucket_size=50,000,000 param_persistence_threshold=100,000 model_persistence_threshold=sys.maxsize max_live_parameters=1,000,000,000 max_reuse_distance=1,000,000,000 gather_16bit_weights_on_model_save=True stage3_gather_fp16_weights_on_model_save=False ignore_unused_parameters=True legacy_stage1=False round_robin_gradients=False zero_hpz_partition_size=1 zero_quantized_weights=False zero_quantized_gradients=False mics_shard_size=-1 mics_hierarchical_params_gather=False memory_efficient_linear=True [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] zero_enabled ................. True [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] zero_force_ds_cpu_optimizer .. True [2023-07-18 18:07:50,078] [INFO] [config.py:964:print] zero_optimization_stage ...... 3 [2023-07-18 18:07:50,078] [INFO] [config.py:950:print_user_config] json = { "train_batch_size": 8, "train_micro_batch_size_per_gpu": 8, "gradient_accumulation_steps": 1, "zero_optimization": { "stage": 3, "offload_optimizer": { "device": "none", "nvme_path": null }, "offload_param": { "device": "none", "nvme_path": null }, "stage3_gather_16bit_weights_on_model_save": true }, "gradient_clipping": 1.0, "steps_per_print": inf, "fp16": { "enabled": false }, "bf16": { "enabled": false }, "zero_allow_untested_optimizer": true } DeepSpeedEngine( (module): PeftModelForCausalLM( (base_model): LoraModel( (model): BloomForCausalLM( (transformer): BloomModel( (word_embeddings): Embedding(250880, 1024) (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True) (h): ModuleList( (0): BloomBlock( (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True) (self_attention): BloomAttention( (query_key_value): Linear( in_features=1024, out_features=3072, bias=True (lora_dropout): ModuleDict( (default): Dropout(p=0.1, inplace=False) ) (lora_A): ModuleDict( (default): Linear(in_features=1024, out_features=8, bias=False) ) (lora_B): ModuleDict( (default): Linear(in_features=8, out_features=3072, bias=False) ) (lora_embedding_A): ParameterDict() (lora_embedding_B): ParameterDict() ) (dense): Linear(in_features=1024, out_features=1024, bias=True) (attention_dropout): Dropout(p=0.0, inplace=False) ) (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True) (mlp): BloomMLP( (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True) (gelu_impl): BloomGelu() (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True) ) ) ... (23): BloomBlock( (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True) (self_attention): BloomAttention( (query_key_value): Linear( in_features=1024, out_features=3072, bias=True (lora_dropout): ModuleDict( (default): Dropout(p=0.1, inplace=False) ) (lora_A): ModuleDict( (default): Linear(in_features=1024, out_features=8, bias=False) ) (lora_B): ModuleDict( (default): Linear(in_features=8, out_features=3072, bias=False) ) (lora_embedding_A): ParameterDict() (lora_embedding_B): ParameterDict() ) (dense): Linear(in_features=1024, out_features=1024, bias=True) (attention_dropout): Dropout(p=0.0, inplace=False) ) (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True) (mlp): BloomMLP( (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True) (gelu_impl): BloomGelu() (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True) ) ) ) (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True) ) (lm_head): Linear(in_features=1024, out_features=250880, bias=False) ) ) ) ) /home/guodong.li/virtual-venv/peft-venv-py310-cu117/lib/python3.10/site-packages/torch/cuda/memory.py:282: FutureWarning: torch.cuda.reset_max_memory_allocated now calls torch.cuda.reset_peak_memory_stats, which resets /all/ peak memory stats. warnings.warn( 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [00:04<00:00, 1.62it/s] GPU Memory before entering the train : 5038 GPU Memory consumed at the end of the train (end-begin): 146 GPU Peak Memory consumed during the train (max-begin): 2917 GPU Total Peak Memory consumed during the train (max): 7955 CPU Memory before entering the train : 1798 CPU Memory consumed at the end of the train (end-begin): 939 CPU Peak Memory consumed during the train (max-begin): 939 CPU Total Peak Memory consumed during the train (max): 2737 epoch=0: train_ppl=tensor(8.6437e+09, device='cuda:0') train_epoch_loss=tensor(22.8801, device='cuda:0') 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [00:13<00:00, 1.99s/it] GPU Memory before entering the eval : 5184 GPU Memory consumed at the end of the eval (end-begin): -146 GPU Peak Memory consumed during the eval (max-begin): 692 GPU Total Peak Memory consumed during the eval (max): 5876 CPU Memory before entering the eval : 2737 CPU Memory consumed at the end of the eval (end-begin): 5 CPU Peak Memory consumed during the eval (max-begin): 5 CPU Total Peak Memory consumed during the eval (max): 2742 accuracy=0.0 eval_preds[:10]=['complaint complaint yang diutarakan oleh polisi, polisi', 'complaint complaint yang sudah diinstruksikan oleh polisi', 'complaint polisi juga complaint yang sudah diinstruksikan', 'complaint complaint yang diutarakan oleh polisi, polisi', 'complaint complaint yang kedua, polisi juga harus meminta', 'complaint polisi juga complaint yang diajukan polisi di negara', 'complaint yang harus didỏi adalah complaint yang harus', 'complaint polisi juga meminta maaf dan meminta maaf kepada', 'complaint polisi juga complaint yang dikeluarkan polisi di negara', 'complaint complaint yang diutarakan oleh polisi, polisi'] dataset['train'][label_column][:10]=['no complaint', 'no complaint', 'complaint', 'complaint', 'no complaint', 'no complaint', 'no complaint', 'complaint', 'complaint', 'no complaint'] 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [00:02<00:00, 2.34it/s] GPU Memory before entering the train : 5038 GPU Memory consumed at the end of the train (end-begin): 146 GPU Peak Memory consumed during the train (max-begin): 2917 GPU Total Peak Memory consumed during the train (max): 7955 CPU Memory before entering the train : 2743 CPU Memory consumed at the end of the train (end-begin): 0 CPU Peak Memory consumed during the train (max-begin): 0 CPU Total Peak Memory consumed during the train (max): 2743 epoch=1: train_ppl=tensor(52.4372, device='cuda:0') train_epoch_loss=tensor(3.9596, device='cuda:0') 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [00:14<00:00, 2.04s/it] GPU Memory before entering the eval : 5184 GPU Memory consumed at the end of the eval (end-begin): -146 GPU Peak Memory consumed during the eval (max-begin): 692 GPU Total Peak Memory consumed during the eval (max): 5876 CPU Memory before entering the eval : 2743 CPU Memory consumed at the end of the eval (end-begin): 0 CPU Peak Memory consumed during the eval (max-begin): 0 CPU Total Peak Memory consumed during the eval (max): 2743 accuracy=0.0 eval_preds[:10]=['no complaintossos್ಬ البطنಿಸteznoಿಖ economista', 'no complaintেষ্টেষ্ট Magdalnoಿಖ economistano complaint', 'no complaintেষ্টnoضاًضاًضاًਧਮाशिवाय', 'no complaintছ البطنುಗಳನ್ನುਧನೆಯಲ್ಲಿছেষ্টestant', 'no complaint細 البطن البطنno complaint أعلمضاً密西西比', 'no complaint阿拉斯加no complaint أعلمುಗಳನ್ನು্যওছಿಸ', 'no complaintছ البطنছਧਮnoেষ্টেষ্ট', 'no complaint阿拉斯加ossosਧನೆಯಲ್ಲಿেছে,no complaint', 'no complaint أعلم أعلمضاًضاًضاًਮেছে,', 'no complaintossosਧਮno執法ਬ البطنಿಸ'] dataset['train'][label_column][:10]=['no complaint', 'no complaint', 'complaint', 'complaint', 'no complaint', 'no complaint', 'no complaint', 'complaint', 'complaint', 'no complaint'] 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [00:02<00:00, 2.34it/s] GPU Memory before entering the train : 5038 GPU Memory consumed at the end of the train (end-begin): 146 GPU Peak Memory consumed during the train (max-begin): 2917 GPU Total Peak Memory consumed during the train (max): 7955 CPU Memory before entering the train : 2744 CPU Memory consumed at the end of the train (end-begin): 0 CPU Peak Memory consumed during the train (max-begin): 0 CPU Total Peak Memory consumed during the train (max): 2744 epoch=2: train_ppl=tensor(7.5966, device='cuda:0') train_epoch_loss=tensor(2.0277, device='cuda:0') 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [00:13<00:00, 1.97s/it] GPU Memory before entering the eval : 5184 GPU Memory consumed at the end of the eval (end-begin): -146 GPU Peak Memory consumed during the eval (max-begin): 692 GPU Total Peak Memory consumed during the eval (max): 5876 CPU Memory before entering the eval : 2744 CPU Memory consumed at the end of the eval (end-begin): 0 CPU Peak Memory consumed during the eval (max-begin): 0 CPU Total Peak Memory consumed during the eval (max): 2744 accuracy=12.0 eval_preds[:10]=['complaint', 'complaint buồn buồn', 'complaint', 'complaint buồn buồn', 'complaint buồn', 'complaint buồn', 'complaint buồn buồn buồn', 'complaint', 'complaint buồn', 'complaint'] dataset['train'][label_column][:10]=['no complaint', 'no complaint', 'complaint', 'complaint', 'no complaint', 'no complaint', 'no complaint', 'complaint', 'complaint', 'no complaint'] 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [00:03<00:00, 2.13it/s] ... GPU Memory before entering the train : 5038 GPU Memory consumed at the end of the train (end-begin): 146 GPU Peak Memory consumed during the train (max-begin): 2917 GPU Total Peak Memory consumed during the train (max): 7955 CPU Memory before entering the train : 2752 CPU Memory consumed at the end of the train (end-begin): 0 CPU Peak Memory consumed during the train (max-begin): 0 CPU Total Peak Memory consumed during the train (max): 2752 epoch=9: train_ppl=tensor(1.0111, device='cuda:0') train_epoch_loss=tensor(0.0110, device='cuda:0') 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [00:16<00:00, 2.36s/it] GPU Memory before entering the eval : 5184 GPU Memory consumed at the end of the eval (end-begin): -146 GPU Peak Memory consumed during the eval (max-begin): 692 GPU Total Peak Memory consumed during the eval (max): 5876 CPU Memory before entering the eval : 2752 CPU Memory consumed at the end of the eval (end-begin): 0 CPU Peak Memory consumed during the eval (max-begin): 0 CPU Total Peak Memory consumed during the eval (max): 2752 accuracy=100.0 eval_preds[:10]=['no complaint', 'no complaint', 'complaint', 'complaint', 'no complaint', 'no complaint', 'no complaint', 'complaint', 'complaint', 'no complaint'] dataset['train'][label_column][:10]=['no complaint', 'no complaint', 'complaint', 'complaint', 'no complaint', 'no complaint', 'no complaint', 'complaint', 'complaint', 'no complaint'] model_output: /data/nfs/llm/model/bloomz-560m_LORA_CAUSAL_LM ```

``` > tree -h /data/nfs/llm/model/bloomz-560m_LORA_CAUSAL_LM /data/nfs/llm/model/bloomz-560m_LORA_CAUSAL_LM ├── [ 447] adapter_config.json ├── [ 14K] adapter_model.bin └── [ 93] README.md 0 directories, 3 files ``` ### 大模型参数高效微调技术实战(四)-AdaLoRA ### 大模型参数高效微调技术实战(五)-QLoRA - 大模型参数高效微调技术实战(一)-Prefix Tuning - 大模型参数高效微调技术实战(二)-Prompt Tuning - 大模型参数高效微调技术实战(三)-P-Tuning - 大模型参数高效微调技术实战(三)-LoRA - 大模型参数高效微调技术实战(四)-AdaLoRA - 大模型参数高效微调技术实战(五)-QLoRA ================================================ FILE: llm-train/peft/clm/accelerate_ds_zero3_cpu_offload_config.yaml ================================================ compute_environment: LOCAL_MACHINE deepspeed_config: gradient_accumulation_steps: 1 gradient_clipping: 1.0 offload_optimizer_device: none offload_param_device: none zero3_init_flag: true zero3_save_16bit_model: true zero_stage: 3 distributed_type: DEEPSPEED downcast_bf16: 'no' dynamo_backend: 'NO' fsdp_config: {} machine_rank: 0 main_training_function: main megatron_lm_config: {} mixed_precision: 'no' num_machines: 1 num_processes: 1 rdzv_backend: static same_network: true use_cpu: false ================================================ FILE: llm-train/peft/clm/peft_ia3_clm.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "id": "a63994ce-83d1-4c84-b372-2a1b6167f90a", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/guodong.li/virtual-venv/peft-venv-py310-cu117/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[2023-07-22 15:47:42,177] [INFO] [real_accelerator.py:133:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n" ] } ], "source": [ "from transformers import AutoModelForCausalLM\n", "\n", "from peft import get_peft_config, get_peft_model, get_peft_model_state_dict, IA3Config, TaskType\n", "\n", "import torch\n", "from datasets import load_dataset\n", "import os\n", "from transformers import AutoTokenizer\n", "from torch.utils.data import DataLoader\n", "from transformers import default_data_collator, get_linear_schedule_with_warmup\n", "from tqdm import tqdm\n", "from datasets import load_dataset\n", "\n", "\n", "device = \"cuda\"\n", "\n", "model_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "tokenizer_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "\n", "\n", "peft_config = IA3Config(task_type=TaskType.CAUSAL_LM,\n", " target_modules=[\"query_key_value\", \"mlp.dense_4h_to_h\"],\n", " inference_mode=False, \n", " feedforward_modules=[\"mlp.dense_4h_to_h\"])\n", "\n", "\n", "\n", "dataset_name = \"twitter_complaints\"\n", "checkpoint_name = f\"{dataset_name}_{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}_v1.pt\".replace(\"/\", \"_\")\n", "text_column = \"Tweet text\"\n", "label_column = \"text_label\"\n", "max_length = 64\n", "lr = 3e-2\n", "num_epochs = 10\n", "batch_size = 8" ] }, { "cell_type": "code", "execution_count": 2, "id": "89aff2bb-0dce-4b2c-908d-5c5363eab688", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Found cached dataset raft (/home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84)\n", "100%|██████████| 2/2 [00:00<00:00, 732.82it/s]\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-0e20fff6b1d898ca.arrow\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-8d14a62b8a688c19.arrow\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "['Unlabeled', 'complaint', 'no complaint']\n", "DatasetDict({\n", " train: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 50\n", " })\n", " test: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 3399\n", " })\n", "})\n" ] }, { "data": { "text/plain": [ "{'Tweet text': '@HMRCcustomers No this is my first job',\n", " 'ID': 0,\n", " 'Label': 2,\n", " 'text_label': 'no complaint'}" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from datasets import load_dataset\n", "\n", "# dataset = load_dataset(\"ought/raft\", dataset_name)\n", "dataset = load_dataset(\"/home/guodong.li/data/peft/raft/raft.py\", dataset_name, cache_dir=\"/home/guodong.li/data/peft/data\")\n", "\n", "classes = [k.replace(\"_\", \" \") for k in dataset[\"train\"].features[\"Label\"].names]\n", "print(classes)\n", "dataset = dataset.map(\n", " lambda x: {\"text_label\": [classes[label] for label in x[\"Label\"]]},\n", " batched=True,\n", " num_proc=1,\n", ")\n", "print(dataset)\n", "dataset[\"train\"][0]" ] }, { "cell_type": "code", "execution_count": 3, "id": "12494f57-2445-4297-9bae-c61a3fcb878d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "target_max_length: 3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " \r" ] } ], "source": [ "# data preprocessing\n", "tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)\n", "if tokenizer.pad_token_id is None:\n", " tokenizer.pad_token_id = tokenizer.eos_token_id\n", "target_max_length = max([len(tokenizer(class_label)[\"input_ids\"]) for class_label in classes])\n", "print(\"target_max_length:\", target_max_length)\n", "\n", "\n", "def preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " targets = [str(x) for x in examples[label_column]]\n", " model_inputs = tokenizer(inputs)\n", " labels = tokenizer(targets)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i] + [tokenizer.pad_token_id]\n", " # print(i, sample_input_ids, label_input_ids)\n", " model_inputs[\"input_ids\"][i] = sample_input_ids + label_input_ids\n", " labels[\"input_ids\"][i] = [-100] * len(sample_input_ids) + label_input_ids\n", " model_inputs[\"attention_mask\"][i] = [1] * len(model_inputs[\"input_ids\"][i])\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (\n", " max_length - len(sample_input_ids)\n", " ) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\n", " \"attention_mask\"\n", " ][i]\n", " labels[\"input_ids\"][i] = [-100] * (max_length - len(sample_input_ids)) + label_input_ids\n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " labels[\"input_ids\"][i] = torch.tensor(labels[\"input_ids\"][i][:max_length])\n", " model_inputs[\"labels\"] = labels[\"input_ids\"]\n", " return model_inputs\n", "\n", "\n", "processed_datasets = dataset.map(\n", " preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "train_dataset = processed_datasets[\"train\"]\n", "eval_dataset = processed_datasets[\"train\"]\n", "\n", "\n", "train_dataloader = DataLoader(train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "eval_dataloader = DataLoader(eval_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)" ] }, { "cell_type": "code", "execution_count": 4, "id": "35d44b0c-1ec8-4ac2-8a94-f91af0639fa2", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " \r" ] }, { "data": { "text/plain": [ "{'input_ids': tensor([[ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 74757, 64626, 12384, 44639, 613,\n", " 52282, 2670, 79920, 3344, 1002, 368, 17646, 14472, 8348,\n", " 664, 718, 4, 19036, 17, 31849, 17, 6312, 76,\n", " 44, 62470, 56, 91, 50, 14839, 21, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 227985, 5484, 915, 405, 187059,\n", " 2256, 664, 2550, 18833, 18607, 162467, 4, 1387, 6199,\n", " 3291, 23405, 613, 4657, 17082, 566, 3432, 368, 78851,\n", " 1185, 61273, 23181, 1553, 15596, 212, 116057, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 39762, 2566, 22253, 6201, 75701, 15, 632, 718,\n", " 5840, 10006, 6201, 18881, 427, 3804, 19528, 267, 158974,\n", " 1320, 368, 10029, 632, 49666, 92, 34, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 227985, 5484, 915, 2566, 104565, 8695, 2089, 6140,\n", " 109676, 99579, 1369, 512, 368, 4570, 54, 632, 368,\n", " 1503, 241485, 132226, 15, 982, 727, 1152, 18100, 861,\n", " 32596, 77597, 168154, 1306, 132226, 4346, 87843, 17, 130462,\n", " 364, 32923, 89, 53, 8309, 20, 75, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 227985, 5484, 915, 2566,\n", " 14173, 2960, 29906, 387, 20706, 49337, 1369, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 227985, 5484, 915, 2566, 219553, 45736,\n", " 36876, 1713, 72, 707, 187205, 13002, 177324, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 233938, 28518, 13716,\n", " 427, 28146, 1119, 17918, 17, 236706, 368, 214997, 7555,\n", " 48659, 5276, 21600, 343, 17, 51416, 22403, 318, 1531,\n", " 1306, 1130, 20934, 567, 101161, 184849, 87843, 17, 1594,\n", " 15231, 2052, 16642, 20, 7180, 80, 26, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 80, 2068, 479, 2566, 80,\n", " 1376, 878, 147587, 3904, 632, 368, 6084, 65673, 78851,\n", " 11736, 15527, 19082, 33151, 461, 17, 45575, 17887, 632,\n", " 5219, 14216, 68870, 5967, 1841, 4346, 87843, 17, 1594,\n", " 14512, 27, 71, 8184, 19, 290, 63748, 77658, 915,\n", " 210]]),\n", " 'attention_mask': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def test_preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " model_inputs = tokenizer(inputs)\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (max_length - len(sample_input_ids)) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\"attention_mask\"][i]\n", " \n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " return model_inputs\n", "\n", "\n", "test_dataset = dataset[\"test\"].map(\n", " test_preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "test_dataloader = DataLoader(test_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "next(iter(test_dataloader))" ] }, { "cell_type": "code", "execution_count": 5, "id": "2a2bc53a-478e-4551-814b-bdbbb3725aa8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "trainable params: 172,032 || all params: 559,386,624 || trainable%: 0.0307536849504646\n" ] } ], "source": [ "model = AutoModelForCausalLM.from_pretrained(model_name_or_path)\n", "\n", "\n", "\n", "model = get_peft_model(model, peft_config)\n", "model.print_trainable_parameters()" ] }, { "cell_type": "code", "execution_count": 6, "id": "00bcf0da-6ad7-4451-a1d4-0c4d143235ab", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PeftModelForCausalLM(\n", " (base_model): IA3Model(\n", " (model): BloomForCausalLM(\n", " (transformer): BloomModel(\n", " (word_embeddings): Embedding(250880, 1024)\n", " (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (h): ModuleList(\n", " (0): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (1): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (2): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (3): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (4): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (5): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (6): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (7): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (8): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (9): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (10): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (11): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (12): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (13): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (14): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (15): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (16): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (17): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (18): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (19): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (20): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (21): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (22): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " (23): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 3072x1])\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(\n", " in_features=4096, out_features=1024, bias=True\n", " (ia3_l): ParameterDict( (default): Parameter containing: [torch.FloatTensor of size 1x4096])\n", " )\n", " )\n", " )\n", " )\n", " (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " )\n", " (lm_head): Linear(in_features=1024, out_features=250880, bias=False)\n", " )\n", " )\n", ")" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model" ] }, { "cell_type": "code", "execution_count": 7, "id": "efaa1106-7356-4597-a149-cc7643731533", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'default': IA3Config(peft_type=, auto_mapping=None, base_model_name_or_path='/data/nfs/llm/model/bloomz-560m', revision=None, task_type=, inference_mode=False, target_modules=['query_key_value', 'mlp.dense_4h_to_h'], feedforward_modules=['mlp.dense_4h_to_h'], fan_in_fan_out=False, modules_to_save=None, init_ia3_weights=True)}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.peft_config" ] }, { "cell_type": "code", "execution_count": 8, "id": "4a546452-e128-40fa-b72c-ba557d17a9f7", "metadata": {}, "outputs": [], "source": [ "# model\n", "# optimizer and lr scheduler\n", "optimizer = torch.optim.AdamW(model.parameters(), lr=lr)\n", "lr_scheduler = get_linear_schedule_with_warmup(\n", " optimizer=optimizer,\n", " num_warmup_steps=0,\n", " num_training_steps=(len(train_dataloader) * num_epochs),\n", ")" ] }, { "cell_type": "code", "execution_count": 9, "id": "b91ef03f-609e-4d2f-9f14-cc219f20c7a4", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:01<00:00, 5.03it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.78it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=0: train_ppl=tensor(2.4646e+10, device='cuda:0') train_epoch_loss=tensor(23.9279, device='cuda:0') eval_ppl=tensor(195.1290, device='cuda:0') eval_epoch_loss=tensor(5.2737, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.21it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 23.23it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=1: train_ppl=tensor(112.6432, device='cuda:0') train_epoch_loss=tensor(4.7242, device='cuda:0') eval_ppl=tensor(46.6624, device='cuda:0') eval_epoch_loss=tensor(3.8429, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.88it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.53it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=2: train_ppl=tensor(37.6138, device='cuda:0') train_epoch_loss=tensor(3.6274, device='cuda:0') eval_ppl=tensor(21.8593, device='cuda:0') eval_epoch_loss=tensor(3.0846, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.28it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 23.16it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=3: train_ppl=tensor(17.3817, device='cuda:0') train_epoch_loss=tensor(2.8554, device='cuda:0') eval_ppl=tensor(9.3968, device='cuda:0') eval_epoch_loss=tensor(2.2404, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.34it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.91it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=4: train_ppl=tensor(6.2920, device='cuda:0') train_epoch_loss=tensor(1.8393, device='cuda:0') eval_ppl=tensor(3.8994, device='cuda:0') eval_epoch_loss=tensor(1.3608, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.29it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 23.15it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=5: train_ppl=tensor(2.7512, device='cuda:0') train_epoch_loss=tensor(1.0120, device='cuda:0') eval_ppl=tensor(1.8104, device='cuda:0') eval_epoch_loss=tensor(0.5936, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.31it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 23.19it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=6: train_ppl=tensor(1.5378, device='cuda:0') train_epoch_loss=tensor(0.4303, device='cuda:0') eval_ppl=tensor(1.2499, device='cuda:0') eval_epoch_loss=tensor(0.2231, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.29it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.97it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=7: train_ppl=tensor(1.1984, device='cuda:0') train_epoch_loss=tensor(0.1810, device='cuda:0') eval_ppl=tensor(1.1350, device='cuda:0') eval_epoch_loss=tensor(0.1267, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.71it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 23.24it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=8: train_ppl=tensor(1.1170, device='cuda:0') train_epoch_loss=tensor(0.1106, device='cuda:0') eval_ppl=tensor(1.0947, device='cuda:0') eval_epoch_loss=tensor(0.0905, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.29it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.97it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=9: train_ppl=tensor(1.0917, device='cuda:0') train_epoch_loss=tensor(0.0877, device='cuda:0') eval_ppl=tensor(1.0843, device='cuda:0') eval_epoch_loss=tensor(0.0809, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "# training and evaluation\n", "model = model.to(device)\n", "\n", "for epoch in range(num_epochs):\n", " model.train()\n", " total_loss = 0\n", " for step, batch in enumerate(tqdm(train_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " # print(batch)\n", " # print(batch[\"input_ids\"].shape)\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " total_loss += loss.detach().float()\n", " loss.backward()\n", " optimizer.step()\n", " lr_scheduler.step()\n", " optimizer.zero_grad()\n", "\n", " model.eval()\n", " eval_loss = 0\n", " eval_preds = []\n", " for step, batch in enumerate(tqdm(eval_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " with torch.no_grad():\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " eval_loss += loss.detach().float()\n", " eval_preds.extend(\n", " tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), skip_special_tokens=True)\n", " )\n", "\n", " eval_epoch_loss = eval_loss / len(eval_dataloader)\n", " eval_ppl = torch.exp(eval_epoch_loss)\n", " train_epoch_loss = total_loss / len(train_dataloader)\n", " train_ppl = torch.exp(train_epoch_loss)\n", " print(f\"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=}\")" ] }, { "cell_type": "code", "execution_count": 10, "id": "67687ddb-7ad0-4609-bcf7-d530cb00631c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game.\n", "{'input_ids': tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210, 16449, 5952,\n", " 3]], device='cuda:0')\n", "[\"Tweet text : Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game. Label : complaint\"]\n" ] } ], "source": [ "# 模型评估\n", "model.eval()\n", "i = 16\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": 11, "id": "0f2a4aaa-49e6-466a-8eb6-6a6703390a8d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "model_output: /data/nfs/llm/model/bloomz-560m_IA3_CAUSAL_LM\n" ] } ], "source": [ "# saving model\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "print(\"model_output:\", peft_model_id)\n", "model.save_pretrained(peft_model_id)" ] }, { "cell_type": "code", "execution_count": 12, "id": "01c3a030-9336-45ee-b7e0-716223f76422", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "692K\t/data/nfs/llm/model/bloomz-560m_IA3_CAUSAL_LM/adapter_model.bin\n", "--------------\n", "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "/data/nfs/llm/model/bloomz-560m_IA3_CAUSAL_LM\n", "├── [ 398] adapter_config.json\n", "├── [689K] adapter_model.bin\n", "└── [ 129] README.md\n", "\n", "0 directories, 3 files\n" ] } ], "source": [ "ckpt = f\"{peft_model_id}/adapter_model.bin\"\n", "!du -h $ckpt\n", "print(\"--------------\")\n", "!tree -h $peft_model_id" ] }, { "cell_type": "code", "execution_count": 13, "id": "97363c9e-5aef-41d6-a2b7-9492f558c058", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "model_input: /data/nfs/llm/model/bloomz-560m_IA3_CAUSAL_LM\n" ] } ], "source": [ "from peft import PeftModel, PeftConfig\n", "\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "print(\"model_input:\", peft_model_id)\n", "\n", "config = PeftConfig.from_pretrained(peft_model_id)\n", "model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path)\n", "model = PeftModel.from_pretrained(model, peft_model_id)" ] }, { "cell_type": "code", "execution_count": 14, "id": "ea98ae02-dcf5-401d-989a-3155cfd44976", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "@greateranglia Ok thanks...\n", "{'input_ids': tensor([[227985, 5484, 915, 2566, 14173, 2960, 29906, 387, 20706,\n", " 49337, 1369, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 2566, 14173, 2960, 29906, 387, 20706,\n", " 49337, 1369, 77658, 915, 210, 1936, 106863, 3]],\n", " device='cuda:0')\n", "['Tweet text : @greateranglia Ok thanks... Label : no complaint']\n" ] } ], "source": [ "model.to(device)\n", "model.eval()\n", "i = 4\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": null, "id": "939ed30a-3ace-4419-8bd6-c2927dd92986", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-train/peft/clm/peft_lora_clm.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "id": "a63994ce-83d1-4c84-b372-2a1b6167f90a", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/guodong.li/virtual-venv/peft-venv-py310-cu117/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[2023-07-18 21:30:17,180] [INFO] [real_accelerator.py:133:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n" ] } ], "source": [ "from transformers import AutoModelForCausalLM\n", "from peft import get_peft_config, get_peft_model, get_peft_model_state_dict, LoraConfig, TaskType\n", "\n", "import torch\n", "from datasets import load_dataset\n", "import os\n", "from transformers import AutoTokenizer\n", "from torch.utils.data import DataLoader\n", "from transformers import default_data_collator, get_linear_schedule_with_warmup\n", "from tqdm import tqdm\n", "from datasets import load_dataset\n", "\n", "\n", "device = \"cuda\"\n", "\n", "model_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "tokenizer_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "\n", "peft_config = LoraConfig(task_type=TaskType.CAUSAL_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1)\n", "\n", "dataset_name = \"twitter_complaints\"\n", "checkpoint_name = f\"{dataset_name}_{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}_v1.pt\".replace(\"/\", \"_\")\n", "text_column = \"Tweet text\"\n", "label_column = \"text_label\"\n", "max_length = 64\n", "lr = 3e-2\n", "num_epochs = 10\n", "batch_size = 8" ] }, { "cell_type": "code", "execution_count": 2, "id": "89aff2bb-0dce-4b2c-908d-5c5363eab688", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Found cached dataset raft (/home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84)\n", "100%|██████████| 2/2 [00:00<00:00, 847.76it/s]\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-0e20fff6b1d898ca.arrow\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-8d14a62b8a688c19.arrow\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "['Unlabeled', 'complaint', 'no complaint']\n", "DatasetDict({\n", " train: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 50\n", " })\n", " test: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 3399\n", " })\n", "})\n" ] }, { "data": { "text/plain": [ "{'Tweet text': '@HMRCcustomers No this is my first job',\n", " 'ID': 0,\n", " 'Label': 2,\n", " 'text_label': 'no complaint'}" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from datasets import load_dataset\n", "\n", "# dataset = load_dataset(\"ought/raft\", dataset_name)\n", "dataset = load_dataset(\"/home/guodong.li/data/peft/raft/raft.py\", dataset_name, cache_dir=\"/home/guodong.li/data/peft/data\")\n", "\n", "classes = [k.replace(\"_\", \" \") for k in dataset[\"train\"].features[\"Label\"].names]\n", "print(classes)\n", "dataset = dataset.map(\n", " lambda x: {\"text_label\": [classes[label] for label in x[\"Label\"]]},\n", " batched=True,\n", " num_proc=1,\n", ")\n", "print(dataset)\n", "dataset[\"train\"][0]" ] }, { "cell_type": "code", "execution_count": 3, "id": "12494f57-2445-4297-9bae-c61a3fcb878d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "target_max_length: 3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " \r" ] } ], "source": [ "# data preprocessing\n", "tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)\n", "if tokenizer.pad_token_id is None:\n", " tokenizer.pad_token_id = tokenizer.eos_token_id\n", "target_max_length = max([len(tokenizer(class_label)[\"input_ids\"]) for class_label in classes])\n", "print(\"target_max_length:\", target_max_length)\n", "\n", "\n", "def preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " targets = [str(x) for x in examples[label_column]]\n", " model_inputs = tokenizer(inputs)\n", " labels = tokenizer(targets)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i] + [tokenizer.pad_token_id]\n", " # print(i, sample_input_ids, label_input_ids)\n", " model_inputs[\"input_ids\"][i] = sample_input_ids + label_input_ids\n", " labels[\"input_ids\"][i] = [-100] * len(sample_input_ids) + label_input_ids\n", " model_inputs[\"attention_mask\"][i] = [1] * len(model_inputs[\"input_ids\"][i])\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (\n", " max_length - len(sample_input_ids)\n", " ) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\n", " \"attention_mask\"\n", " ][i]\n", " labels[\"input_ids\"][i] = [-100] * (max_length - len(sample_input_ids)) + label_input_ids\n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " labels[\"input_ids\"][i] = torch.tensor(labels[\"input_ids\"][i][:max_length])\n", " model_inputs[\"labels\"] = labels[\"input_ids\"]\n", " return model_inputs\n", "\n", "\n", "processed_datasets = dataset.map(\n", " preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "train_dataset = processed_datasets[\"train\"]\n", "eval_dataset = processed_datasets[\"train\"]\n", "\n", "\n", "train_dataloader = DataLoader(train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "eval_dataloader = DataLoader(eval_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)" ] }, { "cell_type": "code", "execution_count": 4, "id": "35d44b0c-1ec8-4ac2-8a94-f91af0639fa2", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " \r" ] }, { "data": { "text/plain": [ "{'input_ids': tensor([[ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 74757, 64626, 12384, 44639, 613,\n", " 52282, 2670, 79920, 3344, 1002, 368, 17646, 14472, 8348,\n", " 664, 718, 4, 19036, 17, 31849, 17, 6312, 76,\n", " 44, 62470, 56, 91, 50, 14839, 21, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 227985, 5484, 915, 405, 187059,\n", " 2256, 664, 2550, 18833, 18607, 162467, 4, 1387, 6199,\n", " 3291, 23405, 613, 4657, 17082, 566, 3432, 368, 78851,\n", " 1185, 61273, 23181, 1553, 15596, 212, 116057, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 39762, 2566, 22253, 6201, 75701, 15, 632, 718,\n", " 5840, 10006, 6201, 18881, 427, 3804, 19528, 267, 158974,\n", " 1320, 368, 10029, 632, 49666, 92, 34, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 227985, 5484, 915, 2566, 104565, 8695, 2089, 6140,\n", " 109676, 99579, 1369, 512, 368, 4570, 54, 632, 368,\n", " 1503, 241485, 132226, 15, 982, 727, 1152, 18100, 861,\n", " 32596, 77597, 168154, 1306, 132226, 4346, 87843, 17, 130462,\n", " 364, 32923, 89, 53, 8309, 20, 75, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 227985, 5484, 915, 2566,\n", " 14173, 2960, 29906, 387, 20706, 49337, 1369, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 227985, 5484, 915, 2566, 219553, 45736,\n", " 36876, 1713, 72, 707, 187205, 13002, 177324, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 233938, 28518, 13716,\n", " 427, 28146, 1119, 17918, 17, 236706, 368, 214997, 7555,\n", " 48659, 5276, 21600, 343, 17, 51416, 22403, 318, 1531,\n", " 1306, 1130, 20934, 567, 101161, 184849, 87843, 17, 1594,\n", " 15231, 2052, 16642, 20, 7180, 80, 26, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 80, 2068, 479, 2566, 80,\n", " 1376, 878, 147587, 3904, 632, 368, 6084, 65673, 78851,\n", " 11736, 15527, 19082, 33151, 461, 17, 45575, 17887, 632,\n", " 5219, 14216, 68870, 5967, 1841, 4346, 87843, 17, 1594,\n", " 14512, 27, 71, 8184, 19, 290, 63748, 77658, 915,\n", " 210]]),\n", " 'attention_mask': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def test_preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " model_inputs = tokenizer(inputs)\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (max_length - len(sample_input_ids)) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\"attention_mask\"][i]\n", " \n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " return model_inputs\n", "\n", "\n", "test_dataset = dataset[\"test\"].map(\n", " test_preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "test_dataloader = DataLoader(test_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "next(iter(test_dataloader))" ] }, { "cell_type": "code", "execution_count": 5, "id": "2a2bc53a-478e-4551-814b-bdbbb3725aa8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "trainable params: 786,432 || all params: 560,001,024 || trainable%: 0.14043402892063284\n" ] } ], "source": [ "model = AutoModelForCausalLM.from_pretrained(model_name_or_path)\n", "model = get_peft_model(model, peft_config)\n", "model.print_trainable_parameters()" ] }, { "cell_type": "code", "execution_count": 6, "id": "00bcf0da-6ad7-4451-a1d4-0c4d143235ab", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PeftModelForCausalLM(\n", " (base_model): LoraModel(\n", " (model): BloomForCausalLM(\n", " (transformer): BloomModel(\n", " (word_embeddings): Embedding(250880, 1024)\n", " (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (h): ModuleList(\n", " (0): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (1): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (2): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (3): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (4): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (5): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (6): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (7): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (8): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (9): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (10): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (11): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (12): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (13): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (14): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (15): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (16): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (17): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (18): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (19): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (20): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (21): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (22): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (23): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(\n", " in_features=1024, out_features=3072, bias=True\n", " (lora_dropout): ModuleDict(\n", " (default): Dropout(p=0.1, inplace=False)\n", " )\n", " (lora_A): ModuleDict(\n", " (default): Linear(in_features=1024, out_features=8, bias=False)\n", " )\n", " (lora_B): ModuleDict(\n", " (default): Linear(in_features=8, out_features=3072, bias=False)\n", " )\n", " (lora_embedding_A): ParameterDict()\n", " (lora_embedding_B): ParameterDict()\n", " )\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " )\n", " (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " )\n", " (lm_head): Linear(in_features=1024, out_features=250880, bias=False)\n", " )\n", " )\n", ")" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model" ] }, { "cell_type": "code", "execution_count": 7, "id": "efaa1106-7356-4597-a149-cc7643731533", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'default': LoraConfig(peft_type=, auto_mapping=None, base_model_name_or_path='/data/nfs/llm/model/bloomz-560m', revision=None, task_type=, inference_mode=False, r=8, target_modules=['query_key_value'], lora_alpha=32, lora_dropout=0.1, fan_in_fan_out=False, bias='none', modules_to_save=None, init_lora_weights=True, layers_to_transform=None, layers_pattern=None)}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.peft_config" ] }, { "cell_type": "code", "execution_count": 8, "id": "4a546452-e128-40fa-b72c-ba557d17a9f7", "metadata": {}, "outputs": [], "source": [ "# model\n", "# optimizer and lr scheduler\n", "optimizer = torch.optim.AdamW(model.parameters(), lr=lr)\n", "lr_scheduler = get_linear_schedule_with_warmup(\n", " optimizer=optimizer,\n", " num_warmup_steps=0,\n", " num_training_steps=(len(train_dataloader) * num_epochs),\n", ")" ] }, { "cell_type": "code", "execution_count": 9, "id": "b91ef03f-609e-4d2f-9f14-cc219f20c7a4", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:01<00:00, 4.49it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.94it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=0: train_ppl=tensor(7.0119e+25, device='cuda:0') train_epoch_loss=tensor(59.5122, device='cuda:0') eval_ppl=tensor(2.6500e+13, device='cuda:0') eval_epoch_loss=tensor(30.9082, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.16it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.95it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=1: train_ppl=tensor(4.4497e+11, device='cuda:0') train_epoch_loss=tensor(26.8213, device='cuda:0') eval_ppl=tensor(59509564., device='cuda:0') eval_epoch_loss=tensor(17.9016, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.94it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 23.06it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=2: train_ppl=tensor(6.5751e+09, device='cuda:0') train_epoch_loss=tensor(22.6066, device='cuda:0') eval_ppl=tensor(4530818.5000, device='cuda:0') eval_epoch_loss=tensor(15.3264, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.04it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.90it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=3: train_ppl=tensor(6.5462e+08, device='cuda:0') train_epoch_loss=tensor(20.2996, device='cuda:0') eval_ppl=tensor(9.2159e+08, device='cuda:0') eval_epoch_loss=tensor(20.6416, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.15it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 23.07it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=4: train_ppl=tensor(61906716., device='cuda:0') train_epoch_loss=tensor(17.9411, device='cuda:0') eval_ppl=tensor(1936483.3750, device='cuda:0') eval_epoch_loss=tensor(14.4764, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.15it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 23.02it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=5: train_ppl=tensor(155084.5781, device='cuda:0') train_epoch_loss=tensor(11.9517, device='cuda:0') eval_ppl=tensor(7552.6094, device='cuda:0') eval_epoch_loss=tensor(8.9296, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.14it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 23.05it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=6: train_ppl=tensor(5289.7910, device='cuda:0') train_epoch_loss=tensor(8.5735, device='cuda:0') eval_ppl=tensor(2450.5276, device='cuda:0') eval_epoch_loss=tensor(7.8041, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.08it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.89it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=7: train_ppl=tensor(2616.7517, device='cuda:0') train_epoch_loss=tensor(7.8697, device='cuda:0') eval_ppl=tensor(2140.2886, device='cuda:0') eval_epoch_loss=tensor(7.6687, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.16it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.97it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=8: train_ppl=tensor(1483.9406, device='cuda:0') train_epoch_loss=tensor(7.3025, device='cuda:0') eval_ppl=tensor(1361.1847, device='cuda:0') eval_epoch_loss=tensor(7.2161, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.17it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.96it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=9: train_ppl=tensor(1103.2817, device='cuda:0') train_epoch_loss=tensor(7.0060, device='cuda:0') eval_ppl=tensor(1395.4637, device='cuda:0') eval_epoch_loss=tensor(7.2410, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "# training and evaluation\n", "model = model.to(device)\n", "\n", "for epoch in range(num_epochs):\n", " model.train()\n", " total_loss = 0\n", " for step, batch in enumerate(tqdm(train_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " # print(batch)\n", " # print(batch[\"input_ids\"].shape)\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " total_loss += loss.detach().float()\n", " loss.backward()\n", " optimizer.step()\n", " lr_scheduler.step()\n", " optimizer.zero_grad()\n", "\n", " model.eval()\n", " eval_loss = 0\n", " eval_preds = []\n", " for step, batch in enumerate(tqdm(eval_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " with torch.no_grad():\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " eval_loss += loss.detach().float()\n", " eval_preds.extend(\n", " tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), skip_special_tokens=True)\n", " )\n", "\n", " eval_epoch_loss = eval_loss / len(eval_dataloader)\n", " eval_ppl = torch.exp(eval_epoch_loss)\n", " train_epoch_loss = total_loss / len(train_dataloader)\n", " train_ppl = torch.exp(train_epoch_loss)\n", " print(f\"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=}\")" ] }, { "cell_type": "code", "execution_count": 10, "id": "67687ddb-7ad0-4609-bcf7-d530cb00631c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game.\n", "{'input_ids': tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210, 1936, 1936,\n", " 1936, 1936, 1936, 1936, 1936, 1936, 1936, 1936]],\n", " device='cuda:0')\n", "[\"Tweet text : Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game. Label : nononononononononono\"]\n" ] } ], "source": [ "# 模型评估\n", "model.eval()\n", "i = 16\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": 11, "id": "0f2a4aaa-49e6-466a-8eb6-6a6703390a8d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "model_output: /data/nfs/llm/model/bloomz-560m_LORA_CAUSAL_LM\n" ] } ], "source": [ "# saving model\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "print(\"model_output:\", peft_model_id)\n", "model.save_pretrained(peft_model_id)" ] }, { "cell_type": "code", "execution_count": 12, "id": "01c3a030-9336-45ee-b7e0-716223f76422", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "3.1M\t/data/nfs/llm/model/bloomz-560m_LORA_CAUSAL_LM/adapter_model.bin\n", "--------------\n", "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "/data/nfs/llm/model/bloomz-560m_LORA_CAUSAL_LM\n", "├── [ 447] adapter_config.json\n", "├── [3.0M] adapter_model.bin\n", "└── [ 147] README.md\n", "\n", "0 directories, 3 files\n" ] } ], "source": [ "ckpt = f\"{peft_model_id}/adapter_model.bin\"\n", "!du -h $ckpt\n", "print(\"--------------\")\n", "!tree -h $peft_model_id" ] }, { "cell_type": "code", "execution_count": 13, "id": "97363c9e-5aef-41d6-a2b7-9492f558c058", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "model_input: /data/nfs/llm/model/bloomz-560m_LORA_CAUSAL_LM\n" ] } ], "source": [ "from peft import PeftModel, PeftConfig\n", "\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "print(\"model_input:\", peft_model_id)\n", "\n", "config = PeftConfig.from_pretrained(peft_model_id)\n", "model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path)\n", "model = PeftModel.from_pretrained(model, peft_model_id)" ] }, { "cell_type": "code", "execution_count": 14, "id": "ea98ae02-dcf5-401d-989a-3155cfd44976", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "@greateranglia Ok thanks...\n", "{'input_ids': tensor([[227985, 5484, 915, 2566, 14173, 2960, 29906, 387, 20706,\n", " 49337, 1369, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 2566, 14173, 2960, 29906, 387, 20706,\n", " 49337, 1369, 77658, 915, 210, 1936, 1936, 1936, 1936,\n", " 1936, 1936, 1936, 1936, 1936, 1936]], device='cuda:0')\n", "['Tweet text : @greateranglia Ok thanks... Label : nononononononononono']\n" ] } ], "source": [ "model.to(device)\n", "model.eval()\n", "i = 4\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-train/peft/clm/peft_lora_clm_accelerate_ds_zero3_offload.py ================================================ import gc import os import sys import threading import numpy as np import psutil import torch from accelerate import Accelerator from datasets import load_dataset from torch.utils.data import DataLoader from tqdm import tqdm from transformers import ( AutoModelForCausalLM, AutoTokenizer, default_data_collator, get_linear_schedule_with_warmup, set_seed, ) from peft import LoraConfig, TaskType, get_peft_model def levenshtein_distance(str1, str2): # TC: O(N^2) # SC: O(N^2) if str1 == str2: return 0 num_rows = len(str1) + 1 num_cols = len(str2) + 1 dp_matrix = np.empty((num_rows, num_cols)) dp_matrix[0, :] = range(num_cols) dp_matrix[:, 0] = range(num_rows) for i in range(1, num_rows): for j in range(1, num_cols): if str1[i - 1] == str2[j - 1]: dp_matrix[i, j] = dp_matrix[i - 1, j - 1] else: dp_matrix[i, j] = min(dp_matrix[i - 1, j - 1], dp_matrix[i - 1, j], dp_matrix[i, j - 1]) + 1 return dp_matrix[num_rows - 1, num_cols - 1] def get_closest_label(eval_pred, classes): min_id = sys.maxsize min_edit_distance = sys.maxsize for i, class_label in enumerate(classes): edit_distance = levenshtein_distance(eval_pred.strip(), class_label) if edit_distance < min_edit_distance: min_id = i min_edit_distance = edit_distance return classes[min_id] # Converting Bytes to Megabytes def b2mb(x): return int(x / 2**20) # This context manager is used to track the peak memory usage of the process class TorchTracemalloc: def __enter__(self): gc.collect() torch.cuda.empty_cache() torch.cuda.reset_max_memory_allocated() # reset the peak gauge to zero self.begin = torch.cuda.memory_allocated() self.process = psutil.Process() self.cpu_begin = self.cpu_mem_used() self.peak_monitoring = True peak_monitor_thread = threading.Thread(target=self.peak_monitor_func) peak_monitor_thread.daemon = True peak_monitor_thread.start() return self def cpu_mem_used(self): """get resident set size memory for the current process""" return self.process.memory_info().rss def peak_monitor_func(self): self.cpu_peak = -1 while True: self.cpu_peak = max(self.cpu_mem_used(), self.cpu_peak) # can't sleep or will not catch the peak right (this comment is here on purpose) # time.sleep(0.001) # 1msec if not self.peak_monitoring: break def __exit__(self, *exc): self.peak_monitoring = False gc.collect() torch.cuda.empty_cache() self.end = torch.cuda.memory_allocated() self.peak = torch.cuda.max_memory_allocated() self.used = b2mb(self.end - self.begin) self.peaked = b2mb(self.peak - self.begin) self.cpu_end = self.cpu_mem_used() self.cpu_used = b2mb(self.cpu_end - self.cpu_begin) self.cpu_peaked = b2mb(self.cpu_peak - self.cpu_begin) # print(f"delta used/peak {self.used:4d}/{self.peaked:4d}") def main(): accelerator = Accelerator() # TODO model_name_or_path = "/data/nfs/llm/model/bloomz-560m" dataset_name = "twitter_complaints" peft_config = LoraConfig(task_type=TaskType.CAUSAL_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1) text_column = "Tweet text" label_column = "text_label" lr = 3e-3 num_epochs = 10 batch_size = 8 seed = 42 max_length = 64 do_test = False set_seed(seed) # TODO # dataset = load_dataset("ought/raft", dataset_name) dataset = load_dataset("/home/guodong.li/data/peft/raft/raft.py", dataset_name, cache_dir="/home/guodong.li/data/peft/data") classes = [k.replace("_", " ") for k in dataset["train"].features["Label"].names] dataset = dataset.map( lambda x: {"text_label": [classes[label] for label in x["Label"]]}, batched=True, num_proc=1, ) tokenizer = AutoTokenizer.from_pretrained(model_name_or_path) def preprocess_function(examples): batch_size = len(examples[text_column]) inputs = [f"{text_column} : {x} Label : " for x in examples[text_column]] targets = [str(x) for x in examples[label_column]] model_inputs = tokenizer(inputs) labels = tokenizer(targets) for i in range(batch_size): sample_input_ids = model_inputs["input_ids"][i] label_input_ids = labels["input_ids"][i] + [tokenizer.pad_token_id] model_inputs["input_ids"][i] = sample_input_ids + label_input_ids labels["input_ids"][i] = [-100] * len(sample_input_ids) + label_input_ids model_inputs["attention_mask"][i] = [1] * len(model_inputs["input_ids"][i]) for i in range(batch_size): sample_input_ids = model_inputs["input_ids"][i] label_input_ids = labels["input_ids"][i] model_inputs["input_ids"][i] = [tokenizer.pad_token_id] * ( max_length - len(sample_input_ids) ) + sample_input_ids model_inputs["attention_mask"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[ "attention_mask" ][i] labels["input_ids"][i] = [-100] * (max_length - len(sample_input_ids)) + label_input_ids model_inputs["input_ids"][i] = torch.tensor(model_inputs["input_ids"][i][:max_length]) model_inputs["attention_mask"][i] = torch.tensor(model_inputs["attention_mask"][i][:max_length]) labels["input_ids"][i] = torch.tensor(labels["input_ids"][i][:max_length]) model_inputs["labels"] = labels["input_ids"] return model_inputs def test_preprocess_function(examples): batch_size = len(examples[text_column]) inputs = [f"{text_column} : {x} Label : " for x in examples[text_column]] model_inputs = tokenizer(inputs) # print(model_inputs) for i in range(batch_size): sample_input_ids = model_inputs["input_ids"][i] model_inputs["input_ids"][i] = [tokenizer.pad_token_id] * ( max_length - len(sample_input_ids) ) + sample_input_ids model_inputs["attention_mask"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[ "attention_mask" ][i] model_inputs["input_ids"][i] = torch.tensor(model_inputs["input_ids"][i][:max_length]) model_inputs["attention_mask"][i] = torch.tensor(model_inputs["attention_mask"][i][:max_length]) return model_inputs with accelerator.main_process_first(): processed_datasets = dataset.map( preprocess_function, batched=True, num_proc=1, remove_columns=dataset["train"].column_names, load_from_cache_file=True, desc="Running tokenizer on dataset", ) accelerator.wait_for_everyone() train_dataset = processed_datasets["train"] with accelerator.main_process_first(): processed_datasets = dataset.map( test_preprocess_function, batched=True, num_proc=1, remove_columns=dataset["train"].column_names, load_from_cache_file=False, desc="Running tokenizer on dataset", ) eval_dataset = processed_datasets["train"] test_dataset = processed_datasets["test"] train_dataloader = DataLoader( train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True ) eval_dataloader = DataLoader( eval_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True ) test_dataloader = DataLoader( test_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True ) print(next(iter(train_dataloader))) # creating model model = AutoModelForCausalLM.from_pretrained(model_name_or_path) model = get_peft_model(model, peft_config) model.print_trainable_parameters() # optimizer optimizer = torch.optim.AdamW(model.parameters(), lr=lr) # lr scheduler lr_scheduler = get_linear_schedule_with_warmup( optimizer=optimizer, num_warmup_steps=0, num_training_steps=(len(train_dataloader) * num_epochs), ) model, train_dataloader, eval_dataloader, test_dataloader, optimizer, lr_scheduler = accelerator.prepare( model, train_dataloader, eval_dataloader, test_dataloader, optimizer, lr_scheduler ) accelerator.print(model) is_ds_zero_3 = False if getattr(accelerator.state, "deepspeed_plugin", None): is_ds_zero_3 = accelerator.state.deepspeed_plugin.zero_stage == 3 for epoch in range(num_epochs): with TorchTracemalloc() as tracemalloc: model.train() total_loss = 0 for step, batch in enumerate(tqdm(train_dataloader)): outputs = model(**batch) loss = outputs.loss total_loss += loss.detach().float() accelerator.backward(loss) optimizer.step() lr_scheduler.step() optimizer.zero_grad() # Printing the GPU memory usage details such as allocated memory, peak memory, and total memory usage accelerator.print("GPU Memory before entering the train : {}".format(b2mb(tracemalloc.begin))) accelerator.print("GPU Memory consumed at the end of the train (end-begin): {}".format(tracemalloc.used)) accelerator.print("GPU Peak Memory consumed during the train (max-begin): {}".format(tracemalloc.peaked)) accelerator.print( "GPU Total Peak Memory consumed during the train (max): {}".format( tracemalloc.peaked + b2mb(tracemalloc.begin) ) ) accelerator.print("CPU Memory before entering the train : {}".format(b2mb(tracemalloc.cpu_begin))) accelerator.print("CPU Memory consumed at the end of the train (end-begin): {}".format(tracemalloc.cpu_used)) accelerator.print("CPU Peak Memory consumed during the train (max-begin): {}".format(tracemalloc.cpu_peaked)) accelerator.print( "CPU Total Peak Memory consumed during the train (max): {}".format( tracemalloc.cpu_peaked + b2mb(tracemalloc.cpu_begin) ) ) train_epoch_loss = total_loss / len(train_dataloader) train_ppl = torch.exp(train_epoch_loss) accelerator.print(f"{epoch=}: {train_ppl=} {train_epoch_loss=}") model.eval() eval_preds = [] with TorchTracemalloc() as tracemalloc: for _, batch in enumerate(tqdm(eval_dataloader)): batch = {k: v for k, v in batch.items() if k != "labels"} with torch.no_grad(): outputs = accelerator.unwrap_model(model).generate( **batch, synced_gpus=is_ds_zero_3, max_new_tokens=10 ) # synced_gpus=True for DS-stage 3 outputs = accelerator.pad_across_processes(outputs, dim=1, pad_index=tokenizer.pad_token_id) preds = accelerator.gather_for_metrics(outputs) preds = preds[:, max_length:].detach().cpu().numpy() eval_preds.extend(tokenizer.batch_decode(preds, skip_special_tokens=True)) # Printing the GPU memory usage details such as allocated memory, peak memory, and total memory usage accelerator.print("GPU Memory before entering the eval : {}".format(b2mb(tracemalloc.begin))) accelerator.print("GPU Memory consumed at the end of the eval (end-begin): {}".format(tracemalloc.used)) accelerator.print("GPU Peak Memory consumed during the eval (max-begin): {}".format(tracemalloc.peaked)) accelerator.print( "GPU Total Peak Memory consumed during the eval (max): {}".format( tracemalloc.peaked + b2mb(tracemalloc.begin) ) ) accelerator.print("CPU Memory before entering the eval : {}".format(b2mb(tracemalloc.cpu_begin))) accelerator.print("CPU Memory consumed at the end of the eval (end-begin): {}".format(tracemalloc.cpu_used)) accelerator.print("CPU Peak Memory consumed during the eval (max-begin): {}".format(tracemalloc.cpu_peaked)) accelerator.print( "CPU Total Peak Memory consumed during the eval (max): {}".format( tracemalloc.cpu_peaked + b2mb(tracemalloc.cpu_begin) ) ) correct = 0 total = 0 assert len(eval_preds) == len( dataset["train"][label_column] ), f"{len(eval_preds)} != {len(dataset['train'][label_column])}" for pred, true in zip(eval_preds, dataset["train"][label_column]): if pred.strip() == true.strip(): correct += 1 total += 1 accuracy = correct / total * 100 accelerator.print(f"{accuracy=}") accelerator.print(f"{eval_preds[:10]=}") accelerator.print(f"{dataset['train'][label_column][:10]=}") if do_test: model.eval() test_preds = [] for _, batch in enumerate(tqdm(test_dataloader)): batch = {k: v for k, v in batch.items() if k != "labels"} with torch.no_grad(): outputs = accelerator.unwrap_model(model).generate( **batch, synced_gpus=is_ds_zero_3, max_new_tokens=10 ) # synced_gpus=True for DS-stage 3 outputs = accelerator.pad_across_processes(outputs, dim=1, pad_index=tokenizer.pad_token_id) preds = accelerator.gather(outputs) preds = preds[:, max_length:].detach().cpu().numpy() test_preds.extend(tokenizer.batch_decode(preds, skip_special_tokens=True)) test_preds_cleaned = [] for _, pred in enumerate(test_preds): test_preds_cleaned.append(get_closest_label(pred, classes)) test_df = dataset["test"].to_pandas() assert len(test_preds_cleaned) == len(test_df), f"{len(test_preds_cleaned)} != {len(test_df)}" test_df[label_column] = test_preds_cleaned test_df["text_labels_orig"] = test_preds accelerator.print(test_df[[text_column, label_column]].sample(20)) pred_df = test_df[["ID", label_column]] pred_df.columns = ["ID", "Label"] os.makedirs(f"data/{dataset_name}", exist_ok=True) pred_df.to_csv(f"data/{dataset_name}/predictions.csv", index=False) accelerator.wait_for_everyone() # model.push_to_hub( # "smangrul/" # + f"{dataset_name}_{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}".replace("/", "_"), # state_dict=accelerator.get_state_dict(model), # use_auth_token=True, # ) model_output = f"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}" print("model_output:", model_output) model.save_pretrained(model_output) accelerator.wait_for_everyone() if __name__ == "__main__": main() ================================================ FILE: llm-train/peft/clm/peft_p_tuning_clm.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "id": "d2f9225b-17c7-47fd-a8b2-7b755c08713f", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/guodong.li/virtual-venv/peft-venv-py310-cu117/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[2023-07-19 19:02:06,848] [INFO] [real_accelerator.py:133:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n" ] } ], "source": [ "from transformers import AutoModelForCausalLM\n", "from peft import (\n", " get_peft_config,\n", " get_peft_model,\n", " get_peft_model_state_dict,\n", " set_peft_model_state_dict,\n", " PeftType,\n", " TaskType,\n", " PromptEncoderConfig,\n", ")\n", "\n", "import torch\n", "from datasets import load_dataset\n", "import os\n", "from transformers import AutoTokenizer\n", "from torch.utils.data import DataLoader\n", "from transformers import default_data_collator, get_linear_schedule_with_warmup\n", "from tqdm import tqdm\n", "from datasets import load_dataset\n", "\n", "\n", "device = \"cuda\"\n", "\n", "model_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "tokenizer_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "\n", "peft_config = PromptEncoderConfig(task_type=TaskType.CAUSAL_LM, num_virtual_tokens=20, encoder_hidden_size=128)\n", "\n", "dataset_name = \"twitter_complaints\"\n", "checkpoint_name = f\"{dataset_name}_{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}_v1.pt\".replace(\"/\", \"_\")\n", "text_column = \"Tweet text\"\n", "label_column = \"text_label\"\n", "max_length = 64\n", "lr = 3e-2\n", "num_epochs = 10\n", "batch_size = 8" ] }, { "cell_type": "code", "execution_count": 2, "id": "551bfa31-cf73-41f4-bdb7-07c492089310", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Found cached dataset raft (/home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84)\n", "100%|██████████| 2/2 [00:00<00:00, 450.13it/s]\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-0e20fff6b1d898ca.arrow\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-8d14a62b8a688c19.arrow\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "['Unlabeled', 'complaint', 'no complaint']\n", "DatasetDict({\n", " train: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 50\n", " })\n", " test: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 3399\n", " })\n", "})\n" ] }, { "data": { "text/plain": [ "{'Tweet text': '@HMRCcustomers No this is my first job',\n", " 'ID': 0,\n", " 'Label': 2,\n", " 'text_label': 'no complaint'}" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from datasets import load_dataset\n", "\n", "# dataset = load_dataset(\"ought/raft\", dataset_name)\n", "dataset = load_dataset(\"/home/guodong.li/data/peft/raft/raft.py\", dataset_name, cache_dir=\"/home/guodong.li/data/peft/data\")\n", "\n", "classes = [k.replace(\"_\", \" \") for k in dataset[\"train\"].features[\"Label\"].names]\n", "print(classes)\n", "dataset = dataset.map(\n", " lambda x: {\"text_label\": [classes[label] for label in x[\"Label\"]]},\n", " batched=True,\n", " num_proc=1,\n", ")\n", "print(dataset)\n", "dataset[\"train\"][0]" ] }, { "cell_type": "code", "execution_count": 3, "id": "388dabbe-e7a8-4a61-98dc-0e1ccea86b0d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "target_max_length: 3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " \r" ] } ], "source": [ "# data preprocessing\n", "# padding_side = \"left\"\n", "# tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, padding_side=padding_side)\n", "tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)\n", "if tokenizer.pad_token_id is None:\n", " tokenizer.pad_token_id = tokenizer.eos_token_id\n", "target_max_length = max([len(tokenizer(class_label)[\"input_ids\"]) for class_label in classes])\n", "print(\"target_max_length:\", target_max_length)\n", "\n", "\n", "def preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " targets = [str(x) for x in examples[label_column]]\n", " model_inputs = tokenizer(inputs)\n", " labels = tokenizer(targets)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i] + [tokenizer.pad_token_id]\n", " # print(i, sample_input_ids, label_input_ids)\n", " model_inputs[\"input_ids\"][i] = sample_input_ids + label_input_ids\n", " labels[\"input_ids\"][i] = [-100] * len(sample_input_ids) + label_input_ids\n", " model_inputs[\"attention_mask\"][i] = [1] * len(model_inputs[\"input_ids\"][i])\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (\n", " max_length - len(sample_input_ids)\n", " ) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\n", " \"attention_mask\"\n", " ][i]\n", " labels[\"input_ids\"][i] = [-100] * (max_length - len(sample_input_ids)) + label_input_ids\n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " labels[\"input_ids\"][i] = torch.tensor(labels[\"input_ids\"][i][:max_length])\n", " model_inputs[\"labels\"] = labels[\"input_ids\"]\n", " return model_inputs\n", "\n", "\n", "processed_datasets = dataset.map(\n", " preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "train_dataset = processed_datasets[\"train\"]\n", "eval_dataset = processed_datasets[\"train\"]\n", "\n", "\n", "train_dataloader = DataLoader(train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "eval_dataloader = DataLoader(eval_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)" ] }, { "cell_type": "code", "execution_count": 4, "id": "2e0999b0-89c3-4389-a2a4-3dfe0d4040b9", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " \r" ] }, { "data": { "text/plain": [ "{'input_ids': tensor([[ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 74757, 64626, 12384, 44639, 613,\n", " 52282, 2670, 79920, 3344, 1002, 368, 17646, 14472, 8348,\n", " 664, 718, 4, 19036, 17, 31849, 17, 6312, 76,\n", " 44, 62470, 56, 91, 50, 14839, 21, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 227985, 5484, 915, 405, 187059,\n", " 2256, 664, 2550, 18833, 18607, 162467, 4, 1387, 6199,\n", " 3291, 23405, 613, 4657, 17082, 566, 3432, 368, 78851,\n", " 1185, 61273, 23181, 1553, 15596, 212, 116057, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 39762, 2566, 22253, 6201, 75701, 15, 632, 718,\n", " 5840, 10006, 6201, 18881, 427, 3804, 19528, 267, 158974,\n", " 1320, 368, 10029, 632, 49666, 92, 34, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 227985, 5484, 915, 2566, 104565, 8695, 2089, 6140,\n", " 109676, 99579, 1369, 512, 368, 4570, 54, 632, 368,\n", " 1503, 241485, 132226, 15, 982, 727, 1152, 18100, 861,\n", " 32596, 77597, 168154, 1306, 132226, 4346, 87843, 17, 130462,\n", " 364, 32923, 89, 53, 8309, 20, 75, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 227985, 5484, 915, 2566,\n", " 14173, 2960, 29906, 387, 20706, 49337, 1369, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 227985, 5484, 915, 2566, 219553, 45736,\n", " 36876, 1713, 72, 707, 187205, 13002, 177324, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 233938, 28518, 13716,\n", " 427, 28146, 1119, 17918, 17, 236706, 368, 214997, 7555,\n", " 48659, 5276, 21600, 343, 17, 51416, 22403, 318, 1531,\n", " 1306, 1130, 20934, 567, 101161, 184849, 87843, 17, 1594,\n", " 15231, 2052, 16642, 20, 7180, 80, 26, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 80, 2068, 479, 2566, 80,\n", " 1376, 878, 147587, 3904, 632, 368, 6084, 65673, 78851,\n", " 11736, 15527, 19082, 33151, 461, 17, 45575, 17887, 632,\n", " 5219, 14216, 68870, 5967, 1841, 4346, 87843, 17, 1594,\n", " 14512, 27, 71, 8184, 19, 290, 63748, 77658, 915,\n", " 210]]),\n", " 'attention_mask': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def test_preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " model_inputs = tokenizer(inputs)\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (max_length - len(sample_input_ids)) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\"attention_mask\"][i]\n", " \n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " return model_inputs\n", "\n", "\n", "test_dataset = dataset[\"test\"].map(\n", " test_preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "test_dataloader = DataLoader(test_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "next(iter(test_dataloader))" ] }, { "cell_type": "code", "execution_count": 5, "id": "fb3bae27-7764-4938-b5c2-f97882c42d58", "metadata": {}, "outputs": [], "source": [ "model = AutoModelForCausalLM.from_pretrained(model_name_or_path)\n" ] }, { "cell_type": "code", "execution_count": 6, "id": "97c1c175-3024-47cf-b337-90d12d57f3a1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BloomForCausalLM(\n", " (transformer): BloomModel(\n", " (word_embeddings): Embedding(250880, 1024)\n", " (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (h): ModuleList(\n", " (0): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (1): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (2): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (3): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (4): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (5): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (6): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (7): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (8): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (9): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (10): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (11): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (12): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (13): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (14): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (15): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (16): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (17): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (18): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (19): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (20): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (21): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (22): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (23): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " )\n", " (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " )\n", " (lm_head): Linear(in_features=1024, out_features=250880, bias=False)\n", ")" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model" ] }, { "cell_type": "code", "execution_count": 7, "id": "38775c10-f960-4ecb-821f-aefd61447a58", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "trainable params: 300,288 || all params: 559,514,880 || trainable%: 0.05366935013417338\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/home/guodong.li/code/peft-20230717/src/peft/tuners/p_tuning.py:146: UserWarning: for MLP, the `encoder_num_layers` is ignored. Exactly 2 MLP layers are used.\n", " warnings.warn(\n" ] } ], "source": [ "model = get_peft_model(model, peft_config)\n", "model.print_trainable_parameters()" ] }, { "cell_type": "code", "execution_count": 8, "id": "2fc154f4-7438-474e-91e0-23a24f97610d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PeftModelForCausalLM(\n", " (base_model): BloomForCausalLM(\n", " (transformer): BloomModel(\n", " (word_embeddings): Embedding(250880, 1024)\n", " (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (h): ModuleList(\n", " (0): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (1): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (2): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (3): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (4): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (5): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (6): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (7): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (8): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (9): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (10): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (11): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (12): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (13): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (14): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (15): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (16): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (17): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (18): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (19): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (20): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (21): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (22): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (23): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " )\n", " (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " )\n", " (lm_head): Linear(in_features=1024, out_features=250880, bias=False)\n", " )\n", " (prompt_encoder): ModuleDict(\n", " (default): PromptEncoder(\n", " (embedding): Embedding(20, 1024)\n", " (mlp_head): Sequential(\n", " (0): Linear(in_features=1024, out_features=128, bias=True)\n", " (1): ReLU()\n", " (2): Linear(in_features=128, out_features=128, bias=True)\n", " (3): ReLU()\n", " (4): Linear(in_features=128, out_features=1024, bias=True)\n", " )\n", " )\n", " )\n", " (word_embeddings): Embedding(250880, 1024)\n", ")" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model" ] }, { "cell_type": "code", "execution_count": 9, "id": "3fa62df7-b3c2-4833-87aa-0f7ad60d7f6e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'default': PromptEncoderConfig(peft_type=, auto_mapping=None, base_model_name_or_path='/data/nfs/llm/model/bloomz-560m', revision=None, task_type=, inference_mode=False, num_virtual_tokens=20, token_dim=1024, num_transformer_submodules=1, num_attention_heads=16, num_layers=24, encoder_reparameterization_type=, encoder_hidden_size=128, encoder_num_layers=2, encoder_dropout=0.0)}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.peft_config" ] }, { "cell_type": "code", "execution_count": 10, "id": "b57a6ed4-f4d0-4215-9871-d72648939f5c", "metadata": {}, "outputs": [], "source": [ "# model\n", "# optimizer and lr scheduler\n", "optimizer = torch.optim.AdamW(model.parameters(), lr=lr)\n", "lr_scheduler = get_linear_schedule_with_warmup(\n", " optimizer=optimizer,\n", " num_warmup_steps=0,\n", " num_training_steps=(len(train_dataloader) * num_epochs),\n", ")" ] }, { "cell_type": "code", "execution_count": 11, "id": "4b521208-262a-4afc-ac1d-b3a2594ed9ec", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:01<00:00, 4.66it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 16.60it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=0: train_ppl=tensor(1.4019e+23, device='cuda:0') train_epoch_loss=tensor(53.2973, device='cuda:0') eval_ppl=tensor(1.5565e+22, device='cuda:0') eval_epoch_loss=tensor(51.0993, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 9.08it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.60it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=1: train_ppl=tensor(3.4324e+14, device='cuda:0') train_epoch_loss=tensor(33.4694, device='cuda:0') eval_ppl=tensor(694663.1250, device='cuda:0') eval_epoch_loss=tensor(13.4512, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 9.15it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.51it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=2: train_ppl=tensor(594353.6875, device='cuda:0') train_epoch_loss=tensor(13.2952, device='cuda:0') eval_ppl=tensor(450830.4062, device='cuda:0') eval_epoch_loss=tensor(13.0188, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 9.12it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.51it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=3: train_ppl=tensor(673112.8125, device='cuda:0') train_epoch_loss=tensor(13.4197, device='cuda:0') eval_ppl=tensor(385877.5938, device='cuda:0') eval_epoch_loss=tensor(12.8633, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.92it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 16.12it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=4: train_ppl=tensor(565632.5625, device='cuda:0') train_epoch_loss=tensor(13.2457, device='cuda:0') eval_ppl=tensor(309009., device='cuda:0') eval_epoch_loss=tensor(12.6411, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.93it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.41it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=5: train_ppl=tensor(428292.1250, device='cuda:0') train_epoch_loss=tensor(12.9676, device='cuda:0') eval_ppl=tensor(264157.9688, device='cuda:0') eval_epoch_loss=tensor(12.4843, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 9.06it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.46it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=6: train_ppl=tensor(378711.1875, device='cuda:0') train_epoch_loss=tensor(12.8445, device='cuda:0') eval_ppl=tensor(251440.4219, device='cuda:0') eval_epoch_loss=tensor(12.4350, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 9.17it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.47it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=7: train_ppl=tensor(289856.9375, device='cuda:0') train_epoch_loss=tensor(12.5771, device='cuda:0') eval_ppl=tensor(242582.3281, device='cuda:0') eval_epoch_loss=tensor(12.3991, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 9.20it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 15.88it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=8: train_ppl=tensor(348310.9688, device='cuda:0') train_epoch_loss=tensor(12.7609, device='cuda:0') eval_ppl=tensor(234650.7188, device='cuda:0') eval_epoch_loss=tensor(12.3659, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.99it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.26it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=9: train_ppl=tensor(344919.1250, device='cuda:0') train_epoch_loss=tensor(12.7511, device='cuda:0') eval_ppl=tensor(231422.7031, device='cuda:0') eval_epoch_loss=tensor(12.3520, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "# training and evaluation\n", "model = model.to(device)\n", "\n", "for epoch in range(num_epochs):\n", " model.train()\n", " total_loss = 0\n", " for step, batch in enumerate(tqdm(train_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " # print(batch)\n", " # print(batch[\"input_ids\"].shape)\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " total_loss += loss.detach().float()\n", " loss.backward()\n", " optimizer.step()\n", " lr_scheduler.step()\n", " optimizer.zero_grad()\n", "\n", " model.eval()\n", " eval_loss = 0\n", " eval_preds = []\n", " for step, batch in enumerate(tqdm(eval_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " with torch.no_grad():\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " eval_loss += loss.detach().float()\n", " eval_preds.extend(\n", " tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), skip_special_tokens=True)\n", " )\n", "\n", " eval_epoch_loss = eval_loss / len(eval_dataloader)\n", " eval_ppl = torch.exp(eval_epoch_loss)\n", " train_epoch_loss = total_loss / len(train_dataloader)\n", " train_ppl = torch.exp(train_epoch_loss)\n", " print(f\"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=}\")" ] }, { "cell_type": "code", "execution_count": 12, "id": "5f7ac5e9-7d52-447e-bf8e-8750cabcb158", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game.\n", "{'input_ids': tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210, 2550, 2,\n", " 36, 17, 1387, 51216, 632, 7220, 2, 36]],\n", " device='cuda:0')\n", "[\"Tweet text : Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game. Label : #A. The weather is goodA\"]\n" ] } ], "source": [ "# 模型评估\n", "model.eval()\n", "i = 16\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": 13, "id": "336e97c4-1706-4941-8bb3-34634cf83b32", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "model_output: /data/nfs/llm/model/bloomz-560m_P_TUNING_CAUSAL_LM\n" ] } ], "source": [ "# saving model\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "print(\"model_output:\", peft_model_id)\n", "model.save_pretrained(peft_model_id)" ] }, { "cell_type": "code", "execution_count": 14, "id": "13b6ec0c-4bd1-44dc-8a09-bff9c940a87c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "84K\t/data/nfs/llm/model/bloomz-560m_P_TUNING_CAUSAL_LM/adapter_model.bin\n", "--------------\n", "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "/data/nfs/llm/model/bloomz-560m_P_TUNING_CAUSAL_LM\n", "├── [ 451] adapter_config.json\n", "├── [ 81K] adapter_model.bin\n", "└── [ 129] README.md\n", "\n", "0 directories, 3 files\n" ] } ], "source": [ "ckpt = f\"{peft_model_id}/adapter_model.bin\"\n", "!du -h $ckpt\n", "print(\"--------------\")\n", "!tree -h $peft_model_id" ] }, { "cell_type": "code", "execution_count": null, "id": "6ea31e8d-145a-45d0-8331-3c94ba980f15", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "model_input: /data/nfs/llm/model/bloomz-560m_P_TUNING_CAUSAL_LM\n" ] } ], "source": [ "from peft import PeftModel, PeftConfig\n", "\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "print(\"model_input:\", peft_model_id)\n", "\n", "config = PeftConfig.from_pretrained(peft_model_id)\n", "model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path)\n", "model = PeftModel.from_pretrained(model, peft_model_id)" ] }, { "cell_type": "code", "execution_count": null, "id": "91c9a1b4-f384-451f-8359-538692f02ada", "metadata": {}, "outputs": [], "source": [ "model.to(device)\n", "model.eval()\n", "i = 4\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": null, "id": "78bc372f-f0f6-4100-a4eb-e178755a66b7", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-train/peft/clm/peft_p_tuning_lstm_clm.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "id": "d2f9225b-17c7-47fd-a8b2-7b755c08713f", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/guodong.li/virtual-venv/peft-venv-py310-cu117/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[2023-07-21 13:37:11,539] [INFO] [real_accelerator.py:133:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n" ] } ], "source": [ "from transformers import AutoModelForCausalLM\n", "from peft import (\n", " get_peft_config,\n", " get_peft_model,\n", " get_peft_model_state_dict,\n", " set_peft_model_state_dict,\n", " PeftType,\n", " TaskType,\n", " PromptEncoderConfig,\n", " PromptEncoderReparameterizationType\n", ")\n", "\n", "import torch\n", "from datasets import load_dataset\n", "import os\n", "from transformers import AutoTokenizer\n", "from torch.utils.data import DataLoader\n", "from transformers import default_data_collator, get_linear_schedule_with_warmup\n", "from tqdm import tqdm\n", "from datasets import load_dataset\n", "\n", "\n", "device = \"cuda\"\n", "\n", "model_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "tokenizer_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "\n", "peft_config = PromptEncoderConfig(task_type=TaskType.CAUSAL_LM, \n", " num_virtual_tokens=20, \n", " encoder_hidden_size=128,\n", " encoder_reparameterization_type=PromptEncoderReparameterizationType.LSTM\n", " )\n", "\n", "dataset_name = \"twitter_complaints\"\n", "checkpoint_name = f\"{dataset_name}_{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}_v1.pt\".replace(\"/\", \"_\")\n", "text_column = \"Tweet text\"\n", "label_column = \"text_label\"\n", "max_length = 64\n", "lr = 3e-2\n", "num_epochs = 10\n", "batch_size = 8" ] }, { "cell_type": "code", "execution_count": 2, "id": "551bfa31-cf73-41f4-bdb7-07c492089310", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Found cached dataset raft (/home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84)\n", "100%|██████████| 2/2 [00:00<00:00, 737.85it/s]\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-0e20fff6b1d898ca.arrow\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-8d14a62b8a688c19.arrow\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "['Unlabeled', 'complaint', 'no complaint']\n", "DatasetDict({\n", " train: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 50\n", " })\n", " test: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 3399\n", " })\n", "})\n" ] }, { "data": { "text/plain": [ "{'Tweet text': '@HMRCcustomers No this is my first job',\n", " 'ID': 0,\n", " 'Label': 2,\n", " 'text_label': 'no complaint'}" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from datasets import load_dataset\n", "\n", "# dataset = load_dataset(\"ought/raft\", dataset_name)\n", "dataset = load_dataset(\"/home/guodong.li/data/peft/raft/raft.py\", dataset_name, cache_dir=\"/home/guodong.li/data/peft/data\")\n", "\n", "classes = [k.replace(\"_\", \" \") for k in dataset[\"train\"].features[\"Label\"].names]\n", "print(classes)\n", "dataset = dataset.map(\n", " lambda x: {\"text_label\": [classes[label] for label in x[\"Label\"]]},\n", " batched=True,\n", " num_proc=1,\n", ")\n", "print(dataset)\n", "dataset[\"train\"][0]" ] }, { "cell_type": "code", "execution_count": 3, "id": "388dabbe-e7a8-4a61-98dc-0e1ccea86b0d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "target_max_length: 3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " \r" ] } ], "source": [ "# data preprocessing\n", "# padding_side = \"left\"\n", "# tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, padding_side=padding_side)\n", "tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)\n", "if tokenizer.pad_token_id is None:\n", " tokenizer.pad_token_id = tokenizer.eos_token_id\n", "target_max_length = max([len(tokenizer(class_label)[\"input_ids\"]) for class_label in classes])\n", "print(\"target_max_length:\", target_max_length)\n", "\n", "\n", "def preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " targets = [str(x) for x in examples[label_column]]\n", " model_inputs = tokenizer(inputs)\n", " labels = tokenizer(targets)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i] + [tokenizer.pad_token_id]\n", " # print(i, sample_input_ids, label_input_ids)\n", " model_inputs[\"input_ids\"][i] = sample_input_ids + label_input_ids\n", " labels[\"input_ids\"][i] = [-100] * len(sample_input_ids) + label_input_ids\n", " model_inputs[\"attention_mask\"][i] = [1] * len(model_inputs[\"input_ids\"][i])\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (\n", " max_length - len(sample_input_ids)\n", " ) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\n", " \"attention_mask\"\n", " ][i]\n", " labels[\"input_ids\"][i] = [-100] * (max_length - len(sample_input_ids)) + label_input_ids\n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " labels[\"input_ids\"][i] = torch.tensor(labels[\"input_ids\"][i][:max_length])\n", " model_inputs[\"labels\"] = labels[\"input_ids\"]\n", " return model_inputs\n", "\n", "\n", "processed_datasets = dataset.map(\n", " preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "train_dataset = processed_datasets[\"train\"]\n", "eval_dataset = processed_datasets[\"train\"]\n", "\n", "\n", "train_dataloader = DataLoader(train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "eval_dataloader = DataLoader(eval_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)" ] }, { "cell_type": "code", "execution_count": 4, "id": "2e0999b0-89c3-4389-a2a4-3dfe0d4040b9", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " \r" ] }, { "data": { "text/plain": [ "{'input_ids': tensor([[ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 74757, 64626, 12384, 44639, 613,\n", " 52282, 2670, 79920, 3344, 1002, 368, 17646, 14472, 8348,\n", " 664, 718, 4, 19036, 17, 31849, 17, 6312, 76,\n", " 44, 62470, 56, 91, 50, 14839, 21, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 227985, 5484, 915, 405, 187059,\n", " 2256, 664, 2550, 18833, 18607, 162467, 4, 1387, 6199,\n", " 3291, 23405, 613, 4657, 17082, 566, 3432, 368, 78851,\n", " 1185, 61273, 23181, 1553, 15596, 212, 116057, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 39762, 2566, 22253, 6201, 75701, 15, 632, 718,\n", " 5840, 10006, 6201, 18881, 427, 3804, 19528, 267, 158974,\n", " 1320, 368, 10029, 632, 49666, 92, 34, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 227985, 5484, 915, 2566, 104565, 8695, 2089, 6140,\n", " 109676, 99579, 1369, 512, 368, 4570, 54, 632, 368,\n", " 1503, 241485, 132226, 15, 982, 727, 1152, 18100, 861,\n", " 32596, 77597, 168154, 1306, 132226, 4346, 87843, 17, 130462,\n", " 364, 32923, 89, 53, 8309, 20, 75, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 227985, 5484, 915, 2566,\n", " 14173, 2960, 29906, 387, 20706, 49337, 1369, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 227985, 5484, 915, 2566, 219553, 45736,\n", " 36876, 1713, 72, 707, 187205, 13002, 177324, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 233938, 28518, 13716,\n", " 427, 28146, 1119, 17918, 17, 236706, 368, 214997, 7555,\n", " 48659, 5276, 21600, 343, 17, 51416, 22403, 318, 1531,\n", " 1306, 1130, 20934, 567, 101161, 184849, 87843, 17, 1594,\n", " 15231, 2052, 16642, 20, 7180, 80, 26, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 80, 2068, 479, 2566, 80,\n", " 1376, 878, 147587, 3904, 632, 368, 6084, 65673, 78851,\n", " 11736, 15527, 19082, 33151, 461, 17, 45575, 17887, 632,\n", " 5219, 14216, 68870, 5967, 1841, 4346, 87843, 17, 1594,\n", " 14512, 27, 71, 8184, 19, 290, 63748, 77658, 915,\n", " 210]]),\n", " 'attention_mask': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def test_preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " model_inputs = tokenizer(inputs)\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (max_length - len(sample_input_ids)) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\"attention_mask\"][i]\n", " \n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " return model_inputs\n", "\n", "\n", "test_dataset = dataset[\"test\"].map(\n", " test_preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "test_dataloader = DataLoader(test_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "next(iter(test_dataloader))" ] }, { "cell_type": "code", "execution_count": 5, "id": "fb3bae27-7764-4938-b5c2-f97882c42d58", "metadata": {}, "outputs": [], "source": [ "model = AutoModelForCausalLM.from_pretrained(model_name_or_path)\n" ] }, { "cell_type": "code", "execution_count": 6, "id": "97c1c175-3024-47cf-b337-90d12d57f3a1", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BloomForCausalLM(\n", " (transformer): BloomModel(\n", " (word_embeddings): Embedding(250880, 1024)\n", " (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (h): ModuleList(\n", " (0): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (1): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (2): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (3): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (4): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (5): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (6): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (7): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (8): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (9): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (10): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (11): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (12): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (13): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (14): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (15): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (16): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (17): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (18): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (19): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (20): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (21): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (22): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (23): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " )\n", " (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " )\n", " (lm_head): Linear(in_features=1024, out_features=250880, bias=False)\n", ")" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model" ] }, { "cell_type": "code", "execution_count": 7, "id": "38775c10-f960-4ecb-821f-aefd61447a58", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "trainable params: 1,926,400 || all params: 561,140,992 || trainable%: 0.343300530074267\n" ] } ], "source": [ "model = get_peft_model(model, peft_config)\n", "model.print_trainable_parameters()" ] }, { "cell_type": "code", "execution_count": 8, "id": "2fc154f4-7438-474e-91e0-23a24f97610d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PeftModelForCausalLM(\n", " (base_model): BloomForCausalLM(\n", " (transformer): BloomModel(\n", " (word_embeddings): Embedding(250880, 1024)\n", " (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (h): ModuleList(\n", " (0): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (1): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (2): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (3): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (4): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (5): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (6): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (7): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (8): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (9): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (10): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (11): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (12): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (13): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (14): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (15): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (16): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (17): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (18): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (19): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (20): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (21): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (22): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (23): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " )\n", " (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " )\n", " (lm_head): Linear(in_features=1024, out_features=250880, bias=False)\n", " )\n", " (prompt_encoder): ModuleDict(\n", " (default): PromptEncoder(\n", " (embedding): Embedding(20, 1024)\n", " (lstm_head): LSTM(1024, 128, num_layers=2, batch_first=True, bidirectional=True)\n", " (mlp_head): Sequential(\n", " (0): Linear(in_features=256, out_features=256, bias=True)\n", " (1): ReLU()\n", " (2): Linear(in_features=256, out_features=1024, bias=True)\n", " )\n", " )\n", " )\n", " (word_embeddings): Embedding(250880, 1024)\n", ")" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model" ] }, { "cell_type": "code", "execution_count": 9, "id": "3fa62df7-b3c2-4833-87aa-0f7ad60d7f6e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'default': PromptEncoderConfig(peft_type=, auto_mapping=None, base_model_name_or_path='/data/nfs/llm/model/bloomz-560m', revision=None, task_type=, inference_mode=False, num_virtual_tokens=20, token_dim=1024, num_transformer_submodules=1, num_attention_heads=16, num_layers=24, encoder_reparameterization_type=, encoder_hidden_size=128, encoder_num_layers=2, encoder_dropout=0.0)}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.peft_config" ] }, { "cell_type": "code", "execution_count": 10, "id": "b57a6ed4-f4d0-4215-9871-d72648939f5c", "metadata": {}, "outputs": [], "source": [ "# model\n", "# optimizer and lr scheduler\n", "optimizer = torch.optim.AdamW(model.parameters(), lr=lr)\n", "lr_scheduler = get_linear_schedule_with_warmup(\n", " optimizer=optimizer,\n", " num_warmup_steps=0,\n", " num_training_steps=(len(train_dataloader) * num_epochs),\n", ")" ] }, { "cell_type": "code", "execution_count": 11, "id": "4b521208-262a-4afc-ac1d-b3a2594ed9ec", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:01<00:00, 4.91it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.15it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=0: train_ppl=tensor(2.3105e+10, device='cuda:0') train_epoch_loss=tensor(23.8633, device='cuda:0') eval_ppl=tensor(416649.0625, device='cuda:0') eval_epoch_loss=tensor(12.9400, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.75it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.47it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=1: train_ppl=tensor(422921.4688, device='cuda:0') train_epoch_loss=tensor(12.9549, device='cuda:0') eval_ppl=tensor(157411.0312, device='cuda:0') eval_epoch_loss=tensor(11.9666, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.89it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.12it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=2: train_ppl=tensor(164426.6094, device='cuda:0') train_epoch_loss=tensor(12.0102, device='cuda:0') eval_ppl=tensor(84267.0625, device='cuda:0') eval_epoch_loss=tensor(11.3417, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.90it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.35it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=3: train_ppl=tensor(55225.2266, device='cuda:0') train_epoch_loss=tensor(10.9192, device='cuda:0') eval_ppl=tensor(38353.1914, device='cuda:0') eval_epoch_loss=tensor(10.5546, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.89it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.13it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=4: train_ppl=tensor(31929.6152, device='cuda:0') train_epoch_loss=tensor(10.3713, device='cuda:0') eval_ppl=tensor(20707.2305, device='cuda:0') eval_epoch_loss=tensor(9.9382, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.86it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.22it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=5: train_ppl=tensor(18845.9863, device='cuda:0') train_epoch_loss=tensor(9.8441, device='cuda:0') eval_ppl=tensor(8464.1455, device='cuda:0') eval_epoch_loss=tensor(9.0436, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.91it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.35it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=6: train_ppl=tensor(10490.0605, device='cuda:0') train_epoch_loss=tensor(9.2582, device='cuda:0') eval_ppl=tensor(13972.7021, device='cuda:0') eval_epoch_loss=tensor(9.5449, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.91it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.31it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=7: train_ppl=tensor(18250.8145, device='cuda:0') train_epoch_loss=tensor(9.8120, device='cuda:0') eval_ppl=tensor(12836.4229, device='cuda:0') eval_epoch_loss=tensor(9.4600, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.93it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 17.19it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=8: train_ppl=tensor(17550.3652, device='cuda:0') train_epoch_loss=tensor(9.7728, device='cuda:0') eval_ppl=tensor(10529.1191, device='cuda:0') eval_epoch_loss=tensor(9.2619, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 8.82it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 16.72it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=9: train_ppl=tensor(10499.9795, device='cuda:0') train_epoch_loss=tensor(9.2591, device='cuda:0') eval_ppl=tensor(9154.5078, device='cuda:0') eval_epoch_loss=tensor(9.1220, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "# training and evaluation\n", "model = model.to(device)\n", "\n", "for epoch in range(num_epochs):\n", " model.train()\n", " total_loss = 0\n", " for step, batch in enumerate(tqdm(train_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " # print(batch)\n", " # print(batch[\"input_ids\"].shape)\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " total_loss += loss.detach().float()\n", " loss.backward()\n", " optimizer.step()\n", " lr_scheduler.step()\n", " optimizer.zero_grad()\n", "\n", " model.eval()\n", " eval_loss = 0\n", " eval_preds = []\n", " for step, batch in enumerate(tqdm(eval_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " with torch.no_grad():\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " eval_loss += loss.detach().float()\n", " eval_preds.extend(\n", " tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), skip_special_tokens=True)\n", " )\n", "\n", " eval_epoch_loss = eval_loss / len(eval_dataloader)\n", " eval_ppl = torch.exp(eval_epoch_loss)\n", " train_epoch_loss = total_loss / len(train_dataloader)\n", " train_ppl = torch.exp(train_epoch_loss)\n", " print(f\"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=}\")" ] }, { "cell_type": "code", "execution_count": 12, "id": "5f7ac5e9-7d52-447e-bf8e-8750cabcb158", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game.\n", "{'input_ids': tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210, 4309, 2,\n", " 36, 17, 36, 17, 54, 17, 36, 17]],\n", " device='cuda:0')\n", "[\"Tweet text : Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game. Label : NoA.A.S.A.\"]\n" ] } ], "source": [ "# 模型评估\n", "model.eval()\n", "i = 16\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": 13, "id": "336e97c4-1706-4941-8bb3-34634cf83b32", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "model_output: /data/nfs/llm/model/bloomz-560m_P_TUNING_CAUSAL_LM\n" ] } ], "source": [ "# saving model\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "print(\"model_output:\", peft_model_id)\n", "model.save_pretrained(peft_model_id)" ] }, { "cell_type": "code", "execution_count": 14, "id": "13b6ec0c-4bd1-44dc-8a09-bff9c940a87c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "84K\t/data/nfs/llm/model/bloomz-560m_P_TUNING_CAUSAL_LM/adapter_model.bin\n", "--------------\n", "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "/data/nfs/llm/model/bloomz-560m_P_TUNING_CAUSAL_LM\n", "├── [ 452] adapter_config.json\n", "├── [ 81K] adapter_model.bin\n", "└── [ 147] README.md\n", "\n", "0 directories, 3 files\n" ] } ], "source": [ "ckpt = f\"{peft_model_id}/adapter_model.bin\"\n", "!du -h $ckpt\n", "print(\"--------------\")\n", "!tree -h $peft_model_id" ] }, { "cell_type": "code", "execution_count": 15, "id": "6ea31e8d-145a-45d0-8331-3c94ba980f15", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "model_input: /data/nfs/llm/model/bloomz-560m_P_TUNING_CAUSAL_LM\n" ] } ], "source": [ "from peft import PeftModel, PeftConfig\n", "\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "print(\"model_input:\", peft_model_id)\n", "\n", "config = PeftConfig.from_pretrained(peft_model_id)\n", "model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path)\n", "model = PeftModel.from_pretrained(model, peft_model_id)" ] }, { "cell_type": "code", "execution_count": 16, "id": "91c9a1b4-f384-451f-8359-538692f02ada", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "@greateranglia Ok thanks...\n", "{'input_ids': tensor([[227985, 5484, 915, 2566, 14173, 2960, 29906, 387, 20706,\n", " 49337, 1369, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 2566, 14173, 2960, 29906, 387, 20706,\n", " 49337, 1369, 77658, 915, 210, 36, 2, 36, 17,\n", " 54, 17, 36, 17, 54, 17]], device='cuda:0')\n", "['Tweet text : @greateranglia Ok thanks... Label : AA.S.A.S.']\n" ] } ], "source": [ "model.to(device)\n", "model.eval()\n", "i = 4\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": null, "id": "78bc372f-f0f6-4100-a4eb-e178755a66b7", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-train/peft/clm/peft_p_tuning_v2_clm.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 2, "id": "9a6c57cf-4250-4b4f-9942-7c72ef4e279f", "metadata": {}, "outputs": [], "source": [ "from transformers import AutoModelForCausalLM\n", "from peft import get_peft_config, get_peft_model, PrefixTuningConfig, TaskType, PeftType\n", "import torch\n", "from datasets import load_dataset\n", "import os\n", "from transformers import AutoTokenizer\n", "from torch.utils.data import DataLoader\n", "from transformers import default_data_collator, get_linear_schedule_with_warmup\n", "from tqdm import tqdm\n", "from datasets import load_dataset\n", "\n", "\n", "device = \"cuda\"\n", "\n", "model_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "tokenizer_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "\n", "peft_config = PrefixTuningConfig(task_type=TaskType.CAUSAL_LM, num_virtual_tokens=30)\n", "\n", "dataset_name = \"twitter_complaints\"\n", "checkpoint_name = f\"{dataset_name}_{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}_v1.pt\".replace(\"/\", \"_\")\n", "text_column = \"Tweet text\"\n", "label_column = \"text_label\"\n", "max_length = 64\n", "lr = 3e-2\n", "num_epochs = 10\n", "batch_size = 8" ] }, { "cell_type": "code", "execution_count": 3, "id": "a51cbbe1-0f0d-4c63-81b7-80c06dac9431", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Found cached dataset raft (/home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84)\n", "100%|██████████| 2/2 [00:00<00:00, 269.92it/s]\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-0e20fff6b1d898ca.arrow\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-8d14a62b8a688c19.arrow\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "['Unlabeled', 'complaint', 'no complaint']\n", "DatasetDict({\n", " train: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 50\n", " })\n", " test: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 3399\n", " })\n", "})\n" ] }, { "data": { "text/plain": [ "{'Tweet text': '@HMRCcustomers No this is my first job',\n", " 'ID': 0,\n", " 'Label': 2,\n", " 'text_label': 'no complaint'}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from datasets import load_dataset\n", "\n", "# dataset = load_dataset(\"ought/raft\", dataset_name)\n", "dataset = load_dataset(\"/home/guodong.li/data/peft/raft/raft.py\", dataset_name, cache_dir=\"/home/guodong.li/data/peft/data\")\n", "\n", "classes = [k.replace(\"_\", \" \") for k in dataset[\"train\"].features[\"Label\"].names]\n", "print(classes)\n", "dataset = dataset.map(\n", " lambda x: {\"text_label\": [classes[label] for label in x[\"Label\"]]},\n", " batched=True,\n", " num_proc=1,\n", ")\n", "print(dataset)\n", "dataset[\"train\"][0]" ] }, { "cell_type": "code", "execution_count": 6, "id": "b0dc139b-ad24-4a27-8fad-a179180863e7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "target_max_length: 3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " \r" ] } ], "source": [ "# data preprocessing\n", "tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)\n", "if tokenizer.pad_token_id is None:\n", " tokenizer.pad_token_id = tokenizer.eos_token_id\n", "target_max_length = max([len(tokenizer(class_label)[\"input_ids\"]) for class_label in classes])\n", "print(\"target_max_length:\", target_max_length)\n", "\n", "\n", "def preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " targets = [str(x) for x in examples[label_column]]\n", " model_inputs = tokenizer(inputs)\n", " labels = tokenizer(targets)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i] + [tokenizer.pad_token_id]\n", " # print(i, sample_input_ids, label_input_ids)\n", " model_inputs[\"input_ids\"][i] = sample_input_ids + label_input_ids\n", " labels[\"input_ids\"][i] = [-100] * len(sample_input_ids) + label_input_ids\n", " model_inputs[\"attention_mask\"][i] = [1] * len(model_inputs[\"input_ids\"][i])\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (\n", " max_length - len(sample_input_ids)\n", " ) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\n", " \"attention_mask\"\n", " ][i]\n", " labels[\"input_ids\"][i] = [-100] * (max_length - len(sample_input_ids)) + label_input_ids\n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " labels[\"input_ids\"][i] = torch.tensor(labels[\"input_ids\"][i][:max_length])\n", " model_inputs[\"labels\"] = labels[\"input_ids\"]\n", " return model_inputs\n", "\n", "\n", "processed_datasets = dataset.map(\n", " preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "train_dataset = processed_datasets[\"train\"]\n", "eval_dataset = processed_datasets[\"train\"]\n", "\n", "\n", "train_dataloader = DataLoader(train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "eval_dataloader = DataLoader(eval_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)" ] }, { "cell_type": "code", "execution_count": 7, "id": "9c84dcdb-3d98-41c2-b66f-efab96495378", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " \r" ] }, { "data": { "text/plain": [ "{'input_ids': tensor([[ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 74757, 64626, 12384, 44639, 613,\n", " 52282, 2670, 79920, 3344, 1002, 368, 17646, 14472, 8348,\n", " 664, 718, 4, 19036, 17, 31849, 17, 6312, 76,\n", " 44, 62470, 56, 91, 50, 14839, 21, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 227985, 5484, 915, 405, 187059,\n", " 2256, 664, 2550, 18833, 18607, 162467, 4, 1387, 6199,\n", " 3291, 23405, 613, 4657, 17082, 566, 3432, 368, 78851,\n", " 1185, 61273, 23181, 1553, 15596, 212, 116057, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 39762, 2566, 22253, 6201, 75701, 15, 632, 718,\n", " 5840, 10006, 6201, 18881, 427, 3804, 19528, 267, 158974,\n", " 1320, 368, 10029, 632, 49666, 92, 34, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 227985, 5484, 915, 2566, 104565, 8695, 2089, 6140,\n", " 109676, 99579, 1369, 512, 368, 4570, 54, 632, 368,\n", " 1503, 241485, 132226, 15, 982, 727, 1152, 18100, 861,\n", " 32596, 77597, 168154, 1306, 132226, 4346, 87843, 17, 130462,\n", " 364, 32923, 89, 53, 8309, 20, 75, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 227985, 5484, 915, 2566,\n", " 14173, 2960, 29906, 387, 20706, 49337, 1369, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 227985, 5484, 915, 2566, 219553, 45736,\n", " 36876, 1713, 72, 707, 187205, 13002, 177324, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 233938, 28518, 13716,\n", " 427, 28146, 1119, 17918, 17, 236706, 368, 214997, 7555,\n", " 48659, 5276, 21600, 343, 17, 51416, 22403, 318, 1531,\n", " 1306, 1130, 20934, 567, 101161, 184849, 87843, 17, 1594,\n", " 15231, 2052, 16642, 20, 7180, 80, 26, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 80, 2068, 479, 2566, 80,\n", " 1376, 878, 147587, 3904, 632, 368, 6084, 65673, 78851,\n", " 11736, 15527, 19082, 33151, 461, 17, 45575, 17887, 632,\n", " 5219, 14216, 68870, 5967, 1841, 4346, 87843, 17, 1594,\n", " 14512, 27, 71, 8184, 19, 290, 63748, 77658, 915,\n", " 210]]),\n", " 'attention_mask': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def test_preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " model_inputs = tokenizer(inputs)\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (max_length - len(sample_input_ids)) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\"attention_mask\"][i]\n", " \n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " return model_inputs\n", "\n", "\n", "test_dataset = dataset[\"test\"].map(\n", " test_preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "test_dataloader = DataLoader(test_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "next(iter(test_dataloader))" ] }, { "cell_type": "code", "execution_count": 8, "id": "313387c6-82c5-42c2-9839-09256a48f3a9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'input_ids': tensor([[ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 227985,\n", " 5484, 915, 2566, 182441, 55, 35040, 435, 16796, 79920,\n", " 427, 661, 6355, 17, 5568, 2213, 3172, 960, 126355,\n", " 6216, 5559, 61273, 23181, 77658, 915, 210, 1936, 106863,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 227985, 5484, 915, 2566,\n", " 112229, 9107, 53312, 3262, 1306, 1152, 157816, 2084, 44326,\n", " 40006, 613, 27019, 16680, 77658, 915, 210, 1936, 106863,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 227985, 5484, 915,\n", " 2566, 24236, 2111, 178653, 11964, 20425, 3370, 10665, 1074,\n", " 2670, 20889, 5011, 17, 77658, 915, 210, 16449, 5952,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 2566, 44, 256, 67875, 21033, 86274, 79707, 2632,\n", " 9999, 427, 2150, 54036, 98091, 34, 112164, 15971, 16154,\n", " 5382, 861, 7220, 17, 77658, 915, 210, 1936, 106863,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 227985, 5484, 915, 5161, 13500, 386,\n", " 4, 122906, 415, 66027, 42431, 613, 70016, 361, 2550,\n", " 51, 21351, 322, 17896, 15, 2550, 49, 45, 2550,\n", " 21450, 388, 655, 2550, 75, 14263, 916, 86, 1881,\n", " 36534, 53902, 4, 4346, 87843, 17, 130462, 8188, 23,\n", " 5949, 187347, 78, 130589, 77658, 915, 210, 1936, 106863,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 227985, 5484, 915, 2566,\n", " 31934, 5227, 6640, 16261, 87843, 17, 130462, 9600, 169668,\n", " 28, 13604, 112581, 40, 77658, 915, 210, 1936, 106863,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 227985, 5484, 915, 2566, 14173, 2960, 29906, 387,\n", " 73303, 473, 9283, 11257, 368, 64129, 361, 11571, 461,\n", " 490, 4283, 40067, 1620, 1130, 1186, 14881, 1002, 75,\n", " 1728, 368, 63049, 17, 77658, 915, 210, 16449, 5952,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 84152, 7643, 2111,\n", " 473, 243647, 3276, 18100, 16916, 17, 38641, 1306, 1369,\n", " 105961, 4936, 28077, 17, 77658, 915, 210, 1936, 106863,\n", " 3]]),\n", " 'attention_mask': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]),\n", " 'labels': tensor([[ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 16449, 5952,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 16449, 5952,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3]])}" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(iter(train_dataloader))" ] }, { "cell_type": "code", "execution_count": 9, "id": "dab59b89-5180-4372-a990-b089fb8abf10", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "425\n" ] }, { "data": { "text/plain": [ "{'input_ids': tensor([[ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 74757, 64626, 12384, 44639, 613,\n", " 52282, 2670, 79920, 3344, 1002, 368, 17646, 14472, 8348,\n", " 664, 718, 4, 19036, 17, 31849, 17, 6312, 76,\n", " 44, 62470, 56, 91, 50, 14839, 21, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 227985, 5484, 915, 405, 187059,\n", " 2256, 664, 2550, 18833, 18607, 162467, 4, 1387, 6199,\n", " 3291, 23405, 613, 4657, 17082, 566, 3432, 368, 78851,\n", " 1185, 61273, 23181, 1553, 15596, 212, 116057, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 39762, 2566, 22253, 6201, 75701, 15, 632, 718,\n", " 5840, 10006, 6201, 18881, 427, 3804, 19528, 267, 158974,\n", " 1320, 368, 10029, 632, 49666, 92, 34, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 227985, 5484, 915, 2566, 104565, 8695, 2089, 6140,\n", " 109676, 99579, 1369, 512, 368, 4570, 54, 632, 368,\n", " 1503, 241485, 132226, 15, 982, 727, 1152, 18100, 861,\n", " 32596, 77597, 168154, 1306, 132226, 4346, 87843, 17, 130462,\n", " 364, 32923, 89, 53, 8309, 20, 75, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 227985, 5484, 915, 2566,\n", " 14173, 2960, 29906, 387, 20706, 49337, 1369, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 227985, 5484, 915, 2566, 219553, 45736,\n", " 36876, 1713, 72, 707, 187205, 13002, 177324, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 233938, 28518, 13716,\n", " 427, 28146, 1119, 17918, 17, 236706, 368, 214997, 7555,\n", " 48659, 5276, 21600, 343, 17, 51416, 22403, 318, 1531,\n", " 1306, 1130, 20934, 567, 101161, 184849, 87843, 17, 1594,\n", " 15231, 2052, 16642, 20, 7180, 80, 26, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 80, 2068, 479, 2566, 80,\n", " 1376, 878, 147587, 3904, 632, 368, 6084, 65673, 78851,\n", " 11736, 15527, 19082, 33151, 461, 17, 45575, 17887, 632,\n", " 5219, 14216, 68870, 5967, 1841, 4346, 87843, 17, 1594,\n", " 14512, 27, 71, 8184, 19, 290, 63748, 77658, 915,\n", " 210]]),\n", " 'attention_mask': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(len(test_dataloader))\n", "next(iter(test_dataloader))" ] }, { "cell_type": "code", "execution_count": 10, "id": "15b07db0-c364-4243-9475-6bdfa1c52f64", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "trainable params: 1,474,560 || all params: 560,689,152 || trainable%: 0.26299064191632515\n" ] } ], "source": [ "# creating model\n", "model = AutoModelForCausalLM.from_pretrained(model_name_or_path)\n", "model = get_peft_model(model, peft_config)\n", "model.print_trainable_parameters()" ] }, { "cell_type": "code", "execution_count": 11, "id": "abc071bf-9fce-4f2b-bc45-d71af1928015", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PeftModelForCausalLM(\n", " (base_model): BloomForCausalLM(\n", " (transformer): BloomModel(\n", " (word_embeddings): Embedding(250880, 1024)\n", " (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (h): ModuleList(\n", " (0): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (1): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (2): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (3): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (4): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (5): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (6): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (7): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (8): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (9): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (10): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (11): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (12): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (13): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (14): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (15): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (16): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (17): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (18): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (19): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (20): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (21): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (22): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (23): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " )\n", " (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " )\n", " (lm_head): Linear(in_features=1024, out_features=250880, bias=False)\n", " )\n", " (prompt_encoder): ModuleDict(\n", " (default): PrefixEncoder(\n", " (embedding): Embedding(30, 49152)\n", " )\n", " )\n", " (word_embeddings): Embedding(250880, 1024)\n", ")" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model" ] }, { "cell_type": "code", "execution_count": 12, "id": "73b9c2c5-fcc7-4a18-b206-4a12e88c107b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'default': PrefixTuningConfig(peft_type=, auto_mapping=None, base_model_name_or_path='/data/nfs/llm/model/bloomz-560m', revision=None, task_type=, inference_mode=False, num_virtual_tokens=30, token_dim=1024, num_transformer_submodules=1, num_attention_heads=16, num_layers=24, encoder_hidden_size=1024, prefix_projection=False)}" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.peft_config" ] }, { "cell_type": "code", "execution_count": 13, "id": "7e083a33-e294-4c25-a391-10981dc7ddb5", "metadata": {}, "outputs": [], "source": [ "# model\n", "# optimizer and lr scheduler\n", "optimizer = torch.optim.AdamW(model.parameters(), lr=lr)\n", "lr_scheduler = get_linear_schedule_with_warmup(\n", " optimizer=optimizer,\n", " num_warmup_steps=0,\n", " num_training_steps=(len(train_dataloader) * num_epochs),\n", ")" ] }, { "cell_type": "code", "execution_count": 14, "id": "2b361e7a-9e02-45d7-8da2-5fcb281ecd92", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:01<00:00, 5.82it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.22it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=0: train_ppl=tensor(1.0067e+10, device='cuda:0') train_epoch_loss=tensor(23.0325, device='cuda:0') eval_ppl=tensor(440.2399, device='cuda:0') eval_epoch_loss=tensor(6.0873, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.53it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.55it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=1: train_ppl=tensor(187.8570, device='cuda:0') train_epoch_loss=tensor(5.2357, device='cuda:0') eval_ppl=tensor(100.1909, device='cuda:0') eval_epoch_loss=tensor(4.6071, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.53it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.79it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=2: train_ppl=tensor(66.6660, device='cuda:0') train_epoch_loss=tensor(4.1997, device='cuda:0') eval_ppl=tensor(45.0488, device='cuda:0') eval_epoch_loss=tensor(3.8077, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.51it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.63it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=3: train_ppl=tensor(37.7751, device='cuda:0') train_epoch_loss=tensor(3.6316, device='cuda:0') eval_ppl=tensor(20.0135, device='cuda:0') eval_epoch_loss=tensor(2.9964, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.55it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.81it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=4: train_ppl=tensor(14.8737, device='cuda:0') train_epoch_loss=tensor(2.6996, device='cuda:0') eval_ppl=tensor(8.6689, device='cuda:0') eval_epoch_loss=tensor(2.1597, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.55it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.78it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=5: train_ppl=tensor(5.6210, device='cuda:0') train_epoch_loss=tensor(1.7265, device='cuda:0') eval_ppl=tensor(3.3080, device='cuda:0') eval_epoch_loss=tensor(1.1963, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.54it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.78it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=6: train_ppl=tensor(2.5512, device='cuda:0') train_epoch_loss=tensor(0.9366, device='cuda:0') eval_ppl=tensor(1.8660, device='cuda:0') eval_epoch_loss=tensor(0.6238, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.06it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.65it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=7: train_ppl=tensor(1.7045, device='cuda:0') train_epoch_loss=tensor(0.5333, device='cuda:0') eval_ppl=tensor(1.4844, device='cuda:0') eval_epoch_loss=tensor(0.3950, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.54it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.60it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=8: train_ppl=tensor(1.4116, device='cuda:0') train_epoch_loss=tensor(0.3447, device='cuda:0') eval_ppl=tensor(1.3491, device='cuda:0') eval_epoch_loss=tensor(0.2994, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 11.49it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.63it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=9: train_ppl=tensor(1.3204, device='cuda:0') train_epoch_loss=tensor(0.2780, device='cuda:0') eval_ppl=tensor(1.3255, device='cuda:0') eval_epoch_loss=tensor(0.2818, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "# training and evaluation\n", "model = model.to(device)\n", "\n", "for epoch in range(num_epochs):\n", " model.train()\n", " total_loss = 0\n", " for step, batch in enumerate(tqdm(train_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " # print(batch)\n", " # print(batch[\"input_ids\"].shape)\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " total_loss += loss.detach().float()\n", " loss.backward()\n", " optimizer.step()\n", " lr_scheduler.step()\n", " optimizer.zero_grad()\n", "\n", " model.eval()\n", " eval_loss = 0\n", " eval_preds = []\n", " for step, batch in enumerate(tqdm(eval_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " with torch.no_grad():\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " eval_loss += loss.detach().float()\n", " eval_preds.extend(\n", " tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), skip_special_tokens=True)\n", " )\n", "\n", " eval_epoch_loss = eval_loss / len(eval_dataloader)\n", " eval_ppl = torch.exp(eval_epoch_loss)\n", " train_epoch_loss = total_loss / len(train_dataloader)\n", " train_ppl = torch.exp(train_epoch_loss)\n", " print(f\"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=}\")" ] }, { "cell_type": "code", "execution_count": 15, "id": "826c92ba-0e19-4a43-ba89-df83034c2887", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game.\n", "{'input_ids': tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210, 1936, 106863,\n", " 3]], device='cuda:0')\n", "[\"Tweet text : Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game. Label : no complaint\"]\n" ] } ], "source": [ "# 模型评估\n", "model.eval()\n", "i = 16\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": 16, "id": "c9756276-4b79-4f2e-bf12-a092d8734651", "metadata": {}, "outputs": [], "source": [ "# saving model\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "model.save_pretrained(peft_model_id)" ] }, { "cell_type": "code", "execution_count": 17, "id": "d602335e-bd15-4e87-98c9-43f6c6d3913f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "5.7M\t/data/nfs/llm/model/bloomz-560m_PREFIX_TUNING_CAUSAL_LM/adapter_model.bin\n", "--------------\n", "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "/data/nfs/llm/model/bloomz-560m_PREFIX_TUNING_CAUSAL_LM\n", "├── [ 390] adapter_config.json\n", "├── [5.6M] adapter_model.bin\n", "└── [ 93] README.md\n", "\n", "0 directories, 3 files\n" ] } ], "source": [ "ckpt = f\"{peft_model_id}/adapter_model.bin\"\n", "!du -h $ckpt\n", "print(\"--------------\")\n", "!tree -h $peft_model_id" ] }, { "cell_type": "code", "execution_count": 18, "id": "04885484-b34b-4d3e-8217-0da101dfdcda", "metadata": {}, "outputs": [], "source": [ "from peft import PeftModel, PeftConfig\n", "\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "\n", "config = PeftConfig.from_pretrained(peft_model_id)\n", "model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path)\n", "model = PeftModel.from_pretrained(model, peft_model_id)" ] }, { "cell_type": "code", "execution_count": 19, "id": "c3ef0558-be14-43c0-a28e-e0c623f5e2fa", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "@greateranglia Ok thanks...\n", "{'input_ids': tensor([[227985, 5484, 915, 2566, 14173, 2960, 29906, 387, 20706,\n", " 49337, 1369, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 2566, 14173, 2960, 29906, 387, 20706,\n", " 49337, 1369, 77658, 915, 210, 1936, 106863, 3]],\n", " device='cuda:0')\n", "['Tweet text : @greateranglia Ok thanks... Label : no complaint']\n" ] } ], "source": [ "model.to(device)\n", "model.eval()\n", "i = 4\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": null, "id": "d3a61b0a-2b61-4fcb-8e9f-2ee7096f700a", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-train/peft/clm/peft_prefix_tuning_clm.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "id": "9a6c57cf-4250-4b4f-9942-7c72ef4e279f", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/guodong.li/virtual-venv/peft-venv-py310-cu117/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[2023-07-21 15:07:09,626] [INFO] [real_accelerator.py:133:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n" ] } ], "source": [ "from transformers import AutoModelForCausalLM\n", "from peft import get_peft_config, get_peft_model, PrefixTuningConfig, TaskType, PeftType\n", "import torch\n", "from datasets import load_dataset\n", "import os\n", "from transformers import AutoTokenizer\n", "from torch.utils.data import DataLoader\n", "from transformers import default_data_collator, get_linear_schedule_with_warmup\n", "from tqdm import tqdm\n", "from datasets import load_dataset\n", "\n", "\n", "device = \"cuda\"\n", "\n", "model_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "tokenizer_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "\n", "peft_config = PrefixTuningConfig(task_type=TaskType.CAUSAL_LM, num_virtual_tokens=30, prefix_projection=True)\n", "\n", "dataset_name = \"twitter_complaints\"\n", "checkpoint_name = f\"{dataset_name}_{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}_v1.pt\".replace(\"/\", \"_\")\n", "text_column = \"Tweet text\"\n", "label_column = \"text_label\"\n", "max_length = 64\n", "lr = 3e-2\n", "num_epochs = 10\n", "batch_size = 8" ] }, { "cell_type": "code", "execution_count": 2, "id": "a51cbbe1-0f0d-4c63-81b7-80c06dac9431", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Found cached dataset raft (/home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84)\n", "100%|██████████| 2/2 [00:00<00:00, 414.07it/s]\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-0e20fff6b1d898ca.arrow\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-8d14a62b8a688c19.arrow\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "['Unlabeled', 'complaint', 'no complaint']\n", "DatasetDict({\n", " train: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 50\n", " })\n", " test: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 3399\n", " })\n", "})\n" ] }, { "data": { "text/plain": [ "{'Tweet text': '@HMRCcustomers No this is my first job',\n", " 'ID': 0,\n", " 'Label': 2,\n", " 'text_label': 'no complaint'}" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from datasets import load_dataset\n", "\n", "# dataset = load_dataset(\"ought/raft\", dataset_name)\n", "dataset = load_dataset(\"/home/guodong.li/data/peft/raft/raft.py\", dataset_name, cache_dir=\"/home/guodong.li/data/peft/data\")\n", "\n", "classes = [k.replace(\"_\", \" \") for k in dataset[\"train\"].features[\"Label\"].names]\n", "print(classes)\n", "dataset = dataset.map(\n", " lambda x: {\"text_label\": [classes[label] for label in x[\"Label\"]]},\n", " batched=True,\n", " num_proc=1,\n", ")\n", "print(dataset)\n", "dataset[\"train\"][0]" ] }, { "cell_type": "code", "execution_count": 3, "id": "b0dc139b-ad24-4a27-8fad-a179180863e7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "target_max_length: 3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " \r" ] } ], "source": [ "# data preprocessing\n", "tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)\n", "if tokenizer.pad_token_id is None:\n", " tokenizer.pad_token_id = tokenizer.eos_token_id\n", "target_max_length = max([len(tokenizer(class_label)[\"input_ids\"]) for class_label in classes])\n", "print(\"target_max_length:\", target_max_length)\n", "\n", "\n", "def preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " targets = [str(x) for x in examples[label_column]]\n", " model_inputs = tokenizer(inputs)\n", " labels = tokenizer(targets)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i] + [tokenizer.pad_token_id]\n", " # print(i, sample_input_ids, label_input_ids)\n", " model_inputs[\"input_ids\"][i] = sample_input_ids + label_input_ids\n", " labels[\"input_ids\"][i] = [-100] * len(sample_input_ids) + label_input_ids\n", " model_inputs[\"attention_mask\"][i] = [1] * len(model_inputs[\"input_ids\"][i])\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " label_input_ids = labels[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (\n", " max_length - len(sample_input_ids)\n", " ) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\n", " \"attention_mask\"\n", " ][i]\n", " labels[\"input_ids\"][i] = [-100] * (max_length - len(sample_input_ids)) + label_input_ids\n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " labels[\"input_ids\"][i] = torch.tensor(labels[\"input_ids\"][i][:max_length])\n", " model_inputs[\"labels\"] = labels[\"input_ids\"]\n", " return model_inputs\n", "\n", "\n", "processed_datasets = dataset.map(\n", " preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "train_dataset = processed_datasets[\"train\"]\n", "eval_dataset = processed_datasets[\"train\"]\n", "\n", "\n", "train_dataloader = DataLoader(train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "eval_dataloader = DataLoader(eval_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)" ] }, { "cell_type": "code", "execution_count": 4, "id": "9c84dcdb-3d98-41c2-b66f-efab96495378", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " \r" ] }, { "data": { "text/plain": [ "{'input_ids': tensor([[ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 74757, 64626, 12384, 44639, 613,\n", " 52282, 2670, 79920, 3344, 1002, 368, 17646, 14472, 8348,\n", " 664, 718, 4, 19036, 17, 31849, 17, 6312, 76,\n", " 44, 62470, 56, 91, 50, 14839, 21, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 227985, 5484, 915, 405, 187059,\n", " 2256, 664, 2550, 18833, 18607, 162467, 4, 1387, 6199,\n", " 3291, 23405, 613, 4657, 17082, 566, 3432, 368, 78851,\n", " 1185, 61273, 23181, 1553, 15596, 212, 116057, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 39762, 2566, 22253, 6201, 75701, 15, 632, 718,\n", " 5840, 10006, 6201, 18881, 427, 3804, 19528, 267, 158974,\n", " 1320, 368, 10029, 632, 49666, 92, 34, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 227985, 5484, 915, 2566, 104565, 8695, 2089, 6140,\n", " 109676, 99579, 1369, 512, 368, 4570, 54, 632, 368,\n", " 1503, 241485, 132226, 15, 982, 727, 1152, 18100, 861,\n", " 32596, 77597, 168154, 1306, 132226, 4346, 87843, 17, 130462,\n", " 364, 32923, 89, 53, 8309, 20, 75, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 227985, 5484, 915, 2566,\n", " 14173, 2960, 29906, 387, 20706, 49337, 1369, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 227985, 5484, 915, 2566, 219553, 45736,\n", " 36876, 1713, 72, 707, 187205, 13002, 177324, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 233938, 28518, 13716,\n", " 427, 28146, 1119, 17918, 17, 236706, 368, 214997, 7555,\n", " 48659, 5276, 21600, 343, 17, 51416, 22403, 318, 1531,\n", " 1306, 1130, 20934, 567, 101161, 184849, 87843, 17, 1594,\n", " 15231, 2052, 16642, 20, 7180, 80, 26, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 80, 2068, 479, 2566, 80,\n", " 1376, 878, 147587, 3904, 632, 368, 6084, 65673, 78851,\n", " 11736, 15527, 19082, 33151, 461, 17, 45575, 17887, 632,\n", " 5219, 14216, 68870, 5967, 1841, 4346, 87843, 17, 1594,\n", " 14512, 27, 71, 8184, 19, 290, 63748, 77658, 915,\n", " 210]]),\n", " 'attention_mask': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def test_preprocess_function(examples):\n", " batch_size = len(examples[text_column])\n", " inputs = [f\"{text_column} : {x} Label : \" for x in examples[text_column]]\n", " model_inputs = tokenizer(inputs)\n", " # print(model_inputs)\n", " for i in range(batch_size):\n", " sample_input_ids = model_inputs[\"input_ids\"][i]\n", " model_inputs[\"input_ids\"][i] = [tokenizer.pad_token_id] * (max_length - len(sample_input_ids)) + sample_input_ids\n", " model_inputs[\"attention_mask\"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs[\"attention_mask\"][i]\n", " \n", " model_inputs[\"input_ids\"][i] = torch.tensor(model_inputs[\"input_ids\"][i][:max_length])\n", " model_inputs[\"attention_mask\"][i] = torch.tensor(model_inputs[\"attention_mask\"][i][:max_length])\n", " return model_inputs\n", "\n", "\n", "test_dataset = dataset[\"test\"].map(\n", " test_preprocess_function,\n", " batched=True,\n", " num_proc=1,\n", " remove_columns=dataset[\"train\"].column_names,\n", " load_from_cache_file=False,\n", " desc=\"Running tokenizer on dataset\",\n", ")\n", "\n", "test_dataloader = DataLoader(test_dataset, collate_fn=default_data_collator, batch_size=batch_size, pin_memory=True)\n", "next(iter(test_dataloader))" ] }, { "cell_type": "code", "execution_count": 5, "id": "313387c6-82c5-42c2-9839-09256a48f3a9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'input_ids': tensor([[ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 2566, 61, 31311, 6640, 1935, 15527, 3784, 46823,\n", " 664, 267, 57502, 427, 2670, 148307, 530, 524, 23099,\n", " 613, 15226, 5840, 34, 77658, 915, 210, 16449, 5952,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 46, 30579, 46,\n", " 12592, 57, 473, 3370, 199020, 267, 46019, 21302, 15804,\n", " 361, 13300, 132548, 27761, 77658, 915, 210, 1936, 106863,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 227985, 5484, 915, 2566, 47959, 6745,\n", " 19624, 13929, 2152, 722, 11045, 635, 3869, 290, 32107,\n", " 75, 2481, 56557, 1002, 208814, 16924, 1231, 17, 19,\n", " 34, 59283, 1152, 4, 77658, 915, 210, 1936, 106863,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 2566, 69408, 73736, 1400, 473, 2213, 267, 131388,\n", " 17817, 9781, 158974, 3262, 718, 35752, 2496, 1336, 20941,\n", " 530, 1701, 44920, 133198, 34, 2550, 44, 328, 61066,\n", " 1258, 8049, 7171, 5448, 77658, 915, 210, 16449, 5952,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 309, 4904, 1130,\n", " 38782, 1002, 1119, 29052, 1485, 5161, 4782, 427, 31451,\n", " 83342, 915, 11, 3804, 3171, 173064, 9955, 760, 5279,\n", " 10641, 7182, 4443, 2815, 77658, 915, 210, 16449, 5952,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 227985, 5484, 915, 2566, 137538, 78869, 12122, 2963,\n", " 3226, 15756, 1965, 3276, 14967, 6610, 664, 3509, 427,\n", " 112046, 1800, 21859, 3250, 77658, 915, 210, 1936, 106863,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 227985,\n", " 5484, 915, 2566, 18247, 11847, 53312, 1728, 461, 267,\n", " 53531, 473, 11229, 14456, 427, 2670, 25357, 82707, 14218,\n", " 1965, 60115, 2592, 11859, 77658, 915, 210, 1936, 106863,\n", " 3],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 84152, 7643, 2111,\n", " 473, 243647, 3276, 18100, 16916, 17, 38641, 1306, 1369,\n", " 105961, 4936, 28077, 17, 77658, 915, 210, 1936, 106863,\n", " 3]]),\n", " 'attention_mask': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]),\n", " 'labels': tensor([[ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 16449, 5952,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 16449, 5952,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 16449, 5952,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3],\n", " [ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3]])}" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "next(iter(train_dataloader))" ] }, { "cell_type": "code", "execution_count": 6, "id": "dab59b89-5180-4372-a990-b089fb8abf10", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "425\n" ] }, { "data": { "text/plain": [ "{'input_ids': tensor([[ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 74757, 64626, 12384, 44639, 613,\n", " 52282, 2670, 79920, 3344, 1002, 368, 17646, 14472, 8348,\n", " 664, 718, 4, 19036, 17, 31849, 17, 6312, 76,\n", " 44, 62470, 56, 91, 50, 14839, 21, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 227985, 5484, 915, 405, 187059,\n", " 2256, 664, 2550, 18833, 18607, 162467, 4, 1387, 6199,\n", " 3291, 23405, 613, 4657, 17082, 566, 3432, 368, 78851,\n", " 1185, 61273, 23181, 1553, 15596, 212, 116057, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 227985, 5484,\n", " 915, 39762, 2566, 22253, 6201, 75701, 15, 632, 718,\n", " 5840, 10006, 6201, 18881, 427, 3804, 19528, 267, 158974,\n", " 1320, 368, 10029, 632, 49666, 92, 34, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 227985, 5484, 915, 2566, 104565, 8695, 2089, 6140,\n", " 109676, 99579, 1369, 512, 368, 4570, 54, 632, 368,\n", " 1503, 241485, 132226, 15, 982, 727, 1152, 18100, 861,\n", " 32596, 77597, 168154, 1306, 132226, 4346, 87843, 17, 130462,\n", " 364, 32923, 89, 53, 8309, 20, 75, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 227985, 5484, 915, 2566,\n", " 14173, 2960, 29906, 387, 20706, 49337, 1369, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 227985, 5484, 915, 2566, 219553, 45736,\n", " 36876, 1713, 72, 707, 187205, 13002, 177324, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 227985, 5484, 915, 2566, 233938, 28518, 13716,\n", " 427, 28146, 1119, 17918, 17, 236706, 368, 214997, 7555,\n", " 48659, 5276, 21600, 343, 17, 51416, 22403, 318, 1531,\n", " 1306, 1130, 20934, 567, 101161, 184849, 87843, 17, 1594,\n", " 15231, 2052, 16642, 20, 7180, 80, 26, 77658, 915,\n", " 210],\n", " [ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 227985, 5484, 915, 2566, 80, 2068, 479, 2566, 80,\n", " 1376, 878, 147587, 3904, 632, 368, 6084, 65673, 78851,\n", " 11736, 15527, 19082, 33151, 461, 17, 45575, 17887, 632,\n", " 5219, 14216, 68870, 5967, 1841, 4346, 87843, 17, 1594,\n", " 14512, 27, 71, 8184, 19, 290, 63748, 77658, 915,\n", " 210]]),\n", " 'attention_mask': tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\n", " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(len(test_dataloader))\n", "next(iter(test_dataloader))" ] }, { "cell_type": "code", "execution_count": 7, "id": "15b07db0-c364-4243-9475-6bdfa1c52f64", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "trainable params: 51,461,120 || all params: 610,675,712 || trainable%: 8.426914479939231\n" ] } ], "source": [ "# creating model\n", "model = AutoModelForCausalLM.from_pretrained(model_name_or_path)\n", "model = get_peft_model(model, peft_config)\n", "model.print_trainable_parameters()" ] }, { "cell_type": "code", "execution_count": 8, "id": "abc071bf-9fce-4f2b-bc45-d71af1928015", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PeftModelForCausalLM(\n", " (base_model): BloomForCausalLM(\n", " (transformer): BloomModel(\n", " (word_embeddings): Embedding(250880, 1024)\n", " (word_embeddings_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (h): ModuleList(\n", " (0): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (1): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (2): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (3): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (4): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (5): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (6): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (7): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (8): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (9): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (10): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (11): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (12): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (13): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (14): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (15): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (16): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (17): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (18): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (19): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (20): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (21): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (22): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " (23): BloomBlock(\n", " (input_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (self_attention): BloomAttention(\n", " (query_key_value): Linear(in_features=1024, out_features=3072, bias=True)\n", " (dense): Linear(in_features=1024, out_features=1024, bias=True)\n", " (attention_dropout): Dropout(p=0.0, inplace=False)\n", " )\n", " (post_attention_layernorm): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " (mlp): BloomMLP(\n", " (dense_h_to_4h): Linear(in_features=1024, out_features=4096, bias=True)\n", " (gelu_impl): BloomGelu()\n", " (dense_4h_to_h): Linear(in_features=4096, out_features=1024, bias=True)\n", " )\n", " )\n", " )\n", " (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n", " )\n", " (lm_head): Linear(in_features=1024, out_features=250880, bias=False)\n", " )\n", " (prompt_encoder): ModuleDict(\n", " (default): PrefixEncoder(\n", " (embedding): Embedding(30, 1024)\n", " (transform): Sequential(\n", " (0): Linear(in_features=1024, out_features=1024, bias=True)\n", " (1): Tanh()\n", " (2): Linear(in_features=1024, out_features=49152, bias=True)\n", " )\n", " )\n", " )\n", " (word_embeddings): Embedding(250880, 1024)\n", ")" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model" ] }, { "cell_type": "code", "execution_count": 9, "id": "73b9c2c5-fcc7-4a18-b206-4a12e88c107b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'default': PrefixTuningConfig(peft_type=, auto_mapping=None, base_model_name_or_path='/data/nfs/llm/model/bloomz-560m', revision=None, task_type=, inference_mode=False, num_virtual_tokens=30, token_dim=1024, num_transformer_submodules=1, num_attention_heads=16, num_layers=24, encoder_hidden_size=1024, prefix_projection=True)}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.peft_config" ] }, { "cell_type": "code", "execution_count": 10, "id": "7e083a33-e294-4c25-a391-10981dc7ddb5", "metadata": {}, "outputs": [], "source": [ "# model\n", "# optimizer and lr scheduler\n", "optimizer = torch.optim.AdamW(model.parameters(), lr=lr)\n", "lr_scheduler = get_linear_schedule_with_warmup(\n", " optimizer=optimizer,\n", " num_warmup_steps=0,\n", " num_training_steps=(len(train_dataloader) * num_epochs),\n", ")" ] }, { "cell_type": "code", "execution_count": 11, "id": "2b361e7a-9e02-45d7-8da2-5fcb281ecd92", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:01<00:00, 4.72it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.29it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=0: train_ppl=tensor(1.2153e+26, device='cuda:0') train_epoch_loss=tensor(60.0622, device='cuda:0') eval_ppl=tensor(7.7051e+19, device='cuda:0') eval_epoch_loss=tensor(45.7910, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.37it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.24it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=1: train_ppl=tensor(1.4996e+18, device='cuda:0') train_epoch_loss=tensor(41.8517, device='cuda:0') eval_ppl=tensor(1.0033e+15, device='cuda:0') eval_epoch_loss=tensor(34.5421, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.74it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.10it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=2: train_ppl=tensor(5.3591e+13, device='cuda:0') train_epoch_loss=tensor(31.6124, device='cuda:0') eval_ppl=tensor(2.4683e+11, device='cuda:0') eval_epoch_loss=tensor(26.2320, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.77it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 21.87it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=3: train_ppl=tensor(1.7712e+10, device='cuda:0') train_epoch_loss=tensor(23.5975, device='cuda:0') eval_ppl=tensor(2.8744e+08, device='cuda:0') eval_epoch_loss=tensor(19.4765, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.75it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.04it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=4: train_ppl=tensor(25556452., device='cuda:0') train_epoch_loss=tensor(17.0564, device='cuda:0') eval_ppl=tensor(842123.9375, device='cuda:0') eval_epoch_loss=tensor(13.6437, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.74it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.07it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=5: train_ppl=tensor(157362.0938, device='cuda:0') train_epoch_loss=tensor(11.9663, device='cuda:0') eval_ppl=tensor(29300.7930, device='cuda:0') eval_epoch_loss=tensor(10.2854, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.74it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.06it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=6: train_ppl=tensor(9741.4102, device='cuda:0') train_epoch_loss=tensor(9.1841, device='cuda:0') eval_ppl=tensor(3307.9692, device='cuda:0') eval_epoch_loss=tensor(8.1041, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.47it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.15it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=7: train_ppl=tensor(2145.2480, device='cuda:0') train_epoch_loss=tensor(7.6710, device='cuda:0') eval_ppl=tensor(1604.1796, device='cuda:0') eval_epoch_loss=tensor(7.3804, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.71it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 22.13it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=8: train_ppl=tensor(1214.0173, device='cuda:0') train_epoch_loss=tensor(7.1017, device='cuda:0') eval_ppl=tensor(1103.5812, device='cuda:0') eval_epoch_loss=tensor(7.0063, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 7/7 [00:00<00:00, 10.76it/s]\n", "100%|██████████| 7/7 [00:00<00:00, 21.82it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "epoch=9: train_ppl=tensor(1016.2148, device='cuda:0') train_epoch_loss=tensor(6.9238, device='cuda:0') eval_ppl=tensor(952.7982, device='cuda:0') eval_epoch_loss=tensor(6.8594, device='cuda:0')\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "# training and evaluation\n", "model = model.to(device)\n", "\n", "for epoch in range(num_epochs):\n", " model.train()\n", " total_loss = 0\n", " for step, batch in enumerate(tqdm(train_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " # print(batch)\n", " # print(batch[\"input_ids\"].shape)\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " total_loss += loss.detach().float()\n", " loss.backward()\n", " optimizer.step()\n", " lr_scheduler.step()\n", " optimizer.zero_grad()\n", "\n", " model.eval()\n", " eval_loss = 0\n", " eval_preds = []\n", " for step, batch in enumerate(tqdm(eval_dataloader)):\n", " batch = {k: v.to(device) for k, v in batch.items()}\n", " with torch.no_grad():\n", " outputs = model(**batch)\n", " loss = outputs.loss\n", " eval_loss += loss.detach().float()\n", " eval_preds.extend(\n", " tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), skip_special_tokens=True)\n", " )\n", "\n", " eval_epoch_loss = eval_loss / len(eval_dataloader)\n", " eval_ppl = torch.exp(eval_epoch_loss)\n", " train_epoch_loss = total_loss / len(train_dataloader)\n", " train_ppl = torch.exp(train_epoch_loss)\n", " print(f\"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=}\")" ] }, { "cell_type": "code", "execution_count": 12, "id": "826c92ba-0e19-4a43-ba89-df83034c2887", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game.\n", "{'input_ids': tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 54078, 2566, 7782, 24502, 2632, 8989,\n", " 427, 36992, 2670, 140711, 21994, 10789, 530, 88399, 632,\n", " 183542, 368, 44799, 17, 29901, 5926, 7229, 861, 11596,\n", " 461, 78851, 14775, 17, 77658, 915, 210, 1936, 106863,\n", " 1936, 106863, 1936, 106863, 1936, 106863, 1936, 106863]],\n", " device='cuda:0')\n", "[\"Tweet text : Hey @nytimes your link to cancel my subscription isn't working and nobody is answering the chat. Please don't play that kind of stupid game. Label : no complaintno complaintno complaintno complaintno complaint\"]\n" ] } ], "source": [ "# 模型评估\n", "model.eval()\n", "i = 16\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": 13, "id": "c9756276-4b79-4f2e-bf12-a092d8734651", "metadata": {}, "outputs": [], "source": [ "# saving model\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "model.save_pretrained(peft_model_id)" ] }, { "cell_type": "code", "execution_count": 14, "id": "d602335e-bd15-4e87-98c9-43f6c6d3913f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "5.7M\t/data/nfs/llm/model/bloomz-560m_PREFIX_TUNING_CAUSAL_LM/adapter_model.bin\n", "--------------\n", "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n", "To disable this warning, you can either:\n", "\t- Avoid using `tokenizers` before the fork if possible\n", "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n", "/data/nfs/llm/model/bloomz-560m_PREFIX_TUNING_CAUSAL_LM\n", "├── [ 389] adapter_config.json\n", "├── [5.6M] adapter_model.bin\n", "└── [ 111] README.md\n", "\n", "0 directories, 3 files\n" ] } ], "source": [ "ckpt = f\"{peft_model_id}/adapter_model.bin\"\n", "!du -h $ckpt\n", "print(\"--------------\")\n", "!tree -h $peft_model_id" ] }, { "cell_type": "code", "execution_count": 15, "id": "04885484-b34b-4d3e-8217-0da101dfdcda", "metadata": {}, "outputs": [], "source": [ "from peft import PeftModel, PeftConfig\n", "\n", "peft_model_id = f\"{model_name_or_path}_{peft_config.peft_type}_{peft_config.task_type}\"\n", "\n", "config = PeftConfig.from_pretrained(peft_model_id)\n", "model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path)\n", "model = PeftModel.from_pretrained(model, peft_model_id)" ] }, { "cell_type": "code", "execution_count": 16, "id": "c3ef0558-be14-43c0-a28e-e0c623f5e2fa", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "@greateranglia Ok thanks...\n", "{'input_ids': tensor([[227985, 5484, 915, 2566, 14173, 2960, 29906, 387, 20706,\n", " 49337, 1369, 77658, 915, 210]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}\n", "tensor([[227985, 5484, 915, 2566, 14173, 2960, 29906, 387, 20706,\n", " 49337, 1369, 77658, 915, 210, 1936, 106863, 1936, 106863,\n", " 1936, 106863, 1936, 106863, 1936, 106863]], device='cuda:0')\n", "['Tweet text : @greateranglia Ok thanks... Label : no complaintno complaintno complaintno complaintno complaint']\n" ] } ], "source": [ "model.to(device)\n", "model.eval()\n", "i = 4\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))" ] }, { "cell_type": "code", "execution_count": null, "id": "d3a61b0a-2b61-4fcb-8e9f-2ee7096f700a", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-train/peft/clm/peft_prompt_tuning_clm.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "id": "b97c2af7-a217-496b-90df-c3f2b15d0b9a", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/guodong.li/virtual-venv/peft-venv-py310-cu117/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[2023-07-20 19:48:06,759] [INFO] [real_accelerator.py:133:get_accelerator] Setting ds_accelerator to cuda (auto detect)\n" ] } ], "source": [ "from transformers import AutoModelForCausalLM\n", "from peft import get_peft_config, get_peft_model, PromptTuningInit, PromptTuningConfig, TaskType, PeftType\n", "import torch\n", "from datasets import load_dataset\n", "import os\n", "from transformers import AutoTokenizer\n", "from torch.utils.data import DataLoader\n", "from transformers import default_data_collator, get_linear_schedule_with_warmup\n", "from tqdm import tqdm\n", "from datasets import load_dataset" ] }, { "cell_type": "code", "execution_count": 2, "id": "81be8225-e340-4b3e-8126-32e4b035bd48", "metadata": {}, "outputs": [], "source": [ "device = \"cuda\"\n", "\n", "model_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "tokenizer_name_or_path = \"/data/nfs/llm/model/bloomz-560m\"\n", "\n", "peft_config = PromptTuningConfig(\n", " task_type=TaskType.CAUSAL_LM,\n", " prompt_tuning_init=PromptTuningInit.TEXT,\n", " num_virtual_tokens=8,\n", " prompt_tuning_init_text=\"Classify if the tweet is a complaint or not:\",\n", " tokenizer_name_or_path=model_name_or_path,\n", ")\n", "\n", "dataset_name = \"twitter_complaints\"\n", "\n", "text_column = \"Tweet text\"\n", "label_column = \"text_label\"\n", "max_length = 64\n", "lr = 3e-2\n", "num_epochs = 10\n", "batch_size = 8" ] }, { "cell_type": "code", "execution_count": 3, "id": "5a637672-43a6-4ba4-9905-a070ff3649fc", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Found cached dataset raft (/home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84)\n", "100%|██████████| 2/2 [00:00<00:00, 759.01it/s]\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-0e20fff6b1d898ca.arrow\n", "Loading cached processed dataset at /home/guodong.li/data/peft/data/raft/twitter_complaints/1.1.0/79c4de1312c1e3730043f7db07179c914f48403101f7124e2fe336f6f54d9f84/cache-8d14a62b8a688c19.arrow\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "['Unlabeled', 'complaint', 'no complaint']\n", "DatasetDict({\n", " train: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 50\n", " })\n", " test: Dataset({\n", " features: ['Tweet text', 'ID', 'Label', 'text_label'],\n", " num_rows: 3399\n", " })\n", "})\n" ] }, { "data": { "text/plain": [ "{'Tweet text': '@HMRCcustomers No this is my first job',\n", " 'ID': 0,\n", " 'Label': 2,\n", " 'text_label': 'no complaint'}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from datasets import load_dataset\n", "\n", "#dataset = load_dataset(\"ought/raft\", dataset_name)\n", "dataset = load_dataset(\"/home/guodong.li/data/peft/raft/raft.py\", dataset_name, cache_dir=\"/home/guodong.li/data/peft/data\")\n", "\n", "classes = [k.replace(\"_\", \" \") for k in dataset[\"train\"].features[\"Label\"].names]\n", "print(classes)\n", "\n", "dataset = dataset.map(\n", " lambda x: {\"text_label\": [classes[label] for label in x[\"Label\"]]},\n", " batched=True,\n", " num_proc=1,\n", ")\n", "print(dataset)\n", "\n", "dataset[\"train\"][0]" ] }, { "cell_type": "code", "execution_count": 4, "id": "2479040b-0ccf-4100-9429-42737e87ebcf", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "target_max_length: 3\n", "column_names: ['Tweet text', 'ID', 'Label', 'text_label']\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " \r" ] }, { "name": "stdout", "output_type": "stream", "text": [ "batch_size: 50\n", "0 [227985, 5484, 915, 2566, 169403, 15296, 36272, 525, 3928, 1119, 632, 2670, 3968, 15270, 77658, 915, 210] [1936, 106863, 3]\n", "model_inputs input_ids: tensor([ 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 3,\n", " 3, 3, 3, 3, 3, 3, 3, 3, 227985,\n", " 5484, 915, 2566, 169403, 15296, 36272, 525, 3928, 1119,\n", " 632, 2670, 3968, 15270, 77658, 915, 210, 1936, 106863,\n", " 3])\n", "model_inputs attention_mask: tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,\n", " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])\n", "labels input_ids: tensor([ -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, -100, -100,\n", " -100, -100, -100, -100, -100, -100, -100, 1936, 106863,\n", " 3])\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Running tokenizer on dataset: 0%| | 0/3399 [00:00\\n\\n']\n" ] } ], "source": [ "model.to(device)\n", "\n", "\n", "model.eval()\n", "i = 4\n", "inputs = tokenizer(f'{text_column} : {dataset[\"test\"][i][\"Tweet text\"]} Label : ', return_tensors=\"pt\")\n", "print(dataset[\"test\"][i][\"Tweet text\"])\n", "print(inputs)\n", "\n", "with torch.no_grad():\n", " inputs = {k: v.to(device) for k, v in inputs.items()}\n", " outputs = model.generate(\n", " input_ids=inputs[\"input_ids\"], attention_mask=inputs[\"attention_mask\"], max_new_tokens=10, eos_token_id=3\n", " )\n", " print(outputs)\n", " print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True))\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "d1c0c93c-3fa0-42e8-b944-e39b7057775a", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-train/peft/conditional_generation/README.md ================================================ ================================================ FILE: llm-train/peft/multimodal/blip2_lora_inference.py ================================================ import torch from datasets import load_dataset from torch.utils.data import DataLoader, Dataset from transformers import AutoModelForVision2Seq, AutoProcessor from peft import LoraConfig, get_peft_model from peft import PeftModel, PeftConfig import torch import requests from PIL import Image from transformers import Blip2Processor, Blip2ForConditionalGeneration peft_model_id = "/workspace/output/multimodal/blip2" config = PeftConfig.from_pretrained(peft_model_id) processor = Blip2Processor.from_pretrained(config.base_model_name_or_path) model = AutoModelForVision2Seq.from_pretrained(config.base_model_name_or_path, load_in_8bit=True, device_map="auto") model = PeftModel.from_pretrained(model, peft_model_id) train_dataset_path = "/workspace/data/pytorch_data/multimodal/blip2/ybelkada___football-dataset/default-80f5618dafa96df9/0.0.0/0111277fb19b16f696664cde7f0cb90f833dec72db2cc73cfdf87e697f78fe02" dataset = load_dataset(train_dataset_path, split="train") # Let's load the dataset here! #dataset = load_dataset("ybelkada/football-dataset", split="train") item = dataset[0] device = "cuda" if torch.cuda.is_available() else "cpu" model.eval() encoding = processor(images=item["image"], padding="max_length", return_tensors="pt") # remove batch dimension encoding = {k: v.squeeze() for k, v in encoding.items()} encoding["text"] = item["text"] print(encoding.keys()) processed_batch = {} for key in encoding.keys(): if key != "text": processed_batch[key] = torch.stack([example[key] for example in [encoding]]) else: text_inputs = processor.tokenizer( [example["text"] for example in [encoding]], padding=True, return_tensors="pt" ) processed_batch["input_ids"] = text_inputs["input_ids"] processed_batch["attention_mask"] = text_inputs["attention_mask"] pixel_values = processed_batch.pop("pixel_values").to(device, torch.float16) print("----------") generated_output = model.generate(pixel_values=pixel_values) print(processor.batch_decode(generated_output, skip_special_tokens=True)) ================================================ FILE: llm-train/peft/multimodal/blip2_lora_int8_fine_tune.py ================================================ # coding=utf-8 import torch from datasets import load_dataset from torch.utils.data import DataLoader, Dataset from transformers import AutoModelForVision2Seq, AutoProcessor import argparse from peft import LoraConfig, get_peft_model import os import matplotlib.pyplot as plt from PIL import Image class ImageCaptioningDataset(Dataset): def __init__(self, dataset, processor): self.dataset = dataset self.processor = processor def __len__(self): return len(self.dataset) def __getitem__(self, idx): item = self.dataset[idx] encoding = self.processor(images=item["image"], padding="max_length", return_tensors="pt") # remove batch dimension encoding = {k: v.squeeze() for k, v in encoding.items()} encoding["text"] = item["text"] return encoding def plot(loss_list, output_path): plt.figure(figsize=(10,5)) freqs = [i for i in range(len(loss_list))] # 绘制训练损失变化曲线 plt.plot(freqs, loss_list, color='#e4007f', label="image2text train/loss curve") # 绘制坐标轴和图例 plt.ylabel("loss", fontsize='large') plt.xlabel("epoch", fontsize='large') plt.legend(loc='upper right', fontsize='x-large') plt.savefig(output_path+'/pytorch_image2text_blip2_loss_curve.png') # plt.show() def main(): parser = argparse.ArgumentParser(description="PyTorch MNIST Example") parser.add_argument("--pretrain-model-path", dest="pretrain_model_path", required=False, type=str, default=None, help="预训练模型路径") parser.add_argument("--train-dataset-path", type=str, default="/Users/liguodong/data/mnist", help="训练集路径") parser.add_argument("--test-dataset-path", type=str, default="/Users/liguodong/data/mnist", help="测试集路径") parser.add_argument("--output-path", type=str, default="/Users/liguodong/output/pytorch_model",help="模型输出路径") args = parser.parse_args() train_dataset_path = args.train_dataset_path test_dataset_path = args.test_dataset_path output_path = args.output_path pretrain_model_path = args.pretrain_model_path if not os.path.exists(output_path): os.makedirs(output_path) #pretrain_model_path="/workspace/model/blip2-opt-2.7b" #train_dataset_path = "/workspace/data/pytorch_data/multimodal/blip2/ybelkada___football-dataset/default-80f5618dafa96df9/0.0.0/0111277fb19b16f696664cde7f0cb90f833dec72db2cc73cfdf87e697f78fe02" peft_model_id = output_path # We load our model and processor using `transformers` model = AutoModelForVision2Seq.from_pretrained(pretrain_model_path, load_in_8bit=True) processor = AutoProcessor.from_pretrained(pretrain_model_path) # Let's define the LoraConfig config = LoraConfig( r=16, lora_alpha=32, lora_dropout=0.05, bias="none", ) # Get our peft model and print the number of trainable parameters model = get_peft_model(model, config) model.print_trainable_parameters() # Let's load the dataset here! # dataset = load_dataset("ybelkada/football-dataset", split="train") def collator(batch): # pad the input_ids and attention_mask processed_batch = {} for key in batch[0].keys(): if key != "text": processed_batch[key] = torch.stack([example[key] for example in batch]) else: text_inputs = processor.tokenizer( [example["text"] for example in batch], padding=True, return_tensors="pt" ) processed_batch["input_ids"] = text_inputs["input_ids"] processed_batch["attention_mask"] = text_inputs["attention_mask"] return processed_batch dataset = load_dataset(train_dataset_path, split="train") train_dataset = ImageCaptioningDataset(dataset, processor) train_dataloader = DataLoader(train_dataset, shuffle=True, batch_size=2, collate_fn=collator) optimizer = torch.optim.AdamW(model.parameters(), lr=5e-5) device = "cuda" if torch.cuda.is_available() else "cpu" model.train() loss_list = [] for epoch in range(11): print("Epoch:", epoch) sum_loss_list = [] for idx, batch in enumerate(train_dataloader): input_ids = batch.pop("input_ids").to(device) pixel_values = batch.pop("pixel_values").to(device, torch.float16) outputs = model(input_ids=input_ids, pixel_values=pixel_values, labels=input_ids) loss = outputs.loss print("Loss:", loss.item()) sum_loss_list.append(float(loss.item())) loss.backward() optimizer.step() optimizer.zero_grad() if idx % 10 == 0: generated_output = model.generate(pixel_values=pixel_values) print(processor.batch_decode(generated_output, skip_special_tokens=True)) avg_sum_loss = sum(sum_loss_list)/len(sum_loss_list) print("epoch: ", epoch, "loss: ", float(avg_sum_loss)) loss_list.append(float(avg_sum_loss)) if not os.path.exists(peft_model_id): os.makedirs(peft_model_id) print("model_output:", peft_model_id) model.save_pretrained(peft_model_id) plot(loss_list, peft_model_id) if __name__ == "__main__": main() ================================================ FILE: llm-train/peft/multimodal/finetune_bloom_bnb_peft.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "id": "de5fe140-f950-4f55-a69d-32b200ad8a7a", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/conda/lib/python3.10/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\n", "===================================BUG REPORT===================================\n", "Welcome to bitsandbytes. For bug reports, please submit your error trace to: https://github.com/TimDettmers/bitsandbytes/issues\n", "================================================================================\n", "CUDA_SETUP: WARNING! libcudart.so not found in any environmental path. Searching /usr/local/cuda/lib64...\n", "CUDA SETUP: CUDA runtime path found: /usr/local/cuda/lib64/libcudart.so\n", "CUDA SETUP: Highest compute capability among GPUs detected: 8.0\n", "CUDA SETUP: Detected CUDA version 117\n", "CUDA SETUP: Loading binary /usr/local/conda/lib/python3.10/site-packages/bitsandbytes-0.37.2-py3.10.egg/bitsandbytes/libbitsandbytes_cuda117.so...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/conda/lib/python3.10/site-packages/bitsandbytes-0.37.2-py3.10.egg/bitsandbytes/cuda_setup/main.py:136: UserWarning: WARNING: The following directories listed in your path were found to be non-existent: {PosixPath('/usr/local/nvidia/lib'), PosixPath('/usr/local/cuda/extras/CUPTI/lib64'), PosixPath('/usr/local/nvidia/lib64')}\n", " warn(msg)\n", "/usr/local/conda/lib/python3.10/site-packages/bitsandbytes-0.37.2-py3.10.egg/bitsandbytes/cuda_setup/main.py:136: UserWarning: /usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/cuda/extras/CUPTI/lib64 did not contain libcudart.so as expected! Searching further paths...\n", " warn(msg)\n", "/usr/local/conda/lib/python3.10/site-packages/bitsandbytes-0.37.2-py3.10.egg/bitsandbytes/cuda_setup/main.py:136: UserWarning: WARNING: The following directories listed in your path were found to be non-existent: {PosixPath('module'), PosixPath('//matplotlib_inline.backend_inline')}\n", " warn(msg)\n" ] } ], "source": [ "import os\n", "\n", "import torch\n", "import torch.nn as nn\n", "import bitsandbytes as bnb\n", "from transformers import AutoTokenizer, AutoConfig, AutoModelForCausalLM\n", "\n", "device=\"cuda\"\n", "model = AutoModelForCausalLM.from_pretrained(\"/workspace/model/bloomz-3b\", load_in_8bit=True)\n", "tokenizer = AutoTokenizer.from_pretrained(\"/workspace/model/bloomz-3b\")" ] }, { "cell_type": "code", "execution_count": 2, "id": "836e6354-38e2-471c-966e-71614d35c5dc", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/conda/lib/python3.10/site-packages/peft/utils/other.py:136: FutureWarning: prepare_model_for_int8_training is deprecated and will be removed in a future version. Use prepare_model_for_kbit_training instead.\n", " warnings.warn(\n" ] } ], "source": [ "from peft import prepare_model_for_int8_training\n", "model = prepare_model_for_int8_training(model)" ] }, { "cell_type": "code", "execution_count": 3, "id": "45138378-5788-4cbd-a938-d2d969f56c26", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "trainable params: 4915200 || all params: 3007472640 || trainable%: 0.1634329082375293\n" ] } ], "source": [ "def print_trainable_parameters(model):\n", " \"\"\"\n", " Prints the number of trainable parameters in the model.\n", " \"\"\"\n", " trainable_params = 0\n", " all_param = 0\n", " for _, param in model.named_parameters():\n", " all_param += param.numel()\n", " if param.requires_grad:\n", " trainable_params += param.numel()\n", " print(\n", " f\"trainable params: {trainable_params} || all params: {all_param} || trainable%: {100 * trainable_params / all_param}\"\n", " )\n", "\n", "from peft import LoraConfig, get_peft_model\n", "\n", "config = LoraConfig(\n", " r=16, lora_alpha=32, target_modules=[\"query_key_value\"], lora_dropout=0.05, bias=\"none\", task_type=\"CAUSAL_LM\"\n", ")\n", "\n", "model = get_peft_model(model, config)\n", "model = model.to(device)\n", "print_trainable_parameters(model)" ] }, { "cell_type": "code", "execution_count": 4, "id": "b482dbfd-95dd-47a6-8762-124d613756dc", "metadata": {}, "outputs": [], "source": [ "import transformers\n", "from datasets import load_dataset\n", "\n", "# data = load_dataset(\"Abirate/english_quotes\")\n", "\n", "data = load_dataset(\"/workspace/data/8bb11242116d547c741b2e8a1f18598ffdd40a1d4f2a2872c7a28b697434bc96\")\n", "data = data.map(lambda samples: tokenizer(samples[\"quote\"]), batched=True)\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 5, "id": "0de2b961-d394-422c-8ef3-3c55893dec2a", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "You're using a BloomTokenizerFast tokenizer. Please note that with a fast tokenizer, using the `__call__` method is faster than using a method to encode the text followed by a call to the `pad` method to get a padded encoding.\n", "/usr/local/conda/lib/python3.10/site-packages/bitsandbytes-0.37.2-py3.10.egg/bitsandbytes/autograd/_functions.py:298: UserWarning: MatMul8bitLt: inputs will be cast from torch.float32 to float16 during quantization\n", " warnings.warn(f\"MatMul8bitLt: inputs will be cast from {A.dtype} to float16 during quantization\")\n" ] }, { "data": { "text/html": [ "\n", "
\n", " \n", " \n", " [20/20 01:55, Epoch 0/1]\n", "
\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
StepTraining Loss
13.211400
23.373700
33.170300
43.282100
53.187100
63.196800
72.952900
83.212800
93.168700
103.116700
113.131100
122.964200
132.955700
143.010200
153.048800
163.031200
172.885200
183.000700
192.994000
203.083600

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "checkpoint folder: outputs/checkpoint-10\n", "checkpoint folder list: ['README.md', 'adapter_config.json', 'adapter_model', 'adapter_model.safetensors', 'optimizer.pt', 'rng_state.pth', 'scheduler.pt', 'trainer_state.json', 'training_args.bin']\n", "checkpoint adapter folder list: ['README.md', 'adapter_config.json', 'adapter_model.bin']\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/conda/lib/python3.10/site-packages/bitsandbytes-0.37.2-py3.10.egg/bitsandbytes/autograd/_functions.py:298: UserWarning: MatMul8bitLt: inputs will be cast from torch.float32 to float16 during quantization\n", " warnings.warn(f\"MatMul8bitLt: inputs will be cast from {A.dtype} to float16 during quantization\")\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "checkpoint folder: outputs/checkpoint-20\n", "checkpoint folder list: ['README.md', 'adapter_config.json', 'adapter_model', 'adapter_model.safetensors', 'optimizer.pt', 'rng_state.pth', 'scheduler.pt', 'trainer_state.json', 'training_args.bin']\n", "checkpoint adapter folder list: ['README.md', 'adapter_config.json', 'adapter_model.bin']\n" ] }, { "data": { "text/plain": [ "TrainOutput(global_step=20, training_loss=3.098853278160095, metrics={'train_runtime': 122.735, 'train_samples_per_second': 10.429, 'train_steps_per_second': 0.163, 'total_flos': 2954973215784960.0, 'train_loss': 3.098853278160095, 'epoch': 0.51})" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from transformers import Seq2SeqTrainer, TrainerCallback, TrainingArguments, TrainerState, TrainerControl\n", "from transformers.trainer_utils import PREFIX_CHECKPOINT_DIR\n", "\n", "class SavePeftModelCallback(TrainerCallback):\n", " def on_save(\n", " self,\n", " args: TrainingArguments,\n", " state: TrainerState,\n", " control: TrainerControl,\n", " **kwargs,\n", " ):\n", " checkpoint_folder = os.path.join(args.output_dir, f\"{PREFIX_CHECKPOINT_DIR}-{state.global_step}\")\n", " print(\"checkpoint folder: \",checkpoint_folder)\n", " peft_model_path = os.path.join(checkpoint_folder, \"adapter_model\")\n", " kwargs[\"model\"].save_pretrained(peft_model_path)\n", "\n", " \n", " files = os.listdir(checkpoint_folder)\n", " print(\"checkpoint folder list: \", files)\n", " adapter_files = os.listdir(peft_model_path)\n", " print(\"checkpoint adapter folder list: \", adapter_files)\n", " \n", " pytorch_model_path = os.path.join(checkpoint_folder, \"pytorch_model.bin\")\n", " if os.path.exists(pytorch_model_path):\n", " os.remove(pytorch_model_path)\n", " return control\n", "\n", "args = transformers.TrainingArguments(\n", " per_device_train_batch_size=2,\n", " gradient_accumulation_steps=4,\n", " warmup_steps=5,\n", " max_steps=20,\n", " learning_rate=2e-4,\n", " fp16=True,\n", " logging_steps=1,\n", " output_dir=\"outputs\",\n", " save_strategy = 'steps',\n", " save_steps = 10\n", " )\n", "\n", "trainer = transformers.Trainer(\n", " model=model,\n", " train_dataset=data[\"train\"],\n", " args=args,\n", " data_collator=transformers.DataCollatorForLanguageModeling(tokenizer, mlm=False),\n", " callbacks=[SavePeftModelCallback()],\n", ")\n", "\n", "model.config.use_cache = False # silence the warnings. Please re-enable for inference!\n", "\n", "trainer.train()" ] }, { "cell_type": "code", "execution_count": 6, "id": "44cf46c9-dbaf-45f0-9a05-694ce53b74f1", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/conda/lib/python3.10/site-packages/transformers/generation/utils.py:1591: UserWarning: You are calling .generate() with the `input_ids` being on a device type different than your model's device. `input_ids` is on cpu, whereas the model is on cuda. You may experience unexpected behaviors or slower generation. Please make sure that you have put `input_ids` to the correct device by calling for example input_ids = input_ids.to('cuda') before running `.generate()`.\n", " warnings.warn(\n", "/usr/local/conda/lib/python3.10/site-packages/bitsandbytes-0.37.2-py3.10.egg/bitsandbytes/autograd/_functions.py:298: UserWarning: MatMul8bitLt: inputs will be cast from torch.float32 to float16 during quantization\n", " warnings.warn(f\"MatMul8bitLt: inputs will be cast from {A.dtype} to float16 during quantization\")\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "output:\n", "\n", " Two things are infinite: the universe and the number of ways you can screw up.\n" ] } ], "source": [ "import torch\n", "from peft import PeftModel, PeftConfig\n", "from transformers import AutoModelForCausalLM, AutoTokenizer\n", "\n", "peft_model_id = \"outputs/checkpoint-20/\"\n", "config = PeftConfig.from_pretrained(peft_model_id)\n", "model = AutoModelForCausalLM.from_pretrained(\n", " config.base_model_name_or_path, return_dict=True, load_in_8bit=True, device_map=\"auto\"\n", ")\n", "tokenizer = AutoTokenizer.from_pretrained(config.base_model_name_or_path)\n", "\n", "# Load the Lora model\n", "model = PeftModel.from_pretrained(model, peft_model_id)\n", "\n", "batch = tokenizer(\"Two things are infinite: \", return_tensors=\"pt\")\n", "\n", "with torch.cuda.amp.autocast():\n", " output_tokens = model.generate(**batch, max_new_tokens=50)\n", "\n", "print(\"output:\\n\\n\", tokenizer.decode(output_tokens[0], skip_special_tokens=True))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.9" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-train/pytorch/Pytorch源码解读.md ================================================ - PyTorch 源码解读系列:https://zhuanlan.zhihu.com/p/328674159 - PyTorch训练推理:https://www.zhihu.com/column/gemfield - PyTorch 分布式:https://juejin.cn/post/7026144707591815175 ================================================ FILE: llm-train/pytorch/README.md ================================================ - 镜像:https://hub.docker.com/r/pytorch/pytorch - https://github.com/pytorch/examples - https://github.com/pytorch/examples.git - https://github.com/pytorch/pytorch --- - torch.distributed.get_rank() # 取得当前进程的全局序号 - torch.distributed.get_world_size() # 取得全局进程的个数 - torch.cuda.set_device(device) # 为当前进程分配GPU - torch.distributed.new_group(ranks) # 设置组 - torch.cuda.current_device() --- --- - https://pytorch.org/tutorials/intermediate/FSDP_tutorial.html - ## PyTorch 分布式训练 - PyTorch 分布式训练(一):概述 - PyTorch 分布式训练(二):数据并行 - PyTorch 分布式训练(三):分布式自动微分 - PyTorch 分布式训练(四):分布式优化器 - PyTorch 分布式训练(五):分布式 RPC 框架 - ## 问题排查 - 将环境变量 NCCL_DEBUG 设置为 INFO 以打印有助于诊断问题的详细日志。(export NCCL_DEBUG=INFO) - 显式设置网络接口。(export NCCL_SOCKET_IFNAME=eth0) ================================================ FILE: llm-train/pytorch/api.md ================================================ dist.init_process_group()是PyTorch中用于初始化分布式训练的函数之一。 它用于设置并行训练环境,连接多个进程以进行数据和模型的分布式处理。我们通过init_process_group()函数这个方法来进行初始化, 其参数包括以下内容 backend(必需参数):指定分布式后端的类型,可以是以下选项之一: ‘tcp’:使用TCP协议进行通信。 ‘gloo’:使用Gloo库进行通信。 ‘mpi’:使用MPI(Message Passing Interface)进行通信。 ‘nccl’:使用NCCL库进行通信(适用于多GPU的分布式训练)。 ‘hccl’:使用HCCL库进行通信(适用于华为昇腾AI处理器的分布式训练)。 init_method(可选参数):指定用于初始化分布式环境的方法。它可以是以下选项之一: ‘env://’:使用环境变量中指定的方法进行初始化。 ‘file:// ’:使用本地文件进行初始化。 ‘tcp://:’:使用TCP地址和端口进行初始化。 ‘gloo://:’:使用Gloo地址和端口进行初始化。 ‘mpi://:’:使用MPI地址和端口进行初始化。 rank(可选参数):指定当前进程的排名(从0开始)。 world_size(可选参数):指定总共使用的进程数。 timeout(可选参数):指定初始化的超时时间。 group_name(可选参数):指定用于连接的进程组名称。 这里由于服务器采用的slurm系统,我们开始计划使用mpi去实现分布式分发,同时torch的初始化也支持mpi,原始想法是通过mpirun来进行分布式计算。但是,如果要使用mpi来实现分布式功能,必须要通过github上的源代码进行编译,通过conda和pip进行下载的pytorch自身是不携带mpi的 通过上面的参数,可以看到backend是有多种通信方式的,常用的有gloo和mpi和nccl,但是这三者是有区别的: 对于分布式 GPU 训练,使用 NCCL 后端。 对于分布式 CPU 训练,使用 Gloo 后端。 如果你的主机是 GPU 主机并且具有 InfiniBand 互连: 使用 NCCL,因为它是目前唯一支持 InfiniBand 和 GPUDirect 的后端。 如果你的主机是 GPU 主机并且具有以太网互连: 使用 NCCL,因为它目前提供了最好的分布式 GPU 训练性能,特别是对于多进程单节点或多节点分布式训练。 如果你遇到 NCCL 的任何问题,使用 Gloo 作为备选选项。(注意,Gloo 目前运行速度比 NCCL 慢) 如果你的主机是 CPU 主机并且具有 InfiniBand 互连: 如果你的 InfiniBand 启用了 IP over IB,使用 Gloo,否则,使用 MPI。我们计划在即将发布的版本中为 Gloo 添加 InfiniBand 支持。 如果你的主机是 CPU 主机并且具有以太网互连: 使用 Gloo,除非你有特定的理由使用 MPI​。 我们可以根据文档的提示,得出,MPI是最不推荐使用的一种方法,对于英伟达的显卡,最优先的还是使用NCCL方法。 和Mpi相匹配的有一种torch官方自带的方法,在torch2.0之前使用的API叫:torch.distributed.launch在使用时显示未来的版本将会弃用这个API,取而代之的是torchrun。因此我们将命令由mpi改为torchrun方法,在dist初始化使用nccl后端通信。 假设我们有三个节点,node02,node03,node04,每个节点上有四张GPU。现在我们将官方测试文档中的代码写为test_mpi.py。最终通过torchrun实现的命令如下: torchrun --nproc_per_node=4 --nnodes=3 --node_rank=0 --master_addr=192.168.0.101 --master_port=29500 test_mpi.py 我们没有必要和torchrun的官方文档一样去设置**–rdzv-backend** 和**–rdzv-id**,因为这不是必须的,用默认的即可。我们只需要设置的参数只有上面这几个。具体参数介绍如下: –nproc_per_node=4:指定每个节点(机器)上的进程数,这里是4个。意味着每个机器将启动4个进程来参与分布式训练。 –nnodes=3:指定总共的节点数,这里是3个。意味着总共有3个机器参与分布式训练。 –node_rank=0:指定当前节点(机器)的排名,这里是0。排名从0开始,用于在分布式环境中区分不同的节点。 –master_addr=192.168.0.101:指定主节点的IP地址,这里是192.168.0.101。主节点用于协调分布式训练过程。 –master_port=29500:指定主节点的端口号,这里是29500。主节点使用指定的端口来与其他节点进行通信。 通过设置这些参数,该命令将在3个节点的分布式环境中启动4个进程,并指定192.168.0.101作为主节点进行协调和通信。 这里的主节点地址我随便写的,可以根据实际情况进行修改。主节点的地址的- --node_rank必须设置为0,也就是上述这行命令,必须要先在主节点上线运行。 举个例子,假如我的主节点是node02,那么我就要先在node02节点的终端上运行上述torchrun命令,同时–master_addr要为node02的ip地址(查看IP地址可以通过:ip addr),然后node03,node04的顺序就不重要了,在其节点的终端上将–node_rank=0改为–node_rank=1和–node_rank=2运行即可。 ================================================ FILE: llm-train/pytorch/distribution/README.md ================================================ ``` docker run -dt --name pytorch_env_cu117 --restart=always --gpus all \ --network=host \ --shm-size 4G \ -v /home/gdong/workspace/code:/workspace/code \ -v /home/gdong/workspace/data:/workspace/data \ -v /home/gdong/workspace/model:/workspace/model \ -v /home/gdong/workspace/output:/workspace/output \ -v /home/gdong/workspace/package:/workspace/package \ -w /workspace \ pytorch/pytorch:2.0.0-cuda11.7-cudnn8-devel \ /bin/bash docker exec -it pytorch_env_cu117 bash ``` ================================================ FILE: llm-train/pytorch/distribution/api.md ================================================ ================================================ FILE: llm-train/pytorch/distribution/data-parallel/README.md ================================================ # DDP - https://zhuanlan.zhihu.com/p/343951042 ## 数据并行 当一张 GPU 可以存储一个模型时,可以采用数据并行得到更准确的梯度或者加速训练,即每个 GPU 复制一份模型,将一批样本分为多份输入各个模型并行计算。因为求导以及加和都是线性的,数据并行在数学上也有效。 ## DP model = nn.DataParallel(model) ## DDP DDP 通过 Reducer 来管理梯度同步。为了提高通讯效率, Reducer 会将梯度归到不同的桶里(按照模型参数的 reverse order, 因为反向传播需要符合这样的顺序),一次归约一个桶。其中,桶的大小为参数 bucket_cap_mb 默认为 25,可根据需要调整。 可以看到每个进程里,模型参数都按照倒序放在桶里,每次归约一个桶。 DDP 通过在构建时注册 autograd hook 进行梯度同步。反向传播时,当一个梯度计算好后,相应的 hook 会告诉 DDP 可以用来归约。 当一个桶里的梯度都可以了,Reducer 就会启动异步 allreduce 去计算所有进程的平均值。allreduce 异步启动使得 DDP 可以边计算边通信,提高效率。 当所有桶都可以了,Reducer 会等所有 allreduce 完成,然后将得到的梯度写到 param.grad。 ### DDP+MP DDP与流水线并行。 ## launch 通过 launch.py 启动,在 8 个 GPU 节点上,每个 GPU 一个进程: ``` python /home/guodong.li/virtual-venv/megatron-ds-venv-py310-cu117/lib/python3.10/site-packages/torch/distributed/launch.py --nnode=1 --node_rank=0 --nproc_per_node=8 example.py --local_world_size=8 python /home/guodong.li/virtual-venv/megatron-ds-venv-py310-cu117/lib/python3.10/site-packages/torch/distributed/launch.py --nnode=1 --node_rank=0 --nproc_per_node=1 example.py --local_world_size=1 ``` ## torch elastic/torchrun ``` torchrun --nnodes=2 --nproc_per_node=8 --rdzv_id=100 --rdzv_backend=c10d --rdzv_endpoint=$MASTER_ADDR:29400 elastic_ddp.py ``` 我们在两台主机上运行 DDP 脚本,每台主机运行 8 个进程,也就是说,我们在 16 个 GPU 上运行它。 请注意,所有节点上的 $MASTER_ADDR 必须相同。 这里torchrun将启动8个进程,并在启动它的节点上的每个进程上调用elastic_ddp.py, 但用户还需要应用slurm等集群管理工具才能在2个节点上实际运行此命令。 例如,在启用 SLURM 的集群上,我们可以编写一个脚本来运行上面的命令并将 MASTER_ADDR 设置为: ``` export MASTER_ADDR=$(scontrol show hostname ${SLURM_NODELIST} | head -n 1) ``` 然后我们可以使用 SLURM 命令运行此脚本: ``` srun --nodes=2 ./torchrun_script.sh ``` 当然,这只是一个例子; 您可以选择自己的集群调度工具来启动torchrun作业。 - 详细启动命令:https://pytorch.org/docs/stable/elastic/quickstart.html ``` torchrun --nnodes=1 --nproc_per_node=8 --rdzv_id=100 --rdzv_backend=c10d --rdzv_endpoint=127.0.0.1:29400 elastic_ddp.py ``` ``` torchrun --nnodes=2 --nproc_per_node=8 --node_rank=0 --rdzv_id=100 --rdzv_backend=c10d --rdzv_endpoint=10.xx.2.46:29400 multigpu_torchrun.py --batch_size 32 10 5 torchrun --nnodes=2 --nproc_per_node=8 --node_rank=1 --rdzv_id=100 --rdzv_backend=c10d --rdzv_endpoint=10.xx.2.46:29400 multigpu_torchrun.py --batch_size 32 10 5 ``` ## 官方文档 - DDP 教程:https://pytorch.org/tutorials/intermediate/ddp_tutorial.html - DDP 设计:https://pytorch.org/docs/master/notes/ddp.html - DDP 示例: - https://github.com/pytorch/examples/tree/main/distributed/ddp (官方没有更新了) - https://github.com/pytorch/examples/tree/main/distributed/ddp-tutorial-series # FSDP - GETTING STARTED WITH FULLY SHARDED DATA PARALLEL(FSDP):https://pytorch.org/tutorials/intermediate/FSDP_tutorial.html - ADVANCED MODEL TRAINING WITH FULLY SHARDED DATA PARALLEL (FSDP):https://pytorch.org/tutorials/intermediate/FSDP_adavnced_tutorial.html ================================================ FILE: llm-train/pytorch/distribution/data-parallel/ddp_launch.py ================================================ import argparse import os import sys import tempfile from urllib.parse import urlparse import torch import torch.distributed as dist import torch.nn as nn import torch.optim as optim from torch.nn.parallel import DistributedDataParallel as DDP class ToyModel(nn.Module): def __init__(self): super(ToyModel, self).__init__() self.net1 = nn.Linear(10, 10) self.relu = nn.ReLU() self.net2 = nn.Linear(10, 5) def forward(self, x): return self.net2(self.relu(self.net1(x))) def demo_basic(local_world_size, local_rank): # setup devices for this process. For local_world_size = 2, num_gpus = 8, # rank 0 uses GPUs [0, 1, 2, 3] and # rank 1 uses GPUs [4, 5, 6, 7]. n = torch.cuda.device_count() // local_world_size device_ids = list(range(local_rank * n, (local_rank + 1) * n)) print( f"[{os.getpid()}] rank = {dist.get_rank()}, " + f"world_size = {dist.get_world_size()}, n = {n}, device_ids = {device_ids} \n", end='' ) model = ToyModel().cuda(device_ids[0]) # ddp_model = DDP(model, device_ids) ddp_model = DDP(model, [device_ids[0]]) loss_fn = nn.MSELoss() optimizer = optim.SGD(ddp_model.parameters(), lr=0.001) optimizer.zero_grad() outputs = ddp_model(torch.randn(20, 10)) labels = torch.randn(20, 5).to(device_ids[0]) loss_fn(outputs, labels).backward() optimizer.step() def spmd_main(local_world_size, local_rank): # These are the parameters used to initialize the process group env_dict = { key: os.environ[key] for key in ("MASTER_ADDR", "MASTER_PORT", "RANK", "WORLD_SIZE") } if sys.platform == "win32": # Distributed package only covers collective communications with Gloo # backend and FileStore on Windows platform. Set init_method parameter # in init_process_group to a local file. if "INIT_METHOD" in os.environ.keys(): print(f"init_method is {os.environ['INIT_METHOD']}") url_obj = urlparse(os.environ["INIT_METHOD"]) if url_obj.scheme.lower() != "file": raise ValueError("Windows only supports FileStore") else: init_method = os.environ["INIT_METHOD"] else: # It is a example application, For convience, we create a file in temp dir. temp_dir = tempfile.gettempdir() init_method = f"file:///{os.path.join(temp_dir, 'ddp_example')}" dist.init_process_group(backend="gloo", init_method=init_method, rank=int(env_dict["RANK"]), world_size=int(env_dict["WORLD_SIZE"])) else: print(f"[{os.getpid()}] Initializing process group with: {env_dict}") dist.init_process_group(backend="nccl") print( f"[{os.getpid()}]: world_size = {dist.get_world_size()}, " + f"rank = {dist.get_rank()}, backend={dist.get_backend()} \n", end='' ) demo_basic(local_world_size, local_rank) # Tear down the process group dist.destroy_process_group() if __name__ == "__main__": parser = argparse.ArgumentParser() # This is passed in via launch.py parser.add_argument("--local_rank", type=int, default=0) # This needs to be explicitly passed in parser.add_argument("--local_world_size", type=int, default=1) args = parser.parse_args() # The main entry point is called directly without using subprocess spmd_main(args.local_world_size, args.local_rank) ================================================ FILE: llm-train/pytorch/distribution/data-parallel/ddp_main.py ================================================ import os import tempfile import torch import torch.distributed as dist import torch.multiprocessing as mp import torch.nn as nn import torch.optim as optim from torch.nn.parallel import DistributedDataParallel as DDP def setup(rank, world_size): os.environ['MASTER_ADDR'] = 'localhost' os.environ['MASTER_PORT'] = '12355' # initialize the process group dist.init_process_group("gloo", rank=rank, world_size=world_size) def cleanup(): dist.destroy_process_group() class ToyModel(nn.Module): def __init__(self): super(ToyModel, self).__init__() self.net1 = nn.Linear(10, 10) self.relu = nn.ReLU() self.net2 = nn.Linear(10, 5) def forward(self, x): return self.net2(self.relu(self.net1(x))) def demo_basic(rank, world_size): print(f"Running basic DDP example on rank {rank}.") setup(rank, world_size) # create model and move it to GPU with id rank model = ToyModel().to(rank) ddp_model = DDP(model, device_ids=[rank]) loss_fn = nn.MSELoss() optimizer = optim.SGD(ddp_model.parameters(), lr=0.001) optimizer.zero_grad() outputs = ddp_model(torch.randn(20, 10)) labels = torch.randn(20, 5).to(rank) loss_fn(outputs, labels).backward() optimizer.step() cleanup() def run_demo(demo_fn, world_size): mp.spawn(demo_fn, args=(world_size,), nprocs=world_size, join=True) def demo_checkpoint(rank, world_size): print(f"Running DDP checkpoint example on rank {rank}.") setup(rank, world_size) model = ToyModel().to(rank) ddp_model = DDP(model, device_ids=[rank]) loss_fn = nn.MSELoss() optimizer = optim.SGD(ddp_model.parameters(), lr=0.001) CHECKPOINT_PATH = tempfile.gettempdir() + "/model.checkpoint" if rank == 0: # All processes should see same parameters as they all start from same # random parameters and gradients are synchronized in backward passes. # Therefore, saving it in one process is sufficient. torch.save(ddp_model.state_dict(), CHECKPOINT_PATH) # Use a barrier() to make sure that process 1 loads the model after process # 0 saves it. dist.barrier() # configure map_location properly map_location = {'cuda:%d' % 0: 'cuda:%d' % rank} ddp_model.load_state_dict( torch.load(CHECKPOINT_PATH, map_location=map_location)) optimizer.zero_grad() outputs = ddp_model(torch.randn(20, 10)) labels = torch.randn(20, 5).to(rank) loss_fn = nn.MSELoss() loss_fn(outputs, labels).backward() optimizer.step() # 没有必要使用 dist.barrier() 来警惕下面的文件删除,因为 DDP 向后传递中的 AllReduce 操作已经用作同步。 # Use a barrier() to make sure that all processes have finished reading the # checkpoint dist.barrier() if rank == 0: os.remove(CHECKPOINT_PATH) cleanup() class ToyMpModel(nn.Module): def __init__(self, dev0, dev1): super(ToyMpModel, self).__init__() self.dev0 = dev0 self.dev1 = dev1 self.net1 = torch.nn.Linear(10, 10).to(dev0) self.relu = torch.nn.ReLU() self.net2 = torch.nn.Linear(10, 5).to(dev1) def forward(self, x): x = x.to(self.dev0) x = self.relu(self.net1(x)) x = x.to(self.dev1) return self.net2(x) # DDP 还适用于多 GPU 模型。 当使用大量数据训练大模型时,DDP 包装多 GPU 模型特别有用。 def demo_model_parallel(rank, world_size): print(f"Running DDP with model parallel example on rank {rank}.") setup(rank, world_size) # setup mp_model and devices for this process dev0 = rank * 2 dev1 = rank * 2 + 1 mp_model = ToyMpModel(dev0, dev1) ddp_mp_model = DDP(mp_model) loss_fn = nn.MSELoss() optimizer = optim.SGD(ddp_mp_model.parameters(), lr=0.001) optimizer.zero_grad() # outputs will be on dev1 outputs = ddp_mp_model(torch.randn(20, 10)) labels = torch.randn(20, 5).to(dev1) loss_fn(outputs, labels).backward() optimizer.step() cleanup() # 将多 GPU 模型传递给 DDP 时,不得设置 device_ids 和 output_device。 # 输入和输出数据将通过应用程序或模型的forward()方法放置在适当的设备中。 if __name__ == "__main__": n_gpus = torch.cuda.device_count() if n_gpus < 8: print(f"Requires at least 8 GPUs to run, but got {n_gpus}.") else: run_demo(demo_basic, 8) run_demo(demo_checkpoint, 8) run_demo(demo_model_parallel, 4) ================================================ FILE: llm-train/pytorch/distribution/data-parallel/elastic_ddp.py ================================================ import torch import torch.distributed as dist import torch.nn as nn import torch.optim as optim from torch.nn.parallel import DistributedDataParallel as DDP class ToyModel(nn.Module): def __init__(self): super(ToyModel, self).__init__() self.net1 = nn.Linear(10, 10) self.relu = nn.ReLU() self.net2 = nn.Linear(10, 5) def forward(self, x): return self.net2(self.relu(self.net1(x))) def demo_basic(): dist.init_process_group("nccl") rank = dist.get_rank() print(f"Start running basic DDP example on rank {rank}.") # create model and move it to GPU with id rank device_id = rank % torch.cuda.device_count() model = ToyModel().to(device_id) ddp_model = DDP(model, device_ids=[device_id]) loss_fn = nn.MSELoss() optimizer = optim.SGD(ddp_model.parameters(), lr=0.001) optimizer.zero_grad() outputs = ddp_model(torch.randn(20, 10)) labels = torch.randn(20, 5).to(device_id) loss_fn(outputs, labels).backward() optimizer.step() dist.destroy_process_group() if __name__ == "__main__": demo_basic() ================================================ FILE: llm-train/pytorch/distribution/data-parallel/minGPT-ddp/README.md ================================================ # miniGPT - https://pytorch.org/tutorials/intermediate/ddp_series_minGPT.html 用于训练的文件: - trainer.py :包含 Trainer 类,该类使用提供的数据集在模型上运行分布式训练迭代。 - model.py :定义模型架构。 - char_dataset.py :包含字符级数据集的 Dataset 类。 - gpt2_train_cfg.yaml :包含数据、模型、优化器和训练运行的配置。 - main.py :训练作业的入口点。 它设置 DDP 进程组,读取所有配置并运行训练作业。 ## 单机多卡 ``` > torchrun --standalone --nproc_per_node=4 main.py WARNING:torch.distributed.run: ***************************************** Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. ***************************************** [2023-09-08 17:48:02,237][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 1 [2023-09-08 17:48:02,246][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 0 [2023-09-08 17:48:02,253][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 2 [2023-09-08 17:48:02,256][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 3 [2023-09-08 17:48:02,257][torch.distributed.distributed_c10d][INFO] - Rank 3: Completed store-based barrier for key:store_based_barrier_key:1 with 4 nodes. [2023-09-08 17:48:02,257][torch.distributed.distributed_c10d][INFO] - Rank 0: Completed store-based barrier for key:store_based_barrier_key:1 with 4 nodes. [2023-09-08 17:48:02,258][torch.distributed.distributed_c10d][INFO] - Rank 1: Completed store-based barrier for key:store_based_barrier_key:1 with 4 nodes. [2023-09-08 17:48:02,264][torch.distributed.distributed_c10d][INFO] - Rank 2: Completed store-based barrier for key:store_based_barrier_key:1 with 4 nodes. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. number of parameters: 27.32M number of parameters: 27.32M number of parameters: 27.32M number of parameters: 27.32M Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch [GPU3] Epoch 1 | Iter 0 | Train Loss 4.18844 [GPU0] Epoch 1 | Iter 0 | Train Loss 4.18055 [2023-09-08 17:48:06,586][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [GPU2] Epoch 1 | Iter 0 | Train Loss 4.18575 [GPU1] Epoch 1 | Iter 0 | Train Loss 4.18100 [2023-09-08 17:48:06,590][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-08 17:48:06,590][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-08 17:48:06,590][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [GPU0] Epoch 1 | Iter 0 | Eval Loss 2.35044 [GPU2] Epoch 1 | Iter 0 | Eval Loss 2.33801 ... [GPU1] Epoch 3 | Iter 0 | Train Loss 2.21209 [GPU2] Epoch 3 | Iter 0 | Train Loss 2.21229 Snapshot saved at epoch 3 [GPU2] Epoch 3 | Iter 0 | Eval Loss 2.12978 [GPU1] Epoch 3 | Iter 0 | Eval Loss 2.12159 ... [GPU2] Epoch 6 | Iter 0 | Train Loss 1.96697 [GPU1] Epoch 6 | Iter 0 | Train Loss 1.97281 Snapshot saved at epoch 6 [GPU2] Epoch 6 | Iter 0 | Eval Loss 1.84860 [GPU3] Epoch 6 | Iter 0 | Eval Loss 1.85607 [GPU1] Epoch 6 | Iter 0 | Eval Loss 1.86408 [GPU0] Epoch 6 | Iter 0 | Eval Loss 1.87735 ... [GPU2] Epoch 9 | Iter 0 | Train Loss 1.43359 [GPU0] Epoch 9 | Iter 0 | Train Loss 1.45036 [GPU1] Epoch 9 | Iter 0 | Train Loss 1.44486 [GPU3] Epoch 9 | Iter 0 | Train Loss 1.41639 Snapshot saved at epoch 9 [GPU2] Epoch 9 | Iter 0 | Eval Loss 1.28527 [GPU3] Epoch 9 | Iter 0 | Eval Loss 1.29209 ... [GPU3] Epoch 10 | Iter 0 | Eval Loss 1.13304 [GPU1] Epoch 10 | Iter 0 | Eval Loss 1.13287 ``` ## 多机多卡 ### 方案一 ``` export NCCL_IB_DISABLE=1 && export NCCL_SOCKET_IFNAME=bond0 && torchrun \ --nproc_per_node=2 --nnodes=2 --node_rank=0 \ --master_addr=xx.99.2.xx --master_port=29500 \ main.py export NCCL_IB_DISABLE=1 && export NCCL_SOCKET_IFNAME=bond0 && torchrun \ --nproc_per_node=2 --nnodes=2 --node_rank=1 \ --master_addr=xx.99.2.xx --master_port=29500 \ main.py ``` ### 方案二 ``` slurm/sbatch_run.sh ``` 日志: ``` > tail -100f slurm-949.out 0 ai-app-2-45 ai-app-2-46 ai-app-2-45 2 WARNING:torch.distributed.run: ***************************************** Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. ***************************************** WARNING:torch.distributed.run: ***************************************** Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. ***************************************** [2023-09-11 20:52:55,311][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 0 [2023-09-11 20:52:55,411][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 2 [2023-09-11 20:52:55,545][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 7 [2023-09-11 20:52:55,548][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 6 [2023-09-11 20:52:55,553][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 5 [2023-09-11 20:52:55,555][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 4 [2023-09-11 20:52:55,590][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 1 [2023-09-11 20:52:55,593][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 3 [2023-09-11 20:52:55,593][torch.distributed.distributed_c10d][INFO] - Rank 3: Completed store-based barrier for key:store_based_barrier_key:1 with 8 nodes. [2023-09-11 20:52:55,594][torch.distributed.distributed_c10d][INFO] - Rank 2: Completed store-based barrier for key:store_based_barrier_key:1 with 8 nodes. [2023-09-11 20:52:55,594][torch.distributed.distributed_c10d][INFO] - Rank 5: Completed store-based barrier for key:store_based_barrier_key:1 with 8 nodes. [2023-09-11 20:52:55,595][torch.distributed.distributed_c10d][INFO] - Rank 0: Completed store-based barrier for key:store_based_barrier_key:1 with 8 nodes. [2023-09-11 20:52:55,596][torch.distributed.distributed_c10d][INFO] - Rank 4: Completed store-based barrier for key:store_based_barrier_key:1 with 8 nodes. [2023-09-11 20:52:55,596][torch.distributed.distributed_c10d][INFO] - Rank 7: Completed store-based barrier for key:store_based_barrier_key:1 with 8 nodes. [2023-09-11 20:52:55,599][torch.distributed.distributed_c10d][INFO] - Rank 6: Completed store-based barrier for key:store_based_barrier_key:1 with 8 nodes. [2023-09-11 20:52:55,601][torch.distributed.distributed_c10d][INFO] - Rank 1: Completed store-based barrier for key:store_based_barrier_key:1 with 8 nodes. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. number of parameters: 27.32M number of parameters: 27.32M number of parameters: 27.32M number of parameters: 27.32M number of parameters: 27.32M number of parameters: 27.32M number of parameters: 27.32M number of parameters: 27.32M Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch [GPU5] Epoch 1 | Iter 0 | Train Loss 4.15149 [GPU4] Epoch 1 | Iter 0 | Train Loss 4.14975 [GPU6] Epoch 1 | Iter 0 | Train Loss 4.15208 [GPU7] Epoch 1 | Iter 0 | Train Loss 4.15188 [GPU3] Epoch 1 | Iter 0 | Train Loss 4.14933 [GPU2] Epoch 1 | Iter 0 | Train Loss 4.15260 [GPU0] Epoch 1 | Iter 0 | Train Loss 4.15156 [GPU1] Epoch 1 | Iter 0 | Train Loss 4.14797 [2023-09-11 20:53:06,174][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-11 20:53:06,177][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-11 20:53:06,177][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-11 20:53:06,177][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-11 20:53:06,184][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-11 20:53:06,184][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-11 20:53:06,184][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-11 20:53:06,184][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [GPU0] Epoch 1 | Iter 0 | Eval Loss 2.41668 [GPU5] Epoch 1 | Iter 0 | Eval Loss 2.41234 [GPU6] Epoch 1 | Iter 0 | Eval Loss 2.42844 [GPU7] Epoch 1 | Iter 0 | Eval Loss 2.42169 [GPU4] Epoch 1 | Iter 0 | Eval Loss 2.41316 [GPU2] Epoch 1 | Iter 0 | Eval Loss 2.40139 [GPU1] Epoch 1 | Iter 0 | Eval Loss 2.41490 [GPU3] Epoch 1 | Iter 0 | Eval Loss 2.42488 ... [GPU5] Epoch 10 | Iter 0 | Train Loss 1.99076 [GPU4] Epoch 10 | Iter 0 | Train Loss 1.99094 [GPU7] Epoch 10 | Iter 0 | Train Loss 2.00854 [GPU6] Epoch 10 | Iter 0 | Train Loss 2.01149 [GPU1] Epoch 10 | Iter 0 | Train Loss 2.01096 [GPU2] Epoch 10 | Iter 0 | Train Loss 2.01783 [GPU0] Epoch 10 | Iter 0 | Train Loss 1.99053 [GPU3] Epoch 10 | Iter 0 | Train Loss 1.97779 [GPU5] Epoch 10 | Iter 0 | Eval Loss 1.96394 [GPU6] Epoch 10 | Iter 0 | Eval Loss 1.95636 [GPU7] Epoch 10 | Iter 0 | Eval Loss 1.99337 [GPU4] Epoch 10 | Iter 0 | Eval Loss 1.96288 [GPU3] Epoch 10 | Iter 0 | Eval Loss 1.97101 [GPU0] Epoch 10 | Iter 0 | Eval Loss 1.94594 [GPU1] Epoch 10 | Iter 0 | Eval Loss 1.98116 [GPU2] Epoch 10 | Iter 0 | Eval Loss 1.94512 ``` ## singularity ``` singularity pull pytorch-multinode.sif docker://harbor.aip.io/base/pytorch-multinode:v1 singularity run --nv \ --pwd /workspace/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif ``` ### 单机多卡 ``` singularity run --nv \ --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif \ torchrun --standalone --nproc_per_node=4 main.py ``` ### 多级多卡 ``` singularity run --nv \ --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 singularity run --nv \ --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif \ torchrun --nproc_per_node=4 \ --nnodes=2 \ --node_rank=0 \ --master_addr=10.xx.2.xxx \ --master_port=29500 \ main.py singularity run --nv \ --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif \ torchrun --nproc_per_node=4 \ --nnodes=2 \ --node_rank=1 \ --master_addr=10.xx.2.xxx \ --master_port=29500 \ main.py ``` ### slurm ``` slurm/sbatch_run_sig.sh ``` ================================================ FILE: llm-train/pytorch/distribution/data-parallel/minGPT-ddp/multinode.sh ================================================ #!/bin/bash #SBATCH --job-name=multinode-example #SBATCH --partition=a800 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.err #日志 #SBATCH -N 2 #SBATCH --ntasks=2 #SBATCH --gres=gpu:4 ##SBATCH --cpus-per-task=4 NODELIST=$(scontrol show hostname $SLURM_JOB_NODELIST) # 对第一个节点赋值为主节点 MASTER_NODE=$(head -n 1 <<< "$NODELIST") # 计数器 NODE_COUNT=0 # 一共的节点数 NODE_NUM=($(echo $NODELIST | tr " " "\n" | wc -l)) # 打印 echo $SLURM_NODEID echo $NODELIST echo $MASTER_NODE echo $NODE_NUM export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 srun --mpi=pmix_v3 singularity run --nv --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt -B /data/hpc/home/guodong.li/:/workspaces:rw pytorch-multinode.sif torchrun --nproc_per_node=4 main.py ================================================ FILE: llm-train/pytorch/distribution/data-parallel/minGPT-ddp/sbatch_run.sh ================================================ #!/bin/bash #SBATCH --job-name=multinode-example #SBATCH --partition=a800 #分区 #SBATCH --nodes=2 #SBATCH --ntasks=4 #SBATCH --gpus-per-task=4 #SBATCH --cpus-per-task=4 NODELIST=$(scontrol show hostname $SLURM_JOB_NODELIST) # 对第一个节点赋值为主节点 MASTER_NODE=$(head -n 1 <<< "$NODELIST") # 计数器 NODE_COUNT=0 # 一共的节点数 NODE_NUM=($(echo $NODELIST | tr " " "\n" | wc -l)) # 打印 echo $SLURM_NODEID echo $NODELIST echo $MASTER_NODE echo $NODE_NUM module load anaconda/3-2023.03 source activate conda activate liguodong-310-multinode module load cuda-cudnn8.9/11.7.1 export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 for NODE in $NODELIST; do if [ "$NODE" == "$MASTER_NODE" ]; then srun --nodes=1 --ntasks=1 -w $NODE torchrun --nproc_per_node=4 --nnodes=$NODE_NUM --node_rank=0 --master_addr=xx.99.2.xx --master_port=29500 main.py & else ((NODE_COUNT++)) srun --nodes=1 --ntasks=1 -w $NODE torchrun --nproc_per_node=4 --nnodes=$NODE_NUM --node_rank=$NODE_COUNT --master_addr=xx.99.2.xx --master_port=29500 main.py & fi done wait ================================================ FILE: llm-train/pytorch/distribution/data-parallel/minGPT-ddp/sbatch_run_sig.sh ================================================ #!/bin/bash #SBATCH --job-name=multinode-example #SBATCH --partition=a800 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.err #日志 #SBATCH --nodes=2 #SBATCH --ntasks=4 #SBATCH --gpus-per-task=4 #SBATCH --cpus-per-task=4 NODELIST=$(scontrol show hostname $SLURM_JOB_NODELIST) # 对第一个节点赋值为主节点 MASTER_NODE=$(head -n 1 <<< "$NODELIST") # 计数器 NODE_COUNT=0 # 一共的节点数 NODE_NUM=($(echo $NODELIST | tr " " "\n" | wc -l)) # 打印 echo $SLURM_NODEID echo $NODELIST echo $MASTER_NODE echo $NODE_NUM export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 for NODE in $NODELIST; do if [ "$NODE" == "$MASTER_NODE" ]; then srun --nodes=1 --ntasks=1 -w $NODE \ singularity run --nv \ --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif \ torchrun --nproc_per_node=4 \ --nnodes=$NODE_NUM \ --node_rank=0 \ --master_addr=10.xx.2.xx \ --master_port=29500 \ main.py & else ((NODE_COUNT++)) srun --nodes=1 --ntasks=1 -w $NODE \ singularity run --nv \ --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif \ torchrun --nproc_per_node=4 \ --nnodes=$NODE_NUM \ --node_rank=$NODE_COUNT \ --master_addr=10.xx.2.xx \ --master_port=29500 \ main.py & fi done wait ================================================ FILE: llm-train/pytorch/distribution/data-parallel/minGPT-ddp/sbatch_run_sig_opt.sh ================================================ #!/bin/bash #SBATCH --job-name=multinode-example #SBATCH --partition=a800 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.err #日志 #SBATCH --nodes=2 #SBATCH --ntasks=4 #SBATCH --gpus-per-task=4 #SBATCH --cpus-per-task=4 NODELIST=$(scontrol show hostname $SLURM_JOB_NODELIST) # 对第一个节点赋值为主节点 MASTER_NODE=$(head -n 1 <<< "$NODELIST") # 计数器 NODE_COUNT=0 # 一共的节点数 NODE_NUM=($(echo $NODELIST | tr " " "\n" | wc -l)) # 打印 echo $SLURM_NODEID echo $NODELIST echo $MASTER_NODE echo $NODE_NUM export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 for NODE in $NODELIST; do if [ "$NODE" == "$MASTER_NODE" ]; then srun --nodes=1 --ntasks=1 -w $NODE \ singularity run --nv \ --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif \ torchrun --nproc_per_node=4 \ --nnodes=$NODE_NUM \ --node_rank=0 \ --master_addr=$MASTER_NODE \ --master_port=29500 \ main.py & else ((NODE_COUNT++)) srun --nodes=1 --ntasks=1 -w $NODE \ singularity run --nv \ --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif \ torchrun --nproc_per_node=4 \ --nnodes=$NODE_NUM \ --node_rank=$NODE_COUNT \ --master_addr=$MASTER_NODE \ --master_port=29500 \ main.py & fi done wait ================================================ FILE: llm-train/pytorch/distribution/data-parallel/sbatch_run.sh ================================================ #!/bin/bash #SBATCH --job-name=multinode-example #SBATCH --nodes=4 #SBATCH --ntasks=4 #SBATCH --gpus-per-task=1 #SBATCH --cpus-per-task=4 nodes=( $( scontrol show hostnames $SLURM_JOB_NODELIST ) ) nodes_array=($nodes) head_node=${nodes_array[0]} head_node_ip=$(srun --nodes=1 --ntasks=1 -w "$head_node" hostname --ip-address) echo Node IP: $head_node_ip export LOGLEVEL=INFO srun torchrun \ --nnodes 4 \ --nproc_per_node 1 \ --rdzv_id $RANDOM \ --rdzv_backend c10d \ --rdzv_endpoint $head_node_ip:29500 \ /shared/examples/multinode_torchrun.py 50 10 ================================================ FILE: llm-train/pytorch/distribution/data-parallel/使用DDP训练真实世界的模型.md ================================================ - https://pytorch.org/tutorials/intermediate/ddp_series_minGPT.html --- ## 单机多卡 ``` torchrun --standalone --nproc_per_node=4 main.py WARNING:torch.distributed.run: ***************************************** Setting OMP_NUM_THREADS environment variable for each process to be 1 in default, to avoid your system being overloaded, please further tune the variable for optimal performance in your application as needed. ***************************************** [2023-09-08 17:48:02,237][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 1 [2023-09-08 17:48:02,246][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 0 [2023-09-08 17:48:02,253][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 2 [2023-09-08 17:48:02,256][torch.distributed.distributed_c10d][INFO] - Added key: store_based_barrier_key:1 to store for rank: 3 [2023-09-08 17:48:02,257][torch.distributed.distributed_c10d][INFO] - Rank 3: Completed store-based barrier for key:store_based_barrier_key:1 with 4 nodes. [2023-09-08 17:48:02,257][torch.distributed.distributed_c10d][INFO] - Rank 0: Completed store-based barrier for key:store_based_barrier_key:1 with 4 nodes. [2023-09-08 17:48:02,258][torch.distributed.distributed_c10d][INFO] - Rank 1: Completed store-based barrier for key:store_based_barrier_key:1 with 4 nodes. [2023-09-08 17:48:02,264][torch.distributed.distributed_c10d][INFO] - Rank 2: Completed store-based barrier for key:store_based_barrier_key:1 with 4 nodes. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. Data has 55769 characters, 59 unique. number of parameters: 27.32M number of parameters: 27.32M number of parameters: 27.32M number of parameters: 27.32M Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch Snapshot not found. Training model from scratch [GPU3] Epoch 1 | Iter 0 | Train Loss 4.18844 [GPU0] Epoch 1 | Iter 0 | Train Loss 4.18055 [2023-09-08 17:48:06,586][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [GPU2] Epoch 1 | Iter 0 | Train Loss 4.18575 [GPU1] Epoch 1 | Iter 0 | Train Loss 4.18100 [2023-09-08 17:48:06,590][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-08 17:48:06,590][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [2023-09-08 17:48:06,590][torch.nn.parallel.distributed][INFO] - Reducer buckets have been rebuilt in this iteration. [GPU0] Epoch 1 | Iter 0 | Eval Loss 2.35044 [GPU2] Epoch 1 | Iter 0 | Eval Loss 2.33801 ... [GPU1] Epoch 3 | Iter 0 | Train Loss 2.21209 [GPU2] Epoch 3 | Iter 0 | Train Loss 2.21229 Snapshot saved at epoch 3 [GPU2] Epoch 3 | Iter 0 | Eval Loss 2.12978 [GPU1] Epoch 3 | Iter 0 | Eval Loss 2.12159 ... [GPU2] Epoch 6 | Iter 0 | Train Loss 1.96697 [GPU1] Epoch 6 | Iter 0 | Train Loss 1.97281 Snapshot saved at epoch 6 [GPU2] Epoch 6 | Iter 0 | Eval Loss 1.84860 [GPU3] Epoch 6 | Iter 0 | Eval Loss 1.85607 [GPU1] Epoch 6 | Iter 0 | Eval Loss 1.86408 [GPU0] Epoch 6 | Iter 0 | Eval Loss 1.87735 ... [GPU2] Epoch 9 | Iter 0 | Train Loss 1.43359 [GPU0] Epoch 9 | Iter 0 | Train Loss 1.45036 [GPU1] Epoch 9 | Iter 0 | Train Loss 1.44486 [GPU3] Epoch 9 | Iter 0 | Train Loss 1.41639 Snapshot saved at epoch 9 [GPU2] Epoch 9 | Iter 0 | Eval Loss 1.28527 [GPU3] Epoch 9 | Iter 0 | Eval Loss 1.29209 ... [GPU3] Epoch 10 | Iter 0 | Eval Loss 1.13304 [GPU1] Epoch 10 | Iter 0 | Eval Loss 1.13287 ``` ## 多机多卡 ``` ``` ================================================ FILE: llm-train/pytorch/distribution/pipeline-parallel/1-流水线.md ================================================ ## torch.distributed.pipeline.sync.Pipe 包装任意的 nn.Sequential 模块以使用同步流水线并行进行训练。 如果模块需要大量内存并且不适合单个 GPU,则流水线并行是一种用于训练的有用技术。该实现基于 torchgpipe 论文。 Pipe 将流水线并行与checkpointing相结合,以减少训练所需的峰值内存;同时,最大限度地减少设备利用率不足的问题。 您应该将所有模块放置在适当的设备上,并将它们包装到定义所需执行顺序的 nn.Sequential 模块中。 如果模块不包含任何参数/buffers,则假定该模块应在 CPU 上执行,并且该模块的适当输入张量在执行之前已移动到 CPU。 此行为可以被 WithDevice 包装器覆盖,该包装器可用于显式指定模块应在哪个设备上运行。 参数说明: module (nn.Sequential) – 使用流水线进行并行的sequential模块。 sequential中的每个模块都必须在单个设备上具有其所有参数。 序列中的每个模块必须是 nn.Module 或 nn.Sequential(在单个设备上组合多个sequential模块) chunks (int) – 微批次数量(默认值:1) checkpoint (str) – 何时启用检查点,always、except_last或never之一(默认值: except_last)。 never:完全禁用检查点,except_last:启用除最后一个之外的所有微批次的检查点,always:启用所有微批次的检查点。 deferred_batch_norm (bool) – 是否使用延迟 BatchNorm 移动统计(默认值:False)。 如果设置为 True,我们将跟踪多个微批次的统计信息,以更新每个小批次的运行统计信息。 ``` # Need to initialize RPC framework first. os.environ['MASTER_ADDR'] = 'localhost' os.environ['MASTER_PORT'] = '29500' torch.distributed.rpc.init_rpc('worker', rank=0, world_size=1) # Build pipe. fc1 = nn.Linear(16, 8).cuda(0) fc2 = nn.Linear(8, 4).cuda(1) model = nn.Sequential(fc1, fc2) model = Pipe(model, chunks=8) input = torch.rand(16, 16).cuda(0) output_rref = model(input) ``` 注:仅当 Pipe 的检查点参数为“never”时,才可以使用 torch.nn.parallel.DistributedDataParallel 包装 Pipe 模型。 Pipe 目前仅支持节点内(intra-node)流水线,未来将扩展支持节点间(inter-node )流水线。 forward 函数返回一个 RRef 以允许将来进行节点间(inter-node )流水线传输,其中输出可能位于远程主机上。 对于节点内流水线,您可以使用 local_value() 在本地检索输出。 警告: Pipe 是实验性的,可能会发生变化。 ### `forward(*inputs)` ## 跳跃连接(Skip connections) 某些模型(例如:ResNeXt)不是完全顺序的,并且层之间有跳跃连接。 简单的实现作为流水线并行的一部分意味着我们需要通过多个 GPU 复制某些层的输出,直到我们最终到达跳跃连接层所在的 GPU。 为了避免这种复制开销,我们提供了以下 API 来在模型的不同层中存储和弹出张量。 - torch.distributed.pipeline.sync.skip.skippable.skippable(stash=(), pop=()) ```python @skippable(stash=['1to3']) class Layer1(nn.Module): def forward(self, input): yield stash('1to3', input) return f1(input) class Layer2(nn.Module): def forward(self, input): return f2(input) @skippable(pop=['1to3']) class Layer3(nn.Module): def forward(self, input): skip_1to3 = yield pop('1to3') return f3(input) + skip_1to3 model = nn.Sequential(Layer1(), Layer2(), Layer3()) ``` 一个可跳跃的模块可以存储或弹出多个跳跃张量: ```python @skippable(stash=['alice', 'bob'], pop=['carol']) class StashStashPop(nn.Module): def forward(self, input): yield stash('alice', f_alice(input)) yield stash('bob', f_bob(input)) carol = yield pop('carol') return input + carol ``` 每个跳跃张量必须与一对 stash 和 pop 相关联。 Pipe 在包装模块时会自动检查此限制。 您还可以在不使用 Pipe 的情况下通过 verify_skippables() 检查限制。 - torch.distributed.pipeline.sync.skip.skippable.stash(name, tensor) - torch.distributed.pipeline.sync.skip.skippable.pop(name) - torch.distributed.pipeline.sync.skip.skippable.verify_skippables(module) ================================================ FILE: llm-train/pytorch/distribution/pipeline-parallel/2-使用torchtext训练transformer模型.md ================================================ ## 定义模型 ``` import math import os from tempfile import TemporaryDirectory from typing import Tuple import torch from torch import nn, Tensor from torch.nn import TransformerEncoder, TransformerEncoderLayer from torch.utils.data import dataset class TransformerModel(nn.Module): def __init__(self, ntoken: int, d_model: int, nhead: int, d_hid: int, nlayers: int, dropout: float = 0.5): super().__init__() self.model_type = 'Transformer' # 位置编码 self.pos_encoder = PositionalEncoding(d_model, dropout) # 单个EncoderLayer encoder_layers = TransformerEncoderLayer(d_model, nhead, d_hid, dropout) # TransformerEncoder 包含多个 EncoderLayer self.transformer_encoder = TransformerEncoder(encoder_layers, nlayers) # 嵌入层 self.embedding = nn.Embedding(ntoken, d_model) self.d_model = d_model self.linear = nn.Linear(d_model, ntoken) # 初始化权重 self.init_weights() def init_weights(self) -> None: initrange = 0.1 self.embedding.weight.data.uniform_(-initrange, initrange) self.linear.bias.data.zero_() self.linear.weight.data.uniform_(-initrange, initrange) def forward(self, src: Tensor, src_mask: Tensor = None) -> Tensor: """ Arguments: src: Tensor, shape ``[seq_len, batch_size]`` src_mask: Tensor, shape ``[seq_len, seq_len]`` Returns: output Tensor of shape ``[seq_len, batch_size, ntoken]`` """ src = self.embedding(src) * math.sqrt(self.d_model) src = self.pos_encoder(src) output = self.transformer_encoder(src, src_mask) output = self.linear(output) return output ``` ```python class PositionalEncoding(nn.Module): def __init__(self, d_model: int, dropout: float = 0.1, max_len: int = 5000): super().__init__() self.dropout = nn.Dropout(p=dropout) position = torch.arange(max_len).unsqueeze(1) div_term = torch.exp(torch.arange(0, d_model, 2) * (-math.log(10000.0) / d_model)) pe = torch.zeros(max_len, 1, d_model) pe[:, 0, 0::2] = torch.sin(position * div_term) pe[:, 0, 1::2] = torch.cos(position * div_term) self.register_buffer('pe', pe) def forward(self, x: Tensor) -> Tensor: """ Arguments: x: Tensor, shape ``[seq_len, batch_size, embedding_dim]`` """ x = x + self.pe[:x.size(0)] return self.dropout(x) ``` ## 构造数据 ``` import torch from torch import nn, Tensor from torch.utils.data import dataset from torchtext.datasets import WikiText2 from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator train_iter = WikiText2(split='train') tokenizer = get_tokenizer('basic_english') # 构建词表 vocab = build_vocab_from_iterator(map(tokenizer, train_iter), specials=['']) # 设置默认索引值,当单词OOV时,使用默认索引 vocab.set_default_index(vocab['']) # 0 print(vocab['']) print(vocab.get_default_index()) item = "You can now install TorchText using pip!" # [178, 112, 199, 19230, 0, 438, 0, 385] print(vocab(tokenizer(item))) def data_process(raw_text_iter: dataset.IterableDataset) -> Tensor: """Converts raw text into a flat Tensor.""" data = [torch.tensor(vocab(tokenizer(item)), dtype=torch.long) for item in raw_text_iter] return torch.cat(tuple(filter(lambda t: t.numel() > 0, data))) # ``train_iter`` was "consumed" by the process of building the vocab, # so we have to create it again train_iter, val_iter, test_iter = WikiText2() train_data = data_process(train_iter) val_data = data_process(val_iter) test_data = data_process(test_iter) print(train_data.shape, val_data.shape, test_data.shape) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') def batchify(data: Tensor, bsz: int) -> Tensor: """Divides the data into ``bsz`` separate sequences, removing extra elements that wouldn't cleanly fit. Arguments: data: Tensor, shape ``[N]`` bsz: int, batch size Returns: Tensor of shape ``[N // bsz, bsz]`` """ seq_len = data.size(0) // bsz # 移除无法整除的余数 data = data[:seq_len * bsz] # torch.Size([2049980]) print(data.shape) # t() 转置 # contiguous()方法首先拷贝了一份张量在内存中的地址,然后将地址按照形状改变后的张量的语义进行排列。 data = data.view(bsz, seq_len).t().contiguous() # torch.Size([102499, 20]) print(data.shape) return data.to(device) batch_size = 20 eval_batch_size = 10 # torch.Size([102499, 20]) train_data = batchify(train_data, batch_size) # shape ``[seq_len, batch_size]`` val_data = batchify(val_data, eval_batch_size) test_data = batchify(test_data, eval_batch_size) ``` ### 生成输入-目标序列 ================================================ FILE: llm-train/pytorch/distribution/pipeline-parallel/3-使用流水线并行训练Transformer模型.md ================================================ ## 定义模型 在本教程中,我们将在两个 GPU 上拆分 Transformer 模型,并使用流水线并行来训练模型。 该模型与使用 nn.Transformer 和 TorchText 进行序列到序列建模教程中使用的模型完全相同,但分为两个阶段。 参数数量最多的是 nn.TransformerEncoder 层。 nn.TransformerEncoder 本身由 nlayers 个 nn.TransformerEncoderLayer 组成。 因此,我们的重点是 nn.TransformerEncoder,并拆分模型,使 nn.TransformerEncoderLayer 的一半位于一个 GPU 上,另一半位于另一个 GPU 上。 为此,我们将编码器和解码器部分提取到单独的模块中,然后构建一个代表原始 Transformer 模块的 nn.Sequential。 ## 模型流水线并行初始化 为了演示使用流水线并行训练大型 Transformer 模型,我们适当扩展了 Transformer 层。 我们使用 4096 的嵌入维度、4096 的隐藏大小、16 个注意力头和 12 个 Transformer 层 (nn.TransformerEncoderLayer)。 这将创建一个具有约 14 亿个参数的模型。 我们需要初始化 RPC 框架,因为 Pipe 通过 RRef 依赖于 RPC 框架,这允许将来扩展到跨主机流水线。 由于我们使用单个进程来驱动多个 GPU,因此我们只需要使用单个工作线程来初始化 RPC 框架。 然后使用一个 GPU 上的 8 个Transformer 层和另一个 GPU 上的 8 个Transformer 层来初始化流水线。 注意: 出于效率目的,我们确保传递给 Pipe 的 nn.Sequential 仅包含两个元素(对应于两个 GPU),这允许 Pipe 仅处理两个分区并避免任何跨分区开销。 ================================================ FILE: llm-train/pytorch/distribution/pipeline-parallel/4-使用DDP与流水线并行训练Transformer模型.md ================================================ ## 定义模型 PositionalEncoding 模块注入一些有关序列中标记的相对或绝对位置的信息。 位置编码与嵌入具有相同的维度,因此可以将两者相加。 在这里,我们使用不同频率的正弦和余弦函数。 在本教程中,我们将在两个 GPU 上拆分 Transformer 模型,并使用流水线并行来训练模型。 除此之外,我们还使用分布式数据并行来训练该流水线的两个副本。 我们有一个进程驱动跨 GPU 0 和 1 的流水线,另一个进程驱动跨 GPU 2 和 3 的流水线。 然后,这两个进程都使用分布式数据并行来训练两个副本。 该模型与使用 nn.Transformer 和 TorchText 进行序列到序列建模教程中使用的模型完全相同,但分为两个阶段。 参数数量最多的是 nn.TransformerEncoder 层。 nn.TransformerEncoder 本身由 nlayers 个 nn.TransformerEncoderLayer 组成。 因此,我们的重点是 nn.TransformerEncoder,并拆分模型,使 nn.TransformerEncoderLayer 的一半位于一个 GPU 上,另一半位于另一个 GPU 上。 为此,我们将编码器和解码器部分提取到单独的模块中,然后构建一个代表原始 Transformer 模块的 nn.Sequential。 ================================================ FILE: llm-train/pytorch/distribution/pipeline-parallel/README.md ================================================ - Pipeline Parallelism:https://pytorch.org/docs/stable/pipeline.html 基本API - Sequence-to-Sequence Modeling with nn.Transformer and TorchText:https://pytorch.org/tutorials/intermediate/pipeline_tutorial.html - TRAINING TRANSFORMER MODELS USING PIPELINE PARALLELISM:https://pytorch.org/tutorials/beginner/transformer_tutorial.html - TRAINING TRANSFORMER MODELS USING DISTRIBUTED DATA PARALLEL AND PIPELINE PARALLELISM :https://pytorch.org/tutorials/advanced/ddp_pipeline.html --- - SINGLE-MACHINE MODEL PARALLEL BEST PRACTICES:https://pytorch.org/tutorials/intermediate/model_parallel_tutorial.html ## 使用DDP与PP训练Transformer模型 ``` python ddp_pipeline.py --------- --------- partition_len: 4 rank: 0 partition_len: 4 rank: 1 [RANK 1]: Total parameters in model: 1,061,924,974 [RANK 0]: Total parameters in model: 1,061,924,974 [W logger.cpp:317] Warning: Cuda time stats are not collected for multi-device modules. (function operator()) [W logger.cpp:317] Warning: Cuda time stats are not collected for multi-device modules. (function operator()) [RANK 1]: | epoch 1 | 10/ 50 batches | lr 5.00 | ms/batch 517.85 | loss 45.48 | ppl 56432121366884458496.00 [RANK 0]: | epoch 1 | 10/ 50 batches | lr 5.00 | ms/batch 517.64 | loss 44.56 | ppl 22504870874679681024.00 [RANK 1]: | epoch 1 | 20/ 50 batches | lr 5.00 | ms/batch 385.36 | loss 46.63 | ppl 178457758192923508736.00 [RANK 0]: | epoch 1 | 20/ 50 batches | lr 5.00 | ms/batch 385.36 | loss 45.77 | ppl 75770339191959027712.00 [RANK 0]: | epoch 1 | 30/ 50 batches | lr 5.00 | ms/batch 385.49 | loss 41.88 | ppl 1546590899039937792.00 [RANK 1]: | epoch 1 | 30/ 50 batches | lr 5.00 | ms/batch 385.49 | loss 42.50 | ppl 2856464247237597696.00 [RANK 1]: | epoch 1 | 40/ 50 batches | lr 5.00 | ms/batch 386.09 | loss 38.95 | ppl 82371305929986336.00 [RANK 0]: | epoch 1 | 40/ 50 batches | lr 5.00 | ms/batch 386.09 | loss 39.99 | ppl 233730045251711744.00 [RANK 0]: ----------------------------------------------------------------------------------------- [RANK 0]: | end of epoch 1 | time: 22.57s | valid loss 0.91 | valid ppl 2.48 [RANK 0]: ----------------------------------------------------------------------------------------- [RANK 1]: ----------------------------------------------------------------------------------------- [RANK 1]: | end of epoch 1 | time: 22.59s | valid loss 0.91 | valid ppl 2.48 [RANK 1]: ----------------------------------------------------------------------------------------- [RANK 1]: | epoch 2 | 10/ 50 batches | lr 4.75 | ms/batch 425.29 | loss 39.88 | ppl 209605830679931392.00 [RANK 0]: | epoch 2 | 10/ 50 batches | lr 4.75 | ms/batch 427.78 | loss 39.88 | ppl 208211260703358496.00 [RANK 0]: | epoch 2 | 20/ 50 batches | lr 4.75 | ms/batch 386.57 | loss 28.43 | ppl 2212304159830.81 [RANK 1]: | epoch 2 | 20/ 50 batches | lr 4.75 | ms/batch 386.57 | loss 28.97 | ppl 3807579905494.86 [RANK 0]: | epoch 2 | 30/ 50 batches | lr 4.75 | ms/batch 387.16 | loss 26.35 | ppl 278391001398.60 [RANK 1]: | epoch 2 | 30/ 50 batches | lr 4.75 | ms/batch 387.17 | loss 25.44 | ppl 111852774843.71 [RANK 1]: | epoch 2 | 40/ 50 batches | lr 4.75 | ms/batch 387.81 | loss 19.52 | ppl 298987362.70 [RANK 0]: | epoch 2 | 40/ 50 batches | lr 4.75 | ms/batch 387.82 | loss 19.41 | ppl 269058605.29 [RANK 0]: ----------------------------------------------------------------------------------------- [RANK 0]: | end of epoch 2 | time: 21.62s | valid loss 0.23 | valid ppl 1.26 [RANK 0]: ----------------------------------------------------------------------------------------- [RANK 1]: ----------------------------------------------------------------------------------------- [RANK 1]: | end of epoch 2 | time: 21.67s | valid loss 0.23 | valid ppl 1.26 [RANK 1]: ----------------------------------------------------------------------------------------- [RANK 0]: | epoch 3 | 10/ 50 batches | lr 4.51 | ms/batch 433.81 | loss 11.59 | ppl 108360.86 [RANK 1]: | epoch 3 | 10/ 50 batches | lr 4.51 | ms/batch 426.98 | loss 11.59 | ppl 107512.77 [RANK 0]: | epoch 3 | 20/ 50 batches | lr 4.51 | ms/batch 386.89 | loss 10.04 | ppl 22813.06 [RANK 1]: | epoch 3 | 20/ 50 batches | lr 4.51 | ms/batch 386.89 | loss 9.99 | ppl 21883.85 [RANK 0]: | epoch 3 | 30/ 50 batches | lr 4.51 | ms/batch 387.63 | loss 10.69 | ppl 43941.38 [RANK 1]: | epoch 3 | 30/ 50 batches | lr 4.51 | ms/batch 387.63 | loss 10.55 | ppl 38258.17 [RANK 1]: | epoch 3 | 40/ 50 batches | lr 4.51 | ms/batch 387.79 | loss 9.80 | ppl 18089.39 [RANK 0]: | epoch 3 | 40/ 50 batches | lr 4.51 | ms/batch 387.79 | loss 9.80 | ppl 18088.98 [RANK 0]: ----------------------------------------------------------------------------------------- [RANK 0]: | end of epoch 3 | time: 21.76s | valid loss 0.31 | valid ppl 1.37 [RANK 0]: ----------------------------------------------------------------------------------------- [RANK 1]: ----------------------------------------------------------------------------------------- [RANK 1]: | end of epoch 3 | time: 21.83s | valid loss 0.31 | valid ppl 1.37 [RANK 1]: ----------------------------------------------------------------------------------------- [RANK 0]: ========================================================================================= [RANK 0]: | End of training | test loss 0.27 | test ppl 1.31 [RANK 0]: ========================================================================================= [RANK 1]: ========================================================================================= [RANK 1]: | End of training | test loss 0.27 | test ppl 1.31 [RANK 1]: ========================================================================================= ``` 显存占用: ``` +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 29461 C ...nv-py310-cu117/bin/python 11612MiB | | 0 N/A N/A 29462 C ...nv-py310-cu117/bin/python 556MiB | | 1 N/A N/A 29461 C ...nv-py310-cu117/bin/python 11748MiB | | 2 N/A N/A 29462 C ...nv-py310-cu117/bin/python 11354MiB | | 3 N/A N/A 29462 C ...nv-py310-cu117/bin/python 11748MiB | +-----------------------------------------------------------------------------+ ``` ================================================ FILE: llm-train/pytorch/distribution/pipeline-parallel/ddp_pipeline.py ================================================ """ Training Transformer models using Distributed Data Parallel and Pipeline Parallelism ==================================================================================== **Author**: `Pritam Damania `_ This tutorial demonstrates how to train a large Transformer model across multiple GPUs using `Distributed Data Parallel `__ and `Pipeline Parallelism `__. This tutorial is an extension of the `Sequence-to-Sequence Modeling with nn.Transformer and TorchText `__ tutorial and scales up the same model to demonstrate how Distributed Data Parallel and Pipeline Parallelism can be used to train Transformer models. Prerequisites: * `Pipeline Parallelism `__ * `Sequence-to-Sequence Modeling with nn.Transformer and TorchText `__ * `Getting Started with Distributed Data Parallel `__ """ ###################################################################### # Define the model # ---------------- # ###################################################################### # ``PositionalEncoding`` module injects some information about the # relative or absolute position of the tokens in the sequence. The # positional encodings have the same dimension as the embeddings so that # the two can be summed. Here, we use ``sine`` and ``cosine`` functions of # different frequencies. import sys import os import math import torch import torch.nn as nn import torch.nn.functional as F import tempfile from torch.nn import TransformerEncoder, TransformerEncoderLayer class PositionalEncoding(nn.Module): def __init__(self, d_model, dropout=0.1, max_len=5000): super(PositionalEncoding, self).__init__() self.dropout = nn.Dropout(p=dropout) pe = torch.zeros(max_len, d_model) position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model)) pe[:, 0::2] = torch.sin(position * div_term) pe[:, 1::2] = torch.cos(position * div_term) pe = pe.unsqueeze(0).transpose(0, 1) self.pe = nn.Parameter(pe, requires_grad=False) def forward(self, x): x = x + self.pe[:x.size(0), :] return self.dropout(x) ###################################################################### # In this tutorial, we will split a Transformer model across two GPUs and use # pipeline parallelism to train the model. In addition to this, we use # `Distributed Data Parallel `__ # to train two replicas of this pipeline. We have one process driving a pipe across # GPUs 0 and 1 and another process driving a pipe across GPUs 2 and 3. Both these # processes then use Distributed Data Parallel to train the two replicas. The # model is exactly the same model used in the `Sequence-to-Sequence Modeling with nn.Transformer and TorchText # `__ tutorial, # but is split into two stages. The largest number of parameters belong to the # `nn.TransformerEncoder `__ layer. # The `nn.TransformerEncoder `__ # itself consists of ``nlayers`` of `nn.TransformerEncoderLayer `__. # As a result, our focus is on ``nn.TransformerEncoder`` and we split the model # such that half of the ``nn.TransformerEncoderLayer`` are on one GPU and the # other half are on another. To do this, we pull out the ``Encoder`` and # ``Decoder`` sections into separate modules and then build an ``nn.Sequential`` # representing the original Transformer module. if sys.platform == 'win32': print('Windows platform is not supported for pipeline parallelism') sys.exit(0) if torch.cuda.device_count() < 4: print('Need at least four GPU devices for this tutorial') sys.exit(0) class Encoder(nn.Module): def __init__(self, ntoken, ninp, dropout=0.5): super(Encoder, self).__init__() self.pos_encoder = PositionalEncoding(ninp, dropout) self.encoder = nn.Embedding(ntoken, ninp) self.ninp = ninp self.init_weights() def init_weights(self): initrange = 0.1 self.encoder.weight.data.uniform_(-initrange, initrange) def forward(self, src): # Need (S, N) format for encoder. src = src.t() src = self.encoder(src) * math.sqrt(self.ninp) return self.pos_encoder(src) class Decoder(nn.Module): def __init__(self, ntoken, ninp): super(Decoder, self).__init__() self.decoder = nn.Linear(ninp, ntoken) self.init_weights() def init_weights(self): initrange = 0.1 self.decoder.bias.data.zero_() self.decoder.weight.data.uniform_(-initrange, initrange) def forward(self, inp): # Need batch dimension first for output of pipeline. return self.decoder(inp).permute(1, 0, 2) ###################################################################### # Start multiple processes for training # ------------------------------------- # ###################################################################### # We start two processes where each process drives its own pipeline across two # GPUs. ``run_worker`` is executed for each process. def run_worker(rank, world_size): ###################################################################### # Load and batch data # ------------------- # ###################################################################### # The training process uses Wikitext-2 dataset from ``torchtext``. # To access torchtext datasets, please install torchdata following instructions at https://github.com/pytorch/data. # # The vocab object is built based on the train dataset and is used to numericalize # tokens into tensors. Starting from sequential data, the ``batchify()`` # function arranges the dataset into columns, trimming off any tokens remaining # after the data has been divided into batches of size ``batch_size``. # For instance, with the alphabet as the sequence (total length of 26) # and a batch size of 4, we would divide the alphabet into 4 sequences of # length 6: # # .. math:: # # \begin{bmatrix} # \text{A} & \text{B} & \text{C} & \ldots & \text{X} & \text{Y} & \text{Z} # \end{bmatrix} # \Rightarrow # \begin{bmatrix} # \begin{bmatrix}\text{A} \\ \text{B} \\ \text{C} \\ \text{D} \\ \text{E} \\ \text{F}\end{bmatrix} & # \begin{bmatrix}\text{G} \\ \text{H} \\ \text{I} \\ \text{J} \\ \text{K} \\ \text{L}\end{bmatrix} & # \begin{bmatrix}\text{M} \\ \text{N} \\ \text{O} \\ \text{P} \\ \text{Q} \\ \text{R}\end{bmatrix} & # \begin{bmatrix}\text{S} \\ \text{T} \\ \text{U} \\ \text{V} \\ \text{W} \\ \text{X}\end{bmatrix} # \end{bmatrix} # # These columns are treated as independent by the model, which means that # the dependence of ``G`` and ``F`` can not be learned, but allows more # efficient batch processing. # # In 'run_worker' def print_with_rank(msg): print('[RANK {}]: {}'.format(rank, msg)) from torchtext.datasets import WikiText2 from torchtext.data.utils import get_tokenizer from torchtext.vocab import build_vocab_from_iterator train_iter = WikiText2(split='train') tokenizer = get_tokenizer('basic_english') vocab = build_vocab_from_iterator(map(tokenizer, train_iter), specials=[""]) vocab.set_default_index(vocab[""]) def data_process(raw_text_iter): data = [torch.tensor(vocab(tokenizer(item)), dtype=torch.long) for item in raw_text_iter] return torch.cat(tuple(filter(lambda t: t.numel() > 0, data))) train_iter, val_iter, test_iter = WikiText2() train_data = data_process(train_iter) val_data = data_process(val_iter) test_data = data_process(test_iter) device = torch.device(2 * rank) def batchify(data, bsz, rank, world_size, is_train=False): # Divide the dataset into ``bsz`` parts. nbatch = data.size(0) // bsz # Trim off any extra elements that wouldn't cleanly fit (remainders). data = data.narrow(0, 0, nbatch * bsz) # Evenly divide the data across the ``bsz`` batches. data = data.view(bsz, -1).t().contiguous() # Divide the data across the ranks only for training data. if is_train: data_per_rank = data.size(0) // world_size data = data[rank * data_per_rank : (rank + 1) * data_per_rank] return data.to(device) batch_size = 20 eval_batch_size = 10 train_data = batchify(train_data, batch_size, rank, world_size, True) val_data = batchify(val_data, eval_batch_size, rank, world_size) test_data = batchify(test_data, eval_batch_size, rank, world_size) ###################################################################### # Functions to generate input and target sequence # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ###################################################################### # ``get_batch()`` function generates the input and target sequence for # the transformer model. It subdivides the source data into chunks of # length ``bptt``. For the language modeling task, the model needs the # following words as ``Target``. For example, with a ``bptt`` value of 2, # we’d get the following two Variables for ``i`` = 0: # # .. image:: ../_static/img/transformer_input_target.png # # It should be noted that the chunks are along dimension 0, consistent # with the ``S`` dimension in the Transformer model. The batch dimension # ``N`` is along dimension 1. # # In 'run_worker' bptt = 35 def get_batch(source, i): seq_len = min(bptt, len(source) - 1 - i) data = source[i:i+seq_len] target = source[i+1:i+1+seq_len].view(-1) # Need batch dimension first for pipeline parallelism. return data.t(), target ###################################################################### # Model scale and Pipe initialization # ----------------------------------- # ###################################################################### # To demonstrate training large Transformer models using pipeline parallelism, # we scale up the Transformer layers appropriately. We use an embedding # dimension of 4096, hidden size of 4096, 16 attention heads and 8 total # transformer layers (``nn.TransformerEncoderLayer``). This creates a model with # **~1 billion** parameters. # # We need to initialize the `RPC Framework `__ # since Pipe depends on the RPC framework via `RRef `__ # which allows for future expansion to cross host pipelining. We need to # initialize the RPC framework with only a single worker since we're using a # single process to drive multiple GPUs. # # The pipeline is then initialized with 8 transformer layers on one GPU and 8 # transformer layers on the other GPU. One pipe is setup across GPUs 0 and 1 and # another across GPUs 2 and 3. Both pipes are then replicated using ``DistributedDataParallel``. # In 'run_worker' ntokens = len(vocab) # the size of vocabulary emsize = 4096 # embedding dimension nhid = 4096 # the dimension of the feedforward network model in ``nn.TransformerEncoder`` nlayers = 8 # the number of ``nn.TransformerEncoderLayer`` in ``nn.TransformerEncoder`` nhead = 16 # the number of heads in the Multihead Attention models dropout = 0.2 # the dropout value from torch.distributed import rpc tmpfile = tempfile.NamedTemporaryFile() rpc.init_rpc( name="worker", rank=0, world_size=1, rpc_backend_options=rpc.TensorPipeRpcBackendOptions( init_method="file://{}".format(tmpfile.name), # Specifying _transports and _channels is a workaround and we no longer # will have to specify _transports and _channels for PyTorch # versions >= 1.8.1 _transports=["ibv", "uv"], _channels=["cuda_ipc", "cuda_basic"], ) ) # Number of GPUs for model parallelism. num_gpus = 2 partition_len = ((nlayers - 1) // num_gpus) + 1 print("partition_len:", partition_len, "rank:", rank) # Add encoder in the beginning. tmp_list = [Encoder(ntokens, emsize, dropout).cuda(2 * rank)] module_list = [] # Add all the necessary transformer blocks. for i in range(nlayers): transformer_block = TransformerEncoderLayer(emsize, nhead, nhid, dropout) if i != 0 and i % (partition_len) == 0: module_list.append(nn.Sequential(*tmp_list)) tmp_list = [] device = i // (partition_len) tmp_list.append(transformer_block.to(2 * rank + device)) # Add decoder in the end. tmp_list.append(Decoder(ntokens, emsize).cuda(2 * rank + num_gpus - 1)) module_list.append(nn.Sequential(*tmp_list)) # Need to use 'checkpoint=never' since as of PyTorch 1.8, Pipe checkpointing # doesn't work with DDP. from torch.distributed.pipeline.sync import Pipe chunks = 8 model = Pipe(torch.nn.Sequential(*module_list), chunks = chunks, checkpoint="never") # Initialize process group and wrap model in DDP. from torch.nn.parallel import DistributedDataParallel import torch.distributed as dist os.environ['MASTER_ADDR'] = 'localhost' os.environ['MASTER_PORT'] = '29500' dist.init_process_group( backend="nccl", rank=rank, world_size=world_size) model = DistributedDataParallel(model) def get_total_params(module: torch.nn.Module): total_params = 0 for param in module.parameters(): total_params += param.numel() return total_params print_with_rank('Total parameters in model: {:,}'.format(get_total_params(model))) ###################################################################### # Run the model # ------------- # ###################################################################### # `CrossEntropyLoss `__ # is applied to track the loss and # `SGD `__ # implements stochastic gradient descent method as the optimizer. The initial # learning rate is set to 5.0. `StepLR `__ is # applied to adjust the learn rate through epochs. During the # training, we use # `nn.utils.clip_grad_norm\_ `__ # function to scale all the gradient together to prevent exploding. # # In 'run_worker' criterion = nn.CrossEntropyLoss() lr = 5.0 # learning rate optimizer = torch.optim.SGD(model.parameters(), lr=lr) scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma=0.95) import time def train(): model.train() # Turn on the train mode total_loss = 0. start_time = time.time() ntokens = len(vocab) # Train only for 50 batches to keep script execution time low. nbatches = min(50 * bptt, train_data.size(0) - 1) for batch, i in enumerate(range(0, nbatches, bptt)): data, targets = get_batch(train_data, i) optimizer.zero_grad() # Since the Pipe is only within a single host and process the ``RRef`` # returned by forward method is local to this node and can simply # retrieved via ``RRef.local_value()``. output = model(data).local_value() # Need to move targets to the device where the output of the # pipeline resides. loss = criterion(output.view(-1, ntokens), targets.cuda(2 * rank + 1)) loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), 0.5) optimizer.step() total_loss += loss.item() log_interval = 10 if batch % log_interval == 0 and batch > 0: cur_loss = total_loss / log_interval elapsed = time.time() - start_time print_with_rank('| epoch {:3d} | {:5d}/{:5d} batches | ' 'lr {:02.2f} | ms/batch {:5.2f} | ' 'loss {:5.2f} | ppl {:8.2f}'.format( epoch, batch, nbatches // bptt, scheduler.get_last_lr()[0], elapsed * 1000 / log_interval, cur_loss, math.exp(cur_loss))) total_loss = 0 start_time = time.time() def evaluate(eval_model, data_source): eval_model.eval() # Turn on the evaluation mode total_loss = 0. ntokens = len(vocab) # Evaluate only for 50 batches to keep script execution time low. nbatches = min(50 * bptt, data_source.size(0) - 1) with torch.no_grad(): for i in range(0, nbatches, bptt): data, targets = get_batch(data_source, i) output = eval_model(data).local_value() output_flat = output.view(-1, ntokens) # Need to move targets to the device where the output of the # pipeline resides. total_loss += len(data) * criterion(output_flat, targets.cuda(2 * rank + 1)).item() return total_loss / (len(data_source) - 1) ###################################################################### # Loop over epochs. Save the model if the validation loss is the best # we've seen so far. Adjust the learning rate after each epoch. # In 'run_worker' best_val_loss = float("inf") epochs = 3 # The number of epochs best_model = None for epoch in range(1, epochs + 1): epoch_start_time = time.time() train() val_loss = evaluate(model, val_data) print_with_rank('-' * 89) print_with_rank('| end of epoch {:3d} | time: {:5.2f}s | valid loss {:5.2f} | ' 'valid ppl {:8.2f}'.format(epoch, (time.time() - epoch_start_time), val_loss, math.exp(val_loss))) print_with_rank('-' * 89) if val_loss < best_val_loss: best_val_loss = val_loss best_model = model scheduler.step() ###################################################################### # Evaluate the model with the test dataset # ------------------------------------- # # Apply the best model to check the result with the test dataset. # In 'run_worker' test_loss = evaluate(best_model, test_data) print_with_rank('=' * 89) print_with_rank('| End of training | test loss {:5.2f} | test ppl {:8.2f}'.format( test_loss, math.exp(test_loss))) print_with_rank('=' * 89) # Main execution import torch.multiprocessing as mp if __name__=="__main__": world_size = 2 mp.spawn(run_worker, args=(world_size, ), nprocs=world_size, join=True) ###################################################################### # Output # ------ # ###################################################################### #.. code-block:: py # # [RANK 0]: | epoch 1 | 10/ 50 batches | lr 5.00 | ms/batch 778.97 | loss 43.31 | ppl 6432469059895903232.00 # [RANK 1]: | epoch 1 | 10/ 50 batches | lr 5.00 | ms/batch 778.90 | loss 44.50 | ppl 21245447128217366528.00 # [RANK 0]: | epoch 1 | 20/ 50 batches | lr 5.00 | ms/batch 699.89 | loss 44.50 | ppl 21176949187407757312.00 # [RANK 1]: | epoch 1 | 20/ 50 batches | lr 5.00 | ms/batch 699.87 | loss 44.62 | ppl 23975861229620961280.00 # [RANK 0]: | epoch 1 | 30/ 50 batches | lr 5.00 | ms/batch 698.86 | loss 41.62 | ppl 1193312915629888256.00 # [RANK 1]: | epoch 1 | 30/ 50 batches | lr 5.00 | ms/batch 698.87 | loss 40.69 | ppl 471605759847546240.00 # [RANK 0]: | epoch 1 | 40/ 50 batches | lr 5.00 | ms/batch 698.34 | loss 45.20 | ppl 42812308420836458496.00 # [RANK 1]: | epoch 1 | 40/ 50 batches | lr 5.00 | ms/batch 698.33 | loss 45.68 | ppl 68839569686012223488.00 # [RANK 1]: ----------------------------------------------------------------------------------------- # [RANK 1]: | end of epoch 1 | time: 40.08s | valid loss 0.80 | valid ppl 2.22 # [RANK 1]: ----------------------------------------------------------------------------------------- # [RANK 0]: ----------------------------------------------------------------------------------------- # [RANK 0]: | end of epoch 1 | time: 40.09s | valid loss 0.80 | valid ppl 2.22 # [RANK 0]: ----------------------------------------------------------------------------------------- # [RANK 0]: | epoch 2 | 10/ 50 batches | lr 4.75 | ms/batch 768.51 | loss 36.34 | ppl 6063529544668166.00 # [RANK 1]: | epoch 2 | 10/ 50 batches | lr 4.75 | ms/batch 769.23 | loss 37.41 | ppl 17651211266236086.00 # [RANK 0]: | epoch 2 | 20/ 50 batches | lr 4.75 | ms/batch 699.57 | loss 28.97 | ppl 3798441739584.11 # [RANK 1]: | epoch 2 | 20/ 50 batches | lr 4.75 | ms/batch 699.56 | loss 29.28 | ppl 5203636967575.47 # [RANK 0]: | epoch 2 | 30/ 50 batches | lr 4.75 | ms/batch 699.04 | loss 28.43 | ppl 2212498693571.25 # [RANK 1]: | epoch 2 | 30/ 50 batches | lr 4.75 | ms/batch 699.05 | loss 28.33 | ppl 2015144761281.48 # [RANK 0]: | epoch 2 | 40/ 50 batches | lr 4.75 | ms/batch 699.10 | loss 23.30 | ppl 13121380184.92 # [RANK 1]: | epoch 2 | 40/ 50 batches | lr 4.75 | ms/batch 699.09 | loss 23.41 | ppl 14653799192.87 # [RANK 0]: ----------------------------------------------------------------------------------------- # [RANK 0]: | end of epoch 2 | time: 39.97s | valid loss 0.24 | valid ppl 1.27 # [RANK 0]: ----------------------------------------------------------------------------------------- # [RANK 1]: ----------------------------------------------------------------------------------------- # [RANK 1]: | end of epoch 2 | time: 39.98s | valid loss 0.24 | valid ppl 1.27 # [RANK 1]: ----------------------------------------------------------------------------------------- # [RANK 0]: | epoch 3 | 10/ 50 batches | lr 4.51 | ms/batch 769.36 | loss 12.80 | ppl 361681.11 # [RANK 1]: | epoch 3 | 10/ 50 batches | lr 4.51 | ms/batch 768.97 | loss 12.57 | ppl 287876.61 # [RANK 0]: | epoch 3 | 20/ 50 batches | lr 4.51 | ms/batch 698.27 | loss 12.01 | ppl 164364.60 # [RANK 1]: | epoch 3 | 20/ 50 batches | lr 4.51 | ms/batch 698.30 | loss 11.98 | ppl 159095.89 # [RANK 0]: | epoch 3 | 30/ 50 batches | lr 4.51 | ms/batch 697.75 | loss 10.90 | ppl 54261.91 # [RANK 1]: | epoch 3 | 30/ 50 batches | lr 4.51 | ms/batch 697.72 | loss 10.89 | ppl 53372.39 # [RANK 0]: | epoch 3 | 40/ 50 batches | lr 4.51 | ms/batch 699.49 | loss 10.78 | ppl 47948.35 # [RANK 1]: | epoch 3 | 40/ 50 batches | lr 4.51 | ms/batch 699.50 | loss 10.79 | ppl 48664.42 # [RANK 0]: ----------------------------------------------------------------------------------------- # [RANK 0]: | end of epoch 3 | time: 39.96s | valid loss 0.38 | valid ppl 1.46 # [RANK 0]: ----------------------------------------------------------------------------------------- # [RANK 1]: ----------------------------------------------------------------------------------------- # [RANK 1]: | end of epoch 3 | time: 39.96s | valid loss 0.38 | valid ppl 1.46 # [RANK 1]: ----------------------------------------------------------------------------------------- # [RANK 0]: ========================================================================================= # [RANK 0]: | End of training | test loss 0.33 | test ppl 1.39 # [RANK 0]: ========================================================================================= # [RANK 1]: ========================================================================================= # [RANK 1]: | End of training | test loss 0.33 | test ppl 1.39 # [RANK 1]: ========================================================================================= # ================================================ FILE: llm-train/pytorch/distribution/pipeline-parallel/pipeline_tutorial.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "id": "f198a97a-9d4c-41cd-b01d-e8b8d1cdd302", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/guodong.li/virtual-venv/peft-venv-py310-cu117/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } ], "source": [ "import sys\n", "import math\n", "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "import tempfile\n", "from torch.nn import TransformerEncoder, TransformerEncoderLayer\n", "\n", "if sys.platform == 'win32':\n", " print('Windows platform is not supported for pipeline parallelism')\n", " sys.exit(0)\n", "if torch.cuda.device_count() < 2:\n", " print('Need at least two GPU devices for this tutorial')\n", " sys.exit(0)\n", "\n", "class Encoder(nn.Module):\n", " def __init__(self, ntoken, ninp, dropout=0.5):\n", " super(Encoder, self).__init__()\n", " self.pos_encoder = PositionalEncoding(ninp, dropout)\n", " self.encoder = nn.Embedding(ntoken, ninp)\n", " self.ninp = ninp\n", " self.init_weights()\n", "\n", " def init_weights(self):\n", " initrange = 0.1\n", " self.encoder.weight.data.uniform_(-initrange, initrange)\n", "\n", " def forward(self, src):\n", " # Need (S, N) format for encoder.\n", " src = src.t()\n", " src = self.encoder(src) * math.sqrt(self.ninp)\n", " return self.pos_encoder(src)\n", "\n", "class Decoder(nn.Module):\n", " def __init__(self, ntoken, ninp):\n", " super(Decoder, self).__init__()\n", " self.decoder = nn.Linear(ninp, ntoken)\n", " self.init_weights()\n", "\n", " def init_weights(self):\n", " initrange = 0.1\n", " self.decoder.bias.data.zero_()\n", " self.decoder.weight.data.uniform_(-initrange, initrange)\n", "\n", " def forward(self, inp):\n", " # Need batch dimension first for output of pipeline.\n", " return self.decoder(inp).permute(1, 0, 2)\n", "\n" ] }, { "cell_type": "code", "execution_count": 2, "id": "cd222a6c-a6fa-41b0-a9cb-fe07c0b093de", "metadata": {}, "outputs": [], "source": [ "class PositionalEncoding(nn.Module):\n", "\n", " def __init__(self, d_model, dropout=0.1, max_len=5000):\n", " super(PositionalEncoding, self).__init__()\n", " self.dropout = nn.Dropout(p=dropout)\n", "\n", " pe = torch.zeros(max_len, d_model)\n", " position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)\n", " div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))\n", " pe[:, 0::2] = torch.sin(position * div_term)\n", " pe[:, 1::2] = torch.cos(position * div_term)\n", " pe = pe.unsqueeze(0).transpose(0, 1)\n", " self.register_buffer('pe', pe)\n", "\n", " def forward(self, x):\n", " x = x + self.pe[:x.size(0), :]\n", " return self.dropout(x)" ] }, { "cell_type": "code", "execution_count": 3, "id": "45263f86-cc4b-4f4f-9f25-967eefd96e2e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "---------\n" ] } ], "source": [ "import torch\n", "from torchtext.datasets import WikiText2\n", "from torchtext.data.utils import get_tokenizer\n", "from torchtext.vocab import build_vocab_from_iterator\n", "\n", "train_iter = WikiText2(split='train')\n", "tokenizer = get_tokenizer('basic_english')\n", "vocab = build_vocab_from_iterator(map(tokenizer, train_iter), specials=[\"\"])\n", "vocab.set_default_index(vocab[\"\"])\n", "\n", "def data_process(raw_text_iter):\n", " data = [torch.tensor(vocab(tokenizer(item)), dtype=torch.long) for item in raw_text_iter]\n", " return torch.cat(tuple(filter(lambda t: t.numel() > 0, data)))\n", "\n", "train_iter, val_iter, test_iter = WikiText2()\n", "train_data = data_process(train_iter)\n", "val_data = data_process(val_iter)\n", "test_data = data_process(test_iter)\n", "\n", "device = torch.device(\"cuda\")\n", "\n", "def batchify(data, bsz):\n", " # Divide the dataset into ``bsz`` parts.\n", " nbatch = data.size(0) // bsz\n", " # Trim off any extra elements that wouldn't cleanly fit (remainders).\n", " data = data.narrow(0, 0, nbatch * bsz)\n", " # Evenly divide the data across the ``bsz` batches.\n", " data = data.view(bsz, -1).t().contiguous()\n", " return data.to(device)\n", "\n", "batch_size = 20\n", "eval_batch_size = 10\n", "train_data = batchify(train_data, batch_size)\n", "val_data = batchify(val_data, eval_batch_size)\n", "test_data = batchify(test_data, eval_batch_size)" ] }, { "cell_type": "code", "execution_count": 4, "id": "df9a8520-c6a5-49bd-a1df-7bf6ee44a4c8", "metadata": {}, "outputs": [], "source": [ "bptt = 25\n", "def get_batch(source, i):\n", " seq_len = min(bptt, len(source) - 1 - i)\n", " data = source[i:i+seq_len]\n", " target = source[i+1:i+1+seq_len].view(-1)\n", " # Need batch dimension first for pipeline parallelism.\n", " return data.t(), target" ] }, { "cell_type": "code", "execution_count": 5, "id": "cb0fe3ff-f65f-4635-b221-beb17758a6e1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tmpfile: /tmp/tmp37b004v1\n", "Total parameters in model: 1,444,261,998\n", "Pipe(\n", " (partitions): ModuleList(\n", " (0): PipeSequential(\n", " (0): Encoder(\n", " (pos_encoder): PositionalEncoding(\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " )\n", " (encoder): Embedding(28782, 4096)\n", " )\n", " (1): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (2): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (3): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (4): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (5): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (6): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " )\n", " (1): PipeSequential(\n", " (0): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (1): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (2): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (3): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (4): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (5): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=4096, out_features=4096, bias=True)\n", " )\n", " (linear1): Linear(in_features=4096, out_features=4096, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=4096, out_features=4096, bias=True)\n", " (norm1): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((4096,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (6): Decoder(\n", " (decoder): Linear(in_features=4096, out_features=28782, bias=True)\n", " )\n", " )\n", " )\n", ")\n" ] } ], "source": [ "ntokens = len(vocab) # the size of vocabulary\n", "emsize = 4096 # embedding dimension\n", "nhid = 4096 # the dimension of the feedforward network model in ``nn.TransformerEncoder``\n", "nlayers = 12 # the number of ``nn.TransformerEncoderLayer`` in ``nn.TransformerEncoder``\n", "nhead = 16 # the number of heads in the Multihead Attention models\n", "dropout = 0.2 # the dropout value\n", "\n", "from torch.distributed import rpc\n", "tmpfile = tempfile.NamedTemporaryFile()\n", "\n", "print(\"tmpfile:\", tmpfile.name)\n", "\n", "rpc.init_rpc(\n", " name=\"worker\",\n", " rank=0,\n", " world_size=1,\n", " rpc_backend_options=rpc.TensorPipeRpcBackendOptions(\n", " init_method=\"file://{}\".format(tmpfile.name),\n", " # Specifying _transports and _channels is a workaround \n", " # 对于 PyTorch 版本 >= 1.8.1 时,不再必须指定 specify _transports 和 _channels 。\n", " _transports=[\"ibv\", \"uv\"],\n", " _channels=[\"cuda_ipc\", \"cuda_basic\"],\n", " )\n", ")\n", "\n", "num_gpus = 2\n", "partition_len = ((nlayers - 1) // num_gpus) + 1\n", "\n", "# Add encoder in the beginning.\n", "# 手动指定cuda0\n", "tmp_list = [Encoder(ntokens, emsize, dropout).cuda(0)]\n", "module_list = []\n", "\n", "# Add all the necessary transformer blocks.\n", "for i in range(nlayers):\n", " transformer_block = TransformerEncoderLayer(emsize, nhead, nhid, dropout)\n", " if i != 0 and i % (partition_len) == 0:\n", " module_list.append(nn.Sequential(*tmp_list))\n", " tmp_list = []\n", " device = i // (partition_len)\n", " tmp_list.append(transformer_block.to(device))\n", "\n", "# Add decoder in the end.\n", "# 手动指定cuda1\n", "tmp_list.append(Decoder(ntokens, emsize).cuda(num_gpus - 1))\n", "\n", "module_list.append(nn.Sequential(*tmp_list))\n", "\n", "from torch.distributed.pipeline.sync import Pipe\n", "\n", "# Build the pipeline.\n", "chunks = 8\n", "model = Pipe(torch.nn.Sequential(*module_list), chunks = chunks)\n", "\n", "\n", "def get_total_params(module: torch.nn.Module):\n", " total_params = 0\n", " for param in module.parameters():\n", " total_params += param.numel()\n", " return total_params\n", "\n", "print ('Total parameters in model: {:,}'.format(get_total_params(model)))\n", "print(model)" ] }, { "cell_type": "code", "execution_count": 6, "id": "f3f464dc-e9ba-42bb-a4d4-fa6c0a5073d0", "metadata": {}, "outputs": [], "source": [ "criterion = nn.CrossEntropyLoss()\n", "lr = 5.0 # learning rate\n", "optimizer = torch.optim.SGD(model.parameters(), lr=lr)\n", "scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma=0.95)\n", "\n", "import time\n", "def train():\n", " model.train() # Turn on the train mode\n", " total_loss = 0.\n", " start_time = time.time()\n", " ntokens = len(vocab)\n", "\n", " # Train only for 50 batches to keep script execution time low.\n", " nbatches = min(50 * bptt, train_data.size(0) - 1)\n", "\n", " for batch, i in enumerate(range(0, nbatches, bptt)):\n", " data, targets = get_batch(train_data, i)\n", " optimizer.zero_grad()\n", " # Since the Pipe is only within a single host and process the ``RRef``\n", " # returned by forward method is local to this node and can simply\n", " # retrieved via ``RRef.local_value()``.\n", " output = model(data).local_value()\n", " # Need to move targets to the device where the output of the\n", " # pipeline resides.\n", " loss = criterion(output.view(-1, ntokens), targets.cuda(1))\n", " loss.backward()\n", " torch.nn.utils.clip_grad_norm_(model.parameters(), 0.5)\n", " optimizer.step()\n", "\n", " total_loss += loss.item()\n", " log_interval = 10\n", " if batch % log_interval == 0 and batch > 0:\n", " cur_loss = total_loss / log_interval\n", " elapsed = time.time() - start_time\n", " print('| epoch {:3d} | {:5d}/{:5d} batches | '\n", " 'lr {:02.2f} | ms/batch {:5.2f} | '\n", " 'loss {:5.2f} | ppl {:8.2f}'.format(\n", " epoch, batch, nbatches // bptt, scheduler.get_lr()[0],\n", " elapsed * 1000 / log_interval,\n", " cur_loss, math.exp(cur_loss)))\n", " total_loss = 0\n", " start_time = time.time()\n", "\n", "def evaluate(eval_model, data_source):\n", " eval_model.eval() # Turn on the evaluation mode\n", " total_loss = 0.\n", " ntokens = len(vocab)\n", " # Evaluate only for 50 batches to keep script execution time low.\n", " nbatches = min(50 * bptt, data_source.size(0) - 1)\n", " with torch.no_grad():\n", " for i in range(0, nbatches, bptt):\n", " data, targets = get_batch(data_source, i)\n", " output = eval_model(data).local_value()\n", " output_flat = output.view(-1, ntokens)\n", " # Need to move targets to the device where the output of the\n", " # pipeline resides.\n", " total_loss += len(data) * criterion(output_flat, targets.cuda(1)).item()\n", " return total_loss / (len(data_source) - 1)" ] }, { "cell_type": "code", "execution_count": 7, "id": "a85df730-3c8d-48aa-b730-81239070f49b", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/guodong.li/virtual-venv/peft-venv-py310-cu117/lib/python3.10/site-packages/torch/optim/lr_scheduler.py:381: UserWarning: To get the last learning rate computed by the scheduler, please use `get_last_lr()`.\n", " warnings.warn(\"To get the last learning rate computed by the scheduler, \"\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "| epoch 1 | 10/ 50 batches | lr 5.00 | ms/batch 507.00 | loss 42.58 | ppl 3094654443538114560.00\n", "| epoch 1 | 20/ 50 batches | lr 5.00 | ms/batch 380.02 | loss 41.60 | ppl 1161863941711398144.00\n", "| epoch 1 | 30/ 50 batches | lr 5.00 | ms/batch 361.34 | loss 42.50 | ppl 2871363680581511680.00\n", "| epoch 1 | 40/ 50 batches | lr 5.00 | ms/batch 372.07 | loss 40.63 | ppl 441516461309450688.00\n", "-----------------------------------------------------------------------------------------\n", "| end of epoch 1 | time: 22.27s | valid loss 0.97 | valid ppl 2.64\n", "-----------------------------------------------------------------------------------------\n", "| epoch 2 | 10/ 50 batches | lr 4.51 | ms/batch 401.81 | loss 39.16 | ppl 101713356373353456.00\n", "| epoch 2 | 20/ 50 batches | lr 4.51 | ms/batch 374.01 | loss 29.01 | ppl 3985883147930.86\n", "| epoch 2 | 30/ 50 batches | lr 4.51 | ms/batch 378.12 | loss 26.52 | ppl 329134739848.90\n", "| epoch 2 | 40/ 50 batches | lr 4.51 | ms/batch 382.70 | loss 20.50 | ppl 802992471.18\n", "-----------------------------------------------------------------------------------------\n", "| end of epoch 2 | time: 21.53s | valid loss 0.38 | valid ppl 1.46\n", "-----------------------------------------------------------------------------------------\n", "| epoch 3 | 10/ 50 batches | lr 4.29 | ms/batch 416.74 | loss 13.64 | ppl 842059.77\n", "| epoch 3 | 20/ 50 batches | lr 4.29 | ms/batch 368.97 | loss 10.73 | ppl 45837.47\n", "| epoch 3 | 30/ 50 batches | lr 4.29 | ms/batch 366.39 | loss 10.70 | ppl 44182.25\n", "| epoch 3 | 40/ 50 batches | lr 4.29 | ms/batch 364.48 | loss 11.38 | ppl 87633.96\n", "-----------------------------------------------------------------------------------------\n", "| end of epoch 3 | time: 21.07s | valid loss 0.21 | valid ppl 1.24\n", "-----------------------------------------------------------------------------------------\n" ] } ], "source": [ "best_val_loss = float(\"inf\")\n", "epochs = 3 # The number of epochs\n", "best_model = None\n", "\n", "for epoch in range(1, epochs + 1):\n", " epoch_start_time = time.time()\n", " # 训练\n", " train()\n", " # 评估\n", " val_loss = evaluate(model, val_data)\n", " print('-' * 89)\n", " print('| end of epoch {:3d} | time: {:5.2f}s | valid loss {:5.2f} | '\n", " 'valid ppl {:8.2f}'.format(epoch, (time.time() - epoch_start_time),\n", " val_loss, math.exp(val_loss)))\n", " print('-' * 89)\n", "\n", " if val_loss < best_val_loss:\n", " best_val_loss = val_loss\n", " best_model = model\n", "\n", " scheduler.step()" ] }, { "cell_type": "code", "execution_count": 8, "id": "2ed6c897-5982-4a49-aafa-6c18d1c7e8e2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "=========================================================================================\n", "| End of training | test loss 0.19 | test ppl 1.21\n", "=========================================================================================\n" ] } ], "source": [ "test_loss = evaluate(best_model, test_data)\n", "print('=' * 89)\n", "print('| End of training | test loss {:5.2f} | test ppl {:8.2f}'.format(\n", " test_loss, math.exp(test_loss)))\n", "print('=' * 89)" ] }, { "cell_type": "code", "execution_count": null, "id": "20438970-1e54-4959-ad48-7eb506fc0405", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "peft-venv-py310-cu117", "language": "python", "name": "peft-venv-py310-cu117" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-train/pytorch/distribution/pipeline-parallel/transformer_tutorial.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 3, "id": "d870f870-e649-46ec-9631-8ae070b01f31", "metadata": {}, "outputs": [], "source": [ "import math\n", "import os\n", "from tempfile import TemporaryDirectory\n", "from typing import Tuple\n", "\n", "import torch\n", "from torch import nn, Tensor\n", "from torch.nn import TransformerEncoder, TransformerEncoderLayer\n", "from torch.utils.data import dataset\n", "\n", "class TransformerModel(nn.Module):\n", "\n", " def __init__(self, ntoken: int, d_model: int, nhead: int, d_hid: int,\n", " nlayers: int, dropout: float = 0.5):\n", " super().__init__()\n", " self.model_type = 'Transformer'\n", " self.pos_encoder = PositionalEncoding(d_model, dropout)\n", " encoder_layers = TransformerEncoderLayer(d_model, nhead, d_hid, dropout)\n", " self.transformer_encoder = TransformerEncoder(encoder_layers, nlayers)\n", " self.embedding = nn.Embedding(ntoken, d_model)\n", " self.d_model = d_model\n", " self.linear = nn.Linear(d_model, ntoken)\n", "\n", " self.init_weights()\n", "\n", " def init_weights(self) -> None:\n", " initrange = 0.1\n", " self.embedding.weight.data.uniform_(-initrange, initrange)\n", " self.linear.bias.data.zero_()\n", " self.linear.weight.data.uniform_(-initrange, initrange)\n", "\n", " def forward(self, src: Tensor, src_mask: Tensor = None) -> Tensor:\n", " \"\"\"\n", " Arguments:\n", " src: Tensor, shape ``[seq_len, batch_size]``\n", " src_mask: Tensor, shape ``[seq_len, seq_len]``\n", "\n", " Returns:\n", " output Tensor of shape ``[seq_len, batch_size, ntoken]``\n", " \"\"\"\n", " src = self.embedding(src) * math.sqrt(self.d_model)\n", " src = self.pos_encoder(src)\n", " output = self.transformer_encoder(src, src_mask)\n", " output = self.linear(output)\n", " return output" ] }, { "cell_type": "code", "execution_count": 4, "id": "d0b62743-5972-40a4-8203-c82f6a999bbc", "metadata": {}, "outputs": [], "source": [ "class PositionalEncoding(nn.Module):\n", "\n", " def __init__(self, d_model: int, dropout: float = 0.1, max_len: int = 5000):\n", " super().__init__()\n", " self.dropout = nn.Dropout(p=dropout)\n", "\n", " position = torch.arange(max_len).unsqueeze(1)\n", " div_term = torch.exp(torch.arange(0, d_model, 2) * (-math.log(10000.0) / d_model))\n", " pe = torch.zeros(max_len, 1, d_model)\n", " pe[:, 0, 0::2] = torch.sin(position * div_term)\n", " pe[:, 0, 1::2] = torch.cos(position * div_term)\n", " self.register_buffer('pe', pe)\n", "\n", " def forward(self, x: Tensor) -> Tensor:\n", " \"\"\"\n", " Arguments:\n", " x: Tensor, shape ``[seq_len, batch_size, embedding_dim]``\n", " \"\"\"\n", " x = x + self.pe[:x.size(0)]\n", " return self.dropout(x)" ] }, { "cell_type": "code", "execution_count": 7, "id": "a30df235-10ba-455b-b5cf-412105ae6ceb", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "torch.Size([2049990])\n", "torch.Size([102499, 20])\n", "tensor([[ 9, 59, 564, ..., 11652, 2435, 1],\n", " [ 3849, 12, 300, ..., 47, 30, 1990],\n", " [ 3869, 315, 19, ..., 97, 7720, 4],\n", " ...,\n", " [ 587, 4011, 59, ..., 1, 1439, 12313],\n", " [ 4987, 29, 4, ..., 3165, 17106, 2060],\n", " [ 6, 8, 1, ..., 62, 18, 2]], device='cuda:0')\n" ] } ], "source": [ "from torchtext.datasets import WikiText2\n", "from torchtext.data.utils import get_tokenizer\n", "from torchtext.vocab import build_vocab_from_iterator\n", "\n", "train_iter = WikiText2(split='train')\n", "tokenizer = get_tokenizer('basic_english')\n", "vocab = build_vocab_from_iterator(map(tokenizer, train_iter), specials=[''])\n", "vocab.set_default_index(vocab[''])\n", "\n", "def data_process(raw_text_iter: dataset.IterableDataset) -> Tensor:\n", " \"\"\"Converts raw text into a flat Tensor.\"\"\"\n", " data = [torch.tensor(vocab(tokenizer(item)), dtype=torch.long) for item in raw_text_iter]\n", " return torch.cat(tuple(filter(lambda t: t.numel() > 0, data)))\n", "\n", "# ``train_iter`` was \"consumed\" by the process of building the vocab,\n", "# so we have to create it again\n", "train_iter, val_iter, test_iter = WikiText2()\n", "train_data = data_process(train_iter)\n", "val_data = data_process(val_iter)\n", "test_data = data_process(test_iter)\n", "\n", "print(train_data.shape)\n", "\n", "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n", "\n", "def batchify(data: Tensor, bsz: int) -> Tensor:\n", " \"\"\"Divides the data into ``bsz`` separate sequences, removing extra elements\n", " that wouldn't cleanly fit.\n", "\n", " Arguments:\n", " data: Tensor, shape ``[N]``\n", " bsz: int, batch size\n", "\n", " Returns:\n", " Tensor of shape ``[N // bsz, bsz]``\n", " \"\"\"\n", " seq_len = data.size(0) // bsz\n", " data = data[:seq_len * bsz]\n", " data = data.view(bsz, seq_len).t().contiguous()\n", " return data.to(device)\n", "\n", "batch_size = 20\n", "eval_batch_size = 10\n", "train_data = batchify(train_data, batch_size) # shape ``[seq_len, batch_size]``\n", "val_data = batchify(val_data, eval_batch_size)\n", "test_data = batchify(test_data, eval_batch_size)\n", "print(train_data.shape)\n", "print(train_data)" ] }, { "cell_type": "code", "execution_count": 8, "id": "d7b4f49f-acf5-4c18-b983-51e1049eada4", "metadata": {}, "outputs": [], "source": [ "bptt = 35\n", "def get_batch(source: Tensor, i: int) -> Tuple[Tensor, Tensor]:\n", " \"\"\"\n", " Args:\n", " source: Tensor, shape ``[full_seq_len, batch_size]``\n", " i: int\n", "\n", " Returns:\n", " tuple (data, target), where data has shape ``[seq_len, batch_size]`` and\n", " target has shape ``[seq_len * batch_size]``\n", " \"\"\"\n", " seq_len = min(bptt, len(source) - 1 - i)\n", " data = source[i:i+seq_len]\n", " target = source[i+1:i+1+seq_len].reshape(-1)\n", " return data, target" ] }, { "cell_type": "code", "execution_count": 9, "id": "0162f2a6-fb9e-4183-a894-8285eabc11a6", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "TransformerModel(\n", " (pos_encoder): PositionalEncoding(\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " )\n", " (transformer_encoder): TransformerEncoder(\n", " (layers): ModuleList(\n", " (0): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=200, out_features=200, bias=True)\n", " )\n", " (linear1): Linear(in_features=200, out_features=200, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=200, out_features=200, bias=True)\n", " (norm1): LayerNorm((200,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((200,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " (1): TransformerEncoderLayer(\n", " (self_attn): MultiheadAttention(\n", " (out_proj): NonDynamicallyQuantizableLinear(in_features=200, out_features=200, bias=True)\n", " )\n", " (linear1): Linear(in_features=200, out_features=200, bias=True)\n", " (dropout): Dropout(p=0.2, inplace=False)\n", " (linear2): Linear(in_features=200, out_features=200, bias=True)\n", " (norm1): LayerNorm((200,), eps=1e-05, elementwise_affine=True)\n", " (norm2): LayerNorm((200,), eps=1e-05, elementwise_affine=True)\n", " (dropout1): Dropout(p=0.2, inplace=False)\n", " (dropout2): Dropout(p=0.2, inplace=False)\n", " )\n", " )\n", " )\n", " (embedding): Embedding(28782, 200)\n", " (linear): Linear(in_features=200, out_features=28782, bias=True)\n", ")" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ntokens = len(vocab) # size of vocabulary\n", "emsize = 200 # embedding dimension\n", "d_hid = 200 # dimension of the feedforward network model in ``nn.TransformerEncoder``\n", "nlayers = 2 # number of ``nn.TransformerEncoderLayer`` in ``nn.TransformerEncoder``\n", "nhead = 2 # number of heads in ``nn.MultiheadAttention``\n", "dropout = 0.2 # dropout probability\n", "model = TransformerModel(ntokens, emsize, nhead, d_hid, nlayers, dropout).to(device)\n", "model" ] }, { "cell_type": "code", "execution_count": 10, "id": "c791ffa0-41fc-4f6d-9cc7-e7c456921749", "metadata": {}, "outputs": [], "source": [ "import time\n", "\n", "criterion = nn.CrossEntropyLoss()\n", "lr = 5.0 # learning rate\n", "optimizer = torch.optim.SGD(model.parameters(), lr=lr)\n", "scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma=0.95)\n", "\n", "def train(model: nn.Module) -> None:\n", " model.train() # turn on train mode\n", " total_loss = 0.\n", " log_interval = 200\n", " start_time = time.time()\n", "\n", " num_batches = len(train_data) // bptt\n", " for batch, i in enumerate(range(0, train_data.size(0) - 1, bptt)):\n", " data, targets = get_batch(train_data, i)\n", " output = model(data)\n", " output_flat = output.view(-1, ntokens)\n", " loss = criterion(output_flat, targets)\n", "\n", " optimizer.zero_grad()\n", " loss.backward()\n", " torch.nn.utils.clip_grad_norm_(model.parameters(), 0.5)\n", " optimizer.step()\n", "\n", " total_loss += loss.item()\n", " if batch % log_interval == 0 and batch > 0:\n", " lr = scheduler.get_last_lr()[0]\n", " ms_per_batch = (time.time() - start_time) * 1000 / log_interval\n", " cur_loss = total_loss / log_interval\n", " ppl = math.exp(cur_loss)\n", " print(f'| epoch {epoch:3d} | {batch:5d}/{num_batches:5d} batches | '\n", " f'lr {lr:02.2f} | ms/batch {ms_per_batch:5.2f} | '\n", " f'loss {cur_loss:5.2f} | ppl {ppl:8.2f}')\n", " total_loss = 0\n", " start_time = time.time()\n", "\n", "def evaluate(model: nn.Module, eval_data: Tensor) -> float:\n", " model.eval() # turn on evaluation mode\n", " total_loss = 0.\n", " with torch.no_grad():\n", " for i in range(0, eval_data.size(0) - 1, bptt):\n", " data, targets = get_batch(eval_data, i)\n", " seq_len = data.size(0)\n", " output = model(data)\n", " output_flat = output.view(-1, ntokens)\n", " total_loss += seq_len * criterion(output_flat, targets).item()\n", " return total_loss / (len(eval_data) - 1)" ] }, { "cell_type": "code", "execution_count": 12, "id": "0e4b1bf0-ca2e-4c37-ac5a-12b279108572", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tempdir: /tmp/tmpnth1zkzl\n", "| epoch 1 | 200/ 2928 batches | lr 5.00 | ms/batch 10.20 | loss 4.36 | ppl 78.05\n", "| epoch 1 | 400/ 2928 batches | lr 5.00 | ms/batch 9.96 | loss 4.00 | ppl 54.58\n", "| epoch 1 | 600/ 2928 batches | lr 5.00 | ms/batch 11.61 | loss 3.66 | ppl 38.98\n", "| epoch 1 | 800/ 2928 batches | lr 5.00 | ms/batch 11.32 | loss 3.52 | ppl 33.73\n", "| epoch 1 | 1000/ 2928 batches | lr 5.00 | ms/batch 11.27 | loss 3.35 | ppl 28.55\n", "| epoch 1 | 1200/ 2928 batches | lr 5.00 | ms/batch 13.18 | loss 3.40 | ppl 30.02\n", "| epoch 1 | 1400/ 2928 batches | lr 5.00 | ms/batch 11.26 | loss 3.46 | ppl 31.69\n", "| epoch 1 | 1600/ 2928 batches | lr 5.00 | ms/batch 9.60 | loss 3.41 | ppl 30.31\n", "| epoch 1 | 1800/ 2928 batches | lr 5.00 | ms/batch 9.24 | loss 3.29 | ppl 26.80\n", "| epoch 1 | 2000/ 2928 batches | lr 5.00 | ms/batch 9.65 | loss 3.23 | ppl 25.29\n", "| epoch 1 | 2200/ 2928 batches | lr 5.00 | ms/batch 12.04 | loss 3.14 | ppl 23.07\n", "| epoch 1 | 2400/ 2928 batches | lr 5.00 | ms/batch 10.88 | loss 3.16 | ppl 23.47\n", "| epoch 1 | 2600/ 2928 batches | lr 5.00 | ms/batch 9.61 | loss 3.10 | ppl 22.30\n", "| epoch 1 | 2800/ 2928 batches | lr 5.00 | ms/batch 8.67 | loss 3.03 | ppl 20.80\n", "-----------------------------------------------------------------------------------------\n", "| end of epoch 1 | time: 31.97s | valid loss 2.17 | valid ppl 8.74\n", "-----------------------------------------------------------------------------------------\n", "| epoch 2 | 200/ 2928 batches | lr 4.75 | ms/batch 8.21 | loss 2.73 | ppl 15.35\n", "| epoch 2 | 400/ 2928 batches | lr 4.75 | ms/batch 12.87 | loss 2.72 | ppl 15.17\n", "| epoch 2 | 600/ 2928 batches | lr 4.75 | ms/batch 8.24 | loss 2.57 | ppl 13.11\n", "| epoch 2 | 800/ 2928 batches | lr 4.75 | ms/batch 8.16 | loss 2.55 | ppl 12.80\n", "| epoch 2 | 1000/ 2928 batches | lr 4.75 | ms/batch 8.54 | loss 2.50 | ppl 12.16\n", "| epoch 2 | 1200/ 2928 batches | lr 4.75 | ms/batch 8.55 | loss 2.56 | ppl 12.94\n", "| epoch 2 | 1400/ 2928 batches | lr 4.75 | ms/batch 7.50 | loss 2.61 | ppl 13.58\n", "| epoch 2 | 1600/ 2928 batches | lr 4.75 | ms/batch 13.12 | loss 2.59 | ppl 13.29\n", "| epoch 2 | 1800/ 2928 batches | lr 4.75 | ms/batch 12.96 | loss 2.52 | ppl 12.48\n", "| epoch 2 | 2000/ 2928 batches | lr 4.75 | ms/batch 8.60 | loss 2.60 | ppl 13.47\n", "| epoch 2 | 2200/ 2928 batches | lr 4.75 | ms/batch 11.87 | loss 2.46 | ppl 11.67\n", "| epoch 2 | 2400/ 2928 batches | lr 4.75 | ms/batch 10.10 | loss 2.56 | ppl 12.88\n", "| epoch 2 | 2600/ 2928 batches | lr 4.75 | ms/batch 12.89 | loss 2.63 | ppl 13.87\n", "| epoch 2 | 2800/ 2928 batches | lr 4.75 | ms/batch 13.42 | loss 2.55 | ppl 12.77\n", "-----------------------------------------------------------------------------------------\n", "| end of epoch 2 | time: 31.17s | valid loss 1.38 | valid ppl 3.99\n", "-----------------------------------------------------------------------------------------\n", "| epoch 3 | 200/ 2928 batches | lr 4.51 | ms/batch 10.00 | loss 2.27 | ppl 9.64\n", "| epoch 3 | 400/ 2928 batches | lr 4.51 | ms/batch 11.53 | loss 2.29 | ppl 9.86\n", "| epoch 3 | 600/ 2928 batches | lr 4.51 | ms/batch 10.95 | loss 2.23 | ppl 9.27\n", "| epoch 3 | 800/ 2928 batches | lr 4.51 | ms/batch 11.43 | loss 2.28 | ppl 9.75\n", "| epoch 3 | 1000/ 2928 batches | lr 4.51 | ms/batch 12.27 | loss 2.24 | ppl 9.35\n", "| epoch 3 | 1200/ 2928 batches | lr 4.51 | ms/batch 11.27 | loss 2.32 | ppl 10.16\n", "| epoch 3 | 1400/ 2928 batches | lr 4.51 | ms/batch 11.91 | loss 2.28 | ppl 9.82\n", "| epoch 3 | 1600/ 2928 batches | lr 4.51 | ms/batch 8.35 | loss 2.36 | ppl 10.57\n", "| epoch 3 | 1800/ 2928 batches | lr 4.51 | ms/batch 7.15 | loss 2.28 | ppl 9.80\n", "| epoch 3 | 2000/ 2928 batches | lr 4.51 | ms/batch 9.61 | loss 2.34 | ppl 10.35\n", "| epoch 3 | 2200/ 2928 batches | lr 4.51 | ms/batch 13.29 | loss 2.26 | ppl 9.59\n", "| epoch 3 | 2400/ 2928 batches | lr 4.51 | ms/batch 13.74 | loss 2.28 | ppl 9.81\n", "| epoch 3 | 2600/ 2928 batches | lr 4.51 | ms/batch 12.92 | loss 2.40 | ppl 11.02\n", "| epoch 3 | 2800/ 2928 batches | lr 4.51 | ms/batch 12.56 | loss 2.34 | ppl 10.37\n", "-----------------------------------------------------------------------------------------\n", "| end of epoch 3 | time: 33.37s | valid loss 1.48 | valid ppl 4.41\n", "-----------------------------------------------------------------------------------------\n" ] } ], "source": [ "best_val_loss = float('inf')\n", "epochs = 3\n", "\n", "with TemporaryDirectory() as tempdir:\n", " print(\"tempdir:\", tempdir)\n", " best_model_params_path = os.path.join(tempdir, \"best_model_params.pt\")\n", "\n", " for epoch in range(1, epochs + 1):\n", " epoch_start_time = time.time()\n", " train(model)\n", " val_loss = evaluate(model, val_data)\n", " val_ppl = math.exp(val_loss)\n", " elapsed = time.time() - epoch_start_time\n", " print('-' * 89)\n", " print(f'| end of epoch {epoch:3d} | time: {elapsed:5.2f}s | '\n", " f'valid loss {val_loss:5.2f} | valid ppl {val_ppl:8.2f}')\n", " print('-' * 89)\n", "\n", " if val_loss < best_val_loss:\n", " best_val_loss = val_loss\n", " # 保存模型\n", " torch.save(model.state_dict(), best_model_params_path)\n", "\n", " scheduler.step()\n", " # 加载最好的模型 \n", " model.load_state_dict(torch.load(best_model_params_path)) # load best model states" ] }, { "cell_type": "code", "execution_count": 13, "id": "a8206bdb-91d6-4b7b-8bb4-f3a8eecfe26e", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "=========================================================================================\n", "| End of training | test loss 1.37 | test ppl 3.93\n", "=========================================================================================\n" ] } ], "source": [ "test_loss = evaluate(model, test_data)\n", "test_ppl = math.exp(test_loss)\n", "print('=' * 89)\n", "print(f'| End of training | test loss {test_loss:5.2f} | '\n", " f'test ppl {test_ppl:8.2f}')\n", "print('=' * 89)" ] }, { "cell_type": "code", "execution_count": null, "id": "cf8296ca-705b-41aa-a3ce-e69f8aa8e710", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 } ================================================ FILE: llm-train/pytorch/distribution/rpc/README.md ================================================ - DISTRIBUTED PIPELINE PARALLELISM USING RPC:https://pytorch.org/tutorials/intermediate/dist_pipeline_parallel_tutorial.html ================================================ FILE: llm-train/pytorch/distribution/sequence-parallelism/README.md ================================================ ================================================ FILE: llm-train/pytorch/distribution/tensor-parallel/2d_parallel_example.py ================================================ import argparse import torch import torch.distributed as dist import torch.multiprocessing as mp from torch.distributed._tensor import DeviceMesh from torch.distributed.fsdp import FullyShardedDataParallel as FSDP from torch.distributed.tensor.parallel import ( PairwiseParallel, parallelize_module, ) from torch.distributed.tensor.parallel.fsdp import enable_2d_with_fsdp from utils import cleanup, setup, ToyModel try: from torch.distributed.tensor.parallel import ( SequenceParallel ) SP_AVAILABLE = True except BaseException as e: pass """ This is the script to test 2D Parallel which combines Tensor/Sequence parallel with Fully Sharded Data Parallel (TP/SP + FSDP) on a toy model in the SPMD style. We show an E2E working flow from forward, backward and optimization. We enabled Fully Sharded Data Parallel + Tensor Parallel in separate parallel dimensions: Data Parallel across hosts Tensor Parallel within each host We use a simple diagram to illustrate below: ====================================================================== ------------ ------------ ------------ ------------ | Host 1 | | Host 2 | | | | Host N | | 8 GPUs | | 8 GPUs | | | | 8 GPUs | | | | | | ... | | | | (TP) | | (TP) | | | | (TP) | |[0,1,..,7]| |[8,9..,15]| | | |[8N-8,8N-7| | | | | | | | .., 8N-1]| | | | | | | | | ------------ ------------ ------------ ------------ FSDP: [0, 8, ..., 8N-8], [1, 9, ..., 8N-7], ..., [7, 15, ..., 8N-1] ====================================================================== More details can be seen in the slide: https://docs.google.com/presentation/d/17g6WqrO00rP3MsxbRENsPpjrlSkwiA_QB4r93_eB5is/ """ def demo_2d(rank, args): """ Main body of the demo of a basic version of tensor parallel by using PyTorch native APIs. """ print(f"Running basic Megatron style TP example on rank {rank}.") setup(rank, args.world_size) assert ( args.world_size % args.tp_size == 0 ), "World size needs to be divisible by TP size" # create a sharding plan based on the given world_size. device_mesh = DeviceMesh( "cuda", torch.arange(0, args.world_size).view(-1, args.tp_size) ) # create model and move it to GPU with id rank model = ToyModel().cuda(rank) # Create a optimizer for the parallelized module. LR = 0.25 optimizer = torch.optim.SGD(model.parameters(), lr=LR) # Parallelize the module based on the given Parallel Style. parallel_style = SequenceParallel() if args.run_seq_parallel else PairwiseParallel() model = parallelize_module(model, device_mesh, parallel_style, tp_mesh_dim=1) # We need to register hooks for TP + FSDP integration. assert ( enable_2d_with_fsdp() ), "FSDP 2D hook is not registered. Please use PyTorch with version >= 2.0" dp_pg = device_mesh.get_dim_groups()[0] model = FSDP(model, process_group=dp_pg) # Perform a num of iterations of forward/backward # and optimizations for the sharded module. for i in range(args.iter_nums): # For TP, input needs to be same across all TP ranks. # while for SP, input can be different across all ranks. # Setting the random seed is to mimic the behavior of dataloader. dp_rank = ( rank if args.run_seq_parallel else dist.get_rank(dp_pg) ) torch.manual_seed(i + dp_rank) inp = torch.rand(20, 10).cuda(rank) output = model(inp) output.sum().backward() optimizer.step() cleanup() if __name__ == "__main__": n_gpus = torch.cuda.device_count() parser = argparse.ArgumentParser() # This is passed in via cmd parser.add_argument("--world_size", type=int, default=n_gpus) parser.add_argument("--iter_nums", type=int, default=10) parser.add_argument("--run_seq_parallel", type=bool, default=False) parser.add_argument("--tp_size", type=int, default=2) args = parser.parse_args() # The main entry point is called directly without using subprocess if n_gpus < 4: print("Requires at least 4 GPUs to run.") elif not SP_AVAILABLE: print( "PyTorch doesn't have Sequence Parallelism available," " need nightly build." ) else: mp.spawn(demo_2d, args=(args,), nprocs=args.world_size, join=True) ================================================ FILE: llm-train/pytorch/distribution/tensor-parallel/README.md ================================================ ``` from utils import cleanup, setup, ToyModel model = ToyModel().cuda(0) model ``` ``` +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 1521759 C /opt/conda/bin/python 3820MiB | +-----------------------------------------------------------------------------+ ``` ``` +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | 0 N/A N/A 4112660 C /opt/conda/bin/python 1382MiB | | 1 N/A N/A 4112661 C /opt/conda/bin/python 1382MiB | | 2 N/A N/A 4112662 C /opt/conda/bin/python 1370MiB | | 3 N/A N/A 4112663 C /opt/conda/bin/python 1370MiB | +-----------------------------------------------------------------------------+ ``` Tensor Parallelism(TP) 建立在 DistributedTensor(DTensor) 之上,并提供多种并行格式:Rowwise、Colwise 和 Pairwise Parallelism。 Rowwise,对模块的行进行分区。假设输入是分片的 DTensor,则输出是仿制的 DTensor。 Colwise,对张量或模块的列进行分区。 假设输入是仿制的 DTensor,则输出是分片的 DTensor。 PairwiseParallel 将 colwise 和 rowwise 样式串联为固定对,就像 [Megatron-LM](https://arxiv.org/abs/1909.08053) 所做的那样。 我们假设输入和输出都需要复制 DTensor。 PairwiseParallel 目前仅支持 `nn.Multihead Attention`、`nn.Transformer` 或偶数层 `MLP`。 由于 Tensor Parallelism 是建立在 DTensor 之上的,因此我们需要使用 DTensor 指定模块的输入和输出位置,以便它可以在前后与模块进行预期的交互。 以下是用于输入/输出准备的函数: torch.distributed.tensor.parallel.style.make_input_replicate_1d(input, device_mesh=None) --- DeviceMesh 设备网格 ================================================ FILE: llm-train/pytorch/distribution/tensor-parallel/sequence_parallel_example.py ================================================ import argparse import torch import torch.multiprocessing as mp from torch.distributed._tensor import DeviceMesh from torch.distributed.tensor.parallel import parallelize_module from utils import cleanup, setup, ToyModel try: from torch.distributed.tensor.parallel import ( SequenceParallel ) SP_AVAILABLE = True except BaseException as e: pass """ This is the script to test Sequence Parallel(SP) on a toy model in a Megetron-LM SPMD style. We show an E2E working flow from forward, backward and optimization. We use the example of two `nn.Linear` layers with an element-wise `nn.RELU` in between to show an example of sequence parallel, which was proposed in paper: https://arxiv.org/pdf/2205.05198.pdf. Like tensor parallel, we parallelize the first linear layer by column and also parallelize the second linear layer by row. But the input in each rank now is different so that we need one all-gather for input and one reduce-scatter in the end of the second linear layer. """ def demo_sp(rank, args): """ Main body of the demo of a basic version of sequence parallel by using PyTorch native APIs. """ print(f"Running SP example on rank {rank}.") setup(rank, args.world_size) # create a sharding plan based on the given world_size. device_mesh = DeviceMesh("cuda", torch.arange(0, args.world_size)) # create model and move it to GPU with id rank model = ToyModel().cuda(rank) # Create a optimizer for the parallelized module. LR = 0.25 optimizer = torch.optim.SGD(model.parameters(), lr=LR) # Parallelize the module based on the given Parallel Style. model = parallelize_module(model, device_mesh, SequenceParallel()) # Perform a num of iterations of forward/backward # and optimizations for the sharded module. for _ in range(args.iter_nums): # For SP, input can be different across all ranks. inp = torch.rand(20, 10).cuda(rank) output = model(inp) output.sum().backward() optimizer.step() cleanup() if __name__ == "__main__": n_gpus = torch.cuda.device_count() parser = argparse.ArgumentParser() # This is passed in via cmd parser.add_argument("--world_size", type=int, default=n_gpus) parser.add_argument("--iter_nums", type=int, default=10) args = parser.parse_args() # The main entry point is called directly without using subprocess if n_gpus < 2: print("Requires at least 2 GPUs to run.") elif not SP_AVAILABLE: print( "PyTorch doesn't have Sequence Parallelism available," " need nightly build." ) else: mp.spawn(demo_sp, args=(args,), nprocs=args.world_size, join=True) ================================================ FILE: llm-train/pytorch/distribution/tensor-parallel/tensor_parallel_example.py ================================================ import argparse import torch import torch.multiprocessing as mp from torch.distributed._tensor import DeviceMesh from torch.distributed.tensor.parallel import PairwiseParallel, parallelize_module from utils import cleanup, setup, ToyModel """ This is the script to test Tensor Parallel(TP) on a toy model in a Megetron-LM SPMD style. We show an E2E working flow from forward, backward and optimization. More context about API designs can be found in the design: https://github.com/pytorch/pytorch/issues/89884. And it is built on top of Distributed Tensor which is proposed in: https://github.com/pytorch/pytorch/issues/88838. We use the example of two `nn.Linear` layers with an element-wise `nn.RELU` in between to show an example of Megatron-LM, which was proposed in paper: https://arxiv.org/abs/1909.08053. The basic idea is that we parallelize the first linear layer by column and also parallelize the second linear layer by row so that we only need one all reduce in the end of the second linear layer. We can speed up the model training by avoiding communications between two layers. To parallelize a nn module, we need to specify what parallel style we want to use and our `parallelize_module` API will parse and parallelize the modules based on the given `ParallelStyle`. We are using this PyTorch native Tensor Parallelism APIs in this example to show users how to use them. """ def demo_tp(rank, args): """ Main body of the demo of a basic version of tensor parallel by using PyTorch native APIs. """ print(f"Running basic Megatron style TP example on rank : {rank} , world_size : {args.world_size}. ") setup(rank, args.world_size) # create a sharding plan based on the given world_size. device_mesh = DeviceMesh("cuda", torch.arange(0, args.world_size)) # create model and move it to GPU with id rank model = ToyModel().cuda(rank) # Create a optimizer for the parallelized module. LR = 0.25 optimizer = torch.optim.SGD(model.parameters(), lr=LR) # Parallelize the module based on the given Parallel Style. model = parallelize_module(model, device_mesh, PairwiseParallel()) # Perform a num of iterations of forward/backward # and optimizations for the sharded module. for i in range(args.iter_nums): # For TP, input needs to be same across all TP ranks. # Setting the random seed is to mimic the behavior of dataloader. if rank==0: print(f"-----------{i}--------------") torch.manual_seed(i) inp = torch.rand(20, 10).cuda(rank) if rank==0: print(f"rank: {rank} , input shape: {inp.shape}") output = model(inp) if rank==0: print(f"rank: {rank} , input shape: {output.shape}") output.sum().backward() optimizer.step() #print("-------------------------") cleanup() if __name__ == "__main__": n_gpus = torch.cuda.device_count() parser = argparse.ArgumentParser() # This is passed in via cmd parser.add_argument("--world_size", type=int, default=n_gpus) parser.add_argument("--iter_nums", type=int, default=10000) args = parser.parse_args() # The main entry point is called directly without using subprocess if n_gpus < 2: print("Requires at least 2 GPUs to run.") else: mp.spawn(demo_tp, args=(args,), nprocs=args.world_size, join=True) ================================================ FILE: llm-train/pytorch/distribution/tensor-parallel/utils.py ================================================ import argparse import os import torch import torch.distributed as dist import torch.multiprocessing as mp import torch.nn as nn def setup(rank, world_size): os.environ["MASTER_ADDR"] = "localhost" os.environ["MASTER_PORT"] = "12355" # initialize the process group dist.init_process_group("nccl", rank=rank, world_size=world_size) torch.cuda.set_device(rank) def cleanup(): dist.destroy_process_group() class ToyModel(nn.Module): def __init__(self): super(ToyModel, self).__init__() self.net1 = nn.Linear(10, 32) self.relu = nn.ReLU() self.net2 = nn.Linear(32, 5) def forward(self, x): return self.net2(self.relu(self.net1(x))) ================================================ FILE: llm-train/pytorch/distribution/torchrun.md ================================================ - https://pytorch.org/docs/stable/elastic/run.html ``` torchrun --nnodes=$NUM_NODES --nproc-per-node=$NUM_TRAINERS --max-restarts=3 --rdzv-id=$JOB_ID --rdzv-backend=c10d --rdzv-endpoint=$HOST_NODE_ADDR YOUR_TRAINING_SCRIPT.py (--arg1 ... train script args...) ``` For multi-node training you need to specify: --rdzv-id: A unique job id (shared by all nodes participating in the job) --rdzv-backend: An implementation of torch.distributed.elastic.rendezvous.RendezvousHandler --rdzv-endpoint: The endpoint where the rendezvous backend is running; usually in form host:port. Currently c10d (recommended), etcd-v2, and etcd (legacy) rendezvous backends are supported out of the box. To use etcd-v2 or etcd, setup an etcd server with the v2 api enabled (e.g. --enable-v2). ================================================ FILE: llm-train/pytorch/distribution/分布式通信包.md ================================================ - https://pytorch.org/docs/stable/distributed.html # Backends ## 常用环境变量 选择要使用的网络接口 默认情况下,NCCL 和 Gloo 后端都会尝试找到要使用的正确网络接口。 如果自动检测到的接口不正确,您可以使用以下环境变量覆盖它(适用于各自的后端): - NCCL_SOCKET_IFNAME,例如:export NCCL_SOCKET_IFNAME=eth0 - GLOO_SOCKET_IFNAME,例如:export GLOO_SOCKET_IFNAME=eth0 如果您使用的是 Gloo 后端,则可以通过用逗号分隔来指定多个接口,如下所示:export GLOO_SOCKET_IFNAME=eth0,eth1,eth2,eth3。 后端将以循环方式跨这些接口调度操作。 所有进程必须在此变量中指定相同数量的接口。 其他 NCCL 环境变量 - 调试 - 如果 NCCL 失败,您可以设置 NCCL_DEBUG=INFO 来打印显式警告消息以及基本 NCCL 初始化信息。 您还可以使用 NCCL_DEBUG_SUBSYS 来获取有关 NCCL 特定方面的更多详细信息。 例如,NCCL_DEBUG_SUBSYS=COLL 将打印collective调用的日志,这在调试挂起时可能会有所帮助,特别是那些由collective类型或消息大小不匹配引起的情况。 如果拓扑检测失败,设置 NCCL_DEBUG_SUBSYS=GRAPH 将有助于检查详细的检测结果并保存以供需要 NCCL 团队进一步帮助时参考。 - 性能调优 - NCCL根据其拓扑检测进行自动调优,以节省用户的调优工作。 在某些基于socket的系统上,用户仍然可以尝试调整 NCCL_SOCKET_NTHREADS 和 NCCL_NSOCKS_PERTHREAD 以增加socket网络带宽。 NCCL 已针对某些云提供商(例如:AWS 或 GCP)预先调整了这两个环境变量。 NCCL环境变量的完整列表,请参考NVIDIA NCCL的官方文档:https://docs.nvidia.com/deeplearning/sdk/nccl-developer-guide/docs/env.html # Basics torch.distributed 包为在一台或多台机器上运行的多个计算节点之间的多进程并行提供了 PyTorch 支持和通信原语。 torch.nn.parallel.DistributedDataParallel() 类基于此功能构建,提供同步分布式训练作为任何 PyTorch 模型的包装器。 这与 Multiprocessing 包 - torch.multiprocessing 和 torch.nn.DataParallel() 提供的并行不同,因为它支持多个网络连接的机器,并且用户必须为每个机器显式启动主训练脚本的单独副本进程。 在单机同步情况下,torch.distributed 或 torch.nn.parallel.DistributedDataParallel() 包装器可能仍然比其他数据并行方法(包括 torch.nn.DataParallel())具有优势: - 每个进程都维护自己的优化器,并在每次迭代时执行完整的优化步骤。 虽然这可能看起来多余,但由于梯度已经被收集在一起并在进程之间求平均值,因此对于每个进程都是相同的,这意味着不需要参数广播步骤,从而减少了在节点之间传输张量所花费的时间。 - 每个进程都包含一个独立的 Python 解释器,消除了从单个 Python 进程驱动多个执行线程、模型副本或 GPU 带来的额外解释器开销和“GIL 颠簸”(GIL-thrashing)。 这对于大量使用 Python 运行时的模型尤其重要,包括具有循环层或许多小组件的模型。 ================================================ FILE: llm-train/pytorch/distribution/多机多卡.md ================================================ 走 IB 需安装: ``` yum install libibverbs ``` --- ## 2机8卡 ``` sudo docker run -it --rm --gpus all --network=host \ --shm-size 4G \ -e NCCL_IB_DISABLE=0 \ -e NCCL_SOCKET_IFNAME="bond0" \ -e NCCL_DEBUG=INFO \ -v /data/hpc/home/guodong.li:/workspaces \ -w /workspaces/code \ aiharbor.local/base/pytorch-alpaca:v4-h800-ib \ torchrun --nproc_per_node=4 --nnodes=2 --node_rank=0 --master_addr=10.xx.64.12 --master_port=29501 train.py \ --model_name_or_path /workspaces/model/llama-7b-hf \ --data_path /workspaces/data/alpaca_data_cleaned.json \ --output_dir /workspaces/output \ --bf16 True \ --max_steps 200 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'LlamaDecoderLayer' \ --tf32 True sudo docker run -it --rm --gpus all --network=host \ --shm-size 4G \ -e NCCL_IB_DISABLE=0 \ -e NCCL_SOCKET_IFNAME="bond0" \ -e NCCL_DEBUG=INFO \ -v /data/hpc/home/guodong.li:/workspaces \ -w /workspaces/code \ aiharbor.local/base/pytorch-alpaca:v4-h800-ib \ torchrun --nproc_per_node=4 --nnodes=2 --node_rank=1 --master_addr=10.xx.64.12 --master_port=29501 train.py \ --model_name_or_path /workspaces/model/llama-7b-hf \ --data_path /workspaces/data/alpaca_data_cleaned.json \ --output_dir /workspaces/output \ --bf16 True \ --max_steps 200 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'LlamaDecoderLayer' \ --tf32 True ``` ================================================ FILE: llm-train/pytorch/distribution/多机训练.md ================================================ - https://pytorch.org/tutorials/intermediate/ddp_series_multinode.html 多节点训练涉及在多台机器上部署训练作业。 有两种方法可以做到这一点: - 在每台机器上使用相同的rendezvous参数运行 torchrun 命令 - 使用工作负载管理器(如:SLURM)将其部署在计算集群上 在本视频中,我们将介绍从单节点多 GPU 迁移到多节点训练所需的(最小)代码更改,并以上述两种方式运行我们的训练脚本。 请注意,多节点训练受到节点间通信延迟的瓶颈。在单个节点上的 4 个 GPU 上运行训练作业比在 4 个节点(每个节点有 1 个 GPU)上运行训练作业要快。 ## Local 和 Global ranks 在单节点设置中,我们跟踪运行训练过程的每个设备的 gpu_id。 torchrun 在环境变量 LOCAL_RANK 中跟踪该值,该变量 唯一标识节点上的每个 GPU 进程。 对于所有节点上的唯一标识符,torchrun 提供了另一个变量 RANK,它指的是进程的全局排名(ranks)。 警告 不要将 RANK 用于训练工作中的关键逻辑。 当 torchrun 在失败或成员数更改后重新启动进程时,无法保证进程将保持相同的 LOCAL_RANK 和 RANKS。 ## 异构扩展 Torchrun 支持异构扩展,即每台多节点机器可以有不同数量的 GPU 参与训练作业。 在视频中,我将代码部署在 2 台机器上,其中一台机器有 4 个 GPU,另一台机器仅使用 2 个 GPU。 ## 故障排除 确保您的节点能够通过 TCP 相互通信。 将环境变量 NCCL_DEBUG 设置为 INFO(使用导出 NCCL_DEBUG=INFO)以打印有助于诊断问题的详细日志。 有时您可能需要显式设置分布式后端。参考:https://pytorch.org/docs/stable/distributed.html#choosing-the-network-interface-to-use ================================================ FILE: llm-train/pytorch/resource.md ================================================ --- - PyTorch工程的最佳实践:https://zhuanlan.zhihu.com/p/371978706 框架不统一的问题: 代码评审方面,无法有效提高代码评审效率; 代码复用方面,根本无法复用; 项目交接方面,问题逐渐呈现; 模型部署方面,一言难尽; 经验复用方面,想都别想; 以及人员备份、性能调试、客户技术支持等。 流水线环节: 数据集 数据增强 模型搭建和裁剪 损失函数 超参和训练 移植和部署 --- ================================================ FILE: llm-train/pytorch/torchrun.md ================================================ - https://pytorch.org/docs/stable/elastic/run.html # torchrun ## 环境变量 ``` ``` ================================================ FILE: llm-train/qlora/README.md ================================================ # qlora - 源码地址:https://github.com/artidoro/qlora - commit id:cc488110b5ea23594a418daca7085000a9420625 ## LLaMA 65B 微调 ### 单GPU ``` CUDA_VISIBLE_DEVICES=0 python qlora.py \ --model_name_or_path /data/nfs/guodong.li/pretrain/hf-llama-model/llama-65b \ --dataset /data/nfs/guodong.li/data/alpaca_data_cleaned.json \ --output_dir /home/guodong.li/output/llama-65b-qlora \ --logging_steps 10 \ --save_strategy steps \ --data_seed 42 \ --save_steps 100 \ --save_total_limit 2 \ --evaluation_strategy steps \ --eval_dataset_size 128 \ --max_eval_samples 200 \ --per_device_eval_batch_size 1 \ --max_new_tokens 32 \ --dataloader_num_workers 3 \ --group_by_length \ --logging_strategy steps \ --remove_unused_columns False \ --do_train \ --do_eval \ --do_mmlu_eval \ --lora_r 64 \ --lora_alpha 16 \ --lora_modules all \ --double_quant \ --quant_type nf4 \ --bf16 \ --bits 4 \ --warmup_ratio 0.03 \ --lr_scheduler_type constant \ --gradient_checkpointing \ --source_max_len 16 \ --target_max_len 512 \ --per_device_train_batch_size 1 \ --gradient_accumulation_steps 16 \ --max_steps 200 \ --eval_steps 50 \ --learning_rate 0.0001 \ --adam_beta2 0.999 \ --max_grad_norm 0.3 \ --lora_dropout 0.05 \ --weight_decay 0.0 \ --seed 0 \ --report_to tensorboard ``` ### 多GPU ``` python qlora.py \ --model_name_or_path /data/nfs/guodong.li/pretrain/hf-llama-model/llama-65b \ --dataset /data/nfs/guodong.li/data/alpaca_data_cleaned.json \ --output_dir /home/guodong.li/output/llama-65b-qlora \ --logging_steps 10 \ --save_strategy steps \ --data_seed 42 \ --save_steps 100 \ --save_total_limit 2 \ --evaluation_strategy steps \ --eval_dataset_size 128 \ --max_eval_samples 200 \ --per_device_eval_batch_size 1 \ --max_new_tokens 32 \ --dataloader_num_workers 3 \ --group_by_length \ --logging_strategy steps \ --remove_unused_columns False \ --do_train \ --do_eval \ --do_mmlu_eval \ --lora_r 64 \ --lora_alpha 16 \ --lora_modules all \ --double_quant \ --quant_type nf4 \ --bf16 \ --bits 4 \ --warmup_ratio 0.03 \ --lr_scheduler_type constant \ --gradient_checkpointing \ --source_max_len 16 \ --target_max_len 512 \ --per_device_train_batch_size 1 \ --gradient_accumulation_steps 16 \ --max_steps 200 \ --eval_steps 50 \ --learning_rate 0.0001 \ --adam_beta2 0.999 \ --max_grad_norm 0.3 \ --lora_dropout 0.05 \ --weight_decay 0.0 \ --seed 0 \ --report_to tensorboard ``` ================================================ FILE: llm-train/qlora/accuracy.py ================================================ # Copyright 2020 The HuggingFace Datasets Authors and the current dataset script contributor. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Accuracy metric.""" import datasets from sklearn.metrics import accuracy_score import evaluate _DESCRIPTION = """ Accuracy is the proportion of correct predictions among the total number of cases processed. It can be computed with: Accuracy = (TP + TN) / (TP + TN + FP + FN) Where: TP: True positive TN: True negative FP: False positive FN: False negative """ _KWARGS_DESCRIPTION = """ Args: predictions (`list` of `int`): Predicted labels. references (`list` of `int`): Ground truth labels. normalize (`boolean`): If set to False, returns the number of correctly classified samples. Otherwise, returns the fraction of correctly classified samples. Defaults to True. sample_weight (`list` of `float`): Sample weights Defaults to None. Returns: accuracy (`float` or `int`): Accuracy score. Minimum possible value is 0. Maximum possible value is 1.0, or the number of examples input, if `normalize` is set to `True`.. A higher score means higher accuracy. Examples: Example 1-A simple example >>> accuracy_metric = evaluate.load("accuracy") >>> results = accuracy_metric.compute(references=[0, 1, 2, 0, 1, 2], predictions=[0, 1, 1, 2, 1, 0]) >>> print(results) {'accuracy': 0.5} Example 2-The same as Example 1, except with `normalize` set to `False`. >>> accuracy_metric = evaluate.load("accuracy") >>> results = accuracy_metric.compute(references=[0, 1, 2, 0, 1, 2], predictions=[0, 1, 1, 2, 1, 0], normalize=False) >>> print(results) {'accuracy': 3.0} Example 3-The same as Example 1, except with `sample_weight` set. >>> accuracy_metric = evaluate.load("accuracy") >>> results = accuracy_metric.compute(references=[0, 1, 2, 0, 1, 2], predictions=[0, 1, 1, 2, 1, 0], sample_weight=[0.5, 2, 0.7, 0.5, 9, 0.4]) >>> print(results) {'accuracy': 0.8778625954198473} """ _CITATION = """ @article{scikit-learn, title={Scikit-learn: Machine Learning in {P}ython}, author={Pedregosa, F. and Varoquaux, G. and Gramfort, A. and Michel, V. and Thirion, B. and Grisel, O. and Blondel, M. and Prettenhofer, P. and Weiss, R. and Dubourg, V. and Vanderplas, J. and Passos, A. and Cournapeau, D. and Brucher, M. and Perrot, M. and Duchesnay, E.}, journal={Journal of Machine Learning Research}, volume={12}, pages={2825--2830}, year={2011} } """ @evaluate.utils.file_utils.add_start_docstrings(_DESCRIPTION, _KWARGS_DESCRIPTION) class Accuracy(evaluate.Metric): def _info(self): return evaluate.MetricInfo( description=_DESCRIPTION, citation=_CITATION, inputs_description=_KWARGS_DESCRIPTION, features=datasets.Features( { "predictions": datasets.Sequence(datasets.Value("int32")), "references": datasets.Sequence(datasets.Value("int32")), } if self.config_name == "multilabel" else { "predictions": datasets.Value("int32"), "references": datasets.Value("int32"), } ), reference_urls=["https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html"], ) def _compute(self, predictions, references, normalize=True, sample_weight=None): return { "accuracy": float( accuracy_score(references, predictions, normalize=normalize, sample_weight=sample_weight) ) } ================================================ FILE: llm-train/qlora/export_hf_checkpoint.py ================================================ import os import torch import transformers from peft import PeftModel from transformers import LlamaForCausalLM, LlamaTokenizer # noqa: F402 BASE_MODEL = os.environ.get("BASE_MODEL", None) LORA_MODEL = os.environ.get("LORA_MODEL", "tloen/alpaca-lora-7b") HF_CHECKPOINT = os.environ.get("HF_CHECKPOINT", "./hf_ckpt") assert ( BASE_MODEL ), "Please specify a value for BASE_MODEL environment variable, e.g. `export BASE_MODEL=decapoda-research/llama-7b-hf`" # noqa: E501 tokenizer = LlamaTokenizer.from_pretrained(BASE_MODEL) base_model = LlamaForCausalLM.from_pretrained( BASE_MODEL, #load_in_8bit=False, torch_dtype=torch.bfloat16, device_map={"": "cpu"}, ) first_weight = base_model.model.layers[0].self_attn.q_proj.weight first_weight_old = first_weight.clone() lora_model = PeftModel.from_pretrained( base_model, # TODO # "tloen/alpaca-lora-7b", LORA_MODEL, #device_map={"": "cpu"}, #torch_dtype=torch.float16, ) lora_weight = lora_model.base_model.model.model.layers[ 0 ].self_attn.q_proj.weight assert torch.allclose(first_weight_old, first_weight) # merge weights for layer in lora_model.base_model.model.model.layers: layer.self_attn.q_proj.merge_weights = True layer.self_attn.v_proj.merge_weights = True lora_model.train(False) # did we do anything? #assert not torch.allclose(first_weight_old, first_weight) lora_model_sd = lora_model.state_dict() deloreanized_sd = { k.replace("base_model.model.", ""): v for k, v in lora_model_sd.items() if "lora" not in k } LlamaForCausalLM.save_pretrained( base_model, HF_CHECKPOINT , state_dict=deloreanized_sd, max_shard_size="400MB" ) ================================================ FILE: llm-train/qlora/inference.py ================================================ from transformers import AutoModelForCausalLM, LlamaTokenizer import torch model_id = "/data/nfs/guodong.li/pretrain/hf-llama-model/llama-7b" merge_model_id = "/home/guodong.li/output/llama-7b-merge" #model = AutoModelForCausalLM.from_pretrained(model_id, load_in_4bit=True) model = AutoModelForCausalLM.from_pretrained(merge_model_id, load_in_4bit=True, device_map="auto") tokenizer = LlamaTokenizer.from_pretrained(model_id) #print(model) device = torch.device("cuda:0") #model = model.to(device) text = "Hello, my name is " inputs = tokenizer(text, return_tensors="pt").to(device) outputs = model.generate(**inputs, max_new_tokens=20, do_sample=True, top_k=30, top_p=0.85) print(tokenizer.decode(outputs[0], skip_special_tokens=True)) print("\n------------------------------------------------\nInput: ") line = input() while line: inputs = tokenizer(line, return_tensors="pt").to(device) outputs = model.generate(**inputs, max_new_tokens=20, do_sample=True, top_k=30, top_p=0.85) print("Output: ",tokenizer.decode(outputs[0], skip_special_tokens=True)) print("\n------------------------------------------------\nInput: ") line = input() ================================================ FILE: llm-train/qlora/inference_merge.py ================================================ from transformers import AutoModelForCausalLM, LlamaTokenizer import torch from peft import PeftModel model_id = "/data/nfs/guodong.li/pretrain/hf-llama-model/llama-7b" lora_weights = "/home/guodong.li/output/llama-7b-qlora/checkpoint-1000/adapter_model" #model = AutoModelForCausalLM.from_pretrained(model_id, load_in_4bit=True) model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.bfloat16, device_map="auto") model = PeftModel.from_pretrained( model, lora_weights, ) model = model.merge_and_unload() tokenizer = LlamaTokenizer.from_pretrained(model_id) #print(model) device = torch.device("cuda:0") #model = model.to(device) text = "Hello, my name is " inputs = tokenizer(text, return_tensors="pt").to(device) outputs = model.generate(**inputs, max_new_tokens=20, do_sample=True, top_k=30, top_p=0.85) print(tokenizer.decode(outputs[0], skip_special_tokens=True)) print("\n------------------------------------------------\nInput: ") line = input() while line: inputs = tokenizer(line, return_tensors="pt").to(device) outputs = model.generate(**inputs, max_new_tokens=20, do_sample=True, top_k=30, top_p=0.85) print("Output: ",tokenizer.decode(outputs[0], skip_special_tokens=True)) print("\n------------------------------------------------\nInput: ") line = input() ================================================ FILE: llm-train/qlora/inference_qlora.py ================================================ import torch from peft import PeftModel model_id = "/data/nfs/guodong.li/pretrain/hf-llama-model/llama-7b" lora_weights = "/home/guodong.li/output/llama-7b-qlora/checkpoint-1000/adapter_model" #model = AutoModelForCausalLM.from_pretrained(model_id, load_in_4bit=True) model = AutoModelForCausalLM.from_pretrained(model_id, load_in_4bit=True, device_map="auto") model = PeftModel.from_pretrained( model, lora_weights, ) tokenizer = LlamaTokenizer.from_pretrained(model_id) #print(model) device = torch.device("cuda:0") #model = model.to(device) text = "Hello, my name is " inputs = tokenizer(text, return_tensors="pt").to(device) outputs = model.generate(**inputs, max_new_tokens=20, do_sample=True, top_k=30, top_p=0.85) print(tokenizer.decode(outputs[0], skip_special_tokens=True)) print("\n------------------------------------------------\nInput: ") line = input() while line: inputs = tokenizer(line, return_tensors="pt").to(device) outputs = model.generate(**inputs, max_new_tokens=20, do_sample=True, top_k=30, top_p=0.85) print("Output: ",tokenizer.decode(outputs[0], skip_special_tokens=True)) print("\n------------------------------------------------\nInput: ") line = input() ================================================ FILE: llm-train/qlora/qlora.py ================================================ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from collections import defaultdict import copy import json import os from os.path import exists, join, isdir from dataclasses import dataclass, field import sys from typing import Optional, Dict, Sequence import numpy as np from tqdm import tqdm import logging import bitsandbytes as bnb import pandas as pd import torch import transformers from torch.nn.utils.rnn import pad_sequence import argparse from transformers import ( AutoTokenizer, AutoModelForCausalLM, set_seed, Seq2SeqTrainer, BitsAndBytesConfig, LlamaTokenizer ) from datasets import load_dataset, Dataset import evaluate from peft import ( prepare_model_for_kbit_training, LoraConfig, get_peft_model, PeftModel ) from peft.tuners.lora import LoraLayer from transformers.trainer_utils import PREFIX_CHECKPOINT_DIR torch.backends.cuda.matmul.allow_tf32 = True logger = logging.getLogger(__name__) IGNORE_INDEX = -100 DEFAULT_PAD_TOKEN = "[PAD]" @dataclass class ModelArguments: model_name_or_path: Optional[str] = field( default="EleutherAI/pythia-12b" ) trust_remote_code: Optional[bool] = field( default=False, metadata={"help": "Enable unpickling of arbitrary code in AutoModelForCausalLM#from_pretrained."} ) use_auth_token: Optional[bool] = field( default=False, metadata={"help": "Enables using Huggingface auth token from Git Credentials."} ) @dataclass class DataArguments: eval_dataset_size: int = field( default=1024, metadata={"help": "Size of validation dataset."} ) max_train_samples: Optional[int] = field( default=None, metadata={ "help": "For debugging purposes or quicker training, truncate the number of training examples to this " "value if set." }, ) max_eval_samples: Optional[int] = field( default=None, metadata={ "help": "For debugging purposes or quicker training, truncate the number of evaluation examples to this " "value if set." }, ) source_max_len: int = field( default=1024, metadata={"help": "Maximum source sequence length. Sequences will be right padded (and possibly truncated)."}, ) target_max_len: int = field( default=256, metadata={"help": "Maximum target sequence length. Sequences will be right padded (and possibly truncated)."}, ) dataset: str = field( default='alpaca', metadata={"help": "Which dataset to finetune on. See datamodule for options."} ) dataset_format: Optional[str] = field( default=None, metadata={"help": "Which dataset format is used. [alpaca|chip2|self-instruct|hh-rlhf]"} ) @dataclass class TrainingArguments(transformers.Seq2SeqTrainingArguments): cache_dir: Optional[str] = field( default=None ) train_on_source: Optional[bool] = field( default=False, metadata={"help": "Whether to train on the input in addition to the target text."} ) mmlu_split: Optional[str] = field( default='eval', metadata={"help": "The MMLU split to run on"} ) mmlu_dataset: Optional[str] = field( default='mmlu-fs', metadata={"help": "MMLU dataset to use: options are `mmlu-zs` for zero-shot or `mmlu-fs` for few shot."} ) do_mmlu_eval: Optional[bool] = field( default=False, metadata={"help": "Whether to run the MMLU evaluation."} ) max_mmlu_samples: Optional[int] = field( default=None, metadata={"help": "If set, only evaluates on `max_mmlu_samples` of the MMMLU dataset."} ) mmlu_source_max_len: int = field( default=2048, metadata={"help": "Maximum source sequence length for mmlu."} ) full_finetune: bool = field( default=False, metadata={"help": "Finetune the entire model without adapters."} ) adam8bit: bool = field( default=False, metadata={"help": "Use 8-bit adam."} ) double_quant: bool = field( default=True, metadata={"help": "Compress the quantization statistics through double quantization."} ) quant_type: str = field( default="nf4", metadata={"help": "Quantization data type to use. Should be one of `fp4` or `nf4`."} ) bits: int = field( default=4, metadata={"help": "How many bits to use."} ) lora_r: int = field( default=64, metadata={"help": "Lora R dimension."} ) lora_alpha: float = field( default=16, metadata={"help": " Lora alpha."} ) lora_dropout: float = field( default=0.0, metadata={"help":"Lora dropout."} ) max_memory_MB: int = field( default=80000, metadata={"help": "Free memory per gpu."} ) report_to: str = field( default='none', metadata={"help": "To use wandb or something else for reporting."} ) output_dir: str = field(default='./output', metadata={"help": 'The output dir for logs and checkpoints'}) optim: str = field(default='paged_adamw_32bit', metadata={"help": 'The optimizer to be used'}) per_device_train_batch_size: int = field(default=1, metadata={"help": 'The training batch size per GPU. Increase for better speed.'}) gradient_accumulation_steps: int = field(default=16, metadata={"help": 'How many gradients to accumulate before to perform an optimizer step'}) max_steps: int = field(default=10000, metadata={"help": 'How many optimizer update steps to take'}) weight_decay: float = field(default=0.0, metadata={"help": 'The L2 weight decay rate of AdamW'}) # use lora dropout instead for regularization if needed learning_rate: float = field(default=0.0002, metadata={"help": 'The learnign rate'}) remove_unused_columns: bool = field(default=False, metadata={"help": 'Removed unused columns. Needed to make this codebase work.'}) max_grad_norm: float = field(default=0.3, metadata={"help": 'Gradient clipping max norm. This is tuned and works well for all models tested.'}) gradient_checkpointing: bool = field(default=True, metadata={"help": 'Use gradient checkpointing. You want to use this.'}) do_train: bool = field(default=True, metadata={"help": 'To train or not to train, that is the question?'}) lr_scheduler_type: str = field(default='constant', metadata={"help": 'Learning rate schedule. Constant a bit better than cosine, and has advantage for analysis'}) warmup_ratio: float = field(default=0.03, metadata={"help": 'Fraction of steps to do a warmup for'}) logging_steps: int = field(default=10, metadata={"help": 'The frequency of update steps after which to log the loss'}) group_by_length: bool = field(default=True, metadata={"help": 'Group sequences into batches with same length. Saves memory and speeds up training considerably.'}) save_strategy: str = field(default='steps', metadata={"help": 'When to save checkpoints'}) save_steps: int = field(default=250, metadata={"help": 'How often to save a model'}) save_total_limit: int = field(default=40, metadata={"help": 'How many checkpoints to save before the oldest is overwritten'}) @dataclass class GenerationArguments: # For more hyperparameters check: # https://huggingface.co/docs/transformers/main_classes/text_generation#transformers.GenerationConfig # Length arguments max_new_tokens: Optional[int] = field( default=256, metadata={"help": "Maximum number of new tokens to be generated in evaluation or prediction loops" "if predict_with_generate is set."} ) min_new_tokens : Optional[int] = field( default=None, metadata={"help": "Minimum number of new tokens to generate."} ) # Generation strategy do_sample: Optional[bool] = field(default=False) num_beams: Optional[int] = field(default=1) num_beam_groups: Optional[int] = field(default=1) penalty_alpha: Optional[float] = field(default=None) use_cache: Optional[bool] = field(default=True) # Hyperparameters for logit manipulation temperature: Optional[float] = field(default=1.0) top_k: Optional[int] = field(default=50) top_p: Optional[float] = field(default=1.0) typical_p: Optional[float] = field(default=1.0) diversity_penalty: Optional[float] = field(default=0.0) repetition_penalty: Optional[float] = field(default=1.0) length_penalty: Optional[float] = field(default=1.0) no_repeat_ngram_size: Optional[int] = field(default=0) def find_all_linear_names(args, model): cls = bnb.nn.Linear4bit if args.bits == 4 else (bnb.nn.Linear8bitLt if args.bits == 8 else torch.nn.Linear) lora_module_names = set() for name, module in model.named_modules(): if isinstance(module, cls): names = name.split('.') lora_module_names.add(names[0] if len(names) == 1 else names[-1]) if 'lm_head' in lora_module_names: # needed for 16-bit lora_module_names.remove('lm_head') return list(lora_module_names) class SavePeftModelCallback(transformers.TrainerCallback): def save_model(self, args, state, kwargs): print('Saving PEFT checkpoint...') if state.best_model_checkpoint is not None: checkpoint_folder = os.path.join(state.best_model_checkpoint, "adapter_model") else: checkpoint_folder = os.path.join(args.output_dir, f"{PREFIX_CHECKPOINT_DIR}-{state.global_step}") peft_model_path = os.path.join(checkpoint_folder, "adapter_model") kwargs["model"].save_pretrained(peft_model_path) pytorch_model_path = os.path.join(checkpoint_folder, "pytorch_model.bin") if os.path.exists(pytorch_model_path): os.remove(pytorch_model_path) def on_save(self, args, state, control, **kwargs): self.save_model(args, state, kwargs) return control def on_train_end(self, args, state, control, **kwargs): def touch(fname, times=None): with open(fname, 'a'): os.utime(fname, times) touch(join(args.output_dir, 'completed')) self.save_model(args, state, kwargs) def get_accelerate_model(args, checkpoint_dir): n_gpus = torch.cuda.device_count() max_memory = f'{args.max_memory_MB}MB' max_memory = {i: max_memory for i in range(n_gpus)} device_map = "auto" # if we are in a distributed setting, we need to set the device map and max memory per device if os.environ.get('LOCAL_RANK') is not None: local_rank = int(os.environ.get('LOCAL_RANK', '0')) device_map = {'': local_rank} max_memory = {'': max_memory[local_rank]} if args.full_finetune: assert args.bits in [16, 32] print(f'loading base model {args.model_name_or_path}...') compute_dtype = (torch.float16 if args.fp16 else (torch.bfloat16 if args.bf16 else torch.float32)) model = AutoModelForCausalLM.from_pretrained( args.model_name_or_path, cache_dir=args.cache_dir, load_in_4bit=args.bits == 4, load_in_8bit=args.bits == 8, device_map=device_map, max_memory=max_memory, quantization_config=BitsAndBytesConfig( load_in_4bit=args.bits == 4, load_in_8bit=args.bits == 8, llm_int8_threshold=6.0, llm_int8_has_fp16_weight=False, bnb_4bit_compute_dtype=compute_dtype, bnb_4bit_use_double_quant=args.double_quant, bnb_4bit_quant_type=args.quant_type, ), torch_dtype=(torch.float32 if args.fp16 else (torch.bfloat16 if args.bf16 else torch.float32)), trust_remote_code=args.trust_remote_code, use_auth_token=args.use_auth_token ) if compute_dtype == torch.float16 and args.bits == 4: major, minor = torch.cuda.get_device_capability() if major >= 8: print('='*80) print('Your GPU supports bfloat16, you can accelerate training with the argument --bf16') print('='*80) setattr(model, 'model_parallel', True) setattr(model, 'is_parallelizable', True) model.config.torch_dtype=(torch.float32 if args.fp16 else (torch.bfloat16 if args.bf16 else torch.float32)) if not args.full_finetune: model = prepare_model_for_kbit_training(model, use_gradient_checkpointing=args.gradient_checkpointing) if args.gradient_checkpointing: model.gradient_checkpointing_enable() if not args.full_finetune: if checkpoint_dir is not None: print("Loading adapters from checkpoint.") model = PeftModel.from_pretrained(model, join(checkpoint_dir, 'adapter_model'), is_trainable=True) else: print(f'adding LoRA modules...') modules = find_all_linear_names(args, model) config = LoraConfig( r=args.lora_r, lora_alpha=args.lora_alpha, target_modules=modules, lora_dropout=args.lora_dropout, bias="none", task_type="CAUSAL_LM", ) model = get_peft_model(model, config) for name, module in model.named_modules(): if isinstance(module, LoraLayer): if args.bf16: module = module.to(torch.bfloat16) if 'norm' in name: module = module.to(torch.float32) if 'lm_head' in name or 'embed_tokens' in name: if hasattr(module, 'weight'): if args.bf16 and module.weight.dtype == torch.float32: module = module.to(torch.bfloat16) return model def print_trainable_parameters(args, model): """ Prints the number of trainable parameters in the model. """ trainable_params = 0 all_param = 0 for _, param in model.named_parameters(): all_param += param.numel() if param.requires_grad: trainable_params += param.numel() if args.bits == 4: trainable_params /= 2 print( f"trainable params: {trainable_params} || " f"all params: {all_param} || " f"trainable: {100 * trainable_params / all_param}" ) def smart_tokenizer_and_embedding_resize( special_tokens_dict: Dict, tokenizer: transformers.PreTrainedTokenizer, model: transformers.PreTrainedModel, ): """Resize tokenizer and embedding. Note: This is the unoptimized version that may make your embedding size not be divisible by 64. """ num_new_tokens = tokenizer.add_special_tokens(special_tokens_dict) model.resize_token_embeddings(len(tokenizer)) if num_new_tokens > 0: input_embeddings = model.get_input_embeddings().weight.data output_embeddings = model.get_output_embeddings().weight.data input_embeddings_avg = input_embeddings[:-num_new_tokens].mean(dim=0, keepdim=True) output_embeddings_avg = output_embeddings[:-num_new_tokens].mean(dim=0, keepdim=True) input_embeddings[-num_new_tokens:] = input_embeddings_avg output_embeddings[-num_new_tokens:] = output_embeddings_avg @dataclass class DataCollatorForCausalLM(object): tokenizer: transformers.PreTrainedTokenizer source_max_len: int target_max_len: int train_on_source: bool predict_with_generate: bool def __call__(self, instances: Sequence[Dict]) -> Dict[str, torch.Tensor]: # Extract elements sources = [f"{self.tokenizer.bos_token}{example['input']}" for example in instances] targets = [f"{example['output']}{self.tokenizer.eos_token}" for example in instances] # Tokenize tokenized_sources_with_prompt = self.tokenizer( sources, max_length=self.source_max_len, truncation=True, add_special_tokens=False, ) tokenized_targets = self.tokenizer( targets, max_length=self.target_max_len, truncation=True, add_special_tokens=False, ) # Build the input and labels for causal LM input_ids = [] labels = [] for tokenized_source, tokenized_target in zip( tokenized_sources_with_prompt['input_ids'], tokenized_targets['input_ids'] ): if not self.predict_with_generate: input_ids.append(torch.tensor(tokenized_source + tokenized_target)) if not self.train_on_source: labels.append( torch.tensor([IGNORE_INDEX for _ in range(len(tokenized_source))] + copy.deepcopy(tokenized_target)) ) else: labels.append(torch.tensor(copy.deepcopy(tokenized_source + tokenized_target))) else: input_ids.append(torch.tensor(tokenized_source)) # Apply padding input_ids = pad_sequence(input_ids, batch_first=True, padding_value=self.tokenizer.pad_token_id) labels = pad_sequence(labels, batch_first=True, padding_value=IGNORE_INDEX) if not self.predict_with_generate else None data_dict = { 'input_ids': input_ids, 'attention_mask':input_ids.ne(self.tokenizer.pad_token_id), } if labels is not None: data_dict['labels'] = labels return data_dict def extract_unnatural_instructions_data(examples, extract_reformulations=False): out = { 'input': [], 'output': [], } for example_instances in examples['instances']: for instance in example_instances: out['input'].append(instance['instruction_with_input']) out['output'].append(instance['output']) if extract_reformulations: for example_reformulations in examples['reformulations']: if example_reformulations is not None: for instance in example_reformulations: out['input'].append(instance['instruction_with_input']) out['output'].append(instance['output']) return out ALPACA_PROMPT_DICT = { "prompt_input": ( "Below is an instruction that describes a task, paired with an input that provides further context. " "Write a response that appropriately completes the request.\n\n" "### Instruction:\n{instruction}\n\n### Input:\n{input}\n\n### Response: " ), "prompt_no_input": ( "Below is an instruction that describes a task. " "Write a response that appropriately completes the request.\n\n" "### Instruction:\n{instruction}\n\n### Response: " ), } def extract_alpaca_dataset(example): if example.get("input", "") != "": prompt_format = ALPACA_PROMPT_DICT["prompt_input"] else: prompt_format = ALPACA_PROMPT_DICT["prompt_no_input"] return {'input': prompt_format.format(**example)} def local_dataset(dataset_name): if dataset_name.endswith('.json'): full_dataset = Dataset.from_json(path_or_paths=dataset_name) elif dataset_name.endswith('.jsonl'): full_dataset = Dataset.from_json(filename=dataset_name, format='jsonlines') elif dataset_name.endswith('.csv'): full_dataset = Dataset.from_pandas(pd.read_csv(dataset_name)) elif dataset_name.endswith('.tsv'): full_dataset = Dataset.from_pandas(pd.read_csv(dataset_name, delimiter='\t')) else: raise ValueError(f"Unsupported dataset format: {dataset_name}") split_dataset = full_dataset.train_test_split(test_size=0.1) return split_dataset def make_data_module(tokenizer: transformers.PreTrainedTokenizer, args) -> Dict: """ Make dataset and collator for supervised fine-tuning. Datasets are expected to have the following columns: { `input`, `output` } Available datasets to be selected with `dataset` argument: - alpaca, 52002 examples - alpaca cleaned, 51942 examples - chip2 (OIG), 210289 examples - self-instruct, 82612 examples - hh-rlhf (Anthropic), 160800 examples - longform, 23.7k examples - oasst1 (OpenAssistant) primary message tree only, 9,846 examples Coming soon: - unnatural instructions core, 66010 examples - unnatural instructions full, 240670 examples - alpaca-gpt4, 52002 examples - unnatural-instructions-gpt4, 9000 examples - supernatural-instructions, 69624 examples (same as paper with 100 ex/task more can be used) - flan (FLAN v2), up to 20M examples available - vicuna """ def load_data(dataset_name): if dataset_name == 'alpaca': # TODO #return load_dataset("tatsu-lab/alpaca") from datasets import Dataset return Dataset.from_file("/home/guodong.li/data/parquet-train.arrow") elif dataset_name == 'alpaca-clean': return load_dataset("yahma/alpaca-cleaned") elif dataset_name == 'chip2': return load_dataset("laion/OIG", data_files='unified_chip2.jsonl') elif dataset_name == 'self-instruct': return load_dataset("yizhongw/self_instruct", name='self_instruct') elif dataset_name == 'hh-rlhf': return load_dataset("Anthropic/hh-rlhf") elif dataset_name == 'longform': return load_dataset("akoksal/LongForm") elif dataset_name == 'oasst1': return load_dataset("timdettmers/openassistant-guanaco") elif dataset_name == 'vicuna': raise NotImplementedError("Vicuna data was not released.") else: if os.path.exists(dataset_name): try: args.dataset_format = args.dataset_format if args.dataset_format else "input-output" full_dataset = local_dataset(dataset_name) return full_dataset except: raise ValueError(f"Error loading dataset from {dataset_name}") else: raise NotImplementedError(f"Dataset {dataset_name} not implemented yet.") def format_dataset(dataset, dataset_format): if ( dataset_format == 'alpaca' or dataset_format == 'alpaca-clean' or (dataset_format is None and args.dataset in ['alpaca', 'alpaca-clean']) ): dataset = dataset.map(extract_alpaca_dataset, remove_columns=['instruction']) elif dataset_format == 'chip2' or (dataset_format is None and args.dataset == 'chip2'): dataset = dataset.map(lambda x: { 'input': x['text'].split('\n: ')[0].replace(': ', ''), 'output': x['text'].split('\n: ')[1], }) elif dataset_format == 'self-instruct' or (dataset_format is None and args.dataset == 'self-instruct'): for old, new in [["prompt", "input"], ["completion", "output"]]: dataset = dataset.rename_column(old, new) elif dataset_format == 'hh-rlhf' or (dataset_format is None and args.dataset == 'hh-rlhf'): dataset = dataset.map(lambda x: { 'input': '', 'output': x['chosen'] }) elif dataset_format == 'oasst1' or (dataset_format is None and args.dataset == 'oasst1'): dataset = dataset.map(lambda x: { 'input': '', 'output': x['text'], }) elif dataset_format == 'input-output': # leave as is pass # Remove unused columns. dataset = dataset.remove_columns( [col for col in dataset.column_names['train'] if col not in ['input', 'output']] ) return dataset # Load dataset. dataset = load_data(args.dataset) dataset = format_dataset(dataset, args.dataset_format) # Split train/eval, reduce size if args.do_eval or args.do_predict: if 'eval' in dataset: eval_dataset = dataset['eval'] else: print('Splitting train dataset in train and validation according to `eval_dataset_size`') dataset = dataset["train"].train_test_split( test_size=args.eval_dataset_size, shuffle=True, seed=42 ) eval_dataset = dataset['test'] if args.max_eval_samples is not None and len(eval_dataset) > args.max_eval_samples: eval_dataset = eval_dataset.select(range(args.max_eval_samples)) if args.group_by_length: eval_dataset = eval_dataset.map(lambda x: {'length': len(x['input']) + len(x['output'])}) if args.do_train: train_dataset = dataset['train'] if args.max_train_samples is not None and len(train_dataset) > args.max_train_samples: train_dataset = train_dataset.select(range(args.max_train_samples)) if args.group_by_length: train_dataset = train_dataset.map(lambda x: {'length': len(x['input']) + len(x['output'])}) data_collator = DataCollatorForCausalLM( tokenizer=tokenizer, source_max_len=args.source_max_len, target_max_len=args.target_max_len, train_on_source=args.train_on_source, predict_with_generate=args.predict_with_generate, ) return dict( train_dataset=train_dataset if args.do_train else None, eval_dataset=eval_dataset if args.do_eval else None, predict_dataset=eval_dataset if args.do_predict else None, data_collator=data_collator ) def get_last_checkpoint(checkpoint_dir): if isdir(checkpoint_dir): is_completed = exists(join(checkpoint_dir, 'completed')) if is_completed: return None, True # already finished max_step = 0 for filename in os.listdir(checkpoint_dir): if isdir(join(checkpoint_dir, filename)) and filename.startswith('checkpoint'): max_step = max(max_step, int(filename.replace('checkpoint-', ''))) if max_step == 0: return None, is_completed # training started, but no checkpoint checkpoint_dir = join(checkpoint_dir, f'checkpoint-{max_step}') print(f"Found a previous checkpoint at: {checkpoint_dir}") return checkpoint_dir, is_completed # checkpoint found! return None, False # first training def train(): hfparser = transformers.HfArgumentParser(( ModelArguments, DataArguments, TrainingArguments, GenerationArguments )) model_args, data_args, training_args, generation_args, extra_args = \ hfparser.parse_args_into_dataclasses(return_remaining_strings=True) training_args.generation_config = transformers.GenerationConfig(**vars(generation_args)) args = argparse.Namespace( **vars(model_args), **vars(data_args), **vars(training_args) ) checkpoint_dir, completed_training = get_last_checkpoint(args.output_dir) if completed_training: print('Detected that training was already completed!') model = get_accelerate_model(args, checkpoint_dir) model.config.use_cache = False print_trainable_parameters(args, model) print('loaded model') set_seed(args.seed) # Tokenizer tokenizer = AutoTokenizer.from_pretrained( args.model_name_or_path, cache_dir=args.cache_dir, padding_side="right", use_fast=False, # Fast tokenizer giving issues. tokenizer_type='llama' if 'llama' in args.model_name_or_path else None, # Needed for HF name change use_auth_token=args.use_auth_token, ) if tokenizer._pad_token is None: smart_tokenizer_and_embedding_resize( special_tokens_dict=dict(pad_token=DEFAULT_PAD_TOKEN), tokenizer=tokenizer, model=model, ) if 'llama' in args.model_name_or_path or isinstance(tokenizer, LlamaTokenizer): # LLaMA tokenizer may not have correct special tokens set. # Check and add them if missing to prevent them from being parsed into different tokens. # Note that these are present in the vocabulary. # Note also that `model.config.pad_token_id` is 0 which corresponds to `` token. print('Adding special tokens.') tokenizer.add_special_tokens({ "eos_token": tokenizer.convert_ids_to_tokens(model.config.eos_token_id), "bos_token": tokenizer.convert_ids_to_tokens(model.config.bos_token_id), "unk_token": tokenizer.convert_ids_to_tokens( model.config.pad_token_id if model.config.pad_token_id != -1 else tokenizer.pad_token_id ), }) data_module = make_data_module(tokenizer=tokenizer, args=args) trainer = Seq2SeqTrainer( model=model, tokenizer=tokenizer, args=training_args, **{k:v for k,v in data_module.items() if k != 'predict_dataset'}, ) # Callbacks if not args.full_finetune: trainer.add_callback(SavePeftModelCallback) if args.do_mmlu_eval: if args.mmlu_dataset == 'mmlu-zs': mmlu_dataset = load_dataset("json", data_files={ 'eval': 'data/mmlu/zero_shot_mmlu_val.json', 'test': 'data/mmlu/zero_shot_mmlu_test.json', }) mmlu_dataset = mmlu_dataset.remove_columns('subject') # MMLU Five-shot (Eval/Test only) elif args.mmlu_dataset == 'mmlu' or args.mmlu_dataset == 'mmlu-fs': mmlu_dataset = load_dataset("json", data_files={ 'eval': 'data/mmlu/five_shot_mmlu_val.json', 'test': 'data/mmlu/five_shot_mmlu_test.json', }) # mmlu_dataset = mmlu_dataset.remove_columns('subject') mmlu_dataset = mmlu_dataset[args.mmlu_split] if args.max_mmlu_samples is not None: mmlu_dataset = mmlu_dataset.select(range(args.max_mmlu_samples)) abcd_idx = [ tokenizer("A", add_special_tokens=False).input_ids[0], tokenizer("B", add_special_tokens=False).input_ids[0], tokenizer("C", add_special_tokens=False).input_ids[0], tokenizer("D", add_special_tokens=False).input_ids[0], ] # accuracy = evaluate.load("accuracy") accuracy = evaluate.load("/home/guodong.li/.cache/huggingface/accuracy.py") class MMLUEvalCallback(transformers.TrainerCallback): def on_evaluate(self, args, state, control, model, **kwargs): data_loader = trainer.get_eval_dataloader(mmlu_dataset) source_max_len = trainer.data_collator.source_max_len trainer.data_collator.source_max_len = args.mmlu_source_max_len trainer.model.eval() preds, refs = [], [] loss_mmlu = 0 for batch in tqdm(data_loader, total=len(data_loader)): (loss, logits, labels) = trainer.prediction_step(trainer.model,batch,prediction_loss_only=False,) # There are two tokens, the output, and eos token. for i, logit in enumerate(logits): label_non_zero_id = (batch['labels'][i] != -100).nonzero()[0][0] logit_abcd = logit[label_non_zero_id-1][abcd_idx] preds.append(torch.argmax(logit_abcd).item()) labels = labels[labels != IGNORE_INDEX].view(-1, 2)[:,0] refs += [abcd_idx.index(label) for label in labels.tolist()] loss_mmlu += loss.item() # Extract results by subject. results = {'mmlu_loss':loss_mmlu/len(data_loader)} subject = mmlu_dataset['subject'] subjects = {s:{'refs':[], 'preds':[]} for s in set(subject)} for s,p,r in zip(subject, preds, refs): subjects[s]['preds'].append(p) subjects[s]['refs'].append(r) subject_scores = [] for subject in subjects: subject_score = accuracy.compute( references=subjects[subject]['refs'], predictions=subjects[subject]['preds'] )['accuracy'] results[f'mmlu_{args.mmlu_split}_accuracy_{subject}'] = subject_score subject_scores.append(subject_score) results[f'mmlu_{args.mmlu_split}_accuracy'] = np.mean(subject_scores) trainer.log(results) trainer.data_collator.source_max_len = source_max_len trainer.add_callback(MMLUEvalCallback) # Verifying the datatypes. dtypes = {} for _, p in model.named_parameters(): dtype = p.dtype if dtype not in dtypes: dtypes[dtype] = 0 dtypes[dtype] += p.numel() total = 0 for k, v in dtypes.items(): total+= v for k, v in dtypes.items(): print(k, v, v/total) all_metrics = {"run_name": args.run_name} # Training if args.do_train: logger.info("*** Train ***") # Note: `resume_from_checkpoint` not supported for adapter checkpoints by HF. # Currently adapter checkpoint is reloaded as expected but optimizer/scheduler states are not. train_result = trainer.train() metrics = train_result.metrics trainer.log_metrics("train", metrics) trainer.save_metrics("train", metrics) trainer.save_state() all_metrics.update(metrics) # Evaluation if args.do_eval: logger.info("*** Evaluate ***") metrics = trainer.evaluate(metric_key_prefix="eval") trainer.log_metrics("eval", metrics) trainer.save_metrics("eval", metrics) all_metrics.update(metrics) # Prediction if args.do_predict: logger.info("*** Predict ***") prediction_output = trainer.predict(test_dataset=data_module['predict_dataset'],metric_key_prefix="predict") prediction_metrics = prediction_output.metrics predictions = prediction_output.predictions predictions = np.where(predictions != -100, predictions, tokenizer.pad_token_id) predictions = tokenizer.batch_decode( predictions, skip_special_tokens=True, clean_up_tokenization_spaces=True ) with open(os.path.join(args.output_dir, 'predictions.jsonl'), 'w') as fout: for i, example in enumerate(data_module['predict_dataset']): example['prediction_with_input'] = predictions[i].strip() example['prediction'] = predictions[i].replace(example['input'], '').strip() fout.write(json.dumps(example) + '\n') print(prediction_metrics) trainer.log_metrics("predict", prediction_metrics) trainer.save_metrics("predict", prediction_metrics) all_metrics.update(prediction_metrics) if (args.do_train or args.do_eval or args.do_predict): with open(os.path.join(args.output_dir, "metrics.json"), "w") as fout: fout.write(json.dumps(all_metrics)) if __name__ == "__main__": train() ================================================ FILE: llm-train/slurm/README.md ================================================ - srun文档: https://slurm.schedmd.com/srun.html - SCOW(web管理):https://github.com/PKUHPC/SCOW ## MUNGE-免密 MUNGE (MUNGE Uid 'N' Gid Emporium)是一种用于创建和验证凭证的身份验证服务。它允许进程在 一组具有公共用户和组的主机中验证另一个本地或远程进程的UID和GID。 ## pytorch ### 单机多卡 ``` ``` ### 多机多卡 (slurm+torchrun) - https://github.com/pytorch/examples/blob/main/distributed/ddp-tutorial-series/slurm/sbatch_run.sh ``` #!/bin/bash #SBATCH --job-name=multinode-example #SBATCH --nodes=4 #SBATCH --ntasks=4 #SBATCH --gpus-per-task=1 #SBATCH --cpus-per-task=4 nodes=( $( scontrol show hostnames $SLURM_JOB_NODELIST ) ) nodes_array=($nodes) head_node=${nodes_array[0]} head_node_ip=$(srun --nodes=1 --ntasks=1 -w "$head_node" hostname --ip-address) echo Node IP: $head_node_ip export LOGLEVEL=INFO srun torchrun \ --nnodes 4 \ --nproc_per_node 1 \ --rdzv_id $RANDOM \ --rdzv_backend c10d \ --rdzv_endpoint $head_node_ip:29500 \ /shared/examples/multinode_torchrun.py 50 10 ``` ## deepspeed ### 单机多卡 ``` deepspeed --include localhost:0,1,2,3 train.py --deepspeed_config=ds_config.json -p 2 --steps=200 ``` ### 多机多卡 ``` python -m torch.distributed.run --nproc_per_node=2 --nnode=2 --node_rank=0 --master_addr=10.99.2.xx \ --master_port=9901 train.py --deepspeed_config=ds_config.json -p 2 --steps=200 python -m torch.distributed.run --nproc_per_node=2 --nnode=2 --node_rank=1 --master_addr=10.99.2.xx \ --master_port=9901 train.py --deepspeed_config=ds_config.json -p 2 --steps=200 ``` ### 单机多卡+docker ``` sudo docker run -it --rm --gpus all \ --network=host \ --shm-size 4G \ -v /data/hpc/home/guodong.li/:/workspaces \ -v /data/hpc/home/guodong.li/.cache/:/root/.cache/ \ -w /workspaces/DeepSpeedExamples-20230430/training/pipeline_parallelism \ deepspeed/deepspeed:v072_torch112_cu117 /bin/bash deepspeed --include localhost:4,5,6,7 --master_port 29001 train.py --deepspeed_config=ds_config.json -p 2 --steps=200 ``` ### 单机多卡+singularity ``` docker tag deepspeed/deepspeed:v072_torch112_cu117 harbor.aip.io/base/deepspeed:torch112_cu117 sudo docker push harbor.aip.io/base/deepspeed:torch112_cu117 SINGULARITY_NOHTTPS=1 singularity build deepspeed.sif docker://harbor.aip.io/base/deepspeed:torch112_cu117 singularity run --nv \ --pwd /workspaces/DeepSpeedExamples-20230430/training/pipeline_parallelism \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ deepspeed.sif export NCCL_IB_DISABLE=1 && export NCCL_SOCKET_IFNAME=bond0 && export CC=/opt/hpcx/ompi/bin/mpicc && deepspeed --include localhost:4,5,6,7 --master_port 29001 train.py --deepspeed_config=ds_config.json -p 2 --steps=200 ``` ### 单机多卡+singularity+slurm ``` sbatch pp-standalone-singularity.slurm squeue scancel -v xx ``` --- ``` srun --mpi=list ``` ### 多机多卡+singularity+slurm - --mpi:指定mpi类型为pmi2 ``` sbatch pp-multinode-singularity.slurm ``` ================================================ FILE: llm-train/slurm/deepspeed/pp-multinode-machine.slurm ================================================ #!/bin/sh #SBATCH --job-name=multinode-deepspeed # name #SBATCH -N 2 #SBATCH --ntasks=2 #SBATCH --gres=gpu:2 #SBATCH --cpus-per-task=4 #SBATCH --time 20:00:00 # maximum execution time (HH:MM:SS) #SBATCH --partition=a800 # 分区 #SBATCH --output=log/%j.out # 日志 #SBATCH --error=log/%j.err # 日志 export GPUS_PER_NODE=2 export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1) export MASTER_PORT=9901 module load anaconda/3-2023.03 source activate conda activate liguodong-310 module load cuda-cudnn8.9/11.7.1 cd /data/hpc/home/guodong.li/DeepSpeedExamples-20230430/training/pipeline_parallelism srun --jobid $SLURM_JOBID bash -c 'python -m torch.distributed.run \ --nproc_per_node $GPUS_PER_NODE --nnodes $SLURM_NNODES --node_rank $SLURM_PROCID \ --master_addr $MASTER_ADDR --master_port $MASTER_PORT \ train.py --deepspeed_config=ds_config.json -p 2 --steps=200' ================================================ FILE: llm-train/slurm/deepspeed/pp-multinode-singularity.slurm ================================================ #!/bin/sh #SBATCH --job-name=multinode-deepspeed-singularity # name #SBATCH -N 2 #SBATCH --ntasks=4 #SBATCH --gres=gpu:2 ###SBATCH --cpus-per-task=1 #SBATCH --time 20:00:00 # maximum execution time (HH:MM:SS) #SBATCH --partition=a800 # 分区 #SBATCH --output=log/%j.out # 日志 #SBATCH --error=log/%j.err # 日志 #export GPUS_PER_NODE=2 #export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1) #export MASTER_PORT=9903 export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 export CC=/opt/hpcx/ompi/bin/mpicc export CUDA_LAUNCH_BLOCKING=1 srun --mpi=pmi2 singularity run --nv --pwd /workspaces/DeepSpeedExamples-20230430/training/pipeline_parallelism \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ deepspeed.sif \ python -m torch.distributed.run \ --nproc_per_node 2 \ train.py --deepspeed_config=ds_config.json -p 2 --steps=200 ================================================ FILE: llm-train/slurm/deepspeed/pp-mutinode-singularity-pmix.slurm ================================================ #!/bin/sh #SBATCH --job-name=multinode-deepspeed-singularity # name #SBATCH -N 2 #SBATCH --ntasks=2 #SBATCH --gres=gpu:2 ###SBATCH --cpus-per-task=1 #SBATCH --time 20:00:00 # maximum execution time (HH:MM:SS) #SBATCH --partition=a800 # 分区 #SBATCH --output=log/%j_%N.out # 日志 #SBATCH --error=log/%j_%N.err # 日志 #export GPUS_PER_NODE=2 #export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1) #export MASTER_PORT=9903 export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 export CC=/opt/hpcx/ompi/bin/mpicc export CUDA_LAUNCH_BLOCKING=1 srun --mpi=pmix_v4 singularity run --nv --pwd /workspaces/DeepSpeedExamples-20230430/training/pipeline_parallelism \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ deepspeed.sif \ python -m torch.distributed.run \ --nproc_per_node 2 \ train.py --deepspeed_config=ds_config.json -p 2 --steps=200 ================================================ FILE: llm-train/slurm/deepspeed/pp-standalone-singularity-v2.slurm ================================================ #!/bin/sh #SBATCH --job-name=multinode-deepspeed-singularity # name #SBATCH -N 1 #SBATCH --ntasks=4 #SBATCH --gres=gpu:4 #SBATCH --cpus-per-task=4 #SBATCH --time 20:00:00 # maximum execution time (HH:MM:SS) #SBATCH --partition=a800 # 分区 #SBATCH --output=log/%j.out # 日志 #SBATCH --error=log/%j.err # 日志 export GPUS_PER_NODE=2 export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1) export MASTER_PORT=9903 export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 export CC=/opt/hpcx/ompi/bin/mpicc srun --mpi=pmix_v3 singularity run --nv \ --pwd /workspaces/DeepSpeedExamples-20230430/training/pipeline_parallelism \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ deepspeed.sif \ python -m torch.distributed.run \ --nproc_per_node 4 \ --master_addr $MASTER_ADDR \ train.py --deepspeed_config=ds_config.json -p 2 --steps=200 ================================================ FILE: llm-train/slurm/deepspeed/pp-standalone-singularity.slurm ================================================ #!/bin/sh #SBATCH --job-name=multinode-deepspeed-singularity # name #SBATCH -N 1 #SBATCH --ntasks=4 #SBATCH --gres=gpu:4 #SBATCH --cpus-per-task=4 #SBATCH --time 20:00:00 # maximum execution time (HH:MM:SS) #SBATCH --partition=a800 # 分区 #SBATCH --output=log/%j.out # 日志 #SBATCH --error=log/%j.err # 日志 export GPUS_PER_NODE=4 export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1) export MASTER_PORT=9901 export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 export CC=/opt/hpcx/ompi/bin/mpicc echo $MASTER_ADDR singularity run --nv --pwd /workspaces/DeepSpeedExamples-20230430/training/pipeline_parallelism \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ deepspeed.sif \ deepspeed --master_port $MASTER_PORT train.py --deepspeed_config=ds_config.json -p 2 --steps=200 ================================================ FILE: llm-train/slurm/megatron-deepspeed/megatron-deepspeed-multinode-ib-part2-65b-fp16.slurm ================================================ #!/bin/bash #SBATCH --job-name=megatron-multinode-ib-30b-2 #作业名称 #SBATCH --partition=h800-ib-2 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.out #日志 #SBATCH -N 8 # 指定机器数量 #SBATCH -c 80 #SBATCH --gres=gpu:8 #每台机器使用四张卡 export NCCL_DEBUG=info #export NCCL_IB_DISABLE=0 #export NCCL_IB_HCA=mlx5_0 #export NCCL_PXN_DISABLE=1 #export NCCL_IB_TIMEOUT=22 #export NCCL_IB_RETRY_CNT=13 #export NCCL_IB_PCI_RELAXED_ORDERING=1 export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 MASTER_HOST=$(scontrol show hostnames "$SLURM_JOB_NODELIST"|head -1) MASTER_ADDR=$(srun --nodes=1 --ntasks=1 -w "$MASTER_HOST" hostname --ip-address|awk '{print $1}') #从中获取一个IP作为通信IP MASTER_PORT=$(expr 10000 + $(echo -n $SLURM_JOBID|tail -c 4)) #master通信端口 ENDPOINT_URL=$MASTER_HOST:$MASTER_PORT echo "$MASTER_HOST --- ""$MASTER_ADDR --- ""$MASTER_PORT" srun --mpi=pmix_v3 singularity run --nv \ --pwd /workspace/code/Megatron-DeepSpeed-llama-20230815 \ -B /data/hpc/home/guodong.li/workspace:/workspace:rw \ megatron-deepspeed-v4-gcc.sif \ torchrun --nnodes 8 --nproc_per_node 8 --rdzv_id=$SLURM_JOBID --rdzv_backend=c10d --rdzv_endpoint=$ENDPOINT_URL pretrain_gpt.py --tensor-model-parallel-size 16 --pipeline-model-parallel-size 4 --num-layers 80 --hidden-size 8192 --ffn-hidden-size 22016 --num-attention-heads 64 --micro-batch-size 1 --global-batch-size 8 --seq-length 2048 --max-position-embeddings 2048 --train-iters 1500 --save ./tmp-llama-65b --load ./tmp-llama-65b --data-path 1 /workspace/data/gpt2-data/my-gpt2_text_document 2 /workspace/data/gpt2-data/my-gpt2-1_text_document --data-impl mmap --tokenizer-type GPTSentencePieceTokenizer --tokenizer-model /workspace/model/llama-tokenizer/tokenizer.model --split 900,50,50 --distributed-backend nccl --lr 3e-4 --lr-decay-style cosine --min-lr 3e-5 --weight-decay 0.1 --clip-grad 1 --lr-warmup-iters 500 --optimizer adam --adam-beta1 0.9 --adam-beta2 0.95 --log-interval 1 --save-interval 2000 --eval-interval 1000 --eval-iters 10 --fp16 --no-query-key-layer-scaling --attention-dropout 0 --hidden-dropout 0 --use-rotary-position-embeddings --untie-embeddings-and-output-weights --swiglu --normalization rmsnorm --disable-bias-linear --deepspeed-activation-checkpointing --zero-stage=0 --deepspeed_config=./tmp/deepspeed.json --deepspeed ================================================ FILE: llm-train/slurm/pytorch/alpaca-docker.slurm ================================================ #!/bin/bash #SBATCH --job-name=alpaca #作业名称 #SBATCH --partition=a800 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.err #日志 #SBATCH -n 10 #总共运行几个进程 #SBATCH --ntasks-per-node=20 #单节点运行几个进程 #SBATCH -c 3 #SBATCH --gpus-per-node=8 sudo docker run -it --gpus all --network=host \ --shm-size 4G \ -v /data/hpc/home/guodong.li:/workspaces \ harbor.maip.io/base/pytorch-alpaca:v3 \ torchrun --nproc_per_node=8 --master_port=25001 train.py \ --model_name_or_path /workspaces/llama-7b \ --data_path /workspaces/alpaca_data_cleaned.json \ --output_dir /workspaces/output \ --bf16 True \ --max_steps 200 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'LlamaDecoderLayer' \ --tf32 True ================================================ FILE: llm-train/slurm/pytorch/alpaca-machine.slurm ================================================ #!/bin/bash #SBATCH --job-name=alpaca #作业名称 #SBATCH --partition=a800 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.err #日志 #SBATCH -n 10 #总共运行几个进程 #SBATCH --ntasks-per-node=20 #单节点运行几个进程 #SBATCH -c 3 #SBATCH --gpus-per-node=8 module load anaconda/3-2023.03 source activate conda activate liguodong-310 module load cuda-cudnn8.9/11.7.1 cd /data/hpc/home/guodong.li/stanford_alpaca torchrun --nproc_per_node=8 --master_port=11223 train.py \ --model_name_or_path /data/hpc/home/guodong.li/llama-7b \ --data_path /data/hpc/home/guodong.li/alpaca_data_cleaned.json \ --output_dir /data/hpc/home/guodong.li/output \ --max_steps 200 \ --per_device_train_batch_size 2 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 100 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --gradient_checkpointing True \ --fp16 True \ --deepspeed ds_config_zero2.json ================================================ FILE: llm-train/slurm/pytorch/alpaca-singularity.slurm ================================================ #!/bin/bash #SBATCH --job-name=alpaca #作业名称 #SBATCH --partition=a800 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.err #日志 #SBATCH -n 10 #总共运行几个进程 #SBATCH --ntasks-per-node=20 #单节点运行几个进程 #SBATCH -c 3 #SBATCH --gpus-per-node=8 singularity run --nv \ --pwd /workspace/stanford_alpaca/ \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-alpaca.sif \ torchrun --nproc_per_node=8 --master_port=25001 train.py \ --model_name_or_path /workspaces/llama-7b \ --data_path /workspaces/alpaca_data_cleaned.json \ --output_dir /workspaces/output \ --bf16 True \ --max_steps 100 \ --per_device_train_batch_size 1 \ --per_device_eval_batch_size 1 \ --gradient_accumulation_steps 2 \ --evaluation_strategy "no" \ --save_strategy "steps" \ --save_steps 2000 \ --save_total_limit 1 \ --learning_rate 2e-5 \ --weight_decay 0. \ --warmup_ratio 0.03 \ --lr_scheduler_type "cosine" \ --logging_steps 1 \ --report_to "tensorboard" \ --fsdp "full_shard auto_wrap" \ --fsdp_transformer_layer_cls_to_wrap 'LlamaDecoderLayer' \ --tf32 True ================================================ FILE: llm-train/slurm/pytorch/mingpt-singularity-multinode-2.slurm ================================================ #!/bin/bash #SBATCH --job-name=multinode-example #SBATCH --partition=a800 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.err #日志 #SBATCH --nodes=2 #SBATCH --ntasks=4 #SBATCH --gpus-per-task=4 #SBATCH --cpus-per-task=4 NODELIST=$(scontrol show hostname $SLURM_JOB_NODELIST) # 对第一个节点赋值为主节点 MASTER_NODE=$(head -n 1 <<< "$NODELIST") # 计数器 NODE_COUNT=0 # 一共的节点数 NODE_NUM=($(echo $NODELIST | tr " " "\n" | wc -l)) # 打印 echo $SLURM_NODEID echo $NODELIST echo $MASTER_NODE echo $NODE_NUM export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 for NODE in $NODELIST; do if [ "$NODE" == "$MASTER_NODE" ]; then srun --nodes=1 --ntasks=1 -w $NODE \ singularity run --nv \ --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif \ torchrun --nproc_per_node=4 \ --nnodes=$NODE_NUM \ --node_rank=0 \ --master_addr=$MASTER_NODE \ --master_port=29500 \ main.py & else ((NODE_COUNT++)) srun --nodes=1 --ntasks=1 -w $NODE \ singularity run --nv \ --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt \ -B /data/hpc/home/guodong.li/:/workspaces:rw \ pytorch-multinode.sif \ torchrun --nproc_per_node=4 \ --nnodes=$NODE_NUM \ --node_rank=$NODE_COUNT \ --master_addr=$MASTER_NODE \ --master_port=29500 \ main.py & fi done wait ================================================ FILE: llm-train/slurm/pytorch/mingpt-singularity-multinode.slurm ================================================ #!/bin/bash #SBATCH --job-name=multinode-example #SBATCH --partition=a800 #分区 #SBATCH --output=log/%j.out #日志 #SBATCH --error=log/%j.err #日志 #SBATCH -N 2 #SBATCH --ntasks=2 #SBATCH --gres=gpu:4 #SBATCH --cpus-per-task=4 NODELIST=$(scontrol show hostname $SLURM_JOB_NODELIST) # 对第一个节点赋值为主节点 MASTER_NODE=$(head -n 1 <<< "$NODELIST") # 计数器 NODE_COUNT=0 # 一共的节点数 NODE_NUM=($(echo $NODELIST | tr " " "\n" | wc -l)) # 打印 echo $SLURM_NODEID echo $NODELIST echo $MASTER_NODE echo $NODE_NUM export NCCL_IB_DISABLE=1 export NCCL_SOCKET_IFNAME=bond0 srun --mpi=pmix_v3 singularity run --nv --pwd /workspaces/examples-main/distributed/minGPT-ddp/mingpt -B /data/hpc/home/guodong.li/:/workspaces:rw pytorch-multinode.sif torchrun --nproc_per_node=4 main.py ================================================ FILE: llm-train/vicuna/README.md ================================================ ================================================ FILE: llmops/FAQ.md ================================================ ## k8s 的 pod 中下载 s3 对象存储的数据网络不通? 可能的问题: 1. 服务器的时间和s3对象存储服务器时间不一致 2. 异构集群导致网络镜像拉取有问题,比如:昇腾NPU服务器需要calico网络镜像是aarch64架构,却下载了 x86 架构的镜像,导致容器启动不成功。 ================================================ FILE: llmops/README.md ================================================ 千帆大模型平台: - https://cloud.baidu.com/product/wenxinworkshop - https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Xlkb0e6eu --- 数据集对应关系说明: https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Wlj3vd4gy --- 模型评估 人工评估: 综合人类专家的主观见解、经验等从不同评价维度对模型回复进行打分,用于评估模型回复的效果。 自动评估: 对⽣成式⼤模型的输出效果进⾏全⽅位评价,提供⾯向事实类或开放性问答的多种打分模式; 自动规则打分 计算模型预测结果与真实标注的文本相似度指标(例如ROUGE、BLUE等),适合标准选择题或简单问答场景。 自动裁判员打分 使用能力更强的大模型作为裁判员,对被评估模型的生成结果进行自动化打分,适用于开放性或复杂问答场景。 ================================================ FILE: llmops/kubernetes.md ================================================ 修改共享内存:https://www.alibabacloud.com/help/zh/eci/user-guide/mount-an-emptydir-volume-to-modify-the-shm-size-of-a-pod?spm=a2c63.p38356.0.0.1c055267llapbW swap(交换内存)和shm(共享内存)的区别:https://blog.csdn.net/songyu0120/article/details/89169987 - tmpfs使用内存空间而swap使用物理存储空间 训练过程内存碎片化问题 - export 'PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:512' - 一文读懂 PyTorch 显存管理机制:https://zhuanlan.zhihu.com/p/486360176 RuntimeError: CUDA out of memory.一些调bug路程:https://zhuanlan.zhihu.com/p/581606031 max_split_size_mb 阻止原生(native)分配器分割大于此大小(MB)的块。这可以减少碎片,并允许某些边缘工作负载在内存不耗尽的情况下完成。性能代价从 "零 "到 "大量 "不等,取决于分配模式。 默认值没有限制,即所有块都可以分割。memory_stats()和 memory_summary()方法可用于调整。如果工作负载因 "内存不足 "而终止,并显示大量未活动的分割块,则应在万不得已时使用该选项。 max_split_size_mb 只对 backend:native 有意义。在使用 backend:cudaMallocAsync 时,max_split_size_mb 将被忽略。 - 官方:https://pytorch.org/docs/stable/notes/cuda.html ================================================ FILE: llmops/tq-llm/train/FAQ.md ================================================ ## FAQ ### baichuan2报错 - 'BitsAndBytesConfig' object is not subscriptable https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat/discussions/2 - AttributeError: 'BaichuanTokenizer' object has no attribute 'sp_model' 降低版本到4.34.0及以下 : pip install transformers==4.34.0 ## Pytorch - RuntimeError: DataLoader worker (pid xxxxx) is killed by signal: Killed. 可能共享内存太小了 --shm-size 4G ================================================ FILE: llmops/tq-llm/train/README.md ================================================ ``` sh /task/script/bootstrap-llm.sh --sft_type=full --conda_env=torch1131-venv \ --train_dataset_path=s3://infer-test/data/train_data_20240105_1k.json,s3://infer-test/data/train_data_20240105_100.json \ --pre_model_path=s3://infer-test/model-bloom-2b6 \ --checkpoint_path=s3://infer-test/model-bloom-2b6 \ --model_output_path=s3://infer-test/model-bloom-2b6 \ --model_metrics_path=s3://infer-test/model-bloom-metrics/processx.json \ --gpu_num=2 \ --epoch=1 --batch_size=8 --learning_rate=1e-5 --max_seq_length=512 --logging_steps=1 --warmup_ratio=0.1 --weight_decay=0 ``` https://download.pytorch.org/whl/cu118/torch-2.0.1%2Bcu118-cp310-cp310-linux_x86_64.whl#sha256=a7a49d459bf4862f64f7bc1a68beccf8881c2fa9f3e0569608e16ba6f85ebf7b https://download.pytorch.org/whl/cu118/torchvision-0.15.2%2Bcu118-cp310-cp310-linux_x86_64.whl#sha256=19ca4ab5d6179bbe53cff79df1a855ee6533c2861ddc7389f68349d8b9f8302a ## lora 降低显存消耗: gradient_checkpointing gradient_accumulation_steps batch_size seq_length ================================================ FILE: llmops/tq-llm/train/bootstrap-llm-zero3-offload.sh ================================================ #!/bin/bash # sh bootstrap.sh -d s3://infer-test/dianxiao-data/train_data_20240105_1k.json -p s3://infer-test/dianxiao-model -o s3://infer-test/dianxiao-output -m s3://infer-test/dianxiao-output/processx.jsonca echo "入参:" $@ for a in "$@"; do #echo $a if [[ `echo $a | grep "^--conda_env="` ]]; then conda_env=`echo $a | grep "^--conda_env=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--sft_type="` ]]; then sft_type=`echo $a | grep "^--sft_type=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--train_dataset_path="` ]]; then train_dataset_path=`echo $a | grep "^--train_dataset_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--pre_model_path="` ]]; then pre_model_path=`echo $a | grep "^--pre_model_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--checkpoint_path="` ]]; then checkpoint_path=`echo $a | grep "^--checkpoint_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--model_output_path="` ]]; then model_output_path=`echo $a | grep "^--model_output_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--model_metrics_path="` ]]; then model_metrics_path=`echo $a | grep "^--model_metrics_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--gpu_num="` ]]; then gpu_num=`echo $a | grep "^--gpu_num=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--epoch="` ]]; then epoch=`echo $a | grep "^--epoch=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--batch_size="` ]]; then batch_size=`echo $a | grep "^--batch_size=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--learning_rate="` ]]; then learning_rate=`echo $a | grep "^--learning_rate=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--max_seq_length="` ]]; then max_seq_length=`echo $a | grep "^--max_seq_length=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--logging_steps="` ]]; then logging_steps=`echo $a | grep "^--logging_steps=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--warmup_ratio="` ]]; then warmup_ratio=`echo $a | grep "^--warmup_ratio=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--weight_decay="` ]]; then weight_decay=`echo $a | grep "^--weight_decay=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--lora_rank="` ]]; then lora_rank=`echo $a | grep "^--lora_rank=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--lora_alpha="` ]]; then lora_alpha=`echo $a | grep "^--lora_alpha=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--lora_dropout="` ]]; then lora_dropout=`echo $a | grep "^--lora_dropout=" | awk -F '=' '{print $2}'` fi done echo "平台入参:sft_type=$sft_type, conda_env=$conda_env, TRAIN_DATASET_PATH: $train_dataset_path ,PRE_MODEL_PATH:$pre_model_path , checkpoint_path: $checkpoint_path, MODEL_OUTPUT_PATH:$model_output_path ,MODEL_METRICS_PATH:$model_metrics_path ,GPU_NUM:$gpu_num" echo "模型超参:epoch: $epoch, batch_size:$batch_size, learning_rate: $learning_rate, max_seq_length: $max_seq_length , logging_steps: $logging_steps, warmup_ratio: $warmup_ratio, weight_decay: $weight_decay" LOCAL_TEMP_DIR=/workspace/temp LOCAL_DATASET_PATH="$LOCAL_TEMP_DIR/datas" LOCAL_MODEL_PATH="$LOCAL_TEMP_DIR/models" LOCAL_OUTPUT_PATH="$LOCAL_TEMP_DIR/outputs" LOCAL_LOG_PATH="$LOCAL_TEMP_DIR/logs" # lora LOCAL_MERGE_PATH="$LOCAL_TEMP_DIR/merges" # 进度 LOCAL_PROGRESS_PATH=$LOCAL_OUTPUT_PATH"/progress.json" BASE_CODE_PATH=/task/code PROJECT_PATH="$BASE_CODE_PATH/Firefly" echo "train task start..." #FILENAME=$(basename -- "$TRAIN_DATASET_PATH") #EXTENSION="${FILENAME##*.}" #FILENAME="${FILENAME%.*}" #FILENAME=$FILENAME"."$EXTENSION #LOCAL_DATASET_FILE_PATH="$LOCAL_DATASET_PATH/$FILENAME" echo "LOCAL_DATASET_PATH: $LOCAL_DATASET_PATH" TRAIN_ARGS_PATH="$PROJECT_PATH/sft-config.json" cat < $TRAIN_ARGS_PATH { "output_dir": "$model_output_path", "logging_dir": "$LOCAL_LOG_PATH", "model_name_or_path": "$LOCAL_MODEL_PATH", "deepspeed": "./train_args/ds_z3_config_offload.json", "train_file": "$LOCAL_DATASET_PATH", "model_metrics_path": "$model_metrics_path", "num_train_epochs": $epoch, "per_device_train_batch_size": $batch_size, "gradient_accumulation_steps": 4, "learning_rate": $learning_rate, "max_seq_length": $max_seq_length, "logging_steps": $logging_steps, "save_steps": 500, "save_total_limit": 1, "lr_scheduler_type": "cosine", "warmup_ratio": $warmup_ratio, "gradient_checkpointing": true, "disable_tqdm": false, "optim": "adamw_hf", "seed": 42, "fp16": true, "report_to": "tensorboard", "dataloader_num_workers": 5, "save_strategy": "steps", "weight_decay": $weight_decay, "max_grad_norm": 1.0, "remove_unused_columns": false } EOF echo "训练参数: " cat $TRAIN_ARGS_PATH echo "执行训练任务脚本:" echo "cd $PROJECT_PATH && deepspeed --num_gpus=$gpu_num train_s3.py --train_args_file $TRAIN_ARGS_PATH" cd $PROJECT_PATH && deepspeed --num_gpus=$gpu_num train_s3.py --train_args_file $TRAIN_ARGS_PATH exit_code=$? if [ $exit_code -ne 0 ]; then exit $exit_code fi ls -al -R $LOCAL_TEMP_DIR echo "train task end..." ================================================ FILE: llmops/tq-llm/train/bootstrap-llm.sh ================================================ #!/bin/bash # sh bootstrap.sh -d s3://infer-test/dianxiao-data/train_data_20240105_1k.json -p s3://infer-test/dianxiao-model -o s3://infer-test/dianxiao-output -m s3://infer-test/dianxiao-output/processx.jsonca echo "入参:" $@ for a in "$@"; do #echo $a if [[ `echo $a | grep "^--conda_env="` ]]; then conda_env=`echo $a | grep "^--conda_env=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--sft_type="` ]]; then sft_type=`echo $a | grep "^--sft_type=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--train_dataset_path="` ]]; then train_dataset_path=`echo $a | grep "^--train_dataset_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--pre_model_path="` ]]; then pre_model_path=`echo $a | grep "^--pre_model_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--checkpoint_path="` ]]; then checkpoint_path=`echo $a | grep "^--checkpoint_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--model_output_path="` ]]; then model_output_path=`echo $a | grep "^--model_output_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--model_metrics_path="` ]]; then model_metrics_path=`echo $a | grep "^--model_metrics_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--gpu_num="` ]]; then gpu_num=`echo $a | grep "^--gpu_num=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--epoch="` ]]; then epoch=`echo $a | grep "^--epoch=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--batch_size="` ]]; then batch_size=`echo $a | grep "^--batch_size=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--learning_rate="` ]]; then learning_rate=`echo $a | grep "^--learning_rate=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--max_seq_length="` ]]; then max_seq_length=`echo $a | grep "^--max_seq_length=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--logging_steps="` ]]; then logging_steps=`echo $a | grep "^--logging_steps=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--warmup_ratio="` ]]; then warmup_ratio=`echo $a | grep "^--warmup_ratio=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--weight_decay="` ]]; then weight_decay=`echo $a | grep "^--weight_decay=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--lora_rank="` ]]; then lora_rank=`echo $a | grep "^--lora_rank=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--lora_alpha="` ]]; then lora_alpha=`echo $a | grep "^--lora_alpha=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--lora_dropout="` ]]; then lora_dropout=`echo $a | grep "^--lora_dropout=" | awk -F '=' '{print $2}'` fi done echo "平台入参:sft_type=$sft_type, conda_env=$conda_env, TRAIN_DATASET_PATH: $train_dataset_path ,PRE_MODEL_PATH:$pre_model_path , checkpoint_path: $checkpoint_path, MODEL_OUTPUT_PATH:$model_output_path ,MODEL_METRICS_PATH:$model_metrics_path ,GPU_NUM:$gpu_num" echo "模型超参:epoch: $epoch, batch_size:$batch_size, learning_rate: $learning_rate, max_seq_length: $max_seq_length , logging_steps: $logging_steps, warmup_ratio: $warmup_ratio, weight_decay: $weight_decay" echo "模型LoRA超参:lora_rank: $lora_rank, lora_alpha: $lora_alpha, lora_dropout: $lora_dropout" BASE_SCRIPT_PATH=/task/script BASE_CODE_PATH=/task/code LOCAL_TEMP_DIR=/workspace/temp LOCAL_OUTPUT_PATH="$LOCAL_TEMP_DIR/outputs" # 进度 LOCAL_PROGRESS_PATH=$LOCAL_OUTPUT_PATH"/progress.json" if [ -n "$train_dataset_path" ] && [ -n "$pre_model_path" ] && [ -n "$model_output_path" ] && [ -n "$model_metrics_path" ]; then echo "--" else echo "变量不能为空" exit -1 fi if [ -n "$gpu_num" ] then echo "--" else echo "GPU卡参数为空,使用默认值1" gpu_num=1 fi if [ -z "$epoch" ]; then echo "epoch 为空,使用默认值2" epoch=2 fi if [ -z "$batch_size" ]; then echo "batch_size 为空,使用默认值1" batch_size=1 fi if [ -z "$learning_rate" ]; then echo "learning_rate 为空,使用默认值:1e-5" learning_rate=1e-5 fi if [ -z "$max_seq_length" ]; then echo "max_seq_length 为空,使用默认值:512" max_seq_length=512 fi if [ -z "$logging_steps" ]; then echo "logging_steps 为空,使用默认值:1" logging_steps=1 fi if [ -z "$warmup_ratio" ]; then echo "warmup_ratio 为空,使用默认值:0.1" warmup_ratio=0.1 fi if [ -z "$weight_decay" ]; then echo "weight_decay 为空,使用默认值:0" weight_decay=0 fi echo "模型超参:epoch: $epoch, batch_size:$batch_size learning_rate: $learning_rate, max_seq_length: $max_seq_length , logging_steps: $logging_steps, warmup_ratio: $warmup_ratio, weight_decay: $weight_decay" source ~/.bashrc # 切换虚拟环境 if [ -n "$conda_env" ]; then echo "切换虚拟环境: $conda_env" conda env list && conda activate $conda_env fi # 环境初始化 sh $BASE_SCRIPT_PATH/init_env.sh exit_code=$? if [ $exit_code -ne 0 ]; then msg="环境初始化异常退出:$exit_code, 虚拟环境: $conda_env" echo $msg echo `cat $LOCAL_PROGRESS_PATH | jq --arg errMsg "$msg" '.errMsg = $errMsg'` > $LOCAL_PROGRESS_PATH exit $exit_code fi # 下载数据 sh $BASE_SCRIPT_PATH/data_prehandle.sh --train_dataset_path=$train_dataset_path \ --pre_model_path=$pre_model_path \ --checkpoint_path=$checkpoint_path exit_code=$? if [ $exit_code -ne 0 ]; then echo "下载数据异常退出:$exit_code" cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit $exit_code fi # 切换训练任务 if [ -z "$sft_type" ]; then echo "sft_type 为空,使用默认值:full" sft_type == "full" fi if [ "$sft_type" == "full" ]; then sh $BASE_SCRIPT_PATH/bootstrap-llm-full.sh --conda_env=$conda_env \ --train_dataset_path=$train_dataset_path \ --pre_model_path=$pre_model_path \ --checkpoint_path=$checkpoint_path \ --model_output_path=$model_output_path \ --model_metrics_path=$model_metrics_path \ --gpu_num=$gpu_num \ --epoch=$epoch --batch_size=$batch_size --learning_rate=$learning_rate --max_seq_length=$max_seq_length --logging_steps=$logging_steps --warmup_ratio=$warmup_ratio --weight_decay=$weight_decay exit_code=$? if [ $exit_code -ne 0 ]; then echo "执行训练异常退出:$exit_code" cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit $exit_code fi elif [ "$sft_type" == "lora" ]; then if [ -z "$lora_rank" ]; then echo "lora_rank 为空,使用默认值:64" lora_rank=64 fi if [ -z "$lora_alpha" ]; then echo "lora_alpha 为空,使用默认值:16" lora_alpha=16 fi if [ -z "$lora_dropout" ]; then echo "lora_dropout 为空,使用默认值:0.05" lora_dropout=0 fi echo "模型LoRA超参:lora_rank: $lora_rank, lora_alpha: $lora_alpha, lora_dropout: $lora_dropout" sh $BASE_SCRIPT_PATH/bootstrap-llm-lora.sh --conda_env=$conda_env \ --train_dataset_path=$train_dataset_path \ --pre_model_path=$pre_model_path \ --model_output_path=$model_output_path \ --model_metrics_path=$model_metrics_path \ --gpu_num=$gpu_num \ --epoch=$epoch --batch_size=$batch_size --learning_rate=$learning_rate --max_seq_length=$max_seq_length --logging_steps=$logging_steps --warmup_ratio=$warmup_ratio --weight_decay=$weight_decay \ --lora_rank=$lora_rank --lora_alpha=$lora_alpha --lora_dropout=$lora_dropout exit_code=$? if [ $exit_code -ne 0 ]; then echo "执行训练异常退出:$exit_code" cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit $exit_code fi else msg="暂不支持该微调类型:$sft_type" echo $msg echo `cat $LOCAL_PROGRESS_PATH | jq --arg errMsg "$msg" '.errMsg = $errMsg'` > $LOCAL_PROGRESS_PATH cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit -1 fi echo "------------------" ================================================ FILE: llmops/tq-llm/train/bootstrap-llm2.sh ================================================ #!/bin/bash echo "入参:" $@ for a in "$@"; do #echo $a if [[ `echo $a | grep "^--conda_env="` ]]; then conda_env=`echo $a | grep "^--conda_env=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--sft_type="` ]]; then sft_type=`echo $a | grep "^--sft_type=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--train_dataset_path="` ]]; then train_dataset_path=`echo $a | grep "^--train_dataset_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--pre_model_path="` ]]; then pre_model_path=`echo $a | grep "^--pre_model_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--checkpoint_path="` ]]; then checkpoint_path=`echo $a | grep "^--checkpoint_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--model_output_path="` ]]; then model_output_path=`echo $a | grep "^--model_output_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--model_metrics_path="` ]]; then model_metrics_path=`echo $a | grep "^--model_metrics_path=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--gpu_num="` ]]; then gpu_num=`echo $a | grep "^--gpu_num=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--epoch="` ]]; then epoch=`echo $a | grep "^--epoch=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--batch_size="` ]]; then batch_size=`echo $a | grep "^--batch_size=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--learning_rate="` ]]; then learning_rate=`echo $a | grep "^--learning_rate=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--max_seq_length="` ]]; then max_seq_length=`echo $a | grep "^--max_seq_length=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--logging_steps="` ]]; then logging_steps=`echo $a | grep "^--logging_steps=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--warmup_ratio="` ]]; then warmup_ratio=`echo $a | grep "^--warmup_ratio=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--weight_decay="` ]]; then weight_decay=`echo $a | grep "^--weight_decay=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--lora_rank="` ]]; then lora_rank=`echo $a | grep "^--lora_rank=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--lora_alpha="` ]]; then lora_alpha=`echo $a | grep "^--lora_alpha=" | awk -F '=' '{print $2}'` fi if [[ `echo $a | grep "^--lora_dropout="` ]]; then lora_dropout=`echo $a | grep "^--lora_dropout=" | awk -F '=' '{print $2}'` fi done echo "平台入参:sft_type=$sft_type, conda_env=$conda_env, TRAIN_DATASET_PATH: $train_dataset_path ,PRE_MODEL_PATH:$pre_model_path , checkpoint_path: $checkpoint_path, MODEL_OUTPUT_PATH:$model_output_path ,MODEL_METRICS_PATH:$model_metrics_path ,GPU_NUM:$gpu_num" echo "模型超参:epoch: $epoch, batch_size:$batch_size, learning_rate: $learning_rate, max_seq_length: $max_seq_length , logging_steps: $logging_steps, warmup_ratio: $warmup_ratio, weight_decay: $weight_decay" echo "模型LoRA超参:lora_rank: $lora_rank, lora_alpha: $lora_alpha, lora_dropout: $lora_dropout" BASE_SCRIPT_PATH=/task/script BASE_CODE_PATH=/task/code LOCAL_TEMP_DIR=/workspace/temp LOCAL_OUTPUT_PATH="$LOCAL_TEMP_DIR/outputs" # 进度 LOCAL_PROGRESS_PATH=$LOCAL_OUTPUT_PATH"/progress.json" if [ -n "$train_dataset_path" ] && [ -n "$pre_model_path" ] && [ -n "$model_output_path" ] && [ -n "$model_metrics_path" ]; then echo "--" else echo "变量不能为空" exit -1 fi if [ -n "$gpu_num" ] then echo "--" else echo "GPU卡参数为空,使用默认值1" gpu_num=1 fi if [ -z "$epoch" ]; then echo "epoch 为空,使用默认值2" epoch=2 fi if [ -z "$batch_size" ]; then echo "batch_size 为空,使用默认值1" batch_size=1 fi if [ -z "$learning_rate" ]; then echo "learning_rate 为空,使用默认值:1e-5" learning_rate=1e-5 fi if [ -z "$max_seq_length" ]; then echo "max_seq_length 为空,使用默认值:512" max_seq_length=512 fi if [ -z "$logging_steps" ]; then echo "logging_steps 为空,使用默认值:1" logging_steps=1 fi if [ -z "$warmup_ratio" ]; then echo "warmup_ratio 为空,使用默认值:0.1" warmup_ratio=0.1 fi if [ -z "$weight_decay" ]; then echo "weight_decay 为空,使用默认值:0" weight_decay=0 fi echo "模型超参:epoch: $epoch, batch_size:$batch_size learning_rate: $learning_rate, max_seq_length: $max_seq_length , logging_steps: $logging_steps, warmup_ratio: $warmup_ratio, weight_decay: $weight_decay" source ~/.bashrc # 切换虚拟环境 if [ -n "$conda_env" ]; then echo "切换虚拟环境: $conda_env" conda env list && conda activate $conda_env exit_code=$? if [ $exit_code -ne 0 ]; then msg="切换虚拟环境异常,请检查该虚拟环境是否存在。$conda_env" echo $msg echo `cat $LOCAL_PROGRESS_PATH | jq --arg errMsg "$msg" '.errMsg = $errMsg'` > $LOCAL_PROGRESS_PATH exit $exit_code fi fi # 环境初始化 sh $BASE_SCRIPT_PATH/init_env.sh exit_code=$? if [ $exit_code -ne 0 ]; then msg="环境初始化异常退出:$exit_code, 虚拟环境: $conda_env" echo $msg echo `cat $LOCAL_PROGRESS_PATH | jq --arg errMsg "$msg" '.errMsg = $errMsg'` > $LOCAL_PROGRESS_PATH cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit $exit_code fi # 下载数据 sh $BASE_SCRIPT_PATH/data_prehandle.sh --train_dataset_path=$train_dataset_path \ --pre_model_path=$pre_model_path \ --checkpoint_path=$checkpoint_path exit_code=$? if [ $exit_code -ne 0 ]; then echo "下载数据异常退出:$exit_code" cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit $exit_code fi # 切换训练任务 if [ -z "$sft_type" ]; then echo "sft_type 为空,使用默认值:full" sft_type == "full" fi if [ "$sft_type" == "full" ]; then sh $BASE_SCRIPT_PATH/bootstrap-llm-full.sh --conda_env=$conda_env \ --train_dataset_path=$train_dataset_path \ --pre_model_path=$pre_model_path \ --checkpoint_path=$checkpoint_path \ --model_output_path=$model_output_path \ --model_metrics_path=$model_metrics_path \ --gpu_num=$gpu_num \ --epoch=$epoch --batch_size=$batch_size --learning_rate=$learning_rate --max_seq_length=$max_seq_length --logging_steps=$logging_steps --warmup_ratio=$warmup_ratio --weight_decay=$weight_decay exit_code=$? if [ $exit_code -ne 0 ]; then echo "执行训练异常退出:$exit_code" cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit $exit_code fi elif [ "$sft_type" == "full-zero3-offload" ]; then sh $BASE_SCRIPT_PATH/bootstrap-llm-full-zero3-offload.sh --conda_env=$conda_env \ --train_dataset_path=$train_dataset_path \ --pre_model_path=$pre_model_path \ --checkpoint_path=$checkpoint_path \ --model_output_path=$model_output_path \ --model_metrics_path=$model_metrics_path \ --gpu_num=$gpu_num \ --epoch=$epoch --batch_size=$batch_size --learning_rate=$learning_rate --max_seq_length=$max_seq_length --logging_steps=$logging_steps --warmup_ratio=$warmup_ratio --weight_decay=$weight_decay exit_code=$? if [ $exit_code -ne 0 ]; then echo "执行训练异常退出:$exit_code" cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit $exit_code fi elif [ "$sft_type" == "lora" ]; then if [ -z "$lora_rank" ]; then echo "lora_rank 为空,使用默认值:64" lora_rank=64 fi if [ -z "$lora_alpha" ]; then echo "lora_alpha 为空,使用默认值:16" lora_alpha=16 fi if [ -z "$lora_dropout" ]; then echo "lora_dropout 为空,使用默认值:0.05" lora_dropout=0 fi echo "模型LoRA超参:lora_rank: $lora_rank, lora_alpha: $lora_alpha, lora_dropout: $lora_dropout" sh $BASE_SCRIPT_PATH/bootstrap-llm-lora.sh --sft_type=$sft_type --conda_env=$conda_env \ --train_dataset_path=$train_dataset_path \ --pre_model_path=$pre_model_path \ --model_output_path=$model_output_path \ --model_metrics_path=$model_metrics_path \ --gpu_num=$gpu_num \ --epoch=$epoch --batch_size=$batch_size --learning_rate=$learning_rate --max_seq_length=$max_seq_length --logging_steps=$logging_steps --warmup_ratio=$warmup_ratio --weight_decay=$weight_decay \ --lora_rank=$lora_rank --lora_alpha=$lora_alpha --lora_dropout=$lora_dropout exit_code=$? if [ $exit_code -ne 0 ]; then echo "执行训练异常退出:$exit_code" cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit $exit_code fi elif [ "$sft_type" == "qlora" ]; then if [ -z "$lora_rank" ]; then echo "lora_rank 为空,使用默认值:64" lora_rank=64 fi if [ -z "$lora_alpha" ]; then echo "lora_alpha 为空,使用默认值:16" lora_alpha=16 fi if [ -z "$lora_dropout" ]; then echo "lora_dropout 为空,使用默认值:0.05" lora_dropout=0 fi echo "模型LoRA超参:lora_rank: $lora_rank, lora_alpha: $lora_alpha, lora_dropout: $lora_dropout" sh $BASE_SCRIPT_PATH/bootstrap-llm-qlora.sh --sft_type=$sft_type --conda_env=$conda_env \ --train_dataset_path=$train_dataset_path \ --pre_model_path=$pre_model_path \ --model_output_path=$model_output_path \ --model_metrics_path=$model_metrics_path \ --gpu_num=$gpu_num \ --epoch=$epoch --batch_size=$batch_size --learning_rate=$learning_rate --max_seq_length=$max_seq_length --logging_steps=$logging_steps --warmup_ratio=$warmup_ratio --weight_decay=$weight_decay \ --lora_rank=$lora_rank --lora_alpha=$lora_alpha --lora_dropout=$lora_dropout exit_code=$? if [ $exit_code -ne 0 ]; then echo "执行训练异常退出:$exit_code" cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit $exit_code fi else msg="暂不支持该微调类型:$sft_type" echo $msg echo `cat $LOCAL_PROGRESS_PATH | jq --arg errMsg "$msg" '.errMsg = $errMsg'` > $LOCAL_PROGRESS_PATH cd $BASE_CODE_PATH && python progress.py --model_metrics_path $model_metrics_path exit -1 fi echo "------------------" ================================================ FILE: llmops/tq-llm/train/zero2-offload.json ================================================ { "gradient_accumulation_steps": "auto", "gradient_clipping": "auto", "steps_per_print": 200, "train_batch_size": "auto", "train_micro_batch_size_per_gpu": "auto", "wall_clock_breakdown": false, "optimizer": { "type": "Adamw", "params": { "lr": "auto", "betas": "auto", "eps": "auto", "weight_decay": "auto" } }, "bf16": { "enabled": "auto" }, "zero_optimization": { "stage": 2, "offload_optimizer": { "device": "cpu", "pin_memory": false }, "overlap_comm": false, "reduce_bucket_size": "auto", "allgather_partitions": true, "allgather_bucket_size": 5e8, "reduce_scatter": true, "contiguous_gradients" : true, "round_robin_gradients": false }, "scheduler": { "type": "WarmupLR", "params": { "warmup_min_lr": "auto", "warmup_max_lr": "auto", "warmup_num_steps": "auto" } } } ================================================ FILE: llmops/tq-llm/train/zero3-offload.json ================================================ { "gradient_accumulation_steps": "auto", "gradient_clipping": "auto", "steps_per_print": 200, "train_batch_size": "auto", "train_micro_batch_size_per_gpu": "auto", "wall_clock_breakdown": false, "optimizer": { "type": "Adamw", "params": { "lr": "auto", "betas": "auto", "eps": "auto", "weight_decay": "auto" } }, "bf16": { "enabled": "auto" }, "zero_optimization": { "stage": 3, "offload_optimizer": { "device": "cpu", "pin_memory": false }, "offload_param": { "device": "cpu", "pin_memory": false }, "overlap_comm": true, "contiguous_gradients": true, "sub_group_size": 1e9, "reduce_bucket_size": "auto", "stage3_prefetch_bucket_size": "auto", "stage3_param_persistence_threshold": "auto", "stage3_max_live_parameters": 1e9, "stage3_max_reuse_distance": 1e9, "stage3_gather_16bit_weights_on_model_save": true }, "scheduler": { "type": "WarmupLR", "params": { "warmup_min_lr": "auto", "warmup_max_lr": "auto", "warmup_num_steps": "auto" } } } ================================================ FILE: llmops/使用docker进行多机多卡训练.md ================================================ - Docker容器中DeepSpeed多机多卡集群分布式训练大模型实践:https://cloud.baidu.com/article/3273769 ================================================ FILE: llmops/千帆大模型平台.md ================================================ ## 大模型训练相关 大模型训练是本平台的核心功能,统一查看模型的训练状态选择更加适合的模型训练方式。 | 概念名 | 描述 | | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | | 训练轮次 | Epoch,训练轮次可以由步长 x 数据批大小/数据量的形式换算。例如,1w条样本在数据批大小为32的情况下,建议训练轮次至少设置为2。 | | 数据批 | Batch_size,即一次训练所抓取的数据样本数量,Batch_size大小影响训练速度和模型的优化。 | | 学习率 | Learning rate (LR),是在梯度下降的过程中更新权重时的超参数,过高会导致模型难以收敛,过低则会导致模型收敛速度过慢,平台已给出默认推荐值,可根据经验调整。 | | 全量更新 | 训练过程中对大模型的全部参数进行更新。 | | Prompt Tuning | 在固定预训练大模型本身的参数的基础上,增加prompt embedding参数,并且训练过程中只更新prompt参数。 | | LoRA | 在固定预训练大模型本身的参数的基础上,在保留自注意力模块中原始权重矩阵的基础上,对权重矩阵进行低秩分解,训练过程中只更新低秩部分的参数。 | | [奖励模型](https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Bliu6p62v#%E5%A5%96%E5%8A%B1%E6%A8%A1%E5%9E%8B%E8%AE%AD%E7%BB%83) | 训练的最终目的是刻画模型的输出是否在人类看来表现不错。 | | [强化学习](https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Bliu6p62v#%E5%BC%BA%E5%8C%96%E5%AD%A6%E4%B9%A0%E8%AE%AD%E7%BB%83) | 再励学习、评价学习或增强学习,利用问题集质问奖励模型,合成问题最优解的应答。 | ## 模型训练 ### Baichuan2-7B-Chat 单条数据支持4096 tokens。Baichuan2-7B-Chat 是在大约 1.2 万亿 tokens 上训练的 70 亿参数模型。 | 训练方法 | 简单描述 | | ---- | -------------------------------------------------------------------- | | 全量更新 | 全量更新在训练过程中对大模型的全部参数进行更新 | | LoRA | 在固定预训练大模型本身的参数的基础上,在保留自注意力模块中原始权重矩阵的基础上,对权重矩阵进行低秩分解,训练过程中只更新低秩部分的参数。 | - 参数配置 | 超参数 | 简单描述 | | ----------- | ------------------------------------------------------------------------------------ | | 迭代轮次 | 迭代轮次(epoch),控制训练过程中的迭代轮数。 | | 批处理大小 | 批处理大小(Batchsize)表示在每次训练迭代中使用的样本数。较大的批处理大小可以加速训练,但可能会导致内存问题。 | | 学习率 | 学习率(learning_rate)是在梯度下降的过程中更新权重时的超参数,过高会导致模型难以收敛,过低则会导致模型收敛速度过慢,平台已给出默认推荐值,可根据经验调整。 | | 学习率调整计划 | 用于调整训练中学习率的变动方式。 | | 学习率预热步数占比 | 指训练初始阶段,在学习率较低的情况下逐渐增加学习率的比例或速率,能够帮助模型更好地适应数据,提高训练的稳定性和性能。 | | 权重衰减数值 | 是一种正则化技术,用于帮助控制神经网络模型的复杂性以及减少过拟合的风险。 | | loraRank | 训练方式选择**LoRA**时填写,LoRA策略中rank,数值越大lora参数越多。 | | loraAlpha | 训练方式选择**LoRA**时填写,LoRA微调中的缩放系数,系数越大lora影响力越大。 | | loraDropout | 训练方式选择**LoRA**时填写,LoRA微调中的Dropout系数,用于防止lora训练中的过拟合。 | | 序列长度 | 单条样本的最大长度。如果训练数据较短,减少此项可以加快训练速度。| ## 模型评估 ### 自动规则打分指标[](https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Bliu6x38y#%E8%87%AA%E5%8A%A8%E8%A7%84%E5%88%99%E6%89%93%E5%88%86%E6%8C%87%E6%A0%87) | 指标名称 | 指标说明 | | ----------- | ------------------------------------------------------------------- | | 准确率 (%) | 规则打分模式下,忽略停用词后,正确预测(标注与预测完全匹配)的样本数与总样本数的比例 | | F1分数 (%) | 规则打分模式下,忽略停用词后,精确率和召回率的调和平均数 | | ROUGE-1 (%) | 忽略停用词后,将模型生成的结果和标准结果按unigram拆分后,计算出的召回率 | | ROUGE-2 (%) | 忽略停用词后,将模型生成的结果和标准结果按bigram拆分后,计算出的召回率 | | ROUGE-L (%) | 忽略停用词后,衡量了模型生成的结果和标准结果的最长公共子序列,并计算出召回率 | | BLEU-4 (%) | 忽略停用词后,用于评估模型生成的句子和实际句子的差异的指标,值为unigram,bigram,trigram,4-grams的加权平均 | **注释**: Ⅰ) unigram:指将句子或文本中的每个单词都单独作为一个基本单元,不考虑单词之间的顺序。 Ⅱ) bigram:指将句子或文本中的每个相邻的单词对都作为一个基本单元,用于描述两个单词之间的顺序关系。 Ⅲ) trigram:指将句子或文本中的每个相邻的三个单词作为一个基本单元,用于描述三个单词之间的顺序关系。 Ⅳ) 4-grams:指将句子或文本中的每个相邻的四个单词作为一个基本单元,用于描述四个单词之间的顺序关系。 Ⅴ) 最长公共子序列:指两个或多个字符串最长的子序列,这些子序列在每个字符串中都存在,且它们的顺序相同。 ================================================ FILE: llmops/模型推理平台方案.md ================================================ GPU解决方案: - https://github.com/NVIDIA/gpu-operator IB解决方案: - https://github.com/Mellanox/network-operator - https://docs.nvidia.com/networking/display/cokan10/network+operator ================================================ FILE: mkdir-dir-file.sh ================================================ dir=$1 # sh mkdir-dir-file.sh llm-algo/chatglm3 mkdir $dir touch $dir/README.md touch $dir/reference.md tree -h $dir ================================================ FILE: paper/A Survey on Efficient Training of Transformers.md ================================================ ----------------------- 优化器。 为了实现梯度下降更快的收敛速度,经典的解决方案是融合动量技术,其中每一步都是最速下降方向和最近迭代位移的组合,有助于加速相关方向的梯度下降并抑制振荡。 开创性的工作包括Nesterov针对凸优化的加速梯度[67]和针对非凸问题的带有动量的近端梯度[55]等。 为了满足机器学习模型大规模优化的需求,主导优化器被设计为随机的。时尚。 特别是,动量随机梯度下降(SGD)和自适应学习率估计方法 Adam [50] 被广泛用于训练深度神经网络。 根据经验,使用 Adam 训练 Transformer 的性能优于 SGD,并且 [96] 揭开了随机梯度中噪声的重尾分布是 SGD 性能不佳的主要原因的神秘面纱,并通过自适应噪声裁剪的视角来理解 Adam。 默认情况下,AdamW [62] 是 Adam 的一个变体,它解耦了 L 正则化和权重衰减,是 Transformer 使用最广泛的优化器。 最近,Google 搜索优化算法并发现了一种简单有效的优化器,称为 Lion [18]。 Lion仅跟踪一阶梯度的动量,其更新仅考虑符号方向并且每个参数具有相同的幅度,这与AdamW等自适应优化器有很大不同。在实践中,Lion 通常收敛速度更快,并且在各种基准上训练 Transformer 时比 AdamW 更节省内存且更准确。 我们建议读者参考 [60, 9],了解有关机器学习中加速优化方法的更多详细信息。 为了提高 Transformers 的泛化能力,锐度感知最小化(SAM)[28]寻求基于损失景观的几何形状与泛化之间的联系,同时最小化损失值和损失锐度,即,更平坦的最小值往往会提高泛化能力。以下工作 [17] 将 SAM 应用到 Transformer,通过平滑损失表面观察到显着的精度增益。然而,SAM 需要解决双层最小-最大优化问题,这几乎使训练时间增加了一倍。 为了加速优化,[23]提出了随机权重扰动保留泛化能力和锐度敏感的子集选择策略。最近,[24]通过将锐度估计替换为两个连续更新步骤之间的 KL 散度,设计了锐度损失的近零成本代理。 初始化。 良好的初始化对于稳定训练、提高学习率、加速收敛和提高泛化能力至关重要。 因此,为了更好地初始化 Transformer,人们提出了许多工作。 具体来说,Fixup [95]建议适当地重新调整标准初始化,以确保适当的梯度范数,以避免梯度爆炸或消失,这可以训练具有超过 10,000 层的非常深的网络,而无需添加归一化层。 基于归一化残差块计算的函数接近恒等函数(即单位方差)的认识,以下工作ReZero [5]和SkipInit [22]简单地初始化每个层以执行恒等操作。具体来说,他们在每个残差块的输出上添加了一个可学习的缩放乘数: 针对 Transformers 定制的 T-Fixup [40] 分析认为,部分优化难度来自于 Adam 优化器的早期更新不稳定,因为二阶动量的方差是无界的。因此,跟随Fixup采用重缩放方案来初始化残差块。所有上述方法都从所有块中删除了批量/层归一化,并且在没有学习率预热的情况下进行训练。在训练深度视觉 Transformers(ViT)时,[85]提出了通道可学习的缩放因子,并根据经验观察到重新引入预热和层归一化技术可以使训练更加稳定。 稀疏训练。 稀疏训练的关键思想是直接训练稀疏子网络而不是从头开始训练完整网络而不牺牲准确性。 可靠性首先由彩票假设(LTH)[29] 证明,即密集、随机初始化的网络包含子网络(中奖彩票),可以单独训练这些子网络以匹配原始网络的准确性。然而,LTH 需要以交替训练-剪枝-再训练的方式识别中奖彩票,这使得大型模型和数据集的训练成本极高,限制了实际收益。 有鉴于此,后续训练效率较高的工作可以大致分为三类: (i)在初始化时通过测量连接对损失的重要性来找到稀疏网络,从而消除了复杂的迭代优化计划的需要[ 52、88]; (ii) 通过低成本方案在非常早期的训练阶段识别《变形金刚》中的中奖彩票,然后仅训练这些早期彩票直到收敛 [90, 16]; (iii) 使用交替修剪和生长计划在整个训练过程中动态更新模型稀疏模式,适用于一般架构 [26, 14]。 过度参数化。 实际的 DNN 严重过度参数化,可学习参数的数量远大于训练样本的数量。据观察,过参数化在经验上提高了收敛性和泛化性,虽然有理论保证,但还不够。 早期的工作 [4] 从数学上证明,线性神经网络中过度参数化增加深度可以加速 SGD 收敛。 [57]进一步探索了两层非线性神经网络,[3]证明SGD可以在多项式时间内收敛到DNN训练目标上的全局最小值,假设训练样本不重复,并且参数数量是多项式训练样本的数量和网络深度。 在泛化方面,[2]从理论上证明了一个充分超参数化(三层)的神经网络可以泛化到总体风险,并且一个有趣的特性是在 SGD 训练轨迹上的任何点的近邻中都存在一个精确的网络随机初始化的概率较高。请注意,它与 LTH 有着深厚的联系,因为它部分解释了为什么 LTH 处于稀疏训练中,因为由于过度参数化,具有低风险的良好小型子网络非常丰富。 应用于变形金刚,[58]利用了更快的收敛和更好的泛化 将过参数化理论应用于 Transformer 设计高效的训练流程(训练一个非常大的模型,然后执行早期停止并对其进行大量压缩,类似于 LTH)获得了更快的收敛和更好的泛化 大批量训练。加速训练的另一种流行方法是使用大批量,减少每个时期的迭代次数并提高计算资源利用率。从统计角度来看,大批量训练减少了随机梯度估计的方差,因此需要调整可靠的步长以获得更好的收敛性[9]。在卷积神经网络时代,[31]采用学习率的线性缩放在ImageNet上训练ResNet-50,批量大小为1小时8,192。随后提出了更先进的步长估计方法。广泛使用的方法是针对 SGD 的 LARS [92] 和针对 Adam 的 LAMB [93],它们建议分别对 ResNet 和 Transformers 使用分层自适应学习率。分层适应策略可以表示为 其中 η、wan 和 γ 是时间步 t 时第 i 层的学习率、参数和基于动量的梯度,φ 是缩放函数。它配备了一个归一化项,可以为爆炸梯度和平台提供鲁棒性,并且缩放项确保更新的范数与参数的范数具有相同的阶数,从而促进更快的收敛。最近,经验表明,针对大批量训练定制的更强大的优化方法表现良好。例如,[46]表明,对一定数量的最新检查点的权重进行平均可以促进更快的训练。 [37] 中的 DeepMind 训练了超过 400 个具有不同规模的模型大小和训练标记数量的 Transformer 语言模型,达到了一个实际假设,即模型大小和训练标记的数量应该同等缩放以获得计算最优< /b1001> 培训。 增量学习。增量学习的高级概念是将原始具有挑战性的优化问题放松为一系列易于优化的子问题,其中一个子问题的解决方案可以作为后续子问题的良好初始化,以规避训练难度,与退火类似。一些工作 [30, 32] 提出通过逐步堆叠层、正确地从较小的模型初始化较大的模型来加速 BERT 预训练。 [97]以相反的方向通过层下降来训练随机深度的 Transformer,它沿着时间维度和深度维度逐渐增加下降率。 AutoProg [54] 针对 ViT 进行了定制,建议使用神经架构搜索来自动决定模型在渐进学习过程中是否应该增长、在何处增长以及增长多少。一个关键的观察结果是,逐步提高输入图像的分辨率(减小 patch 大小)可以显着加速 ViT 训练,这与众所周知的训练动态相一致,该训练动态侧重于早期阶段的低频结构和后期阶段的高频语义。后期。 -------------- 令牌屏蔽。标记掩码是自监督预训练任务中的主要方法,例如掩码语言建模(MLM)[48, 10]和掩码图像建模(MIM)[6, 35]。 标记屏蔽的本质是随机屏蔽一些输入标记,并训练模型使用可见标记的上下文信息来预测丢失的内容,例如词汇 ID 或像素。由于压缩序列长度可以成倍地降低计算和内存复杂性,因此跳过处理屏蔽标记可以为 MLM 和 MIM 带来可观的训练效率增益。 对于 MLM,[80] 提出联合预训练编码器和解码器以执行语言生成任务,同时删除解码器中的屏蔽标记以节省内存和计算成本。 对于 MIM,代表性工作 [35] 表明,在视觉中,在编码器之前删除屏蔽图像块表现出更强的性能,并且比保留屏蔽标记的总体预训练时间和内存消耗低 3 倍或更多。在[56]中也发现了类似的现象,对于语言图像预训练,随机屏蔽和删除屏蔽图像块显示出比原始CLIP[72]快3.7倍的整体预训练时间。 重要性抽样。对数据的重要性采样,也称为数据剪枝,理论上可以通过优先考虑信息丰富的训练样本来加速监督学习的随机梯度算法,主要受益于方差减少。 对于 DNN,估计每个样本重要性的主要方法是使用梯度范数,并且 [47, 44] 使用不同的近似值 [47] 使这些规范的计算变得容易处理。 [70]进一步加速了类似于早鸟LTH的采样过程,但在数据域中,几个权重初始化上的简单平均梯度范数或误差范数可以用于在早期阶段识别重要的例子。训练。最近,[81]展示了一个令人兴奋的分析理论,即如果配备了卓越的数据修剪指标,测试误差随数据集大小的缩放可以突破幂缩放定律,并且至少可以减少到指数缩放,并且它采用了自我监督使用 k 均值聚类的度量。它展示了基于数据重要性采样的更有效的神经缩放法则的有前途的方向。 ----------------------- 内存高效: 对于DP来说,随着可用worker的增加,batch size接近线性缩放。 DP 具有较高的通信/计算效率,但当模型变大时,内存效率较差,单个设备无法存储模型副本,并且梯度的同步通信会阻碍 DP 的可扩展性。 因此,DP本身只适合训练中小型模型。为了提高DP的可扩展性,Transformer的一种解决方案是参数共享,称为Albert,但它限制了表示能力。 最近,ZeRO 将统一分区策略与 DP 结合起来,其中每个数据并行过程仅处理模型状态的一个分区,在混合精度状态下工作。为了处理非常大的 DNN,人们总是需要利用模型并行以“垂直”方式在多个加速卡上分配不同的层。 尽管MP具有良好的存储效率,但由于跨设备的大量数据传输和PE利用率较差,其通信和计算效率较低。幸运的是,有两种策略可以进一步提高 MP 效率。 张量并行(TP)和管道并行(PP)。 TP 将张量操作划分为跨worker的张量操作,以加快计算速度并节省更多内存。 就PP而言,它最初是在GPipe中提出的,它将输入的小批量分割成多个更小的微批量,使得不同的加速卡在应用之前同时处理不同的微批量。对于整个小批量使用单个同步梯度更新。然而,它仍然受到流水线气泡(加速器空闲时间)的影响,从而降低了效率。 特别是,PyTorch 实现了 torchgpipe ,它通过检查点执行微批次 PP,允许扩展到大量微批次以最小化气泡开销。 同时量化激活/权重/梯度降低精度训练之外, 激活压缩训练(ACT)在精确计算前向传递时存储激活的低精度近似副本,这有助于减少训练期间的总体内存消耗。 然后,保存的激活在向后传递中被反量化到原始精度以计算梯度。 重计算 与 Offload。再物化,也称为检查点[15],是一种广泛使用的时空权衡技术,它仅在前向传递期间存储一部分激活/权重,并在后向传递期间重新计算其余部分。 [15]提供了一个在 PyTorch 中实现的简单周期调度,但它仅对于同质顺序网络是最佳的。更先进的方法(例如[36])实现了异构网络的最佳检查点。就卸载而言,它是一种利用CPU内存等外部内存作为GPU内存的扩展,通过GPU和CPU之间的通信来增加训练过程中内存容量的技术。模型状态和激活可以卸载到 CPU,但最佳选择需要最大限度地减少与 GPU 之间的通信成本(即数据移动)、减少 CPU 计算并最大限度地节省 GPU 内存。 一个代表性的工作是 ZeRO-Offload [75],它提供了使用 Adam 优化器针对混合精度训练定制的最佳卸载策略。它将所有 fp32 模型状态和 fp16 梯度卸载到 CPU 内存上,并在 CPU 上计算 fp32 参数更新。 fp16参数保存在GPU上,前向和后向计算都在GPU上。为了两全其美,[7]建议联合优化激活卸载和重新实现。 参数高效调整。以HuggingFace为代表的公共模型动物园包含丰富的预训练模型,可供下载和执行,为降低训练成本做出了巨大贡献。 高效微调这些现成的模型正在成为大幅降低训练成本的流行方法。作为原版完全微调的强大替代方案,参数高效调整(PET)仅更新少量额外参数,同时冻结预训练模型以显着减少存储负担,可根据动态部署场景进行扩展,而无需为每种情况存储单独的模型实例。 一般的 PET 方法可以分为基于加法的方法和基于重新参数化的方法。前者将额外的可训练参数附加到预训练模型上,并且仅调整这些参数。例如,[53, 43] 将可训练参数添加到输入空间,[38] 在 MSA 和 FFN 之后将适配器模块添加到每个 Transformer 块中两次。然而,额外的参数在推理过程中引入了额外的计算和内存开销。 为了应对这一挑战,后者建议调整模型[94]中固有的参数或可以重新参数化到模型[39]中的新参数,从而不会牺牲推理效率。受大型语言预训练模型内在维度较低的观察启发[1],代表性工作LoRA[39]将自注意力权重的更新近似为两个低秩矩阵,可以在推理过程中合并到预训练权重中。 值得注意的是,最受认可的民主化努力之一是斯坦福羊驼[83],它是使用从ChatGPT生成的52K指令跟踪数据对开源LLaMA模型[86]进行微调的。为了廉价且高效地对其进行微调,其变体 Alpaca-LoRA 进一步采用低阶 LoRA 来支持在客户硬件上指令调整 LLaMA,表明可以在单个 RTX 4090 上在数小时内完成训练。 开源框架:Microsoft DeepSpeed、HPC-AI Tech Colossal-AI、Nvidia Megatron-LM DeepSpeed 主要基于[74]和ZeRO系列作品[73, 75]实现。 Colossal-AI 基于(Colossal-ai: A unified deep learning system for large-scale parallel training)构建。 Megatron-LM 基于 (Efficient large-scale language model training on gpu clusters using megatron-lm)实现。 所有这些都支持混合精度的数据和模型并行,以及卸载和重计算等其他通用实践。 更多用于高效分布式训练的库包括但不限于 HuggingFace Transformers、MosaicML Composer、百度 PaddlePaddle、Bytedance Lightseq、EleutherAI GPT-NeoX 等。 ---------------------- ---------------------- 硬件/算法协同设计 除了计算和内存负担之外,设计高效的硬件加速器还可以加快 DNN 的训练和推理速度。具体来说,与中央处理单元(CPU)相比,图形处理单元(GPU)由于并行度高,执行矩阵乘法的能力更强大。对于专注于特定计算任务的应用,专用集成电路(ASIC)具有低功耗和高训练/推理速度的优势。例如,谷歌设计的张量处理单元(TPU)的每瓦性能比当代 CPU 和 GPU 高 30∼80 倍 [45]。然而,ASIC 不容易重新编程或适应新任务。相比之下,现场可编程门阵列 (FPGA) 旨在根据需要重新编程以执行不同的功能,并且还可以在最终设计之前用作 ASIC 的原型。 为了进一步优化 DNN,特别是 Transformer 的训练效率,硬件算法协同设计在设计算法时考虑了硬件的约束和能力,这将在下面的小节中介绍。 --- 稀疏矩阵乘法。为了减少 Transformers 的计算开销,稀疏通用矩阵乘法(SpGEMM)涉及将稀疏矩阵与稠密矩阵相乘,利用注意力矩阵的稀疏性来减少计算量。 有几种流行的稀疏矩阵计算库,例如 Intel Math Kernel Library on CPU 和 cuSPARSE、CUSP 以及 GPU 上的 2:4 结构化稀疏性 [65]。 然而,由于不规则的稀疏性,SpGEMM 通常对通用处理器(例如 CPU 和 GPU)的硬件不友好。 为了解决这个问题,需要专门的硬件加速器(例如 FPGA 和 ASIC)来处理数据局部性较差的问题。例如,OuterSPACE [68]将矩阵乘法转换为外积过程,并通过将乘法与累加解耦来消除冗余内存访问。 为了在不引入大量开销的情况下充分利用这种优势,OuterSPACE 构建了一个具有可重新配置内存层次结构的定制加速器,与运行英特尔数学核心库的 CPU 相比,平均加速达到 7.9 倍,与运行 CUSP 的 GPU 相比,平均加速达到 14.0 倍。 此外,为了缓解高稀疏性引起的数据移动瓶颈,ViTCoD [91]使用可学习的自动编码器将稀疏注意力压缩为更紧凑的表示,并设计编码器和解码器引擎以提高硬件利用率。 --- 硬件感知的低精度。降低计算精度会减少内存和计算量,这可以以硬件友好的定点或整数表示形式(而不是浮点表示形式)来实现。因此,我们可以使用较低精度的乘法器、加法器和内存块,从而显着改善功耗和加速。此外,低精度算法可以与剪枝和低秩近似等其他技术相结合,以实现进一步的加速。 例如,Sanger [63] 使用 4 位Query和Key来计算稀疏注意力矩阵的量化预测。然后,稀疏注意力掩模被重新排列成结构化块并由可重新配置的硬件处理。 以下工作 DOTA [71] 使用低秩变换和低精度计算来识别注意力中不重要的连接。通过结合令牌级并行性和乱序执行,DOTA 比 GPU 实现了 152.6 倍的加速。 --- 高效的注意力。除了稀疏矩阵乘法和低精度计算之外,一些开创性的工作还专注于硬件中高效且轻量级的注意力实现[33,34,20]。 具体来说,A[33]仅选择那些可能与给定查询具有较高相似度的键,以减少注意力的计算量。 ELSA [34]根据哈希相似性过滤掉特定查询的不相关键以节省计算。凭借高效的硬件加速器,与配备 16GB 内存的 Nvidia V100 GPU 相比,ELSA 的加速速度提高了 58.1 倍,能源效率提高了三个数量级。 值得注意的是,FlashAttention [20] 提出利用平铺来减少 GPU 高带宽内存 (HBM) 和片上 SRAM 之间的 I/O 通信,这正在成为默认的快速且内存高效的注意力块,以实现加速。 ================================================ FILE: paper/LESS-选择有影响力的数据进行目标指令精调.md ================================================ - LESS: Selecting Influential Data for Targeted Instruction Tuning - https://github.com/princeton-nlp/LESS ================================================ FILE: paper/LLM增强LLMS.md ================================================ - https://github.com/lucidrains/CALM-pytorch - LLM AUGMENTED LLMS:EXPANDING CAPABILITIES THROUGH COMPOSITION ================================================ FILE: paper/PagedAttention.md ================================================ 许多LLM的参数大小超过了单个GPU的容量,因此有必要将它们跨分布式GPU进行分割在以模型并行方式下执行。这就要求内存管理器能够处理分布式内存。vLLM通过支持Megatron-LM风格的张量模型并行策略来在分布式设置中有效工作。这种策略遵循SPMD(单程序多数据)执行计划,其中线性层被分割以执行块矩阵乘法,并且GPU通过allreduce操作不断同步中间结果。具体来说,注意力运算在注意力头维度上被分割,每个SPMD进程处理多头注意力中的一个子集。 我们观察到,即使在模型并行执行的情况下,每个模型分片仍然处理相同的输入Token集,因此需要相同位置的KV缓存。因此,vLLM在调度器内设置了一个单一的KV缓存管理器,如图4所示。 不同的GPU workers 共享管理器以及从逻辑块到物理块的映射。这个共同的映射允许 GPU workers 使用调度器为每个输入请求提供的物理块来执行模型。虽然每个GPU worker 有相同的物理块ID,但worker只存储其相应注意力头的KV缓存的一部分。 在每一步中,调度器首先为每个请求准备包含输入Token ID的消息,以及每个请求的块表。 接下来,调度器将此控制消息广播给GPU workers。然后,GPU工作器开始使用输入Token ID执行模型。在注意力层中,GPU工作器根据控制消息中的块表读取KV缓存。在执行过程中,GPU工作器使用all-reduce通信原语同步中间结果,而不需要调度器的协调。最后,GPU工作器将本次迭代的采样Token发送回调度器。总之,GPU工作器不需要在内存管理上进行同步,它们只需要在每个解码迭代开始时以及步骤输入时接收所有的内存管理信息即可。 ================================================ FILE: paper/README.md ================================================ ================================================ FILE: paper/data/LESS 实践:仅用少量的数据完成目标指令微调.md ================================================ 之前的文章 [LESS:仅选择5%有影响力的数据优于全量数据集进行目标指令微调](https://juejin.cn/user/3642056016410728/posts) 中详细讲述了LESS,本文对其进行实践。 ## LESS 核心思想 LESS 核心思想通过仅给出**少数体现特定能力的示例**,从大量指令数据集中**有效地选择5%有影响力的数据**用于目标指令微调,结果优于全量数据集进行微调,并且所选子集在不同模型参数规模和不同模型系列中仍然普遍有效。 **数据选择流水线**: 1. 使用 LoRA 进行热身训练。 2. 构建了一个**投影低维梯度特征**的**梯度数据存储**,可以重复用于不同的目标任务。 3. 利用**数据选择算法**使用数据存储来构建训练数据集。 4. 使用选择的数据训练模型。 **实验关键结果**: 1. **LESS 在不同的模型中都是有效的** 2. **使用LESS 选择 5% 的数据通常优于完整数据集进行训练**。 3. **使用小模型选择的数据可以提高较大的模型和不同模型的性能**。 **LESS 存在的局限性**: 1. 需要使用候选数据 D 的随机 5% 进行**热身训练**。对于获得有用的梯度特征以进行数据选择至关重要,但增加了 LESS 的复杂性和计算负载 2. 使用补全Token的平均梯度,这增加了较短训练序列的权重,从而导致性能明显变差。为了缓解这个问题,对 **LESS 中的梯度特征进行归一化,并使用余弦相似度而不是点积来估计影响**。 3. 最小化验证损失(即交叉熵损失)不会单调提高准确性。 4. 一阶近似**忽略了将多个数据点添加在一起的影响**。特别是,两个重复的点将获得同样高的分数,并被认为可以双重改进模型,但情况可能并非如此。 ## LESS 应用 ### 环境安装 ``` pip3 install torch==2.1.2 torchvision torchaudio cd LESS pip install -r requirement.txt # 以可编辑模式安装 `less` 包,使其可供您的开发环境访问 pip install -e . ``` ### 数据准备 按照 [open-instruct](https://github.com/allenai/open-instruct?tab=readme-ov-file#dataset-preparation) 库来准备指令调优数据集。这里结合使用了四个训练数据集:Flan v2、COT、Dolly 和 Open Assistant。出于评估目的,还使用了三个额外的数据集:MMLU、Tydiqa 和 BBH。[此处](https://huggingface.co/datasets/princeton-nlp/less_data)提供了这些文件的处理版本。 ### 数据选择流水线 #### 1. 热身训练 为了提高数据选择的性能,预热训练步骤至关重要。通过选择整个数据集的一小部分来使用 LoRA 方法进行训练。 热身训练执行脚本: ``` DATA_DIR=../data MODEL_PATH=meta-llama/Llama-2-7b-hf PERCENTAGE=0.05 # percentage of the full data to train, you can specify the training file you want to use in the script DATA_SEED=3 JOB_NAME=llama2-7b-p${PERCENTAGE}-lora-seed${DATA_SEED} ./less/scripts/train/warmup_lora_train.sh "$DATA_DIR" "$MODEL_PATH" "$PERCENTAGE" "$DATA_SEED" "$JOB_NAME" ``` #### 2. 构建梯度数据存储 初始预热训练阶段完成后,将收集整个训练数据集的梯度。对于每个检查点,我们的目标是获取我们想要选择的所有训练数据的梯度。 执行脚本: ```bash CKPT=105 TRAINING_DATA_NAME=dolly TRAINING_DATA_FILE=../data/train/processed/dolly/dolly_data.jsonl # when changing data name, change the data path accordingly GRADIENT_TYPE="adam" MODEL_PATH=../out/llama2-7b-p0.05-lora-seed3/checkpoint-${CKPT} OUTPUT_PATH=../grads/llama2-7b-p0.05-lora-seed3/${TRAINING_DATA_NAME}-ckpt${CKPT}-${GRADIENT_TYPE} DIMS="8192" ./less/scripts/get_info/get_train_lora_grads.sh \ "$TRAINING_DATA_FILE" \ "$MODEL_PATH" \ "$OUTPUT_PATH" \ "$DIMS" \ "$GRADIENT_TYPE" ``` 创建的一个数据存储,包含了您希望从中选择的所有检查点和训练数据的梯度。 #### 3. 为任务选择数据 要为特定下游任务选择数据,首先使用与训练期间使用的相同的指令调优提示格式准备特定于该任务的数据。 这里为三个评估数据集设置了数据加载模块:BBH、TydiQA 和 MMLU。如果您对其他任务的数据选择感兴趣,可以扩展 `less/data_selection/get_validation_dataset.py` 脚本以适应这些任务。与获取训练数据的梯度类似,运行以下脚本。主要区别在于,此过程将根据影响力估计的公式生成验证数据的 SGD 梯度。 ``` CKPT=105 TASK=tydiqa MODEL_PATH=../out/llama2-7b-p0.05-lora-seed3/checkpoint-${CKPT} OUTPUT_PATH=../grads/llama2-7b-p0.05-lora-seed3/${TASK}-ckpt${CKPT}-sgd # for validation data, we always use sgd DATA_DIR=../data DIMS="4096 8192" # We use 8192 as our default projection dimension ./less/scripts/get_info/get_eval_lora_grads.sh "$TASK" "$DATA_DIR" "$MODEL_PATH" $OUTPUT_PATH "$DIMS" ``` 正常情况下,你获得在上一步中用于构建梯度数据存储的所有检查点的验证数据的梯度。 获得验证数据的梯度后,就可以为任务选择数据。以下脚本将计算每个训练数据点的影响力得分,并选择影响力得分最高的前 k 个数据点。 ```bash # decide which dimension to use DIM=8192 # checkpoing index CKPTS="105 211 317 420" # average lr of the epoch CHECKPOINT_WEIGHTS="1.6877e-05 1.2859e-05 7.7030e-06 2.5616e-06" GRADIENT_PATH=../grads/llama2-7b-p0.05-lora-seed3/{}-ckpt{}-adam/dim${DIM} TRAIN_FILE_NAMES="flan_v2 cot dolly oasst1" VALIDATION_GRADIENT_PATH=../grads/llama2-7b-p0.05-lora-seed3/{}-ckpt{}-sgd/dim${DIM} TARGET_TASK_NAMES="tydiqa" SELECTED_DATA_OUTPUT_PATH="../selected_data" ./less/scripts/data_selection/matching.sh \ "$GRADIENT_PATH" \ "$TRAIN_FILE_NAMES" \ "$CKPTS" \ "$CHECKPOINT_WEIGHTS" \ "$VALIDATION_GRADIENT_PATH" \ "$TARGET_TASK_NAMES" \ "$SELECTED_DATA_OUTPUT_PATH" ``` 每个训练数据点的影响力得分将保存在 `OUTPUT_PATH` 目录中。使用以下脚本来选择影响力得分最高的前 k 个数据点。 ``` python3 -m less.data_selection.write_selected_data \ --target_task_names ${TARGET_TASK_NAMES} \ --train_file_names ${TRAIN_FILE_NAMES} \ --train_files ../data/train/processed/dolly/dolly_data.jsonl ../data/train/processed/oasst1/oasst1_data.jsonl \ --output_path $SELECTED_DATA_OUTPUT_PATH \ --percentage 0.05 ``` #### 4. 使用选择的数据进行训练 选择数据后,使用以下脚本使用所选数据训练模型。 ```bash TARGET_TASK_NAME="tydiqa" PERCENTAGE=0.05 TRAIN_FILES=../selected_data/${TARGET_TASK_NAME}/top_p${PERCENTAGE}.jsonl MODEL_PATH=meta-llama/Llama-2-7b-hf JOB_NAME=llama2-7b-less-p${PERCENTAGE}-lora ./less/scripts/train/lora_train.sh "$TRAIN_FILES" "$MODEL_PATH" "$JOB_NAME" ``` > 注意:这里您也可以通过删除 lora 训练参数来执行全参数微调。 ### 评估 这里使用三个评估数据集(MMLU、Tydiqa 和 BBH)来评估数据选择流水线的性能:。使用评估流水线 open-instruct。按照以下步骤操作评估经过训练的模型,请: #### 1:安装 Open-Instruct ``` git clone https://github.com/allenai/open-instruct.git cd open-instruct pip install -e . ``` #### 2:评估 查看 [`evaluation`](https://github.com/princeton-nlp/LESS/tree/main/evaluation) 目录中的 `eval_mmlu.sh` 、 `eval_tydiqa.sh` 和 `eval_bbh.sh` 脚本。这些脚本包含在相应数据集上评估模型所需的命令。`eval_bbh.sh` 脚本如下: ``` source eval.sh # 主评估函数 eval_bbh() { cd $n/space10/open-instruct mdir=$1 type=$2 set_save_dir $mdir bbh mkdir -p $save_dir cmd="python -m eval.bbh.run_eval \ --data_dir $DATA_DIR/bbh \ --save_dir $save_dir \ --model $mdir \ --tokenizer $mdir \ --eval_batch_size 10 \ --convert_to_bf16 \ --max_num_examples_per_task 40" eval "$cmd" } # 评估校验集,目前还不支持 valid_bbh() { cd $n/space10/open-instruct mdir=$1 type=$2 set_valid_dir $mdir bbh echo $save_dir mkdir -p $save_dir cmd="python -m eval.bbh.run_eval \ --data_dir $DATA_DIR/bbh-valid \ --save_dir $save_dir \ --model $mdir \ --tokenizer $mdir \ --eval_batch_size 10 \ --convert_to_bf16 \ --eval_valid \ --max_num_examples_per_task 3" } # 提取结果 extract_bbh() { mdir=$1 set_save_dir $mdir bbh-nonchat result=$(jq .average_exact_match $save_dir/metrics.json) result=$(echo "$result * 100" | bc) echo $result } # 提取验证集的结果 extract_valid_bbh() { mdir=$1 set_valid_dir $mdir bbh-nonchat result=$(jq .average_exact_match $save_dir/metrics.json) result=$(echo "$result * 100" | bc) echo $result } ``` ## 结语 本文简要介绍了 LESS 的核心思想,同时讲述了 LESS 的应用实践。 码字不易,如果觉得我的文章能够能够给您带来帮助,期待您的点赞收藏加关注~~ 参考文档: - 论文:LESS: Selecting Influential Data for Targeted Instruction Tuning - 代码:https://github.com/princeton-nlp/LESS ================================================ FILE: paper/data/LESS-选择有影响力的数据进行目标指令精调.md ================================================ - LESS: Selecting Influential Data for Targeted Instruction Tuning - https://github.com/princeton-nlp/LESS ================================================ FILE: paper/data/LESS.md ================================================ 本文给大家分享一篇论文(LESS: Selecting Influential Data for Targeted Instruction Tuning),通过选择有影响力的少量数据进行目标指令调优。 以下是省流版: ## LESS 核心思想 LESS 核心思想通过仅给出的**少数体现特定能力的示例**,从大量指令数据集中**有效地选择5%有影响力的数据**用于目标任务的指令微调,其结果优于全量数据集进行微调,并且所选子集在不同模型参数规模和不同模型系列中仍然普遍有效。 **数据选择流水线**: 1. 使用 LoRA 进行热身训练,有利于后续获得有用的梯度特征。 2. 构建了一个**投影低维梯度特征**的**梯度数据存储**,可以重复用于不同的目标任务。 3. 利用**数据选择算法**使用存储梯度数据来构建训练数据集(少量有影响力的数据)。 4. 使用选择的数据训练模型。 **实验关键结果**: 1. **LESS 在不同的模型中都是有效的。** 2. **使用 LESS 选择 5% 的数据通常优于完整数据集进行训练**。 3. **使用小模型选择的数据可以提高较大的模型和不同模型的性能**。 **LESS 存在的局限性**: 1. 需要使用候选数据 D 的随机 5% 进行**热身训练**。这对于获得有用的梯度特征以进行数据选择至关重要,但**增加了 LESS 的复杂性和计算负载**。 2. 使用补全Token的平均梯度,这增加了较短训练序列的权重,从而导致性能明显变差。为了缓解这个问题,对 **LESS 中的梯度特征进行归一化,并使用余弦相似度而不是点积来估计影响**。 3. 最小化验证损失(即交叉熵损失)不会单调提高准确性。 4. 一阶近似**忽略了将多个数据点添加在一起的影响**。特别是,两个重复的点将获得同样高的分数,并被认为可以双重改进模型,但情况可能并非如此。 以下是完整版: ## 0. 摘要 LESS是一种优化器感知且实用和有效的算法,可**有效估计数据影响**并执行**低秩梯度相似性搜索**(Low-rankgradiEnt Similarity Search)以进行指令数据选择。更重要的是,LESS 兼容现有的影响力公式,以与 **Adam 优化器**和**可变长度指令数据**一起使用。 LESS 首先构建具有**低维梯度特征**的高度**可重用和可转移的梯度数据存储**,然后根据它们与**体现特定能力的少数示例数据**的**相似性**来选择有影响力的示例。 实验表明,在不同下游任务中,对选择的 5% 数据进行训练通常可以优于对完整数据集进行训练。此外,所选数据具有高度可转移性:即**可以利用较小的模型为较大的模型和来自不同系列的模型选择有用的数据**。通过定性分析表明,我们的方法超越了表面形式线索,**可以识别能够体现预期下游应用所需推理技能的数据**。 ## 1. 简介 指令微调使得大语言模型善于遵循人类指令,成为多功能聊天机器人。然而了解如何最好地利用这些不同的数据集仍然是一个悬而未决的问题。 许多现实世界的应用程序要求训练LLMs中有一套特定能力(例如,推理技能)。然而,使用混合指令微调数据集训练 LLMs 可能会阻碍这些特定功能的开发。例如,在混合指令微调数据集上训练的 LLMs 表现出的性能比在数据子集上训练的性能更差。此外,考虑到广泛的用户查询以及响应这些查询所需的多种技能,可能**并不总是有足够的域内数据可用**。因此,我们希望能够**有效地利用通用指令微调数据来提高特定能力**。我们将此设置作为目标指令微调: > 仅给出**少数体现特定能力的示例数据**,我们如何从大量指令数据集中有效地选择相关的微调数据? 我们通过对**最小化目标任务损失的数据**进行优先训练来解决这个问题,而不是依赖于表面形式特征。受到过去的工作**利用梯度信息估计单个训练数据点的影响**的启发,我们设计了一种**优化器感知方法**来选择此类数据。然而,这种影响力公式的直接应用面临着指令调优设置特有的几个挑战: - 1. LLMs 传统上是**使用 Adam 优化器而不是**过去工作中考虑的**标准的 SGD 优化器**进行微调; - 2. 使用可变长度指令数据的**序列级梯度可能会破坏影响估计**; - 3. LLMs中大量的可训练参数使得**梯度的计算和存储极其消耗资源**。 我们在 LESS 中解决了这些问题,LESS 是一种执行**低秩梯度相似性搜索**来为目标应用程序选择相关指令微调数据的算法,它具有以下属性: - **与 Adam 的指令微调兼容**:LESS 采用经典影响力公式中的梯度特征,同时与 Adam 优化器和可变长度指令数据配合使用。当然优化洞察(insights)和影响力公式也可能具有独立的意义。 - **高效**:LESS 使用 **LoRA 和随机投影**构建具有低维、易于计算梯度特征的**梯度数据存储**,从而允许高效且有效的数据集选择。梯度数据存储可以重复用于新的目标任务。 - **可转移**:使用小模型的梯度特征选择的数据会在大型模型和来自不同系列的模型中产生强大的性能,从而提高 LESS 的效率。 - **可解释**:定性分析表明,LESS 选择具有**相似推理和技能类型**的数据作为目标任务,而现有方法通常根据表面形式线索(例如:语言或主题)选择数据。 我们在三个不同的下游数据集(MMLU、TYDIQA 和 BBH)上评估我们的方法,每个数据集都包含不同的子任务,可以有效地模拟目标指令微调场景。 结果表明,LESS 通常会选择一小部分数据子集 (5%),其性能优于整个数据集上的训练,并且所选子集在不同模型参数规模和模型系列中仍然普遍有效。 与其他数据选择方法的比较表明,**LESS 是唯一一致有效的方法**,证明其相对**较高的计算成本**是合理的。 ## 2. 准备工作:影响力公式 使用训练时动态的一阶近似来**估计训练数据点对保留数据的影响**。 **每一步(step)的影响**。考虑一个模型 $\theta^t$ 在时间步$t$上训练损失 $\ell(\cdot;\theta)$ 。我们可以在验证数据点 $z'$ 上写出损失的一阶泰勒展开式: $$ \ell(z';\theta^{t+1}) \approx \ell(z';\theta^t) + \langle\nabla\ell(z';\theta^t), \theta^{t+1}-\theta^t\rangle $$ 为了便于说明,假设我们使用批量大小为 $1$、学习率为 $\eta_t$ 的 SGD 来训练模型。如果 $z$ 是时间步 t 的训练数据,我们可以将 SGD 更新写为 $\theta^{t+1} - \theta^t = -\eta_t \nabla\ell(z;\theta^t)$。那么泰勒展开式可以写为 $$ \ell(z';\theta^{t+1}) - \ell(z';\theta^t) \approx -\eta_t \langle\nabla\ell(z;\theta^t), \nabla\ell(z';\theta^t)\rangle $$ **轨迹影响**。 z 对**整个训练运行的影响**可以通过聚合使用 z 的每个训练step的影响来测量。由于 z 被每个epoch使用一次,因此很自然地将其表示为epochs的总和: ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/39b29be9b5624e989361030565cf0b41~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1008&h=164&s=32206&e=png&b=ffffff) 其中, $\bar\eta_i$是 N 个总训练epochs中第 i 个epoch期间使用的学习率。 Pruthi et al. (2020) 使用这种洞察(insights)来**识别错误标记的训练数据**,我们应用这个公式来**设计数据选择策略**。特别是,选择 z 来最大化 $$ \langle \nabla \ell(z';\theta^t), \nabla \ell(z;\theta^t)\rangle $$ 将**导致验证点 $z'$ 上的损失大幅减少**。值得注意的是,$z'$ 不一定与训练数据 z 直接相关,这使得该**数据选择策略在迁移学习设置中特别有用**。 接下来的两节描述我们如何采用这种基本方法通过指令微调来高效且有效地运行。 ## 3. LESS:评估指令的影响力 在这里,我们描述 LESS 如何适应等式(1)中的影响力公式来选择有效促使目标能力的指令。我们在这里考虑两个主要的概念挑战: - (1) 第 2 节中描述的过去的工作重点是使用 SGD 优化器,但 LLMs 传统上使用 Adam 进行调优。 - (2) **指令微调表现出异常梯度这导致先前的公式非常倾向于选择较短的指令,从而损害性能**。 > 我们遵循指令调优的标准自回归设置,其中,数据点z由指令s和补全c组成。对于每个数据点,损失为$\ell(z;\theta)$是模型分布$p(\cdot\vert s)$与真实标签c之间的交叉熵。当c包含多个tokens时,我们使用补全过程中token-wise交叉熵的平均值作为z的损失。我们使用$θ_t$表示第t步的模型,使用$θ_i$表示第i次训练之后的模型。 ### 3.1. 扩展到 Adam 算法 等式 (1) 的公式是使用SGD优化模型所特有的。然而,指令调优通常使用 Adam 优化器进行。在这种情况下,给定步骤的参数更新为: ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8bb740adc4a548af98fef8cbb6fbd600~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1008&h=352&s=70543&e=png&b=ffffff) 其中,所有操作均按元素执行,$\beta_1$ 和 $\beta_2$分别作为一阶矩和二阶矩的超参数,$\epsilon$ 作为一个小常数。然后,Adam 动力学的一阶展开表明我们应该选择 z 来最大化 $\langle \nabla \ell(z';\theta^t), \Gamma(z;\theta^t)\rangle$。 然而,**使用此内积来测量轨迹影响需要在训练过程中访问模型梯度和优化器状态**。此外, $\Gamma(z;\theta)$ 需要 m 和 v 项,这些项由先前的训练梯度确定。 总的来说,**这个公式使数据选择问题成为一个循环问题,因为每个点的影响取决于所选点的集合**。根据经验,我们可以通过在随机选择的完整数据集 D 的 5% 上运行 N = 4 个epochs的短期warmup训练来规避这些问题。我们在影响计算中使用本次运行的优化器状态作为$\Gamma(z;\theta_i)$。 ### 3.2. 解决序列级梯度的异常问题 将第 2 节应用到指令微调设置中会认为示例 z 的梯度是补全c中每个Token的梯度的平均值。然后,我们将选择在每个序列中训练哪些Token,以便最好地减少验证损失。然而,估计单个Token的影响非常昂贵,因为它需要计算Token损失向量相对于模型参数的梯度,因此我们改为在序列级别执行数据选择。 由于示例梯度是许多 token 梯度的平均值,因此序列的**梯度范数** $$ ||\nabla \ell(z;\theta^t)|| $$ **与补全c的长度负相关**(图 3 和图 4)。对于计算不同长度序列的平均Token梯度的影响公式来说,这是一个普遍问题。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b0f712cf9aea431c8eb780272f07c22a~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1058&h=527&s=117781&e=png&b=ffffff) 这种现象导致等式(1)中的影响大大**增加了较短训练序列的权重,这反过来又导致性能明显变差**(见表12)。为了缓解这个问题,我们对 **LESS 中的梯度特征进行归一化,并使用余弦相似度而不是点积来估计影响**。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a333bef24ad44d0e82f20c56ff394c18~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1059&h=279&s=83539&e=png&b=fefefe) **公式 3.1 Adam Influence**:假设模型经过 N 个 epoch 的训练,其中 $\bar\eta_i$ 是第 i 个 epoch 的平均学习率,$\theta_i$ 是第 i 个 epoch 之后的模型检查点。当与Adam一起训练时,我们将训练数据点 $z$ 对验证数据点 $z'$ 的影响定义为 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/027e63a2848e4ccbb2b38db5bdcdabfd~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=866&h=188&s=42019&e=png&b=ffffff) ## 4. LESS:有效评估影响力 我们已经确定了如何**使用模型梯度来估计影响**,但考虑到 LLMs 的庞大规模,计算和存储模型梯度仍然非常昂贵。在本节中,将探讨**降低计算效率的设计**,并说明图 1 中的计算步骤。 ![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0c5bc9064be344b597932284b26f3d68~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1068&h=341&s=139108&e=png&b=f8f7f7) - 我们使用 LoRA 来有效地进行 warmup 训练,有利于后续获得有用的梯度特征。 - 然后,我们构建了一个**投影低维梯度特征**的**梯度数据存储**,可以重复用于不同的目标任务。 - 最后,我们详细介绍了我们的数据选择算法如何使用数据存储来构建训练数据集,以容纳目标验证集中的子结构(例如:推理技能)。 **设置**。我们的目标是大量、多样化的指令微调数据集 $D$ 中选择子集 $D_{train}$,以便在 $D_{train}$ 上训练模型可以在目标验证数据集 $D_{val}$ 上实现较低的损失,从而在测试数据上表现良好。 $D_{val}$ 可以包含多个子任务 $D_{val}^{(1)}, ..., D_{val}^{(m)}$(例如,多种语言的问答)。验证集是固定的,每个子任务仅包含几个示例(例如,TYDIQA 中每种语言 1 个示例)。我们使用保留的测试集 $D_{test}$ 来评估在 $D_{train}$ 上训练的模型的性能。 我们使用 $M_S$ 表示用 $\theta$ 参数化的模型,用于评分和选择数据;并使用 $M_T$ 表示在所选数据上训练的模型。 **选择模型$M_S$不需要与目标模型$M_T$相同,在这种情况下,我们将该设置称为LESS-T**。 ### 4.1. 高效的梯度特征计算 **计算定义公式 3.1** 需要计算两个向量的内积,其中可训练参数的大小为该模型。**直接使用这样的高维梯度向量作为数据集选择的特征在计算上非常昂贵**,因此我们**应用两种技术**来构造有意义的**低维梯度特征**: 通过 LoRA 进行参数高效微调和随机投影。我们将这些技术应用于 ∇ℓ(z′; θ) 来验证数据点 $z'$,并将这些技术应用于 Γ(z, θ) 来训练数据点 z。为了能够快速转移到新的目标验证任务,我们为候选训练数据点创建了一个具有这些低维特征的数据存储区。 第 1 步:**使用 LoRA 进行热身(Warmup)训练**。我们用LoRA减少可训练参数的数量并加速**定义 3.1** 中的内积计算。 LoRA 冻结预先训练的权重,并向整个网络的全连接层添加低秩适配器。我们使用 LoRA 在随机子集 $D_{warmup} ⊂ D$ 上对预训练的基础模型(例如: LLAMA-2-7B)进行 N 个epochs的指令调优,在每个epoch之后对模型进行checkpointing以存储 $\{\theta_i\}_{i=1}^N$。 使用 LoRA 训练时的梯度,表示为 $\hat{\nabla} \ell( . ;\theta) \in \R^{P}$ ,比模型本身的维度低得多;例如,在 LLAMA-2-7B中,$\hat{\nabla} \ell(.;\theta)$ 小于 θ 大小的 2%。我们使用 $\hat{\nabla} \ell(.;\theta)$ 来计算 Adam 更新,并将其表示为$\hat{\Gamma} \ell(.,\theta)$。这种**初始热身训练**的动机是在第 3.1 节中,第 6.1 节中的经验结果表明,省略它会产生次优结果。 第 2 步:**投影梯度**。为了进一步降低特征维度,我们**对 LoRA 梯度应用随机投影**。 Johnson-Lindenstrauss 引理断言**此类投影通常保留定义 3.1 中的内积,从而确保这些低维梯度特征对于数据集选择仍然有用**。 对于给定的验证数据点 $z'$ 和模型检查点 $\theta_i$,我们可以计算 LoRA 梯度的 d 维投影 $\tilde{\nabla} \ell(z';\theta_i) = \Pi^\top \hat{\nabla} \ell(z';\theta_i) $,其中$\Pi \in \R^{P\times d}$的每个条目从 Rademacher 分布中绘制 (即$\Pi_{ij}\sim \mathcal{U}(\{-1,1\})$)。 对于训练数据点 z,我们计算$\tilde{\Gamma}({z} , {\cdot}) = \Pi^\top\hat{\Gamma}({z},{\cdot})$。我们使用内存高效在线随机投影实现去计算并应用 $\Pi$。实际上,我们选择 $d = 8192$。 ### 4.2. 数据选择算法 数据选择策略(参见图 1 中的步骤 3)采用第 2 节中的方法来有效地操作验证集的子任务(例如:BigBench 中的各个任务)。对于每个子任务 D,我们计算每个模型检查点 $\theta_1,...,\theta_N$ 的平均梯度特征。 ![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3d7680804ef947e3975e472354859e3b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=373&h=83&s=11303&e=png&b=ffffff) 如定义 3.1 所示,然后我们在整个训练过程中汇总给定数据点与每个验证子任务的接近程度的分数。例如,我们可以将定义3.1改写为 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/63101746f39b4f5f8b3ea267a97c623b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=519&h=91&s=18036&e=png&b=ffffff) 我们选择可以提高任何一项验证子任务性能的训练数据点。按照公式2中的逻辑,我们计算 z 的分数作为所有子任务的最大值:$\max_j Inf_{Adam}(z, \mathcal{D} _{val}^{(j)})$ 。我们选择得分最高的例子来构造$D_{train}$。选择后,我们使用选择的子集$D_{train}$来训练目标模型$M_T$。 ## 5. 实验结果 ### 5.1.实验装置 **训练数据集**。使用以下指令调优数据集: (1) 从现有数据集创建的数据集,例如:FLAN V2 (Longpre et al., 2023) and COT (Wei et al., 2022c); (2) 具有人工编写答案的开放式生成数据集,包括 DOLLY (Conover et al., 2023) 和 OPEN ASSISTANT。 这些数据集的格式和底层推理任务差异很大。训练数据集不包含目标查询的任何明显的域内数据。 **评估数据集**。我们在 MMLU (Hendrycks et al., 2020), TYDIQA (Clark et al.,2020) 和 BBH (bench authors, 2023) 上评估我们的方法。 MMLU 包含多项选择题,涵盖 57 个任务,包括初等数学、美国历史、计算机科学、法律等。 TYDIQA 是一个多语言问答数据集,包含 11 种类型不同的语言。给定一个问题和相关段落,该任务需要从段落中提取答案。 BBH 是 BIG-Bench 中用于评估推理能力的 27 项挑战性任务的集合。 表 1 包含有关这些任务的更多详细信息。每个数据集都包含多个子任务,每个子任务都带有少量示例。这些示例用作数据选择(第 4.2 节)的 $D_{val}$ 以及评估中的少量上下文学习演示。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/15e5e280980f4f35a44dda61f0880aff~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=536&h=205&s=36930&e=png&b=ffffff) **用于数据选择和训练的模型**。我们测试LESS具有三个base模型:LLAMA-2-7B ,LLAMA-2-13B 和 MISTRAL-7B。在迁移设置(如:LESS-T)中,我们数据选择使用LLAMA-2-7B作为$M_s$,并训练LLAMA- 2-13B 或 MISTRAL-7B 作为目标模型 $M_T$ 。预热训练和最终模型训练均使用LoRA进行。我们的报告中使用了三个随机种子的平均性能和标准差。 **默认设置**。 LESS 对随机选择的完整数据集的 5% 进行 4 个 epoch 的预热训练,并计算数据 D 上的 8192 维梯度特征(第 4.1 节)。对于每个目标任务,我们使用这些特征根据其影响对数据点进行评分(定义 3.1)并选择$D$中得分最高的5%来构建$D_{train}$。我们在这个选定的数据$D_{train}$上训练目标模型$M_T$ 。 ### 5.2.基线 我们将 LESS 与几个baseline进行比较。 最简单的baseline是**随机选择**,我们从训练集中随机采样数据以进行指令调优。 我们还与 BM25进行比较,后者通过词频统计(即 TF-IDF)来对示例进行特征化,以对训练实例进行排名。我们测量候选训练数据 D 和验证数据 $D_{val}$ 之间的相似度,并选择相关性得分最高的前 k 个数据点来构建 $D_{train}$。 另一个baseline是 DSIR,它使用 n-gram,然后根据这些估计的权重对数据进行采样以构造 $D_{train}$。 我们还与 RDS(基于表示的数据选择)进行比较,后者使用模型的隐藏表示作为数据选择的特征。 为了公平比较,我们使用等式(2)**计算相似度得分**,但用每个序列最后一个token的最后层表示替换梯度特征。这些特征在 LLAMA-2-7B 中是 2048 维的。我们考虑的另一个直观baseline直接**使用验证数据 $D_{val}$ 进行训练,但这会大大降低性能**。 ### 5.3. 关键结果 - **LESS 在不同的模型中都是有效的**。表2显示在所有模型和评估数据集中,LESS 始终优于随机选择 2 到 5 个点,这表明我们的数据选择方法选择有用的数据进行微调。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bfd337ec2aea496a94a356c5a42692cd~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1059&h=312&s=118759&e=png&b=ffffff) - **5% 的数据通常优于完整数据集**。在表 2,我们比较了使用 LESS 选择的 5% 数据进行的训练和使用完整数据集进行的训练。令人惊讶的是,我们发现在大多数情况下,仅使用 5% 的数据进行训练会比使用整个数据集产生更好的结果。我们假设**完整数据集包含与特定目标任务无关或有害的数据点**。当使用更强的基础模型(例如:LLAMA-2-13B 和 MISTRAL-7B)时,这种效果更加明显。 > 我们注意到,被丢弃的 95% 中可能仍然有有用的数据,我们将探索未来工作的最佳阈值。 - **使用小模型选择的数据可以提高较大和不同模型的性能**。表 2 评估了几种 LESS-T 设置。我们使用 LLAMA-2-7B 作为选择数据的模型并训练 LLAMA-2-13B (即更大的模型)和 MISTRAL-7B ((即不同的模型系列)作为目标模型 $M_T$。LESS-T 优于随机选择,与LESS(即直接使用LLAMA-2-13B 或 MISTRAL-7B作为选择模型$M_S$)相比差距较小。 LESS-T 的强大性能表明 LESS 选择了普遍有用的数据,因此数据选择成本可以进一步摊销到不同的模型中。从概念上讲,我们在第 2 节中的推导指出,**当不同examples的梯度内积对于 $M_S$ 和 $M_T$ 大致相等时**,**使用一种模型选择的数据集会在另一种模型中产生强大的性能**。我们的实验证实这一发现是正确的,因此,在预训练和上下文学习中,小模型可以有效地为其他模型选择数据。 - **与其他 baseline 相比 LESS 是唯一持续有效的方法**:在表 3 中,我们将 LESS 与几个基线进行了比较。我们观察到依靠**词频统计**(例如:BM25)、n-gram 特征(例如:DSIR)或表示(例如:RDS)的传统方法相对于随机选择的改进很小,并且 LESS 始终优于最强的基线。我们承认基线方法的计算成本较低。尽管如此,我们的研究结果表明,**指令数据需要对数据点之间的相似性进行精确定义**(即,定义 3.1 中的影响力公式)。尽管基线方法通常选择与查询和补全在主题或语义上相似的数据,但定性分析(第 6.2 节)表明**LESS更擅长选择与目标任务$D_{val}$需要相同推理过程(即:指令如何执行)的数据**。 ## 6. 分析 我们通过两种方式来分析 LESS。首先,我们详细介绍了 LESS 的计算成本,并探讨了不同的设计选择如何影响性能(第 6.1 节)。其次,我们提出了定性分析,表明了 LESS 选择了与目标任务所需的推理能力相符的数据(第 6.2 节)。 ### 6.1. 计算复杂度 表 4 描述了 LESS 每一步所需的渐近复杂度、运行时间(wall-clock runtime)和存储成本。表中的运行时间以单个 A100 (80GB) GPU 小时来测量。**梯度特征计算是最昂贵的步骤**,并且成本与候选数据集大小 |D|、检查点数量 N 和梯度维度 d 线性增长。存储结果的梯度数据存储所消耗的内存与d成线性比例。热身训练也相对昂贵,并且复杂性随着 $|\mathcal{D}_{warmup}|$ 和 N 的变化而变化。然而,这两个阶段产生的费用是一次性成本,可以在许多目标任务中摊销。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8344565bcedd442ba7ec826cac303940~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1060&h=254&s=90139&e=png&b=ffffff) 在以下部分中,我们将探讨 $|\mathcal{D}_{warmup}|$ 、N 和 d 的选择如何影响 LESS 的性能。总之,增加 $\mathcal{D}_{warmup}$ 和 N 可以提高影响评估的准确性(定义 3.1),但这样做也会增加预热训练步骤的成本。同样,增加 d 可以提高投影梯度特征的效用,但这样做也会增加 LESS 所需的内存和计算量。 **热身训练至关重要**。热身训练步骤在 $\mathcal{D}_{warmup}$ 上微调模型,通常是数据 D 的随机 5%。我们调查: - (1) 是否此步骤是必要的 - (2) 使用更多数据是否可以进一步提高性能。 对于(1),我们使用预训练的 LLAMA-2-7B 和 LLAMA- 2-7B-CHAT 作为选择模型来创建用于选择数据的梯度数据存储。表 5 表明,使用预训练的模型进行数据选择会严重损害LESS的性能。这一观察结果可能源于**输入分布的变化**,或者更一般地说,源于**训练动态中的细微差别**。我们将详细的调查留给未来的工作。 对于 (2),我们将 $\mathcal{D}_{warmup}$ 的大小更改为 5%(默认值)、25% 和整个数据集并计算 $Inf_{adam}$。增加$\mathcal{D}_{warmup}$提高性能,证实了我们的假设,即更准确地估计 $Inf_{adam}$(定义 3.1)是有帮助的。因此,**预热阶段至关重要,但不需要太长的时间,LESS 就能产生强劲的性能**。 **更多检查点,更好的性能**。我们调查在热身训练阶段使用较少的检查点(即对定义 3.1 中较少的梯度特征进行求和)是否会影响 LESS 的性能。表 6 显示,仅使用一个 LoRA 检查点的性能优于随机选择,但低于使用四个检查点的性能。我们推测这是因为梯度特征在指令调优开始时发生了很大变化。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/837fcde19b974c63b2957fe439a93e75~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=516&h=259&s=46708&e=png&b=ffffff) **小的投影维度就足够了**。我们学习选择不同的梯度投影维度 d,特别是 1024、2048、4096 和 8192(默认),如何影响 LESS 的性能。图 2 显示,d 的所有选择都比随机选择提高了性能,并且随着 d 的增加,LESS 以更高的计算成本产生更强的性能(参见表 4)。 ![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/39920516f9df48b899f6ea87ffaf3a4b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=520&h=431&s=54333&e=png&b=ffffff) ### 6.2. 定性分析 我们手动比较 LESS 和 baseline 方法选择的数据。表 15 显示了 BM25、RDS 和 LESS 选择的top示例,给出了来自TYDIQA数据集的单个孟加拉语问答示例。 **BM25 和 RDS 只是简单的匹配少样本(few-shot)数据**$\mathcal{D}_{val}$,并从不同的任务中选择孟加拉语示例(掩模恢复和仇恨言论检测)。 相比之下,LESS 从类似于 TYDIQA 的开卷问答任务中选择英语示例。此示例表明,**LESS 选择具有相似底层推理类型的示例,而不会严重依赖表面文本或语言提示**。尽管使用不同的语言,此类示例仍然可以有效地零样本(zero-shot)迁移到孟加拉语。 此外,我们观察到LESS从DOLLY数据集中为TYDIQA选择了更多的例子,可能是因为DOLLY包含了许多开卷问答的例子。我们的研究结果表明,**LESS 可用于提高大型通用指令微调数据集的可解释性**。 ## 7. 相关工作 ### 7.1. 整理高质量的指令调优数据 使用高质量的指令调优数据可以显著提高 base LLMs。指令调优数据通常有两种类型: - (1)从传统 NLP 任务中收集的基于任务的数据集 - (2)开放式指令遵循数据集,涵盖广泛的主题。 事实证明,**提高数据质量和多样性而不是数量可以更有效地诱导指令遵循能力**。我们的工作通过从大量可用数据集中选择高质量的相关数据来丰富这一叙述,以在模型中引入特定的能力。 ### 7.2. 核心集和基于梯度的数据选择 数据集选择问题被视为核心集选择问题,**其目的是找到训练示例的子集,从而产生与完整数据集训练类似的性能**。通常这些工作侧重于**领域内核心集选择**,而我们的工作涉及**迁移学习**。 之前的几项工作使用预定义的有用数据概念或 n-gram 特征来选择预训练示例,但 LESS 更接近类似于对梯度信息的依赖。我们的工作最接近 Han et al. (2023),它使用模型梯度来选择预训练数据以提高上下文学习性能。然而,我们的离线方法可以非常有效地适应新的下游任务。 ### 7.3. 数据归因和影响函数 我们的影响力公式已被用于**识别错误标记**的例子、分析记忆效果以及得出各种可解释性见解,但它**不允许反事实推理**。 另一方面,影响力函数**可以对模型行为和训练数据进行反事实推理**,但一些研究发现其**鲁棒性和有效性存在局限性**。 在 LLM 场景中,影响力函数的计算成本很高,尽管一些并发工作提出**使用高效的影响力函数估计来选择预训练数据**。我们的研究结果表明,一阶影响力近似对于迁移学习环境中的数据选择是有效的。 ## 8. 讨论和未来的工作 我们提出了一种**基于优化器感知影响力的数据选择算法** LESS。 LESS 创建了一个有效且可重用的低维梯度特征的数据存储,以实现高效的数据选择。第 5 节中的实验证明了 LESS 与相关基线相比的有效性,并强调了**使用较小模型选择数据来训练较大模型的能力**(表 2)。第 6 节中的分析和消融实验表明,我们的方法**选择了更多可解释的数据,但计算成本可能很高**。 将来,LESS 可以有效地用于测试时间自适应,使模型能够适应根据用户提供的上下文和示范来选择的数据。此外,我们可以**修改数据选择过程,以最小化任何可微分指标**(例如,毒性和危害性的替代指标),而**不仅仅是交叉熵损失**。此外,我们的实验发现可能会促使我们进一步研究**梯度特征在数据选择中的作用,而不是表面形式线索**。对优化特性和序列级梯度现象(第 3.2 节)的见解可能具有理论意义。 我们观察到,调**优更多数据会降低特定任务的性能,这也可能与 LLMs 中观察到的灾难性遗忘行为密切相关**。 ## 9. 局限性 1. **需要热身训练阶段**。预热训练阶段对于获得有用的梯度特征以进行数据选择至关重要。显然,我们必须微调base模型以与我们打算选择的特定数据分布保持一致,因为直接利用 LLAMA-2-7B 或者 LLAMA-2-7B-CHAT 等预训练模型的梯度并不有效(表5)。这一额外步骤增加了 LESS 的复杂性和计算负载。 2. **使用补全Token的平均梯度**。 所有补全Token的平均梯度用作代表整个序列的代理。在训练或验证数据中涉及较长序列的场景中,例如:开放式生成,这种合并可能会变得更加模糊且效率较低。在第 3.2 节中,我们重点介绍了此操作如何导致数据选择流水线中出现异常。 3. **最小化损失不会单调提高准确性**。最小化验证损失(即交叉熵损失)并不总能提高指令调优中的任务性能。这是因为指令调优任务通常需要模型产生长格式的生成。尽管困惑度与base LLMs 中的任务表现非常一致,但在微调或指令调优中,这种关系更加模糊。 LESS 的动机是选择最小化验证损失的数据点(第 2 节),这种策略通常会产生高准确性模型(表 2),但最小化损失并不能单调提高准确性(见附录I,图 5 和图 6 )。 4. **数据选择中的线性度**:第 2 节中的**一阶近似忽略了将多个数据点添加在一起的影响**。特别是,**两个重复的点将获得同样高的分数,并被认为可以双重改进模型,尽管情况可能并非如此**。 Saunshi et al. 的初步理论 (2023) 讨论了影响力何时可以线性增加,但总的来说,我们认为这种近似是 LESS 的限制。 ![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/93dd482656de4175a9f73a5f726243bb~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1062&h=694&s=126386&e=png&b=fff9f9) ## 结语 本文介绍了一种数据选择的方法 LESS及其技术原理。 码字不易,如果觉得我的文章能够能够给您带来帮助,期待您的点赞收藏加关注~~ 参考文档: - 论文:LESS: Selecting Influential Data for Targeted Instruction Tuning - 代码:https://github.com/princeton-nlp/LESS ================================================ FILE: paper/inference/llm-in-a-flash.md ================================================ LLM in a Flash: Efficient Inference Techniques With Limited Memory https://arxiv.org/abs/2312.11514 https://medium.com/@marketing_novita.ai/llm-in-a-flash-efficient-inference-techniques-with-limited-memory-5f0a404794b0 ================================================ FILE: paper/inference/orca.md ================================================ 这篇论文是关于一个名为ORCA的分布式服务系统,它专门为基于Transformer的生成模型设计。以下是论文的主要内容概述: 1. **背景与动机**: - 大型基于Transformer的模型(如GPT-3)在生成任务中表现出色,但现有的推理服务系统在处理这类模型时存在性能瓶颈。这些模型需要多次迭代来生成每个输出令牌,而现有系统在处理多迭代请求时效率不高。 2. **主要问题**: - 现有系统在处理请求时,通常是按批次处理,这导致一些请求在批次中提前完成但无法及时返回给客户端,增加了延迟。同时,新到达的请求需要等待当前批次完全处理完毕,增加了排队时间。 3. **解决方案**: - **迭代级调度(Iteration-level Scheduling)**:提出一种新的调度机制,调度执行时以迭代为单位,而不是整个请求。这样,每次迭代后,可以立即处理新到达的请求,减少等待时间。 - **选择性批处理(Selective Batching)**:在应用批处理和迭代级调度时,只对选定的操作应用批处理。这样可以在不同的操作中灵活地处理请求,避免因不同请求处理不同数量的令牌而导致的批处理问题。 4. **ORCA系统**: - ORCA是一个分布式服务系统,实现了上述两种技术。它还采用了模型并行化策略(如层内和层间模型并行化),以支持大规模模型。 - ORCA的设计包括一个请求池、调度器和执行引擎。调度器负责从请求池中选择请求,执行引擎则负责执行模型的迭代。 5. **评估**: - 使用GPT-3模型进行评估,结果显示ORCA在延迟和吞吐量方面显著优于NVIDIA FasterTransformer。具体来说,ORCA在相同延迟水平下,吞吐量提高了36.9倍。 6. **结论**: - ORCA通过迭代级调度和选择性批处理,为基于Transformer的生成模型提供了一个高效、低延迟的服务系统。这种方法在处理大规模模型时表现出色,能够显著提高服务的吞吐量和响应速度。 论文的主要贡献在于提出了一种新的调度和批处理机制,解决了现有系统在处理基于Transformer的生成模型时的性能问题。 第三章 - 重点 ================================================ FILE: paper/inference/迈向高效的生成式大语言模型服务综述-从算法到系统.md ================================================ LLM 推理优化技术分类: 算法创新 解码算法 Non-autoregressive Decoding Speculative Decoding Early Exiting Cascade Inference 架构设计 Config Downsizing Attention Simplification Recurrent Unit Activation Sharing Conditional Computing 模型压缩 知识蒸馏 网络剪枝 系统优化 低比特量化 并行计算 模型并行 Decentralized Inference 内存管理 请求调度 Kernel 优化 Kernel 融合 Tailored Attention Sampling Optimization Variable Sequence length 自动编译 ================================================ FILE: paper/llm对齐综述.md ================================================ A Comprehensive Survey of LLM Alignment Techniques: RLHF, RLAIF, PPO, DPO and More https://arxiv.org/abs/2407.16216 # 笔记 https://f46522gm22.feishu.cn/docx/HfxXdnEheouZ42xAoWYcy1q8nSd ================================================ FILE: paper/moe/README.md ================================================ - https://github.com/GCYZSL/MoLA - 大模型微调新范式:当LoRA遇见MoE:https://zhuanlan.zhihu.com/p/683637455 ================================================ FILE: paper/parameter-pruning/LLM-Pruner.md ================================================ - LLM-Pruner:https://github.com/horseee/LLM-Pruner ================================================ FILE: paper/parameter-pruning/SparseGPT.md ================================================ - SparseGPT:https://github.com/IST-DASLab/sparsegpt ================================================ FILE: paper/parameter-pruning/Wanda.md ================================================ ================================================ FILE: paper/parameter-pruning/公式.md ================================================ - MarkDown数学公式基本语法:https://blog.csdn.net/qq_38342510/article/details/124064158 - 史上最全Markdown公式、符号总结:https://blog.csdn.net/weixin_42782150/article/details/104878759 ================================================ FILE: paper/training/A Survey on Efficient Training of Transformers.md ================================================ 涵盖了加速算法和硬件方面的最新进展, 分析和比较了在训练期间节省中间张量的计算和内存成本的方法,以及硬件/算法协同设计的技术。 ## Introduction SOTA 大规模模型需要内存高效的训练技术,以减少存储中间张量和跨加速卡的数据交换(通信)的内存占用,同时确保高处理元件利用率。 计算优化 Optimization 优化器 初始化 稀疏训练 过参数化 大批量训练 数据选择 Token masking 重要性抽样 内存优化 ## 硬件/算法协同设计 硬件感知的低精度。降低计算精度会减少内存和计算量,这可以以硬件友好的定点或整数表示形式(而不是浮点表示形式)来实现。因此,我们可以使用较低精度的乘法器、加法器和内存块,从而显着改善功耗和加速。 此外,低精度算法可以与剪枝和低秩近似等其他技术相结合,以实现进一步的加速。例如,Sanger [63] 使用 4 位 queries and keys 来计算稀疏注意力矩阵的量化预测。然后,稀疏注意力masks被重新排列成结构化块并由可重新配置的硬件处理。以下工作 DOTA [71] 使用低秩变换和低精度计算来识别注意力中不重要的连接。通过结合Token-level 并行和乱序执行,DOTA 比 GPU 实现了 152.6 倍的加速。 高效的注意力。除了稀疏矩阵乘法和低精度计算之外,一些开创性的工作还专注于硬件中高效且轻量级的注意力实现 [ 33, 34 , 20 ]。具体来说,A[33]仅选择那些可能与给定queries具有较高相似度的keys,以减少注意力的计算量。 ELSA [34]根据哈希相似性过滤掉特定query的不相关的keys以节省计算。凭借高效的硬件加速器,与配备 16GB 内存的 Nvidia V100 GPU 相比,ELSA 的加速速度提高了 58.1 倍,能源效率提高了三个数量级。值得注意的是,FlashAttention [20] 提出利用tiling来减少 GPU 高带宽内存 (HBM) 和片上 SRAM 之间的 I/O 通信,这正在成为默认的快速且内存高效的attention模块,以实现加速。 ================================================ FILE: paper/training/GaLore.md ================================================ - 代码:https://github.com/jiaweizzhao/GaLore - 论文:https://arxiv.org/abs/2403.03507 - GaLore:通过梯度低秩投影进行内存高效的 LLM 训练 ``` git clone git@github.com:jiaweizzhao/GaLore.git cd GaLore git checkout a6bc1650 ``` https://download.pytorch.org/whl/cu118/torch-2.1.0%2Bcu118-cp310-cp310-linux_x86_64.whl#sha256=a81b554184492005543ddc32e96469f9369d778dedd195d73bda9bed407d6589 使用单个 GPU(例如:NVIDIA RTX 4090)训练 7B 模型,仅需指定 --optimizer=galore_adamw8bit_per_layer 即可,这会启用 GaLoreAdamW8bit 并进行每层权重更新。通过激活检查点,在 NVIDIA RTX 4090 上批量大小可以到达 16。 ``` # LLaMA-7B, 8-bit GaLore-Adam, single GPU, activation checkpointing # bsz=16, 22.8G, torchrun --standalone --nproc_per_node 1 torchrun_main.py \ --model_config configs/llama_7b.json \ --lr 0.005 \ --galore_scale 0.25 \ --rank 1024 \ --update_proj_gap 500 \ --batch_size 16 \ --total_batch_size 512 \ --activation_checkpointing \ --num_training_steps 150000 \ --warmup_steps 15000 \ --weight_decay 0 \ --grad_clipping 1.0 \ --dtype bfloat16 \ --eval_every 1000 \ --single_gpu \ --optimizer galore_adamw8bit_per_layer ``` 目前,每层权重更新技术仅支持单 GPU 训练 ( --single_gpu ),而不能使用 nn.parallel.DistributedDataParallel 。 ================================================ FILE: paper/training/Reducing Activation Recomputation in Large Transformer Models.md ================================================ Reducing Activation Recomputation in Large Transformer Models:https://arxiv.org/pdf/2205.05198 **选择性激活重计算**(selective activation recomputation),是一种策略,即只对那些**占用大量内存但重新计算成本不高的Transformer层的部分激活进行存储和重计算**。例如,在自注意力机制中,某些操作(如: $QK^T$矩阵乘法、softmax、softmax dropout和对V的注意力)会产生较大的激活,但每个输入元素所需的浮点运算次数却相对较低。通过选择性地存储这些激活,可以在使用较少内存的同时,以较低的计算开销重新计算未存储的激活。 通过结合使用序列并行性(sequence parallelism)和张量并行性(tensor parallelism),以及选择性激活重计算,论文中的方法能够在减少5倍激活内存需求的同时,将由激活重计算引起的执行时间开销降低90%以上。这使得在大规模参数的语言模型上训练变换器模型变得更加高效。 ================================================ FILE: template/server.md ================================================ 优云智算-公共模型目录:/model/ ``` base_path=`pwd` mkdir -p "$base_path/workspace" mkdir -p "$base_path/workspace/code" ``` /model/ModelScope/Qwen/Qwen3-0.6B ``` pip install transformers accelerate seaborn matplotlib conda deactivate # 将虚拟环境添加到 Jupyter lab内核 python -m ipykernel install --user --name=py310 # 确认已经成功添加 jupyter kernelspec list ``` ``` pip install torch==2.4.0 transformers accelerate matplotlib nohup jupyter lab --allow-root --no-browser --ip=0.0.0.0 --port=8888 > jupyter.log 2>&1 & sleep 2 tail -100f jupyter.log | grep http:// http://117.50.213.xxx:8888/lab?token=e6d93f34f936c4a485d06f6ca267614ae09e585497adbeae ``` ``` git config --global user.email "liguodongiot@foxmail.com" git config --global user.name "wintfru" ``` ``` scp -r lambada root@ucloud:/root/workspace/data ```