Skip to content

Commit 4e7aadd

Browse files
authored
Merge pull request #82 from jonnor/pip-install-github-actions
Support installing with pip, and run tests with GitHub Actions
2 parents 3520488 + 7936ab0 commit 4e7aadd

File tree

9 files changed

+162
-90
lines changed

9 files changed

+162
-90
lines changed

.github/workflows/tests.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Python package
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
test:
7+
8+
runs-on: ubuntu-latest
9+
strategy:
10+
matrix:
11+
python-version: ["3.10"]
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
with:
16+
submodules: true
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v2
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
22+
- name: Install OS dependencies
23+
run: |
24+
sudo apt-get install -yqq python-tk git
25+
- name: Install Python dependencies
26+
run: |
27+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
28+
if [ -f requirements.dev.txt ]; then pip install -r requirements.dev.txt; fi
29+
- name: Install as pip package
30+
run: |
31+
pip install ./ -v
32+
- name: Test installed package
33+
working-directory: examples/auto_test
34+
run: |
35+
python auto_test.py
36+

README.md

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,27 @@ make
162162
./mbnet
163163
```
164164

165+
166+
## How to install
167+
168+
TinyMaix can be installed as a Python package
169+
170+
```
171+
pip install git+https://github.com/sipeed/TinyMaix@master
172+
```
173+
174+
TinyMaix requires [Tensorflow](https://www.tensorflow.org/) version `<= 2.14`.
175+
There are multiple options for how to install this, see the TensorFlow documentation.
176+
177+
For example:
178+
```
179+
pip install 'tensorflow-cpu<=2.14.1'
180+
```
181+
182+
NOTE: Tensorflow 2.14 supports up until Python 3.11.
183+
However, *Python 3.12 is not supported* by Tensorflow 2.14.
184+
185+
165186
## How to use (API)
166187
### Load Model
167188
tm_err_t tm_load (tm_mdl_t* mdl, const uint8_t* bin, uint8_t*buf, tm_cb_t cb, tm_mat_t* in);
@@ -199,17 +220,17 @@ And now just put them into your project, compile it~
199220

200221
## How to train/convert models
201222
There are training scripts in examples/mnist to learn how to train simple mnist models.
202-
> Note: you need install TensorFlow (>=2.7) first.
223+
> Note: you need install TinyMaix first.
203224
204225
After training and save h5 models, you can use scripts in tools to convert to tmdl or c header files.
205226

206227
1. h5_to_tflite.py
207228
convert h5 model to float or int8 quant tflite files
208-
python3 h5_to_tflite.py h5/mnist.h5 tflite/mnist_f.tflite 0
209-
python3 h5_to_tflite.py h5/mnist.h5 tflite/mnist_q.tflite 1 quant_img_mnist/ 0to1
229+
python -m tinymaix.tools.h5_to_tflite h5/mnist.h5 tflite/mnist_f.tflite 0
230+
python -m tinymaix.tools.h5_to_tflite h5/mnist.h5 tflite/mnist_q.tflite 1 quant_img_mnist/ 0to1
210231
2. tflite2tmdl.py
211232
convert tflite file to tmdl or c header files.
212-
python3 tflite2tmdl.py tflite/mnist_q.tflite tmdl/mnist_q.tmdl int8 1 28,28,1 10
233+
python -m tinymaix.tools.tflite2tmdl tflite/mnist_q.tflite tmdl/mnist_q.tmdl int8 1 28,28,1 10
213234
```
214235
================ pack model head ================
215236
mdl_type =0

README_ZH.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,17 +198,17 @@ TinyMaix的核心文件只有这5个:tm_model.c, tm_layers.c, tinymaix.h, tm_p
198198

199199
## 怎样训练/转换模型
200200
在examples/mnist下有训练脚本可以学习如何训练基础的mnist模型
201-
> 注意:你需要先安装TensorFlow (>=2.7) 环境.
201+
> 注意:你需要先安装TinyMaix 环境.
202202
203203
完成训练并保存h5模型后,你可以使用以下脚本转换原始模型到tmdl或者c头文件。
204204

205205
1. h5_to_tflite.py
206206
转换h5模型到浮点或者int8量化的tflite模型
207-
python3 h5_to_tflite.py h5/mnist.h5 tflite/mnist_f.tflite 0
208-
python3 h5_to_tflite.py h5/mnist.h5 tflite/mnist_q.tflite 1 quant_img_mnist/ 0to1
207+
python -m tinymaix.tools.h5_to_tflite h5/mnist.h5 tflite/mnist_f.tflite 0
208+
python -m tinymaix.tools.h5_to_tflite h5/mnist.h5 tflite/mnist_q.tflite 1 quant_img_mnist/ 0to1
209209
2. tflite2tmdl.py
210210
转换tflite文件到tmdl或者c头文件
211-
python3 tflite2tmdl.py tflite/mnist_q.tflite tmdl/mnist_q.tmdl int8 1 28,28,1 10
211+
python -m tinymaix.tools.tflite2tmdl tflite/mnist_q.tflite tmdl/mnist_q.tmdl int8 1 28,28,1 10
212212
```
213213
================ pack model head ================
214214
mdl_type =0

examples/auto_test/auto_test.py

Lines changed: 58 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
11
import os,sys,time
2-
from subprocess import *
3-
import datetime,time
4-
import threading
2+
import datetime
3+
import subprocess
4+
55

66
### This script do auto testing before release code.
77
test_list = ["mnist_f", "mnist_q", "mbnet_f", "mbnet_q"]
88

99

10-
def runcmd(cmd):
11-
r=Popen(cmd,stdin=PIPE,stdout=PIPE,stderr=PIPE, shell=True)
10+
def runcmd(cmd, cwd=None):
11+
12+
stdout = subprocess.check_output(cmd, shell=True, cwd=cwd)
13+
# stdin=PIPE,stdout=PIPE,stderr=PIPE
1214
a=[]
13-
for line in r.stdout.readlines():
14-
a.append(line.decode("utf8").strip())
15+
for line in stdout.decode("utf8").strip().split('\n'):
16+
a.append(line.strip())
1517
return a
1618

19+
def run_h5_to_tflite(cmd, **kwargs):
20+
program = 'python -m tinymaix.tools.h5_to_tflite'
21+
cmd = program + ' ' + cmd
22+
return runcmd(cmd, **kwargs)
23+
24+
def run_tflite2tmdl(cmd, **kwargs):
25+
program = 'python -m tinymaix.tools.tflite2tmdl'
26+
cmd = program + ' ' + cmd
27+
return runcmd(cmd, **kwargs)
28+
29+
tools_dir = '../../tools/'
30+
mnist_dir = '../mnist'
31+
mbnet_dir = '../mbnet'
32+
1733

1834
print("This script only test INT8/FP32, you need change OPT0&OPT1")
1935
t00= time.time()
@@ -22,25 +38,20 @@ def runcmd(cmd):
2238
t0= time.time()
2339
print("========Step1.1: test MNIST fp32")
2440
print("====Step1.1.1: MNIST fp32 cvt")
25-
cmd="cd ../../tools/ && python3 h5_to_tflite.py h5/mnist_valid.h5 tflite/mnist_valid_f.tflite 0 && python3 tflite2tmdl.py tflite/mnist_valid_f.tflite tmdl/mnist_valid_f.tmdl fp32 1 28,28,1 10"
26-
res = runcmd(cmd)
27-
print(res[-1])
28-
if res[-1] == "Saved to tinymaix model header to tmdl/mnist_valid_f.h":
29-
print("====Step1.1.1: OK~")
30-
else:
31-
print("====Step1.1.1: ERR!!!")
32-
exit(-1)
41+
run_h5_to_tflite("h5/mnist_valid.h5 tflite/mnist_valid_f.tflite 0", cwd=tools_dir)
42+
res = run_tflite2tmdl("tflite/mnist_valid_f.tflite tmdl/mnist_valid_f.tmdl fp32 1 28,28,1 10", cwd=tools_dir)
43+
assert 'Saved to tmdl/mnist_valid_f.tmdl' in res[-1], ('Step 1.1.1 ERR', res)
44+
3345

3446
print("====Step1.1.2: MNIST fp32 compile&run")
35-
cmd="cd ../mnist && sed -i 's/#define TM_MDL_TYPE TM_MDL_INT8/#define TM_MDL_TYPE TM_MDL_FP32/g' ../../include/tm_port.h && rm -rf build && mkdir build && cd build && cmake .. && make && ./mnist"
36-
res = runcmd(cmd)
47+
cmd="sed -i 's/#define TM_MDL_TYPE TM_MDL_INT8/#define TM_MDL_TYPE TM_MDL_FP32/g' ../../include/tm_port.h"
48+
res = runcmd(cmd, cwd=mnist_dir)
49+
res = runcmd("rm -rf build && mkdir build && cd build && cmake .. && make && ./mnist", cwd=mnist_dir)
3750
print(res[-1])
38-
if res[-1] == "### Predict output is: Number 2, prob 1.000":
39-
print("====Step1.1.2: OK~")
40-
runcmd("rm ../../tools/tmdl/mnist_valid_f.tmdl") #clean tmdl
41-
else:
42-
print("====Step1.1.2: ERR!!!")
43-
exit(-2)
51+
assert 'Predict output is: Number 2, prob 1.0' in res[-1], res[-1]
52+
53+
runcmd("rm ../../tools/tmdl/mnist_valid_f.tmdl") #clean tmdl
54+
4455
t1= time.time()
4556
print("========Step1.1: test MNIST fp32 OK~ use %.1fs"%(t1-t0))
4657

@@ -49,26 +60,17 @@ def runcmd(cmd):
4960
t0= time.time()
5061
print("========Step1.2: test MNIST int8")
5162
print("====Step1.2.1: MNIST int8 cvt")
52-
cmd="cd ../../tools/ && python3 h5_to_tflite.py h5/mnist_valid.h5 tflite/mnist_valid_q.tflite 1 quant_img_mnist/ 0to1 && python3 tflite2tmdl.py tflite/mnist_valid_q.tflite tmdl/mnist_valid_q.tmdl int8 1 28,28,1 10"
53-
res = runcmd(cmd)
54-
print(res[-1])
55-
if res[-1] == "Saved to tinymaix model header to tmdl/mnist_valid_q.h":
56-
print("====Step1.2.1: OK~")
57-
else:
58-
print("====Step1.2.1: ERR!!!")
59-
exit(-1)
63+
res = run_h5_to_tflite("h5/mnist_valid.h5 tflite/mnist_valid_q.tflite 1 quant_img_mnist/ 0to1", cwd=tools_dir)
64+
res = run_tflite2tmdl("tflite/mnist_valid_q.tflite tmdl/mnist_valid_q.tmdl int8 1 28,28,1 10", cwd=tools_dir)
6065

6166
print("====Step1.2.2: MNIST int8 compile&run")
62-
63-
cmd="cd ../mnist && sed -i 's/#define TM_MDL_TYPE TM_MDL_FP32/#define TM_MDL_TYPE TM_MDL_INT8/g' ../../include/tm_port.h && rm -rf build && mkdir build && cd build && cmake .. && make && ./mnist"
64-
res = runcmd(cmd)
67+
cmd="sed -i 's/#define TM_MDL_TYPE TM_MDL_FP32/#define TM_MDL_TYPE TM_MDL_INT8/g' ../../include/tm_port.h"
68+
res = runcmd(cmd, cwd=mnist_dir)
69+
res = runcmd("rm -rf build && mkdir build && cd build && cmake .. && make && ./mnist", cwd=mnist_dir)
6570
print(res[-1])
66-
if res[-1] == "### Predict output is: Number 2, prob 0.996":
67-
print("====Step1.2.2: OK~")
68-
runcmd("rm ../../tools/tmdl/mnist_valid_q.tmdl") #clean tmdl
69-
else:
70-
print("====Step1.2.2: ERR!!!")
71-
exit(-2)
71+
assert 'Predict output is: Number 2, prob 0.996' in res[-1], res[-1]
72+
73+
runcmd("rm ../../tools/tmdl/mnist_valid_q.tmdl") #clean tmdl
7274

7375
t1= time.time()
7476
print("========Step1.2: test MNIST int8 OK~ use %.1fs"%(t1-t0))
@@ -79,27 +81,17 @@ def runcmd(cmd):
7981
t0= time.time()
8082
print("========Step2.1: test MBNET fp32")
8183
print("====Step2.1.1: MBNET fp32 cvt")
82-
cmd="cd ../../tools/ && python3 h5_to_tflite.py h5/mbnet128_0.25.h5 tflite/mbnet128_0.25_f.tflite 0 && python3 tflite2tmdl.py tflite/mbnet128_0.25_f.tflite tmdl/mbnet128_0.25_f.tmdl fp32 1 128,128,3 1000"
83-
res = runcmd(cmd)
84-
print(res[-1])
85-
if res[-1] == "Saved to tinymaix model header to tmdl/mbnet128_0.25_f.h":
86-
print("====Step2.1.1: OK~")
87-
else:
88-
print("====Step2.1.1: ERR!!!")
89-
exit(-1)
84+
res = run_h5_to_tflite("h5/mbnet128_0.25.h5 tflite/mbnet128_0.25_f.tflite 0", cwd=tools_dir)
85+
res = run_tflite2tmdl("tflite/mbnet128_0.25_f.tflite tmdl/mbnet128_0.25_f.tmdl fp32 1 128,128,3 1000", cwd=tools_dir)
9086

9187
print("====Step2.1.2: MBNET fp32 compile&run")
92-
93-
cmd="cd ../mbnet && sed -i 's/#define TM_MDL_TYPE TM_MDL_INT8/#define TM_MDL_TYPE TM_MDL_FP32/g' ../../include/tm_port.h && rm -rf build && mkdir build && cd build && cmake .. && make && ./mbnet"
94-
res = runcmd(cmd)
88+
cmd="sed -i 's/#define TM_MDL_TYPE TM_MDL_INT8/#define TM_MDL_TYPE TM_MDL_FP32/g' ../../include/tm_port.h"
89+
res = runcmd(cmd, cwd=mbnet_dir)
90+
res = runcmd("rm -rf build && mkdir build && cd build && cmake .. && make && ./mbnet", cwd=mbnet_dir)
9591
print(res[-1])
96-
if res[-1] == "### Predict output is: Class 292 (tiger, Panthera tigris), Prob 0.866" or \
97-
res[-1] == "### Predict output is: Class 292 (tiger, Panthera tigris), Prob 0.891":
98-
print("====Step2.1.2: OK~")
99-
runcmd("rm ../../tools/tmdl/mbnet128_0.25_f.tmdl") #clean tmdl
100-
else:
101-
print("====Step2.1.2: ERR!!!")
102-
exit(-2)
92+
assert 'Class 292 (tiger, Panthera tigris), Prob 0.8' in res[-1], res[-1]
93+
94+
runcmd("rm ../../tools/tmdl/mbnet128_0.25_f.tmdl") #clean tmdl
10395

10496
t1= time.time()
10597
print("========Step2.1: test MBNET fp32 OK~ use %.1fs"%(t1-t0))
@@ -109,26 +101,17 @@ def runcmd(cmd):
109101
t0= time.time()
110102
print("========Step2.2: test MBNET int8")
111103
print("====Step2.2.1: MBNET int8 cvt")
112-
cmd="cd ../../tools/ && python3 h5_to_tflite.py h5/mbnet128_0.25.h5 tflite/mbnet128_0.25_q.tflite 1 quant_img128/ 0to1 && python3 tflite2tmdl.py tflite/mbnet128_0.25_q.tflite tmdl/mbnet128_0.25_q.tmdl int8 1 128,128,3 1000"
113-
res = runcmd(cmd)
114-
print(res[-1])
115-
if res[-1] == "Saved to tinymaix model header to tmdl/mbnet128_0.25_q.h":
116-
print("====Step2.2.1: OK~")
117-
else:
118-
print("====Step2.2.1: ERR!!!")
119-
exit(-1)
104+
res = run_h5_to_tflite("h5/mbnet128_0.25.h5 tflite/mbnet128_0.25_q.tflite 1 quant_img128/ 0to1", cwd=tools_dir)
105+
res = run_tflite2tmdl("tflite/mbnet128_0.25_q.tflite tmdl/mbnet128_0.25_q.tmdl int8 1 128,128,3 1000", cwd=tools_dir)
120106

121107
print("====Step2.2.2: MBNET int8 compile&run")
122-
123-
cmd="cd ../mbnet && sed -i 's/#define TM_MDL_TYPE TM_MDL_FP32/#define TM_MDL_TYPE TM_MDL_INT8/g' ../../include/tm_port.h && rm -rf build && mkdir build && cd build && cmake .. && make && ./mbnet"
124-
res = runcmd(cmd)
108+
cmd="sed -i 's/#define TM_MDL_TYPE TM_MDL_FP32/#define TM_MDL_TYPE TM_MDL_INT8/g' ../../include/tm_port.h"
109+
res = runcmd(cmd, cwd=mbnet_dir)
110+
res = runcmd("rm -rf build && mkdir build && cd build && cmake .. && make && ./mbnet", cwd=mbnet_dir)
125111
print(res[-1])
126-
if res[-1] == "### Predict output is: Class 292 (tiger, Panthera tigris), Prob 0.824":
127-
print("====Step2.2.2: OK~")
128-
runcmd("rm ../../tools/tmdl/mbnet128_0.25_q.tmdl") #clean tmdl
129-
else:
130-
print("====Step2.2.2: ERR!!!")
131-
exit(-2)
112+
assert 'Class 292 (tiger, Panthera tigris), Prob 0.8' in res[-1]
113+
114+
runcmd("rm ../../tools/tmdl/mbnet128_0.25_q.tmdl") #clean tmdl
132115

133116
t1= time.time()
134117
print("========Step2.2: test MBNET int8 OK~ use %.1fs"%(t1-t0))

examples/auto_test/requirements.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

examples/mbnet/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ limitations under the License.
2525
#elif TM_MDL_TYPE==TM_MDL_FP16
2626
#include "../../tools/tmdl/mbnet128_0.25_fp16.h"
2727
#elif TM_MDL_TYPE==TM_MDL_INT8
28-
#include "../../tools/mbtestv2.h"
28+
#include "../../tools/tmdl/mbnet128_0.25_q.h"
2929
#elif TM_MDL_TYPE==TM_MDL_FP8_143
3030
#include "../../tools/tmdl/mbnet128_0.25_fp8_143.h"
3131
#elif TM_MDL_TYPE==TM_MDL_FP8_152

pyproject.toml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
[build-system]
3+
requires = ["hatchling"]
4+
build-backend = "hatchling.build"
5+
6+
[tool.hatch.build.targets.wheel]
7+
packages = ["src", "include", "tools" ]
8+
9+
[tool.hatch.build.targets.wheel.sources]
10+
"src" = "tinymaix/src"
11+
"include" = "tinymaix/include"
12+
"tools" = "tinymaix/tools"
13+
14+
[project]
15+
name = "TinyMaix"
16+
readme = "README.md"
17+
requires-python = ">= 3.8"
18+
keywords = ["machine learning", "deep learning", "microcontroller", "embedded"]
19+
version = "0.0.1"
20+
21+
dependencies = [
22+
"keras<3.0.0",
23+
"pillow>=10.0.0",
24+
]
25+
26+
classifiers = [
27+
"License :: OSI Approved :: Apache Software License",
28+
]
29+
30+
31+
[project.urls]
32+
Homepage = "https://github.com/sipeed/TinyMaix"
33+
Documentation = "https://github.com/sipeed/TinyMaix"
34+
Repository = "https://github.com/sipeed/TinyMaix"
35+

requirements.dev.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
tensorflow-cpu==2.14.1
2+
numpy

tools/tflite2tmdl.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@
1818
import tensorflow as tf
1919
import time, struct
2020
from PIL import Image
21-
try:
22-
from .tflite_reader import read_tflite
23-
except:
24-
from tflite_reader import read_tflite
25-
21+
from .tflite_reader import read_tflite
2622

2723
# constant
2824
TM_MDL_INT8 = 0

0 commit comments

Comments
 (0)