mirror of
https://github.com/GoogleCloudPlatform/vertex-ai-samples.git
synced 2026-09-26 22:51:56 +00:00
Compare commits
750
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06daeb1575 | ||
|
|
2074fb56a9 | ||
|
|
1bdbb7921a | ||
|
|
7154a722ba | ||
|
|
99d4a8c31a | ||
|
|
f9cedf2850 | ||
|
|
f4f0112a6a | ||
|
|
e441568c38 | ||
|
|
fee8c969e4 | ||
|
|
bdac091e3f | ||
|
|
ff9338ed3c | ||
|
|
1a538fd249 | ||
|
|
4f09c94b5f | ||
|
|
bcf3e6b0f5 | ||
|
|
fbcf783064 | ||
|
|
2f5fe80f34 | ||
|
|
a850f3a88a | ||
|
|
de91feaca1 | ||
|
|
a7fd0734dc | ||
|
|
ce1b167f08 | ||
|
|
65ff3cab60 | ||
|
|
c7ef72f1d3 | ||
|
|
bd58428857 | ||
|
|
a4a6ed848b | ||
|
|
b753bc58d3 | ||
|
|
6279e12eea | ||
|
|
fc0c34c905 | ||
|
|
ef388ecf30 | ||
|
|
bafb2c6f59 | ||
|
|
f2d431c182 | ||
|
|
2e4b6a1b1b | ||
|
|
95cebcbf8f | ||
|
|
08f1b659c5 | ||
|
|
86ba71931d | ||
|
|
d811306fb9 | ||
|
|
4173e6d561 | ||
|
|
499d25055a | ||
|
|
60776de953 | ||
|
|
182ebcf285 | ||
|
|
39359a5b21 | ||
|
|
0d72cfe070 | ||
|
|
64fef140a2 | ||
|
|
015809b948 | ||
|
|
faccdd081f | ||
|
|
3e8a3cf28e | ||
|
|
821bba2776 | ||
|
|
c82bdee299 | ||
|
|
c27381139b | ||
|
|
01236836f2 | ||
|
|
b8380650bd | ||
|
|
69d266cb90 | ||
|
|
530524ac6e | ||
|
|
ba66961fce | ||
|
|
aca7035482 | ||
|
|
3d270cde69 | ||
|
|
9754c265ff | ||
|
|
f5d730c9f1 | ||
|
|
acd42a3a1b | ||
|
|
eb7cf4b6bc | ||
|
|
34b1011ac9 | ||
|
|
239d664990 | ||
|
|
920c771238 | ||
|
|
e7c68ecb78 | ||
|
|
cfeb118d8b | ||
|
|
2c9c8db15c | ||
|
|
6778a2cfbf | ||
|
|
26c5d56e6d | ||
|
|
527fe79f15 | ||
|
|
2a003fa9c3 | ||
|
|
03b9b6026f | ||
|
|
ff8d6a9d56 | ||
|
|
874c881ad6 | ||
|
|
f484429a89 | ||
|
|
7fa2502c09 | ||
|
|
056791fadd | ||
|
|
154be75dce | ||
|
|
ed7e900a02 | ||
|
|
f109fefbfa | ||
|
|
6f9c99d1df | ||
|
|
ed39d78005 | ||
|
|
d6466ab1a6 | ||
|
|
65e310e4e6 | ||
|
|
0e773ba90f | ||
|
|
0747f9efb8 | ||
|
|
53785fb812 | ||
|
|
b85c24dca5 | ||
|
|
ea5c12c22a | ||
|
|
392c1b7361 | ||
|
|
c5980e636e | ||
|
|
8859e9426d | ||
|
|
db7cc9000a | ||
|
|
d1fe50a1d9 | ||
|
|
9e3597692f | ||
|
|
45c8deebe5 | ||
|
|
6705c4e4ee | ||
|
|
b7f06d948a | ||
|
|
7f3c1a9a36 | ||
|
|
2e991c5b9d | ||
|
|
f8ac68ec10 | ||
|
|
a591c39367 | ||
|
|
d938982aae | ||
|
|
1397c9a64a | ||
|
|
da97ec2244 | ||
|
|
c3f1f8239b | ||
|
|
73878dcc01 | ||
|
|
13bad2e6a3 | ||
|
|
0172f2b11b | ||
|
|
1ba0c17555 | ||
|
|
399c961074 | ||
|
|
d44836db9d | ||
|
|
4e236fd553 | ||
|
|
352b1e2710 | ||
|
|
13cc94d3b7 | ||
|
|
632362ed80 | ||
|
|
90b5575b0c | ||
|
|
2d96cc0af1 | ||
|
|
aadc80752b | ||
|
|
e8745a750b | ||
|
|
67b54685be | ||
|
|
738dc1e01c | ||
|
|
3b481a43a9 | ||
|
|
35d0dee5a0 | ||
|
|
90a0bb9b4c | ||
|
|
e59d5462b4 | ||
|
|
f94bf3c7e1 | ||
|
|
dd215b8cf0 | ||
|
|
784c94a72f | ||
|
|
dccfed9743 | ||
|
|
8346855cfe | ||
|
|
64ad5123d0 | ||
|
|
0025e56323 | ||
|
|
8fd9f35aca | ||
|
|
658abd6d5b | ||
|
|
1243f736e2 | ||
|
|
dd0b07163f | ||
|
|
c6b268ba89 | ||
|
|
fd4f7d2641 | ||
|
|
5c513e20c9 | ||
|
|
d78dba7941 | ||
|
|
42fa88547b | ||
|
|
c4cda29095 | ||
|
|
47725449b5 | ||
|
|
2eba462437 | ||
|
|
97a3f4d3dd | ||
|
|
531e567358 | ||
|
|
1f7c7105bb | ||
|
|
b109183d52 | ||
|
|
72ed00fe0f | ||
|
|
e8d9137a50 | ||
|
|
872e98c544 | ||
|
|
0966fc56a4 | ||
|
|
e8d1e58fc6 | ||
|
|
f73ff8a44f | ||
|
|
48c5810bd7 | ||
|
|
9821d8986c | ||
|
|
207d5db3e9 | ||
|
|
9deb05e3e7 | ||
|
|
8dafc25aab | ||
|
|
ef10e7db53 | ||
|
|
cba907ddf8 | ||
|
|
16c3d7fe25 | ||
|
|
60e1f92ef4 | ||
|
|
fb392c6375 | ||
|
|
b4d10bc5aa | ||
|
|
4049250bad | ||
|
|
923db816e1 | ||
|
|
872f1561cd | ||
|
|
8d7832de6e | ||
|
|
f840017cda | ||
|
|
de3f35b8a6 | ||
|
|
b746bc80d4 | ||
|
|
2001604d37 | ||
|
|
faa148f66e | ||
|
|
f184411666 | ||
|
|
bdad774100 | ||
|
|
9abe9a643b | ||
|
|
ab230ca06f | ||
|
|
dcbd3702d2 | ||
|
|
0505d0c04c | ||
|
|
a47e0aacbb | ||
|
|
15912adeaf | ||
|
|
35fdba7e1c | ||
|
|
f403fa9051 | ||
|
|
0d346b136e | ||
|
|
60d71d29cc | ||
|
|
28c872f4b6 | ||
|
|
c637d693b7 | ||
|
|
5c3a216eb7 | ||
|
|
0b7831b0f4 | ||
|
|
6a6f077ae4 | ||
|
|
27f0a4bb63 | ||
|
|
1476453603 | ||
|
|
dbafcb47ea | ||
|
|
f20700f25a | ||
|
|
d1ca1cd7f8 | ||
|
|
9b03fb7f8e | ||
|
|
aac271eacc | ||
|
|
68b53e0d32 | ||
|
|
bf354adfd3 | ||
|
|
55ad5701e4 | ||
|
|
918564dcc7 | ||
|
|
19b3b5da0f | ||
|
|
2bdab9a9b8 | ||
|
|
88e5d5d236 | ||
|
|
79730d191f | ||
|
|
019040e4cb | ||
|
|
4fd3514d6d | ||
|
|
bb17381b03 | ||
|
|
3f06f48282 | ||
|
|
33abd1e427 | ||
|
|
1d9bfe9934 | ||
|
|
fb9defa985 | ||
|
|
824fb689e4 | ||
|
|
c48dd8662b | ||
|
|
f251721d23 | ||
|
|
e949eb128f | ||
|
|
df48e74f59 | ||
|
|
ce9e6ecf62 | ||
|
|
9ab5f4274a | ||
|
|
29e584a422 | ||
|
|
beabb87cff | ||
|
|
e3f6717ff6 | ||
|
|
fd30c4014a | ||
|
|
4be8b0a59a | ||
|
|
aa09d46265 | ||
|
|
5667967131 | ||
|
|
4e4f532658 | ||
|
|
14b2ce4f2e | ||
|
|
c14b98c92d | ||
|
|
8275ea6c49 | ||
|
|
40fbffcc95 | ||
|
|
08bb513488 | ||
|
|
b298f83cd3 | ||
|
|
659cbb54c4 | ||
|
|
6ddcaa540a | ||
|
|
1656c57b18 | ||
|
|
6cac60f74a | ||
|
|
55e37f795c | ||
|
|
c030d7ef74 | ||
|
|
96be449c69 | ||
|
|
e40ddab4d5 | ||
|
|
d02bc2d56b | ||
|
|
76b641b23d | ||
|
|
bbf4345e76 | ||
|
|
058358a795 | ||
|
|
1c2f75f680 | ||
|
|
999866fad1 | ||
|
|
89f4571a2c | ||
|
|
eaff81fd97 | ||
|
|
976ed94cf2 | ||
|
|
8ab8ef9ca9 | ||
|
|
eaff80a920 | ||
|
|
8646285c26 | ||
|
|
7cad8680e1 | ||
|
|
4f66324883 | ||
|
|
468fd144d2 | ||
|
|
2503c3411c | ||
|
|
94b27550e8 | ||
|
|
3542e0b0a3 | ||
|
|
5cf3b64618 | ||
|
|
885bfd56e5 | ||
|
|
3a5eec64af | ||
|
|
8cdc7f1f79 | ||
|
|
84fd10f408 | ||
|
|
7804c860c5 | ||
|
|
ed0c1c74a6 | ||
|
|
5127a59e92 | ||
|
|
d8df732d6b | ||
|
|
9c10899db8 | ||
|
|
80770188ec | ||
|
|
fa91e45018 | ||
|
|
fa27309134 | ||
|
|
7b85f76384 | ||
|
|
40a0477b08 | ||
|
|
839c7dddb8 | ||
|
|
578cfb7da7 | ||
|
|
b129c0bf43 | ||
|
|
07b4c37135 | ||
|
|
f48fb1c650 | ||
|
|
3bbd59311c | ||
|
|
15bb4cea73 | ||
|
|
1511cc9fd1 | ||
|
|
2885a7a70f | ||
|
|
ea36f5c43e | ||
|
|
a905a6305f | ||
|
|
aeaeddcc75 | ||
|
|
161965cfb0 | ||
|
|
b9d4457474 | ||
|
|
a5b6bcfab1 | ||
|
|
5d55f5b0d2 | ||
|
|
36ace6f4a6 | ||
|
|
32d9b416c1 | ||
|
|
1c6309f401 | ||
|
|
728dec8526 | ||
|
|
7692f902dd | ||
|
|
9281403198 | ||
|
|
2be602fbef | ||
|
|
b140077eb1 | ||
|
|
d3139f7df8 | ||
|
|
72baced988 | ||
|
|
5232654705 | ||
|
|
125fe32eb2 | ||
|
|
614f4154dc | ||
|
|
970415398b | ||
|
|
a052a3d361 | ||
|
|
f8203b9f46 | ||
|
|
fac8c4c9b1 | ||
|
|
d6c13c201e | ||
|
|
8db9ce0415 | ||
|
|
8c7fb38136 | ||
|
|
acec861ad5 | ||
|
|
b5cc2b425e | ||
|
|
710e6ea0d8 | ||
|
|
4dce246b57 | ||
|
|
696efb00ee | ||
|
|
fea73bb9c0 | ||
|
|
f50ea24dd1 | ||
|
|
473e673d0a | ||
|
|
127297ee4e | ||
|
|
fb528b60c6 | ||
|
|
1c1a2b2097 | ||
|
|
8cb2a26817 | ||
|
|
3bf098b361 | ||
|
|
433cffbf76 | ||
|
|
0ec2f4fbe8 | ||
|
|
a9af97f1b9 | ||
|
|
d6431fab4c | ||
|
|
dcfde86928 | ||
|
|
5d747ffa0d | ||
|
|
53f25201cc | ||
|
|
9b17db3025 | ||
|
|
423f7ac584 | ||
|
|
aec82c7e5b | ||
|
|
b227509fbb | ||
|
|
e715e68273 | ||
|
|
406de6fe9a | ||
|
|
eacc49d911 | ||
|
|
b95959e7a1 | ||
|
|
cc2cf876de | ||
|
|
1047237335 | ||
|
|
791d589d41 | ||
|
|
f7bdf75d90 | ||
|
|
785ca9f864 | ||
|
|
aaa7d5c259 | ||
|
|
e21cb948d6 | ||
|
|
5551c5f895 | ||
|
|
e8853475bc | ||
|
|
33cb8139da | ||
|
|
0288fa3703 | ||
|
|
d48edc2cb4 | ||
|
|
7b26f01671 | ||
|
|
59cd2cda3c | ||
|
|
3ac469f57c | ||
|
|
008833422c | ||
|
|
59c85c3085 | ||
|
|
f2b5d0924e | ||
|
|
772cd44cef | ||
|
|
379a4c6a1c | ||
|
|
5cea72848e | ||
|
|
9c12dd811b | ||
|
|
844cf5b047 | ||
|
|
1492051560 | ||
|
|
40bdd5fce3 | ||
|
|
d1cc60e8d7 | ||
|
|
7ca4cf9912 | ||
|
|
294e40cb61 | ||
|
|
f69e43d3d6 | ||
|
|
582c479dbe | ||
|
|
f83660cf62 | ||
|
|
e948fae793 | ||
|
|
cd51333ff1 | ||
|
|
cf5d266bd7 | ||
|
|
8ef840affb | ||
|
|
4dcc3d0183 | ||
|
|
0bcb6a8d8e | ||
|
|
d26b385ec7 | ||
|
|
d5a2766aa4 | ||
|
|
7abfbb5473 | ||
|
|
096423da33 | ||
|
|
89a133549c | ||
|
|
648f1c34e0 | ||
|
|
3f21907c31 | ||
|
|
fce66b3e57 | ||
|
|
3b140f9caa | ||
|
|
89325d7e52 | ||
|
|
e4d44f02d6 | ||
|
|
78993c4729 | ||
|
|
c29e7d86bd | ||
|
|
a8793fb00a | ||
|
|
bb60a7d0db | ||
|
|
eef758c719 | ||
|
|
486ef17ab8 | ||
|
|
90dfef3db6 | ||
|
|
d59c87b387 | ||
|
|
9d69b77ac6 | ||
|
|
b0da5d69f8 | ||
|
|
830e10e583 | ||
|
|
db904b424e | ||
|
|
c371f05bfa | ||
|
|
5f7de16e2d | ||
|
|
3908580ad6 | ||
|
|
77d2cac20a | ||
|
|
a92d5ce473 | ||
|
|
416ec74af3 | ||
|
|
8443bbfe44 | ||
|
|
23a599068a | ||
|
|
c63bb4c464 | ||
|
|
2226e915c0 | ||
|
|
cd9f8b1d89 | ||
|
|
aae9ad0422 | ||
|
|
89d50579a6 | ||
|
|
2d6afa8313 | ||
|
|
00cfb20c36 | ||
|
|
14c87ae702 | ||
|
|
e2a6610c2d | ||
|
|
145cdd0928 | ||
|
|
04e1697bca | ||
|
|
be785d0389 | ||
|
|
976e346a3d | ||
|
|
e37caca496 | ||
|
|
7a48fe8850 | ||
|
|
915a1edba8 | ||
|
|
424f947b04 | ||
|
|
c95f73c1a8 | ||
|
|
9da033c887 | ||
|
|
f61f9bfdc2 | ||
|
|
b2a17dfc83 | ||
|
|
7072219d8b | ||
|
|
57db2f4014 | ||
|
|
4604b0a0a9 | ||
|
|
c8c26a12ba | ||
|
|
3a8fa3e312 | ||
|
|
bbfba5aaaf | ||
|
|
e30b2182b0 | ||
|
|
4c4dade55a | ||
|
|
5690d50430 | ||
|
|
10c33f934f | ||
|
|
0c43cbd563 | ||
|
|
b640a8f545 | ||
|
|
a575528b11 | ||
|
|
42a2c4d082 | ||
|
|
0bcf44e9fa | ||
|
|
9ac2774ece | ||
|
|
975c9fe6bc | ||
|
|
417410f382 | ||
|
|
8fdfbe4e31 | ||
|
|
80f977546c | ||
|
|
c5fe281e32 | ||
|
|
49a2ddaf08 | ||
|
|
e9cba94bb4 | ||
|
|
fc83cfcea5 | ||
|
|
e3aa9e8f35 | ||
|
|
37c52abc11 | ||
|
|
c8320c8764 | ||
|
|
b5d51e61b6 | ||
|
|
aa5464151d | ||
|
|
386cecf4c2 | ||
|
|
dffdb15c17 | ||
|
|
2f3691eb71 | ||
|
|
f456d86555 | ||
|
|
f534b4e7a5 | ||
|
|
de247cd78b | ||
|
|
22ad74eb8d | ||
|
|
baf69999fc | ||
|
|
d5057da9bb | ||
|
|
24904a5999 | ||
|
|
881a2b45c5 | ||
|
|
41fc83ad03 | ||
|
|
9928276dc3 | ||
|
|
6607f93f5e | ||
|
|
dcc0cfe06e | ||
|
|
00d5c5c4bf | ||
|
|
f8152dde19 | ||
|
|
0586e04c21 | ||
|
|
3de18a7fab | ||
|
|
dc0bf24cc5 | ||
|
|
8ce4c3070c | ||
|
|
13c3acb976 | ||
|
|
c1150ff584 | ||
|
|
4f11d70f7e | ||
|
|
2bf9a2b317 | ||
|
|
b1e0ad0c4f | ||
|
|
5624f92f02 | ||
|
|
1335032954 | ||
|
|
0b13c66e07 | ||
|
|
ef25b54926 | ||
|
|
064dbfeefa | ||
|
|
044c69e7a5 | ||
|
|
32a46e7471 | ||
|
|
b52d59822d | ||
|
|
529995ecde | ||
|
|
0726328c92 | ||
|
|
090e83c286 | ||
|
|
c3802626b9 | ||
|
|
9570c2477f | ||
|
|
2b1a898b2a | ||
|
|
f2a42aa66e | ||
|
|
30a03f1fd1 | ||
|
|
ca25448f59 | ||
|
|
8f922710b0 | ||
|
|
9509c6ab9d | ||
|
|
ccba176979 | ||
|
|
1b8f383897 | ||
|
|
e5cd9e86d2 | ||
|
|
a7e86a4f26 | ||
|
|
8f0c73b32c | ||
|
|
c7d7b48a91 | ||
|
|
583eb90f07 | ||
|
|
c3a9249c0c | ||
|
|
81b70e779c | ||
|
|
085713a818 | ||
|
|
5af7c851dc | ||
|
|
691312d467 | ||
|
|
650c256c13 | ||
|
|
9b00c4380b | ||
|
|
4851457e93 | ||
|
|
1c54878fab | ||
|
|
c139b84454 | ||
|
|
15c38b4ca6 | ||
|
|
271c949a71 | ||
|
|
09b5401434 | ||
|
|
dad76547f0 | ||
|
|
c14a110c81 | ||
|
|
d1e16546cc | ||
|
|
f91bc3d0c9 | ||
|
|
5168808b6c | ||
|
|
501cca7b5e | ||
|
|
f19d40d858 | ||
|
|
5a721ce01d | ||
|
|
66421fb4d8 | ||
|
|
3658ee8c88 | ||
|
|
afaab4bb02 | ||
|
|
c1e004bdff | ||
|
|
874e5a3ef5 | ||
|
|
51529f370c | ||
|
|
5ddf98866c | ||
|
|
fbb6830876 | ||
|
|
ee1bb281da | ||
|
|
da2f7e88fe | ||
|
|
3fb28e353f | ||
|
|
c8e7f44f0a | ||
|
|
3d9049aeeb | ||
|
|
7b8726af24 | ||
|
|
0443b05360 | ||
|
|
e422dbdef2 | ||
|
|
ec5fc0b1c8 | ||
|
|
c52e3f20ba | ||
|
|
e367dceceb | ||
|
|
19b8666808 | ||
|
|
a2df0e9fca | ||
|
|
73b094550e | ||
|
|
d05ae109e1 | ||
|
|
fdb25791d5 | ||
|
|
5a88492498 | ||
|
|
f19a12b829 | ||
|
|
3ed0ea73f4 | ||
|
|
b98fd24a72 | ||
|
|
eb4e9a0f91 | ||
|
|
ec7c136b0a | ||
|
|
ee7e43cc1a | ||
|
|
ea9f5f3c5c | ||
|
|
bd44798412 | ||
|
|
2af0cc0f80 | ||
|
|
5c0fa14d2d | ||
|
|
7cc50d3203 | ||
|
|
9c7da13177 | ||
|
|
45e0645f0b | ||
|
|
cb884cc74a | ||
|
|
d3a6475580 | ||
|
|
4e7061b2db | ||
|
|
0250879f65 | ||
|
|
5cee23ae68 | ||
|
|
d518558b3d | ||
|
|
5c085c843f | ||
|
|
936b434ac4 | ||
|
|
43059c9fd9 | ||
|
|
19f72d426d | ||
|
|
14ecaf3023 | ||
|
|
80c93a9b6d | ||
|
|
06a1b4dc57 | ||
|
|
4e779eedf1 | ||
|
|
afb341f5fd | ||
|
|
e34b0fa115 | ||
|
|
6fa0345f25 | ||
|
|
dd43ae6639 | ||
|
|
840385e0a7 | ||
|
|
9daaf51a1f | ||
|
|
9b2511e54e | ||
|
|
b6674e6540 | ||
|
|
a109cb6d44 | ||
|
|
f730d6b9de | ||
|
|
0947f2792d | ||
|
|
dbf19acde4 | ||
|
|
1aaa833153 | ||
|
|
c73d995680 | ||
|
|
3fe5028724 | ||
|
|
44dd24f910 | ||
|
|
c20a9c4e63 | ||
|
|
edffdf34b7 | ||
|
|
340c24c5b4 | ||
|
|
11f20f3f08 | ||
|
|
199b330aa5 | ||
|
|
5143db1024 | ||
|
|
2f0bd3de15 | ||
|
|
4d6c541967 | ||
|
|
5228a5c978 | ||
|
|
c6118bd17d | ||
|
|
d2c9e84af4 | ||
|
|
fe0a0ff055 | ||
|
|
40e287245d | ||
|
|
c79646a537 | ||
|
|
e293e1c2fb | ||
|
|
f2ab65bd03 | ||
|
|
aa686516d3 | ||
|
|
11c80a0251 | ||
|
|
c5e9e5812b | ||
|
|
98b126fa0b | ||
|
|
55553f9e69 | ||
|
|
563013c745 | ||
|
|
fefb9778a7 | ||
|
|
be1831082c | ||
|
|
9e15ee2e8a | ||
|
|
ceff7d7271 | ||
|
|
df9b5cd6f0 | ||
|
|
bc57801525 | ||
|
|
1b403373d3 | ||
|
|
987fb74ca6 | ||
|
|
65a209bc7b | ||
|
|
16e6d9e90f | ||
|
|
7ce6bee763 | ||
|
|
6d7ca3eb55 | ||
|
|
8e9f205e9a | ||
|
|
5fdb6c4368 | ||
|
|
71ebfd402c | ||
|
|
6e4ca83531 | ||
|
|
05793d6a3c | ||
|
|
3dc374b7db | ||
|
|
3ac8a4f617 | ||
|
|
21b4b5b063 | ||
|
|
9ffd921ca4 | ||
|
|
14e6ebbb95 | ||
|
|
277b685a39 | ||
|
|
67e7715ed9 | ||
|
|
bb87900209 | ||
|
|
96ebe7286b | ||
|
|
0b3a5dde09 | ||
|
|
17a30360b4 | ||
|
|
b386f51916 | ||
|
|
dd4f40c7f4 | ||
|
|
d402fc085a | ||
|
|
a12b9cd60f | ||
|
|
bf1032d550 | ||
|
|
dea05e1e36 | ||
|
|
a9f0117c82 | ||
|
|
83f1fe9ecd | ||
|
|
7344274037 | ||
|
|
e36bfa9a3b | ||
|
|
950aa245b8 | ||
|
|
ac47b2e370 | ||
|
|
6662fc809b | ||
|
|
12b3171d5e | ||
|
|
579d4751bd | ||
|
|
d4c607323d | ||
|
|
3ad30738a7 | ||
|
|
119273ae7e | ||
|
|
95bc39a685 | ||
|
|
b054104851 | ||
|
|
e0e0cf849a | ||
|
|
c95b3d7088 | ||
|
|
19c2bdb008 | ||
|
|
3c815f3888 | ||
|
|
cfcd9b29fd | ||
|
|
4fca7d98b2 | ||
|
|
dea950bcb6 | ||
|
|
4c43755fb6 | ||
|
|
374942a9e9 | ||
|
|
8add418428 | ||
|
|
9d73cc4574 | ||
|
|
5edb4bb1bf | ||
|
|
0e811868d3 | ||
|
|
9efcfa25e8 | ||
|
|
48036cf581 | ||
|
|
79fd9b4049 | ||
|
|
46b2181a4e | ||
|
|
d04f25a8bd | ||
|
|
9f341c350c | ||
|
|
f22f97f680 | ||
|
|
fe75745d44 | ||
|
|
bbc9f1337e | ||
|
|
eb1fa9213a | ||
|
|
a7033a6527 | ||
|
|
7e6c2d69c8 | ||
|
|
1a21b81804 | ||
|
|
2bbd520613 | ||
|
|
8285e4ebd1 | ||
|
|
859849894e | ||
|
|
e74dd48ae0 | ||
|
|
a14eb71210 | ||
|
|
0b6a9718ff | ||
|
|
6ac0d8a029 | ||
|
|
2ee013bcab | ||
|
|
1ebb3f5714 | ||
|
|
11c5134961 | ||
|
|
e328b7268f | ||
|
|
d297e99e5a | ||
|
|
48c7a4c82e | ||
|
|
eb3b52f863 | ||
|
|
4e58cca127 | ||
|
|
182a98768f | ||
|
|
f483447235 | ||
|
|
c59050608b | ||
|
|
3b9844f92c | ||
|
|
ee301a22f6 | ||
|
|
b7d16f66aa | ||
|
|
57aad5b802 | ||
|
|
9e311433ba | ||
|
|
04b310927a | ||
|
|
2fed3ad014 | ||
|
|
0ec94e0af6 | ||
|
|
9470be0900 | ||
|
|
479a0c6271 | ||
|
|
053f9c397f | ||
|
|
2c82469756 | ||
|
|
fdfc7009d0 | ||
|
|
59fcfe137d | ||
|
|
9b434b32bc | ||
|
|
fc27cd8628 | ||
|
|
a62f03c396 | ||
|
|
a270439814 | ||
|
|
a97af4a078 | ||
|
|
d7127cc22f | ||
|
|
802ab4edd8 | ||
|
|
ae7f28fb31 | ||
|
|
f63e3e6e4c | ||
|
|
b9bb497ebc | ||
|
|
4368b9e7f8 | ||
|
|
2e9cb5d2cf | ||
|
|
9ec8a93e05 | ||
|
|
3ed8778656 | ||
|
|
bf5e3cf870 | ||
|
|
c23215893d | ||
|
|
1c96f7ca71 | ||
|
|
0d5661835b | ||
|
|
fe1a3c0bc9 | ||
|
|
82bffb87f1 | ||
|
|
741c6732f1 | ||
|
|
9d8caf7888 | ||
|
|
e63d354413 | ||
|
|
831c515477 | ||
|
|
06ba5d6804 |
@@ -1 +1,2 @@
|
||||
ratemate
|
||||
google-cloud-aiplatform
|
||||
@@ -1,45 +1,49 @@
|
||||
from typing import List
|
||||
from ratemate import RateLimit
|
||||
from resource_cleanup_manager import (
|
||||
ResourceCleanupManager,
|
||||
DatasetResourceCleanupManager,
|
||||
EndpointResourceCleanupManager,
|
||||
ModelResourceCleanupManager,
|
||||
DatasetResourceCleanupManager,
|
||||
ModelResourceCleanupManager,
|
||||
EndpointResourceCleanupManager,
|
||||
ResourceCleanupManager,
|
||||
)
|
||||
|
||||
rate_limit = RateLimit(max_count=25, per=60, greedy=False)
|
||||
|
||||
|
||||
def run_cleanup_managers(managers: List[ResourceCleanupManager], is_dry_run: bool):
|
||||
for manager in managers:
|
||||
type_name = manager.type_name
|
||||
for manager in managers:
|
||||
type_name = manager.type_name
|
||||
|
||||
print(f"Fetching {type_name}'s...")
|
||||
resources = manager.list()
|
||||
print(f"Found {len(resources)} {type_name}'s")
|
||||
for resource in resources:
|
||||
if not manager.is_deletable(resource):
|
||||
continue
|
||||
print(f"Fetching {type_name}'s...")
|
||||
resources = manager.list()
|
||||
print(f"Found {len(resources)} {type_name}'s")
|
||||
for resource in resources:
|
||||
try:
|
||||
if not manager.is_deletable(resource):
|
||||
continue
|
||||
|
||||
if is_dry_run:
|
||||
resource_name = manager.resource_name(resource)
|
||||
print(f"Will delete '{type_name}': {resource_name}")
|
||||
else:
|
||||
try:
|
||||
manager.delete(resource)
|
||||
except Exception as exception:
|
||||
print(exception)
|
||||
if is_dry_run:
|
||||
resource_name = manager.resource_name(resource)
|
||||
print(f"Will delete '{type_name}': {resource_name}")
|
||||
else:
|
||||
rate_limit.wait() # wait before deleting
|
||||
manager.delete(resource)
|
||||
except Exception as exception:
|
||||
print(exception)
|
||||
|
||||
print("")
|
||||
print("")
|
||||
|
||||
|
||||
is_dry_run = False
|
||||
|
||||
if is_dry_run:
|
||||
print("Starting cleanup in dry run mode...")
|
||||
print("Starting cleanup in dry run mode...")
|
||||
|
||||
# List of all cleanup managers
|
||||
managers = [
|
||||
DatasetResourceCleanupManager(),
|
||||
EndpointResourceCleanupManager(),
|
||||
ModelResourceCleanupManager(),
|
||||
DatasetResourceCleanupManager(),
|
||||
EndpointResourceCleanupManager(),
|
||||
ModelResourceCleanupManager(), # ModelResourceCleanupManager must follow EndpointResourceCleanupManager due to deployed models blocking model deletion.
|
||||
]
|
||||
|
||||
run_cleanup_managers(managers=managers, is_dry_run=is_dry_run)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import abc
|
||||
from typing import Any, Type
|
||||
|
||||
from google.cloud import aiplatform
|
||||
from typing import Any
|
||||
from proto.datetime_helpers import DatetimeWithNanoseconds
|
||||
from google.cloud.aiplatform import base
|
||||
from proto.datetime_helpers import DatetimeWithNanoseconds
|
||||
|
||||
# If a resource was updated within this number of seconds, do not delete.
|
||||
RESOURCE_UPDATE_BUFFER_IN_SECONDS = 60 * 60 * 8
|
||||
@@ -40,7 +41,7 @@ class ResourceCleanupManager(abc.ABC):
|
||||
# Check that it wasn't created too recently, to prevent race conditions
|
||||
if time_difference <= RESOURCE_UPDATE_BUFFER_IN_SECONDS:
|
||||
print(
|
||||
f"Skipping '{resource}' due update_time being '{time_difference}', which is less than '{RESOURCE_UPDATE_BUFFER_IN_SECONDS}'."
|
||||
f"Skipping '{resource}' due to update_time being '{time_difference}', which is less than '{RESOURCE_UPDATE_BUFFER_IN_SECONDS}'."
|
||||
)
|
||||
return False
|
||||
|
||||
@@ -50,7 +51,7 @@ class ResourceCleanupManager(abc.ABC):
|
||||
class VertexAIResourceCleanupManager(ResourceCleanupManager):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def vertex_ai_resource(self) -> base.VertexAiResourceNounWithFutureManager:
|
||||
def vertex_ai_resource(self) -> Type[base.VertexAiResourceNounWithFutureManager]:
|
||||
pass
|
||||
|
||||
@property
|
||||
@@ -60,7 +61,9 @@ class VertexAIResourceCleanupManager(ResourceCleanupManager):
|
||||
def list(self) -> Any:
|
||||
return self.vertex_ai_resource.list()
|
||||
|
||||
def resource_name(self, resource: Any) -> str:
|
||||
def resource_name(
|
||||
self, resource: Type[base.VertexAiResourceNounWithFutureManager]
|
||||
) -> str:
|
||||
return resource.display_name
|
||||
|
||||
def delete(self, resource):
|
||||
@@ -74,12 +77,33 @@ class VertexAIResourceCleanupManager(ResourceCleanupManager):
|
||||
|
||||
class DatasetResourceCleanupManager(VertexAIResourceCleanupManager):
|
||||
vertex_ai_resource = aiplatform.datasets._Dataset
|
||||
dataset_types = [
|
||||
aiplatform.ImageDataset,
|
||||
aiplatform.TabularDataset,
|
||||
aiplatform.TextDataset,
|
||||
aiplatform.TimeSeriesDataset,
|
||||
aiplatform.VideoDataset,
|
||||
]
|
||||
|
||||
def list(self) -> Any:
|
||||
return [
|
||||
dataset
|
||||
for dataset_type in self.dataset_types
|
||||
for dataset in dataset_type.list()
|
||||
]
|
||||
|
||||
|
||||
class EndpointResourceCleanupManager(VertexAIResourceCleanupManager):
|
||||
vertex_ai_resource = aiplatform.Endpoint
|
||||
|
||||
def delete(self, resource):
|
||||
# TODO: Remove this once https://github.com/googleapis/python-aiplatform/issues/1441 is fixed
|
||||
resource._sync_gca_resource()
|
||||
for deployed_model_id in [
|
||||
models.id for models in resource._gca_resource.deployed_models
|
||||
]:
|
||||
resource._undeploy(deployed_model_id=deployed_model_id)
|
||||
|
||||
resource.delete(force=True)
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
|
||||
import execute_changed_notebooks_helper
|
||||
|
||||
|
||||
@@ -61,6 +62,18 @@ parser.add_argument(
|
||||
help="The GCP region. This is used to inject a variable value into the notebook before running.",
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--variable_service_account",
|
||||
type=str,
|
||||
help="A service account. This is used to inject a variable value into the notebook before running. This is not the account that will run the notebook.",
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--variable_vpc_network",
|
||||
type=str,
|
||||
help="The full VPC network name. See https://cloud.google.com/compute/docs/networks-and-firewalls#networks. Format is projects/{project}/global/networks/{network}, where {project} is a project number, as in '12345', and {network} is network name. See <https://cloud.google.com/compute/docs/reference/rest/v1/networks/insert> for details. This is used to inject a variable value into the notebook before running.",
|
||||
required=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--staging_bucket",
|
||||
type=str,
|
||||
@@ -73,6 +86,13 @@ parser.add_argument(
|
||||
help="The GCP directory for storing executed notebooks.",
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--timeout",
|
||||
type=int,
|
||||
help="Timeout in seconds",
|
||||
default=86400,
|
||||
required=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--private_pool_id",
|
||||
type=str,
|
||||
@@ -100,8 +120,11 @@ execute_changed_notebooks_helper.process_and_execute_notebooks(
|
||||
container_uri=args.container_uri,
|
||||
staging_bucket=args.staging_bucket,
|
||||
artifacts_bucket=args.artifacts_bucket,
|
||||
should_parallelize=args.should_parallelize,
|
||||
timeout=args.timeout,
|
||||
variable_project_id=args.variable_project_id,
|
||||
variable_region=args.variable_region,
|
||||
private_pool_id=args.private_pool_id if not "default" else None,
|
||||
should_parallelize=args.should_parallelize,
|
||||
variable_service_account=args.variable_service_account,
|
||||
variable_vpc_network=args.variable_vpc_network,
|
||||
private_pool_id=args.private_pool_id,
|
||||
)
|
||||
|
||||
@@ -17,18 +17,28 @@ import concurrent
|
||||
import dataclasses
|
||||
import datetime
|
||||
import functools
|
||||
import json
|
||||
import git
|
||||
import operator
|
||||
import os
|
||||
import pathlib
|
||||
import nbformat
|
||||
import re
|
||||
import subprocess
|
||||
import utils
|
||||
from typing import List, Optional
|
||||
from tabulate import tabulate
|
||||
import operator
|
||||
from utils import util
|
||||
|
||||
import execute_notebook_helper
|
||||
import execute_notebook_remote
|
||||
from utils import util, NotebookProcessors
|
||||
import nbformat
|
||||
from google.cloud.devtools.cloudbuild_v1.types import BuildOperationMetadata
|
||||
from ratemate import RateLimit
|
||||
from tabulate import tabulate
|
||||
from utils import NotebookProcessors, util
|
||||
|
||||
# A buffer so that workers finish before the orchestrating job
|
||||
WORKER_TIMEOUT_BUFFER_IN_SECONDS: int = 60 * 60
|
||||
PYTHON_VERSION = "3.9" # Set default python version
|
||||
|
||||
|
||||
def format_timedelta(delta: datetime.timedelta) -> str:
|
||||
@@ -60,13 +70,23 @@ class NotebookExecutionResult:
|
||||
log_url: str
|
||||
output_uri: str
|
||||
build_id: str
|
||||
logs_bucket: str
|
||||
error_message: Optional[str]
|
||||
|
||||
@property
|
||||
def output_uri_web(self) -> Optional[str]:
|
||||
if self.output_uri.startswith("gs://"):
|
||||
return f"https://storage.googleapis.com/{self.output_uri[5:]}"
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def _process_notebook(
|
||||
notebook_path: str,
|
||||
variable_project_id: str,
|
||||
variable_region: str,
|
||||
variable_service_account: str,
|
||||
variable_vpc_network: Optional[str],
|
||||
):
|
||||
# Read notebook
|
||||
with open(notebook_path) as f:
|
||||
@@ -78,6 +98,8 @@ def _process_notebook(
|
||||
replacement_map={
|
||||
"PROJECT_ID": variable_project_id,
|
||||
"REGION": variable_region,
|
||||
"SERVICE_ACCOUNT": variable_service_account,
|
||||
"VPC_NETWORK": variable_vpc_network,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -93,6 +115,33 @@ def _process_notebook(
|
||||
nbformat.write(nb, new_file)
|
||||
|
||||
|
||||
def _get_notebook_python_version(notebook_path: str) -> str:
|
||||
"""
|
||||
Get the python version for running the notebook if it is specified in
|
||||
the notebook.
|
||||
"""
|
||||
python_version = PYTHON_VERSION
|
||||
|
||||
# Load the notebook
|
||||
file = open(notebook_path)
|
||||
src = file.read()
|
||||
nb_json = json.loads(src)
|
||||
|
||||
#Iterate over the cells in the ipynb
|
||||
for cell in nb_json['cells']:
|
||||
if cell['cell_type'] == 'markdown':
|
||||
markdown = str.join('', cell['source'])
|
||||
|
||||
# Look for the python version specification pattern
|
||||
re_match = re.search('python version = (\d\.\d)', markdown, flags=re.IGNORECASE)
|
||||
if re_match:
|
||||
# get the version number
|
||||
python_version = re_match.group(1)
|
||||
break
|
||||
|
||||
return python_version
|
||||
|
||||
|
||||
def _create_tag(filepath: str) -> str:
|
||||
tag = os.path.basename(os.path.normpath(filepath))
|
||||
tag = re.sub("[^0-9a-zA-Z_.-]+", "-", tag)
|
||||
@@ -103,18 +152,33 @@ def _create_tag(filepath: str) -> str:
|
||||
return tag
|
||||
|
||||
|
||||
rate_limit = RateLimit(max_count=50, per=60, greedy=True)
|
||||
|
||||
|
||||
def process_and_execute_notebook(
|
||||
container_uri: str,
|
||||
staging_bucket: str,
|
||||
artifacts_bucket: str,
|
||||
variable_project_id: str,
|
||||
variable_region: str,
|
||||
variable_service_account: str,
|
||||
variable_vpc_network: Optional[str],
|
||||
private_pool_id: Optional[str],
|
||||
deadline: datetime.datetime,
|
||||
notebook: str,
|
||||
should_get_tail_logs: bool = False,
|
||||
) -> NotebookExecutionResult:
|
||||
rate_limit.wait() # wait before creating the task
|
||||
|
||||
print(f"Running notebook: {notebook}")
|
||||
|
||||
# Handle empty strings
|
||||
if not variable_vpc_network:
|
||||
variable_vpc_network = None
|
||||
|
||||
if not private_pool_id:
|
||||
private_pool_id = None
|
||||
|
||||
# Create paths
|
||||
notebook_output_uri = "/".join([artifacts_bucket, pathlib.Path(notebook).name])
|
||||
|
||||
@@ -128,6 +192,7 @@ def process_and_execute_notebook(
|
||||
output_uri=notebook_output_uri,
|
||||
log_url="",
|
||||
build_id="",
|
||||
logs_bucket="",
|
||||
error_message=None,
|
||||
)
|
||||
|
||||
@@ -135,29 +200,43 @@ def process_and_execute_notebook(
|
||||
time_start = datetime.datetime.now()
|
||||
operation = None
|
||||
try:
|
||||
# Get the python version for running the notebook if specified
|
||||
notebook_exec_python_version = _get_notebook_python_version(notebook_path=notebook)
|
||||
print(f"Running notebook with python {notebook_exec_python_version}")
|
||||
|
||||
# Pre-process notebook by substituting variable names
|
||||
_process_notebook(
|
||||
notebook_path=notebook,
|
||||
variable_project_id=variable_project_id,
|
||||
variable_region=variable_region,
|
||||
variable_service_account=variable_service_account,
|
||||
variable_vpc_network=variable_vpc_network,
|
||||
)
|
||||
|
||||
# Upload the pre-processed code to a GCS bucket
|
||||
code_archive_uri = util.archive_code_and_upload(staging_bucket=staging_bucket)
|
||||
|
||||
# Calculate timeout in seconds
|
||||
timeout_in_seconds = max(
|
||||
int((deadline - datetime.datetime.now()).total_seconds()), 1
|
||||
)
|
||||
|
||||
operation = execute_notebook_remote.execute_notebook_remote(
|
||||
code_archive_uri=code_archive_uri,
|
||||
notebook_uri=notebook,
|
||||
notebook_output_uri=notebook_output_uri,
|
||||
container_uri=container_uri,
|
||||
tag=tag,
|
||||
region=variable_region,
|
||||
private_pool_id=private_pool_id,
|
||||
private_pool_region=variable_region,
|
||||
timeout_in_seconds=timeout_in_seconds,
|
||||
python_version=notebook_exec_python_version
|
||||
)
|
||||
|
||||
operation_metadata = BuildOperationMetadata(mapping=operation.metadata)
|
||||
result.build_id = operation_metadata.build.id
|
||||
result.log_url = operation_metadata.build.log_url
|
||||
result.logs_bucket = operation_metadata.build.logs_bucket
|
||||
|
||||
# Block and wait for the result
|
||||
operation_result = operation.result()
|
||||
@@ -215,20 +294,40 @@ def get_changed_notebooks(
|
||||
|
||||
# Find notebooks
|
||||
notebooks = []
|
||||
|
||||
# Instantiate GitPython objects
|
||||
repo = git.Repo(os.getcwd())
|
||||
index = repo.index
|
||||
|
||||
if base_branch:
|
||||
print(f"Looking for notebooks that changed from branch: {base_branch}")
|
||||
notebooks = subprocess.check_output(
|
||||
["git", "diff", "--name-only", f"origin/{base_branch}..."] + test_paths
|
||||
)
|
||||
# Get the point at which this branch branches off from main
|
||||
branching_commits = repo.merge_base("HEAD", f"origin/{base_branch}")
|
||||
|
||||
if len(branching_commits) > 0:
|
||||
branching_commit = branching_commits[0]
|
||||
print(f"Looking for notebooks that changed from branch: {branching_commit}")
|
||||
|
||||
notebooks = [
|
||||
diff.b_path
|
||||
for diff in index.diff(branching_commit, paths=test_paths)
|
||||
if diff.b_path is not None
|
||||
]
|
||||
else:
|
||||
notebooks = []
|
||||
else:
|
||||
print(f"Looking for all notebooks.")
|
||||
notebooks = subprocess.check_output(["git", "ls-files"] + test_paths)
|
||||
notebooks_str = subprocess.check_output(["git", "ls-files"] + test_paths)
|
||||
notebooks = notebooks_str.decode("utf-8").split("\n")
|
||||
|
||||
notebooks = notebooks.decode("utf-8").split("\n")
|
||||
notebooks = [notebook for notebook in notebooks if notebook.endswith(".ipynb")]
|
||||
notebooks = [notebook for notebook in notebooks if len(notebook) > 0]
|
||||
notebooks = [notebook for notebook in notebooks if pathlib.Path(notebook).exists()]
|
||||
|
||||
if len(notebooks) > 0:
|
||||
print(f"Found {len(notebooks)} notebooks:")
|
||||
for notebook in notebooks:
|
||||
print(f"\t{notebook}")
|
||||
|
||||
return notebooks
|
||||
|
||||
|
||||
@@ -237,10 +336,13 @@ def process_and_execute_notebooks(
|
||||
container_uri: str,
|
||||
staging_bucket: str,
|
||||
artifacts_bucket: str,
|
||||
should_parallelize: bool,
|
||||
timeout: int,
|
||||
variable_project_id: str,
|
||||
variable_region: str,
|
||||
private_pool_id: Optional[str],
|
||||
should_parallelize: bool,
|
||||
variable_service_account: str,
|
||||
variable_vpc_network: Optional[str] = None,
|
||||
private_pool_id: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
Run the notebooks that exist under the folders defined in the test_paths_file.
|
||||
@@ -267,17 +369,27 @@ def process_and_execute_notebooks(
|
||||
Required. The value for REGION to inject into notebooks.
|
||||
should_parallelize (bool):
|
||||
Required. Should run notebooks in parallel using a thread pool as opposed to in sequence.
|
||||
timeout (str):
|
||||
Required. Timeout string according to https://cloud.google.com/build/docs/build-config-file-schema#timeout.
|
||||
"""
|
||||
notebook_execution_results: List[NotebookExecutionResult] = []
|
||||
|
||||
if len(notebooks) > 0:
|
||||
# Calculate deadline
|
||||
deadline = datetime.datetime.now() + datetime.timedelta(
|
||||
seconds=max(timeout - WORKER_TIMEOUT_BUFFER_IN_SECONDS, 0)
|
||||
)
|
||||
|
||||
if len(notebooks) >= 1:
|
||||
notebook_execution_results: List[NotebookExecutionResult] = []
|
||||
|
||||
print(f"Found {len(notebooks)} modified notebooks: {notebooks}")
|
||||
|
||||
if should_parallelize and len(notebooks) > 1:
|
||||
print(
|
||||
"Running notebooks in parallel, so no logs will be displayed. Please wait..."
|
||||
)
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=None) as executor:
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:
|
||||
print(f"Max workers: {executor._max_workers}")
|
||||
|
||||
notebook_execution_results = list(
|
||||
executor.map(
|
||||
functools.partial(
|
||||
@@ -287,7 +399,10 @@ def process_and_execute_notebooks(
|
||||
artifacts_bucket,
|
||||
variable_project_id,
|
||||
variable_region,
|
||||
variable_service_account,
|
||||
variable_vpc_network,
|
||||
private_pool_id,
|
||||
deadline,
|
||||
),
|
||||
notebooks,
|
||||
)
|
||||
@@ -300,48 +415,88 @@ def process_and_execute_notebooks(
|
||||
artifacts_bucket=artifacts_bucket,
|
||||
variable_project_id=variable_project_id,
|
||||
variable_region=variable_region,
|
||||
variable_service_account=variable_service_account,
|
||||
variable_vpc_network=variable_vpc_network,
|
||||
private_pool_id=private_pool_id,
|
||||
deadline=deadline,
|
||||
notebook=notebook,
|
||||
)
|
||||
for notebook in notebooks
|
||||
]
|
||||
|
||||
print("\n=== RESULTS ===\n")
|
||||
|
||||
results_sorted = sorted(
|
||||
notebook_execution_results,
|
||||
key=lambda result: result.is_pass,
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
# Print results
|
||||
print(
|
||||
tabulate(
|
||||
[
|
||||
[
|
||||
result.name,
|
||||
"PASSED" if result.is_pass else "FAILED",
|
||||
format_timedelta(result.duration),
|
||||
result.log_url,
|
||||
result.output_uri,
|
||||
result.output_uri_web,
|
||||
result.logs_bucket
|
||||
]
|
||||
for result in results_sorted
|
||||
],
|
||||
headers=[
|
||||
"build_tag",
|
||||
"status",
|
||||
"duration",
|
||||
"log_url",
|
||||
"output_uri",
|
||||
"output_uri_web",
|
||||
"logs_bucket"
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
if len(notebooks) == 1:
|
||||
print("="*100)
|
||||
print("The notebook execution build log:\n")
|
||||
print("="*100)
|
||||
|
||||
build_id = results_sorted[0].build_id
|
||||
logs_bucket_name = (results_sorted[0].logs_bucket).removeprefix("gs://")
|
||||
log_file_name = f"log-{build_id}.txt"
|
||||
|
||||
log_contents = util.download_blob_into_memory(
|
||||
bucket_name=logs_bucket_name,
|
||||
blob_name=log_file_name,
|
||||
download_as_text=True
|
||||
)
|
||||
|
||||
# Remove extra steps from the log
|
||||
match = re.search("starting Step #4", log_contents, flags=re.IGNORECASE)
|
||||
|
||||
if match is not None:
|
||||
match_index = match.span()[0]
|
||||
print(log_contents[match_index:])
|
||||
else:
|
||||
print(log_contents)
|
||||
|
||||
print("\n=== END RESULTS===\n")
|
||||
|
||||
total_notebook_duration = functools.reduce(
|
||||
operator.add,
|
||||
[datetime.timedelta(seconds=0)]
|
||||
+ [result.duration for result in results_sorted],
|
||||
)
|
||||
|
||||
print(
|
||||
f"Cumulative notebook duration: {format_timedelta(total_notebook_duration)}"
|
||||
)
|
||||
|
||||
# Raise error if any notebooks failed
|
||||
if not all([result.is_pass for result in results_sorted]):
|
||||
raise RuntimeError("Notebook failures detected. See logs for details")
|
||||
else:
|
||||
print("No notebooks modified in this pull request.")
|
||||
|
||||
print("\n=== RESULTS ===\n")
|
||||
|
||||
results_sorted = sorted(
|
||||
notebook_execution_results,
|
||||
key=lambda result: result.is_pass,
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
# Print results
|
||||
print(
|
||||
tabulate(
|
||||
[
|
||||
[
|
||||
result.name,
|
||||
"PASSED" if result.is_pass else "FAILED",
|
||||
format_timedelta(result.duration),
|
||||
result.log_url,
|
||||
]
|
||||
for result in results_sorted
|
||||
],
|
||||
headers=["build_tag", "status", "duration", "log_url"],
|
||||
)
|
||||
)
|
||||
|
||||
print("\n=== END RESULTS===\n")
|
||||
|
||||
total_notebook_duration = functools.reduce(
|
||||
operator.add,
|
||||
[datetime.timedelta(seconds=0)]
|
||||
+ [result.duration for result in results_sorted],
|
||||
)
|
||||
|
||||
print(f"Cumulative notebook duration: {format_timedelta(total_notebook_duration)}")
|
||||
|
||||
# Raise error if any notebooks failed
|
||||
if not all([result.is_pass for result in results_sorted]):
|
||||
raise RuntimeError("Notebook failures detected. See logs for details")
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"""A CLI to download (optional) and run a single notebook locally"""
|
||||
|
||||
import argparse
|
||||
|
||||
import execute_notebook_helper
|
||||
|
||||
parser = argparse.ArgumentParser(description="Run a single notebook locally.")
|
||||
|
||||
@@ -15,17 +15,20 @@
|
||||
|
||||
"""Methods to run a notebook locally"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import errno
|
||||
import papermill as pm
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from utils import util
|
||||
import papermill as pm
|
||||
from google.cloud.aiplatform import utils
|
||||
from utils import util
|
||||
|
||||
# This script is used to execute a notebook and write out the output notebook.
|
||||
|
||||
# This is used to force papermill to use this kernel to run the notebook instead of any defined inside the notebook itself
|
||||
DEFAULT_KERNEL_NAME = "python3"
|
||||
|
||||
|
||||
def execute_notebook(
|
||||
notebook_source: str,
|
||||
@@ -50,6 +53,17 @@ def execute_notebook(
|
||||
|
||||
execution_exception = None
|
||||
|
||||
print("\n=== DOWNLOAD EXECUTED NOTEBOOK ===\n")
|
||||
print(f"Please debug the executed notebook by downloading the executed notebook:")
|
||||
|
||||
print("Option 1. Using gsutil. Run the following command in your terminal.")
|
||||
print(f'\tgsutil cp "{output_file_or_uri}" .')
|
||||
|
||||
print("Option 2. Using this link.")
|
||||
print(f"\thttps://storage.googleapis.com/{output_file_or_uri[5:]}")
|
||||
|
||||
print("\n======\n")
|
||||
|
||||
# Execute notebook
|
||||
try:
|
||||
# Execute notebook
|
||||
@@ -58,6 +72,7 @@ def execute_notebook(
|
||||
output_path=notebook_source,
|
||||
progress_bar=should_log_output,
|
||||
request_save_on_cell_execute=should_log_output,
|
||||
kernel_name=DEFAULT_KERNEL_NAME,
|
||||
log_output=should_log_output,
|
||||
stdout_file=sys.stdout if should_log_output else None,
|
||||
stderr_file=sys.stderr if should_log_output else None,
|
||||
@@ -71,10 +86,6 @@ def execute_notebook(
|
||||
util.upload_file(notebook_source, remote_file_path=output_file_or_uri)
|
||||
|
||||
print("\n=== EXECUTION FINISHED ===\n")
|
||||
print(
|
||||
f"Please debug the executed notebook by downloading: {output_file_or_uri}"
|
||||
)
|
||||
print("\n======\n")
|
||||
else:
|
||||
# Create directories if they don't exist
|
||||
if not os.path.exists(os.path.dirname(output_file_or_uri)):
|
||||
|
||||
@@ -16,22 +16,18 @@
|
||||
"""Methods to run a notebook on Google Cloud Build"""
|
||||
|
||||
from re import sub
|
||||
from typing import Optional
|
||||
|
||||
import google.auth
|
||||
import yaml
|
||||
from google.api_core import client_options, operation
|
||||
from google.cloud.aiplatform import utils
|
||||
from google.cloud.devtools import cloudbuild_v1
|
||||
from google.cloud.devtools.cloudbuild_v1.types import Source, StorageSource
|
||||
from google.protobuf import duration_pb2
|
||||
from yaml.loader import FullLoader
|
||||
|
||||
import google.auth
|
||||
from google.cloud.devtools import cloudbuild_v1
|
||||
from google.cloud.devtools.cloudbuild_v1.types import Source, StorageSource
|
||||
|
||||
from typing import Optional
|
||||
import yaml
|
||||
|
||||
from google.cloud.aiplatform import utils
|
||||
from google.api_core import operation, client_options
|
||||
|
||||
|
||||
CLOUD_BUILD_FILEPATH = ".cloud-build/notebook-execution-test-cloudbuild-single.yaml"
|
||||
TIMEOUT_IN_SECONDS = 86400
|
||||
SERVICE_BASE_PATH = "cloudbuild.googleapis.com"
|
||||
|
||||
|
||||
@@ -40,30 +36,38 @@ def execute_notebook_remote(
|
||||
notebook_uri: str,
|
||||
notebook_output_uri: str,
|
||||
container_uri: str,
|
||||
region: str,
|
||||
private_pool_id: Optional[str],
|
||||
private_pool_region: Optional[str],
|
||||
tag: Optional[str],
|
||||
timeout_in_seconds: Optional[int] = None,
|
||||
python_version: Optional[str] = None
|
||||
) -> operation.Operation:
|
||||
"""Create and execute a single notebook on Google Cloud Build"""
|
||||
# Load build steps from YAML
|
||||
|
||||
cloudbuild_config = yaml.load(open(CLOUD_BUILD_FILEPATH), Loader=FullLoader)
|
||||
|
||||
substitutions = {
|
||||
"_PYTHON_IMAGE": container_uri,
|
||||
"_NOTEBOOK_GCS_URI": notebook_uri,
|
||||
"_NOTEBOOK_OUTPUT_GCS_URI": notebook_output_uri,
|
||||
"_PYTHON_VERSION" : f"python{python_version}"
|
||||
}
|
||||
|
||||
if python_version is not None:
|
||||
substitutions["_PYTHON_VERSION"] = "python" + python_version
|
||||
|
||||
build = cloudbuild_v1.Build()
|
||||
|
||||
options: Optional[client_options.ClientOptions] = None
|
||||
if private_pool_id:
|
||||
substitutions["_PRIVATE_POOL_NAME"] = private_pool_id
|
||||
build.options = cloudbuild_config["options"]
|
||||
if private_pool_id and private_pool_region:
|
||||
# substitutions["_PRIVATE_POOL_NAME"] = private_pool_id
|
||||
build.options = cloudbuild_config.get("options")
|
||||
build.options.pool = {"name": private_pool_id}
|
||||
|
||||
# Switch to the regional endpoint of the pool
|
||||
options = client_options.ClientOptions(
|
||||
api_endpoint=f"{region}-{SERVICE_BASE_PATH}"
|
||||
api_endpoint=f"{private_pool_region}-{SERVICE_BASE_PATH}"
|
||||
)
|
||||
|
||||
# Authorize the client with Google defaults
|
||||
@@ -85,8 +89,8 @@ def execute_notebook_remote(
|
||||
|
||||
build.steps = cloudbuild_config["steps"]
|
||||
build.substitutions = substitutions
|
||||
build.timeout = duration_pb2.Duration(seconds=TIMEOUT_IN_SECONDS)
|
||||
build.queue_ttl = duration_pb2.Duration(seconds=TIMEOUT_IN_SECONDS)
|
||||
build.timeout = duration_pb2.Duration(seconds=timeout_in_seconds)
|
||||
build.queue_ttl = duration_pb2.Duration(seconds=timeout_in_seconds)
|
||||
|
||||
if tag:
|
||||
build.tags = [tag]
|
||||
|
||||
@@ -4,28 +4,35 @@ steps:
|
||||
entrypoint: /bin/sh
|
||||
args:
|
||||
- -c
|
||||
- 'gcloud config list'
|
||||
- 'gcloud config list --quiet'
|
||||
# Check the Python version
|
||||
- name: ${_PYTHON_IMAGE}
|
||||
entrypoint: /bin/sh
|
||||
args:
|
||||
- -c
|
||||
- 'python3 .cloud-build/CheckPythonVersion.py'
|
||||
- ${_PYTHON_VERSION} .cloud-build/CheckPythonVersion.py -q
|
||||
# Create a virtual environment
|
||||
- name: ${_PYTHON_IMAGE}
|
||||
entrypoint: /bin/sh
|
||||
args:
|
||||
- -c
|
||||
- ${_PYTHON_VERSION} -m venv workspace/env
|
||||
# Install Python dependencies
|
||||
- name: ${_PYTHON_IMAGE}
|
||||
entrypoint: /bin/sh
|
||||
args:
|
||||
- -c
|
||||
- 'python3 -m pip install -U pip && python3 -m pip install -U --user -r .cloud-build/requirements.txt'
|
||||
- . workspace/env/bin/activate &&
|
||||
python -m pip -q install -U pip &&
|
||||
python -m pip -q install -U -r .cloud-build/requirements.txt
|
||||
# Install Python dependencies and run testing script
|
||||
- name: ${_PYTHON_IMAGE}
|
||||
entrypoint: /bin/sh
|
||||
args:
|
||||
- -c
|
||||
- 'python3 -m pip install -U pip && python3 -m pip freeze && python3 .cloud-build/execute_notebook_cli.py --notebook_source "${_NOTEBOOK_GCS_URI}" --output_file_or_uri "${_NOTEBOOK_OUTPUT_GCS_URI}"'
|
||||
- |
|
||||
. workspace/env/bin/activate &&
|
||||
python .cloud-build/execute_notebook_cli.py --notebook_source "${_NOTEBOOK_GCS_URI}" --output_file_or_uri "${_NOTEBOOK_OUTPUT_GCS_URI}"
|
||||
env:
|
||||
- 'IS_TESTING=1'
|
||||
timeout: 86400s
|
||||
options:
|
||||
pool:
|
||||
name: ${_PRIVATE_POOL_NAME}
|
||||
@@ -4,35 +4,42 @@ steps:
|
||||
entrypoint: /bin/sh
|
||||
args:
|
||||
- -c
|
||||
- 'gcloud config list'
|
||||
- gcloud config list --quiet
|
||||
# Check the Python version
|
||||
- name: ${_PYTHON_IMAGE}
|
||||
entrypoint: /bin/sh
|
||||
args:
|
||||
- -c
|
||||
- 'python3 .cloud-build/CheckPythonVersion.py'
|
||||
# Fetch base branch if required
|
||||
- python3 .cloud-build/CheckPythonVersion.py -q
|
||||
# Fetch full repo for diff purposes
|
||||
- name: gcr.io/cloud-builders/git
|
||||
args: [fetch, --unshallow, --quiet]
|
||||
# Create a virtual environment
|
||||
- name: ${_PYTHON_IMAGE}
|
||||
entrypoint: /bin/sh
|
||||
args:
|
||||
- -c
|
||||
- 'if [ -n "${_BASE_BRANCH}" ]; then git fetch origin "${_BASE_BRANCH}":refs/remotes/origin/"${_BASE_BRANCH}"; else echo "Skipping fetch."; fi'
|
||||
- python3 -m venv workspace/env
|
||||
# Install Python dependencies
|
||||
- name: ${_PYTHON_IMAGE}
|
||||
entrypoint: /bin/sh
|
||||
args:
|
||||
- -c
|
||||
- 'python3 -m pip install -U pip && python3 -m pip install -U --user -r .cloud-build/requirements.txt'
|
||||
- . workspace/env/bin/activate &&
|
||||
python3 -m pip -q install -U pip &&
|
||||
python3 -m pip -q install -U -r .cloud-build/requirements.txt
|
||||
# Install Python dependencies and run testing script
|
||||
# TODO: Only pass in private_pool_id if it is set
|
||||
- name: ${_PYTHON_IMAGE}
|
||||
entrypoint: /bin/sh
|
||||
args:
|
||||
- -c
|
||||
- 'python3 -m pip install -U pip && python3 -m pip freeze && python3 .cloud-build/execute_changed_notebooks_cli.py --test_paths_file "${_TEST_PATHS_FILE}" --base_branch "${_FORCED_BASE_BRANCH}" --container_uri ${_PYTHON_IMAGE} --staging_bucket ${_GCS_STAGING_BUCKET} --artifacts_bucket ${_GCS_STAGING_BUCKET}/executed_notebooks/PR_${_PR_NUMBER}/BUILD_${BUILD_ID} --variable_project_id ${PROJECT_ID} --variable_region ${_GCP_REGION} `if [ ! -z "${_PRIVATE_POOL_NAME}" ]; then echo "--private_pool_id ${_PRIVATE_POOL_NAME}"; fi`'
|
||||
- |
|
||||
. workspace/env/bin/activate &&
|
||||
python3 .cloud-build/execute_changed_notebooks_cli.py --test_paths_file "${_TEST_PATHS_FILE}" --base_branch "${_FORCED_BASE_BRANCH}" --container_uri ${_PYTHON_IMAGE} --staging_bucket ${_GCS_STAGING_BUCKET} --artifacts_bucket ${_GCS_STAGING_BUCKET}/executed_notebooks/PR_${_PR_NUMBER}/BUILD_${BUILD_ID} --variable_project_id ${PROJECT_ID} --variable_region ${_GCP_REGION} --variable_service_account ${_GCP_SERVICE_ACCOUNT} --variable_vpc_network "${_GPC_VPC_NETWORK_NAME}" `if [ ! -z "${_PRIVATE_POOL_NAME}" ]; then echo "--private_pool_id ${_PRIVATE_POOL_NAME}"; fi`
|
||||
env:
|
||||
- 'IS_TESTING=1'
|
||||
timeout: 86400s
|
||||
options:
|
||||
pool:
|
||||
name: ${_PRIVATE_POOL_NAME}
|
||||
name: ${_PRIVATE_POOL_NAME}
|
||||
|
||||
@@ -9,4 +9,5 @@ tabulate
|
||||
google-cloud-aiplatform
|
||||
google-cloud-storage
|
||||
google-cloud-build
|
||||
gcloud
|
||||
ratemate
|
||||
GitPython
|
||||
@@ -1,3 +1,2 @@
|
||||
notebooks/official
|
||||
notebooks/notebook_template.ipynb
|
||||
notebooks/community/ml_ops
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
notebooks/official/vizier/gapic-vizier-multi-objective-optimization.ipynb
|
||||
notebooks/official/pipelines/lightweight_functions_component_io_kfp.ipynb
|
||||
notebooks/official/matching_engine/intro-swivel.ipynb
|
||||
notebooks/official/ml_metadata/sdk-metric-parameter-tracking-for-locally-trained-models.ipynb
|
||||
notebooks/official/pipelines/metrics_viz_run_compare_kfp.ipynb
|
||||
notebooks/official/custom/custom-tabular-bq-managed-dataset.ipynb
|
||||
notebooks/official/matching_engine/sdk_matching_engine_for_indexing.ipynb
|
||||
.cloud-build/tests/python_version_test.ipynb
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
notebooks/official/custom/custom-tabular-bq-managed-dataset.ipynb
|
||||
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "57a3d44ed8a8"
|
||||
},
|
||||
"source": [
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**_NOTE_**: This notebook has been tested in the following environment:\n",
|
||||
"\n",
|
||||
"* Python version = 3.7\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI API and Compute Engine API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,compute_component).\n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you will need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "c6516f90311b"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# test if the right python version is being used\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"actual_python_version = f\"{sys.version_info.major}.{sys.version_info.minor}\"\n",
|
||||
"print(f\"Runtime python version: {actual_python_version}\")\n",
|
||||
"\n",
|
||||
"assert actual_python_version == \"3.7\", \"Wrong python version!\""
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"name": "python_version_test.ipynb",
|
||||
"toc_visible": true
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"name": "python3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -13,8 +13,10 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from nbconvert.preprocessors import Preprocessor
|
||||
from typing import Dict
|
||||
|
||||
from nbconvert.preprocessors import Preprocessor
|
||||
|
||||
from . import UpdateNotebookVariables as update_notebook_variables
|
||||
|
||||
|
||||
@@ -60,4 +62,4 @@ class UpdateVariablesPreprocessor(Preprocessor):
|
||||
|
||||
executable_cells.append(cell)
|
||||
notebook.cells = executable_cells
|
||||
return notebook, resources
|
||||
return notebook, resources
|
||||
|
||||
@@ -35,8 +35,8 @@ Variables in conditionals can also be replaced:
|
||||
|
||||
def get_updated_value(content: str, variable_name: str, variable_value: str) -> str:
|
||||
return re.sub(
|
||||
rf"({variable_name}.*?=.*?[\",\'])\[.+?\]([\",\'].*?)",
|
||||
rf"\1{variable_value}\2",
|
||||
rf"({variable_name}.*? = .*?[\",\'])\[.+?\]([\",\'].*?)",
|
||||
rf"\g<1>{variable_value}\g<2>",
|
||||
content,
|
||||
flags=re.M,
|
||||
)
|
||||
@@ -78,4 +78,27 @@ def test_region():
|
||||
variable_name="REGION",
|
||||
variable_value="us-central1",
|
||||
)
|
||||
assert new_content == 'REGION = "us-central1" # @param {type:"string"}'
|
||||
assert new_content == 'REGION = "us-central1" # @param {type:"string"}'
|
||||
|
||||
|
||||
def test_region_equal_equals_ignore():
|
||||
# Tests that == is ignored
|
||||
new_content = get_updated_value(
|
||||
content='REGION == "[your-region]" # @param {type:"string"}',
|
||||
variable_name="REGION",
|
||||
variable_value="us-central1",
|
||||
)
|
||||
assert new_content == 'REGION == "[your-region]" # @param {type:"string"}'
|
||||
|
||||
|
||||
def test_service_account():
|
||||
# Tests that == is ignored
|
||||
new_content = get_updated_value(
|
||||
content='SERVICE_ACCOUNT = "[your-service-account]" # @param {type:"string"}',
|
||||
variable_name="SERVICE_ACCOUNT",
|
||||
variable_value="12345-compute@developer.gserviceaccount.com",
|
||||
)
|
||||
assert (
|
||||
new_content
|
||||
== 'SERVICE_ACCOUNT = "12345-compute@developer.gserviceaccount.com" # @param {type:"string"}'
|
||||
)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from google.cloud import storage
|
||||
from google.cloud.aiplatform import utils
|
||||
from google.auth import credentials as auth_credentials
|
||||
import os
|
||||
|
||||
import subprocess
|
||||
import tarfile
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from typing import Optional, Union
|
||||
|
||||
from google.auth import credentials as auth_credentials
|
||||
from google.cloud import storage
|
||||
from google.cloud.aiplatform import utils
|
||||
|
||||
|
||||
def download_file(bucket_name: str, blob_name: str, destination_file: str) -> str:
|
||||
@@ -57,4 +57,35 @@ def archive_code_and_upload(staging_bucket: str):
|
||||
|
||||
print(f"Uploaded source code archive to {source_archived_file_gcs}")
|
||||
|
||||
return source_archived_file_gcs
|
||||
return source_archived_file_gcs
|
||||
|
||||
|
||||
def download_blob_into_memory(
|
||||
bucket_name: str,
|
||||
blob_name: str,
|
||||
download_as_text: Optional[bool]=False
|
||||
) -> Union[bytes, str]:
|
||||
"""
|
||||
Downloads a blob into memory as byte or as text if
|
||||
download_as_text is set to True.
|
||||
"""
|
||||
|
||||
storage_client = storage.Client()
|
||||
|
||||
bucket = storage_client.bucket(bucket_name)
|
||||
|
||||
# Construct a client side representation of a blob.
|
||||
blob = bucket.blob(blob_name)
|
||||
|
||||
# Download the blob content
|
||||
if download_as_text:
|
||||
contents = blob.download_as_text()
|
||||
else:
|
||||
contents = blob.download_as_bytes()
|
||||
|
||||
print(
|
||||
f"Downloaded storage object {blob_name} from bucket {bucket_name}."
|
||||
)
|
||||
|
||||
return contents
|
||||
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
If you are opening a PR for `Official Notebooks` under the [notebooks/official](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/official) folder, follow this mandatory checklist:
|
||||
**REQUIRED:** Add a summary of your PR here, typically including why the change is needed and what was changed. Include any design alternatives for discussion purposes.
|
||||
|
||||
<br>
|
||||
--- YOUR PR SUMMARY GOES HERE ---
|
||||
<br><br><br>
|
||||
|
||||
**REQUIRED:** Fill out the below checklists or remove if irrelevant
|
||||
1. If you are opening a PR for `Official Notebooks` under the [notebooks/official](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/official) folder, follow this mandatory checklist:
|
||||
- [ ] Use the [notebook template](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.ipynb) as a starting point.
|
||||
- [ ] Follow the style and grammar rules outlined in the above notebook template.
|
||||
- [ ] Verify the notebook runs successfully in Colab since the automated tests cannot guarantee this even when it passes.
|
||||
- [ ] Passes all the required automated checks. You can locally test for formatting and linting with these [instructions](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/docs/contributing.md#code-quality-checks).
|
||||
- [ ] Passes all the required automated checks. You can locally test for formatting and linting with these [instructions](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/CONTRIBUTING.md#code-quality-checks).
|
||||
- [ ] You have consulted with a tech writer to see if tech writer review is necessary. If so, the notebook has been reviewed by a tech writer, and they have approved it.
|
||||
- [ ] This notebook has been added to the [CODEOWNERS](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/docs/CODEOWNERS) file under `# Official Notebooks` section, pointing to the author or the author's team.
|
||||
- [ ] This notebook has been added to the [CODEOWNERS](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/CODEOWNERS) file under the `Official Notebooks` section, pointing to the author or the author's team.
|
||||
- [ ] The Jupyter notebook cleans up any artifacts it has created (datasets, ML models, endpoints, etc) so as not to eat up unnecessary resources.
|
||||
|
||||
<br>
|
||||
|
||||
If you are opening a PR for `Community Notebooks` under the [notebooks/community](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/community) folder:
|
||||
- [ ] This notebook has been added to the [CODEOWNERS](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/docs/CODEOWNERS) file under the `# Community Notebooks` section, pointing to the author or the author's team.
|
||||
- [ ] Passes all the required formatting and linting checks. You can locally test with these [instructions](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/docs/contributing.md#code-quality-checks).
|
||||
2. If you are opening a PR for `Community Notebooks` under the [notebooks/community](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/community) folder:
|
||||
- [ ] This notebook has been added to the [CODEOWNERS](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/CODEOWNERS) file under the `Community Notebooks` section, pointing to the author or the author's team.
|
||||
- [ ] Passes all the required formatting and linting checks. You can locally test with these [instructions](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/CONTRIBUTING.md#code-quality-checks).
|
||||
|
||||
If you are opening a PR for `Community Content` under the [community-content](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/community-content) folder:
|
||||
<br>
|
||||
|
||||
3. If you are opening a PR for `Community Content` under the [community-content](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/community-content) folder:
|
||||
- [ ] Make sure your main `Content Directory Name` is descriptive, informative, and includes some of the key products and attributes of your content, so that it is differentiable from other content
|
||||
- [ ] The main content directory has been added to the [CODEOWNERS](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/docs/CODEOWNERS) file under the `# Community Content` section, pointing to the author or the author's team.
|
||||
- [ ] Passes all the required formatting and linting checks. You can locally test with these [instructions](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/docs/contributing.md#code-quality-checks).
|
||||
- [ ] The main content directory has been added to the [CODEOWNERS](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/community-content/CODEOWNERS) file under the `Community Content` section, pointing to the author or the author's team.
|
||||
- [ ] Passes all the required formatting and linting checks. You can locally test with these [instructions](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/CONTRIBUTING.md#code-quality-checks).
|
||||
|
||||
@@ -7,7 +7,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v3
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Fetch pull request branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# To use this image, run this command with the desired notebook args from the top-level vertex-ai-samples directory:
|
||||
# 1. To lint all changed notebooks:
|
||||
# docker run -v ${PWD}:/setup/app gcr.io/python-docs-samples-tests/notebook_linter:latest
|
||||
# 2. To lint specific notebooks:
|
||||
# docker run -v ${PWD}:/setup/app gcr.io/python-docs-samples-tests/notebook_linter:latest notebooks/1.ipynb notebooks/2.ipynb
|
||||
|
||||
FROM python:3.10
|
||||
|
||||
WORKDIR setup
|
||||
|
||||
COPY ./requirements.txt .
|
||||
COPY ./run_linter.sh .
|
||||
|
||||
# Install dependencies.
|
||||
RUN pip install --upgrade pip
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
WORKDIR app
|
||||
|
||||
ENTRYPOINT ["/setup/run_linter.sh"]
|
||||
@@ -2,8 +2,9 @@ git+https://github.com/tensorflow/docs
|
||||
ipython
|
||||
jupyter
|
||||
nbconvert
|
||||
black==22.3.0
|
||||
pyupgrade==2.31.1
|
||||
black==22.6.0
|
||||
pyupgrade==2.34.0
|
||||
isort==5.10.1
|
||||
flake8==4.0.1
|
||||
nbqa==1.3.1
|
||||
nbqa==1.4.0
|
||||
|
||||
|
||||
@@ -47,12 +47,22 @@ done
|
||||
|
||||
echo "Test mode: $is_test"
|
||||
|
||||
# Read in user-provided notebooks
|
||||
notebooks=()
|
||||
for arg in "$@"; do
|
||||
if [[ $arg == *.ipynb ]]; then
|
||||
notebooks+=("$arg")
|
||||
fi
|
||||
done
|
||||
|
||||
# Only check notebooks in test folders modified in this pull request.
|
||||
# Note: Use process substitution to persist the data in the array
|
||||
notebooks=()
|
||||
while read -r file || [ -n "$line" ]; do
|
||||
notebooks+=("$file")
|
||||
done < <(git diff --name-only main... | grep '\.ipynb$')
|
||||
if [ ${#notebooks[@]} -eq 0 ]; then
|
||||
echo "Checking for changed notebooked using git"
|
||||
while read -r file || [ -n "$line" ]; do
|
||||
notebooks+=("$file")
|
||||
done < <(git diff --name-only main... | grep '\.ipynb$')
|
||||
fi
|
||||
|
||||
problematic_notebooks=()
|
||||
if [ ${#notebooks[@]} -gt 0 ]; then
|
||||
@@ -68,7 +78,7 @@ if [ ${#notebooks[@]} -gt 0 ]; then
|
||||
|
||||
if [ "$is_test" = true ]; then
|
||||
echo "Running nbfmt..."
|
||||
python3 -m tensorflow_docs.tools.nbfmt --remove_outputs --test "$notebook"
|
||||
python3 -m tensorflow_docs.tools.nbfmt --test "$notebook"
|
||||
NBFMT_RTN=$?
|
||||
# echo "Running black..."
|
||||
# python3 -m nbqa black "$notebook" --check
|
||||
@@ -93,7 +103,7 @@ if [ ${#notebooks[@]} -gt 0 ]; then
|
||||
python3 -m nbqa isort "$notebook"
|
||||
ISORT_RTN=$?
|
||||
echo "Running nbfmt..."
|
||||
python3 -m tensorflow_docs.tools.nbfmt --remove_outputs "$notebook"
|
||||
python3 -m tensorflow_docs.tools.nbfmt "$notebook"
|
||||
NBFMT_RTN=$?
|
||||
echo "Running flake8..."
|
||||
python3 -m nbqa flake8 "$notebook" --show-source --extend-ignore=W391,E501,F821,E402,F404,W503,E203,E722,W293,W291
|
||||
|
||||
+1
-1
@@ -48,8 +48,8 @@ then you will need to manually address them before submitting your PR.
|
||||
nbqa black "$notebook"
|
||||
nbqa pyupgrade "$notebook"
|
||||
nbqa isort "$notebook"
|
||||
python3 -m tensorflow_docs.tools.nbfmt --remove_outputs "$notebook"
|
||||
nbqa flake8 "$notebook" --extend-ignore=W391,E501,F821,E402,F404,W503,E203,E722,W293,W291
|
||||
python3 -m tensorflow_docs.tools.nbfmt --remove_outputs "$notebook"
|
||||
```
|
||||
|
||||
## Code Reviews
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
* @vertex-ai-samples-contributors @GoogleCloudPlatform/cloudml-samples-owners
|
||||
/tf_agents_bandits_movie_recommendation_with_kfp_and_vertex_sdk @yinghsienwu
|
||||
/pytorch_pre_built_images_deployment @googleapis/vertex-prediction-team
|
||||
/pytorch_text_classification_using_vertex_sdk_and_gcloud @RajeshThallam
|
||||
/pytorch_text_classification_using_vertex_sdk_and_gcloud @RajeshThallam @ultrons
|
||||
/sklearn_text_classification_from_script_using_vertex_sdk @maxhardt
|
||||
/pluto_on_workbench @wkharold
|
||||
/cpr-examples @samthrasher
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
testdata/*
|
||||
build.py
|
||||
test.py
|
||||
state_dict.pth
|
||||
config.json
|
||||
@@ -0,0 +1,6 @@
|
||||
cpr_model_server.py
|
||||
entrypoint.py
|
||||
state_dict.pth
|
||||
config.json
|
||||
**/__pycache__
|
||||
!testdata/**
|
||||
@@ -0,0 +1,110 @@
|
||||
# CPR Example: PyTorch Image Models (timm)
|
||||
|
||||
## About CPR
|
||||
|
||||
CPR ([custom prediction routines](https://github.com/googleapis/python-aiplatform/blob/main/google/cloud/aiplatform/prediction/README.md)) is a framework designed by Google Cloud developers to make it easier to combine machine learning models with custom preprocessing and postprocessing logic in a real-time serving application.
|
||||
|
||||
## Using this example
|
||||
|
||||
This code is a self-contained example of a custom model server project built using CPR.
|
||||
|
||||
As is, you can use it to serve the ViT-Small image classification model from Ross Wightman's [`timm`](https://github.com/rwightman/pytorch-image-models) library of image model implementations in PyTorch. Both CPU and GPU are supported.
|
||||
|
||||
You can also consider using the code here as a template for your own CPR project if you want to use a different model from `timm`, a different PyTorch model, or an entirely different framework.
|
||||
|
||||
### Requirements
|
||||
|
||||
In order to use this example, you'll need Docker and Python 3 installed on your system.
|
||||
|
||||
To get started, first create a virtual environment in an empty directory:
|
||||
```sh
|
||||
mkdir cpr-example
|
||||
python3 -m venv cpr-example
|
||||
cd cpr-example && source bin/activate
|
||||
```
|
||||
|
||||
Then, clone the [vertex-ai-samples repo](https://github.com/GoogleCloudPlatform/vertex-ai-samples) in that directory:
|
||||
```sh
|
||||
git clone https://github.com/GoogleCloudPlatform/vertex-ai-samples.git
|
||||
cd vertex-ai-samples/community-content/cpr-examples/timm_serving
|
||||
```
|
||||
|
||||
Finally, install the Python modules required to build and run the model server:
|
||||
```sh
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Auth
|
||||
|
||||
This example uses Google Cloud Storage for hosting model artifacts and Artifact Registry to store the container image.
|
||||
You'll need to authorize yourself before you can interact with these.
|
||||
|
||||
First, log in to GCP with application default credentials:
|
||||
```sh
|
||||
gcloud auth application-default login
|
||||
```
|
||||
|
||||
Next, if you haven't done so already, set up the [gcloud credential helper](https://cloud.google.com/artifact-registry/docs/docker/authentication)
|
||||
for the Artifact Registry region where you intend to host the image.
|
||||
```
|
||||
gcloud auth configure-docker <region>-docker.pkg.dev
|
||||
```
|
||||
|
||||
|
||||
### Predictor
|
||||
|
||||
The `TimmPredictor` class in `timm_serving/predictor.py` implements most of the important logic for the server.
|
||||
|
||||
- `load(artifacts_dir)`: The predictor's `load` method is called when the server starts up in order to set up the predictor, usually by loading model weights and any artifacts needed for preprocessing and postprocessing. In this example, we initialize the saved model from the `state_dict.pth` file located inside the `artifacts_dir` folder and create the preprocessing transform from the model config.
|
||||
|
||||
- `preprocess`, `predict`, `postprocess`: These methods are applied in sequence to the deserialized JSON data from each request.
|
||||
- `preprocess` decodes images from base64 and apply cropping, scaling and normalizing transforms.
|
||||
- `predict` runs the ViT-Small model on the preprocessed images and returns class scores.
|
||||
- `postprocess` finds the top five classes and packs the class names, probabilities, and indices in a serializable result.
|
||||
|
||||
### Building the container
|
||||
|
||||
To build the model server locally, run the build command:
|
||||
```sh
|
||||
python build.py build
|
||||
```
|
||||
|
||||
You can edit configuration values such as the model server's base image, the name and tag assigned to the image, and the path where model weights are stored locally.
|
||||
|
||||
When you run the build command, model weights are downloaded and the model server container is built.
|
||||
|
||||
### Running local tests
|
||||
|
||||
`test.py` contains a suite of unit tests for the predictor as well as end-to-end tests for the model server.
|
||||
|
||||
To run the tests:
|
||||
```sh
|
||||
python test.py
|
||||
```
|
||||
|
||||
All of the test images are public domain.
|
||||
- [Cat](https://commons.wikimedia.org/wiki/File:Stray_cat_on_wall.jpg)
|
||||
- [Airplane](https://commons.wikimedia.org/wiki/File:Airplanes_jets.jpg)
|
||||
- The infamous [mandrill](https://commons.wikimedia.org/wiki/File:Wikipedia-sipi-image-db-mandrill-4.2.03.png)
|
||||
|
||||
### Deploying to Vertex AI
|
||||
|
||||
Before uploading or deploying the container, you'll need to modify `config.py` to set appropriate values for:
|
||||
- `project_id`: Your GCP project id.
|
||||
- `region`: Region where the model will be uploaded and deployed.
|
||||
- `repository`: [Artifact Registry repository](https://cloud.google.com/artifact-registry/docs/repositories/create-repos) in your project where the container image will be uploaded.
|
||||
- `artifacts_gcs_dir`: Folder in a [Google Cloud Storage bucket](https://cloud.google.com/storage/docs/creating-buckets) where the model weights will be uploaded.
|
||||
|
||||
Once this is done, first upload the model:
|
||||
```sh
|
||||
python build.py upload
|
||||
```
|
||||
|
||||
Then deploy it:
|
||||
```sh
|
||||
python build.py deploy
|
||||
```
|
||||
|
||||
If you run the deploy command again, it will create a new endpoint. If you want to undeploy the model, you can do so using the Vertex AI dashboard on the Google Cloud console, or use `gcloud ai endpoints undeploy` from the command line.
|
||||
|
||||
After deploying successfully, you can run `python build.py probe` to send a sample request to the deployed model.
|
||||
@@ -0,0 +1,117 @@
|
||||
# Copyright 2022 Google LLC
|
||||
|
||||
# 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
|
||||
|
||||
# https://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.
|
||||
|
||||
"""Build the model server container."""
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
from typing import Sequence
|
||||
|
||||
from absl import app
|
||||
from absl import logging
|
||||
from config import CPRConfig
|
||||
from google.cloud import aiplatform
|
||||
from google.cloud.aiplatform import prediction as cpr
|
||||
import smart_open
|
||||
import timm
|
||||
from timm_serving import predictor
|
||||
import torch
|
||||
|
||||
|
||||
def build_container(config: CPRConfig, tag: str) -> cpr.LocalModel:
|
||||
"""Build the model server container.
|
||||
|
||||
Args:
|
||||
tag: Output image tag.
|
||||
|
||||
Returns:
|
||||
LocalModel exposing the built model server.
|
||||
"""
|
||||
return cpr.LocalModel.build_cpr_model(
|
||||
src_dir=os.path.join(os.getcwd()),
|
||||
output_image_uri=tag,
|
||||
base_image=config.base_image,
|
||||
predictor=predictor.TimmPredictor,
|
||||
requirements_path=os.path.join(os.getcwd(), "requirements.txt"),
|
||||
)
|
||||
|
||||
|
||||
def save_model_artifact(destination: str) -> None:
|
||||
"""Save a copy of the model state dict."""
|
||||
model = timm.create_model(predictor.TimmPredictor.TIMM_MODEL_NAME, pretrained=True)
|
||||
dest_file = os.path.join(destination, predictor.TimmPredictor.WEIGHTS_FILE)
|
||||
with smart_open.open(dest_file, "wb") as f:
|
||||
torch.save(model, f)
|
||||
logging.info("Saved model to %s", dest_file)
|
||||
logging.info("%s parameters", sum(p.numel() for p in model.parameters()))
|
||||
|
||||
|
||||
def upload_model(config: CPRConfig) -> aiplatform.Model:
|
||||
"""Tag and upload the model server."""
|
||||
ar_tag = (
|
||||
f"{config.region}-docker.pkg.dev/{config.project_id}"
|
||||
f"/{config.repository}/{config.image}"
|
||||
)
|
||||
local_model = build_container(config, tag=ar_tag)
|
||||
aiplatform.init(project=config.project_id, location=config.region)
|
||||
local_model.push_image()
|
||||
aip_model = aiplatform.Model.upload(
|
||||
local_model=local_model,
|
||||
display_name=predictor.TimmPredictor.TIMM_MODEL_NAME,
|
||||
artifact_uri=config.artifact_gcs_dir,
|
||||
)
|
||||
config.model_name = aip_model.resource_name
|
||||
config.save()
|
||||
return aip_model
|
||||
|
||||
|
||||
def deploy_model(config: CPRConfig) -> aiplatform.Endpoint:
|
||||
"""Deploy the model server to a Vertex Prediction endpoint."""
|
||||
aiplatform.init(project=config.project_id, location=config.region)
|
||||
aip_model = aiplatform.Model(model_name=config.model_name)
|
||||
endpoint = aip_model.deploy(machine_type=config.machine_type)
|
||||
config.endpoint_name = endpoint.resource_name
|
||||
config.save()
|
||||
return endpoint
|
||||
|
||||
|
||||
def probe_prediction(config: CPRConfig, request_path: str) -> None:
|
||||
"""Send a sample prediction request to the Vertex Prediction endpoint."""
|
||||
aiplatform.init(project=config.project_id, location=config.region)
|
||||
aip_endpoint = aiplatform.Endpoint(endpoint_name=config.endpoint_name)
|
||||
with open(request_path) as f:
|
||||
logging.info(aip_endpoint.predict(**json.load(f)))
|
||||
|
||||
|
||||
def main(argv: Sequence[str]):
|
||||
config = CPRConfig()
|
||||
if pathlib.Path(config.config_file).exists():
|
||||
config.load()
|
||||
|
||||
actions = set(argv[1:])
|
||||
if "build" in actions:
|
||||
build_container(config, config.image)
|
||||
save_model_artifact(config.artifact_local_dir)
|
||||
if "upload" in actions:
|
||||
save_model_artifact(config.artifact_gcs_dir)
|
||||
upload_model(config)
|
||||
if "deploy" in actions:
|
||||
deploy_model(config)
|
||||
if "probe" in actions:
|
||||
probe_prediction(config, request_path="sample_request.json")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(main)
|
||||
@@ -0,0 +1,76 @@
|
||||
# Copyright 2022 Google LLC
|
||||
|
||||
# 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
|
||||
|
||||
# https://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 dataclasses
|
||||
import json
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class CPRConfig(object):
|
||||
"""Configure the build process by editing the default values here.
|
||||
|
||||
config_file: File path used to save values in this config. (Some
|
||||
values, such as the model name, are generated at build time and
|
||||
depended on by future steps, so saving it allows this script to
|
||||
deploy the model without re-uploading it, for example.)
|
||||
|
||||
base_image: Base Docker image on top of which the model server will
|
||||
be built. By default, a Debian-based Python 3 image without GPU
|
||||
support will be used.
|
||||
|
||||
image: Name and tag assigned to the built model server image.
|
||||
|
||||
artifact_local_dir: Local directory where a copy of the pretrained model weights
|
||||
will be saved.
|
||||
|
||||
region: Google Cloud Region where the model will be uploaded during the
|
||||
build process.
|
||||
|
||||
project_id: Google Cloud project ID.
|
||||
|
||||
repository: Name of the Artifact Registry repository where the container
|
||||
will be uploaded.
|
||||
|
||||
artifact_gcs_dir: Location on GCS where a copy of the pretrained model
|
||||
weights will be uploaded.
|
||||
|
||||
model_name: Full resource path of the uploaded model. This is a write-only
|
||||
field, the value is generated by Vertex AI when the model is uploaded.
|
||||
|
||||
endpoint_name: Full resource path of the created endpoint. This is a
|
||||
write-only field, the value is generated by Vertex AI when the model is
|
||||
deployed to an endpoint.
|
||||
|
||||
machine_type: Machine type to use when deploying the model.
|
||||
"""
|
||||
|
||||
config_file: str = "config.json"
|
||||
base_image: str = "python:3.10-bullseye"
|
||||
image: str = "timm_predictor:latest"
|
||||
artifact_local_dir: str = ""
|
||||
region: str = "us-central1"
|
||||
project_id: str = "<your project ID here>"
|
||||
repository: str = "cpr-images"
|
||||
artifact_gcs_dir: str = "gs://<your bucket ID here>/timm-vit224/"
|
||||
model_name: str = ""
|
||||
endpoint_name: str = ""
|
||||
machine_type: str = "n1-standard-2"
|
||||
|
||||
def save(self):
|
||||
with open(self.config_file, "w") as f:
|
||||
json.dump(dataclasses.asdict(self), f, indent=2)
|
||||
|
||||
def load(self):
|
||||
with open(self.config_file) as f:
|
||||
self.__init__(**json.load(f))
|
||||
@@ -0,0 +1,8 @@
|
||||
absl-py==1.1.0
|
||||
fastapi==0.75.2
|
||||
uvicorn==0.18.2
|
||||
timm==0.5.4
|
||||
smart_open==6.0.0
|
||||
|
||||
google-cloud-storage>=1.26.0,<2.0.0dev
|
||||
google-cloud-aiplatform[prediction]>=1.16.0
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,255 @@
|
||||
"""Test the timm_serving predictor."""
|
||||
import base64
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import pickle
|
||||
from typing import List, Dict
|
||||
|
||||
from absl import flags
|
||||
from absl import logging
|
||||
from absl.testing import absltest
|
||||
from config import CPRConfig
|
||||
import fastapi
|
||||
from google.cloud import aiplatform
|
||||
from google.cloud.aiplatform import prediction as cpr
|
||||
import PIL
|
||||
from timm_serving import predictor
|
||||
import torch
|
||||
|
||||
VIT_SMALL_PARAMS = 22878952
|
||||
|
||||
|
||||
def b64_encode_file(path: str) -> str:
|
||||
"""Encode a file's contents as base64.
|
||||
|
||||
Args:
|
||||
path: Path to the file.
|
||||
|
||||
Returns:
|
||||
Base64-encoded contents of the file.
|
||||
"""
|
||||
with open(path, "rb") as f:
|
||||
return str(base64.b64encode(f.read()), encoding="utf-8")
|
||||
|
||||
|
||||
def make_instance_dict(
|
||||
image_paths: List[str], base64_encodings: List[str]
|
||||
) -> Dict[str, List[str]]:
|
||||
"""Generate a dictionary similar to a parsed prediction server request.
|
||||
|
||||
Args:
|
||||
image_paths: Paths to image files to include.
|
||||
base64_encodings: Pre-encoded base64 strings.
|
||||
|
||||
Returns:
|
||||
Dictionary of instances in the format accepted by the preprocessor.
|
||||
"""
|
||||
instances = [s for s in base64_encodings]
|
||||
for path in image_paths:
|
||||
instances.append(b64_encode_file(path))
|
||||
return {"instances": instances}
|
||||
|
||||
|
||||
def count_parameters(model: torch.nn.Module):
|
||||
"""Count the parameters in a Pytorch model.
|
||||
|
||||
Args:
|
||||
model: Pytorch model (nn.Module).
|
||||
|
||||
Returns:
|
||||
Number of parameters in the model.
|
||||
|
||||
"""
|
||||
return sum(p.numel() for p in model.parameters())
|
||||
|
||||
|
||||
class PredictorUnitTests(absltest.TestCase):
|
||||
"""Unit tests for timm_serving.predictor."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.config = CPRConfig()
|
||||
try:
|
||||
self.config.load()
|
||||
except FileNotFoundError:
|
||||
logging.info("No saved config file found, using default values.")
|
||||
self.predictor = predictor.TimmPredictor()
|
||||
|
||||
def test_load_from_saved_state_dict_ok(self):
|
||||
self.predictor.load(self.config.artifact_local_dir)
|
||||
self.assertEqual(count_parameters(self.predictor._model), VIT_SMALL_PARAMS)
|
||||
|
||||
def test_load_bad_path(self):
|
||||
with self.assertRaises(FileNotFoundError):
|
||||
self.predictor.load("testdata/")
|
||||
with self.assertRaisesRegex(ValueError, "not a directory"):
|
||||
self.predictor.load("blah")
|
||||
|
||||
def test_load_bad_data(self):
|
||||
with self.assertRaises(pickle.UnpicklingError):
|
||||
self.predictor.load("testdata/bad_model_1")
|
||||
with self.assertRaisesRegex(RuntimeError, "Invalid magic number"):
|
||||
self.predictor.load("testdata/bad_model_2")
|
||||
|
||||
def test_preprocess_ok(self):
|
||||
self.predictor.load(self.config.artifact_local_dir)
|
||||
instance_dict = make_instance_dict(
|
||||
base64_encodings=[],
|
||||
image_paths=[
|
||||
"testdata/airplane.jpg",
|
||||
"testdata/mandrill.tiff",
|
||||
"testdata/mandrill.tiff",
|
||||
"testdata/cat_alpha.png",
|
||||
],
|
||||
)
|
||||
result = self.predictor.preprocess(instance_dict)
|
||||
self.assertEqual(result.size(), torch.Size([4, 3, 224, 224]))
|
||||
self.assertEqual(result.dtype, torch.float32)
|
||||
|
||||
def test_preprocess_no_instances(self):
|
||||
self.predictor.load(self.config.artifact_local_dir)
|
||||
with self.assertRaises(fastapi.HTTPException) as ctx:
|
||||
self.predictor.preprocess({})
|
||||
self.assertEqual(ctx.exception.status_code, 400)
|
||||
self.assertRegex(ctx.exception.detail, 'must contain "instances"')
|
||||
|
||||
def test_preprocess_wrong_shape_instances(self):
|
||||
self.predictor.load(self.config.artifact_local_dir)
|
||||
instance_dict = {"instances": [[b64_encode_file("testdata/mandrill.tiff")]]}
|
||||
with self.assertRaises(fastapi.HTTPException) as ctx:
|
||||
self.predictor.preprocess(instance_dict)
|
||||
self.assertEqual(ctx.exception.status_code, 400)
|
||||
self.assertRegex(ctx.exception.detail, "not 'list'")
|
||||
|
||||
def test_preprocess_bad_base64(self):
|
||||
self.predictor.load(self.config.artifact_local_dir)
|
||||
instance_dict = make_instance_dict(base64_encodings=["!@#$"], image_paths=[])
|
||||
with self.assertRaises(fastapi.HTTPException) as ctx:
|
||||
self.predictor.preprocess(instance_dict)
|
||||
self.assertEqual(ctx.exception.status_code, 400)
|
||||
self.assertRegex(ctx.exception.detail, "[Bb]ase64")
|
||||
|
||||
def test_preprocess_not_image_data(self):
|
||||
self.predictor.load(self.config.artifact_local_dir)
|
||||
instance_dict = make_instance_dict(
|
||||
base64_encodings=[], image_paths=["testdata/bad.jpg"]
|
||||
)
|
||||
with self.assertRaises(fastapi.HTTPException) as ctx:
|
||||
self.predictor.preprocess(instance_dict)
|
||||
self.assertEqual(ctx.exception.status_code, 400)
|
||||
self.assertRegex(ctx.exception.detail, "image file")
|
||||
|
||||
def test_predict_ok(self):
|
||||
self.predictor.load(self.config.artifact_local_dir)
|
||||
inputs = torch.zeros(size=[2, 3, 224, 224], dtype=torch.float32)
|
||||
if torch.cuda.device_count() > 0:
|
||||
inputs = inputs.cuda()
|
||||
result = self.predictor.predict(inputs)
|
||||
self.assertEqual(result.size(), torch.Size([2, 1000]))
|
||||
self.assertEqual(result.dtype, torch.float32)
|
||||
|
||||
def test_postprocess_ok(self):
|
||||
class_probs = torch.zeros(size=[2, 1000])
|
||||
class_probs[0, 0] = 1
|
||||
class_probs[1, 123] = 1
|
||||
result = self.predictor.postprocess(class_probs)
|
||||
predictions = result["predictions"]
|
||||
self.assertLen(predictions[0]["class_names"], 5)
|
||||
self.assertLen(predictions[0]["indices"], 5)
|
||||
self.assertLen(predictions[0]["probabilities"], 5)
|
||||
self.assertLen(predictions[1]["class_names"], 5)
|
||||
self.assertLen(predictions[1]["indices"], 5)
|
||||
self.assertLen(predictions[1]["probabilities"], 5)
|
||||
self.assertContainsSubsequence(predictions[0]["class_names"][0], "tench")
|
||||
self.assertContainsSubsequence(
|
||||
predictions[1]["class_names"][0], "spiny lobster"
|
||||
)
|
||||
|
||||
|
||||
class ServerEndToEndTests(absltest.TestCase):
|
||||
"""End-to-end tests for the model server, using LocalEndpoint."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.config = CPRConfig()
|
||||
try:
|
||||
self.config.load()
|
||||
except FileNotFoundError:
|
||||
logging.info("No saved config file found, using default values.")
|
||||
self.local_model = cpr.LocalModel(
|
||||
serving_container_spec=aiplatform.gapic.ModelContainerSpec(
|
||||
image_uri=self.config.image
|
||||
)
|
||||
)
|
||||
|
||||
self.local_endpoint = self.local_model.deploy_to_local_endpoint(
|
||||
artifact_uri=self.config.artifact_local_dir or os.getcwd()
|
||||
)
|
||||
self.local_endpoint.serve()
|
||||
|
||||
def tearDown(self):
|
||||
self.local_endpoint.stop()
|
||||
super().tearDown()
|
||||
|
||||
def test_e2e_healthcheck_ok(self):
|
||||
health_check_response = self.local_endpoint.run_health_check()
|
||||
self.assertEqual(health_check_response.status_code, 200)
|
||||
self.assertEqual(health_check_response.content, b"{}")
|
||||
|
||||
def test_e2e_predict_ok(self):
|
||||
predict_request = json.dumps(
|
||||
make_instance_dict(
|
||||
base64_encodings=[],
|
||||
image_paths=[
|
||||
"testdata/mandrill.tiff",
|
||||
],
|
||||
)
|
||||
)
|
||||
response = self.local_endpoint.predict(
|
||||
request=predict_request, headers={"Content-Type": "application/json"}
|
||||
)
|
||||
logging.info(response.content)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
predictions = response.json()["predictions"]
|
||||
self.assertContainsSubsequence(predictions[0]["class_names"][0], "baboon")
|
||||
|
||||
def test_e2e_predict_bad_json_returns_400(self):
|
||||
predict_request = "blah"
|
||||
response = self.local_endpoint.predict(
|
||||
request=predict_request, headers={"Content-Type": "application/json"}
|
||||
)
|
||||
logging.info(response.content)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_e2e_predict_no_instances_returns_400(self):
|
||||
predict_request = json.dumps({})
|
||||
response = self.local_endpoint.predict(
|
||||
request=predict_request, headers={"Content-Type": "application/json"}
|
||||
)
|
||||
logging.info(response.content)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_e2e_predict_bad_base64_returns_400(self):
|
||||
predict_request = json.dumps(
|
||||
make_instance_dict(base64_encodings=["blah"], image_paths=[])
|
||||
)
|
||||
response = self.local_endpoint.predict(
|
||||
request=predict_request, headers={"Content-Type": "application/json"}
|
||||
)
|
||||
logging.info(response.content)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_e2e_predict_bad_image_returns_400(self):
|
||||
predict_request = json.dumps(
|
||||
make_instance_dict(base64_encodings=[], image_paths=["testdata/bad.jpg"])
|
||||
)
|
||||
response = self.local_endpoint.predict(
|
||||
request=predict_request, headers={"Content-Type": "application/json"}
|
||||
)
|
||||
logging.info(response.content)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
absltest.main()
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1 @@
|
||||
some non-image data
|
||||
@@ -0,0 +1 @@
|
||||
some non-image data
|
||||
+1
@@ -0,0 +1 @@
|
||||
blah
|
||||
BIN
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 348 KiB |
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,178 @@
|
||||
# Copyright 2022 Google LLC
|
||||
|
||||
# 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
|
||||
|
||||
# https://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.
|
||||
|
||||
"""Adapts a pretrained TIMM image classification model to the CPR framework.
|
||||
|
||||
Documentation for the TIMM (Torch IMage Models) library is here:
|
||||
https://rwightman.github.io/pytorch-image-models/
|
||||
|
||||
Its source can also be found here:
|
||||
https://github.com/rwightman/pytorch-image-models
|
||||
"""
|
||||
|
||||
import base64
|
||||
import binascii
|
||||
import io
|
||||
import os
|
||||
from typing import Dict, List, Union
|
||||
|
||||
from fastapi import HTTPException
|
||||
from google.cloud.aiplatform import prediction as cpr
|
||||
from pathlib import Path
|
||||
import PIL
|
||||
import smart_open
|
||||
import timm
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
|
||||
with open(Path(__file__).parent.absolute().joinpath("imagenet.txt")) as f:
|
||||
IMAGENET_CLASSES = f.read().splitlines()
|
||||
|
||||
|
||||
class TimmPredictor(cpr.predictor.Predictor):
|
||||
"""Predictor class for image models based on TIMM."""
|
||||
|
||||
TIMM_MODEL_NAME = os.getenv("TIMM_MODEL_NAME", default="vit_small_patch32_224")
|
||||
WEIGHTS_FILE = "state_dict.pth"
|
||||
NUM_TOP_CLASSES_TO_RETURN = 5
|
||||
|
||||
def __init__(self):
|
||||
self._cuda = torch.cuda.device_count() > 0
|
||||
|
||||
def load(self, artifacts_uri: str = ""):
|
||||
"""Initializes the model and preprocessing transforms.
|
||||
|
||||
Args:
|
||||
artifacts_uri: Directory where state dict is stored. Can be a
|
||||
GCS URI or local path.
|
||||
"""
|
||||
if artifacts_uri:
|
||||
artifact_path = os.path.join(artifacts_uri)
|
||||
if not (os.path.isdir(artifact_path) or artifact_path.startswith("gs://")):
|
||||
raise ValueError("Provided artifact_uri is not a directory.")
|
||||
else:
|
||||
artifact_path = os.getcwd()
|
||||
|
||||
artifact_path = os.path.join(artifact_path, self.WEIGHTS_FILE)
|
||||
with smart_open.open(artifact_path, "rb") as f:
|
||||
self._model = torch.load(f)
|
||||
|
||||
if self._cuda:
|
||||
self._model.cuda()
|
||||
|
||||
config = timm.data.resolve_data_config(model=self.TIMM_MODEL_NAME, args=[])
|
||||
self._transform = timm.data.create_transform(
|
||||
is_training=False, use_prefetcher=False, **config
|
||||
)
|
||||
|
||||
def preprocess(self, request_dict: Dict[str, List[str]]) -> torch.Tensor:
|
||||
"""Performs preprocessing.
|
||||
|
||||
By default, the server expects a request body consisting of a valid JSON
|
||||
object. This will be parsed by the handler before it's evaluated by the
|
||||
preprocess method.
|
||||
|
||||
Args:
|
||||
request_dict: Parsed request body. We expect that the input consists of
|
||||
a list of base64-encoded image files under the "instances" key. (Any
|
||||
image format that PIL.image.open can handle is okay.)
|
||||
|
||||
Returns:
|
||||
torch.Tensor containing the preprocessed images as a batch. If GPU is
|
||||
available, the result tensor will be stored on GPU.
|
||||
"""
|
||||
|
||||
if "instances" not in request_dict:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail='Request must contain "instances" as a top-level key.',
|
||||
)
|
||||
|
||||
tensors = []
|
||||
|
||||
for (i, image) in enumerate(request_dict["instances"]):
|
||||
# We use Base64 encoding to handle image data.
|
||||
# This is probably the best we can do while still using JSON input.
|
||||
# Overriding the input format requires building a custom Handler.
|
||||
try:
|
||||
image_bytes = base64.b64decode(image, validate=True)
|
||||
except (binascii.Error, TypeError) as e:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"Base64 decoding of the input image at index {i} failed:"
|
||||
f" {str(e)}",
|
||||
)
|
||||
|
||||
try:
|
||||
pil_image = PIL.Image.open(io.BytesIO(image_bytes)).convert("RGB")
|
||||
except PIL.UnidentifiedImageError:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"The input image at index {i} could not be identified as an"
|
||||
" image file.",
|
||||
)
|
||||
|
||||
tensors.append(self._transform(pil_image))
|
||||
|
||||
with torch.inference_mode():
|
||||
result = torch.stack(tensors)
|
||||
if self._cuda:
|
||||
result = result.cuda()
|
||||
return result
|
||||
|
||||
def predict(self, instances: torch.Tensor) -> torch.Tensor:
|
||||
"""Performs prediction.
|
||||
|
||||
Args:
|
||||
instances: torch.Tensor with type torch.float32 and shape
|
||||
[?, 3, 224, 224], containing the pre-processed input images.
|
||||
|
||||
Returns:
|
||||
Vector of scores with type torch.float32 and shape [?, 1000],
|
||||
representing the model's estimate of the likelihood that the
|
||||
input belongs to the Imagenet class with that index.
|
||||
"""
|
||||
with torch.inference_mode():
|
||||
class_scores = self._model(instances)
|
||||
return class_scores
|
||||
|
||||
def postprocess(
|
||||
self, class_scores: torch.Tensor
|
||||
) -> Dict[str, List[Dict[str, Union[str, int, float]]]]:
|
||||
"""Translate the model output into a classification result.
|
||||
|
||||
Args:
|
||||
class_scores: torch.Tensor with type torch.float32 and shape
|
||||
[?, 1000], containing the scores assigned to each class by
|
||||
the model.
|
||||
|
||||
Returns:
|
||||
Dictionary containing the list of classification results. Each
|
||||
classification result contains the probabilities, class names, and
|
||||
class indices of the classes with the top class scores as reported by
|
||||
the model.
|
||||
"""
|
||||
class_probs = F.softmax(class_scores, dim=1)
|
||||
top_k = class_probs.topk(self.NUM_TOP_CLASSES_TO_RETURN)
|
||||
top_k_values = top_k.values.numpy().tolist()
|
||||
top_k_indices = top_k.indices.numpy().tolist()
|
||||
predictions = [
|
||||
dict(
|
||||
probabilities=values,
|
||||
indices=indices,
|
||||
class_names=[IMAGENET_CLASSES[int(class_num)] for class_num in indices],
|
||||
)
|
||||
for (values, indices) in zip(top_k_values, top_k_indices)
|
||||
]
|
||||
return {"predictions": predictions}
|
||||
-474
@@ -1,474 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "a6b56b1c7b76"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Copyright 2021 Google LLC\n",
|
||||
"#\n",
|
||||
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
|
||||
"# you may not use this file except in compliance with the License.\n",
|
||||
"# You may obtain a copy of the License at\n",
|
||||
"#\n",
|
||||
"# https://www.apache.org/licenses/LICENSE-2.0\n",
|
||||
"#\n",
|
||||
"# Unless required by applicable law or agreed to in writing, software\n",
|
||||
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
|
||||
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
|
||||
"# See the License for the specific language governing permissions and\n",
|
||||
"# limitations under the License."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "c414a395a19b"
|
||||
},
|
||||
"source": [
|
||||
"# PyTorch Image Classification Multi-Node Distributed Data Parallel Training on CPU using Vertex Training with Custom Container"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "b98238e32cf7"
|
||||
},
|
||||
"source": [
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/master/community-content/pytorch_image_classification_distributed_data_parallel_training_with_vertex_sdk/multi_node_ddp_gloo_vertex_training_with_custom_container.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
"</table>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "03d216c7f7b1"
|
||||
},
|
||||
"source": [
|
||||
"## Setup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "c5ac73516218"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"PROJECT_ID = \"YOUR PROJECT ID\"\n",
|
||||
"BUCKET_NAME = \"gs://YOUR BUCKET NAME\"\n",
|
||||
"REGION = \"YOUR REGION\"\n",
|
||||
"SERVICE_ACCOUNT = \"YOUR SERVICE ACCOUNT\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "0b5ae674177e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_NAME"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "19a9b3bdd553"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"content_name = \"pt-img-cls-multi-node-ddp-cust-cont\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "57bf6f8b4361"
|
||||
},
|
||||
"source": [
|
||||
"## Local Training"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "e5d8a3443da0"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! ls trainer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "07f79309472d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! cat trainer/requirements.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "e16cd8bb7483"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip install -r trainer/requirements.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "0b8a210718c4"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! cat trainer/task.py"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "c0c6e7dfb3c6"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%run trainer/task.py --epochs 5 --no-cuda --local-mode"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "31dfdeede587"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! ls ./tmp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "48d56ec621cc"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! rm -rf ./tmp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "8f3ea1210749"
|
||||
},
|
||||
"source": [
|
||||
"## Vertex Training using Vertex SDK and Custom Container"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "93002a20a2a6"
|
||||
},
|
||||
"source": [
|
||||
"### Build Custom Container"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "4130ce43fd08"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"hostname = \"gcr.io\"\n",
|
||||
"image_name = content_name\n",
|
||||
"tag = \"latest\"\n",
|
||||
"\n",
|
||||
"custom_container_image_uri = f\"{hostname}/{PROJECT_ID}/{image_name}:{tag}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "2f1fc5b05240"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! cd trainer && docker build -t $custom_container_image_uri -f Dockerfile ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "b4f274f499ac"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! docker run --rm $custom_container_image_uri --epochs 5 --no-cuda --local-mode"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "ee1a0a06d0b4"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! docker push $custom_container_image_uri"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "cb763be12fc9"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gcloud container images list --repository $hostname/$PROJECT_ID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "10c8cc6b3334"
|
||||
},
|
||||
"source": [
|
||||
"### Initialize Vertex SDK"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "1a12348169fa"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip install -r requirements.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "42e981cefe41"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from google.cloud import aiplatform\n",
|
||||
"\n",
|
||||
"aiplatform.init(\n",
|
||||
" project=PROJECT_ID,\n",
|
||||
" staging_bucket=BUCKET_NAME,\n",
|
||||
" location=REGION,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "73c92c9298e9"
|
||||
},
|
||||
"source": [
|
||||
"### Create a Vertex Tensorboard Instance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "bde509558cd5"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"content_name = content_name + \"-cpu\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "6d7908c0083c"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"tensorboard = aiplatform.Tensorboard.create(\n",
|
||||
" display_name=content_name,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "a1f0a4f54037"
|
||||
},
|
||||
"source": [
|
||||
"#### Option: Use a Previously Created Vertex Tensorboard Instance\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"tensorboard_name = \"Your Tensorboard Resource Name or Tensorboard ID\"\n",
|
||||
"tensorboard = aiplatform.Tensorboard(tensorboard_name=tensorboard_name)\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "a4cac84e04ac"
|
||||
},
|
||||
"source": [
|
||||
"### Run a Vertex SDK CustomContainerTrainingJob"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "f92e8fdd44ee"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"display_name = content_name\n",
|
||||
"gcs_output_uri_prefix = f\"{BUCKET_NAME}/{display_name}\"\n",
|
||||
"\n",
|
||||
"replica_count = 4\n",
|
||||
"machine_type = \"n1-standard-4\"\n",
|
||||
"\n",
|
||||
"args = [\n",
|
||||
" \"--backend\",\n",
|
||||
" \"gloo\",\n",
|
||||
" \"--no-cuda\",\n",
|
||||
" \"--batch-size\",\n",
|
||||
" \"128\",\n",
|
||||
" \"--epochs\",\n",
|
||||
" \"25\",\n",
|
||||
"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "ae4c57df7e07"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"custom_container_training_job = aiplatform.CustomContainerTrainingJob(\n",
|
||||
" display_name=display_name,\n",
|
||||
" container_uri=custom_container_image_uri,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "35cf3ecdf0df"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"custom_container_training_job.run(\n",
|
||||
" args=args,\n",
|
||||
" base_output_dir=gcs_output_uri_prefix,\n",
|
||||
" replica_count=replica_count,\n",
|
||||
" machine_type=machine_type,\n",
|
||||
" tensorboard=tensorboard.resource_name,\n",
|
||||
" service_account=SERVICE_ACCOUNT,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "49d10dded73b"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(f\"Custom Training Job Name: {custom_container_training_job.resource_name}\")\n",
|
||||
"print(f\"GCS Output URI Prefix: {gcs_output_uri_prefix}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "78398f52807b"
|
||||
},
|
||||
"source": [
|
||||
"### Training Output Artifact"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "fc74422de1d1"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls $gcs_output_uri_prefix"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "5e99a6a05b10"
|
||||
},
|
||||
"source": [
|
||||
"## Clean Up Artifact"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "b0c1b3f7466b"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil rm -rf $gcs_output_uri_prefix"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"name": "multi_node_ddp_gloo_vertex_training_with_custom_container.ipynb",
|
||||
"toc_visible": true
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"name": "python3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
-347
@@ -1,347 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "a6b56b1c7b76"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Copyright 2021 Google LLC\n",
|
||||
"#\n",
|
||||
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
|
||||
"# you may not use this file except in compliance with the License.\n",
|
||||
"# You may obtain a copy of the License at\n",
|
||||
"#\n",
|
||||
"# https://www.apache.org/licenses/LICENSE-2.0\n",
|
||||
"#\n",
|
||||
"# Unless required by applicable law or agreed to in writing, software\n",
|
||||
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
|
||||
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
|
||||
"# See the License for the specific language governing permissions and\n",
|
||||
"# limitations under the License."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "20a5ea0081d0"
|
||||
},
|
||||
"source": [
|
||||
"# PyTorch Image Classification Multi-Node Distributed Data Parallel Training on GPU using Vertex Training with Custom Container"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "8752d4a255fb"
|
||||
},
|
||||
"source": [
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/master/community-content/pytorch_image_classification_distributed_data_parallel_training_with_vertex_sdk/multi_node_ddp_nccl_vertex_training_with_custom_container.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
"</table>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "03d216c7f7b1"
|
||||
},
|
||||
"source": [
|
||||
"## Setup"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "c5ac73516218"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"PROJECT_ID = \"YOUR PROJECT ID\"\n",
|
||||
"BUCKET_NAME = \"gs://YOUR BUCKET NAME\"\n",
|
||||
"REGION = \"YOUR REGION\"\n",
|
||||
"SERVICE_ACCOUNT = \"YOUR SERVICE ACCOUNT\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "0b5ae674177e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_NAME"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "19a9b3bdd553"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"content_name = \"pt-img-cls-multi-node-ddp-cust-cont\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "5307fe28b633"
|
||||
},
|
||||
"source": [
|
||||
"## Vertex Training using Vertex SDK and Custom Container"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "46cb58c7fbf9"
|
||||
},
|
||||
"source": [
|
||||
"### Built Custom Container"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "97e66e9f9bab"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"hostname = \"gcr.io\"\n",
|
||||
"image_name = content_name\n",
|
||||
"tag = \"latest\"\n",
|
||||
"\n",
|
||||
"custom_container_image_uri = f\"{hostname}/{PROJECT_ID}/{image_name}:{tag}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ae9b29c4773f"
|
||||
},
|
||||
"source": [
|
||||
"### Initialize Vertex SDK"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "dc1e84d5dec2"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip install -r requirements.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "6964be27b98e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from google.cloud import aiplatform\n",
|
||||
"\n",
|
||||
"aiplatform.init(\n",
|
||||
" project=PROJECT_ID,\n",
|
||||
" staging_bucket=BUCKET_NAME,\n",
|
||||
" location=REGION,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "594a91f438f2"
|
||||
},
|
||||
"source": [
|
||||
"### Create a Vertex Tensorboard Instance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "93134273261e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"content_name = content_name + \"-gpu\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "c2bd82dbcd9b"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"tensorboard = aiplatform.Tensorboard.create(\n",
|
||||
" display_name=content_name,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ebc593c6472e"
|
||||
},
|
||||
"source": [
|
||||
"#### Option: Use a Previously Created Vertex Tensorboard Instance\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"tensorboard_name = \"Your Tensorboard Resource Name or Tensorboard ID\"\n",
|
||||
"tensorboard = aiplatform.Tensorboard(tensorboard_name=tensorboard_name)\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "0769e8e34c2f"
|
||||
},
|
||||
"source": [
|
||||
"### Run a Vertex SDK CustomContainerTrainingJob"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "023f33ece826"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"display_name = content_name\n",
|
||||
"gcs_output_uri_prefix = f\"{BUCKET_NAME}/{display_name}\"\n",
|
||||
"\n",
|
||||
"replica_count = 1\n",
|
||||
"machine_type = \"n1-standard-4\"\n",
|
||||
"accelerator_count = 4\n",
|
||||
"accelerator_type = \"NVIDIA_TESLA_K80\"\n",
|
||||
"\n",
|
||||
"args = [\n",
|
||||
" \"--backend\",\n",
|
||||
" \"nccl\",\n",
|
||||
" \"--batch-size\",\n",
|
||||
" \"128\",\n",
|
||||
" \"--epochs\",\n",
|
||||
" \"25\",\n",
|
||||
"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "d4b599e726ef"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"custom_container_training_job = aiplatform.CustomContainerTrainingJob(\n",
|
||||
" display_name=display_name,\n",
|
||||
" container_uri=custom_container_image_uri,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "81321e3bdf7f"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"custom_container_training_job.run(\n",
|
||||
" args=args,\n",
|
||||
" base_output_dir=gcs_output_uri_prefix,\n",
|
||||
" replica_count=replica_count,\n",
|
||||
" machine_type=machine_type,\n",
|
||||
" accelerator_count=accelerator_count,\n",
|
||||
" accelerator_type=accelerator_type,\n",
|
||||
" tensorboard=tensorboard.resource_name,\n",
|
||||
" service_account=SERVICE_ACCOUNT,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "5100712c2c4c"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(f\"Custom Training Job Name: {custom_container_training_job.resource_name}\")\n",
|
||||
"print(f\"GCS Output URI Prefix: {gcs_output_uri_prefix}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "f9b77676e5a6"
|
||||
},
|
||||
"source": [
|
||||
"### Training Output Artifact"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "0e171ce95ace"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls $gcs_output_uri_prefix"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "cf1b74a12b87"
|
||||
},
|
||||
"source": [
|
||||
"## Clean Up Artifact"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "a0b15089c341"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil rm -rf $gcs_output_uri_prefix"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"name": "multi_node_ddp_nccl_vertex_training_with_custom_container.ipynb",
|
||||
"toc_visible": true
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"name": "python3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
# PyTorch Deployment on Google Cloud: Text Classification
|
||||
|
||||
**This is an Experimental release**, covered by the Pre-GA Offerings Terms of your Google Cloud Platform [Terms of Service](https://cloud.google.com/terms).
|
||||
|
||||
Experiments are focused on validating a prototype and are not guaranteed to be released. They are not intended for production use or covered by any SLA, support obligation, or deprecation policy and might be subject to backward-incompatible changes.
|
||||
|
||||
**Kindly drop us a note before you run any scale tests.**
|
||||
|
||||
**Do not hesitate to contact vertexai-prediction-preview-feedback@google.com if you have any questions or run into any issues.**
|
||||
|
||||
The projects need to be added to the allowlist in order to deploy PyTorch models using Vertex AI Prediction pre-built PyTorch images. If you are interested in the feature, please send an email to vertexai-prediction-preview-feedback@google.com to provide your project numbers OR project ids.
|
||||
|
||||
## Overview
|
||||
|
||||
In the PyTorch on Google Cloud series of blog posts, we aim to share how to deploy PyTorch models at scale on [Vertex AI](https://cloud.google.com/vertex-ai).
|
||||
|
||||
This tutorial on text classification shows how to deploy a PyTorch based text classification model on [Vertex AI](https://cloud.google.com/vertex-ai/docs/start/client-libraries#python) using Vertex SDK and [`gcloud ai`](https://cloud.google.com/sdk/gcloud/reference/beta/ai).
|
||||
|
||||
## Notebooks
|
||||
|
||||
| <h4>Notebook</h4> | <h4>Description</h4> |
|
||||
| :-------- | :------- |
|
||||
| [pytorch-text-classification-vertex-ai-deploy.ipynb](./pytorch-text-classification-vertex-ai-deploy.ipynb) | Notebook to show deploying a PyTorch model on Vertex AI |
|
||||
|
||||
## Folders
|
||||
|
||||
|
||||
| <h4>Folder Name</h4> | <h4>Description</h4> |
|
||||
| :-------- | :------- |
|
||||
| [`predictor`](./predictor) | Folder with custom prediction handler to deploy a PyTorch model to Vertex Prediction. In the [notebook](./pytorch-text-classification-vertex-ai-deploy.ipynb), this folder is used for deploying a PyTorch model on Vertex AI using Vertex Prediction pre-built PyTorch images |
|
||||
@@ -0,0 +1,91 @@
|
||||
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
|
||||
import torch
|
||||
from transformers import AutoModelForSequenceClassification, AutoTokenizer
|
||||
from ts.torch_handler.base_handler import BaseHandler
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TransformersClassifierHandler(BaseHandler):
|
||||
"""
|
||||
The handler takes an input string and returns the classification text
|
||||
based on the serialized transformers checkpoint.
|
||||
"""
|
||||
def __init__(self):
|
||||
super(TransformersClassifierHandler, self).__init__()
|
||||
self.initialized = False
|
||||
|
||||
def initialize(self, ctx):
|
||||
""" Loads the model.pt file and initialized the model object.
|
||||
Instantiates Tokenizer for preprocessor to use
|
||||
Loads labels to name mapping file for post-processing inference response
|
||||
"""
|
||||
self.manifest = ctx.manifest
|
||||
|
||||
properties = ctx.system_properties
|
||||
model_dir = properties.get("model_dir")
|
||||
self.device = torch.device("cuda:" + str(properties.get("gpu_id")) if torch.cuda.is_available() else "cpu")
|
||||
|
||||
# Read model serialize/pt file
|
||||
serialized_file = self.manifest["model"]["serializedFile"]
|
||||
model_pt_path = os.path.join(model_dir, serialized_file)
|
||||
if not os.path.isfile(model_pt_path):
|
||||
raise RuntimeError("Missing the model.pt or pytorch_model.bin file")
|
||||
|
||||
# Load model
|
||||
self.model = AutoModelForSequenceClassification.from_pretrained(model_dir)
|
||||
self.model.to(self.device)
|
||||
self.model.eval()
|
||||
logger.debug('Transformer model from path {0} loaded successfully'.format(model_dir))
|
||||
|
||||
# Ensure to use the same tokenizer used during training
|
||||
self.tokenizer = AutoTokenizer.from_pretrained('bert-base-cased')
|
||||
|
||||
# Read the mapping file, index to object name
|
||||
mapping_file_path = os.path.join(model_dir, "index_to_name.json")
|
||||
|
||||
if os.path.isfile(mapping_file_path):
|
||||
with open(mapping_file_path) as f:
|
||||
self.mapping = json.load(f)
|
||||
else:
|
||||
logger.warning('Missing the index_to_name.json file. Inference output will default.')
|
||||
self.mapping = {"0": "Negative", "1": "Positive"}
|
||||
|
||||
self.initialized = True
|
||||
|
||||
def preprocess(self, data):
|
||||
""" Preprocessing input request by tokenizing
|
||||
Extend with your own preprocessing steps as needed
|
||||
"""
|
||||
text = data[0].get("data")
|
||||
if text is None:
|
||||
text = data[0].get("body")
|
||||
sentences = text.decode('utf-8')
|
||||
logger.info("Received text: '%s'", sentences)
|
||||
|
||||
# Tokenize the texts
|
||||
tokenizer_args = ((sentences,))
|
||||
inputs = self.tokenizer(*tokenizer_args,
|
||||
padding='max_length',
|
||||
max_length=128,
|
||||
truncation=True,
|
||||
return_tensors = "pt")
|
||||
return inputs
|
||||
|
||||
def inference(self, inputs):
|
||||
""" Predict the class of a text using a trained transformer model.
|
||||
"""
|
||||
prediction = self.model(inputs['input_ids'].to(self.device))[0].argmax().item()
|
||||
|
||||
if self.mapping:
|
||||
prediction = self.mapping[str(prediction)]
|
||||
|
||||
logger.info("Model predicted: '%s'", prediction)
|
||||
return [prediction]
|
||||
|
||||
def postprocess(self, inference_output):
|
||||
return inference_output
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
{
|
||||
"0": "Negative",
|
||||
"1": "Positive"
|
||||
}
|
||||
+1625
File diff suppressed because it is too large
Load Diff
+13
-13
@@ -658,8 +658,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"datasets = load_dataset(\"imdb\")\n",
|
||||
"datasets"
|
||||
"dataset = load_dataset(\"imdb\")\n",
|
||||
"dataset"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -668,7 +668,7 @@
|
||||
"id": "RzfPtOMoIrIu"
|
||||
},
|
||||
"source": [
|
||||
"The `datasets` object itself is [`DatasetDict`](https://huggingface.co/docs/datasets/package_reference/main_classes.html#datasetdict), which contains one key for the training, validation and test set."
|
||||
"The `dataset` object itself is [`DatasetDict`](https://huggingface.co/docs/datasets/package_reference/main_classes.html#datasetdict), which contains one key for the training, validation and test set."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -681,12 +681,12 @@
|
||||
"source": [
|
||||
"print(\n",
|
||||
" \"Total # of rows in training dataset {} and size {:5.2f} MB\".format(\n",
|
||||
" datasets[\"train\"].shape[0], datasets[\"train\"].size_in_bytes / (1024 * 1024)\n",
|
||||
" dataset[\"train\"].shape[0], dataset[\"train\"].size_in_bytes / (1024 * 1024)\n",
|
||||
" )\n",
|
||||
")\n",
|
||||
"print(\n",
|
||||
" \"Total # of rows in test dataset {} and size {:5.2f} MB\".format(\n",
|
||||
" datasets[\"test\"].shape[0], datasets[\"test\"].size_in_bytes / (1024 * 1024)\n",
|
||||
" dataset[\"test\"].shape[0], dataset[\"test\"].size_in_bytes / (1024 * 1024)\n",
|
||||
" )\n",
|
||||
")"
|
||||
]
|
||||
@@ -708,7 +708,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"datasets[\"train\"][0]"
|
||||
"dataset[\"train\"][0]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -728,7 +728,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"label_list = datasets[\"train\"].unique(\"label\")\n",
|
||||
"label_list = dataset[\"train\"].unique(\"label\")\n",
|
||||
"label_list"
|
||||
]
|
||||
},
|
||||
@@ -779,7 +779,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"show_random_elements(datasets[\"train\"])"
|
||||
"show_random_elements(dataset[\"train\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -883,7 +883,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"example = datasets[\"train\"][4]\n",
|
||||
"example = dataset[\"train\"][4]\n",
|
||||
"print(example)"
|
||||
]
|
||||
},
|
||||
@@ -920,7 +920,7 @@
|
||||
"source": [
|
||||
"# Dataset loading repeated here to make this cell idempotent\n",
|
||||
"# Since we are over-writing datasets variable\n",
|
||||
"datasets = load_dataset(\"imdb\")\n",
|
||||
"dataset = load_dataset(\"imdb\")\n",
|
||||
"\n",
|
||||
"# Mapping labels to ids\n",
|
||||
"# NOTE: We can extract this automatically but the `Unique` method of the datasets\n",
|
||||
@@ -948,7 +948,7 @@
|
||||
"\n",
|
||||
"\n",
|
||||
"# apply preprocessing function to input examples\n",
|
||||
"datasets = datasets.map(preprocess_function, batched=True, load_from_cache_file=True)"
|
||||
"dataset = dataset.map(preprocess_function, batched=True, load_from_cache_file=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1091,8 +1091,8 @@
|
||||
"trainer = Trainer(\n",
|
||||
" model,\n",
|
||||
" args,\n",
|
||||
" train_dataset=datasets[\"train\"],\n",
|
||||
" eval_dataset=datasets[\"test\"],\n",
|
||||
" train_dataset=dataset[\"train\"],\n",
|
||||
" eval_dataset=dataset[\"test\"],\n",
|
||||
" data_collator=default_data_collator,\n",
|
||||
" tokenizer=tokenizer,\n",
|
||||
" compute_metrics=compute_metrics,\n",
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
google-cloud-bigquery==2.20.0
|
||||
tensorflow==2.5.3
|
||||
tensorflow==2.7.2
|
||||
pillow==9.0.1
|
||||
tf-agents==0.8.0
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
google-cloud-pubsub==2.5.0
|
||||
pillow==9.0.1
|
||||
tf-agents==0.8.0
|
||||
tensorflow==2.5.3
|
||||
tensorflow==2.7.2
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
dataclasses==0.6
|
||||
google-cloud-aiplatform==1.8.1
|
||||
tensorflow==2.5.3
|
||||
tensorflow==2.7.2
|
||||
pillow==9.0.1
|
||||
tf-agents==0.8.0
|
||||
+1
-1
@@ -1 +1 @@
|
||||
tensorflow==2.5.3
|
||||
tensorflow==2.7.2
|
||||
+1
-1
@@ -1 +1 @@
|
||||
tensorflow==2.5.3
|
||||
tensorflow==2.7.2
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
The [official](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/official) folder contains notebooks organized by Google Cloud product.
|
||||
The [official](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/official) folder contains notebooks organized by Google Cloud product. These are tested weekly and maintained by Google.
|
||||
|
||||
The [community](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/community) folder contains notebooks that aren't officially supported by Google.
|
||||
The [community](https://github.com/GoogleCloudPlatform/vertex-ai-samples/tree/main/notebooks/community) folder contains notebooks that may be created by Google or external contributors. They are not necessary maintained.
|
||||
|
||||
Contributions to the repo should use the [notebook template](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.ipynb) as a starting point.
|
||||
|
||||
@@ -5,18 +5,32 @@
|
||||
|
||||
/sdk/sdk_* @andrewferlitsch
|
||||
/gapic @andrewferlitsch
|
||||
/gapic/custom/showcase_custom_image_classification_online_explain_example_based_api.ipynb @inardini
|
||||
/ml_ops @andrewferlitsch
|
||||
/model_monitoring/* @mco-gh
|
||||
/model_monitoring/* @andrewferlitsch
|
||||
/structured_data/rapid_prototyping_* @rafael-carvalho
|
||||
|
||||
/managed_notebooks/
|
||||
/bigquery_ml/ @polong
|
||||
/sdk/SDK_FBProphet_Forecasting_Online.ipynb @brianchunkang
|
||||
/pipelines/google_cloud_pipeline_components_TPU_model_train_upload_deploy.ipynb @brianchunkang
|
||||
/explainable_ai/SDK_Custom_Container_XAI.ipynb @brianchunkang
|
||||
/matching_engine/sdk_matching_engine_for_indexing.ipynb @ivanmkc
|
||||
/matching_engine/matching_engine_for_indexing.ipynb @yinghsienwu
|
||||
/matching_engine/stream_update_for_matching_engine.ipynb @peterping666
|
||||
/sdk/pytorch_lightning_custom_container_training.ipynb @brianchunkang
|
||||
/tensorboard @yfang1
|
||||
/feature_store @nayaknishant @morgandu
|
||||
/prediction @googleapis/vertex-prediction-team
|
||||
/vertex_endpoints/tf_hub_obj_detection/deploy_tfhub_object_detection_on_vertex_endpoints.ipynb @entrpn
|
||||
/vertex_endpoints/nvidia-triton/nvidia-triton-custom-container-prediction.ipynb @RajeshThallam
|
||||
/vertex_endpoints/optimized_tensorflow_runtime @vlasenkoalexey
|
||||
/notebooks/community/ml_ops/stage2/get_started_with_visionapi_and_automl.ipynb @mansari
|
||||
/notebooks/community/neo4j/graph_paysim.ipynb @benofben @laeg
|
||||
/notebooks/community/ml_ops/stage1/get_started_with_visionapi_and_vertex_datasets.ipynb @mansari
|
||||
/notebooks/community/pipelines/google_cloud_pipeline_components_bqml_pipeline_demand_forecasting.ipynb @inardini
|
||||
/notebooks/community/ml_ops/stage2/get_started_vertex_hpt_r_kernel.ipynb @fhirschmann
|
||||
/notebooks/community/ml_ops/stage2/get_started_vertex_training_r_using_r_kernel.ipynb @fhirschmann
|
||||
/notebooks/community/vertex-ai-samples/notebooks/community/model_registry/vertex_ai_model_registry_bqml_custom_model_versioning.ipynb @inardini
|
||||
/notebooks/community/vertex-ai-samples/notebooks/community/model_registry/vertex_ai_model_registry_automl_model_versioning.ipynb @inardini
|
||||
/notebooks/community/vizier/conversions_vertex_vizier_and_open_source_vizier.ipynb @halio-g
|
||||
|
||||
+808
-390
File diff suppressed because it is too large
Load Diff
+128
-36
@@ -292,6 +292,37 @@
|
||||
" PROJECT_ID = \"python-docs-samples-tests\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "d9f118b92c74"
|
||||
},
|
||||
"source": [
|
||||
"#### UUID\n",
|
||||
"\n",
|
||||
"If you are in a live tutorial session, you might be using a shared test account or project. To avoid name collisions between users on resources created, you create a uuid for each instance session, and append it onto the name of resources you create in this tutorial."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "3ee72715c0fd"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import random\n",
|
||||
"import string\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Generate a uuid of a specifed length(default=8)\n",
|
||||
"def generate_uuid(length: int = 8) -> str:\n",
|
||||
" return \"\".join(random.choices(string.ascii_lowercase + string.digits, k=length))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"UUID = generate_uuid()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -478,7 +509,6 @@
|
||||
"from google.cloud.aiplatform_v1.types import \\\n",
|
||||
" featurestore_service as featurestore_service_pb2\n",
|
||||
"from google.cloud.aiplatform_v1.types import io as io_pb2\n",
|
||||
"from google.protobuf.duration_pb2 import Duration\n",
|
||||
"\n",
|
||||
"# Create admin_client for CRUD and data_client for reading feature values.\n",
|
||||
"admin_client = FeaturestoreServiceClient(client_options={\"api_endpoint\": API_ENDPOINT})\n",
|
||||
@@ -542,7 +572,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"FEATURESTORE_ID = \"movie_prediction\"\n",
|
||||
"FEATURESTORE_ID = f\"movie_prediction_{UUID}\"\n",
|
||||
"try:\n",
|
||||
" create_lro = admin_client.create_featurestore(\n",
|
||||
" featurestore_service_pb2.CreateFeaturestoreRequest(\n",
|
||||
@@ -567,7 +597,7 @@
|
||||
"id": "ag8pCQ7rNjVf"
|
||||
},
|
||||
"source": [
|
||||
"You can use [GetFeaturestore](https://cloud.google.com/vertex-ai/docs/reference/rpc/google.cloud.aiplatform.v1beta1#google.cloud.aiplatform.v1beta1.FeaturestoreService.GetFeaturestore) or [ListFeaturestores](https://cloud.google.com/vertex-ai/docs/reference/rpc/google.cloud.aiplatform.v1beta1#google.cloud.aiplatform.v1beta1.FeaturestoreService.ListFeaturestores) to check if the Featurestore was successfully created. The following example gets the details of the Featurestore.\n"
|
||||
"You can use [GetFeaturestore](https://cloud.google.com/vertex-ai/docs/reference/rpc/google.cloud.aiplatform.v1#google.cloud.aiplatform.v1.FeaturestoreService.GetFeaturestore) or [ListFeaturestores](https://cloud.google.com/vertex-ai/docs/reference/rpc/google.cloud.aiplatform.v1#google.cloud.aiplatform.v1.FeaturestoreService.ListFeaturestores) to check if the Featurestore was successfully created. The following example gets the details of the Featurestore.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -589,7 +619,7 @@
|
||||
"id": "018ab19d934f"
|
||||
},
|
||||
"source": [
|
||||
"Auto scaling is available in v1beta1 since v1.11. Below is the example for the `CreateFeaturestoreRequest` with auto-scaling, use it with `aiplatform_v1beta1.FeaturestoreServiceClient` to create Featurestore:"
|
||||
"Auto scaling is available in v1 since v1.11. Below is the example for the `CreateFeaturestoreRequest` with auto-scaling, use it with `aiplatform_v1.FeaturestoreServiceClient` to create Featurestore:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -600,17 +630,17 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from google.cloud.aiplatform_v1beta1.types import \\\n",
|
||||
" featurestore as v1beta1_featurestore_pb2\n",
|
||||
"from google.cloud.aiplatform_v1beta1.types import \\\n",
|
||||
" featurestore_service as v1beta1_featurestore_service_pb2\n",
|
||||
"from google.cloud.aiplatform_v1.types import \\\n",
|
||||
" featurestore as v1_featurestore_pb2\n",
|
||||
"from google.cloud.aiplatform_v1.types import \\\n",
|
||||
" featurestore_service as v1_featurestore_service_pb2\n",
|
||||
"\n",
|
||||
"create_featurestore_request = v1beta1_featurestore_service_pb2.CreateFeaturestoreRequest(\n",
|
||||
"create_featurestore_request = v1_featurestore_service_pb2.CreateFeaturestoreRequest(\n",
|
||||
" parent=BASE_RESOURCE_PATH,\n",
|
||||
" featurestore_id=FEATURESTORE_ID,\n",
|
||||
" featurestore=v1beta1_featurestore_pb2.Featurestore(\n",
|
||||
" online_serving_config=v1beta1_featurestore_pb2.Featurestore.OnlineServingConfig(\n",
|
||||
" scaling=v1beta1_featurestore_pb2.Featurestore.OnlineServingConfig.Scaling(\n",
|
||||
" featurestore=v1_featurestore_pb2.Featurestore(\n",
|
||||
" online_serving_config=v1_featurestore_pb2.Featurestore.OnlineServingConfig(\n",
|
||||
" scaling=v1_featurestore_pb2.Featurestore.OnlineServingConfig.Scaling(\n",
|
||||
" min_node_count=1, max_node_count=5\n",
|
||||
" )\n",
|
||||
" ),\n",
|
||||
@@ -675,14 +705,67 @@
|
||||
" print(e)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dPkT7KDuEvWv"
|
||||
},
|
||||
"source": [
|
||||
"Feature [monitoring](https://cloud.google.com/vertex-ai/docs/featurestore/monitoring) is in preview, so you need to use v1 Python. Import feature analysis is only available through SDK for now."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "9kiqrBN6E28r"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from google.cloud.aiplatform_v1 import \\\n",
|
||||
" FeaturestoreServiceClient as v1_FeaturestoreServiceClient\n",
|
||||
"from google.cloud.aiplatform_v1.types import entity_type as v1_entity_type_pb2\n",
|
||||
"from google.cloud.aiplatform_v1.types import \\\n",
|
||||
" featurestore_monitoring as v1_featurestore_monitoring_pb2\n",
|
||||
"from google.cloud.aiplatform_v1.types import \\\n",
|
||||
" featurestore_service as v1_featurestore_service_pb2\n",
|
||||
"\n",
|
||||
"v1_admin_client = v1_FeaturestoreServiceClient(\n",
|
||||
" client_options={\"api_endpoint\": API_ENDPOINT}\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Enable import feature analysis for users entity type.\n",
|
||||
"# All Features belonging to this EntityType will by default inherit the monitoring config.\n",
|
||||
"v1_admin_client.update_entity_type(\n",
|
||||
" v1_featurestore_service_pb2.UpdateEntityTypeRequest(\n",
|
||||
" entity_type=v1_entity_type_pb2.EntityType(\n",
|
||||
" name=admin_client.entity_type_path(\n",
|
||||
" PROJECT_ID, REGION, FEATURESTORE_ID, \"users\"\n",
|
||||
" ),\n",
|
||||
" monitoring_config=v1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig(\n",
|
||||
" import_features_analysis=v1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig.ImportFeaturesAnalysis(\n",
|
||||
" anomaly_detection_baseline=v1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig.ImportFeaturesAnalysis.Baseline.LATEST_STATS,\n",
|
||||
" state=v1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig.ImportFeaturesAnalysis.State.ENABLED,\n",
|
||||
" ),\n",
|
||||
" numerical_threshold_config=v1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig.ThresholdConfig(\n",
|
||||
" value=0.001,\n",
|
||||
" ),\n",
|
||||
" categorical_threshold_config=v1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig.ThresholdConfig(\n",
|
||||
" value=0.001,\n",
|
||||
" ),\n",
|
||||
" ),\n",
|
||||
" ),\n",
|
||||
" )\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "85b1f59fbf6d"
|
||||
},
|
||||
"source": [
|
||||
"Feature [monitoring](https://cloud.google.com/vertex-ai/docs/featurestore/monitoring) is in preview, so you need to use v1beta1 Python. The easiest way to set this for now is using [console UI](https://console.cloud.google.com/vertex-ai/features). For completeness, below is example to do this using v1beta1 SDK.\n",
|
||||
"\n",
|
||||
"The easiest way to set up snapshot analysis for now is using [console UI](https://console.cloud.google.com/vertex-ai/features). For completeness, below is example to do this using v1 SDK.\n",
|
||||
"\n",
|
||||
"You can view monitoring statistics on [console UI](https://console.cloud.google.com/vertex-ai/features)."
|
||||
]
|
||||
@@ -695,30 +778,36 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from google.cloud.aiplatform_v1beta1 import \\\n",
|
||||
" FeaturestoreServiceClient as v1beta1_FeaturestoreServiceClient\n",
|
||||
"from google.cloud.aiplatform_v1beta1.types import \\\n",
|
||||
" entity_type as v1beta1_entity_type_pb2\n",
|
||||
"from google.cloud.aiplatform_v1beta1.types import \\\n",
|
||||
" featurestore_monitoring as v1beta1_featurestore_monitoring_pb2\n",
|
||||
"from google.cloud.aiplatform_v1beta1.types import \\\n",
|
||||
" featurestore_service as v1beta1_featurestore_service_pb2\n",
|
||||
"from google.cloud.aiplatform_v1 import \\\n",
|
||||
" FeaturestoreServiceClient as v1_FeaturestoreServiceClient\n",
|
||||
"from google.cloud.aiplatform_v1.types import entity_type as v1_entity_type_pb2\n",
|
||||
"from google.cloud.aiplatform_v1.types import \\\n",
|
||||
" featurestore_monitoring as v1_featurestore_monitoring_pb2\n",
|
||||
"from google.cloud.aiplatform_v1.types import \\\n",
|
||||
" featurestore_service as v1_featurestore_service_pb2\n",
|
||||
"\n",
|
||||
"v1beta1_admin_client = v1beta1_FeaturestoreServiceClient(\n",
|
||||
"v1_admin_client = v1_FeaturestoreServiceClient(\n",
|
||||
" client_options={\"api_endpoint\": API_ENDPOINT}\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Enable monitoring for users entity type.\n",
|
||||
"# Enable snapshot analysis for users entity type.\n",
|
||||
"# All Features belonging to this EntityType will by default inherit the monitoring config.\n",
|
||||
"v1beta1_admin_client.update_entity_type(\n",
|
||||
" v1beta1_featurestore_service_pb2.UpdateEntityTypeRequest(\n",
|
||||
" entity_type=v1beta1_entity_type_pb2.EntityType(\n",
|
||||
"v1_admin_client.update_entity_type(\n",
|
||||
" v1_featurestore_service_pb2.UpdateEntityTypeRequest(\n",
|
||||
" entity_type=v1_entity_type_pb2.EntityType(\n",
|
||||
" name=admin_client.entity_type_path(\n",
|
||||
" PROJECT_ID, REGION, FEATURESTORE_ID, \"users\"\n",
|
||||
" ),\n",
|
||||
" monitoring_config=v1beta1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig(\n",
|
||||
" snapshot_analysis=v1beta1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig.SnapshotAnalysis(\n",
|
||||
" monitoring_interval=Duration(seconds=86400), # 1 day\n",
|
||||
" monitoring_config=v1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig(\n",
|
||||
" snapshot_analysis=v1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig.SnapshotAnalysis(\n",
|
||||
" monitoring_interval_days=1, # 1 day\n",
|
||||
" staleness_days=30,\n",
|
||||
" ),\n",
|
||||
" numerical_threshold_config=v1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig.ThresholdConfig(\n",
|
||||
" value=0.001,\n",
|
||||
" ),\n",
|
||||
" categorical_threshold_config=v1_featurestore_monitoring_pb2.FeaturestoreMonitoringConfig.ThresholdConfig(\n",
|
||||
" value=0.001,\n",
|
||||
" ),\n",
|
||||
" ),\n",
|
||||
" ),\n",
|
||||
@@ -754,6 +843,7 @@
|
||||
" feature=feature_pb2.Feature(\n",
|
||||
" value_type=feature_pb2.Feature.ValueType.INT64,\n",
|
||||
" description=\"User age\",\n",
|
||||
" disable_monitoring=False,\n",
|
||||
" ),\n",
|
||||
" feature_id=\"age\",\n",
|
||||
" ),\n",
|
||||
@@ -761,6 +851,8 @@
|
||||
" feature=feature_pb2.Feature(\n",
|
||||
" value_type=feature_pb2.Feature.ValueType.STRING,\n",
|
||||
" description=\"User gender\",\n",
|
||||
" # Default is False. If True, Feature 'gender' monitoring analysis is disabled.\n",
|
||||
" disable_monitoring=True,\n",
|
||||
" ),\n",
|
||||
" feature_id=\"gender\",\n",
|
||||
" ),\n",
|
||||
@@ -827,8 +919,8 @@
|
||||
"source": [
|
||||
"## Search created features\n",
|
||||
"\n",
|
||||
"While the [ListFeatures](https://cloud.google.com/vertex-ai/docs/reference/rpc/google.cloud.aiplatform.v1beta1#google.cloud.aiplatform.v1beta1.FeaturestoreService.ListFeatures) method allows you to easily view all features of a single\n",
|
||||
"entity type, the [SearchFeatures](https://cloud.google.com/vertex-ai/docs/reference/rpc/google.cloud.aiplatform.v1beta1#google.cloud.aiplatform.v1beta1.FeaturestoreService.SearchFeatures) method searches across all featurestores\n",
|
||||
"While the [ListFeatures](https://cloud.google.com/vertex-ai/docs/reference/rpc/google.cloud.aiplatform.v1#google.cloud.aiplatform.v1.FeaturestoreService.ListFeatures) method allows you to easily view all features of a single\n",
|
||||
"entity type, the [SearchFeatures](https://cloud.google.com/vertex-ai/docs/reference/rpc/google.cloud.aiplatform.v1#google.cloud.aiplatform.v1.FeaturestoreService.SearchFeatures) method searches across all featurestores\n",
|
||||
"and entity types in a given location (such as `us-central1`). This can help you discover features that were created by someone else.\n",
|
||||
"\n",
|
||||
"You can query based on feature properties including feature ID, entity type ID,\n",
|
||||
@@ -1030,6 +1122,8 @@
|
||||
" ],\n",
|
||||
" feature_time_field=\"update_time\",\n",
|
||||
" worker_count=1,\n",
|
||||
" # Default is False. If True, the import feature analysis won't happen for this specific operation.\n",
|
||||
" disable_ingestion_analysis=False,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
@@ -1140,7 +1234,7 @@
|
||||
},
|
||||
"source": [
|
||||
"The\n",
|
||||
"[Online Serving APIs](https://cloud.google.com/vertex-ai/docs/reference/rpc/google.cloud.aiplatform.v1beta1#featurestoreonlineservingservice)\n",
|
||||
"[Online Serving APIs](https://cloud.google.com/vertex-ai/docs/reference/rpc/google.cloud.aiplatform.v1#featurestoreonlineservingservice)\n",
|
||||
"lets you serve feature values for small batches of entities. It's designed for latency-sensitive service, such as online model prediction. For example, for a movie service, you might want to quickly shows movies that the current user would most likely watch by using online predictions."
|
||||
]
|
||||
},
|
||||
@@ -1438,9 +1532,7 @@
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"collapsed_sections": [
|
||||
"ze4-nDLfK4pw"
|
||||
],
|
||||
"collapsed_sections": [],
|
||||
"name": "gapic-feature-store.ipynb",
|
||||
"toc_visible": true
|
||||
},
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 140 KiB |
+349
-205
@@ -32,18 +32,18 @@
|
||||
"<table align=\"left\">\n",
|
||||
"\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.ipynb\">\n",
|
||||
" <a href=\"https://colab.research.google.com/github/vertex-ai-samples/blob/main/notebooks/community/feature_store/mobile_gaming/mobile_gaming_feature_store.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.ipynb\">\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/feature_store/mobile_gaming/mobile_gaming_feature_store.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/feature_store/mobile_gaming/mobile_gaming_feature_store.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -54,52 +54,52 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "7FZeBEwdXS4d"
|
||||
"id": "tvgnzT1CKxrO"
|
||||
},
|
||||
"source": [
|
||||
"## Overview\n",
|
||||
"\n",
|
||||
"Imagine you are a member of the Data Science team working on the same Mobile Gaming application reported in the [Churn prediction for game developers using Google Analytics 4 (GA4) and BigQuery ML](https://cloud.google.com/blog/topics/developers-practitioners/churn-prediction-game-developers-using-google-analytics-4-ga4-and-bigquery-ml) blog post. \n",
|
||||
"\n",
|
||||
"Business wants to use that information in real-time to take immediate intervention actions in-game to prevent churn. In particular, for each player, they want to provide gaming incentives like new items or bonus packs depending on the customer demographic, behavioral information and the resulting propensity of return. \n",
|
||||
"\n",
|
||||
"Last year, Google Cloud announced Vertex AI, a managed machine learning (ML) platform that allows data science teams to accelerate the deployment and maintenance of ML models. One of the platform building blocks is Vertex AI Feature store which provides a managed service for low latency scalable feature serving. Also it is a centralized feature repository with easy APIs to search & discover features and feature monitoring capabilities to track drift and other quality issues. \n",
|
||||
"\n",
|
||||
"In this notebook, we will show how the role of Vertex AI Feature Store in a ready to production scenario when the user's activities within the first 24 hours of last engagment and the gaming platform would consume in order to improver UX. Below you can find the high level picture of the system\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"Imagine you are a member of the Data Science team working on the same Mobile Gaming application reported in the [Churn prediction for game developers using Google Analytics 4 (GA4) and BigQuery ML](https://cloud.google.com/blog/topics/developers-practitioners/churn-prediction-game-developers-using-google-analytics-4-ga4-and-bigquery-ml) blog post.\n",
|
||||
" \n",
|
||||
"Business wants to use that information in real-time to take immediate intervention actions in-game to prevent churn. In particular, for each player, they want to provide gaming incentives like new items or bonus packs depending on the customer demographic, behavioral information and the resulting propensity of return.\n",
|
||||
" \n",
|
||||
"Last year, Google Cloud announced Vertex AI, a managed machine learning (ML) platform that allows data science teams to accelerate the deployment and maintenance of ML models. One of the platform building blocks is Vertex AI Feature store which provides a managed service for low latency scalable feature serving. Also it is a centralized feature repository with easy APIs to search & discover features and feature monitoring capabilities to track drift and other quality issues.\n",
|
||||
" \n",
|
||||
"In this notebook, we will show how the role of Vertex AI Feature Store in a ready to production scenario when the user's activities within the first 24 hours of last engagement and the gaming platform would consume in order to improve UX. Below you can find the high level picture of the system\n",
|
||||
" \n",
|
||||
"<img src=\"./assets/mobile_gaming_architecture_1.png\">\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" \n",
|
||||
" \n",
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"The dataset is the public sample export data from an actual mobile game app called \"Flood It!\" (Android, iOS)\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"### Objective\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"In the following notebook, you will learn how Vertex AI Feature store\n",
|
||||
"\n",
|
||||
"1. Provide a centralized feature repository with easy APIs to search & discover features and fetch them for training/serving. \n",
|
||||
"\n",
|
||||
"2. Simplify deployments of models for Online Prediction, via low latency scalable feature serving.\n",
|
||||
"\n",
|
||||
"3. Mitigate training serving skew and data leakage by performing point in time lookups to fetch historical data for training.\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"1. Provide a centralized feature repository with easy APIs to search & discover features and fetch them for training/serving.\n",
|
||||
" \n",
|
||||
"2. Simplify deployments of models for Online Prediction, via low latency scalable feature serving.\n",
|
||||
" \n",
|
||||
"3. Mitigate training serving skew and data leakage by performing point in time lookups to fetch historical data for training.\n",
|
||||
" \n",
|
||||
"**Notice that we assume that already know how to set up a Vertex AI Feature store. In case you are not, please check out [this detailed notebook](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/feature_store/gapic-feature-store.ipynb).**\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"### Costs \n",
|
||||
"\n",
|
||||
" \n",
|
||||
" \n",
|
||||
"### Costs\n",
|
||||
" \n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"* Vertex AI\n",
|
||||
"* BigQuery\n",
|
||||
"* Cloud Storage\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"Learn about [Vertex AI\n",
|
||||
"pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage\n",
|
||||
"pricing](https://cloud.google.com/storage/pricing), and use the [Pricing\n",
|
||||
"Calculator](https://cloud.google.com/products/calculator/)\n",
|
||||
"to generate a cost estimate based on your projected usage."
|
||||
"to generate a cost estimate based on your projected usage.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -110,7 +110,7 @@
|
||||
"source": [
|
||||
"### Set up your local development environment\n",
|
||||
"\n",
|
||||
"**If you are using Colab or Google Cloud Notebooks**, your environment already meets\n",
|
||||
"**If you are using Colab or Vertex AI Workbench Notebooks**, your environment already meets\n",
|
||||
"all the requirements to run this notebook. You can skip this step."
|
||||
]
|
||||
},
|
||||
@@ -159,7 +159,7 @@
|
||||
"source": [
|
||||
"### Install additional packages\n",
|
||||
"\n",
|
||||
"Install additional package dependencies not installed in your notebook environment, such as {XGBoost, AdaNet, or TensorFlow Hub TODO: Replace with relevant packages for the tutorial}. Use the latest major GA version of each package."
|
||||
"Install additional package dependencies not installed in your notebook environment, such as XGBoost. Use the latest major GA version of each package."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -172,12 +172,15 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\""
|
||||
]
|
||||
},
|
||||
@@ -185,11 +188,11 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "SzEo6DeE2GOP"
|
||||
"id": "_vr6BYED_5my"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip3 install {USER_FLAG} --upgrade pip\n",
|
||||
"! pip3 install {USER_FLAG} --upgrade pip -q\n",
|
||||
"! pip3 install {USER_FLAG} --upgrade google-cloud-aiplatform==1.11.0 -q --no-warn-conflicts\n",
|
||||
"! pip3 install {USER_FLAG} git+https://github.com/googleapis/python-aiplatform.git@main # For features monitoring\n",
|
||||
"! pip3 install {USER_FLAG} --upgrade google-cloud-bigquery==2.24.0 -q --no-warn-conflicts\n",
|
||||
@@ -249,7 +252,7 @@
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI API and Compute Engine API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,compute_component). \n",
|
||||
"1. [Enable the APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,notebooks.googleapis.com, ). \n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you will need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
@@ -307,18 +310,76 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if PROJECT_ID == \"\" or PROJECT_ID is None:\n",
|
||||
" PROJECT_ID = \"\" # @param {type:\"string\"}"
|
||||
" PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "dEjRdjxBuDsi"
|
||||
"id": "set_gcloud_project_id"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!gcloud config set project $PROJECT_ID #change it"
|
||||
"! gcloud config set project $PROJECT_ID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "23988890fef6"
|
||||
},
|
||||
"source": [
|
||||
"#### Get your project number (Optional)\n",
|
||||
"\n",
|
||||
"Now that the project ID is set, you get your corresponding project number."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "2d6950574e1d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"shell_output = ! gcloud projects list --filter=\"PROJECT_ID:'{PROJECT_ID}'\" --format='value(PROJECT_NUMBER)'\n",
|
||||
"PROJECT_NUMBER = shell_output[0]\n",
|
||||
"print(\"Project Number:\", PROJECT_NUMBER)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "region"
|
||||
},
|
||||
"source": [
|
||||
"#### Region\n",
|
||||
"\n",
|
||||
"You can also change the `REGION` variable, which is used for operations\n",
|
||||
"throughout the rest of this notebook. Below are regions supported for Vertex AI. We recommend that you choose the region closest to you.\n",
|
||||
"\n",
|
||||
"- Americas: `us-central1`\n",
|
||||
"- Europe: `europe-west4`\n",
|
||||
"- Asia Pacific: `asia-east1`\n",
|
||||
"\n",
|
||||
"You may not use a multi-regional bucket for training with Vertex AI. Not all regions provide support for all Vertex AI services.\n",
|
||||
"\n",
|
||||
"Learn more about [Vertex AI regions](https://cloud.google.com/vertex-ai/docs/general/locations)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "jIcZV7-C2RrX"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -353,7 +414,7 @@
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Google Cloud Notebooks**, your environment is already\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already\n",
|
||||
"authenticated. Skip this step."
|
||||
]
|
||||
},
|
||||
@@ -376,9 +437,13 @@
|
||||
"3. In the **Service account name** field, enter a name, and\n",
|
||||
" click **Create**.\n",
|
||||
"\n",
|
||||
"4. In the **Grant this service account access to project** section, click the **Role** drop-down list. Type \"Vertex AI\"\n",
|
||||
"into the filter box, and select\n",
|
||||
" **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"4. In the **Grant this service account access to project** section, click the **Role** drop-down list and add the following roles:\n",
|
||||
" - BigQuery Admin\n",
|
||||
" - Storage Admin\n",
|
||||
" - Storage Object Admin\n",
|
||||
" - Vertex AI Administrator\n",
|
||||
" - Vertex AI Feature Store Admin\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"5. Click *Create*. A JSON file that contains your key downloads to your\n",
|
||||
"local environment.\n",
|
||||
@@ -395,19 +460,19 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Google Cloud Notebooks, then don't execute this code\n",
|
||||
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = \"google.colab\" in sys.modules\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
@@ -447,8 +512,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}\n",
|
||||
"REGION = \"[your-region]\" # @param {type:\"string\"}"
|
||||
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
|
||||
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -459,11 +524,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"-aip-\" + TIMESTAMP\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = PROJECT_ID + \"-aip-\" + TIMESTAMP\n",
|
||||
" BUCKET_URI = f\"gs://{BUCKET_NAME}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -486,26 +549,6 @@
|
||||
"! gsutil mb -l $REGION -p $PROJECT_ID $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "994afa65eaa2"
|
||||
},
|
||||
"source": [
|
||||
"Run the following cell to grant access to your Cloud Storage resources from Vertex AI Feature store"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "psP1rPU9TRnX"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil uniformbucketlevelaccess set on $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -526,6 +569,78 @@
|
||||
"! gsutil ls -al $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "set_service_account"
|
||||
},
|
||||
"source": [
|
||||
"#### Service Account (Optional)\n",
|
||||
"\n",
|
||||
"If you do not want to use your project's Compute Engine service account, set `SERVICE_ACCOUNT` to another service account ID."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "MQVV9haf2Rra"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"SERVICE_ACCOUNT = \"[your-service-account]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "autoset_service_account"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if (\n",
|
||||
" SERVICE_ACCOUNT == \"\"\n",
|
||||
" or SERVICE_ACCOUNT is None\n",
|
||||
" or SERVICE_ACCOUNT == \"[your-service-account]\"\n",
|
||||
"):\n",
|
||||
" # Get your service account from gcloud\n",
|
||||
" if not IS_COLAB:\n",
|
||||
" shell_output = !gcloud auth list 2>/dev/null\n",
|
||||
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
|
||||
"\n",
|
||||
" else: # IS_COLAB:\n",
|
||||
" shell_output = ! gcloud projects describe $PROJECT_ID\n",
|
||||
" project_number = shell_output[-1].split(\":\")[1].strip().replace(\"'\", \"\")\n",
|
||||
" SERVICE_ACCOUNT = f\"{project_number}-compute@developer.gserviceaccount.com\"\n",
|
||||
"\n",
|
||||
" print(\"Service Account:\", SERVICE_ACCOUNT)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "set_service_account:pipelines"
|
||||
},
|
||||
"source": [
|
||||
"#### Set service account access\n",
|
||||
"\n",
|
||||
"Run the following commands to grant your service account access. You only need to run this step once per service account."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "U4UpQThc2Rrb"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectCreator $BUCKET_URI\n",
|
||||
"\n",
|
||||
"! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.objectViewer $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -541,13 +656,22 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "G3G2BXqswb_J"
|
||||
"id": "8615339fa4ca"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BQ_DATASET = \"Mobile_Gaming\" # @param {type:\"string\"}\n",
|
||||
"LOCATION = \"US\"\n",
|
||||
"\n",
|
||||
"LOCATION = \"US\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "G3G2BXqswb_J"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!bq mk --location=$LOCATION --dataset $PROJECT_ID:$BQ_DATASET"
|
||||
]
|
||||
},
|
||||
@@ -600,12 +724,9 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Data Engineering and Feature Engineering\n",
|
||||
"TODAY = \"2018-10-03\"\n",
|
||||
"TOMORROW = \"2018-10-04\"\n",
|
||||
"TODAY = \"2022-06-16\"\n",
|
||||
"LABEL_TABLE = f\"label_table_{TODAY}\".replace(\"-\", \"\")\n",
|
||||
"FEATURES_TABLE = \"wide_features_table\" # @param {type:\"string\"}\n",
|
||||
"FEATURES_TABLE_TODAY = f\"wide_features_table_{TODAY}\".replace(\"-\", \"\")\n",
|
||||
"FEATURES_TABLE_TOMORROW = f\"wide_features_table_{TOMORROW}\".replace(\"-\", \"\")\n",
|
||||
"FEATURES_TABLE = f\"wide_features_table_{TODAY}\" # @param {type:\"string\"}\n",
|
||||
"FEATURESTORE_ID = \"mobile_gaming\" # @param {type:\"string\"}\n",
|
||||
"ENTITY_TYPE_ID = \"user\"\n",
|
||||
"\n",
|
||||
@@ -947,13 +1068,37 @@
|
||||
"You will cover those steps in details below."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "init_aip:mbsdk,all"
|
||||
},
|
||||
"source": [
|
||||
"### Initialize Vertex AI SDK for Python\n",
|
||||
"\n",
|
||||
"Initialize the Vertex AI SDK for Python for your project and corresponding bucket."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "poLJ0fV52Rrc"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"vertex_ai.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_URI)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "4ffd54e97270"
|
||||
},
|
||||
"source": [
|
||||
"## Initiate clients"
|
||||
"### Initialize BigQuery SDK for Python\n",
|
||||
"\n",
|
||||
"Initialize the BigQuery AI SDK for Python for your project and corresponding bucket."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -964,55 +1109,53 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"bq_client = bigquery.Client(project=PROJECT_ID, location=LOCATION)\n",
|
||||
"vertex_ai.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_URI)"
|
||||
"bq_client = bigquery.Client(project=PROJECT_ID, location=LOCATION)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "zmMWIpCwsET9"
|
||||
"id": "WnUQO2IHC9pZ"
|
||||
},
|
||||
"source": [
|
||||
"## Identify users and build your features\n",
|
||||
"\n",
|
||||
"This section we will static features we want to fetch from Vertex AI Feature Store. In particular, we will cover the following steps:\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"This section we will have static features we want to fetch from Vertex AI Feature Store. In particular, we will cover the following steps:\n",
|
||||
" \n",
|
||||
"1. Identify users, process demographic features and process behavioral features within the last 24 hours using **BigQuery**\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"2. Set up the feature store\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"3. Register features using **Vertex AI Feature Store** and the SDK.\n",
|
||||
"\n",
|
||||
"Below you have a picture that shows the process. \n",
|
||||
"\n",
|
||||
" \n",
|
||||
"Below you have a picture that shows the process.\n",
|
||||
" \n",
|
||||
"<img src=\"./assets/feature_store_ingestion_2.png\">\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"The original dataset contains raw event data we cannot ingest in the feature store as they are. We need to pre-process the raw data in order to get user features. \n",
|
||||
"\n",
|
||||
"**Notice we simulate those transformations in different point of time (today and tomorrow).**\n"
|
||||
" \n",
|
||||
" \n",
|
||||
"The original dataset contains raw event data we cannot ingest in the feature store as they are. We need to pre-process the raw data in order to get user features.\n",
|
||||
" \n",
|
||||
"**Notice we simulate those transformations in different points of time (today and tomorrow).**\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "8avYy5QOv02s"
|
||||
"id": "e9zIrwhpDF2q"
|
||||
},
|
||||
"source": [
|
||||
"### Label, Demographic and Behavioral Transformations\n",
|
||||
"\n",
|
||||
"This section is based on the [Churn prediction for game developers using Google Analytics 4 (GA4) and BigQuery ML](https://cloud.google.com/blog/topics/developers-practitioners/churn-prediction-game-developers-using-google-analytics-4-ga4-and-bigquery-ml?utm_source=linkedin&utm_medium=unpaidsoc&utm_campaign=FY21-Q2-Google-Cloud-Tech-Blog&utm_content=google-analytics-4&utm_term=-) blog article by Minhaz Kazi and Polong Lin. \n",
|
||||
"\n",
|
||||
"You will adapt it in order to turn a batch churn prediction (using features within the first 24h user of first engagment) in a real-time churn prediction (using features within the first 24h user of last engagment)."
|
||||
" \n",
|
||||
"This section is based on the [Churn prediction for game developers using Google Analytics 4 (GA4) and BigQuery ML](https://cloud.google.com/blog/topics/developers-practitioners/churn-prediction-game-developers-using-google-analytics-4-ga4-and-bigquery-ml?utm_source=linkedin&utm_medium=unpaidsoc&utm_campaign=FY21-Q2-Google-Cloud-Tech-Blog&utm_content=google-analytics-4&utm_term=-) blog article by Minhaz Kazi and Polong Lin.\n",
|
||||
" \n",
|
||||
"You will adapt it to turn a batch churn prediction (using features within the first 24h user of first engagement) into a real-time churn prediction (using features within the first 6h user of last engagement).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "YO28RAITh6L-"
|
||||
"id": "RQX5m8UiC_px"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1039,27 +1182,27 @@
|
||||
" SELECT\n",
|
||||
" event_timestamp,\n",
|
||||
" user_pseudo_id,\n",
|
||||
" SUM(IF(event_name = 'user_engagement', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'user_engagement', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_user_engagement,\n",
|
||||
" SUM(IF(event_name = 'level_start_quickplay', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'level_start_quickplay', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_level_start_quickplay,\n",
|
||||
" SUM(IF(event_name = 'level_end_quickplay', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'level_end_quickplay', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_level_end_quickplay,\n",
|
||||
" SUM(IF(event_name = 'level_complete_quickplay', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'level_complete_quickplay', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_level_complete_quickplay,\n",
|
||||
" SUM(IF(event_name = 'level_reset_quickplay', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'level_reset_quickplay', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_level_reset_quickplay,\n",
|
||||
" SUM(IF(event_name = 'post_score', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'post_score', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_post_score,\n",
|
||||
" SUM(IF(event_name = 'spend_virtual_currency', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'spend_virtual_currency', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_spend_virtual_currency,\n",
|
||||
" SUM(IF(event_name = 'ad_reward', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'ad_reward', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_ad_reward,\n",
|
||||
" SUM(IF(event_name = 'challenge_a_friend', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'challenge_a_friend', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_challenge_a_friend,\n",
|
||||
" SUM(IF(event_name = 'completed_5_levels', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'completed_5_levels', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_completed_5_levels,\n",
|
||||
" SUM(IF(event_name = 'use_extra_steps', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 86400000000 PRECEDING\n",
|
||||
" SUM(IF(event_name = 'use_extra_steps', 1, 0)) OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp ASC RANGE BETWEEN 21600000000 PRECEDING\n",
|
||||
" AND CURRENT ROW ) AS cnt_use_extra_steps,\n",
|
||||
" FROM (\n",
|
||||
" SELECT\n",
|
||||
@@ -1071,7 +1214,7 @@
|
||||
"\n",
|
||||
"SELECT\n",
|
||||
" -- PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', CONCAT('{TODAY}', ' ', STRING(TIME_TRUNC(CURRENT_TIME(), SECOND))), 'UTC') as timestamp,\n",
|
||||
" PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_MICROS(beh.event_timestamp))) AS timestamp,\n",
|
||||
" TIMESTAMP_ADD(PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_MICROS(beh.event_timestamp))), INTERVAL 1351 DAY) AS timestamp,\n",
|
||||
" dem.*,\n",
|
||||
" CAST(IFNULL(beh.cnt_user_engagement, 0) AS FLOAT64) AS cnt_user_engagement,\n",
|
||||
" CAST(IFNULL(beh.cnt_level_start_quickplay, 0) AS FLOAT64) AS cnt_level_start_quickplay,\n",
|
||||
@@ -1097,7 +1240,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "Z6CjIOmDsET-"
|
||||
"id": "oGYxLCSnD068"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1107,31 +1250,31 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "Lx__2-assET-"
|
||||
"id": "xQLIlsTCD_nk"
|
||||
},
|
||||
"source": [
|
||||
"## Create a Vertex AI Feature store and ingest your features\n",
|
||||
"\n",
|
||||
"Now you have the wide table of features. It is time to ingest them into the feature store. \n",
|
||||
"\n",
|
||||
" \n",
|
||||
"Now you have a wide table of features. It is time to ingest them into the feature store.\n",
|
||||
" \n",
|
||||
"Before to moving on, you may have a question: **Why do I need a feature store**\n",
|
||||
"in this scenario at that point?\n",
|
||||
"\n",
|
||||
"One of the reason would be to make those features accessable across team by calculating once and reuse them many times. And in order to make it possible you need also be able to monitor those features over time to guarantee freshness and in case have a new feature engineerign run to refresh them. \n",
|
||||
"\n",
|
||||
"If it is not your case, I will give even more reasons about why you should consider feature store in the following sections. Just keep following me for now.\n",
|
||||
"\n",
|
||||
"One of the most important thing is related to its data model. As you can see in the picture below, Vertex AI Feature Store organizes resources hierarchically in the following order: `Featurestore -> EntityType -> Feature`. You must create these resources before you can ingest data into Vertex AI Feature Store.\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"One of the reasons would be to make those features accessible across teams by calculating once and reuse them many times. And in order to make it possible you need also be able to monitor those features over time to guarantee freshness and in case have a new feature engineering run to refresh them.\n",
|
||||
" \n",
|
||||
"If it is not your case, I will give even more reasons about why you should consider a feature store in the following sections. Just keep following me for now.\n",
|
||||
" \n",
|
||||
"One of the most important things is related to its data model. As you can see in the picture below, Vertex AI Feature Store organizes resources hierarchically in the following order: `Featurestore -> EntityType -> Feature`. You must create these resources before you can ingest data into Vertex AI Feature Store.\n",
|
||||
" \n",
|
||||
"<img src=\"./assets/feature_store_data_model_3.png\">\n",
|
||||
"\n",
|
||||
"In our case we are going to create **mobile_gaming** featurestore resource containing **user** entity type and all its associated **features** such as country or the number of times a user challenged a friend (cnt_challenge_a_friend)."
|
||||
" \n",
|
||||
"In our case we are going to create **mobile_gaming** featurestore resource containing **user** entity type and all its associated **features** such as country or the number of times a user challenged a friend (cnt_challenge_a_friend).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "8dNlxda2sET_"
|
||||
"id": "VR7BJEozED_Q"
|
||||
},
|
||||
"source": [
|
||||
"### Create featurestore, ```mobile_gaming```\n",
|
||||
@@ -1143,7 +1286,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "t2en8I7TSe4b"
|
||||
"id": "vUFqtYU-EDTR"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1164,7 +1307,7 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "rN-vlvPUsET_"
|
||||
"id": "mUlCwfdpEHJG"
|
||||
},
|
||||
"source": [
|
||||
"### Create the ```User``` entity type and its features\n",
|
||||
@@ -1176,7 +1319,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "CbZ2RQ5XbuRq"
|
||||
"id": "PnCU1wBND3W7"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1194,7 +1337,7 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "B2PIAprPmnhB"
|
||||
"id": "bT9LXzu1EOvW"
|
||||
},
|
||||
"source": [
|
||||
"### Set Feature Monitoring\n",
|
||||
@@ -1208,7 +1351,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "N6im2c3ymiwC"
|
||||
"id": "8WBlYUkOERaI"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1231,7 +1374,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "gp9xaLQXn0CS"
|
||||
"id": "92X4-7PFETj5"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1254,18 +1397,18 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ustwKOMle8Qp"
|
||||
"id": "hxAuZjt3EWFo"
|
||||
},
|
||||
"source": [
|
||||
"### Create features\n",
|
||||
"\n",
|
||||
"In order to ingest features, you need to provide feature configuration and create them as featurestore resources.\n"
|
||||
"In order to ingest features, you need to provide feature configuration and create them as featurestore resources."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ijeZCTKIfCRL"
|
||||
"id": "hRXO2I5VEYwt"
|
||||
},
|
||||
"source": [
|
||||
"#### Create Feature configuration\n",
|
||||
@@ -1278,7 +1421,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "vX_uYmjUgd9x"
|
||||
"id": "K26NEYZIEbvE"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1359,7 +1502,7 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ErkruXPJkPuy"
|
||||
"id": "FjzMd1XbEfdo"
|
||||
},
|
||||
"source": [
|
||||
"#### Create features using `batch_create_features` method\n",
|
||||
@@ -1371,7 +1514,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "ZsCAO_IfsEUC"
|
||||
"id": "nqlgCDI9pbCD"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1388,19 +1531,19 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "9WisJk18qqgs"
|
||||
"id": "7zpFV7wAppkC"
|
||||
},
|
||||
"source": [
|
||||
"### Search features\n",
|
||||
"\n",
|
||||
"Vertex AI Feature store supports serching capabilities. Below you have a simple example that show how to filter a feature based on its name. "
|
||||
"Vertex AI Feature store supports searching capabilities. Below you have a simple example that shows how to filter a feature based on its name. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "JzqyarMZqvZS"
|
||||
"id": "BJXYLLOfppCL"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1412,7 +1555,7 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ugtBfW5gsEUD"
|
||||
"id": "is9C_6-QpxG3"
|
||||
},
|
||||
"source": [
|
||||
"## Ingest features \n",
|
||||
@@ -1447,7 +1590,7 @@
|
||||
" entity_id_field=ENTITY_ID_FIELD,\n",
|
||||
" disable_online_serving=False,\n",
|
||||
" worker_count=10,\n",
|
||||
" sync=True,\n",
|
||||
" sync=False,\n",
|
||||
" )\n",
|
||||
"except RuntimeError as error:\n",
|
||||
" print(error)"
|
||||
@@ -1456,7 +1599,7 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "3Yv8MenWXrRX"
|
||||
"id": "8lCMpDPGp-oQ"
|
||||
},
|
||||
"source": [
|
||||
"# Train and deploy a real-time churn ML model using Vertex AI Training and Endpoints\n",
|
||||
@@ -1467,34 +1610,34 @@
|
||||
"\n",
|
||||
"<img src=\"./assets/train_model_4.png\">\n",
|
||||
"\n",
|
||||
"Let's dive into each step of this process.\n"
|
||||
"Let's dive into each step of this process."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "saZZ3zWKX1YK"
|
||||
"id": "VMrvnuyjqGfY"
|
||||
},
|
||||
"source": [
|
||||
"## Fetch training data with point-in-time query using BigQuery and Vertex AI Feature store \n",
|
||||
"\n",
|
||||
"As we mentioned above, in real time churn prediction, it is so important defining the label you want to predict with your model. \n",
|
||||
"\n",
|
||||
"Let's assume that you decide to predict the churn probability over the last 24 hr. So now you have your label. Next step is to define your training sample. But let's think about that for a second. \n",
|
||||
"\n",
|
||||
"In that churn real time system, you have a high volume of transactions you could use to calculate those features which keep floating and are collected constantly over time. It implies that you always get fresh data to reconstruct features. And depending on when you decide to calculate one feature or another you can end up with a set of features that are not aligned in time. \n",
|
||||
"\n",
|
||||
"## Fetch training data with point-in-time query using BigQuery and Vertex AI Feature store \n",
|
||||
" \n",
|
||||
"As we mentioned above, in real time churn prediction, it is so important defining the label you want to predict with your model.\n",
|
||||
" \n",
|
||||
"Let's assume that you decide to predict the churn probability over the next hour. So now you have your label. Next step is to define your training sample. But let's think about that for a second.\n",
|
||||
" \n",
|
||||
"In that churn real time system, you have a high volume of transactions you could use to calculate those features which keep floating and are collected constantly over time. It implies that you always get fresh data to reconstruct features. And depending on when you decide to calculate one feature or another you can end up with a set of features that are not aligned in time.\n",
|
||||
" \n",
|
||||
"When you have labels available, it would be incredibly difficult to say which set of features contains the most up to date historical information associated with the label you want to predict. And, when you are not able to guarantee that, the performance of your model would be badly affected because you serve no representative features of the data and the label from the field when it goes live. So you need a way to get the most updated features you calculated over time before the label becomes available in order to avoid this informational skew.\n",
|
||||
"\n",
|
||||
"**With the Vertex AI Feature store, you can fetch feature values corresponding to a particular timestamp thanks to point-in-time lookup capability.** In our case, it would be the timestamp associated to the label you want to predict with your model. In this way, you will avoid data leakage and you will get the most updated features to train your model. \n",
|
||||
"\n",
|
||||
"Let's see how to do that. \n"
|
||||
" \n",
|
||||
"**With the Vertex AI Feature store, you can fetch feature values corresponding to a particular timestamp thanks to point-in-time lookup capability.** In our case, it would be the timestamp associated with the label you want to predict with your model. In this way, you will avoid data leakage and you will get the most updated features to train your model.\n",
|
||||
" \n",
|
||||
"Let's see how to do that.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "YHNbIHqFcQiM"
|
||||
"id": "RE_Pvmu-qdDt"
|
||||
},
|
||||
"source": [
|
||||
"### Define query for reading instances at a specific point in time\n",
|
||||
@@ -1506,7 +1649,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "DGUm0bYqhVV4"
|
||||
"id": "bUDVw7l-qF2x"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1518,13 +1661,13 @@
|
||||
" # get training threshold ----------------------------------------------------------------------------------\n",
|
||||
" get_training_threshold AS (\n",
|
||||
" SELECT\n",
|
||||
" (MAX(event_timestamp) - 86400000000) AS training_thrs\n",
|
||||
" (MAX(event_timestamp) - 10800000000) AS training_thrs\n",
|
||||
" FROM\n",
|
||||
" `firebase-public-project.analytics_153293282.events_*`\n",
|
||||
" WHERE\n",
|
||||
" event_name=\"user_engagement\"\n",
|
||||
" AND\n",
|
||||
" PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_MICROS(event_timestamp))) < '{TODAY}'),\n",
|
||||
" TIMESTAMP_ADD(PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_MICROS(event_timestamp))), INTERVAL 1351 DAY) < '{TODAY}'),\n",
|
||||
"\n",
|
||||
" # query to create label -----------------------------------------------------------------------------------\n",
|
||||
" get_label AS (\n",
|
||||
@@ -1549,7 +1692,7 @@
|
||||
" WHERE\n",
|
||||
" event_name=\"user_engagement\"\n",
|
||||
" AND\n",
|
||||
" PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_MICROS(event_timestamp))) < '{TODAY}'\n",
|
||||
" TIMESTAMP_ADD(PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_MICROS(event_timestamp))), INTERVAL 1351 DAY) < '{TODAY}'\n",
|
||||
" GROUP BY\n",
|
||||
" user_pseudo_id )\n",
|
||||
" GROUP BY\n",
|
||||
@@ -1669,7 +1812,7 @@
|
||||
"source": [
|
||||
"!mkdir -m 777 -p trainer data/ingest data/raw model config\n",
|
||||
"!gsutil -m cp -r $GCS_DESTINATION_OUTPUT_URI/*.csv data/ingest\n",
|
||||
"!head -n 1000 data/ingest/*.csv > data/raw/sample.csv"
|
||||
"!head -n 2000 data/ingest/*.csv > data/raw/sample.csv"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -2071,7 +2214,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"TRAIN_JOB_RESOURCE_NAME = \"\" # @param {type:\"string\"}"
|
||||
"TRAIN_JOB_RESOURCE_NAME = \"[your-train-job-resource-name]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -2166,32 +2309,32 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "7c9330928aa1"
|
||||
"id": "1TNzL_EGrVUm"
|
||||
},
|
||||
"source": [
|
||||
"# Serve ML features at scale with low latency\n",
|
||||
"\n",
|
||||
"At that time, you are ready **to deploy our simple model which would requires fetching preprocessed attributes as input features in real time**. \n",
|
||||
"\n",
|
||||
" \n",
|
||||
"At that time, you are ready **to deploy our simple model which would requires fetching preprocessed attributes as input features in real time**.\n",
|
||||
" \n",
|
||||
"Below you can see how it works\n",
|
||||
"\n",
|
||||
"<img src=\"./assets/online_serving_5.png\" width=\"600\">\n",
|
||||
"\n",
|
||||
"But think about those features for a second. \n",
|
||||
"\n",
|
||||
"Your behavioral features used to trained your model, they cannot be computed when you are going to serve the model online. \n",
|
||||
"\n",
|
||||
"How could you compute the number of time a user challenged a friend withing the last 24 hours on the fly?\n",
|
||||
"\n",
|
||||
"You simply can't do that. You need to be computed this feature on the server side and serve it with low latency. And becuase Bigquery is not optimized for those read operations, we need a different service that allows singleton lookup where the result is a single row with many columns.\n",
|
||||
"\n",
|
||||
"Also, even if it was not the case, when you deploy a model that requires preprocessing your data, you need to be sure to reproduce the same preprocessing steps you had when you trained it. If you are not able to do that a skew between training and serving data would happen and it will affect badly your model performance (and in the worst scenario break your serving system). \n",
|
||||
"\n",
|
||||
"You need a way to mitigate that in a way you don't need to implement those preprocessing steps online but just serve the same aggregated features you already have for training to generate online prediction. \n",
|
||||
"\n",
|
||||
"These are other valuable reasons to introduce Vertex AI Feature Store. With it, you have a service which helps you to serve feature at scale with low latency as they were available at training time mitigating in that way possible training-serving skew.\n",
|
||||
"\n",
|
||||
"Now that you know **why you need a feature store**, let's closing this journey by deploying your model and use feature store to retrieve features online, pass them to endpoint and generate predictions.\n"
|
||||
" \n",
|
||||
"<center><img src=\"./assets/online_serving_5.png\" width=\"800\"/></center>\n",
|
||||
" \n",
|
||||
"But think about those features for a second.\n",
|
||||
" \n",
|
||||
"Your behavioral features used to train your model, they cannot be computed when you are going to serve the model online.\n",
|
||||
" \n",
|
||||
"How could you compute the number of times a user challenged a friend within the last 24 hours on the fly?\n",
|
||||
" \n",
|
||||
"You need to be computed this feature on the server side and serve it with low latency. And because Bigquery is not optimized for those read operations, we need a different service that allows singleton lookup where the result is a single row with many columns.\n",
|
||||
" \n",
|
||||
"Also, even if it was not the case, when you deploy a model that requires preprocessing your data, you need to be sure to reproduce the same preprocessing steps you had when you trained it. If you are not able to do that a skew between training and serving data would happen and it will badly affect your model performance (and in the worst scenario break your serving system).\n",
|
||||
" \n",
|
||||
"You need a way to mitigate that in a way you don't need to implement those preprocessing steps online but just serve the same aggregated features you already have for training to generate online prediction.\n",
|
||||
" \n",
|
||||
"These are other valuable reasons to introduce Vertex AI Feature Store. With it, you have a service which helps you to serve features at scale with low latency as they were available at training time mitigating in that way possible training-serving skew.\n",
|
||||
" \n",
|
||||
"Now that you know **why you need a feature store**, let's conclude this journey by deploying your model using a feature store to retrieve features online, pass them to the endpoint and generate predictions.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -2221,13 +2364,13 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"simulate_prediction(endpoint=endpoint, n_requests=1000, latency=1)"
|
||||
"simulate_prediction(endpoint=endpoint, n_requests=10, latency=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "TpV-iwP9qw9c"
|
||||
"id": "8d3S1d1urZOy"
|
||||
},
|
||||
"source": [
|
||||
"## Cleaning up\n",
|
||||
@@ -2267,11 +2410,12 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "sx_vKniMq9ZX"
|
||||
"id": "FMXT2akXrZOy"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Delete bucket\n",
|
||||
"delete_bucket = False\n",
|
||||
"if (delete_bucket or os.getenv(\"IS_TESTING\")) and \"BUCKET_URI\" in globals():\n",
|
||||
" ! gsutil -m rm -r $BUCKET_URI"
|
||||
]
|
||||
|
||||
+3294
File diff suppressed because it is too large
Load Diff
-823
@@ -1,823 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "d1cc1c1fa076"
|
||||
},
|
||||
"source": [
|
||||
"# Pricing Optimization \n",
|
||||
"## Table of contents\n",
|
||||
"* [Overview](#section-1)\n",
|
||||
"* [Dataset](#section-2)\n",
|
||||
"* [Objective](#section-3)\n",
|
||||
"* [Costs](#section-4)\n",
|
||||
"* [Create a BigQuery dataset](#section-5)\n",
|
||||
"* [Load the dataset from Cloud Storage](#section-6)\n",
|
||||
"* [Data analysis](#section-7)\n",
|
||||
"* [Preprocess the data for training](#section-8)\n",
|
||||
"* [Train the model using BigQuery ML](#section-9)\n",
|
||||
"* [Generate forecasts from the model](#section-10)\n",
|
||||
"* [Interpret the results to choose the best price](#section-11)\n",
|
||||
"* [Clean up](#section-12)\n",
|
||||
"\n",
|
||||
"## Overview\n",
|
||||
"<a name=\"section-1\"></a>\n",
|
||||
"\n",
|
||||
"This notebook demonstrates analysis of pricing optimization on [CDM Pricing Data](https://github.com/trifacta/trifacta-google-cloud/tree/main/design-pattern-pricing-optimization) and automating the workflow using Vertex AI Workbench managed notebooks.\n",
|
||||
"\n",
|
||||
"*Note: This notebook file was developed to run in a [Vertex AI Workbench managed notebooks](https://console.cloud.google.com/vertex-ai/workbench/list/managed) instance using the Python (Local) kernel. Some components of this notebook may not work in other notebook environments.*\n",
|
||||
"\n",
|
||||
"## Dataset\n",
|
||||
"<a name=\"section-2\"></a>\n",
|
||||
"\n",
|
||||
"The dataset used in this notebook is a part of the [CDM Pricing dataset](https://github.com/trifacta/trifacta-google-cloud/blob/main/design-pattern-pricing-optimization/CDM_Pricing_large_table.csv), which consists of product sales information on specified dates.\n",
|
||||
"\n",
|
||||
"## Objective\n",
|
||||
"<a name=\"section-3\"></a>\n",
|
||||
"\n",
|
||||
"The objective of this notebook is to build a pricing optimization model using Vertex AI. The following steps have been followed: \n",
|
||||
"\n",
|
||||
"- Load the required dataset from a Cloud Storage bucket.\n",
|
||||
"- Analyze the fields present in the dataset.\n",
|
||||
"- Process the data to build a model.\n",
|
||||
"- Build a BigQuery ML forecast model on the processed data.\n",
|
||||
"- Get forecasted values from the BigQuery ML model.\n",
|
||||
"- Interpret the forecasts to identify the best prices.\n",
|
||||
"- Clean up.\n",
|
||||
"\n",
|
||||
"## Costs\n",
|
||||
"<a name=\"section-4\"></a>\n",
|
||||
"\n",
|
||||
"This tutorial uses the following billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"- Vertex AI\n",
|
||||
"- BigQuery\n",
|
||||
"- Cloud Storage\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI\n",
|
||||
"pricing](https://cloud.google.com/vertex-ai/pricing), [BigQuery pricing](https://cloud.google.com/bigquery/pricing) and [Cloud Storage\n",
|
||||
"pricing](https://cloud.google.com/storage/pricing), and use the [Pricing\n",
|
||||
"Calculator](https://cloud.google.com/products/calculator/)\n",
|
||||
"to generate a cost estimate based on your projected usage.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "5ed1f5e85640"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set your project ID\n",
|
||||
"\n",
|
||||
"**If you don't know your project ID**, you may be able to get your project ID using `gcloud`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "c3f30148b66d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"PROJECT_ID = \"\"\n",
|
||||
"\n",
|
||||
"# Get your Google Cloud project ID from gcloud\n",
|
||||
"if not os.getenv(\"IS_TESTING\"):\n",
|
||||
" shell_output = !gcloud config list --format 'value(core.project)' 2>/dev/null\n",
|
||||
" PROJECT_ID = shell_output[0]\n",
|
||||
" print(\"Project ID: \", PROJECT_ID)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "750bf2883c2d"
|
||||
},
|
||||
"source": [
|
||||
"Otherwise, set your project ID here."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "3c6db1ca88b9"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if PROJECT_ID == \"\" or PROJECT_ID is None:\n",
|
||||
" PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2a1c270c7d34"
|
||||
},
|
||||
"source": [
|
||||
"### Import the required libraries and define constants\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "acc6fac1fa55"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import pandas as pd\n",
|
||||
"import seaborn as sns\n",
|
||||
"from google.cloud import bigquery\n",
|
||||
"from google.cloud.bigquery import Client"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "a06006dff8f9"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"DATASET = \"[your-bigquery-dataset-id]\" # set the BigQuery dataset-id\n",
|
||||
"TRAINING_DATA_TABLE = \"[your-bigquery-table-id-to-store-the-training-data]\" # set the BigQuery table-id to store the training data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "016c3d47cc69"
|
||||
},
|
||||
"source": [
|
||||
"## Create a BigQuery dataset\n",
|
||||
"<a name=\"section-5\"></a>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "12ccd8d7956e"
|
||||
},
|
||||
"source": [
|
||||
"#@bigquery\n",
|
||||
"-- create a dataset in BigQuery\n",
|
||||
"\n",
|
||||
"CREATE SCHEMA pricing_optimization\n",
|
||||
"OPTIONS(\n",
|
||||
" location=\"us\"\n",
|
||||
" )"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "c106b978a79b"
|
||||
},
|
||||
"source": [
|
||||
"## Load the dataset from Cloud Storage\n",
|
||||
"<a name=\"section-6\"></a>\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "8aeae9da9796"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"DATA_LOCATION = \"gs://cloud-samples-data/ai-platform-unified/datasets/tabular/cdm_pricing_large_table.csv\"\n",
|
||||
"df = pd.read_csv(DATA_LOCATION)\n",
|
||||
"print(df.shape)\n",
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "7b98d5f09842"
|
||||
},
|
||||
"source": [
|
||||
"You will build a forecast model on this data and thus determine the best price for a product. For this type of model, you will not be using many fields: only the sales and price related ones. For the current execrcise, focus on the following fields:\n",
|
||||
"\n",
|
||||
"- `Product_ID`\n",
|
||||
"- `Customer_Hierarchy`\n",
|
||||
"- `Fiscal_Date`\n",
|
||||
"- `List_Price_Converged`\n",
|
||||
"- `Invoiced_quantity_in_Pieces`\n",
|
||||
"- `Net_Sales`\n",
|
||||
"\n",
|
||||
"## Data Analysis\n",
|
||||
"<a name=\"section-7\"></a>\n",
|
||||
"\n",
|
||||
"First, explore the data and distributions.\n",
|
||||
"\n",
|
||||
"Select the required columns from the dataframe."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "af4b41c5eb1f"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"id_col = \"Product_ID\"\n",
|
||||
"date_col = \"Fiscal_Date\"\n",
|
||||
"categ_cols = [\"Customer_Hierarchy\"]\n",
|
||||
"num_cols = [\"List_Price_Converged\", \"Invoiced_quantity_in_Pieces\", \"Net_Sales\"]\n",
|
||||
"\n",
|
||||
"df = df[[id_col, date_col] + categ_cols + num_cols].copy()\n",
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "3d780043ee5b"
|
||||
},
|
||||
"source": [
|
||||
"Check the column types and null values in the dataframe."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "f54c445a1288"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df.info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "cd817b414c4d"
|
||||
},
|
||||
"source": [
|
||||
"This data description reveals that there are no null values in the data. Also, the field `Fiscal_Date` which is a date field is loaded as an object type. \n",
|
||||
"\n",
|
||||
"Change the type of the date field to datetime."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "b160fac085c8"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df[\"Fiscal_Date\"] = pd.to_datetime(df[\"Fiscal_Date\"], infer_datetime_format=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "fb4778578064"
|
||||
},
|
||||
"source": [
|
||||
"Plot the distributions for the categorical fields."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "dd0467cd57c3"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"for i in categ_cols:\n",
|
||||
" df[i].value_counts(normalize=True).plot(kind=\"bar\")\n",
|
||||
" plt.title(i)\n",
|
||||
" plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "145deed255e0"
|
||||
},
|
||||
"source": [
|
||||
"Plot the distributions for the numerical fields."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "f934137c6d82"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"for i in num_cols:\n",
|
||||
" _, ax = plt.subplots(1, 2, figsize=(10, 4))\n",
|
||||
" df[i].plot(kind=\"box\", ax=ax[0])\n",
|
||||
" df[i].plot(kind=\"hist\", ax=ax[1])\n",
|
||||
" ax[0].set_title(i + \"-Boxplot\")\n",
|
||||
" ax[1].set_title(i + \"-Histogram\")\n",
|
||||
" plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "f9b9c2e58380"
|
||||
},
|
||||
"source": [
|
||||
"Check the maximum date and minimum date in Fiscal_Date column."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "2a10aa689f9d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(df[\"Fiscal_Date\"].max())\n",
|
||||
"print(df[\"Fiscal_Date\"].min())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "4834f63e2e59"
|
||||
},
|
||||
"source": [
|
||||
"Check the product distribution across each category."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "4664877f5304"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"grp_cols = [\"Customer_Hierarchy\", \"Product_ID\"]\n",
|
||||
"grp_df = df[grp_cols].groupby(by=grp_cols).count().reset_index()\n",
|
||||
"grp_df.groupby(\"Customer_Hierarchy\").nunique()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "01ed02b9c8fd"
|
||||
},
|
||||
"source": [
|
||||
"Check the percentage changes in the orders based on the percentage changes in the price."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "0b2c428cb135"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# aggregate the data\n",
|
||||
"df_aggr = (\n",
|
||||
" df.groupby([\"Product_ID\", \"List_Price_Converged\"])\n",
|
||||
" .agg({\"Fiscal_Date\": min, \"Invoiced_quantity_in_Pieces\": sum, \"Net_Sales\": sum})\n",
|
||||
" .reset_index()\n",
|
||||
")\n",
|
||||
"# rename the aggregated columns\n",
|
||||
"df_aggr.rename(\n",
|
||||
" columns={\n",
|
||||
" \"Fiscal_Date\": \"First_price_date\",\n",
|
||||
" \"Invoiced_quantity_in_Pieces\": \"Total_ordered_pieces\",\n",
|
||||
" \"Net_Sales\": \"Total_net_sales\",\n",
|
||||
" },\n",
|
||||
" inplace=True,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# sort values chronologically\n",
|
||||
"df_aggr.sort_values(by=[\"Product_ID\", \"First_price_date\"], inplace=True)\n",
|
||||
"df_aggr.reset_index(drop=True, inplace=True)\n",
|
||||
"\n",
|
||||
"# add columns for previous values\n",
|
||||
"df_aggr[\"Previous_List\"] = df_aggr.groupby([\"Product_ID\"])[\n",
|
||||
" \"List_Price_Converged\"\n",
|
||||
"].shift()\n",
|
||||
"df_aggr[\"Previous_Total_ordered_pieces\"] = df_aggr.groupby([\"Product_ID\"])[\n",
|
||||
" \"Total_ordered_pieces\"\n",
|
||||
"].shift()\n",
|
||||
"\n",
|
||||
"# average price change across sku's\n",
|
||||
"df_aggr[\"price_change_perc\"] = (\n",
|
||||
" (df_aggr[\"List_Price_Converged\"] - df_aggr[\"Previous_List\"])\n",
|
||||
" / df_aggr[\"Previous_List\"].fillna(0)\n",
|
||||
" * 100\n",
|
||||
")\n",
|
||||
"df_aggr[\"order_change_perc\"] = (\n",
|
||||
" (df_aggr[\"Total_ordered_pieces\"] - df_aggr[\"Previous_Total_ordered_pieces\"])\n",
|
||||
" / df_aggr[\"Previous_Total_ordered_pieces\"].fillna(0)\n",
|
||||
" * 100\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# plot a scatterplot to visualize the changes\n",
|
||||
"sns.scatterplot(\n",
|
||||
" x=\"price_change_perc\",\n",
|
||||
" y=\"order_change_perc\",\n",
|
||||
" data=df_aggr,\n",
|
||||
" hue=\"Product_ID\",\n",
|
||||
" legend=False,\n",
|
||||
")\n",
|
||||
"plt.title(\"Percentage of change in price vs order\")\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "8259e916fe25"
|
||||
},
|
||||
"source": [
|
||||
"For most of the products, the percentage change in orders are high where the percentage changes in the prices are low. This suggests that too much change in the prices can affect the number of orders. \n",
|
||||
"\n",
|
||||
"**Note**: There seem to be some outliers in the data as percentage changes greater than 800 are found. In the current exercise, do not take any manual measures to deal with outliers as you will create a BigQuery ML timeseries model that already deals with outliers.\n",
|
||||
"\n",
|
||||
"## Preprocess the data for training\n",
|
||||
"<a name=\"section-8\"></a>\n",
|
||||
"\n",
|
||||
"Check which `Product_ID`'s have the maximum orders."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "f5cbc7709c6a"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_orders = df.groupby([\"Product_ID\", \"Customer_Hierarchy\"], as_index=False)[\n",
|
||||
" \"Invoiced_quantity_in_Pieces\"\n",
|
||||
"].sum()\n",
|
||||
"df_orders.loc[\n",
|
||||
" df_orders.groupby(\"Customer_Hierarchy\")[\"Invoiced_quantity_in_Pieces\"].idxmax()\n",
|
||||
"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "fd6d227e513e"
|
||||
},
|
||||
"source": [
|
||||
"From the above result, you can infer the following:\n",
|
||||
"\n",
|
||||
"- Under the **Food** category, **SKU 62** has the maximum orders.\n",
|
||||
"- Under the **Manufacturing** category, **SKU 17** has the maximum orders.\n",
|
||||
"- Under the **Paper** category, **SKU 107** has the maximum orders.\n",
|
||||
"- Under the **Publishing** category, **SKU 8** has the maximum orders.\n",
|
||||
"- Under the **Utilities** category, **SKU 140** has the maximum orders.\n",
|
||||
"\n",
|
||||
"Given that there are too many ids and only a few records for most of them, consider only the above `Product_ID`s for which there are a maximum number of orders. \n",
|
||||
"\n",
|
||||
"**Note**: The `Invoiced_quantity_in_Pieces` field seems to be a *float* type rather than an *int* type as it should be. This could be because the data itself might be averaged in the first place."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2dbc0d64d157"
|
||||
},
|
||||
"source": [
|
||||
"Check the various prices available for these `Product_ID`s."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "acc1dbd2d838"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_type_food = df[(df[\"Product_ID\"] == \"SKU 62\") & (df[\"Customer_Hierarchy\"] == \"Food\")]\n",
|
||||
"print(\"Food :\")\n",
|
||||
"print(df_type_food[\"List_Price_Converged\"].value_counts())\n",
|
||||
"df_type_manuf = df[\n",
|
||||
" (df[\"Product_ID\"] == \"SKU 17\") & (df[\"Customer_Hierarchy\"] == \"Manufacturing\")\n",
|
||||
"]\n",
|
||||
"print(\"Manufacturing :\")\n",
|
||||
"print(df_type_manuf[\"List_Price_Converged\"].value_counts())\n",
|
||||
"df_type_paper = df[\n",
|
||||
" (df[\"Product_ID\"] == \"SKU 107\") & (df[\"Customer_Hierarchy\"] == \"Paper\")\n",
|
||||
"]\n",
|
||||
"print(\"Paper :\")\n",
|
||||
"print(df_type_paper[\"List_Price_Converged\"].value_counts())\n",
|
||||
"df_type_pub = df[\n",
|
||||
" (df[\"Product_ID\"] == \"SKU 8\") & (df[\"Customer_Hierarchy\"] == \"Publishing\")\n",
|
||||
"]\n",
|
||||
"print(\"Publishing :\")\n",
|
||||
"print(df_type_pub[\"List_Price_Converged\"].value_counts())\n",
|
||||
"df_type_util = df[\n",
|
||||
" (df[\"Product_ID\"] == \"SKU 140\") & (df[\"Customer_Hierarchy\"] == \"Utilities\")\n",
|
||||
"]\n",
|
||||
"print(\"Utilities :\")\n",
|
||||
"print(df_type_util[\"List_Price_Converged\"].value_counts())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "f023af578c0f"
|
||||
},
|
||||
"source": [
|
||||
"In the publishing category, `Product_ID` `SKU 8` and `SKU 17` are less than or equal to two different prices in the entire data and so you will exclude them and consider the rest for building the forecast model. The idea here is to train a forecast model on the timeseries data for products with different prices.\n",
|
||||
"\n",
|
||||
"Join the data for all the `Product_ID`s into one dataframe and remove duplicate records."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "a44771cc4c20"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_final = pd.concat([df_type_food, df_type_paper, df_type_util])\n",
|
||||
"df_final = (\n",
|
||||
" df_final[\n",
|
||||
" [\n",
|
||||
" \"Product_ID\",\n",
|
||||
" \"Fiscal_Date\",\n",
|
||||
" \"Customer_Hierarchy\",\n",
|
||||
" \"List_Price_Converged\",\n",
|
||||
" \"Invoiced_quantity_in_Pieces\",\n",
|
||||
" ]\n",
|
||||
" ]\n",
|
||||
" .drop_duplicates()\n",
|
||||
" .reset_index(drop=True)\n",
|
||||
")\n",
|
||||
"df_final.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "add5063df368"
|
||||
},
|
||||
"source": [
|
||||
"Save the data to a BigQuery table."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "fd82ba56571f"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"bq_client = bigquery.Client(project=PROJECT_ID)\n",
|
||||
"\n",
|
||||
"job_config = bigquery.LoadJobConfig(\n",
|
||||
" # Specify a (partial) schema. All columns are always written to the\n",
|
||||
" # table. The schema is used to assist in data type definitions.\n",
|
||||
" schema=[\n",
|
||||
" bigquery.SchemaField(\"Product_ID\", bigquery.enums.SqlTypeNames.STRING),\n",
|
||||
" bigquery.SchemaField(\"Fiscal_Date\", bigquery.enums.SqlTypeNames.DATE),\n",
|
||||
" bigquery.SchemaField(\"List_Price_Converged\", bigquery.enums.SqlTypeNames.FLOAT),\n",
|
||||
" bigquery.SchemaField(\n",
|
||||
" \"Invoiced_quantity_in_Pieces\", bigquery.enums.SqlTypeNames.FLOAT\n",
|
||||
" ),\n",
|
||||
" ],\n",
|
||||
" # Optionally, set the write disposition. BigQuery appends loaded rows\n",
|
||||
" # to an existing table by default, but with WRITE_TRUNCATE write\n",
|
||||
" # disposition it replaces the table with the loaded data.\n",
|
||||
" write_disposition=\"WRITE_TRUNCATE\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# save the dataframe to a table in the created dataset\n",
|
||||
"job = bq_client.load_table_from_dataframe(\n",
|
||||
" df_final,\n",
|
||||
" \"{}.{}.{}\".format(PROJECT_ID, DATASET, TRAINING_DATA_TABLE),\n",
|
||||
" job_config=job_config,\n",
|
||||
") # Make an API request.\n",
|
||||
"job.result() # Wait for the job to complete."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "fca77641b03b"
|
||||
},
|
||||
"source": [
|
||||
"# Train the model using BigQuery ML\n",
|
||||
"<a name=\"section-9\"></a>\n",
|
||||
"\n",
|
||||
"Train an [Arima-Plus](https://cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-create-time-series) model on the data using BigQuery ML."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "cded27507891"
|
||||
},
|
||||
"source": [
|
||||
"#@bigquery\n",
|
||||
"create or replace model pricing_optimization.bqml_arima\n",
|
||||
"options\n",
|
||||
" (model_type = 'ARIMA_PLUS',\n",
|
||||
" time_series_timestamp_col = 'Fiscal_Date',\n",
|
||||
" time_series_data_col = 'Invoiced_quantity_in_Pieces',\n",
|
||||
" time_series_id_col = 'ID'\n",
|
||||
" ) as\n",
|
||||
"select\n",
|
||||
" Fiscal_Date,\n",
|
||||
" Concat(Product_ID,\"_\" ,Cast(List_Price_Converged as string)) as ID,\n",
|
||||
" Invoiced_quantity_in_Pieces\n",
|
||||
"from\n",
|
||||
" pricing_optimization.TRAINING_DATA\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "332fd11ff32b"
|
||||
},
|
||||
"source": [
|
||||
"## Generate forecasts from the model\n",
|
||||
"<a name=\"section-10\"></a>\n",
|
||||
"\n",
|
||||
"Predict the sales for the next 30 days for each id and save to a dataframe."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "ef926cdbf28e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"client = Client()\n",
|
||||
"\n",
|
||||
"query = '''\n",
|
||||
"DECLARE HORIZON STRING DEFAULT \"30\"; #number of values to forecast\n",
|
||||
"DECLARE CONFIDENCE_LEVEL STRING DEFAULT \"0.90\"; ## required confidence level\n",
|
||||
"\n",
|
||||
"EXECUTE IMMEDIATE format(\"\"\"\n",
|
||||
" SELECT\n",
|
||||
" *\n",
|
||||
" FROM \n",
|
||||
" ML.FORECAST(MODEL pricing_optimization.bqml_arima, \n",
|
||||
" STRUCT(%s AS horizon, \n",
|
||||
" %s AS confidence_level)\n",
|
||||
" )\n",
|
||||
" \"\"\",HORIZON,CONFIDENCE_LEVEL)'''\n",
|
||||
"job = client.query(query)\n",
|
||||
"dfforecast = job.to_dataframe()\n",
|
||||
"dfforecast.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "608c7de72dae"
|
||||
},
|
||||
"source": [
|
||||
"## Interpret the results to choose the best price\n",
|
||||
"<a name=\"section-11\"></a>\n",
|
||||
"\n",
|
||||
"Calculate average forecast values for the forecast duration."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "e1e193680400"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dfforecast_avg = (\n",
|
||||
" dfforecast[[\"ID\", \"forecast_value\"]].groupby(\"ID\", as_index=False).mean()\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "5ce395d652a3"
|
||||
},
|
||||
"source": [
|
||||
"Extract the ID and Price fields from the ID field."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "452c56fa58ed"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dfforecast_avg[\"Product_ID\"] = dfforecast_avg[\"ID\"].apply(lambda x: x.split(\"_\")[0])\n",
|
||||
"dfforecast_avg[\"Price\"] = dfforecast_avg[\"ID\"].apply(lambda x: x.split(\"_\")[1])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "3cee67f4028f"
|
||||
},
|
||||
"source": [
|
||||
"Plot the average forecasted sales vs. the price of the product."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "fb351c8f383d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"for i in dfforecast_avg[\"Product_ID\"].unique():\n",
|
||||
" dfforecast_avg[dfforecast_avg[\"Product_ID\"] == i].set_index(\"Price\").sort_values(\n",
|
||||
" \"forecast_value\"\n",
|
||||
" ).plot(kind=\"bar\")\n",
|
||||
" plt.title(\"Price vs. Average Sales for \" + i)\n",
|
||||
" plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "67ff3acc74a5"
|
||||
},
|
||||
"source": [
|
||||
"Based on the plots for price vs. the average forecasted orders, it can be said that to use the maximum orders, each of the considered `Product_ID`s can follow the below prices:\n",
|
||||
"\n",
|
||||
"- SKU 107's price range can be from 4.44 - 4.73 units\n",
|
||||
"- SKU 140's price can be 1.95 units\n",
|
||||
"- SKU 62's price can be 4.23 units\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"## Clean Up\n",
|
||||
"<a name=\"section-12\"></a>\n",
|
||||
"\n",
|
||||
"To clean up all Google Cloud resources used in this project, you can [delete the Google Cloud project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects) you used for the tutorial.\n",
|
||||
"\n",
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial. The following code deletes the entire dataset."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "d78908b8134d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Construct a BigQuery client object.\n",
|
||||
"client = bigquery.Client()\n",
|
||||
"\n",
|
||||
"# TODO(developer): Set model_id to the ID of the model to fetch.\n",
|
||||
"dataset_id = \"{PROJECT}.{DATASET}\".format(PROJECT=PROJECT_ID, DATASET=DATASET)\n",
|
||||
"\n",
|
||||
"# Use the delete_contents parameter to delete a dataset and its contents.\n",
|
||||
"# Use the not_found_ok parameter to not receive an error if the dataset has already been deleted.\n",
|
||||
"client.delete_dataset(\n",
|
||||
" dataset_id, delete_contents=True, not_found_ok=True\n",
|
||||
") # Make an API request.\n",
|
||||
"\n",
|
||||
"print(\"Deleted dataset '{}'.\".format(dataset_id))"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"name": "pricing-optimization.ipynb",
|
||||
"toc_visible": true
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"name": "python3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,5 +14,5 @@ The purpose of this set of notebooks and markdown files is to demonstrate Google
|
||||
4. [Evaluation](stage4)
|
||||
5. [Deployment](stage5)
|
||||
6. [Serving](stage6)
|
||||
7. Monitoring
|
||||
7. Monitoring(stage7)
|
||||
8. Continuous Training
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
## Before you begin
|
||||
|
||||
### Set up your Google Cloud project
|
||||
|
||||
**The following steps are required, regardless of your notebook environment.**
|
||||
|
||||
1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.
|
||||
|
||||
1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).
|
||||
|
||||
1. [Enable the Vertex AI, BigQuery, Compute Engine and Cloud Storage APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,bigquery,compute_component,storage_component).
|
||||
|
||||
1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).
|
||||
|
||||
1. Enter your project ID in the cell below. Then run the cell to make sure the
|
||||
Cloud SDK uses the right project for all the commands in this notebook.
|
||||
|
||||
**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands.
|
||||
|
||||
### Set up your local development environment
|
||||
|
||||
**If you are using Colab or Vertex AI Workbench Notebooks**, your environment already meets all the requirements to run this notebook. You can skip this step.
|
||||
|
||||
**Otherwise**, make sure your environment meets this notebook's requirements. You need the following:
|
||||
|
||||
- The Cloud Storage SDK
|
||||
- Python 3
|
||||
- virtualenv
|
||||
- Jupyter notebook running in a virtual environment with Python 3
|
||||
|
||||
The Cloud Storage guide to [Setting up a Python development environment](https://cloud.google.com/python/setup) and the [Jupyter installation guide](https://jupyter.org/install) provide detailed instructions for meeting these requirements. The following steps provide a condensed set of instructions:
|
||||
|
||||
1. [Install and initialize the SDK](https://cloud.google.com/sdk/docs/).
|
||||
|
||||
2. [Install Python 3](https://cloud.google.com/python/setup#installing_python).
|
||||
|
||||
3. [Install virtualenv](https://cloud.google.com/python/setup#installing_and_using_virtualenv) and create a virtual environment that uses Python 3. Activate the virtual environment.
|
||||
|
||||
4. To install Jupyter, run `pip3 install jupyter` on the command-line in a terminal shell.
|
||||
|
||||
5. To launch Jupyter, run `jupyter notebook` on the command-line in a terminal shell.
|
||||
|
||||
6. Open this notebook in the Jupyter Notebook Dashboard.
|
||||
@@ -0,0 +1,112 @@
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import subprocess
|
||||
import random
|
||||
import string
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--bucket', dest='bucket_required', action='store_true',
|
||||
default=False, help='Bucket required')
|
||||
parser.add_argument('--email', dest='email_required', action='store_true',
|
||||
default=False, help='Email required')
|
||||
parser.add_argument('--sa', dest='sa_required', action='store_true',
|
||||
default=False, help='Service account required')
|
||||
parser.add_argument('--packages', dest='extra_packages',
|
||||
default='', type=str, help='additional required packages')
|
||||
args = parser.parse_args()
|
||||
|
||||
extra_pkgs = args.extra_packages
|
||||
|
||||
|
||||
# Installation
|
||||
|
||||
|
||||
# The Vertex AI Workbench Notebook product has specific requirements
|
||||
IS_WORKBENCH_NOTEBOOK = os.getenv("DL_ANACONDA_HOME")
|
||||
IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(
|
||||
"/opt/deeplearning/metadata/env_version"
|
||||
)
|
||||
IS_COLAB = "google.colab" in sys.modules
|
||||
|
||||
# Vertex AI Notebook requires dependencies to be installed with '--user'
|
||||
USER_FLAG = ""
|
||||
if IS_WORKBENCH_NOTEBOOK:
|
||||
USER_FLAG = "--user"
|
||||
|
||||
# not used
|
||||
'''
|
||||
print("Installing packages")
|
||||
os.system(f"pip3 install --upgrade --quiet {USER_FLAG} google-cloud-aiplatform {args.extra_packages}")
|
||||
print("Done installation")
|
||||
'''
|
||||
|
||||
# Authenticate
|
||||
if IS_COLAB:
|
||||
from google.colab import auth as google_auth
|
||||
|
||||
google_auth.authenticate_user()
|
||||
|
||||
|
||||
# project ID
|
||||
if IS_WORKBENCH_NOTEBOOK:
|
||||
shell_output = subprocess.check_output("gcloud config list --format 'value(core.project)' 2>/dev/null", shell=True)
|
||||
PROJECT_ID = shell_output[0:-1].decode('utf-8')
|
||||
print("PROJECT ID: ", PROJECT_ID)
|
||||
else:
|
||||
PROJECT_ID = input("Enter PROJECT_ID: ")
|
||||
os.system(f"gcloud config set project {PROJECT_ID}")
|
||||
|
||||
# email
|
||||
if args.email_required:
|
||||
shell_output = subprocess.check_output("gcloud config list --format 'value(core.account)' 2>/dev/null", shell=True)
|
||||
EMAIL_ADDR = shell_output[0:-1].decode('utf-8')
|
||||
if EMAIL_ADDR == '':
|
||||
EMAIL_ADDR = input("Enter Email Address: ")
|
||||
print("EMAIL_ADDR: ", EMAIL_ADDR)
|
||||
|
||||
# region
|
||||
shell_output = subprocess.check_output("gcloud config list --format 'value(ai.region)'", shell=True)
|
||||
REGION = shell_output[0:-1].decode('utf-8')
|
||||
if REGION == '':
|
||||
REGION = input("Enter REGION: ")
|
||||
print("REGION: ", REGION)
|
||||
|
||||
# multi-region
|
||||
MULTI_REGION = REGION.split('-')[0]
|
||||
|
||||
|
||||
# UUID
|
||||
# Generate a uuid of a specifed length(default=8)
|
||||
def generate_uuid(length: int = 8) -> str:
|
||||
return "".join(random.choices(string.ascii_lowercase + string.digits, k=length))
|
||||
|
||||
|
||||
UUID = generate_uuid()
|
||||
print("UUID", UUID)
|
||||
|
||||
# Bucket
|
||||
if args.bucket_required:
|
||||
BUCKET_NAME = PROJECT_ID + "aip-" + UUID
|
||||
BUCKET_URI = f"gs://{BUCKET_NAME}"
|
||||
os.system(f"gsutil mb -l {REGION} {BUCKET_URI}")
|
||||
print("BUCKET_URI", BUCKET_URI)
|
||||
|
||||
|
||||
# Project Number
|
||||
if args.sa_required:
|
||||
if IS_WORKBENCH_NOTEBOOK:
|
||||
shell_output = subprocess.check_output("gcloud auth list 2>/dev/null", shell=True)
|
||||
SERVICE_ACCOUNT = shell_output[:-1].decode('utf-8').split('\n')[2].strip()
|
||||
PROJECT_NUMBER = SERVICE_ACCOUNT.split('-')[0]
|
||||
else:
|
||||
shell_output = subprocess.check_output(f"gcloud projects describe {PROJECT_ID}", shell=True)
|
||||
try:
|
||||
PROJECT_NUMBER = shell_output[:-1].decode('utf-8').split('\n')[7].split(':')[-1].strip().replace("'", "")
|
||||
SERVICE_ACCOUNT = f"{PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
|
||||
except:
|
||||
PROJECT_NUMBER = input("Enter project number: ")
|
||||
SERVICE_ACCOUNT = f"{PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
|
||||
|
||||
print("SERVICE_ACCOUNT", SERVICE_ACCOUNT)
|
||||
print("PROJECT_NUMBER", PROJECT_NUMBER)
|
||||
@@ -22,31 +22,31 @@ The first stage in MLOps is the collection and preparation for the purpose of de
|
||||
- Data is preprocessed for training and evaluation using Dataflow.
|
||||
- Data augmentation is performed on-the-fly and is coupled with model feeding.
|
||||
|
||||
<img src='stage1.jpg'>
|
||||
<img src='stage1v2.png'>
|
||||
|
||||
## Notebooks
|
||||
|
||||
### Get Started
|
||||
|
||||
[Get Started with BQ datasets](get_started_bq_datasets.ipynb)
|
||||
[Get started with Dataflow](community/ml_ops/stage1/get_started_dataflow.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Dataflow` for training with `Vertex AI`.
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Create a Vertex AI `Dataset` resource from `BigQuery` table -- compatible for `AutoML` training.
|
||||
- Extract a copy of the dataset from `BigQuery` to a CSV file in Cloud Storage -- compatible for `AutoML` or custom training.
|
||||
- Select rows from a `BigQuery` dataset into a `pandas` dataframe -- compatible for custom training.
|
||||
- Select rows from a `BigQuery` dataset into a `tf.data.Dataset` -- compatible for custom training `TensorFlow` models.
|
||||
- Select rows from extracted CSV files into a `tf.data.Dataset` -- compatible for custom training `TensorFlow` models.
|
||||
- Create a `BigQuery` dataset from CSV files.
|
||||
- Extract data from `BigQuery` table into a `DMatrix` -- compatible for custom training `XGBoost` models.
|
||||
```
|
||||
- Offline preprocessing of data:
|
||||
- Serially - w/o dataflow
|
||||
- Parallel - with dataflow
|
||||
- Upstream preprocessing of data:
|
||||
- tabular data
|
||||
- image data
|
||||
|
||||
[Get Started with Vertex datasets](get_started_vertex_datasets.ipynb)
|
||||
[Get started with Vertex AI datasets](community/ml_ops/stage1/get_started_vertex_datasets.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Dataset` for training with `Vertex AI`.
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
|
||||
- Create a Vertex AI `Dataset` resource for:
|
||||
- image data
|
||||
- text data
|
||||
@@ -61,24 +61,25 @@ The steps performed include:
|
||||
- Detect anomalies in new data using TensorFlow Data Validation.
|
||||
- Generate a TFRecord feature specification using TensorFlow Transform from the data schema.
|
||||
- Export a dataset and convert to TFRecords.
|
||||
```
|
||||
|
||||
[Get Started with Dataflow](get_started_dataflow.ipynb)
|
||||
[Get started with BigQuery datasets](community/ml_ops/stage1/get_started_bq_datasets.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `BigQuery` as a dataset for training with `Vertex AI`.
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Offline preprocessing of data:
|
||||
- Serially - w/o dataflow
|
||||
- Parallel - with dataflow
|
||||
- Upstream preprocessing of data:
|
||||
- tabular data
|
||||
- image data
|
||||
```
|
||||
- Create a Vertex AI `Dataset` resource from `BigQuery` table -- compatible for `AutoML` training.
|
||||
- Extract a copy of the dataset from `BigQuery` to a CSV file in Cloud Storage -- compatible for `AutoML` or custom training.
|
||||
- Select rows from a `BigQuery` dataset into a `pandas` dataframe -- compatible for custom training.
|
||||
- Select rows from a `BigQuery` dataset into a `tf.data.Dataset` -- compatible for custom training `TensorFlow` models.
|
||||
- Select rows from extracted CSV files into a `tf.data.Dataset` -- compatible for custom training `TensorFlow` models.
|
||||
- Create a `BigQuery` dataset from CSV files.
|
||||
- Extract data from `BigQuery` table into a `DMatrix` -- compatible for custom training `XGBoost` models.
|
||||
|
||||
[Get Started with Data Labeling](get_started_data_labeling.ipynb)
|
||||
[Get started with Vertex AI Data Labeling](community/ml_ops/stage1/get_started_with_data_labeling.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use the `Vertex AI Data Labeling` service.
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Create a Specialist Pool for data labelers.
|
||||
@@ -86,15 +87,28 @@ The steps performed include:
|
||||
- Submit the data labeling job.
|
||||
- List data labeling jobs.
|
||||
- Cancel a data labeling job.
|
||||
```
|
||||
|
||||
|
||||
|
||||
[Create an unlabelled Vertex AI AutoML text entity extraction dataset from PDFs using Vision API](community/ml_ops/stage1/get_started_with_visionapi_and_vertex_datasets.ipynb)
|
||||
|
||||
In this tutorial, you learn to use `Vision API` to extract text from PDF files stored on a Cloud Storage bucket. You then process the results and create an unlabelled `Vertex AI Dataset`, compatible with `AutoML`, for text entity extraction.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
1. Using `Vision API` to perform Optical Character Recognition (OCR) to extract text from PDF files.
|
||||
2. Processing the results and saving them to text files.
|
||||
3. Generating a `Vertex AI Dataset` import file.
|
||||
4. Creating a new unlabelled text entity extraction `Vertex AI Dataset` resource in `Vertex AI`.
|
||||
|
||||
|
||||
### E2E Stage Example
|
||||
|
||||
[Stage 1: Data Management](mlops_data_management.ipynb)
|
||||
|
||||
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Explore and visualize the data.
|
||||
- Create a Vertex AI `Dataset` resource from `BigQuery` table -- for AutoML training.
|
||||
- Extract a copy of the dataset to a CSV file in Cloud Storage.
|
||||
@@ -104,4 +118,3 @@ The steps performed include:
|
||||
- Generate a TFRecord feature specification using TensorFlow Data Validation from the data schema.
|
||||
- Preprocess a portion of the BigQuery data using `Dataflow` -- for custom training.
|
||||
```
|
||||
|
||||
|
||||
@@ -34,17 +34,16 @@
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_bq_datasets.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_bq_datasets.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\\\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_bq_datasets.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_bq_datasets.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage1/get_started_bq_datasets.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -65,17 +64,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 1 : data management: get started with BigQuery datasets."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:gsod,lrg"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). In this version of the dataset you consider the fields year, month and day to predict the value of mean daily temperature (mean_temp)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -132,7 +120,7 @@
|
||||
" - XGBoost model training:\n",
|
||||
" - Use BigQuery ML built-in XGBoost training.\n",
|
||||
" - Alternatively, create a DMatrix generator from CSV files extracted from BigQuery table.\n",
|
||||
" - Pytorch model training:\n",
|
||||
" - PyTorch model training:\n",
|
||||
" - Extract the BigQuery to a pandas dataframe.\n",
|
||||
" - Preprocess the data in the dataframe.\n",
|
||||
" - Create a DataLoader generator from the pandas dataframe.\n",
|
||||
@@ -141,8 +129,26 @@
|
||||
"- Alternatively:\n",
|
||||
" - Extract the BigQuery table to CSV files.\n",
|
||||
" - Preprocess the CSV files.\n",
|
||||
" - Create a tf.data.Dataset generator from the CSV files.\n",
|
||||
" \n",
|
||||
" - Create a tf.data.Dataset generator from the CSV files."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:gsod,lrg"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). In this version of the dataset you consider the fields year, month and day to predict the value of mean daily temperature (mean_temp)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "9e483012a752"
|
||||
},
|
||||
"source": [
|
||||
"### Costs\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
@@ -174,20 +180,19 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"# Install the packages\n",
|
||||
"! pip3 install --upgrade pyarrow $USER_FLAG\n",
|
||||
"! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
|
||||
"! pip3 install -U xgboost $USER_FLAG\n",
|
||||
"! pip3 install -U tensorflow-io==0.18 $USER_FLAG"
|
||||
"extra_pkgs = \"tensorflow tensorflow-io==0.18 pyarrow xgboost google-cloud-bigquery\"\n",
|
||||
"! pip3 install --upgrade --quiet {USER_FLAG} google-cloud-aiplatform $extra_pkgs"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -209,9 +214,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"if not os.getenv(\"IS_TESTING\"):\n",
|
||||
"if \"google.colab\" in sys.modules:\n",
|
||||
" # Automatically restart kernel after installs\n",
|
||||
" import IPython\n",
|
||||
"\n",
|
||||
@@ -222,278 +227,42 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "a47846030fef"
|
||||
"id": "fc8fb52b5cca"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "84cd83853240"
|
||||
},
|
||||
"source": [
|
||||
"### Set up your Google Cloud project\n",
|
||||
"### Common setup\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI, BigQuery, Compute Engine and Cloud Storage APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,bigquery,compute_component,storage_component).\n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "project_id"
|
||||
},
|
||||
"source": [
|
||||
"#### Set your project ID\n",
|
||||
"\n",
|
||||
"**If you don't know your project ID**, you may be able to get your project ID using `gcloud`."
|
||||
"Now, execute the common setup for the notebook tutorials."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "set_project_id"
|
||||
"id": "001a0fcd5d78"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
|
||||
"# Common code setup for notebook tutorials\n",
|
||||
"\n",
|
||||
"! wget https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/setup.py -O setup.py\n",
|
||||
"\n",
|
||||
"%run setup.py --bucket"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "autoset_project_id"
|
||||
"id": "d809f07a8935"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if PROJECT_ID == \"\" or PROJECT_ID is None or PROJECT_ID == \"[your-project-id]\":\n",
|
||||
" # Get your GCP project id from gcloud\n",
|
||||
" shell_output = ! gcloud config list --format 'value(core.project)' 2>/dev/null\n",
|
||||
" PROJECT_ID = shell_output[0]\n",
|
||||
" print(\"Project ID:\", PROJECT_ID)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "set_gcloud_project_id"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gcloud config set project $PROJECT_ID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "region"
|
||||
},
|
||||
"source": [
|
||||
"#### Region\n",
|
||||
"# Other Common setup instructions for notebook tutorials\n",
|
||||
"\n",
|
||||
"You can also change the `REGION` variable, which is used for operations\n",
|
||||
"throughout the rest of this notebook. Below are regions supported for Vertex AI. We recommend that you choose the region closest to you.\n",
|
||||
"! wget https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/setup.md -O setup.md\n",
|
||||
"\n",
|
||||
"- Americas: `us-central1`\n",
|
||||
"- Europe: `europe-west4`\n",
|
||||
"- Asia Pacific: `asia-east1`\n",
|
||||
"\n",
|
||||
"You may not use a multi-regional bucket for training with Vertex AI. Not all regions provide support for all Vertex AI services.\n",
|
||||
"\n",
|
||||
"Learn more about [Vertex AI regions](https://cloud.google.com/vertex-ai/docs/general/locations)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "region"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "timestamp"
|
||||
},
|
||||
"source": [
|
||||
"#### Timestamp\n",
|
||||
"\n",
|
||||
"If you are in a live tutorial session, you might be using a shared test account or project. To avoid name collisions between users on resources created, you create a timestamp for each instance session, and append the timestamp onto the name of resources you create in this tutorial."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "timestamp"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "77c385f0db59"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Google Cloud Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"1. **Click Create service account**.\n",
|
||||
"\n",
|
||||
"2. In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"3. In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex AI\" into the filter box, and select **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"4. Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"5. Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "535223fa4b84"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"\n",
|
||||
"# If on Google Cloud Notebooks, then don't execute this code\n",
|
||||
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "bucket:custom"
|
||||
},
|
||||
"source": [
|
||||
"### Create a Cloud Storage bucket\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"When you create a dataset resource using the Vertex SDK, you can provide a Cloud Storage bucket that contains the data. Vertex AI creates the dataset resource from the data. In this tutorial, Vertex AI also creates a dataset resource from your data in the Cloud Storage bucket.\n",
|
||||
"\n",
|
||||
"Set the name of your Cloud Storage bucket below. Bucket names must be globally unique across all Google Cloud projects, including those outside of your organization."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "autoset_bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "create_bucket"
|
||||
},
|
||||
"source": [
|
||||
"**Only if your bucket doesn't already exist**: Run the following cell to create your Cloud Storage bucket."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "create_bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil mb -l $REGION $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "validate_bucket"
|
||||
},
|
||||
"source": [
|
||||
"Finally, validate access to your Cloud Storage bucket by examining its contents:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "validate_bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_URI"
|
||||
"%load setup.md"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -614,7 +383,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dataset = aiplatform.TabularDataset.create(\n",
|
||||
" display_name=\"NOAA historical weather data\" + \"_\" + TIMESTAMP,\n",
|
||||
" display_name=\"NOAA historical weather data\" + \"_\" + UUID,\n",
|
||||
" bq_source=[IMPORT_FILE],\n",
|
||||
" labels={\"user_metadata\": BUCKET_URI[5:]},\n",
|
||||
")\n",
|
||||
@@ -689,7 +458,7 @@
|
||||
"gcs_source = IMPORT_FILES\n",
|
||||
"\n",
|
||||
"dataset = aiplatform.TabularDataset.create(\n",
|
||||
" display_name=\"NOAA historical weather data\" + \"_\" + TIMESTAMP,\n",
|
||||
" display_name=\"NOAA historical weather data\" + \"_\" + UUID,\n",
|
||||
" gcs_source=gcs_source,\n",
|
||||
" labels={\"user_metadata\": BUCKET_URI[5:]},\n",
|
||||
")\n",
|
||||
@@ -731,10 +500,10 @@
|
||||
" or BQ_MY_DATASET is None\n",
|
||||
" or BQ_MY_DATASET == \"[your-dataset-name]\"\n",
|
||||
"):\n",
|
||||
" BQ_MY_DATASET = \"mlops_dataset_\" + TIMESTAMP\n",
|
||||
" BQ_MY_DATASET = \"mlops_dataset_\" + UUID\n",
|
||||
"\n",
|
||||
"if BQ_MY_TABLE == \"\" or BQ_MY_TABLE is None or BQ_MY_TABLE == \"[your-view-name]\":\n",
|
||||
" BQ_MY_TABLE = \"mlops_view_\" + TIMESTAMP"
|
||||
" BQ_MY_TABLE = \"mlops_view_\" + UUID"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1133,7 +902,7 @@
|
||||
"source": [
|
||||
"dataframe[\"station_number\"] = pd.to_numeric(dataframe[\"station_number\"])\n",
|
||||
"labels = dataframe[\"mean_temp\"]\n",
|
||||
"data = dataframe.drop(4)\n",
|
||||
"data = dataframe.drop([\"mean_temp\"], axis=1)\n",
|
||||
"\n",
|
||||
"dtrain = xgb.DMatrix(data, label=labels)"
|
||||
]
|
||||
@@ -1194,6 +963,7 @@
|
||||
"\n",
|
||||
"# Delete the dataset using the Vertex dataset object\n",
|
||||
"dataset.delete()\n",
|
||||
"\n",
|
||||
"# Delete the temporary BigQuery dataset\n",
|
||||
"! bq rm -r -f $PROJECT_ID:$DATASET_ID\n",
|
||||
"\n",
|
||||
|
||||
@@ -39,8 +39,14 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_dataflow.ipynb\">\n",
|
||||
" Open in Google Cloud Notebooks\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_dataflow.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\\\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage1/get_started_dataflow.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
"</table>\n",
|
||||
@@ -59,17 +65,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 1 : data management: get started with Dataflow."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:gsod,lrg"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). The version of the dataset you use only the fields year, month and day to predict the value of mean daily temperature (mean_temp)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -131,6 +126,34 @@
|
||||
"Alternately for AutoML tabular model training, you can reconfigure the otherwise default preprocessing."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:gsod,lrg"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). The version of the dataset you use only the fields year, month and day to predict the value of mean daily temperature (mean_temp)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "9e483012a752"
|
||||
},
|
||||
"source": [
|
||||
"### Costs\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"- Vertex AI\n",
|
||||
"- Cloud Storage\n",
|
||||
"- BigQuery\n",
|
||||
"- Dataflow\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing), [Cloud Storage pricing](https://cloud.google.com/storage/pricing), [BigQuery pricing](https://cloud.google.com/bigquery/pricing), and [Dataflow pricing](https://cloud.google.com/dataflow/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -139,7 +162,7 @@
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"\n",
|
||||
"Install *one time* the packages for executing the MLOps notebooks."
|
||||
"Install the following packages to execute this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -150,20 +173,22 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ONCE_ONLY = False\n",
|
||||
"if ONCE_ONLY:\n",
|
||||
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade kfp $USER_FLAG"
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"extra_pkgs = \"tensorflow==2.5 tensorflow-data-validation==1.2 tensorflow-transform==1.2 \\\n",
|
||||
" tensorflow-io==0.18 pyarrow pandas apache-beam[gcp] google-cloud-bigquery\"\n",
|
||||
"! pip3 install --upgrade --quiet {USER_FLAG} google-cloud-aiplatform $extra_pkgs"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -185,9 +210,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"if not os.getenv(\"IS_TESTING\"):\n",
|
||||
"if \"google.colab\" in sys.modules:\n",
|
||||
" # Automatically restart kernel after installs\n",
|
||||
" import IPython\n",
|
||||
"\n",
|
||||
@@ -198,187 +223,42 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "project_id"
|
||||
"id": "fc8fb52b5cca"
|
||||
},
|
||||
"source": [
|
||||
"#### Set your project ID\n",
|
||||
"### Common setup\n",
|
||||
"\n",
|
||||
"**If you don't know your project ID**, you may be able to get your project ID using `gcloud`."
|
||||
"Now, execute the common setup for the notebook tutorials."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "set_project_id"
|
||||
"id": "001a0fcd5d78"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
|
||||
"# Common code setup for notebook tutorials\n",
|
||||
"\n",
|
||||
"! wget https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/setup.py -O setup.py\n",
|
||||
"\n",
|
||||
"%run setup.py --bucket"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "autoset_project_id"
|
||||
"id": "d809f07a8935"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if PROJECT_ID == \"\" or PROJECT_ID is None or PROJECT_ID == \"[your-project-id]\":\n",
|
||||
" # Get your GCP project id from gcloud\n",
|
||||
" shell_output = ! gcloud config list --format 'value(core.project)' 2>/dev/null\n",
|
||||
" PROJECT_ID = shell_output[0]\n",
|
||||
" print(\"Project ID:\", PROJECT_ID)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "set_gcloud_project_id"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gcloud config set project $PROJECT_ID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "region"
|
||||
},
|
||||
"source": [
|
||||
"#### Region\n",
|
||||
"# Other Common setup instructions for notebook tutorials\n",
|
||||
"\n",
|
||||
"You can also change the `REGION` variable, which is used for operations\n",
|
||||
"throughout the rest of this notebook. Below are regions supported for Vertex AI. We recommend that you choose the region closest to you.\n",
|
||||
"! wget https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/setup.md -O setup.md\n",
|
||||
"\n",
|
||||
"- Americas: `us-central1`\n",
|
||||
"- Europe: `europe-west4`\n",
|
||||
"- Asia Pacific: `asia-east1`\n",
|
||||
"\n",
|
||||
"You may not use a multi-regional bucket for training with Vertex AI. Not all regions provide support for all Vertex AI services.\n",
|
||||
"\n",
|
||||
"Learn more about [Vertex AI regions](https://cloud.google.com/vertex-ai/docs/general/locations)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "region"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"us-central1\" # @param {type: \"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "timestamp"
|
||||
},
|
||||
"source": [
|
||||
"#### Timestamp\n",
|
||||
"\n",
|
||||
"If you are in a live tutorial session, you might be using a shared test account or project. To avoid name collisions between users on resources created, you create a timestamp for each instance session, and append the timestamp onto the name of resources you create in this tutorial."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "timestamp"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "bucket:custom"
|
||||
},
|
||||
"source": [
|
||||
"### Create a Cloud Storage bucket\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"When you submit a custom training job using the Vertex SDK, you upload a Python package\n",
|
||||
"containing your training code to a Cloud Storage bucket. Vertex AI runs\n",
|
||||
"the code from this package. In this tutorial, Vertex AI also saves the\n",
|
||||
"trained model that results from your job in the same bucket. You can then\n",
|
||||
"create an `Endpoint` resource based on this output in order to serve\n",
|
||||
"online predictions.\n",
|
||||
"\n",
|
||||
"Set the name of your Cloud Storage bucket below. Bucket names must be globally unique across all Google Cloud projects, including those outside of your organization."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "autoset_bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "create_bucket"
|
||||
},
|
||||
"source": [
|
||||
"**Only if your bucket doesn't already exist**: Run the following cell to create your Cloud Storage bucket."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "create_bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil mb -l $REGION $BUCKET_NAME"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "validate_bucket"
|
||||
},
|
||||
"source": [
|
||||
"Finally, validate access to your Cloud Storage bucket by examining its contents:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "validate_bucket"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_NAME"
|
||||
"%load setup.md "
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -401,7 +281,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import google.cloud.aiplatform as aip"
|
||||
"import google.cloud.aiplatform as aiplatform"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -555,7 +435,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aip.init(project=PROJECT_ID, location=REGION)"
|
||||
"aiplatform.init(project=PROJECT_ID, location=REGION)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1004,7 +884,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"SCHEMA_LOCATION = BUCKET_NAME + \"/schema.txt\"\n",
|
||||
"SCHEMA_LOCATION = BUCKET_URI + \"/schema.txt\"\n",
|
||||
"\n",
|
||||
"# When running Apache Beam directly (file is directly accessed)\n",
|
||||
"tfdv.write_schema_text(output_path=SCHEMA_LOCATION, schema=schema)\n",
|
||||
@@ -1149,7 +1029,7 @@
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"EXPORTED_DATA_PREFIX = os.path.join(BUCKET_NAME, \"exported_data\")\n",
|
||||
"EXPORTED_DATA_PREFIX = os.path.join(BUCKET_URI, \"exported_data\")\n",
|
||||
"\n",
|
||||
"QUERY_STRING = \"SELECT {},{} FROM {} LIMIT 500\".format(\n",
|
||||
" \"CAST(station_number as STRING) AS station_number,year,month,day\",\n",
|
||||
@@ -1162,7 +1042,7 @@
|
||||
" \"runner\": RUNNER,\n",
|
||||
" \"raw_data_query\": QUERY_STRING,\n",
|
||||
" \"exported_data_prefix\": EXPORTED_DATA_PREFIX,\n",
|
||||
" \"temp_location\": os.path.join(BUCKET_NAME, \"temp\"),\n",
|
||||
" \"temp_location\": os.path.join(BUCKET_URI, \"temp\"),\n",
|
||||
" \"project\": PROJECT_ID,\n",
|
||||
" \"region\": REGION,\n",
|
||||
" \"setup_file\": \"./setup.py\",\n",
|
||||
@@ -1187,17 +1067,7 @@
|
||||
"To clean up all Google Cloud resources used in this project, you can [delete the Google Cloud\n",
|
||||
"project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects) you used for the tutorial.\n",
|
||||
"\n",
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
|
||||
"\n",
|
||||
"- Dataset\n",
|
||||
"- Pipeline\n",
|
||||
"- Model\n",
|
||||
"- Endpoint\n",
|
||||
"- AutoML Training Job\n",
|
||||
"- Batch Job\n",
|
||||
"- Custom Job\n",
|
||||
"- Hyperparameter Tuning Job\n",
|
||||
"- Cloud Storage Bucket"
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1208,61 +1078,11 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"delete_all = True\n",
|
||||
"delete_storage = False\n",
|
||||
"\n",
|
||||
"if delete_all:\n",
|
||||
" # Delete the dataset using the Vertex dataset object\n",
|
||||
" try:\n",
|
||||
" if \"dataset\" in globals():\n",
|
||||
" dataset.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the model using the Vertex model object\n",
|
||||
" try:\n",
|
||||
" if \"model\" in globals():\n",
|
||||
" model.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the endpoint using the Vertex endpoint object\n",
|
||||
" try:\n",
|
||||
" if \"endpoint\" in globals():\n",
|
||||
" endpoint.undeploy_all()\n",
|
||||
" endpoint.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the AutoML or Pipeline training job\n",
|
||||
" try:\n",
|
||||
" if \"dag\" in globals():\n",
|
||||
" dag.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the custom training job\n",
|
||||
" try:\n",
|
||||
" if \"job\" in globals():\n",
|
||||
" job.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the batch prediction job using the Vertex batch prediction object\n",
|
||||
" try:\n",
|
||||
" if \"batch_predict_job\" in globals():\n",
|
||||
" batch_predict_job.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
|
||||
" try:\n",
|
||||
" if \"hpt_job\" in globals():\n",
|
||||
" hpt_job.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" if \"BUCKET_NAME\" in globals():\n",
|
||||
" ! gsutil rm -r $BUCKET_NAME"
|
||||
"if delete_storage or os.getenv(\"IS_TESTING\"):\n",
|
||||
" if \"BUCKET_URI\" in globals():\n",
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Copyright 2021 Google LLC\n",
|
||||
"# Copyright 2022 Google LLC\n",
|
||||
"#\n",
|
||||
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
|
||||
"# you may not use this file except in compliance with the License.\n",
|
||||
@@ -29,20 +29,26 @@
|
||||
"id": "title:generic,gcp"
|
||||
},
|
||||
"source": [
|
||||
"# E2E ML on GCP: MLOps stage 1 : data management: get started with Vertex datasets\n",
|
||||
"# E2E ML on GCP: MLOps stage 1 : data management: get started with Vertex AI datasets\n",
|
||||
"\n",
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_vertex_datasets.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_vertex_datasets.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_vertex_datasets.ipynb\">\n",
|
||||
" Open in Google Cloud Notebooks\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_vertex_datasets.ipynb\">\n",
|
||||
"<img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage1/get_started_vertex_datasets.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
" </td> \n",
|
||||
"</table>\n",
|
||||
"<br/><br/><br/>"
|
||||
]
|
||||
@@ -133,6 +139,33 @@
|
||||
" - Create a tf.data.Dataset from the TFRecords."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "533dd6fe83c8"
|
||||
},
|
||||
"source": [
|
||||
"### Datasets\n",
|
||||
"\n",
|
||||
"This tutorial uses a variety of public datasets to demonstrate using a `Vertex AI` managed dataset."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "9e483012a752"
|
||||
},
|
||||
"source": [
|
||||
"### Costs\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"- Vertex AI\n",
|
||||
"- Cloud Storage\n",
|
||||
"- BigQuery\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing), [Cloud Storage pricing](https://cloud.google.com/storage/pricing) and [BigQuery pricing](https://cloud.google.com/bigquery/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -141,7 +174,7 @@
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"\n",
|
||||
"Install *one time* the packages for executing the MLOps notebooks."
|
||||
"Install the packages required for executing this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -152,20 +185,27 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ONCE_ONLY = False\n",
|
||||
"if ONCE_ONLY:\n",
|
||||
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade kfp $USER_FLAG"
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install -U tensorflow $USER_FLAG -q\n",
|
||||
"! pip3 install -U tensorflow-data-validation $USER_FLAG -q\n",
|
||||
"! pip3 install -U tensorflow-transform $USER_FLAG -q\n",
|
||||
"! pip3 install -U tensorflow-io $USER_FLAG -q\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG -q\n",
|
||||
"! pip3 install --upgrade google-cloud-bigquery $USER_FLAG -q\n",
|
||||
"! pip3 install -U tensorflow-io==0.18 $USER_FLAG -q\n",
|
||||
"! pip3 install --upgrade db-dtypes $USER_FLAG -q! pip3 install --upgrade future $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -197,6 +237,32 @@
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "cb082379ed5b"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). \n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -223,7 +289,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "autoset_project_id"
|
||||
"id": "nWlzLu5ELxWd"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -238,7 +304,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "set_gcloud_project_id"
|
||||
"id": "c021ca495967"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -273,7 +339,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"us-central1\" # @param {type: \"string\"}"
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -300,6 +369,66 @@
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "927085b84a07"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"**Click Create service account**.\n",
|
||||
"\n",
|
||||
"In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex\" into the filter box, and select **Vertex Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "89788a802687"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = \"google.colab\" in sys.modules\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -328,7 +457,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -339,8 +468,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -360,7 +489,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil mb -l $REGION $BUCKET_NAME"
|
||||
"! gsutil mb -l $REGION $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -380,7 +509,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_NAME"
|
||||
"! gsutil ls -al $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -392,7 +521,11 @@
|
||||
"### Set up variables\n",
|
||||
"\n",
|
||||
"Next, set up some variables used throughout the tutorial.\n",
|
||||
"### Import libraries and define constants"
|
||||
"### Import libraries and define constants\n",
|
||||
"\n",
|
||||
"Import the BigQuery package, TensorFlow Data Validation (TFDV) package and TensorFlow Data Validation package into your Python environment. \n",
|
||||
"\n",
|
||||
"Import TensorFlow Transform (TFT) package and pandas into your Python environment."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -403,97 +536,13 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import google.cloud.aiplatform as aip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "import_bq"
|
||||
},
|
||||
"source": [
|
||||
"#### Import BigQuery\n",
|
||||
"\n",
|
||||
"Import the BigQuery package into your Python environment."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_bq"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import google.cloud.aiplatform as aip\n",
|
||||
"import pandas as pd\n",
|
||||
"import tensorflow_data_validation as tfdv\n",
|
||||
"import tensorflow_transform as tft\n",
|
||||
"from google.cloud import bigquery"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "import_tfdv"
|
||||
},
|
||||
"source": [
|
||||
"#### Import TensorFlow Data Validation\n",
|
||||
"\n",
|
||||
"Import the TensorFlow Data Validation (TFDV) package into your Python environment."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_tfdv"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import tensorflow_data_validation as tfdv"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "import_tft"
|
||||
},
|
||||
"source": [
|
||||
"#### Import TensorFlow Transform\n",
|
||||
"\n",
|
||||
"Import the TensorFlow Transform (TFT) package into your Python environment."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_tft"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import tensorflow_transform as tft"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "import_pandas"
|
||||
},
|
||||
"source": [
|
||||
"#### Import pandas\n",
|
||||
"\n",
|
||||
"Import the pandas package into your Python environment."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_pandas"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -513,7 +562,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aip.init(project=PROJECT_ID, location=REGION)"
|
||||
"aip.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_URI)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -567,26 +616,13 @@
|
||||
"Learn more about [All dataset documentation](https://cloud.google.com/vertex-ai/docs/datasets/datasets)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_file:flowers,csv,icn"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMPORT_FILE = (\n",
|
||||
" \"gs://cloud-samples-data/vision/automl_classification/flowers/all_data_v2.csv\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "create_dataset:image,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Create the Dataset\n",
|
||||
"### Create an Image Dataset\n",
|
||||
"\n",
|
||||
"Next, create the `Dataset` resource using the `create` method for the `ImageDataset` class, which takes the following parameters:\n",
|
||||
"\n",
|
||||
@@ -601,6 +637,19 @@
|
||||
"Learn more about [ImageDataset](https://cloud.google.com/vertex-ai/docs/datasets/prepare-image)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_file:flowers,csv,icn"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMPORT_FILE = (\n",
|
||||
" \"gs://cloud-samples-data/vision/automl_classification/flowers/all_data_v2.csv\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -618,24 +667,13 @@
|
||||
"print(dataset.resource_name)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_file:hmdb,csv,vcn"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMPORT_FILE = \"gs://automl-video-demo-data/hmdb_split1_5classes_train_inf.csv\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "create_dataset:video,vcn"
|
||||
},
|
||||
"source": [
|
||||
"### Create the Dataset\n",
|
||||
"### Create a Video Dataset\n",
|
||||
"\n",
|
||||
"Next, create the `Dataset` resource using the `create` method for the `VideoDataset` class, which takes the following parameters:\n",
|
||||
"\n",
|
||||
@@ -649,6 +687,17 @@
|
||||
"Learn more about [VideoDataset](https://cloud.google.com/vertex-ai/docs/datasets/prepare-video)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_file:hmdb,csv,vcn"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMPORT_FILE = \"gs://automl-video-demo-data/hmdb_split1_5classes_train_inf.csv\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -666,24 +715,13 @@
|
||||
"print(dataset.resource_name)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_file:happydb,csv,tcn"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMPORT_FILE = \"gs://cloud-ml-data/NL-classification/happiness.csv\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "create_dataset:text,tcn"
|
||||
},
|
||||
"source": [
|
||||
"### Create the Dataset\n",
|
||||
"### Create a Text Dataset\n",
|
||||
"\n",
|
||||
"Next, create the `Dataset` resource using the `create` method for the `TextDataset` class, which takes the following parameters:\n",
|
||||
"\n",
|
||||
@@ -698,6 +736,17 @@
|
||||
"Learn more about [TextDataset](https://cloud.google.com/vertex-ai/docs/datasets/prepare-text)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_file:happydb,csv,tcn"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMPORT_FILE = \"gs://cloud-ml-data/NL-classification/happiness.csv\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -715,6 +764,24 @@
|
||||
"print(dataset.resource_name)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "create_dataset:tabular,bq,lrg,v2"
|
||||
},
|
||||
"source": [
|
||||
"### Create a Tabular Dataset\n",
|
||||
"\n",
|
||||
"#### CSV input data\n",
|
||||
"\n",
|
||||
"Next, create the `Dataset` resource using the `create` method for the `TabularDataset` class for CSV input data, which takes the following parameters:\n",
|
||||
"\n",
|
||||
"- `display_name`: The human readable name for the `Dataset` resource.\n",
|
||||
"- `gcs_source`: A list of one or more dataset index files to import the data items into the `Dataset` resource.\n",
|
||||
"\n",
|
||||
"Learn more about [TabularDataset from CSV files](https://cloud.google.com/vertex-ai/docs/datasets/create-dataset-api#aiplatform_create_dataset_tabular_gcs_sample-python)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -723,27 +790,50 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMPORT_FILE = \"bq://bigquery-public-data.samples.gsod\"\n",
|
||||
"BQ_TABLE = \"bigquery-public-data.samples.gsod\""
|
||||
"IMPORT_FILE = \"gs://cloud-samples-data/tables/iris_1000.csv\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "create_dataset:tabular,bq,lrg,v2"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dataset = aip.TabularDataset.create(\n",
|
||||
" display_name=\"example\" + \"_\" + TIMESTAMP, gcs_source=[IMPORT_FILE]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(dataset.resource_name)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "create_dataset:tabular,bq,lrg,v2"
|
||||
"id": "854dd1e0195c"
|
||||
},
|
||||
"source": [
|
||||
"### Create the Dataset\n",
|
||||
"#### BigQuery input data\n",
|
||||
"\n",
|
||||
"#### CSV input data\n",
|
||||
"\n",
|
||||
"Next, create the `Dataset` resource using the `create` method for the `TabularDataset` class, which takes the following parameters:\n",
|
||||
"Next, create the `Dataset` resource using the `create` method for the `TabularDataset` class for BigQuery table input, which takes the following parameters:\n",
|
||||
"\n",
|
||||
"- `display_name`: The human readable name for the `Dataset` resource.\n",
|
||||
"- `gcs_source`: A list of one or more dataset index files to import the data items into the `Dataset` resource.\n",
|
||||
"- `labels`: User defined metadata. In this example, you store the location of the Cloud Storage bucket containing the user defined data.\n",
|
||||
"- `bq_source`: A list of one or more BigQuery tables to import the data items into the `Dataset` resource.\n",
|
||||
"\n",
|
||||
"Learn more about [TabularDataset from CSV files](https://cloud.google.com/vertex-ai/docs/datasets/create-dataset-api#aiplatform_create_dataset_tabular_gcs_sample-python)"
|
||||
"Learn more about [TabularDataset from BigQuery table](https://cloud.google.com/vertex-ai/docs/datasets/create-dataset-api#aiplatform_create_dataset_tabular_bigquery_sample-pythonn)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "86343c146300"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMPORT_FILE = \"bq://bigquery-public-data.samples.gsod\"\n",
|
||||
"BQ_TABLE = \"bigquery-public-data.samples.gsod\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -761,15 +851,63 @@
|
||||
"print(dataset.resource_name)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "82e9fe20ce71"
|
||||
},
|
||||
"source": [
|
||||
"#### Dataframe input data\n",
|
||||
"\n",
|
||||
"Next, create the `Dataset` resource using the `create_from_dataframe` method for the `TabularDataset` class for pandas dataframe input, which takes the following parameters:\n",
|
||||
"\n",
|
||||
"- `display_name`: The human readable name for the `Dataset` resource.\n",
|
||||
"- `df_source`: The pandas dataframe to import the data items into the `Dataset` resource.\n",
|
||||
"- `staging_path`: The BigQuery table to store the imported data."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_file:covid,csv,forecast"
|
||||
"id": "3805f945ffdd"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMPORT_FILE = \"gs://cloud-samples-data/ai-platform/covid/bigquery-public-covid-nyt-us-counties-train.csv\""
|
||||
"# Download the table.\n",
|
||||
"table = bigquery.TableReference.from_string(BQ_TABLE)\n",
|
||||
"\n",
|
||||
"rows = bqclient.list_rows(\n",
|
||||
" table,\n",
|
||||
" max_results=10000,\n",
|
||||
" selected_fields=[\n",
|
||||
" bigquery.SchemaField(\"station_number\", \"STRING\"),\n",
|
||||
" bigquery.SchemaField(\"year\", \"INTEGER\"),\n",
|
||||
" bigquery.SchemaField(\"month\", \"INTEGER\"),\n",
|
||||
" bigquery.SchemaField(\"day\", \"INTEGER\"),\n",
|
||||
" bigquery.SchemaField(\"mean_temp\", \"FLOAT\"),\n",
|
||||
" ],\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"dataframe = rows.to_dataframe()\n",
|
||||
"print(dataframe.head())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "create_dataset:tabular,bq,lrg,v2"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dataset = aip.TabularDataset.create_from_dataframe(\n",
|
||||
" display_name=\"example\" + \"_\" + TIMESTAMP,\n",
|
||||
" df_source=dataframe,\n",
|
||||
" staging_path=f\"bq://{PROJECT_ID}.samples.gsod\",\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(dataset.resource_name)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -778,7 +916,7 @@
|
||||
"id": "create_dataset:tabular,forecast,v2"
|
||||
},
|
||||
"source": [
|
||||
"### Create the Dataset\n",
|
||||
"### Create a Time Series Dataset\n",
|
||||
"\n",
|
||||
"Next, create the `Dataset` resource using the `create` method for the `TimeSeriesDataset` class, which takes the following parameters:\n",
|
||||
"\n",
|
||||
@@ -789,6 +927,17 @@
|
||||
"Learn more about [TimeSeriesDataset](https://cloud.google.com/vertex-ai/docs/datasets/prepare-tabular)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_file:covid,csv,forecast"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"IMPORT_FILE = \"gs://cloud-samples-data/ai-platform/covid/bigquery-public-covid-nyt-us-counties-train.csv\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -1149,9 +1298,9 @@
|
||||
"comps = BQ_TABLE.split(\".\")\n",
|
||||
"BQ_PROJECT_DATASET_TABLE = comps[0] + \":\" + comps[1] + \".\" + comps[2]\n",
|
||||
"\n",
|
||||
"! bq --location=us extract --destination_format CSV $BQ_PROJECT_DATASET_TABLE $BUCKET_NAME/mydata*.csv\n",
|
||||
"! bq --location=us extract --destination_format CSV $BQ_PROJECT_DATASET_TABLE $BUCKET_URI/mydata*.csv\n",
|
||||
"\n",
|
||||
"IMPORT_FILES = ! gsutil ls $BUCKET_NAME/mydata*.csv\n",
|
||||
"IMPORT_FILES = ! gsutil ls $BUCKET_URI/mydata*.csv\n",
|
||||
"\n",
|
||||
"print(IMPORT_FILES)\n",
|
||||
"\n",
|
||||
@@ -1209,6 +1358,38 @@
|
||||
"To create a dataframe from multiple CSV sources, you read each CSV file and concatenate the dataframes together."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "bcd2e4e0703b"
|
||||
},
|
||||
"source": [
|
||||
"If you are running this notebook on Colab, run the following cell to install packages fsspec and gcsfs."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "927bd3f92268"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Workbench AI Notebook, then don't execute this code\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" ! pip3 install fsspec\n",
|
||||
" ! pip3 install gcsfs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -1269,7 +1450,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"EXPORTED_DIR = f\"{BUCKET_NAME}/exported\"\n",
|
||||
"EXPORTED_DIR = f\"{BUCKET_URI}/exported\"\n",
|
||||
"exported_files = dataset.export_data(output_dir=EXPORTED_DIR)\n",
|
||||
"\n",
|
||||
"! gsutil ls $EXPORTED_DIR"
|
||||
@@ -1498,7 +1679,7 @@
|
||||
" data = f.readlines()\n",
|
||||
"\n",
|
||||
"# The path to the TFRecord cached file.\n",
|
||||
"GCS_TFRECORD_URI = BUCKET_NAME + \"/flowers.tfrecord\"\n",
|
||||
"GCS_TFRECORD_URI = BUCKET_URI + \"/flowers.tfrecord\"\n",
|
||||
"\n",
|
||||
"# Create the TFRecord cached file\n",
|
||||
"with tf.io.TFRecordWriter(GCS_TFRECORD_URI) as writer:\n",
|
||||
@@ -1532,14 +1713,7 @@
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
|
||||
"\n",
|
||||
"- Dataset\n",
|
||||
"- Pipeline\n",
|
||||
"- Model\n",
|
||||
"- Endpoint\n",
|
||||
"- AutoML Training Job\n",
|
||||
"- Batch Job\n",
|
||||
"- Custom Job\n",
|
||||
"- Hyperparameter Tuning Job\n",
|
||||
"- Cloud Storage Bucket"
|
||||
"- Bucket"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1550,61 +1724,16 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"delete_all = True\n",
|
||||
"delete_bucket = False\n",
|
||||
"\n",
|
||||
"if delete_all:\n",
|
||||
" # Delete the dataset using the Vertex dataset object\n",
|
||||
" try:\n",
|
||||
" if \"dataset\" in globals():\n",
|
||||
" dataset.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"# Delete the dataset using the Vertex dataset object\n",
|
||||
"datasets = aip.TabularDataset.list(filter=f'display_name=\"example_{TIMESTAMP}\"')\n",
|
||||
"for dataset in datasets:\n",
|
||||
" dataset.delete()\n",
|
||||
"\n",
|
||||
" # Delete the model using the Vertex model object\n",
|
||||
" try:\n",
|
||||
" if \"model\" in globals():\n",
|
||||
" model.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the endpoint using the Vertex endpoint object\n",
|
||||
" try:\n",
|
||||
" if \"endpoint\" in globals():\n",
|
||||
" endpoint.undeploy_all()\n",
|
||||
" endpoint.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the AutoML or Pipeline training job\n",
|
||||
" try:\n",
|
||||
" if \"dag\" in globals():\n",
|
||||
" dag.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the custom training job\n",
|
||||
" try:\n",
|
||||
" if \"job\" in globals():\n",
|
||||
" job.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the batch prediction job using the Vertex batch prediction object\n",
|
||||
" try:\n",
|
||||
" if \"batch_predict_job\" in globals():\n",
|
||||
" batch_predict_job.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
|
||||
" try:\n",
|
||||
" if \"hpt_job\" in globals():\n",
|
||||
" hpt_job.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" if \"BUCKET_NAME\" in globals():\n",
|
||||
" ! gsutil rm -r $BUCKET_NAME"
|
||||
"# Delete the bucket\n",
|
||||
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_with_data_labeling.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage1/get_started_with_data_labeling.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -65,17 +65,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 1 : data management: get started with Vertex AI Data Labeling service."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:flowers,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the type of flower an image is from a class of five flowers: daisy, dandelion, rose, sunflower, or tulip."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -102,6 +91,17 @@
|
||||
"Learn more about [Request a Vertex AI Data Labeling job](https://cloud.google.com/vertex-ai/docs/datasets/data-labeling-job)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:flowers,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset you use in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the type of flower an image is from a class of five flowers: daisy, dandelion, rose, sunflower, or tulip."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -145,17 +145,20 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"# Install the packages\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG\n",
|
||||
"! pip3 install --upgrade google-cloud-storage $USER_FLAG"
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG -q\n",
|
||||
"! pip3 install --upgrade google-cloud-storage $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -164,7 +167,7 @@
|
||||
"id": "restart"
|
||||
},
|
||||
"source": [
|
||||
"### Restart the Kernel\n",
|
||||
"### Restart the kernel\n",
|
||||
"\n",
|
||||
"Once you've installed the Vertex AI SDK and Google *cloud-storage*, you need to restart the notebook kernel so it can find the packages.\n"
|
||||
]
|
||||
@@ -207,9 +210,9 @@
|
||||
"\n",
|
||||
"2. [Make sure that billing is enabled for your project.](https://cloud.google.com/billing/docs/how-to/modify-project)\n",
|
||||
"\n",
|
||||
"3. [Enable the Vertex AI APIs and Compute Engine APIs.](https://console.cloud.google.com/flows/enableapi?apiid=ml.googleapis.com,compute_component)\n",
|
||||
"3. [Enable the Vertex AI APIs and Compute Engine APIs.](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,compute_component)\n",
|
||||
"\n",
|
||||
"4. [Google Cloud SDK](https://cloud.google.com/sdk) is already installed in Google Cloud Notebooks.\n",
|
||||
"4. [Google Cloud SDK](https://cloud.google.com/sdk) is already installed in Vertex AI Workbench Notebooks.\n",
|
||||
"\n",
|
||||
"5. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
@@ -217,6 +220,17 @@
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "WReHDGG5g0XY"
|
||||
},
|
||||
"source": [
|
||||
"#### Set your project ID\n",
|
||||
"\n",
|
||||
"**If you don't know your project ID**, you may be able to get your project ID using `gcloud`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -359,16 +373,9 @@
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Google Cloud Notebooks**, your environment is already\n",
|
||||
"authenticated. Skip this step."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "32e1cd21a5d5"
|
||||
},
|
||||
"source": [
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already\n",
|
||||
"authenticated. \n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions\n",
|
||||
"when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
@@ -401,20 +408,21 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Google Cloud Notebooks, then don't execute this code\n",
|
||||
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
@@ -462,7 +470,8 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
" BUCKET_NAME = PROJECT_ID + \"aip-\" + TIMESTAMP\n",
|
||||
" BUCKET_URI = \"gs://\" + BUCKET_NAME"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+1005
File diff suppressed because it is too large
Load Diff
@@ -39,12 +39,15 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/mlops_data_management.ipynb\">\n",
|
||||
" Open in Google Cloud Notebooks\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage1/mlops_data_management.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
"</table>\n",
|
||||
"<br/><br/><br/>"
|
||||
"<br/><br/><br/>\n",
|
||||
"\n",
|
||||
"*Note: This notebook is not supported for execution in Colab*"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -59,17 +62,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 1 : data management."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:bq,chicago,lbn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Chicago Taxi](https://www.kaggle.com/chicago/chicago-taxi-trips-bq). The version of the dataset you will use in this tutorial is stored in a public BigQuery table. The trained model predicts whether someone would leave a tip for a taxi fare."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -114,6 +106,34 @@
|
||||
" - Preprocess the data with `Dataflow`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:bq,chicago,lbn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Chicago Taxi](https://www.kaggle.com/chicago/chicago-taxi-trips-bq). The version of the dataset used in this tutorial is stored in a public BigQuery table. The trained model predicts whether someone leaves a tip for a taxi fare."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "9e483012a752"
|
||||
},
|
||||
"source": [
|
||||
"### Costs\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"- Vertex AI\n",
|
||||
"- Cloud Storage\n",
|
||||
"- BigQuery\n",
|
||||
"- Dataflow\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing), [Cloud Storage pricing](https://cloud.google.com/storage/pricing), [BigQuery pricing](https://cloud.google.com/bigquery/pricing), and [Dataflow pricing](https://cloud.google.com/dataflow/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -133,20 +153,33 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"ONCE_ONLY = False\n",
|
||||
"if ONCE_ONLY:\n",
|
||||
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade kfp $USER_FLAG"
|
||||
" ! pip3 install -U {USER_FLAG} -q tensorflow==2.5 \\\n",
|
||||
" tensorflow-data-validation==1.2 \\\n",
|
||||
" tensorflow-transform==1.2 \\\n",
|
||||
" tensorflow-io==0.18 \n",
|
||||
" \n",
|
||||
" ! pip3 install --upgrade {USER_FLAG} -q google-cloud-aiplatform[tensorboard] \\\n",
|
||||
" google-cloud-pipeline-components \\\n",
|
||||
" google-cloud-bigquery \\\n",
|
||||
" google-cloud-logging \\\n",
|
||||
" apache-beam[gcp] \\\n",
|
||||
" pyarrow \\\n",
|
||||
" cloudml-hypertune\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -178,6 +211,32 @@
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "84cd83853240"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI, BigQuery, Compute Engine and Cloud Storage APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,bigquery,compute_component,storage_component).\n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -254,7 +313,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"us-central1\" # @param {type: \"string\"}"
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -281,6 +343,66 @@
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "77c385f0db59"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. \n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"1. **Click Create service account**.\n",
|
||||
"\n",
|
||||
"2. In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"3. In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex AI\" into the filter box, and select **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"4. Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"5. Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "535223fa4b84"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = \"google.colab\" in sys.modules\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -291,7 +413,7 @@
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"When you submit a custom training job using the Vertex SDK, you upload a Python package\n",
|
||||
"When you submit a custom training job using the Vertex AI SDK, you upload a Python package\n",
|
||||
"containing your training code to a Cloud Storage bucket. Vertex AI runs\n",
|
||||
"the code from this package. In this tutorial, Vertex AI also saves the\n",
|
||||
"trained model that results from your job in the same bucket. You can then\n",
|
||||
@@ -309,7 +431,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
|
||||
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -320,8 +443,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = PROJECT_ID + \"aip-\" + TIMESTAMP\n",
|
||||
" BUCKET_URI = \"gs://\" + BUCKET_NAME"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -341,7 +465,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil mb -l $REGION $BUCKET_NAME"
|
||||
"! gsutil mb -l $REGION $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -361,7 +485,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_NAME"
|
||||
"! gsutil ls -al $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -516,7 +640,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
|
||||
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -538,7 +662,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"bqclient = bigquery.Client()"
|
||||
"bqclient = bigquery.Client(project=PROJECT_ID)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -661,6 +785,11 @@
|
||||
"LIMIT = 300000\n",
|
||||
"YEAR = 2020\n",
|
||||
"\n",
|
||||
"# First, create the dataset entry\n",
|
||||
"dataset = bigquery.Dataset(f\"{PROJECT_ID}.{BQ_DATASET}\")\n",
|
||||
"dataset.location = \"US\"\n",
|
||||
"dataset = bqclient.create_dataset(dataset, timeout=30)\n",
|
||||
"\n",
|
||||
"query = f\"\"\"\n",
|
||||
"CREATE OR REPLACE TABLE `{BQ_TABLE_COPY}`\n",
|
||||
"AS (\n",
|
||||
@@ -757,7 +886,7 @@
|
||||
"dataset = aip.TabularDataset.create(\n",
|
||||
" display_name=\"Chicago Taxi\" + \"_\" + TIMESTAMP,\n",
|
||||
" bq_source=[IMPORT_FILE],\n",
|
||||
" labels={\"user_metadata\": BUCKET_NAME[5:]},\n",
|
||||
" labels={\"user_metadata\": BUCKET_NAME},\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"label_column = \"tip_bin\"\n",
|
||||
@@ -949,9 +1078,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"STATISTICS_SCHEMA = BUCKET_NAME + \"/statistics.jsonl\"\n",
|
||||
"STATISTICS_SCHEMA = BUCKET_URI + \"/statistics.jsonl\"\n",
|
||||
"\n",
|
||||
"tfdv.write_stats_text(stats, BUCKET_NAME + \"/statistics.jsonl\")\n",
|
||||
"tfdv.write_stats_text(stats, BUCKET_URI + \"/statistics.jsonl\")\n",
|
||||
"\n",
|
||||
"with tf.io.gfile.GFile(\n",
|
||||
" \"gs://\" + dataset.labels[\"user_metadata\"] + \"/metadata.jsonl\", \"r\"\n",
|
||||
@@ -964,7 +1093,7 @@
|
||||
") as f:\n",
|
||||
" json.dump(metadata, f)\n",
|
||||
"\n",
|
||||
"!gsutil cat $BUCKET_NAME/metadata.jsonl"
|
||||
"! gsutil cat $BUCKET_URI/metadata.jsonl"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1011,7 +1140,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"SCHEMA_LOCATION = BUCKET_NAME + \"/schema.txt\"\n",
|
||||
"SCHEMA_LOCATION = BUCKET_URI + \"/schema.txt\"\n",
|
||||
"\n",
|
||||
"# When running Apache Beam directly (file is directly accessed)\n",
|
||||
"tfdv.write_schema_text(output_path=SCHEMA_LOCATION, schema=schema)\n",
|
||||
@@ -1049,7 +1178,7 @@
|
||||
") as f:\n",
|
||||
" json.dump(metadata, f)\n",
|
||||
"\n",
|
||||
"!gsutil cat $BUCKET_NAME/metadata.jsonl"
|
||||
"! gsutil cat $BUCKET_URI/metadata.jsonl"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1101,7 +1230,7 @@
|
||||
"import setuptools\n",
|
||||
"\n",
|
||||
"REQUIRED_PACKAGES = [\n",
|
||||
" \"google-cloud-aiplatform==1.4.2\",\n",
|
||||
" \"google-cloud-aiplatform\",\n",
|
||||
" \"tensorflow-transform==1.2.0\",\n",
|
||||
" \"tensorflow-data-validation==1.2.0\",\n",
|
||||
"]\n",
|
||||
@@ -1372,10 +1501,10 @@
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"EXPORTED_JSONL_PREFIX = os.path.join(BUCKET_NAME, \"exported_data/jsonl\")\n",
|
||||
"EXPORTED_TFREC_PREFIX = os.path.join(BUCKET_NAME, \"exported_data/tfrec\")\n",
|
||||
"TRANSFORMED_DATA_PREFIX = os.path.join(BUCKET_NAME, \"transformed_data\")\n",
|
||||
"TRANSFORM_ARTIFACTS_DIR = os.path.join(BUCKET_NAME, \"transformed_artifacts\")\n",
|
||||
"EXPORTED_JSONL_PREFIX = os.path.join(BUCKET_URI, \"exported_data/jsonl\")\n",
|
||||
"EXPORTED_TFREC_PREFIX = os.path.join(BUCKET_URI, \"exported_data/tfrec\")\n",
|
||||
"TRANSFORMED_DATA_PREFIX = os.path.join(BUCKET_URI, \"transformed_data\")\n",
|
||||
"TRANSFORM_ARTIFACTS_DIR = os.path.join(BUCKET_URI, \"transformed_artifacts\")\n",
|
||||
"\n",
|
||||
"QUERY_STRING = \"SELECT * FROM {} LIMIT 300000\".format(BQ_TABLE)\n",
|
||||
"JOB_NAME = \"chicago\" + TIMESTAMP\n",
|
||||
@@ -1388,7 +1517,7 @@
|
||||
" \"transform_artifact_dir\": TRANSFORM_ARTIFACTS_DIR,\n",
|
||||
" \"exported_jsonl_prefix\": EXPORTED_JSONL_PREFIX,\n",
|
||||
" \"exported_tfrec_prefix\": EXPORTED_TFREC_PREFIX,\n",
|
||||
" \"temp_location\": os.path.join(BUCKET_NAME, \"temp\"),\n",
|
||||
" \"temp_location\": os.path.join(BUCKET_URI, \"temp\"),\n",
|
||||
" \"project\": PROJECT_ID,\n",
|
||||
" \"region\": REGION,\n",
|
||||
" \"setup_file\": \"./setup.py\",\n",
|
||||
@@ -1459,7 +1588,7 @@
|
||||
") as f:\n",
|
||||
" json.dump(metadata, f)\n",
|
||||
"\n",
|
||||
"!gsutil cat $BUCKET_NAME/metadata.jsonl"
|
||||
"! gsutil cat $BUCKET_URI/metadata.jsonl"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1473,17 +1602,9 @@
|
||||
"To clean up all Google Cloud resources used in this project, you can [delete the Google Cloud\n",
|
||||
"project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects) you used for the tutorial.\n",
|
||||
"\n",
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial.\n",
|
||||
"\n",
|
||||
"- Dataset\n",
|
||||
"- Pipeline\n",
|
||||
"- Model\n",
|
||||
"- Endpoint\n",
|
||||
"- AutoML Training Job\n",
|
||||
"- Batch Job\n",
|
||||
"- Custom Job\n",
|
||||
"- Hyperparameter Tuning Job\n",
|
||||
"- Cloud Storage Bucket"
|
||||
"*Note:* stage2/mlops_experimentation is dependent on the resources created by this stage1 notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1504,8 +1625,8 @@
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" if \"BUCKET_NAME\" in globals():\n",
|
||||
" ! gsutil rm -r $BUCKET_NAME"
|
||||
" if \"BUCKET_URI\" in globals():\n",
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 39 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
@@ -25,83 +25,20 @@ The second stage in MLOps is experimenting in developing one or more baseline mo
|
||||
- Use the What-if-Tool (WIT) to explore how the trained model would make predictions in different scenarios.
|
||||
|
||||
|
||||
<img src='stage2.png'>
|
||||
<img src='stage2v3.png'>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<img src='stage2.2v1.png'>
|
||||
|
||||
## Notebooks
|
||||
|
||||
### Get Started
|
||||
|
||||
[Get Started with Vertex Experiments and Vertex ML Metadata](get_started_vertex_experiments.ipynb)
|
||||
[Get started with Vertex AI Training for R](community/ml_ops/stage2/get_started_vertex_training_r.ipynb)
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
In this tutorial, you learn how to use `Vertex AI Training` for training a R custom model.
|
||||
|
||||
- Use Python logging to log training configuration/results locally.
|
||||
- Use Google Cloud Logging to log training configuration/results in cloud storage.
|
||||
- Create a Vertex AI `Experiment` resource.
|
||||
- Instantiate an experiment run.
|
||||
- Log parameters for the run.
|
||||
- Log metrics for the run.
|
||||
- Display the logged experiment run.
|
||||
```
|
||||
|
||||
[Get Started with Vertex TensorBoard](get_started_vertex_tensorboard.ipynb)
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Create a TensorBoard callback when training a model.
|
||||
- Using Tensorboard with locally trained model.
|
||||
- Using Vertex AI TensorBoard with Vertex AI Training.
|
||||
```
|
||||
|
||||
[Get Started with Custom Training Packages (Tensorflow)](get_started_vertex_training.ipynb)
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Training using a single Python script.
|
||||
- Training using a Python package.
|
||||
- Training using a custom training image.
|
||||
- Laying out a training package.
|
||||
```
|
||||
|
||||
[Get Started with Custom Training Packages (Scikit-Learn)](get_started_vertex_training_sklearn.ipynb)
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Training using a Python package.
|
||||
- Report accuracy when hyperparameter tuning.
|
||||
- Save the model artifacts to Cloud Storage using GCSFuse.
|
||||
- Create a `Vertex AI Model` resource.
|
||||
```
|
||||
|
||||
[Get Started with Custom Training Packages (XGBoost)](get_started_vertex_training_xgboost.ipynb)
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Training using a Python package.
|
||||
- Report accuracy when hyperparameter tuning.
|
||||
- Save the model artifacts to Cloud Storage using GCSFuse.
|
||||
- Create a `Vertex AI Model` resource.
|
||||
```
|
||||
|
||||
[Get Started with Custom Training Packages (Pytorch)](get_started_vertex_training_pytorch.ipynb)
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Single node training using a Python package.
|
||||
- Report accuracy when hyperparameter tuning.
|
||||
- Save the model artifacts to Cloud Storage using GCSFuse.
|
||||
- Create a `Vertex AI Model` resource.
|
||||
```
|
||||
|
||||
[Get Started with Custom Training Packages (R)](get_started_vertex_training_r.ipynb)
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Locally train an R model in a notebook using %%R magic commands
|
||||
@@ -113,82 +50,57 @@ The steps performed include:
|
||||
- Create a R-to-Python training package.
|
||||
- Create a training image for training the model.
|
||||
- Train a R model using `Vertex AI Trainingh` service with the R-to-Python training package.
|
||||
```
|
||||
|
||||
[Get Started with Distributed Training](get_started_vertex_distributed_training.ipynb)
|
||||
[Get started with Logging](community/ml_ops/stage2/get_started_with_logging.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use Python and Cloud logging awhen training with `Vertex AI`.
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- `MirroredStrategy`: Train on a single VM with multiple GPUs.
|
||||
- `MultiWorkerMirroredStrategy`: Train on multiple VMs with automatic setup of replicas.
|
||||
- `MultiWorkerMirroredStrategy`: Train on multiple VMs with fine grain control of replicas.
|
||||
- `ReductionServer`: Train on multiple VMS and sync updates across VMS with `Vertex AI Reduction Server`.
|
||||
- `TPUTraining`: Train with multiple Cloud TPUs.
|
||||
```
|
||||
- Use Python logging to log training configuration/results locally.
|
||||
- Use Google Cloud Logging to log training configuration/results in cloud storage.
|
||||
|
||||
[Get Started with Vizier Hyperparameter Tuning](get_started_vertex_vizier.ipynb)
|
||||
[Get started with Vertex AI Hyperparameter Tuning for XGBoost] (community/ml_ops/stage2/get_started_vertex_hpt_xgboost.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Hyperparameter Tuning` for training a XGBoost custom model.
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Hyperparameter tuning with Random algorithm.
|
||||
- Hyperparameter tuning with Vizier (Bayesian) algorithm.
|
||||
```
|
||||
- Training using a Python package.
|
||||
- Report accuracy when hyperparameter tuning.
|
||||
- Save the model artifacts to Cloud Storage using GCSFuse.
|
||||
- Create a `Vertex AI Model` resource.
|
||||
|
||||
[Get Started with AutoML Training](get_started_automl_training.ipynb)
|
||||
[Get started with Vertex AI Training for XGBoost](community/ml_ops/stage2/get_started_vertex_training_xgboost.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Training` for training a XGBoost custom model.
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Train an image model.
|
||||
- Export the image model as an edge model.
|
||||
- Train a tabular model.
|
||||
- Export the tabular model as a cloud model.
|
||||
- Train a text model.
|
||||
```
|
||||
- Training using a Python package.
|
||||
- Report accuracy when hyperparameter tuning.
|
||||
- Save the model artifacts to Cloud Storage using GCSFuse.
|
||||
- Create a `Vertex AI Model` resource.
|
||||
|
||||
[Get Started with BQML Training](get_started_bqml_training.ipynb)
|
||||
[Get started with TabNet builtin algorithm for training tabular models](community/ml_ops/stage2/get_started_with_tabnet.ipynb)
|
||||
|
||||
In this notebook, you learn how to run `Vertex AI TabNet` built algorithm for training custom tabular models.
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Create a local BigQuery table in your project
|
||||
- Train a BQML model
|
||||
- Evaluate the BQML model
|
||||
- Export the BQML model as a cloud model
|
||||
- Upload the exported model as a `Vertex AI Model` resource
|
||||
- Hyperparameter tune a BQML model with `Vertex AI Vizier`
|
||||
- Automatically register a BQML model to `Vertex AI Model Registry`
|
||||
```
|
||||
- Get the training data.
|
||||
- Configure training parameters for the `Vertex AI TabNet` container.
|
||||
- Train the model using `Vertex AI Training` using CSV data.
|
||||
- Upload the model as a `Vertex AI Model` resource.
|
||||
- Deploy the `Vertex AI Model` resource to a `Vertex AI Endpoint` resource.
|
||||
- Make a prediction with the deployed model.
|
||||
- Hyperparameter tuning the `Vertex AI TabNet` model.
|
||||
- Train the model using `Vertex AI Training` using BigQuery table.
|
||||
|
||||
[Get Started with Vertex Feature Store](get_started_vertex_feature_store.ipynb)
|
||||
[Get started with prebuilt TFHub models](community/ml_ops/stage2/get_started_with_tfhub_models.ipynb)
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
In this tutorial, you learn how to use `Vertex AI Training` with prebuilt models from TensorFlow Hub.
|
||||
|
||||
- Creating a Vertex AI `Featurestore` resource.
|
||||
- Creating `EntityType` resources for the `Featurestore` resource.
|
||||
- Creating `Feature` resources for each `EntityType` resource.
|
||||
- Import feature values (entity data items) into `Featurestore` resource from Cloud Storage.
|
||||
- Import feature values (entity data items) into `Featurestore` resource from pandas DataFrame.
|
||||
- Perform online serving from a `Featurestore` resource.
|
||||
- Perform batch serving from a `Featurestore` resource.
|
||||
```
|
||||
|
||||
[Get Started with Google CMEK Training](get_started_with_cmek_training.ipynb)
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Creating a customer managed encryption key.
|
||||
- Creating an image dataset with CMEK encryption.
|
||||
- Train an AutoML model with CMEK encryption.
|
||||
```
|
||||
|
||||
[Get Started with TensorFlow Hub models](get_started_with_tfhub_models.ipynb)
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Download a TensorFlow Hub prebuilt model.
|
||||
@@ -199,35 +111,206 @@ The steps performed include:
|
||||
- Get model architecture from TensorFlow Hub
|
||||
- Train then model
|
||||
- Save model artifacts and upload as Vertex AI Model resource.
|
||||
```
|
||||
|
||||
[Get Started with Vertex AI TabNet builtin algorithm](get_started_with_tabnet.ipynb)
|
||||
```
|
||||
[Get started with BigQuery ML Training](community/ml_ops/stage2/get_started_bqml_training.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `BigQueryML` (BQML) for training with `Vertex AI`.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Get the training data.
|
||||
- Configure training parameters for the Vertex AI TabNet container.
|
||||
- Train the model using Vertex AI Training using CSV data.
|
||||
- Upload the model as a Vertex AI Model resource.
|
||||
- Deploy the Vertex AI Model resource to a Vertex AI Endpoint resource.
|
||||
- Make a prediction with the deployed model.
|
||||
- Hyperparameter tuning the Vertex AI TabNet model.
|
||||
- Train the model using Vertex AI Training using BigQuery table.
|
||||
```
|
||||
[Get Started with Vertex AI TabNet builtin algorithm](get_started_with_tabnet.ipynb)
|
||||
```
|
||||
- Create a local BigQuery table in your project
|
||||
- Train a BQML model
|
||||
- Evaluate the BQML model
|
||||
- Export the BQML model as a cloud model
|
||||
- Upload the exported model as a `Vertex AI Model` resource
|
||||
- Hyperparameter tune a BQML model with `Vertex AI Vizier`
|
||||
- Automatically register a BQML model to `Vertex AI Model Registry`
|
||||
|
||||
[Get started with Vertex AI Vizier](community/ml_ops/stage2/get_started_vertex_vizier.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Vizier` for when training with `Vertex AI`.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Get the training data.
|
||||
- Configure training parameters for the Vertex AI TabNet container.
|
||||
- Train the model using Vertex AI Training using CSV data.
|
||||
- Upload the model as a Vertex AI Model resource.
|
||||
- Deploy the Vertex AI Model resource to a Vertex AI Endpoint resource.
|
||||
- Make a prediction with the deployed model.
|
||||
- Hyperparameter tuning the Vertex AI TabNet model.
|
||||
- Train the model using Vertex AI Training using BigQuery table.
|
||||
```
|
||||
- Hyperparameter tuning with Random algorithm.
|
||||
- Hyperparameter tuning with Vizier (Bayesian) algorithm.
|
||||
- Suggesting trials and updating results for Vizier study
|
||||
|
||||
[Get started with distributed training using DASK](community/ml_ops/stage2/get_started_with_distributed_training_xgboost.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Training` for distributed training of XGBoost model using the OSS package DASK. Additionally, you learn to construct and deploy a custom serving container using a Flask web server.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Construct an XGBoost training script using DASK for distributed training.
|
||||
- Construct a custom training container.
|
||||
- Configure a distributed custom training job.
|
||||
- Execute the custom training job.
|
||||
- Construct a custom serving container using Flask.
|
||||
- Upload the trained XGBoost model as a `Vertex AI Model` resource.
|
||||
- Create a `Vertex AI Endpoint` resource.
|
||||
- Deploy the `Vertex AI Model` resource to `Vertex AI Endpoint` resource.
|
||||
- Make a prediction.
|
||||
|
||||
[Get started with Vertex AI TensorBoard](community/ml_ops/stage2/get_started_vertex_tensorboard.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI TensorBoard` when training with `Vertex AI`.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Create a TensorBoard callback when training a model.
|
||||
- Using TensorBoard with locally trained model.
|
||||
- Using Vertex AI TensorBoard with Vertex AI Training.
|
||||
|
||||
[Get started with Vertex AI Training for R using R Kernel](community/ml_ops/stage2/get_started_vertex_training_r_using_r_kernel.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI`, using an R kernel, for training and deploying an R custom model.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Create a custom R training script
|
||||
- Create a custom R serving script
|
||||
- Create a custom R deployment (serving) container.
|
||||
- Train the model using `Vertex AI` custom training.
|
||||
- Create an `Endpoint` resouce.
|
||||
- Deploy the `Model` resource (trained R model) to the `Endpoint` resource.
|
||||
- Make an online prediction.
|
||||
|
||||
|
||||
[Get started Vision API test preprocessing and AutoML text model generation](community/ml_ops/stage2/get_started_with_visionapi_and_automl.ipynb)
|
||||
|
||||
In this tutorial, you create an `AutoML` text entity extraction model pre-existing extracted data by generating a custom import file. You deploy this mode for online prediction from a Python script using the `BigQuery`, `Vision AI`, Cloud Storage and `Vertex AI SDK` for Python.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Preprocess training files using `Vision AI` APIs to extract the text from PDF files.
|
||||
- Create a custom import file that includes annotation data based on the sample `BigQuery` dataset.
|
||||
- Create a `Vertex AI Dataset` resource.
|
||||
- Train the model.
|
||||
- View the model evaluation.
|
||||
- Deploy the `Vertex AI Model` resource to a serving `Endpoint` resource.
|
||||
- Make a prediction.
|
||||
- Undeploy the `Model`.
|
||||
|
||||
[Get started with Vertex AI Experiments](community/ml_ops/stage2/get_started_vertex_experiments.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Experiments` when training with `Vertex AI`.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Local (notebook) Training
|
||||
- Create an experiment
|
||||
- Create a first run in the experiment
|
||||
- Log parameters and metrics
|
||||
- Create artifact lineage
|
||||
- Visualize the experiment results
|
||||
- Execute a second run
|
||||
- Compare the two runs in the experiment
|
||||
- Cloud (`Vertex AI`) Training
|
||||
- Within the training script:
|
||||
- Create an experiment
|
||||
- Log parameters and metrics
|
||||
- Create artifact lineage
|
||||
- Create a `Vertex AI Training` custom job
|
||||
- Execute the custom job
|
||||
- Visualize the experiment results
|
||||
|
||||
[AutoML Image Classfication Training with Customer Managed Encryption Keys (CMEK)](community/ml_ops/stage2/get_started_with_cmek_training.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use a customer managed encryption key (CMEK) for `Vertex AI AutoML` training.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Creating a customer managed encryption key.
|
||||
- Creating an image dataset with CMEK encryption.
|
||||
- Train an AutoML model with CMEK encryption.
|
||||
|
||||
[Get started with Vertex AI Feature Store](community/ml_ops/stage2/get_started_vertex_feature_store.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Feature Store` when training and predicting with `Vertex AI`.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Creating a Vertex AI `Featurestore` resource.
|
||||
- Creating `EntityType` resources for the `Featurestore` resource.
|
||||
- Creating `Feature` resources for each `EntityType` resource.
|
||||
- Import feature values (entity data items) into `Featurestore` resource.
|
||||
- From a Cloud Storage location.
|
||||
- From a pandas DataFrame.
|
||||
- Perform online serving from a `Featurestore` resource.
|
||||
- Perform batch serving from a `Featurestore` resource.
|
||||
|
||||
[Get started with AutoML Training](community/ml_ops/stage2/get_started_automl_training.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `AutoML` for training with `Vertex AI`.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Train an image model
|
||||
- Export the image model as an edge model
|
||||
- Train a tabular model
|
||||
- Export the tabular model as a cloud model
|
||||
- Train a text model
|
||||
- Train a video model
|
||||
|
||||
[Get started with Vertex AI Training for LightGBM](community/ml_ops/stage2/get_started_vertex_training_lightgbm.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Training` for training a LightGBM custom model.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Training using a Python package.
|
||||
- Save the model artifacts to Cloud Storage using GCSFuse.
|
||||
- Construct a FastAPI prediction server.
|
||||
- Construct a Dockerfile deployment image.
|
||||
- Test the deployment image locally.
|
||||
- Create a `Vertex AI Model` resource.
|
||||
|
||||
[Get started with Vertex AI Training for Scikit-Learn](community/ml_ops/stage2/get_started_vertex_training_sklearn.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Training` for training a Scikit-Learn custom model.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Training using a Python package.
|
||||
- Report accuracy when hyperparameter tuning.
|
||||
- Save the model artifacts to Cloud Storage using GCSFuse.
|
||||
- Create a `Vertex AI Model` resource.
|
||||
|
||||
[Get started with Vertex AI Training](community/ml_ops/stage2/get_started_vertex_training.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Training` for custom models when training with `Vertex AI`.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Training using a single Python script.
|
||||
- Training using a Python package.
|
||||
- Training using a custom training image.
|
||||
- Laying out a training package.
|
||||
|
||||
|
||||
[Get started with Vertex AI Training for Pytorch](community/ml_ops/stage2/get_started_vertex_training_pytorch.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Training` for training a Pytorch custom model.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- Single node training using a Python package.
|
||||
- Report accuracy when hyperparameter tuning.
|
||||
- Save the model artifacts to Cloud Storage using GCSFuse.
|
||||
- Create a `Vertex AI Model` resource.
|
||||
|
||||
[Get started with Vertex AI Distributed Training](community/ml_ops/stage2/get_started_vertex_distributed_training.ipynb)
|
||||
|
||||
In this tutorial, you learn how to use `Vertex AI Distributed Training` for when training with `Vertex AI`.
|
||||
|
||||
The steps performed include:
|
||||
|
||||
- `MirroredStrategy`: Train on a single VM with multiple GPUs.
|
||||
- `MultiWorkerMirroredStrategy`: Train on multiple VMs with automatic setup of replicas.
|
||||
- `MultiWorkerMirroredStrategy`: Train on multiple VMs with fine grain control of replicas.
|
||||
- `ReductionServer`: Train on multiple VMS and sync updates across VMS with `Vertex AI Reduction Server`.
|
||||
- `TPUTraining`: Train with multiple Cloud TPUs.
|
||||
|
||||
### E2E Stage Example
|
||||
|
||||
@@ -235,7 +318,6 @@ The steps performed include:
|
||||
|
||||
```
|
||||
The steps performed include:
|
||||
|
||||
- Review the `Dataset` resource created during stage 1.
|
||||
- Train an AutoML tabular binary classifier model in the background.
|
||||
- Build the experimental model architecture.
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_automl_training.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\\\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_automl_training.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_automl_training.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -65,52 +65,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with AutoML Training."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:flowers,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Datasets\n",
|
||||
"\n",
|
||||
"#### Image\n",
|
||||
"\n",
|
||||
"The image dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the type of flower in a given image from a class of five flowers: daisy, dandelion, rose, sunflower, or tulip."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:gsod,lrg"
|
||||
},
|
||||
"source": [
|
||||
"#### Tabular\n",
|
||||
"\n",
|
||||
"The tabular dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). The version of the dataset you use only the fields year, month and day to predict the value of mean daily temperature (mean_temp)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:happydb,tcn"
|
||||
},
|
||||
"source": [
|
||||
"#### Text\n",
|
||||
"\n",
|
||||
"The text dataset used for this tutorial is the [Happy Moments dataset](https://www.kaggle.com/ritresearch/happydb) from [Kaggle Datasets](https://www.kaggle.com/ritresearch/happydb). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "98eb93ec6faa"
|
||||
},
|
||||
"source": [
|
||||
"#### Video\n",
|
||||
"\n",
|
||||
"The video dataset used for this tutorial is the golf swing recognition portion of the [Human Motion dataset](https://todo) from [MIT](http://cbcl.mit.edu/publications/ps/Kuehne_etal_iccv11.pdf). The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model will predict the start frame where a golf swing begins."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -124,6 +78,7 @@
|
||||
"This tutorial uses the following Google Cloud ML services:\n",
|
||||
"\n",
|
||||
"- `AutoML Training`\n",
|
||||
"- `Vertex AI Datasets`\n",
|
||||
"\n",
|
||||
"The steps performed include:\n",
|
||||
"\n",
|
||||
@@ -150,6 +105,31 @@
|
||||
"* **You want to establish a baseline metric before experimenting with a custom model**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:flowers,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Datasets\n",
|
||||
"\n",
|
||||
"#### Image\n",
|
||||
"\n",
|
||||
"The image dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the type of flower in a given image from a class of five flowers: daisy, dandelion, rose, sunflower, or tulip.\n",
|
||||
"\n",
|
||||
"#### Tabular\n",
|
||||
"\n",
|
||||
"The tabular dataset used for this tutorial is the GSOD dataset from [BigQuery public datasets](https://cloud.google.com/bigquery/public-data). The version of the dataset you use only the fields year, month and day to predict the value of mean daily temperature (mean_temp).\n",
|
||||
"\n",
|
||||
"#### Text\n",
|
||||
"\n",
|
||||
"The text dataset used for this tutorial is the [Happy Moments dataset](https://www.kaggle.com/ritresearch/happydb) from [Kaggle Datasets](https://www.kaggle.com/ritresearch/happydb). The version of the dataset you use in this tutorial is stored in a public Cloud Storage bucket.\n",
|
||||
"\n",
|
||||
"#### Video\n",
|
||||
"\n",
|
||||
"The video dataset used for this tutorial is the golf swing recognition portion of the [Human Motion dataset](https://todo) from [MIT](http://cbcl.mit.edu/publications/ps/Kuehne_etal_iccv11.pdf). The version of the dataset you use in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the start frame where a golf swing begins."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -173,7 +153,7 @@
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"\n",
|
||||
"Install the following packages for executing the MLOps notebooks."
|
||||
"Install the packages required for executing this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -186,16 +166,21 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG\n",
|
||||
"! pip3 install --upgrade google-cloud-storage $USER_FLAG"
|
||||
"# Install the packages\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG -q\n",
|
||||
"! pip3 install --upgrade google-cloud-storage $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -233,6 +218,8 @@
|
||||
"id": "project_id"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
@@ -248,8 +235,15 @@
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "5aee4379e8e5"
|
||||
},
|
||||
"source": [
|
||||
"#### Set your project ID\n",
|
||||
"\n",
|
||||
"**If you don't know your project ID**, you may be able to get your project ID using `gcloud`."
|
||||
@@ -358,7 +352,7 @@
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Google Cloud Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
@@ -393,9 +387,13 @@
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Google Cloud Notebook, then don't execute this code\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
@@ -501,7 +499,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"id": "import_aip:mbsdk"
|
||||
},
|
||||
@@ -571,6 +569,142 @@
|
||||
"Learn more about [AutoML Model Types](https://cloud.google.com/vertex-ai/docs/start/automl-model-types)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "data_preparation:image,u_dataset"
|
||||
},
|
||||
"source": [
|
||||
"### Data preparation\n",
|
||||
"\n",
|
||||
"The Vertex `Dataset` resource for images has some requirements for your data:\n",
|
||||
"\n",
|
||||
"- Images must be stored in a Cloud Storage bucket.\n",
|
||||
"- Each image file must be in an image format (PNG, JPEG, BMP, ...).\n",
|
||||
"- There must be an index file stored in your Cloud Storage bucket that contains the path and label for each image.\n",
|
||||
"- The index file must be either CSV or JSONL.\n",
|
||||
"\n",
|
||||
"Learn more about [Preparing image data](https://cloud.google.com/vertex-ai/docs/datasets/prepare-image)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "data_import_format:icn,u_dataset,csv"
|
||||
},
|
||||
"source": [
|
||||
"#### CSV\n",
|
||||
"\n",
|
||||
"For image classification, the CSV index file has the requirements:\n",
|
||||
"\n",
|
||||
"- No heading.\n",
|
||||
"- First column is the Cloud Storage path to the image.\n",
|
||||
"- Second column is the label.\n",
|
||||
"- Any remaining columns are additional labels for multi-label image classification.\n",
|
||||
"\n",
|
||||
"For image object detection, the CSV index file has the requirements:\n",
|
||||
"\n",
|
||||
"- No heading.\n",
|
||||
"- First column is the Cloud Storage path to the image.\n",
|
||||
"- Second column is the label.\n",
|
||||
"- Third/Fourth columns are the upper left corner of bounding box. Coordinates are normalized, between 0 and 1.\n",
|
||||
"- Fifth/Sixth/Seventh columns are not used and should be 0.\n",
|
||||
"- Eighth/Ninth columns are the lower right corner of the bounding box.\n",
|
||||
"\n",
|
||||
"##### ML_USE\n",
|
||||
"\n",
|
||||
"Each row may additionally specify which split to assign the data item to when the dataset is split for training; otherwise, the dataset will be randomly split: 80/10/10.\n",
|
||||
"\n",
|
||||
"The `ml_use` assignment is specified by prepending a column for specifying the assignment -- as the first column. The value may be one of: training, test, or validation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "data_import_format:isg,u_dataset,jsonl"
|
||||
},
|
||||
"source": [
|
||||
"#### JSONL\n",
|
||||
"\n",
|
||||
"For image classification, the JSONL index file has the requirements:\n",
|
||||
"\n",
|
||||
"- Each data item is a separate JSON object, on a separate line.\n",
|
||||
"- The key/value pair `image_gcs_uri` is the Cloud Storage path to the image.\n",
|
||||
"- The key/value pair `display_name` is the label for the image.\n",
|
||||
"\n",
|
||||
" { 'image_gcs_uri': image, \n",
|
||||
" 'classification_annotations': \n",
|
||||
" { 'display_name': label\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
"For multi-label, the labels are specified as a list of `display_name` key/value pairs:\n",
|
||||
"\n",
|
||||
" { 'image_gcs_uri': image, \n",
|
||||
" 'classification_annotations': [\n",
|
||||
" { 'display_name': label1\n",
|
||||
" },\n",
|
||||
" { 'display_name': labelN\n",
|
||||
" },\n",
|
||||
" ]\n",
|
||||
" }\n",
|
||||
" \n",
|
||||
"For object detection, the JSONL index file has the requirements:\n",
|
||||
"\n",
|
||||
"- Each data item is a separate JSON object, on a separate line.\n",
|
||||
"- The key/value pair `image_gcs_uri` is the Cloud Storage path to the image.\n",
|
||||
"- The key/value pair `bounding_box_annotations` is a list of:\n",
|
||||
" - `display_name`: The label of the object\n",
|
||||
" - `x_min`, `y_min`, `x_max`, `y_max`: The coordinates for the bounding box\n",
|
||||
"\n",
|
||||
"{\n",
|
||||
" \"image_gcs_uri\": image,\n",
|
||||
" \"bounding_box_annotations\": [\n",
|
||||
" {\n",
|
||||
" \"display name\": label,\n",
|
||||
" \"x_min\": \"X_MIN\",\n",
|
||||
" \"y_min\": \"Y_MIN\",\n",
|
||||
" \"x_max\": \"X_MAX\",\n",
|
||||
" \"y_max\": \"Y_MAX\"\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" {\n",
|
||||
" \"displayName\": \"OBJECT2_LABEL\",\n",
|
||||
" \"x_min\": \"X_MIN\",\n",
|
||||
" \"y_min\": \"Y_MIN\",\n",
|
||||
" \"x_max\": \"X_MAX\",\n",
|
||||
" \"y_max\": \"Y_MAX\"\n",
|
||||
" }\n",
|
||||
" ]\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"For image segmentation, the JSONL index file has the requirements:\n",
|
||||
"\n",
|
||||
"- Each data item is a separate JSON object, on a separate line.\n",
|
||||
"- The key/value pair `image_gcs_uri` is the Cloud Storage path to the image.\n",
|
||||
"- The key/value pair `category_mask_uri` is the Cloud Storage path to the mask image in PNG format.\n",
|
||||
"- The key/value pair `'annotation_spec_colors'` is a list mapping mask colors to a label.\n",
|
||||
" - The key/value pair pair `display_name` is the label for the pixel color mask.\n",
|
||||
" - The key/value pair pair `color` are the RGB normalized pixel values (between 0 and 1) of the mask for the corresponding label.\n",
|
||||
"\n",
|
||||
" { 'image_gcs_uri': image, \n",
|
||||
" 'segmentation_annotations': { 'category_mask_uri': mask_image, 'annotation_spec_colors' : [ \n",
|
||||
" { 'display_name': label, 'color': {\"red\": value, \"blue\", value, \"green\": value} }, ...\n",
|
||||
" ] \n",
|
||||
" }\n",
|
||||
" \n",
|
||||
"##### ML_USE\n",
|
||||
"\n",
|
||||
"Each JSONL object may additionally specify which split to assign the data item to when the dataset is split for training; otherwise, the dataset will be randomly split: 80/10/10.\n",
|
||||
"\n",
|
||||
"\"data_item_resource_labels\": {\n",
|
||||
" \"aiplatform.googleapis.com/ml_use\": \"training|test|validation\"\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"*Note*: The dictionary key fields may alternatively be in camelCase. For example, 'image_gcs_uri' can also be 'imageGcsUri'."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -762,9 +896,8 @@
|
||||
},
|
||||
"source": [
|
||||
"## Review model evaluation scores\n",
|
||||
"After your model training has finished, you can review the evaluation scores for it.\n",
|
||||
"\n",
|
||||
"First, you need to get a reference to the new model. As with datasets, you can either use the reference to the model variable you created when you deployed the model or you can list all of the models in your project."
|
||||
"After your model training has finished, you can review the evaluation scores for it using the `list_model_evaluations()` method. This method will return an iterator for each evaluation slice."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -775,20 +908,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Get model resource ID\n",
|
||||
"models = aiplatform.Model.list(filter=\"display_name=flowers_\" + TIMESTAMP)\n",
|
||||
"model_evaluations = model.list_model_evaluations()\n",
|
||||
"\n",
|
||||
"# Get a reference to the Model Service client\n",
|
||||
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
|
||||
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
|
||||
" client_options=client_options\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"model_evaluations = model_service_client.list_model_evaluations(\n",
|
||||
" parent=models[0].resource_name\n",
|
||||
")\n",
|
||||
"model_evaluation = list(model_evaluations)[0]\n",
|
||||
"print(model_evaluation)"
|
||||
"for model_evaluation in model_evaluations:\n",
|
||||
" print(model_evaluation.to_dict())"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1082,6 +1205,42 @@
|
||||
"Learn more about [AutoML Model Types](https://cloud.google.com/vertex-ai/docs/start/automl-model-types)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "data_preparation:tabular,u_dataset"
|
||||
},
|
||||
"source": [
|
||||
"### Data preparation\n",
|
||||
"\n",
|
||||
"The Vertex AI `Dataset` resource for tabular has a couple of requirements for your tabular data.\n",
|
||||
"\n",
|
||||
"- Must be in a CSV file or a BigQuery table.\n",
|
||||
"\n",
|
||||
"Learn more about [Preparing tabular data](https://cloud.google.com/vertex-ai/docs/datasets/prepare-tabular)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "data_import_format:lbn,u_dataset,csv"
|
||||
},
|
||||
"source": [
|
||||
"#### CSV\n",
|
||||
"\n",
|
||||
"For tabular models, the CSV file has a few requirements:\n",
|
||||
"\n",
|
||||
"- The first row must be the heading -- note how this is different from Image, Text and Video where the requirement is no heading.\n",
|
||||
"- All but one column are features.\n",
|
||||
"- One column is the label, which you will specify when you subsequently create the training pipeline.\n",
|
||||
"\n",
|
||||
"##### ML_USE\n",
|
||||
"\n",
|
||||
"Each row may additionally specify which split to assign the data item to when the dataset is split for training; otherwise, the dataset will be randomly split: 80/10/10.\n",
|
||||
"\n",
|
||||
"The `ml_use` assignment is specified by prepending a column for specifying the assignment -- as the first column. The value may be one of: training, test, or validation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -1263,9 +1422,8 @@
|
||||
},
|
||||
"source": [
|
||||
"## Review model evaluation scores\n",
|
||||
"After your model has finished training, you can review the evaluation scores for it.\n",
|
||||
"\n",
|
||||
"First, you need to get a reference to the new model. As with datasets, you can either use the reference to the model variable you created when you deployed the model or you can list all of the models in your project."
|
||||
"After your model training has finished, you can review the evaluation scores for it using the `list_model_evaluations()` method. This method will return an iterator for each evaluation slice."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1276,20 +1434,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Get model resource ID\n",
|
||||
"models = aiplatform.Model.list(filter=\"display_name=gsod_\" + TIMESTAMP)\n",
|
||||
"model_evaluations = model.list_model_evaluations()\n",
|
||||
"\n",
|
||||
"# Get a reference to the Model Service client\n",
|
||||
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
|
||||
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
|
||||
" client_options=client_options\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"model_evaluations = model_service_client.list_model_evaluations(\n",
|
||||
" parent=models[0].resource_name\n",
|
||||
")\n",
|
||||
"model_evaluation = list(model_evaluations)[0]\n",
|
||||
"print(model_evaluation)"
|
||||
"for model_evaluation in model_evaluations:\n",
|
||||
" print(model_evaluation.to_dict())"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1452,6 +1600,155 @@
|
||||
"Learn more about [AutoML Model Types](https://cloud.google.com/vertex-ai/docs/start/automl-model-types)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "data_preparation:text,u_dataset"
|
||||
},
|
||||
"source": [
|
||||
"### Data preparation\n",
|
||||
"\n",
|
||||
"The Vertex AI `Dataset` resource for text has a couple of requirements for your text data.\n",
|
||||
"\n",
|
||||
"- Text examples must be stored in a CSV or JSONL file.\n",
|
||||
"\n",
|
||||
"Learn more about [Preparing text data](https://cloud.google.com/vertex-ai/docs/datasets/prepare-text)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "data_import_format:tcn,u_dataset,csv"
|
||||
},
|
||||
"source": [
|
||||
"#### CSV\n",
|
||||
"\n",
|
||||
"For text classification, the CSV file has a few requirements:\n",
|
||||
"\n",
|
||||
"- No heading.\n",
|
||||
"- First column is the text example or Cloud Storage path to text file (.txt suffix).\n",
|
||||
"- Second column the label.\n",
|
||||
"- Any remaining columns are additional labels for multi-label text classification.\n",
|
||||
"\n",
|
||||
"For text sentiment analysis, the CSV file has a few requirements:\n",
|
||||
"\n",
|
||||
"- No heading.\n",
|
||||
"- First column is the text example or Cloud Storage path to text file (.txt suffix).\n",
|
||||
"- Second column is the sentiment value.\n",
|
||||
"- Third column is the maximum possible sentiment value.\n",
|
||||
"\n",
|
||||
"##### ML_USE\n",
|
||||
"\n",
|
||||
"Each row may additionally specify which split to assign the data item to when the dataset is split for training; otherwise, the dataset will be randomly split: 80/10/10.\n",
|
||||
"\n",
|
||||
"The `ml_use` assignment is specified by prepending a column for specifying the assignment -- as the first column. The value may be one of: training, test, or validation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "766c838de8a0"
|
||||
},
|
||||
"source": [
|
||||
"#### JSONL \n",
|
||||
"\n",
|
||||
"For text classification, the JSONL file has a few requirements:\n",
|
||||
"\n",
|
||||
"- Each data item is a separate JSON object, on a separate line.\n",
|
||||
"- The key/value pair `text_gcs_uri` is the Cloud Storage path to the text file.\n",
|
||||
"- The key/value pair `text_content` is the alternate way of specifying the text as inlined.\n",
|
||||
"- The key/value pair `display_name` is the label for the text.\n",
|
||||
"\n",
|
||||
"{\n",
|
||||
" \"classification_annotation\": {\n",
|
||||
" \"display_name\": label\n",
|
||||
" },\n",
|
||||
" \"text_content\": text\n",
|
||||
"}\n",
|
||||
"{\n",
|
||||
" \"classification_annotation\": {\n",
|
||||
" \"display_name\": label\n",
|
||||
" },\n",
|
||||
" \"text_gcs_uri\": \"gcs_uri_to_file\"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"For multi-label, the labels are specified as a list of `display_name` key/value pairs:\n",
|
||||
"\n",
|
||||
" 'classification_annotations': [\n",
|
||||
" { 'display_name': label1\n",
|
||||
" },\n",
|
||||
" { 'display_name': labelN\n",
|
||||
" },\n",
|
||||
" ]\n",
|
||||
"\n",
|
||||
"For text sentiment analysis, the JSONL file has a few requirements:\n",
|
||||
"\n",
|
||||
"- Each data item is a separate JSON object, on a separate line.\n",
|
||||
"- The key/value pair `text_gcs_uri` is the Cloud Storage path to the text file.\n",
|
||||
"- The key/value pair `text_content` is the alternate way of specifying the text as inlined.\n",
|
||||
"- The key/value pair `sentiment` is the sentiment value as an integer value greater than 0.\n",
|
||||
"- The key/value pair `sentiment_max`is the maximum possible value for the sentiment.\n",
|
||||
"\n",
|
||||
"{\n",
|
||||
" \"sentiment_annotation\": {\n",
|
||||
" \"sentiment\": number,\n",
|
||||
" \"sentiment_max\": number\n",
|
||||
" },\n",
|
||||
" \"text_content\": text,\n",
|
||||
"}\n",
|
||||
"{\n",
|
||||
" \"sentiment_annotation\": {\n",
|
||||
" \"sentiment\": number,\n",
|
||||
" \"sentiment_max\": number\n",
|
||||
" },\n",
|
||||
" \"text_gcs_uri\": \"gcs_uri_to_file\"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"For text entity extraction, the JSONL file has a few requirements:\n",
|
||||
"\n",
|
||||
"- Each data item is a separate JSON object, on a separate line.\n",
|
||||
"- The key/value pair `text_gcs_uri` is the Cloud Storage path to the text file.\n",
|
||||
"- The key/value pair `text_content` is the alternate way of specifying the text as inlined.\n",
|
||||
"- The key/value pair `start_offset` is the character offset of the start of the text.\n",
|
||||
"- The key/value pair `end_offset` is the character offset of the end of the text.\n",
|
||||
"- The key/value pair `display_name` is the label for the text.\n",
|
||||
"\n",
|
||||
"{\n",
|
||||
" \"text_segment_annotations\": [\n",
|
||||
" {\n",
|
||||
" \"start_offset\":number,\n",
|
||||
" \"end_offset\":number,\n",
|
||||
" \"display_name\": label\n",
|
||||
" },\n",
|
||||
" ...\n",
|
||||
" ],\n",
|
||||
" \"textContent\": \"inline_text\"\n",
|
||||
"}\n",
|
||||
"{\n",
|
||||
" \"textSegmentAnnotations\": [\n",
|
||||
" {\n",
|
||||
" \"start_offset\": number,\n",
|
||||
" \"end_offset\": number,\n",
|
||||
" \"displayName\": label\n",
|
||||
" },\n",
|
||||
" ...\n",
|
||||
" ],\n",
|
||||
" \"text_gcs_uri\": \"gcs_uri_to_file\"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"##### ML_USE\n",
|
||||
"\n",
|
||||
"Each JSONL object may additionally specify which split to assign the data item to when the dataset is split for training; otherwise, the dataset will be randomly split: 80/10/10.\n",
|
||||
"\n",
|
||||
"\"data_item_resource_labels\": {\n",
|
||||
" \"aiplatform.googleapis.com/ml_use\": \"training|test|validation\"\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"*Note*: The dictionary key fields may alternatively be in camelCase. For example, 'text_gcs_uri' can also be 'textGcsUri'."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -1627,9 +1924,8 @@
|
||||
},
|
||||
"source": [
|
||||
"## Review model evaluation scores\n",
|
||||
"After your model has finished training, you can review the evaluation scores for it.\n",
|
||||
"\n",
|
||||
"First, you need to get a reference to the new model. As with datasets, you can either use the reference to the model variable you created when you deployed the model or you can list all of the models in your project."
|
||||
"After your model training has finished, you can review the evaluation scores for it using the `list_model_evaluations()` method. This method will return an iterator for each evaluation slice."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1640,20 +1936,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Get model resource ID\n",
|
||||
"models = aiplatform.Model.list(filter=\"display_name=happydb_\" + TIMESTAMP)\n",
|
||||
"model_evaluations = model.list_model_evaluations()\n",
|
||||
"\n",
|
||||
"# Get a reference to the Model Service client\n",
|
||||
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
|
||||
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
|
||||
" client_options=client_options\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"model_evaluations = model_service_client.list_model_evaluations(\n",
|
||||
" parent=models[0].resource_name\n",
|
||||
")\n",
|
||||
"model_evaluation = list(model_evaluations)[0]\n",
|
||||
"print(model_evaluation)"
|
||||
"for model_evaluation in model_evaluations:\n",
|
||||
" print(model_evaluation.to_dict())"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1785,6 +2071,144 @@
|
||||
"Learn more about [AutoML Model Types](https://cloud.google.com/vertex-ai/docs/start/automl-model-types)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "data_preparation:text,u_dataset"
|
||||
},
|
||||
"source": [
|
||||
"### Data preparation\n",
|
||||
"\n",
|
||||
"The Vertex AI `Dataset` resource for text has a couple of requirements for your text data.\n",
|
||||
"\n",
|
||||
"- Text examples must be stored in a CSV or JSONL file.\n",
|
||||
"\n",
|
||||
"Learn more about [Preparing video data](https://cloud.google.com/vertex-ai/docs/datasets/prepare-video)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "427212b48840"
|
||||
},
|
||||
"source": [
|
||||
"#### CSV\n",
|
||||
"\n",
|
||||
"For video classification, the CSV file has a few requirements:\n",
|
||||
"\n",
|
||||
"- No heading.\n",
|
||||
"- First column is the Cloud Storage path to video file.\n",
|
||||
"- Second column the label.\n",
|
||||
"- Third column is the start time (seconds) in the video to classify.\n",
|
||||
"- Fourth column is the end time (seconds) in the video to classify.\n",
|
||||
"\n",
|
||||
"For multi-label classification, each label is a separate row entry.\n",
|
||||
"\n",
|
||||
"For video object tracking, the CSV file has a few requirements:\n",
|
||||
"\n",
|
||||
"- No heading.\n",
|
||||
"- First column is the Cloud Storage path to video file.\n",
|
||||
"- Second column the label.\n",
|
||||
"- Third column is unused (blank).\n",
|
||||
"- Fourth column is the start time (seconds) in the video to start tracking the object.\n",
|
||||
"- The fifth through eighth columns are the vertices of the object to track.\n",
|
||||
" - x_min\n",
|
||||
" - y_min\n",
|
||||
" - x_max\n",
|
||||
" - y_max\n",
|
||||
" \n",
|
||||
"For action recognition, the CSV file has a few requirements:\n",
|
||||
"\n",
|
||||
"- No heading.\n",
|
||||
"- Each row can be one of the following four formats:\n",
|
||||
"\n",
|
||||
"VIDEO_URI, TIME_SEGMENT_START, TIME_SEGMENT_END, LABEL, ANNOTATION_FRAME_TIMESTAMP\n",
|
||||
"\n",
|
||||
"VIDEO_URI, , , LABEL, ANNOTATION_FRAME_TIMESTAMP\n",
|
||||
"\n",
|
||||
"VIDEO_URI, TIME_SEGMENT_START, TIME_SEGMENT_END, LABEL, ANNOTATION_SEGMENT_START, ANNOTATION_SEGMENT_END\n",
|
||||
"\n",
|
||||
"VIDEO_URI, , , LABEL, ANNOTATION_SEGMENT_START, ANNOTATION_SEGMENT_END\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"##### ML_USE\n",
|
||||
"\n",
|
||||
"Each row may additionally specify which split to assign the data item to when the dataset is split for training; otherwise, the dataset will be randomly split: 80/10/10.\n",
|
||||
"\n",
|
||||
"The `ml_use` assignment is specified by prepending a column for specifying the assignment -- as the first column. The value may be one of: training, or test."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "461301339727"
|
||||
},
|
||||
"source": [
|
||||
"#### JSONL\n",
|
||||
"\n",
|
||||
"For video classification, the CSV file has a few requirements:\n",
|
||||
"\n",
|
||||
"- Each data item is a separate JSON object, on a separate line.\n",
|
||||
"- The key/value pair `video_gcs_uri` is the Cloud Storage path to the text file.\n",
|
||||
"- The key/value pair `display_name` is the label for the text.\n",
|
||||
"- The key/value pair `start_time` is the start time (seconds) for classifying.\n",
|
||||
"- The key/value pair `end_time` is the end time (seconds) for classifying.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" {\n",
|
||||
" \"video_gcs_uri\": video,\n",
|
||||
" \"time_segment_annotations\": [{\n",
|
||||
" \"display_name\": label,\n",
|
||||
" \"start_time\": \"start_time_of_segment\",\n",
|
||||
" \"end_time\": \"end_time_of_segment\"\n",
|
||||
" }]\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"For video object tracking, the CSV file has a few requirements:\n",
|
||||
"\n",
|
||||
"- Each data item is a separate JSON object, on a separate line.\n",
|
||||
"- The key/value pair `video_gcs_uri` is the Cloud Storage path to the text file.\n",
|
||||
"\n",
|
||||
" {\n",
|
||||
" \"video_gcs_uri\": video,\n",
|
||||
" \"temporal_bounding_box_annotations\": [{\n",
|
||||
" \"display_name\": label,\n",
|
||||
" \"x_min\": \"leftmost_coordinate_of_the_bounding box\",\n",
|
||||
" \"x_max\": \"rightmost_coordinate_of_the_bounding box\",\n",
|
||||
" \"y_min\": \"topmost_coordinate_of_the_bounding box\",\n",
|
||||
" \"y_max\": \"bottommost_coordinate_of_the_bounding box\",\n",
|
||||
" \"time_offset\": \"timeframe_object-detected\"\n",
|
||||
" }]\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"For video action recognition, the CSV file has a few requirements:\n",
|
||||
"\n",
|
||||
"- Each data item is a separate JSON object, on a separate line.\n",
|
||||
"- The key/value pair `video_gcs_uri` is the Cloud Storage path to the text file.\n",
|
||||
"\n",
|
||||
" {\n",
|
||||
" \"video_gcs_uri': video,\n",
|
||||
" \"time_segments\": [{\n",
|
||||
" \"start_time\": \"start_time_of_fully_annotated_segment\",\n",
|
||||
" \"end_time\": \"end_time_of_segment\"}],\n",
|
||||
" \"time_segment_annotations\": [{\n",
|
||||
" \"display_name\": label,\n",
|
||||
" \"start_time\": \"start_time_of_segment\",\n",
|
||||
" \"end_time\": \"end_time_of_segment\"\n",
|
||||
" }]\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"##### ML_USE\n",
|
||||
"\n",
|
||||
"Each JSONL object may additionally specify which split to assign the data item to when the dataset is split for training; otherwise, the dataset will be randomly split: 80/20.\n",
|
||||
"\n",
|
||||
"\"data_item_resource_labels\": {\n",
|
||||
" \"aiplatform.googleapis.com/ml_use\": \"training|test\"\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"*Note*: The dictionary key fields may alternatively be in camelCase. For example, 'video_gcs_uri' can also be 'videoGcsUri'."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -1954,9 +2378,8 @@
|
||||
},
|
||||
"source": [
|
||||
"## Review model evaluation scores\n",
|
||||
"After your model has finished training, you can review the evaluation scores for it.\n",
|
||||
"\n",
|
||||
"First, you need to get a reference to the new model. As with datasets, you can either use the reference to the model variable you created when you deployed the model or you can list all of the models in your project."
|
||||
"After your model training has finished, you can review the evaluation scores for it using the `list_model_evaluations()` method. This method will return an iterator for each evaluation slice."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1967,20 +2390,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Get model resource ID\n",
|
||||
"models = aiplatform.Model.list(filter=\"display_name=human_motion_\" + TIMESTAMP)\n",
|
||||
"model_evaluations = model.list_model_evaluations()\n",
|
||||
"\n",
|
||||
"# Get a reference to the Model Service client\n",
|
||||
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
|
||||
"model_service_client = aiplatform.gapic.ModelServiceClient(\n",
|
||||
" client_options=client_options\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"model_evaluations = model_service_client.list_model_evaluations(\n",
|
||||
" parent=models[0].resource_name\n",
|
||||
")\n",
|
||||
"model_evaluation = list(model_evaluations)[0]\n",
|
||||
"print(model_evaluation)"
|
||||
"for model_evaluation in model_evaluations:\n",
|
||||
" print(model_evaluation.to_dict())"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -38,8 +38,13 @@
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_bqml_training.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_bqml_training.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_bqml_training.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -60,6 +65,33 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with BigQuery ML Training."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "objective:mlops,stage2,get_started_bqml_training"
|
||||
},
|
||||
"source": [
|
||||
"### Objective\n",
|
||||
"\n",
|
||||
"In this tutorial, you learn how to use `BigQueryML` for training with `Vertex AI`.\n",
|
||||
"\n",
|
||||
"This tutorial uses the following Google Cloud ML services:\n",
|
||||
"\n",
|
||||
"- `BigQueryML Training`\n",
|
||||
"- `Vertex AI Model resource`\n",
|
||||
"- `Vertex AI Vizier`\n",
|
||||
"\n",
|
||||
"The steps performed include:\n",
|
||||
"\n",
|
||||
"- Create a local BigQuery table in your project\n",
|
||||
"- Train a BigQuery ML model\n",
|
||||
"- Evaluate the BigQuery ML model\n",
|
||||
"- Export the BigQuery ML model as a cloud model\n",
|
||||
"- Upload the exported model as a `Vertex AI Model` resource\n",
|
||||
"- Hyperparameter tune a BigQuery ML model with `Vertex AI Vizier`\n",
|
||||
"- Automatically register a BigQuery ML model to `Vertex AI Model Registry`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -74,29 +106,9 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "objective:mlops,stage2,get_started_bqml_training"
|
||||
"id": "81c777b8ad32"
|
||||
},
|
||||
"source": [
|
||||
"### Objective\n",
|
||||
"\n",
|
||||
"In this tutorial, you learn how to use `BigQueryML` (BQML) for training with `Vertex AI`.\n",
|
||||
"\n",
|
||||
"This tutorial uses the following Google Cloud ML services:\n",
|
||||
"\n",
|
||||
"- `BigQueryML Training`\n",
|
||||
"- `Vertex AI Model resource`\n",
|
||||
"- `Vertex AI Vizier`\n",
|
||||
"\n",
|
||||
"The steps performed include:\n",
|
||||
"\n",
|
||||
"- Create a local BigQuery table in your project\n",
|
||||
"- Train a BQML model\n",
|
||||
"- Evaluate the BQML model\n",
|
||||
"- Export the BQML model as a cloud model\n",
|
||||
"- Upload the exported model as a `Vertex AI Model` resource\n",
|
||||
"- Hyperparameter tune a BQML model with `Vertex AI Vizier`\n",
|
||||
"- Automatically register a BQML model to `Vertex AI Model Registry`\n",
|
||||
"\n",
|
||||
"### Costs\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
@@ -128,18 +140,20 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"# Install the packages\n",
|
||||
"! pip3 install --upgrade pyarrow $USER_FLAG\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG\n",
|
||||
"! pip3 install --upgrade google-cloud-bigquery $USER_FLAG"
|
||||
"! pip3 install --upgrade pyarrow \\\n",
|
||||
" google-cloud-aiplatform \\\n",
|
||||
" google-cloud-bigquery \\\n",
|
||||
" google-cloud-bigquery-storage $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -176,6 +190,32 @@
|
||||
"metadata": {
|
||||
"id": "project_id"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI, BigQuery, Compute Engine and Cloud Storage APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,bigquery,compute_component,storage_component).\n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "56d591439df1"
|
||||
},
|
||||
"source": [
|
||||
"#### Set your project ID\n",
|
||||
"\n",
|
||||
@@ -277,6 +317,67 @@
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "f3bd8c0d0469"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"1. **Click Create service account**.\n",
|
||||
"\n",
|
||||
"2. In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"3. In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex AI\" into the filter box, and select **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"4. Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"5. Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "e0953a00668e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -300,7 +401,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
|
||||
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -311,8 +413,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = PROJECT_ID + \"aip-\" + TIMESTAMP\n",
|
||||
" BUCKET_URI = f\"gs://{BUCKET_NAME}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -332,7 +435,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil mb -l $REGION $BUCKET_NAME"
|
||||
"! gsutil mb -l $REGION $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -352,7 +455,55 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_NAME"
|
||||
"! gsutil ls -al $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "set_service_account"
|
||||
},
|
||||
"source": [
|
||||
"#### Service Account\n",
|
||||
"\n",
|
||||
"You use a service account to create Vertex AI Pipeline jobs. If you do not want to use your project's Compute Engine service account, set `SERVICE_ACCOUNT` to another service account ID."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "set_service_account"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"SERVICE_ACCOUNT = \"[your-service-account]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "autoset_service_account"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if (\n",
|
||||
" SERVICE_ACCOUNT == \"\"\n",
|
||||
" or SERVICE_ACCOUNT is None\n",
|
||||
" or SERVICE_ACCOUNT == \"[your-service-account]\"\n",
|
||||
"):\n",
|
||||
" # Get your service account from gcloud\n",
|
||||
" if not IS_COLAB:\n",
|
||||
" shell_output = !gcloud auth list 2>/dev/null\n",
|
||||
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
|
||||
"\n",
|
||||
" if IS_COLAB:\n",
|
||||
" shell_output = ! gcloud projects describe $PROJECT_ID\n",
|
||||
" project_number = shell_output[-1].split(\":\")[1].strip().replace(\"'\", \"\")\n",
|
||||
" SERVICE_ACCOUNT = f\"{project_number}-compute@developer.gserviceaccount.com\"\n",
|
||||
"\n",
|
||||
" print(\"Service Account:\", SERVICE_ACCOUNT)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -395,7 +546,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
|
||||
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -598,9 +749,9 @@
|
||||
"id": "bqml_create_model"
|
||||
},
|
||||
"source": [
|
||||
"### Train BQML model\n",
|
||||
"### Train BigQuery ML model\n",
|
||||
"\n",
|
||||
"Next, you create and train a BQML tabular classification model from the public dataset penguins and store the model in your project using the `CREATE MODEL` statement. The model configuration is specified in the `OPTIONS` statement as follows:\n",
|
||||
"Next, you create and train a BigQuery ML tabular classification model from the public dataset penguins and store the model in your project using the `CREATE MODEL` statement. The model configuration is specified in the `OPTIONS` statement as follows:\n",
|
||||
"\n",
|
||||
"- `model_type`: The type and archictecture of tabular model to train, e.g., DNN classification.\n",
|
||||
"- `labels`: The column which are the labels.\n",
|
||||
@@ -649,9 +800,9 @@
|
||||
"id": "bqml_eval_model"
|
||||
},
|
||||
"source": [
|
||||
"### Evaluate the trained BQML model\n",
|
||||
"### Evaluate the trained BigQuery ML model\n",
|
||||
"\n",
|
||||
"Next, retrieve the model evaluation for the trained BQML model.\n",
|
||||
"Next, retrieve the model evaluation for the trained BigQuery ML model.\n",
|
||||
"\n",
|
||||
"Learn more about [The ML.EVALUATE function](https://cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-evaluate)."
|
||||
]
|
||||
@@ -682,9 +833,9 @@
|
||||
"id": "bqml_export_model"
|
||||
},
|
||||
"source": [
|
||||
"### Export the model from BQML\n",
|
||||
"### Export the model from BigQuery ML\n",
|
||||
"\n",
|
||||
"The model you trained in BQML is a TensorFlow model. Next, you export the TensorFlow model artifacts in TF.SavedModel format."
|
||||
"The model you trained in BigQuery ML is a TensorFlow model. Next, you export the TensorFlow model artifacts in TF.SavedModel format."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -695,10 +846,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"param = f\"{PROJECT_ID}:{BQ_DATASET_NAME}.{MODEL_NAME} {BUCKET_NAME}/{MODEL_NAME}\"\n",
|
||||
"param = f\"{PROJECT_ID}:{BQ_DATASET_NAME}.{MODEL_NAME} {BUCKET_URI}/{MODEL_NAME}\"\n",
|
||||
"! bq extract -m $param\n",
|
||||
"\n",
|
||||
"MODEL_DIR = f\"{BUCKET_NAME}/{BQ_DATASET_NAME}\"\n",
|
||||
"MODEL_DIR = f\"{BUCKET_URI}/{BQ_DATASET_NAME}\"\n",
|
||||
"! gsutil ls $MODEL_DIR"
|
||||
]
|
||||
},
|
||||
@@ -829,7 +980,7 @@
|
||||
"id": "model_delete:mbsdk"
|
||||
},
|
||||
"source": [
|
||||
"#### Delete the model\n",
|
||||
"#### Delete the `Vertex AI Model` resource\n",
|
||||
"\n",
|
||||
"The method 'delete()' deletes the model."
|
||||
]
|
||||
@@ -845,15 +996,41 @@
|
||||
"model.delete()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "7890ae6f6410"
|
||||
},
|
||||
"source": [
|
||||
"### Delete the `BigQuery ML` model\n",
|
||||
"\n",
|
||||
"Next, delete the `BigQuery ML` instance of the model."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "f0b6163e70c0"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MODEL_QUERY = f\"\"\"\n",
|
||||
"DROP MODEL `{BQ_DATASET_NAME}.{MODEL_NAME}`\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"job = bqclient.query(MODEL_QUERY)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "bqml_create_model:vizier"
|
||||
},
|
||||
"source": [
|
||||
"### Hyperparameter Tune and train a BQML model\n",
|
||||
"### Hyperparameter Tune and train a BigQuery ML model\n",
|
||||
"\n",
|
||||
"Next, you train a BQML tabular classification model with hyperparameter tuning using the `Vertex AI Vizier` service. The hyperparameter settings are specified in the `OPTIONS` statement as follows:\n",
|
||||
"Next, you train a BigQuery ML tabular classification model with hyperparameter tuning using the `Vertex AI Vizier` service. The hyperparameter settings are specified in the `OPTIONS` statement as follows:\n",
|
||||
"\n",
|
||||
"- `HPARAM_TUNING_ALGORITHM`: The algorithm for selecting the next trial parameters.\n",
|
||||
"- `num_trials`: The number of trials.\n",
|
||||
@@ -906,9 +1083,9 @@
|
||||
"id": "bqml_eval_model"
|
||||
},
|
||||
"source": [
|
||||
"### Evaluate the BQML trained model\n",
|
||||
"### Evaluate the BigQuery ML trained model\n",
|
||||
"\n",
|
||||
"Next, retrieve the model evaluation results for the trained BQML model.\n",
|
||||
"Next, retrieve the model evaluation results for the trained BigQuery ML model.\n",
|
||||
"\n",
|
||||
"Learn more about [The ML.EVALUATE function](https://cloud.google.com/bigquery-ml/docs/reference/standard-sql/bigqueryml-syntax-evaluate)."
|
||||
]
|
||||
@@ -933,15 +1110,41 @@
|
||||
"print(results)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "3f3cee1236b1"
|
||||
},
|
||||
"source": [
|
||||
"### Delete the `BigQuery ML` model\n",
|
||||
"\n",
|
||||
"Next, delete the `BigQuery ML` instance of the model."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "957b7d841502"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MODEL_QUERY = f\"\"\"\n",
|
||||
"DROP MODEL `{BQ_DATASET_NAME}.{MODEL_NAME}`\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"job = bqclient.query(MODEL_QUERY)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "bqml_create_model:xai"
|
||||
},
|
||||
"source": [
|
||||
"### Train a BQML model with Explainability\n",
|
||||
"### Train a BigQuery ML model with Explainability\n",
|
||||
"\n",
|
||||
"Next, you train the same BQML model, but this time you enable Vertex AI Explainability on the model predictions by adding the option:\n",
|
||||
"Next, you train the same BigQuery ML model, but this time you enable Vertex AI Explainability on the model predictions by adding the option:\n",
|
||||
"\n",
|
||||
"- `ENABLE_GLOBAL_EXPLAIN`"
|
||||
]
|
||||
@@ -985,7 +1188,33 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "1bb996026c94"
|
||||
"id": "4def8aaf3398"
|
||||
},
|
||||
"source": [
|
||||
"### Delete the `BigQuery ML` model\n",
|
||||
"\n",
|
||||
"Next, delete the `BigQuery ML` instance of the model."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "ff5b32618018"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MODEL_QUERY = f\"\"\"\n",
|
||||
"DROP MODEL `{BQ_DATASET_NAME}.{MODEL_NAME}`\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"job = bqclient.query(MODEL_QUERY)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2b4498ca6fea"
|
||||
},
|
||||
"source": [
|
||||
"## Model Registry\n",
|
||||
@@ -994,30 +1223,27 @@
|
||||
"\n",
|
||||
"### Setting permissions to automatically register the model\n",
|
||||
"\n",
|
||||
"You need to set some additional IAM permissions for BigQuery ML to automatically upload and register the model after training. Depending on your service account, the setting of the permissions below may fail. In this case, we recommend executing the permissions in a Cloud Shell."
|
||||
"You need to set some additional IAM permissions for BigQuery ML to automatically upload and register the model after training. Depending on your service account, the setting of the permissions below may fail. In this case, we recommend executing the permissions in a Cloud Shell.\n",
|
||||
"\n",
|
||||
"Learn more about [Setting permissions for Model Registry](https://cloud.google.com/bigquery-ml/docs/managing-models-vertex)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "eaaf24146aad"
|
||||
"id": "29229f72d13d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gcloud projects add-iam-policy-binding $PROJECT_ID \\\n",
|
||||
" --member='serviceAccount:cloud-dataengine@system.gserviceaccount.com' \\\n",
|
||||
" --role='roles/aiplatform.admin'\n",
|
||||
"\n",
|
||||
"! gcloud projects add-iam-policy-binding $PROJECT_ID \\\n",
|
||||
" --member='user:cloud-dataengine@prod.google.com' \\\n",
|
||||
" --role='roles/aiplatform.admin'"
|
||||
" --member=serviceAccount:$SERVICE_ACCOUNT --role=roles/aiplatform.admin --condition=None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "8bfc0b26155f"
|
||||
"id": "6c390ee7c11a"
|
||||
},
|
||||
"source": [
|
||||
"### Training and registering the model\n",
|
||||
@@ -1033,7 +1259,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "3ff1d4ef4df2"
|
||||
"id": "57db464f4c42"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1070,7 +1296,7 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "a243d86f9d22"
|
||||
"id": "5b4970272040"
|
||||
},
|
||||
"source": [
|
||||
"### Find the model in the `Vertex Model Registry`\n",
|
||||
@@ -1082,7 +1308,7 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "4fd9a143d900"
|
||||
"id": "76c22674ba99"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -1092,6 +1318,46 @@
|
||||
"print(model.gca_resource)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "48e6ef5d5ffa"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"models = aiplatform.Model.list()\n",
|
||||
"for model in models:\n",
|
||||
" if model.gca_resource.display_name.startswith(\"bqml\"):\n",
|
||||
" print(model.gca_resource.display_name)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ef61354b1a5f"
|
||||
},
|
||||
"source": [
|
||||
"### Delete the `BigQuery ML` model\n",
|
||||
"\n",
|
||||
"Next, delete the `BigQuery ML` instance of the model."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "f6004d1ce59d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MODEL_QUERY = f\"\"\"\n",
|
||||
"DROP MODEL `{BQ_DATASET_NAME}.{MODEL_NAME}`\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"job = bqclient.query(MODEL_QUERY)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -1103,12 +1369,9 @@
|
||||
"To clean up all Google Cloud resources used in this project, you can [delete the Google Cloud\n",
|
||||
"project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects) you used for the tutorial.\n",
|
||||
"\n",
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial.\n",
|
||||
"\n",
|
||||
"- Model\n",
|
||||
"- Endpoint\n",
|
||||
"- Dataset\n",
|
||||
"- Cloud Storage Bucket"
|
||||
"Set `delete_storage` to `True` to delete the Cloud Storage bucket used in this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1129,11 +1392,13 @@
|
||||
"except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
"if os.getenv(\"IS_TESTING\"):\n",
|
||||
"# Delete the created BigQuery dataset\n",
|
||||
"! bq rm -r -f $PROJECT_ID:$BQ_DATASET_NAME\n",
|
||||
"\n",
|
||||
"delete_storage = False\n",
|
||||
"if delete_storage or os.getenv(\"IS_TESTING\"):\n",
|
||||
" # Delete the created GCS bucket\n",
|
||||
" ! gsutil rm -r $BUCKET_NAME\n",
|
||||
" # Delete the created BigQuery dataset\n",
|
||||
" ! bq rm -r -f $PROJECT_ID:$BQ_DATASET_NAME"
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
"id": "title:generic,gcp"
|
||||
},
|
||||
"source": [
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Distributed Training\n",
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex AI Distributed Training\n",
|
||||
"\n",
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/community/ml_ops/stage2/get_started_vertex_distributed_training.ipynb\">\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_distributed_training.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
@@ -44,7 +44,7 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_distributed_training.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_vertex_distributed_training.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
"Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -65,17 +65,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex Distributed Training. Please note: There are incompatibilities between Colab and Docker and the Docker section may not work until resolved by the platform."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:custom,boston,lrg"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Boston Housing Prices dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html). The version of the dataset you will use in this tutorial is built into TensorFlow. The trained model predicts the median price of a house in units of 1K USD."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -106,15 +95,6 @@
|
||||
"id": "recommendation:mlops,stage2,vertex,distributed_training"
|
||||
},
|
||||
"source": [
|
||||
"### Costs\n",
|
||||
" \n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"Vertex AI\n",
|
||||
"Cloud Storage\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage pricing](https://cloud.google.com/storage/pricing), and use the [Pricing Calculator](https://cloud.google.com/products/calculator/),\n",
|
||||
" to generate a cost estimate based on your projected usage.\n",
|
||||
"### Recommendations\n",
|
||||
"\n",
|
||||
"When doing E2E MLOps on Google Cloud, the following are best practices for when to use Vertex AI Distributed Training:\n",
|
||||
@@ -138,15 +118,43 @@
|
||||
"While training across a large number of VMs and the model parameters updates to sync is very large."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:custom,boston,lrg"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Boston Housing Prices dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html). The version of the dataset you use in this tutorial is built into TensorFlow. The trained model predicts the median price of a house in units of 1K USD."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "d10166df7141"
|
||||
},
|
||||
"source": [
|
||||
"### Costs\n",
|
||||
" \n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"Vertex AI\n",
|
||||
"Cloud Storage\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage pricing](https://cloud.google.com/storage/pricing), and use the [Pricing Calculator](https://cloud.google.com/products/calculator/),\n",
|
||||
" to generate a cost estimate based on your projected usage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "XkYpRvOQyVYb"
|
||||
},
|
||||
"source": [
|
||||
"### Install additional packages\n",
|
||||
"## Installation\n",
|
||||
"\n",
|
||||
"Install the latest version of Vertex SDK for Python."
|
||||
"Install the packages required for executing this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -159,24 +167,18 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "TjOXHg2VyajN"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip3 install {USER_FLAG} --upgrade google-cloud-aiplatform"
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install {USER_FLAG} --upgrade google-cloud-aiplatform -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -209,6 +211,32 @@
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "84cd83853240"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI, BigQuery, Compute Engine and Cloud Storage APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,bigquery,compute_component,storage_component).\n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -228,8 +256,6 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
@@ -287,7 +313,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"us-central1\" # @param {type: \"string\"}"
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -322,7 +351,7 @@
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Google Cloud Notebooks**, your environment is already\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already\n",
|
||||
"authenticated. Skip this step."
|
||||
]
|
||||
},
|
||||
@@ -364,20 +393,21 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Google Cloud Notebooks, then don't execute this code\n",
|
||||
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
@@ -412,7 +442,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
|
||||
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -423,8 +454,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = PROJECT_ID + \"aip-\" + TIMESTAMP\n",
|
||||
" BUCKET_URI = f\"gs://{BUCKET_NAME}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -444,7 +476,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil mb -l $REGION $BUCKET_NAME"
|
||||
"! gsutil mb -l $REGION $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -464,7 +496,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_NAME"
|
||||
"! gsutil ls -al $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -509,7 +541,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
|
||||
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -587,7 +619,7 @@
|
||||
"if os.getenv(\"IS_TESTING_TF\"):\n",
|
||||
" TF = os.getenv(\"IS_TESTING_TF\")\n",
|
||||
"else:\n",
|
||||
" TF = \"2.1\".replace(\".\", \"-\")\n",
|
||||
" TF = \"2.5\".replace(\".\", \"-\")\n",
|
||||
"\n",
|
||||
"if TF[0] == \"2\":\n",
|
||||
" if TRAIN_GPU:\n",
|
||||
@@ -718,7 +750,7 @@
|
||||
"\n",
|
||||
"job = aip.CustomPythonPackageTrainingJob(\n",
|
||||
" display_name=DISPLAY_NAME,\n",
|
||||
" python_package_gcs_uri=f\"{BUCKET_NAME}/trainer_boston.tar.gz\",\n",
|
||||
" python_package_gcs_uri=f\"{BUCKET_URI}/trainer_boston.tar.gz\",\n",
|
||||
" python_module_name=\"trainer.task\",\n",
|
||||
" container_uri=TRAIN_IMAGE,\n",
|
||||
" model_serving_container_image_uri=DEPLOY_IMAGE,\n",
|
||||
@@ -974,7 +1006,7 @@
|
||||
"! rm -f custom.tar custom.tar.gz\n",
|
||||
"! tar cvf custom.tar custom\n",
|
||||
"! gzip custom.tar\n",
|
||||
"! gsutil cp custom.tar.gz $BUCKET_NAME/trainer_boston.tar.gz"
|
||||
"! gsutil cp custom.tar.gz $BUCKET_URI/trainer_boston.tar.gz"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -996,7 +1028,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MODEL_DIR = BUCKET_NAME\n",
|
||||
"MODEL_DIR = BUCKET_URI\n",
|
||||
"\n",
|
||||
"CMDARGS = [\"--epochs=5\", \"--batch_size=16\", \"--distribute=mirrored\"]\n",
|
||||
"\n",
|
||||
@@ -1168,7 +1200,7 @@
|
||||
"\n",
|
||||
"job = aip.CustomPythonPackageTrainingJob(\n",
|
||||
" display_name=DISPLAY_NAME,\n",
|
||||
" python_package_gcs_uri=f\"{BUCKET_NAME}/trainer_boston.tar.gz\",\n",
|
||||
" python_package_gcs_uri=f\"{BUCKET_URI}/trainer_boston.tar.gz\",\n",
|
||||
" python_module_name=\"trainer.task\",\n",
|
||||
" container_uri=TRAIN_IMAGE,\n",
|
||||
" model_serving_container_image_uri=DEPLOY_IMAGE,\n",
|
||||
@@ -1195,7 +1227,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MODEL_DIR = BUCKET_NAME\n",
|
||||
"MODEL_DIR = BUCKET_URI\n",
|
||||
"\n",
|
||||
"CMDARGS = [\"--epochs=5\", \"--batch_size=16\", \"--distribute=multiworker\"]\n",
|
||||
"\n",
|
||||
@@ -1338,7 +1370,11 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! docker build custom -t $TRAIN_IMAGE"
|
||||
"if not IS_COLAB:\n",
|
||||
" ! docker build custom -t $TRAIN_IMAGE\n",
|
||||
"else:\n",
|
||||
" # install docker daemon\n",
|
||||
" ! apt-get -qq install docker.io"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1360,7 +1396,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! docker run $TRAIN_IMAGE --epochs=5 --model-dir=./"
|
||||
"if not IS_COLAB:\n",
|
||||
" ! docker run $TRAIN_IMAGE --epochs=5 --model-dir=./"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1382,7 +1419,38 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! docker push $TRAIN_IMAGE"
|
||||
"if not IS_COLAB:\n",
|
||||
" ! docker push $TRAIN_IMAGE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "f50e9c553fb7"
|
||||
},
|
||||
"source": [
|
||||
"*Executes in Colab*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "a7e8c98f1e56"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%bash -s $IS_COLAB $TRAIN_IMAGE\n",
|
||||
"if [ $1 == \"False\" ]; then\n",
|
||||
" exit 0\n",
|
||||
"fi\n",
|
||||
"set -x\n",
|
||||
"dockerd -b none --iptables=0 -l warn &\n",
|
||||
"for i in $(seq 5); do [ ! -S \"/var/run/docker.sock\" ] && sleep 2 || break; done\n",
|
||||
"docker build custom -t $2\n",
|
||||
"docker run $2 --epochs=5 --model-dir=./\n",
|
||||
"docker push $2\n",
|
||||
"kill $(jobs -p)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1408,7 +1476,7 @@
|
||||
"source": [
|
||||
"PRIMARY_COMPUTE = \"n2-highcpu-64\"\n",
|
||||
"\n",
|
||||
"MODEL_DIR = BUCKET_NAME\n",
|
||||
"MODEL_DIR = BUCKET_URI\n",
|
||||
"\n",
|
||||
"CMDARGS = [\n",
|
||||
" \"--model-dir=\" + MODEL_DIR,\n",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@
|
||||
"id": "title:generic,gcp"
|
||||
},
|
||||
"source": [
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Feature Store\n",
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex AI Feature Store\n",
|
||||
"\n",
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
@@ -41,12 +41,12 @@
|
||||
" \n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_feature_store.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\\\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" \n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_feature_store.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_vertex_feature_store.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -68,19 +68,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Feature Store."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:movies,lbn,avro"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the `Movie Recommendations` dataset. The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket, in Avro format.\n",
|
||||
"\n",
|
||||
"This dataset is used to predict whether a person will watch a movie or not."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -107,6 +94,19 @@
|
||||
"- Perform batch serving from a `Featurestore` resource."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:movies,lbn,avro"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the `Movie Recommendations` dataset. The version of the dataset you use in this tutorial is stored in a public Cloud Storage bucket, in Avro format.\n",
|
||||
"\n",
|
||||
"This dataset is used to predict whether a person watches a movie or not."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -144,12 +144,15 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"# Install the dependecies\n",
|
||||
@@ -185,6 +188,32 @@
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "project_id"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI, Compute Engine, Cloud Storage and Cloud Logging APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,compute_component,storage_component,logging).\n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -299,7 +328,7 @@
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Google Cloud Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
@@ -334,8 +363,11 @@
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Google Cloud Notebook, then don't execute this code\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = \"google.colab\" in sys.modules\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
@@ -459,7 +491,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Represents featurestore resource path.\n",
|
||||
"FEATURESTORE_NAME = \"movies\"\n",
|
||||
"FEATURESTORE_NAME = \"movies_\" + TIMESTAMP\n",
|
||||
"\n",
|
||||
"featurestore = aiplatform.Featurestore.create(\n",
|
||||
" featurestore_id=FEATURESTORE_NAME,\n",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@
|
||||
"id": "title:generic,gcp"
|
||||
},
|
||||
"source": [
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Tensorboard\n",
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex AI TensorBoard\n",
|
||||
"\n",
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
@@ -44,7 +44,7 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_vertex_tensorboard.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -62,7 +62,7 @@
|
||||
"## Overview\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex Tensorboard."
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex AI TensorBoard."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -83,10 +83,44 @@
|
||||
"The steps performed include:\n",
|
||||
"\n",
|
||||
"- Create a TensorBoard callback when training a model.\n",
|
||||
"- Using Tensorboard with locally trained model.\n",
|
||||
"- Using TensorBoard with locally trained model.\n",
|
||||
"- Using Vertex AI TensorBoard with Vertex AI Training."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "recommendation:mlops,stage2,vertex,tensorboard"
|
||||
},
|
||||
"source": [
|
||||
"### Recommendations\n",
|
||||
"\n",
|
||||
"When doing E2E MLOps on Google Cloud, the following are the best practices for visualizing your training with TensorBoard.\n",
|
||||
"\n",
|
||||
"#### Local TensorBoard\n",
|
||||
"\n",
|
||||
"Use the OSS version of TensorBoard, either command-line or daemon version, when doing ad-hoc training locally.\n",
|
||||
"\n",
|
||||
"#### Cloud TensorBoard\n",
|
||||
"\n",
|
||||
"Use the tensorboard.dev, when doing training on the cloud -- unless you have a privacy issue.\n",
|
||||
"\n",
|
||||
"#### Experiments\n",
|
||||
"\n",
|
||||
"Use Vertex AI TensorBoard when you have a privacy issue or doing experiments to compare results for different experiment configurations."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "03bfd1274241"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"In this tutorial you use the MNIST dataset. The version of the dataset is built into the TF.Keras framework. The dataset predicts which digit an image is, between 0 .. 9."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -110,21 +144,14 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "94a148f11da5"
|
||||
"id": "56cb7f08a9e8"
|
||||
},
|
||||
"source": [
|
||||
"### Set up your local development environment\n",
|
||||
"\n",
|
||||
"**If you are using Colab or Google Cloud Notebooks**, your environment already meets\n",
|
||||
"all the requirements to run this notebook. You can skip this step."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "56cb7f08a9e8"
|
||||
},
|
||||
"source": [
|
||||
"**If you are using Colab or Vertex AI Workbench Notebooks**, your environment already meets\n",
|
||||
"all the requirements to run this notebook. \n",
|
||||
"\n",
|
||||
"**Otherwise**, make sure your environment meets this notebook's requirements.\n",
|
||||
"You need the following:\n",
|
||||
"\n",
|
||||
@@ -156,29 +183,6 @@
|
||||
"1. Open this notebook in the Jupyter Notebook Dashboard.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "recommendation:mlops,stage2,vertex,tensorboard"
|
||||
},
|
||||
"source": [
|
||||
"### Recommendations\n",
|
||||
"\n",
|
||||
"When doing E2E MLOps on Google Cloud, the following are the best practices for visualizing your training with TensorBoard.\n",
|
||||
"\n",
|
||||
"#### Local TensorBoard\n",
|
||||
"\n",
|
||||
"Use the OSS version of TensorBoard, either command-line or daemon version, when doing ad-hoc training locally.\n",
|
||||
"\n",
|
||||
"#### Cloud TensorBoard\n",
|
||||
"\n",
|
||||
"Use the Tensorboard.dev, when doing training on the cloud -- unless you have a privacy issue.\n",
|
||||
"\n",
|
||||
"#### Experiments\n",
|
||||
"\n",
|
||||
"Use Vertex AI TensorBoard when you have a privacy issue or doing experiments to compare results for different experiment configurations."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -187,7 +191,7 @@
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"\n",
|
||||
"Install *one time* the packages for executing the MLOps notebooks."
|
||||
"Install the following packages for executing this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -200,25 +204,19 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "install_mlops"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip3 install -U tensorflow==2.8 $USER_FLAG\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG"
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install -U tensorflow==2.8 $USER_FLAG -q\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -250,21 +248,14 @@
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "d6a00c14b087"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2721ef0202d9"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
@@ -273,9 +264,9 @@
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). {TODO: Update the APIs needed for your tutorial. Edit the API names, and update the link to append the API IDs, separating each one with a comma. For example, container.googleapis.com,cloudbuild.googleapis.com}\n",
|
||||
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). \n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you will need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
@@ -359,7 +350,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"us-central1\" # @param {type: \"string\"}"
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -394,7 +388,7 @@
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Google Cloud Notebooks**, your environment is already\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already\n",
|
||||
"authenticated. Skip this step."
|
||||
]
|
||||
},
|
||||
@@ -436,20 +430,21 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Google Cloud Notebooks, then don't execute this code\n",
|
||||
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
@@ -574,9 +569,16 @@
|
||||
" or SERVICE_ACCOUNT is None\n",
|
||||
" or SERVICE_ACCOUNT == \"[your-service-account]\"\n",
|
||||
"):\n",
|
||||
" # Get your GCP project id from gcloud\n",
|
||||
" shell_output = !gcloud auth list 2>/dev/null\n",
|
||||
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
|
||||
" # Get your service account from gcloud\n",
|
||||
" if not IS_COLAB:\n",
|
||||
" shell_output = !gcloud auth list 2>/dev/null\n",
|
||||
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
|
||||
"\n",
|
||||
" if IS_COLAB:\n",
|
||||
" shell_output = ! gcloud projects describe $PROJECT_ID\n",
|
||||
" project_number = shell_output[-1].split(\":\")[1].strip().replace(\"'\", \"\")\n",
|
||||
" SERVICE_ACCOUNT = f\"{project_number}-compute@developer.gserviceaccount.com\"\n",
|
||||
"\n",
|
||||
" print(\"Service Account:\", SERVICE_ACCOUNT)"
|
||||
]
|
||||
},
|
||||
@@ -783,9 +785,9 @@
|
||||
"source": [
|
||||
"## Training with TensorBoard\n",
|
||||
"\n",
|
||||
"Tensorboard provides the means to visualize your training in-real time and to visualize the results (metrics).\n",
|
||||
"TensorBoard provides the means to visualize your training in-real time and to visualize the results (metrics).\n",
|
||||
"\n",
|
||||
"You can use Tensorboard in conjunction with local training, cloud training and with `Vertex AI Training`, which is referred to as `Vertex AI TensorBoard`"
|
||||
"You can use TensorBoard in conjunction with local training, cloud training and with `Vertex AI Training`, which is referred to as `Vertex AI TensorBoard`"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"id": "title:generic,gcp"
|
||||
},
|
||||
"source": [
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Training\n",
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex AI Training\n",
|
||||
"\n",
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
@@ -39,8 +39,14 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training.ipynb\">\n",
|
||||
" Open in Google Cloud Notebooks\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_vertex_training.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
"</table>\n",
|
||||
@@ -56,18 +62,7 @@
|
||||
"## Overview\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex Training."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:custom,boston,lrg"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Boston Housing Prices dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html). The version of the dataset you will use in this tutorial is built into TensorFlow. The trained model predicts the median price of a house in units of 1K USD."
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex AI Training."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -119,6 +114,38 @@
|
||||
"CustomJob"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:custom,boston,lrg"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Boston Housing Prices dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html). The version of the dataset this tutorial is built into TensorFlow. The trained model predicts the median price of a house in units of 1K USD."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "c480fc50ec3c"
|
||||
},
|
||||
"source": [
|
||||
"### Costs \n",
|
||||
"\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"* Vertex AI\n",
|
||||
"* Cloud Storage\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI\n",
|
||||
"pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage\n",
|
||||
"pricing](https://cloud.google.com/storage/pricing), and use the [Pricing\n",
|
||||
"Calculator](https://cloud.google.com/products/calculator/)\n",
|
||||
"to generate a cost estimate based on your projected usage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -127,7 +154,7 @@
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"\n",
|
||||
"Install *one time* the packages for executing the MLOps notebooks."
|
||||
"Install the packages required for executing this notebook"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -138,20 +165,20 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ONCE_ONLY = False\n",
|
||||
"if ONCE_ONLY:\n",
|
||||
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade kfp $USER_FLAG"
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -173,8 +200,6 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"if not os.getenv(\"IS_TESTING\"):\n",
|
||||
" # Automatically restart kernel after installs\n",
|
||||
" import IPython\n",
|
||||
@@ -183,6 +208,36 @@
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "before_you_begin"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### GPU runtime\n",
|
||||
"\n",
|
||||
"*Make sure you're running this notebook in a GPU runtime if you have that option. In Colab, select* **Runtime > Change Runtime Type > GPU**\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"2. [Make sure that billing is enabled for your project.](https://cloud.google.com/billing/docs/how-to/modify-project)\n",
|
||||
"\n",
|
||||
"3. [Enable the following APIs: Vertex AI APIs, Compute Engine APIs, and Cloud Storage.](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,compute_component,storage-component.googleapis.com)\n",
|
||||
"\n",
|
||||
"4. If you are running this notebook locally, you need to install the [Cloud SDK]((https://cloud.google.com/sdk)).\n",
|
||||
"\n",
|
||||
"5. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -259,7 +314,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"us-central1\" # @param {type: \"string\"}"
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -286,6 +344,67 @@
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "gcp_authenticate"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"**Click Create service account**.\n",
|
||||
"\n",
|
||||
"In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex\" into the filter box, and select **Vertex Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "gcp_authenticate"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -309,7 +428,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
|
||||
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -320,8 +440,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = PROJECT_ID + \"aip-\" + TIMESTAMP\n",
|
||||
" BUCKET_URI = \"gs://\" + BUCKET_NAME"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -341,7 +462,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil mb -l $REGION $BUCKET_NAME"
|
||||
"! gsutil mb -l $REGION $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -361,7 +482,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_NAME"
|
||||
"! gsutil ls -al $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -384,7 +505,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import google.cloud.aiplatform as aip"
|
||||
"import google.cloud.aiplatform as aiplatform"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -406,7 +527,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_NAME)"
|
||||
"aiplatform.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -441,7 +562,7 @@
|
||||
"source": [
|
||||
"if os.getenv(\"IS_TESTING_TRAIN_GPU\"):\n",
|
||||
" TRAIN_GPU, TRAIN_NGPU = (\n",
|
||||
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
|
||||
" aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
|
||||
" int(os.getenv(\"IS_TESTING_TRAIN_GPU\")),\n",
|
||||
" )\n",
|
||||
"else:\n",
|
||||
@@ -449,7 +570,7 @@
|
||||
"\n",
|
||||
"if os.getenv(\"IS_TESTING_DEPLOY_GPU\"):\n",
|
||||
" DEPLOY_GPU, DEPLOY_NGPU = (\n",
|
||||
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
|
||||
" aiplatform.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
|
||||
" int(os.getenv(\"IS_TESTING_DEPLOY_GPU\")),\n",
|
||||
" )\n",
|
||||
"else:\n",
|
||||
@@ -484,7 +605,7 @@
|
||||
"if os.getenv(\"IS_TESTING_TF\"):\n",
|
||||
" TF = os.getenv(\"IS_TESTING_TF\")\n",
|
||||
"else:\n",
|
||||
" TF = \"2.1\".replace(\".\", \"-\")\n",
|
||||
" TF = \"2.5\".replace(\".\", \"-\")\n",
|
||||
"\n",
|
||||
"if TF[0] == \"2\":\n",
|
||||
" if TRAIN_GPU:\n",
|
||||
@@ -602,7 +723,7 @@
|
||||
"DISPLAY_NAME = \"boston_\" + TIMESTAMP\n",
|
||||
"REQUIREMENTS = [\"tensorflow==2.3\"]\n",
|
||||
"\n",
|
||||
"job = aip.CustomTrainingJob(\n",
|
||||
"job = aiplatform.CustomTrainingJob(\n",
|
||||
" display_name=DISPLAY_NAME,\n",
|
||||
" script_path=\"task.py\",\n",
|
||||
" requirements=REQUIREMENTS,\n",
|
||||
@@ -693,12 +814,12 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"CMDARGS = [\n",
|
||||
" \"--model-dir=\" + BUCKET_NAME,\n",
|
||||
" \"--model-dir=\" + BUCKET_URI,\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"job.run(args=CMDARGS, replica_count=1, machine_type=TRAIN_COMPUTE, sync=True)\n",
|
||||
"\n",
|
||||
"! gsutil cat {BUCKET_NAME}/test.txt"
|
||||
"! gsutil cat {BUCKET_URI}/test.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -768,9 +889,9 @@
|
||||
"source": [
|
||||
"DISPLAY_NAME = \"boston_\" + TIMESTAMP\n",
|
||||
"\n",
|
||||
"job = aip.CustomPythonPackageTrainingJob(\n",
|
||||
"job = aiplatform.CustomPythonPackageTrainingJob(\n",
|
||||
" display_name=DISPLAY_NAME,\n",
|
||||
" python_package_gcs_uri=f\"{BUCKET_NAME}/trainer_boston.tar.gz\",\n",
|
||||
" python_package_gcs_uri=f\"{BUCKET_URI}/trainer_boston.tar.gz\",\n",
|
||||
" python_module_name=\"trainer.task\",\n",
|
||||
" container_uri=TRAIN_IMAGE,\n",
|
||||
")"
|
||||
@@ -900,7 +1021,7 @@
|
||||
"! rm -f custom.tar custom.tar.gz\n",
|
||||
"! tar cvf custom.tar custom\n",
|
||||
"! gzip custom.tar\n",
|
||||
"! gsutil cp custom.tar.gz $BUCKET_NAME/trainer_boston.tar.gz"
|
||||
"! gsutil cp custom.tar.gz $BUCKET_URI/trainer_boston.tar.gz"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -922,11 +1043,11 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"CMDARGS = [\"--model-dir=\" + BUCKET_NAME, \"--epochs=5\"]\n",
|
||||
"CMDARGS = [\"--model-dir=\" + BUCKET_URI, \"--epochs=5\"]\n",
|
||||
"\n",
|
||||
"job.run(args=CMDARGS, replica_count=1, machine_type=TRAIN_COMPUTE, sync=True)\n",
|
||||
"\n",
|
||||
"! gsutil cat {BUCKET_NAME}/test.txt"
|
||||
"! gsutil cat {BUCKET_URI}/test.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1151,7 +1272,11 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! docker build custom -t $TRAIN_IMAGE"
|
||||
"if not IS_COLAB:\n",
|
||||
" ! docker build custom -t $TRAIN_IMAGE\n",
|
||||
"else:\n",
|
||||
" # install docker daemon\n",
|
||||
" ! apt-get -qq install docker.io"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1173,7 +1298,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! docker run $TRAIN_IMAGE --epochs=5 --model-dir=./"
|
||||
"if not IS_COLAB:\n",
|
||||
" ! docker run $TRAIN_IMAGE --epochs=5 --model-dir=./"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1195,7 +1321,38 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! docker push $TRAIN_IMAGE"
|
||||
"if not IS_COLAB:\n",
|
||||
" ! docker push $TRAIN_IMAGE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "f50e9c553fb7"
|
||||
},
|
||||
"source": [
|
||||
"*Executes in Colab*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "a7e8c98f1e56"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%bash -s $IS_COLAB $TRAIN_IMAGE\n",
|
||||
"if [ $1 == \"False\" ]; then\n",
|
||||
" exit 0\n",
|
||||
"fi\n",
|
||||
"set -x\n",
|
||||
"dockerd -b none --iptables=0 -l warn &\n",
|
||||
"for i in $(seq 5); do [ ! -S \"/var/run/docker.sock\" ] && sleep 2 || break; done\n",
|
||||
"docker build custom -t $2\n",
|
||||
"docker run $2 --epochs=5 --model-dir=./\n",
|
||||
"docker push $2\n",
|
||||
"kill $(jobs -p)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1229,7 +1386,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"job = aip.CustomContainerTrainingJob(\n",
|
||||
"job = aiplatform.CustomContainerTrainingJob(\n",
|
||||
" display_name=\"boston_\" + TIMESTAMP,\n",
|
||||
" container_uri=TRAIN_IMAGE,\n",
|
||||
" command=[\"python3\", \"trainer/task.py\"],\n",
|
||||
@@ -1257,11 +1414,11 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"CMDARGS = [\"--model-dir=\" + BUCKET_NAME, \"--epochs=5\"]\n",
|
||||
"CMDARGS = [\"--model-dir=\" + BUCKET_URI, \"--epochs=5\"]\n",
|
||||
"\n",
|
||||
"job.run(args=CMDARGS, replica_count=1, machine_type=TRAIN_COMPUTE, sync=True)\n",
|
||||
"\n",
|
||||
"! gsutil cat {BUCKET_NAME}/test.txt"
|
||||
"! gsutil cat {BUCKET_URI}/test.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1466,7 +1623,7 @@
|
||||
"! rm -f custom.tar custom.tar.gz\n",
|
||||
"! tar cvf custom.tar custom\n",
|
||||
"! gzip custom.tar\n",
|
||||
"! gsutil cp custom.tar.gz $BUCKET_NAME/trainer_boston.tar.gz"
|
||||
"! gsutil cp custom.tar.gz $BUCKET_URI/trainer_boston.tar.gz"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1496,7 +1653,7 @@
|
||||
"if os.getenv(\"IS_TESTING_TF\"):\n",
|
||||
" TF = os.getenv(\"IS_TESTING_TF\")\n",
|
||||
"else:\n",
|
||||
" TF = \"2.1\".replace(\".\", \"-\")\n",
|
||||
" TF = \"2.5\".replace(\".\", \"-\")\n",
|
||||
"\n",
|
||||
"if TF[0] == \"2\":\n",
|
||||
" if TRAIN_GPU:\n",
|
||||
@@ -1551,9 +1708,9 @@
|
||||
"source": [
|
||||
"DISPLAY_NAME = \"boston_\" + TIMESTAMP\n",
|
||||
"\n",
|
||||
"job = aip.CustomPythonPackageTrainingJob(\n",
|
||||
"job = aiplatform.CustomPythonPackageTrainingJob(\n",
|
||||
" display_name=DISPLAY_NAME,\n",
|
||||
" python_package_gcs_uri=f\"{BUCKET_NAME}/trainer_boston.tar.gz\",\n",
|
||||
" python_package_gcs_uri=f\"{BUCKET_URI}/trainer_boston.tar.gz\",\n",
|
||||
" python_module_name=\"trainer.task\",\n",
|
||||
" container_uri=TRAIN_IMAGE,\n",
|
||||
" model_serving_container_image_uri=DEPLOY_IMAGE,\n",
|
||||
@@ -1587,12 +1744,12 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MODEL_DIR = \"{}/{}\".format(BUCKET_NAME, TIMESTAMP)\n",
|
||||
"MODEL_DIR = \"{}/{}\".format(BUCKET_URI, TIMESTAMP)\n",
|
||||
"\n",
|
||||
"EPOCHS = 20\n",
|
||||
"STEPS = 100\n",
|
||||
"\n",
|
||||
"DIRECT = True\n",
|
||||
"DIRECT = False\n",
|
||||
"if DIRECT:\n",
|
||||
" CMDARGS = [\n",
|
||||
" \"--model-dir=\" + MODEL_DIR,\n",
|
||||
@@ -1758,17 +1915,7 @@
|
||||
"To clean up all Google Cloud resources used in this project, you can [delete the Google Cloud\n",
|
||||
"project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects) you used for the tutorial.\n",
|
||||
"\n",
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
|
||||
"\n",
|
||||
"- Dataset\n",
|
||||
"- Pipeline\n",
|
||||
"- Model\n",
|
||||
"- Endpoint\n",
|
||||
"- AutoML Training Job\n",
|
||||
"- Batch Job\n",
|
||||
"- Custom Job\n",
|
||||
"- Hyperparameter Tuning Job\n",
|
||||
"- Cloud Storage Bucket"
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1779,61 +1926,24 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"delete_all = True\n",
|
||||
"delete_bucket = False\n",
|
||||
"delete_model = True\n",
|
||||
"delete_job = True\n",
|
||||
"\n",
|
||||
"if delete_all:\n",
|
||||
" # Delete the dataset using the Vertex dataset object\n",
|
||||
"if delete_model:\n",
|
||||
" try:\n",
|
||||
" if \"dataset\" in globals():\n",
|
||||
" dataset.delete()\n",
|
||||
" model.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the model using the Vertex model object\n",
|
||||
"if delete_job:\n",
|
||||
" try:\n",
|
||||
" if \"model\" in globals():\n",
|
||||
" model.delete()\n",
|
||||
" job.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the endpoint using the Vertex endpoint object\n",
|
||||
" try:\n",
|
||||
" if \"endpoint\" in globals():\n",
|
||||
" endpoint.undeploy_all()\n",
|
||||
" endpoint.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the AutoML or Pipeline training job\n",
|
||||
" try:\n",
|
||||
" if \"dag\" in globals():\n",
|
||||
" dag.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the custom training job\n",
|
||||
" try:\n",
|
||||
" if \"job\" in globals():\n",
|
||||
" job.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the batch prediction job using the Vertex batch prediction object\n",
|
||||
" try:\n",
|
||||
" if \"batch_predict_job\" in globals():\n",
|
||||
" batch_predict_job.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" # Delete the hyperparameter tuning job using the Vertex hyperparameter tuning object\n",
|
||||
" try:\n",
|
||||
" if \"hpt_job\" in globals():\n",
|
||||
" hpt_job.delete()\n",
|
||||
" except Exception as e:\n",
|
||||
" print(e)\n",
|
||||
"\n",
|
||||
" if \"BUCKET_NAME\" in globals():\n",
|
||||
" ! gsutil rm -r $BUCKET_NAME"
|
||||
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
|
||||
" ! gsutil rm -rf {BUCKET_URI}"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,17 +29,22 @@
|
||||
"id": "title:generic,gcp"
|
||||
},
|
||||
"source": [
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Training for Pytorch\n",
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex AI Training for PyTorch\n",
|
||||
"\n",
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_pytorch.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_pytorch.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/notebook_template.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_pytorch.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -57,18 +62,7 @@
|
||||
"## Overview\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex Training for Pytorch."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:pytorch,cifar10,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [CIFAR10 dataset](https://pytorch.org/vision/stable/datasets.html#cifar) from [Pytorch Datasets](https://pytorch.org/vision/stable/datasets.html). The version of the dataset you will use is built into TensorFlow. The trained model predicts which type of class an image is from ten classes: airplane, automobile, bird, cat, deer, dog, frog, horse, ship, or truck."
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex AI Training for PyTorch."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -79,7 +73,7 @@
|
||||
"source": [
|
||||
"### Objective\n",
|
||||
"\n",
|
||||
"In this tutorial, you learn how to use `Vertex AI Training` for training a Pytorch custom model.\n",
|
||||
"In this tutorial, you learn how to use `Vertex AI Training` for training a PyTorch custom model.\n",
|
||||
"\n",
|
||||
"This tutorial uses the following Google Cloud ML services:\n",
|
||||
"\n",
|
||||
@@ -95,13 +89,24 @@
|
||||
"- Create a `Vertex AI Model` resource."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:pytorch,cifar10,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [CIFAR10 dataset](https://pytorch.org/vision/stable/datasets.html#cifar) from [PyTorch Datasets](https://pytorch.org/vision/stable/datasets.html). The version of the dataset is built into TensorFlow. The trained model predicts which type of class an image is from ten classes: airplane, automobile, bird, cat, deer, dog, frog, horse, ship, or truck."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "85ee859437ed"
|
||||
},
|
||||
"source": [
|
||||
"## Costs \n",
|
||||
"### Costs \n",
|
||||
"\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
@@ -123,7 +128,7 @@
|
||||
"source": [
|
||||
"### Set up your local development environment\n",
|
||||
"\n",
|
||||
"**If you are using Colab or Google Cloud Notebooks**, your environment already meets\n",
|
||||
"**If you are using Colab or Vertex AI Workbench Notebooks**, your environment already meets\n",
|
||||
"all the requirements to run this notebook. You can skip this step."
|
||||
]
|
||||
},
|
||||
@@ -172,7 +177,7 @@
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"\n",
|
||||
"Install *one time* the packages for executing the MLOps notebooks."
|
||||
"Install the following packages to execute this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -183,10 +188,22 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
|
||||
"! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
|
||||
"! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
|
||||
"! pip3 install --upgrade torchvision $USER_FLAG"
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG -q\n",
|
||||
"! pip3 install --upgrade cloudml-hypertune $USER_FLAG -q\n",
|
||||
"! pip3 install --upgrade torchvision $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -218,6 +235,32 @@
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "84cd83853240"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI, BigQuery, Compute Engine and Cloud Storage APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,bigquery,compute_component,storage_component).\n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -294,7 +337,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"us-central1\" # @param {type: \"string\"}"
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -321,6 +367,67 @@
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "77c385f0db59"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"1. **Click Create service account**.\n",
|
||||
"\n",
|
||||
"2. In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"3. In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex AI\" into the filter box, and select **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"4. Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"5. Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "535223fa4b84"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -565,17 +672,17 @@
|
||||
"id": "pytorch_intro"
|
||||
},
|
||||
"source": [
|
||||
"## Introduction to Pytorch training\n",
|
||||
"## Introduction to PyTorch training\n",
|
||||
"\n",
|
||||
"The Pytorch package supports both single node and distributed model training.\n",
|
||||
"The PyTorch package supports both single node and distributed model training.\n",
|
||||
"\n",
|
||||
"Once you have trained a Pytorch model, you will want to save it at a Cloud Storage location, so it can subsequently be uploaded to a `Vertex AI Model` resource.\n",
|
||||
"The Pytorch package does not have support to save the model to a Cloud Storage location. Instead, you will do the following steps to save to a Cloud Storage location.\n",
|
||||
"Once you have trained a PyTorch model, you will want to save it at a Cloud Storage location, so it can subsequently be uploaded to a `Vertex AI Model` resource.\n",
|
||||
"The PyTorch package does not have support to save the model to a Cloud Storage location. Instead, you will do the following steps to save to a Cloud Storage location.\n",
|
||||
"\n",
|
||||
"1. Save the in-memory model to the local filesystem (e.g., model.pth).\n",
|
||||
"2. Use gsutil to copy the local copy to the specified Cloud Storage location.\n",
|
||||
"\n",
|
||||
"*Note*: You can do hyperparameter tuning with a Pytorch model."
|
||||
"*Note*: You can do hyperparameter tuning with a PyTorch model."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -962,9 +1069,9 @@
|
||||
"id": "docker_write,prediction,pytorch"
|
||||
},
|
||||
"source": [
|
||||
"### Make Pytorch container for prediction\n",
|
||||
"### Make PyTorch container for prediction\n",
|
||||
"\n",
|
||||
"Currently, Vertex AI does not have a predefined container for making predictions with a deployed Pytorch model. No problem, you can assemble your own custom container. Typically, one would base the container on the `Torch Server`. For demonstration purpose, you build a placeholder container (not complete) that includes the latest `Torch Server` image, and push it to the `Container Registry`."
|
||||
"Currently, Vertex AI does not have a predefined container for making predictions with a deployed PyTorch model. No problem, you can assemble your own custom container. Typically, one would base the container on the `Torch Server`. For demonstration purpose, you build a placeholder container (not complete) that includes the latest `Torch Server` image, and push it to the `Container Registry`."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -994,11 +1101,52 @@
|
||||
"source": [
|
||||
"APP_NAME = \"cifar10\"\n",
|
||||
"DEPLOY_IMAGE = f\"gcr.io/{PROJECT_ID}/pytorch_predict_{APP_NAME}\"\n",
|
||||
"print(DEPLOY_IMAGE)\n",
|
||||
"\n",
|
||||
"! docker build --tag=$DEPLOY_IMAGE ./\n",
|
||||
"\n",
|
||||
"! docker push $DEPLOY_IMAGE"
|
||||
"print(DEPLOY_IMAGE)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "85739262f629"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if not IS_COLAB:\n",
|
||||
" ! docker build --tag=$DEPLOY_IMAGE ./\n",
|
||||
" ! docker push $DEPLOY_IMAGE\n",
|
||||
"else:\n",
|
||||
" # install docker daemon\n",
|
||||
" ! apt-get -qq install docker.io"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "f50e9c553fb7"
|
||||
},
|
||||
"source": [
|
||||
"*Executes in Colab*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "a7e8c98f1e56"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%bash -s $IS_COLAB $DEPLOY_IMAGE\n",
|
||||
"if [ $1 == \"False\" ]; then\n",
|
||||
" exit 0\n",
|
||||
"fi\n",
|
||||
"set -x\n",
|
||||
"dockerd -b none --iptables=0 -l warn &\n",
|
||||
"for i in $(seq 5); do [ ! -S \"/var/run/docker.sock\" ] && sleep 2 || break; done\n",
|
||||
"docker build --tag=$2 ./\n",
|
||||
"docker push $2\n",
|
||||
"kill $(jobs -p)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1211,7 +1359,6 @@
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
|
||||
"\n",
|
||||
"- Model\n",
|
||||
"- Custom Job (Custom job deleted in previous cell)\n",
|
||||
"- Cloud Storage Bucket"
|
||||
]
|
||||
},
|
||||
@@ -1226,8 +1373,8 @@
|
||||
"# Delete the model using the Vertex model object\n",
|
||||
"model.delete()\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"if os.getenv(\"IS_TESTING\"):\n",
|
||||
"delete_bucket = False\n",
|
||||
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -39,7 +39,12 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_r.ipynb\">\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_r.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_r.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -60,17 +65,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex AI Training for R. Please note that this notebook should be ran only in R notebook image (e.g., R4.1)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:r,iris,lcn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the Iris dataset built into the R package. This dataset does not require any feature engineering. The trained model predicts the type of Iris flower species from a class of three species: setosa, virginica, or versicolor."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -99,6 +93,17 @@
|
||||
"- Train a R model using `Vertex AI Trainingh` service with the R-to-Python training package."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:r,iris,lcn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the Iris dataset built into the R package. This dataset does not require any feature engineering. The trained model predicts the type of Iris flower species from a class of three species: setosa, virginica, or versicolor."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -129,7 +134,7 @@
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"\n",
|
||||
"Install *one time* the packages for executing the MLOps notebooks."
|
||||
"Install the packages required for executing this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -142,25 +147,19 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "install_mlops"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
|
||||
"! pip3 install --upgrade rpy2 $USER_FLAG"
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG -q\n",
|
||||
"! pip3 install --upgrade rpy2 $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -215,9 +214,9 @@
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). {TODO: Update the APIs needed for your tutorial. Edit the API names, and update the link to append the API IDs, separating each one with a comma. For example, container.googleapis.com,cloudbuild.googleapis.com}\n",
|
||||
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). \n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you will need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
@@ -244,8 +243,6 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
@@ -332,6 +329,67 @@
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "3ffa6b6c7cdb"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"1. **Click Create service account**.\n",
|
||||
"\n",
|
||||
"2. In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"3. In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex AI\" into the filter box, and select **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"4. Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"5. Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "2b72272258fc"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -1366,7 +1424,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if os.getenv(\"IS_TESTING\"):\n",
|
||||
"delete_bucket = False\n",
|
||||
"\n",
|
||||
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
]
|
||||
}
|
||||
|
||||
+1150
File diff suppressed because it is too large
Load Diff
@@ -29,25 +29,27 @@
|
||||
"id": "title:generic,gcp"
|
||||
},
|
||||
"source": [
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Training for Scikit-Learn\n",
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex AI Training for Scikit-Learn\n",
|
||||
"\n",
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_sklearn.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_sklearn.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_sklearn.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_sklearn.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
"Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
"</table>\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
"</table>\n",
|
||||
"<br/><br/><br/>"
|
||||
]
|
||||
},
|
||||
@@ -60,18 +62,7 @@
|
||||
"## Overview\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex Training for Scikit-Learn."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:custom,newsaggr,tcn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [News Aggregation](https://archive.ics.uci.edu/ml/datasets/News+Aggregator) from [ICS Machine Learning Datasets](https://archive.ics.uci.edu/ml/datasets.php). The trained model predicts the news category of the news article."
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex AI Training for scikit-Learn."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -97,15 +88,167 @@
|
||||
"- Create a `Vertex AI Model` resource."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:custom,newsaggr,tcn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [News Aggregation](https://archive.ics.uci.edu/ml/datasets/News+Aggregator) from [ICS Machine Learning Datasets](https://archive.ics.uci.edu/ml/datasets.php). The trained model predicts the news category of the news article."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "b132d4ef86d6"
|
||||
},
|
||||
"source": [
|
||||
"### Costs \n",
|
||||
"\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"* Vertex AI\n",
|
||||
"* Cloud Storage\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI\n",
|
||||
"pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage\n",
|
||||
"pricing](https://cloud.google.com/storage/pricing), and use the [Pricing\n",
|
||||
"Calculator](https://cloud.google.com/products/calculator/)\n",
|
||||
"to generate a cost estimate based on your projected usage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "94a148f11da5"
|
||||
},
|
||||
"source": [
|
||||
"### Set up your local development environment\n",
|
||||
"\n",
|
||||
"**If you are using Colab or Vertex AI Workbench Notebooks**, your environment already meets\n",
|
||||
"all the requirements to run this notebook. You can skip this step.\n",
|
||||
"\n",
|
||||
"**Otherwise**, make sure your environment meets this notebook's requirements.\n",
|
||||
"You need the following:\n",
|
||||
"\n",
|
||||
"* The Google Cloud SDK\n",
|
||||
"* Git\n",
|
||||
"* Python 3\n",
|
||||
"* virtualenv\n",
|
||||
"* Jupyter notebook running in a virtual environment with Python 3\n",
|
||||
"\n",
|
||||
"The Google Cloud guide to [Setting up a Python development\n",
|
||||
"environment](https://cloud.google.com/python/setup) and the [Jupyter\n",
|
||||
"installation guide](https://jupyter.org/install) provide detailed instructions\n",
|
||||
"for meeting these requirements. The following steps provide a condensed set of\n",
|
||||
"instructions:\n",
|
||||
"\n",
|
||||
"1. [Install and initialize the Cloud SDK.](https://cloud.google.com/sdk/docs/)\n",
|
||||
"\n",
|
||||
"1. [Install Python 3.](https://cloud.google.com/python/setup#installing_python)\n",
|
||||
"\n",
|
||||
"1. [Install\n",
|
||||
" virtualenv](https://cloud.google.com/python/setup#installing_and_using_virtualenv)\n",
|
||||
" and create a virtual environment that uses Python 3. Activate the virtual environment.\n",
|
||||
"\n",
|
||||
"1. To install Jupyter, run `pip3 install jupyter` on the\n",
|
||||
"command-line in a terminal shell.\n",
|
||||
"\n",
|
||||
"1. To launch Jupyter, run `jupyter notebook` on the command-line in a terminal shell.\n",
|
||||
"\n",
|
||||
"1. Open this notebook in the Jupyter Notebook Dashboard.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "install_mlops"
|
||||
},
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"## Installation\n",
|
||||
"\n",
|
||||
"You will not need special packages for this notebook."
|
||||
"Install the following packages for executing this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "78168417490e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install {USER_FLAG} --upgrade google-cloud-aiplatform -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "restart"
|
||||
},
|
||||
"source": [
|
||||
"### Restart the kernel\n",
|
||||
"\n",
|
||||
"Once you've installed the additional packages, you need to restart the notebook kernel so it can find the packages."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "restart"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"if not os.getenv(\"IS_TESTING\"):\n",
|
||||
" # Automatically restart kernel after installs\n",
|
||||
" import IPython\n",
|
||||
"\n",
|
||||
" app = IPython.Application.instance()\n",
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2721ef0202d9"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). \n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -184,7 +327,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"us-central1\" # @param {type: \"string\"}"
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -211,6 +357,67 @@
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "77c385f0db59"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"1. **Click Create service account**.\n",
|
||||
"\n",
|
||||
"2. In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"3. In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex AI\" into the filter box, and select **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"4. Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"5. Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "535223fa4b84"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -468,9 +675,9 @@
|
||||
"id": "sklearn_intro"
|
||||
},
|
||||
"source": [
|
||||
"## Introduction to Scikit-learn training\n",
|
||||
"## Introduction to scikit-learn training\n",
|
||||
"\n",
|
||||
"Once you have trained a Scikit-learn model, you will want to save it at a Cloud Storage location, so it can subsequently be uploaded to a `Vertex AI Model` resource. The Scikit-learn package does not have support to save the model to a Cloud Storage location. Instead, you will do the following steps to save to a Cloud Storage location.\n",
|
||||
"Once you have trained a scikit-learn model, you will want to save it at a Cloud Storage location, so it can subsequently be uploaded to a `Vertex AI Model` resource. The Scikit-learn package does not have support to save the model to a Cloud Storage location. Instead, you will do the following steps to save to a Cloud Storage location.\n",
|
||||
"\n",
|
||||
"1. Save the in-memory model to the local filesystem in pickle format (e.g., model.pkl).\n",
|
||||
"2. Create a Cloud Storage storage client.\n",
|
||||
@@ -955,7 +1162,6 @@
|
||||
"\n",
|
||||
"\n",
|
||||
"- Model\n",
|
||||
"- Custom Job (already deleted in previous cell)\n",
|
||||
"- Cloud Storage Bucket"
|
||||
]
|
||||
},
|
||||
@@ -970,7 +1176,8 @@
|
||||
"# Delete the model using the Vertex model object\n",
|
||||
"model.delete()\n",
|
||||
"\n",
|
||||
"if os.getenv(\"IS_TESTING\"):\n",
|
||||
"delete_bucket = False\n",
|
||||
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_xgboost.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_vertex_training_xgboost.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -66,17 +66,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex AI Training for XGBoost."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:iris,lcn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Iris dataset](https://www.tensorflow.org/datasets/catalog/iris) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). This dataset does not require any feature engineering. The version of the dataset you will use in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the type of Iris flower species from a class of three species: setosa, virginica, or versicolor."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -97,8 +86,26 @@
|
||||
"- Training using a Python package.\n",
|
||||
"- Report accuracy when hyperparameter tuning.\n",
|
||||
"- Save the model artifacts to Cloud Storage using GCSFuse.\n",
|
||||
"- Create a `Vertex AI Model` resource.\n",
|
||||
"- Create a `Vertex AI Model` resource."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:iris,lcn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Iris dataset](https://www.tensorflow.org/datasets/catalog/iris) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). This dataset does not require any feature engineering. The version of the dataset in this tutorial is stored in a public Cloud Storage bucket. The trained model predicts the type of Iris flower species from a class of three species: setosa, virginica, or versicolor."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "4fc0ad661ebb"
|
||||
},
|
||||
"source": [
|
||||
"### Costs \n",
|
||||
"\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
@@ -122,7 +129,7 @@
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"\n",
|
||||
"Install *one time* the packages for executing the MLOps notebooks."
|
||||
"Install the following packages to execute this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -133,20 +140,76 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
|
||||
"# ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
|
||||
"# ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
|
||||
"# ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
|
||||
"# ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
|
||||
"# ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
|
||||
"# ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
|
||||
"# ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
|
||||
"# ! pip3 install --upgrade pyarrow $USER_FLAG\n",
|
||||
"# ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
|
||||
"# ! pip3 install --upgrade kfp $USER_FLAG\n",
|
||||
"# ! pip3 install --upgrade torchvision $USER_FLAG\n",
|
||||
"# ! pip3 install --upgrade rpy2 $USER_FLAG"
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "oQhwq1iozAxh"
|
||||
},
|
||||
"source": [
|
||||
"### Restart the kernel\n",
|
||||
"\n",
|
||||
"After you install the additional packages, you need to restart the notebook kernel so it can find the packages."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "zo3YFZXLzCRJ"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Automatically restart kernel after installs\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"if not os.getenv(\"IS_TESTING\"):\n",
|
||||
" # Automatically restart kernel after installs\n",
|
||||
" import IPython\n",
|
||||
"\n",
|
||||
" app = IPython.Application.instance()\n",
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2721ef0202d9"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). \n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -234,25 +297,59 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "timestamp"
|
||||
"id": "06571eb4063b"
|
||||
},
|
||||
"source": [
|
||||
"#### Timestamp\n",
|
||||
"#### UUID\n",
|
||||
"\n",
|
||||
"If you are in a live tutorial session, you might be using a shared test account or project. To avoid name collisions between users on resources created, you create a timestamp for each instance session, and append the timestamp onto the name of resources you create in this tutorial."
|
||||
"If you are in a live tutorial session, you might be using a shared test account or project. To avoid name collisions between users on resources created, you create a uuid for each instance session, and append it onto the name of resources you create in this tutorial."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "JYtXOocrox9Q"
|
||||
"id": "4e166d927e36"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"import random\n",
|
||||
"import string\n",
|
||||
"\n",
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
"\n",
|
||||
"# Generate a uuid of a specifed length(default=8)\n",
|
||||
"def generate_uuid(length: int = 8) -> str:\n",
|
||||
" return \"\".join(random.choices(string.ascii_lowercase + string.digits, k=length))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"UUID = generate_uuid()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "77c385f0db59"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"1. **Click Create service account**.\n",
|
||||
"\n",
|
||||
"2. In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"3. In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex AI\" into the filter box, and select **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"4. Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"5. Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -263,19 +360,19 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Google Cloud Notebooks, then don't execute this code\n",
|
||||
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = \"google.colab\" in sys.modules\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
@@ -311,7 +408,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
"BUCKET_NAME = \"[your-bucket-name]\" # @param {type:\"string\"}\n",
|
||||
"BUCKET_URI = f\"gs://{BUCKET_NAME}\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -322,8 +420,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = PROJECT_ID + \"aip-\" + UUID\n",
|
||||
" BUCKET_URI = \"gs://\" + BUCKET_NAME"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -658,6 +757,7 @@
|
||||
"import hypertune\n",
|
||||
"import argparse\n",
|
||||
"import logging\n",
|
||||
"import numpy as np\n",
|
||||
"\n",
|
||||
"from sklearn.model_selection import train_test_split\n",
|
||||
"from sklearn.metrics import accuracy_score\n",
|
||||
@@ -699,16 +799,23 @@
|
||||
"def train_model(dtrain):\n",
|
||||
" logging.info(\"Start training ...\")\n",
|
||||
" # Train XGBoost model\n",
|
||||
" model = xgb.train({}, dtrain, num_boost_round=args.boost_rounds)\n",
|
||||
" params = {\n",
|
||||
" 'objective': 'multi:softprob',\n",
|
||||
" 'num_class': 3\n",
|
||||
" }\n",
|
||||
" model = xgb.train(params, dtrain, num_boost_round=args.boost_rounds)\n",
|
||||
" logging.info(\"Training completed\")\n",
|
||||
" return model\n",
|
||||
"\n",
|
||||
"def evaluate_model(model, test_data, test_labels):\n",
|
||||
" dtest = xgb.DMatrix(test_data)\n",
|
||||
" pred = model.predict(dtest)\n",
|
||||
" predictions = [round(value) for value in pred]\n",
|
||||
" predictions = [np.around(value) for value in pred]\n",
|
||||
" # evaluate predictions\n",
|
||||
" accuracy = accuracy_score(test_labels, predictions)\n",
|
||||
" try:\n",
|
||||
" accuracy = accuracy_score(test_labels, predictions)\n",
|
||||
" except:\n",
|
||||
" accuracy = 0.0\n",
|
||||
" logging.info(f\"Evaluation completed with model accuracy: {accuracy}\")\n",
|
||||
"\n",
|
||||
" # report metric for hyperparameter tuning\n",
|
||||
@@ -802,7 +909,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"DISPLAY_NAME = \"iris_\" + TIMESTAMP\n",
|
||||
"DISPLAY_NAME = \"iris_\" + UUID\n",
|
||||
"\n",
|
||||
"job = aip.CustomPythonPackageTrainingJob(\n",
|
||||
" display_name=DISPLAY_NAME,\n",
|
||||
@@ -841,7 +948,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MODEL_DIR = \"{}/{}\".format(BUCKET_URI, TIMESTAMP)\n",
|
||||
"MODEL_DIR = \"{}/{}\".format(BUCKET_URI, UUID)\n",
|
||||
"DATASET_DIR = \"gs://cloud-samples-data/ai-platform/iris\"\n",
|
||||
"\n",
|
||||
"ROUNDS = 20\n",
|
||||
@@ -892,7 +999,7 @@
|
||||
"source": [
|
||||
"if TRAIN_GPU:\n",
|
||||
" model = job.run(\n",
|
||||
" model_display_name=\"iris_\" + TIMESTAMP,\n",
|
||||
" model_display_name=\"iris_\" + UUID,\n",
|
||||
" args=CMDARGS,\n",
|
||||
" replica_count=1,\n",
|
||||
" machine_type=TRAIN_COMPUTE,\n",
|
||||
@@ -903,7 +1010,7 @@
|
||||
" )\n",
|
||||
"else:\n",
|
||||
" model = job.run(\n",
|
||||
" model_display_name=\"iris_\" + TIMESTAMP,\n",
|
||||
" model_display_name=\"iris_\" + UUID,\n",
|
||||
" args=CMDARGS,\n",
|
||||
" replica_count=1,\n",
|
||||
" machine_type=TRAIN_COMPUTE,\n",
|
||||
@@ -1004,7 +1111,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if os.getenv(\"IS_TESTING\"):\n",
|
||||
"delete_bucket = True\n",
|
||||
"\n",
|
||||
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"id": "title:generic,gcp"
|
||||
},
|
||||
"source": [
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex Vizier\n",
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Vertex AI Vizier\n",
|
||||
"\n",
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
@@ -39,7 +39,12 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_vizier.ipynb\">\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_vertex_vizier.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_vertex_vizier.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -57,18 +62,7 @@
|
||||
"## Overview\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex Vizier."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:custom,boston,lrg"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Boston Housing Prices dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html). The version of the dataset you will use in this tutorial is built into TensorFlow. The trained model predicts the median price of a house in units of 1K USD."
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Vertex AI Vizier."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -90,7 +84,8 @@
|
||||
"The steps performed include:\n",
|
||||
"\n",
|
||||
"- Hyperparameter tuning with Random algorithm.\n",
|
||||
"- Hyperparameter tuning with Vizier (Bayesian) algorithm."
|
||||
"- Hyperparameter tuning with Vizier (Bayesian) algorithm.\n",
|
||||
"- Suggesting trials and updating results for Vizier study"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -129,6 +124,38 @@
|
||||
"- multiple of objectives"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:custom,boston,lrg"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Boston Housing Prices dataset](https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html). The version of the dataset in this tutorial is built into TensorFlow. The trained model predicts the median price of a house in units of 1K USD."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "c480fc50ec3c"
|
||||
},
|
||||
"source": [
|
||||
"### Costs \n",
|
||||
"\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"* Vertex AI\n",
|
||||
"* Cloud Storage\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI\n",
|
||||
"pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage\n",
|
||||
"pricing](https://cloud.google.com/storage/pricing), and use the [Pricing\n",
|
||||
"Calculator](https://cloud.google.com/products/calculator/)\n",
|
||||
"to generate a cost estimate based on your projected usage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -137,7 +164,7 @@
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"\n",
|
||||
"Install *one time* the packages for executing the MLOps notebooks."
|
||||
"Install the packages required for executing this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -150,25 +177,19 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook requires dependencies to be installed with '--user'\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "install_mlops"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
|
||||
" "
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade $USER_FLAG -q google-cloud-aiplatform \\\n",
|
||||
" google-vizier==0.0.4"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -200,6 +221,32 @@
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2721ef0202d9"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). \n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -284,25 +331,93 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "timestamp"
|
||||
"id": "06571eb4063b"
|
||||
},
|
||||
"source": [
|
||||
"#### Timestamp\n",
|
||||
"#### UUID\n",
|
||||
"\n",
|
||||
"If you are in a live tutorial session, you might be using a shared test account or project. To avoid name collisions between users on resources created, you create a timestamp for each instance session, and append the timestamp onto the name of resources you create in this tutorial."
|
||||
"If you are in a live tutorial session, you might be using a shared test account or project. To avoid name collisions between users on resources created, you create a uuid for each instance session, and append it onto the name of resources you create in this tutorial."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "timestamp"
|
||||
"id": "4e166d927e36"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"import random\n",
|
||||
"import string\n",
|
||||
"\n",
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
"\n",
|
||||
"# Generate a uuid of a specifed length(default=8)\n",
|
||||
"def generate_uuid(length: int = 8) -> str:\n",
|
||||
" return \"\".join(random.choices(string.ascii_lowercase + string.digits, k=length))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"UUID = generate_uuid()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "gcp_authenticate"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. \n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"**Click Create service account**.\n",
|
||||
"\n",
|
||||
"In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex\" into the filter box, and select **Vertex Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "gcp_authenticate"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -340,7 +455,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + UUID"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -403,7 +518,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import google.cloud.aiplatform as aip"
|
||||
"import google.cloud.aiplatform as aip\n",
|
||||
"from google.cloud.aiplatform.vizier import Study, pyvizier"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -428,35 +544,6 @@
|
||||
"aip.init(project=PROJECT_ID, staging_bucket=BUCKET_URI)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "aip_constants"
|
||||
},
|
||||
"source": [
|
||||
"#### Vertex AI constants\n",
|
||||
"\n",
|
||||
"Setup up the following constants for Vertex AI:\n",
|
||||
"\n",
|
||||
"- `API_ENDPOINT`: The Vertex AI API service endpoint for `Dataset`, `Model`, `Job`, `Pipeline` and `Endpoint` services.\n",
|
||||
"- `PARENT`: The Vertex AI location root path for `Dataset`, `Model`, `Job`, `Pipeline` and `Endpoint` resources."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "aip_constants"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# API service endpoint\n",
|
||||
"API_ENDPOINT = \"{}-aiplatform.googleapis.com\".format(REGION)\n",
|
||||
"\n",
|
||||
"# Vertex location root path for your dataset, model and endpoint resources\n",
|
||||
"PARENT = \"projects/\" + PROJECT_ID + \"/locations/\" + REGION"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -520,7 +607,7 @@
|
||||
"if os.getenv(\"IS_TESTING_TF\"):\n",
|
||||
" TF = os.getenv(\"IS_TESTING_TF\")\n",
|
||||
"else:\n",
|
||||
" TF = \"2.1\".replace(\".\", \"-\")\n",
|
||||
" TF = \"2.5\".replace(\".\", \"-\")\n",
|
||||
"\n",
|
||||
"if TF[0] == \"2\":\n",
|
||||
" if TRAIN_GPU:\n",
|
||||
@@ -925,7 +1012,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"JOB_NAME = \"custom_job_\" + TIMESTAMP\n",
|
||||
"JOB_NAME = \"custom_job_\" + UUID\n",
|
||||
"MODEL_DIR = \"{}/{}\".format(BUCKET_URI, JOB_NAME)\n",
|
||||
"\n",
|
||||
"if not TRAIN_NGPU or TRAIN_NGPU < 2:\n",
|
||||
@@ -988,9 +1075,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"job = aip.CustomJob(\n",
|
||||
" display_name=\"boston_\" + TIMESTAMP, worker_pool_specs=worker_pool_spec\n",
|
||||
")"
|
||||
"job = aip.CustomJob(display_name=\"boston_\" + UUID, worker_pool_specs=worker_pool_spec)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1022,7 +1107,7 @@
|
||||
"from google.cloud.aiplatform import hyperparameter_tuning as hpt\n",
|
||||
"\n",
|
||||
"hpt_job = aip.HyperparameterTuningJob(\n",
|
||||
" display_name=\"boston_\" + TIMESTAMP,\n",
|
||||
" display_name=\"boston_\" + UUID,\n",
|
||||
" custom_job=job,\n",
|
||||
" metric_spec={\n",
|
||||
" \"val_loss\": \"minimize\",\n",
|
||||
@@ -1190,7 +1275,8 @@
|
||||
"Use the class `CustomJob` to create a custom job, such as for hyperparameter tuning, with the following parameters:\n",
|
||||
"\n",
|
||||
"- `display_name`: A human readable name for the custom job.\n",
|
||||
"- `worker_pool_specs`: The specification for the corresponding VM instances."
|
||||
"- `worker_pool_specs`: The specification for the corresponding VM instances.\n",
|
||||
"- `base_output_dir`: The Cloud Storage location for storing the model artifacts."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1202,7 +1288,9 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"job = aip.CustomJob(\n",
|
||||
" display_name=\"boston_\" + TIMESTAMP, worker_pool_specs=worker_pool_spec\n",
|
||||
" display_name=\"boston_\" + UUID,\n",
|
||||
" worker_pool_specs=worker_pool_spec,\n",
|
||||
" base_output_dir=MODEL_DIR,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
@@ -1235,7 +1323,7 @@
|
||||
"from google.cloud.aiplatform import hyperparameter_tuning as hpt\n",
|
||||
"\n",
|
||||
"hpt_job = aip.HyperparameterTuningJob(\n",
|
||||
" display_name=\"boston_\" + TIMESTAMP,\n",
|
||||
" display_name=\"boston_\" + UUID,\n",
|
||||
" custom_job=job,\n",
|
||||
" metric_spec={\n",
|
||||
" \"val_loss\": \"minimize\",\n",
|
||||
@@ -1335,6 +1423,32 @@
|
||||
"print(best)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "get_best_model"
|
||||
},
|
||||
"source": [
|
||||
"### Get the Best Model\n",
|
||||
"\n",
|
||||
"If you used the method of having the service tell the tuning script where to save the model artifacts (`DIRECT = False`), then the model artifacts for the best model are saved at:\n",
|
||||
"\n",
|
||||
" MODEL_DIR/<best_trial_id>/model"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "get_best_model"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BEST_MODEL_DIR = MODEL_DIR + \"/\" + best[0] + \"/model\"\n",
|
||||
"\n",
|
||||
"! gsutil ls {BEST_MODEL_DIR}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -1378,22 +1492,25 @@
|
||||
"id": "vizier_client"
|
||||
},
|
||||
"source": [
|
||||
"### Create Vizier client\n",
|
||||
"### Specify the algorithm used to suggest trial parameters\n",
|
||||
"\n",
|
||||
"Create a client side connection to the Vertex AI Vizier service."
|
||||
"First, you create a `StudyConfig`, and specify the algorithm to suggest the next trial.\n",
|
||||
"\n",
|
||||
" GRID_SEARCH: grid search\n",
|
||||
" RANDOM_SEARCH: random search\n",
|
||||
" ALGORIGTHM_UNSPECIFIED: Vizier bayesian algorithm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "vizier_client"
|
||||
"id": "d7dd26490358"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"vizier_client = aip.gapic.VizierServiceClient(\n",
|
||||
" client_options=dict(api_endpoint=API_ENDPOINT)\n",
|
||||
")"
|
||||
"problem = pyvizier.StudyConfig()\n",
|
||||
"problem.algorithm = pyvizier.Algorithm.RANDOM_SEARCH"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1408,7 +1525,15 @@
|
||||
"\n",
|
||||
"In the following example, the goal is to maximize y = x^2 with x in the range of \\[-10. 10\\]. This example has only one parameter and uses an easily calculated function to help demonstrate how to use Vizier.\n",
|
||||
"\n",
|
||||
"First, you will create the study using the `create_study()` method."
|
||||
"First, you specify the metrics to minimize or maximize in the study as a list to the property `metric_information`. Then you specify the parameters to the study using the `add_XXX_params()` method for the corresponding data type:\n",
|
||||
"\n",
|
||||
" - add_bool_param\n",
|
||||
" - add_categorical_param\n",
|
||||
" - add_discrete_param\n",
|
||||
" - add_float_param\n",
|
||||
" - add_int_param\n",
|
||||
"\n",
|
||||
"You create the study using the `create_or_load()` method."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1419,28 +1544,19 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"STUDY_DISPLAY_NAME = \"xpow2\" + TIMESTAMP\n",
|
||||
"STUDY_DISPLAY_NAME = \"xpow2\" + UUID\n",
|
||||
"\n",
|
||||
"param_x = {\n",
|
||||
" \"parameter_id\": \"x\",\n",
|
||||
" \"double_value_spec\": {\"min_value\": -10.0, \"max_value\": 10.0},\n",
|
||||
"}\n",
|
||||
"problem.metric_information.append(\n",
|
||||
" pyvizier.MetricInformation(name=\"y\", goal=pyvizier.ObjectiveMetricGoal.MAXIMIZE)\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"metric_y = {\"metric_id\": \"y\", \"goal\": \"MAXIMIZE\"}\n",
|
||||
"params = problem.search_space.select_root()\n",
|
||||
"params.add_float_param(\"x\", -10.0, 10.0, scale_type=pyvizier.ScaleType.LINEAR)\n",
|
||||
"\n",
|
||||
"study = {\n",
|
||||
" \"display_name\": STUDY_DISPLAY_NAME,\n",
|
||||
" \"study_spec\": {\n",
|
||||
" \"algorithm\": \"RANDOM_SEARCH\",\n",
|
||||
" \"parameters\": [param_x],\n",
|
||||
" \"metrics\": [metric_y],\n",
|
||||
" },\n",
|
||||
"}\n",
|
||||
"study = Study.create_or_load(display_name=STUDY_DISPLAY_NAME, problem=problem)\n",
|
||||
"\n",
|
||||
"study = vizier_client.create_study(parent=PARENT, study=study)\n",
|
||||
"STUDY_NAME = study.name\n",
|
||||
"\n",
|
||||
"print(STUDY_NAME)"
|
||||
"print(\"STUDY_NAME: {}\".format(STUDY_NAME))"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1451,9 +1567,7 @@
|
||||
"source": [
|
||||
"### Get Vizier study\n",
|
||||
"\n",
|
||||
"You can get a study using the method `get_study()`, with the following key/value pairs:\n",
|
||||
"\n",
|
||||
"- `name`: The name of the study."
|
||||
"You can get a study using the method `list()`."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1464,9 +1578,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"study = vizier_client.get_study({\"name\": STUDY_NAME})\n",
|
||||
"\n",
|
||||
"print(study)"
|
||||
"studies = Study.list()\n",
|
||||
"print(studies[0].gca_resource)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1477,11 +1590,9 @@
|
||||
"source": [
|
||||
"### Get suggested trial\n",
|
||||
"\n",
|
||||
"Next, query the Vizier service for a suggested trial(s) using the method `suggest_trials`, with the following key/value pairs:\n",
|
||||
"Next, query the Vizier service for a suggested trial(s) using the method `suggest()`, with the following key/value pairs:\n",
|
||||
"\n",
|
||||
"- `parent`: The name of the study.\n",
|
||||
"- `suggestion_count`: The number of trials to suggest.\n",
|
||||
"- `client_id`: blah\n",
|
||||
"- `count`: The number of trials to suggest.\n",
|
||||
"\n",
|
||||
"This call is a long running operation. The method `result()` from the response object will wait until the call has completed."
|
||||
]
|
||||
@@ -1490,18 +1601,13 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "vizier_suggest_trial"
|
||||
"id": "11ff2c4562cb"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"SUGGEST_COUNT = 1\n",
|
||||
"CLIENT_ID = \"1001\"\n",
|
||||
"\n",
|
||||
"response = vizier_client.suggest_trials(\n",
|
||||
" {\"parent\": STUDY_NAME, \"suggestion_count\": SUGGEST_COUNT, \"client_id\": CLIENT_ID}\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"trials = response.result().trials\n",
|
||||
"trials = study.suggest(count=SUGGEST_COUNT)\n",
|
||||
"\n",
|
||||
"print(trials)\n",
|
||||
"\n",
|
||||
@@ -1544,12 +1650,10 @@
|
||||
"source": [
|
||||
"RESULT = 0.01\n",
|
||||
"\n",
|
||||
"vizier_client.add_trial_measurement(\n",
|
||||
" {\n",
|
||||
" \"trial_name\": TRIAL_ID,\n",
|
||||
" \"measurement\": {\"metrics\": [{\"metric_id\": \"y\", \"value\": RESULT}]},\n",
|
||||
" }\n",
|
||||
")"
|
||||
"measurement = pyvizier.Measurement()\n",
|
||||
"measurement.metrics[\"y\"] = RESULT\n",
|
||||
"\n",
|
||||
"trials[0].add_measurement(measurement)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1560,7 +1664,7 @@
|
||||
"source": [
|
||||
"### Delete the Vizier study\n",
|
||||
"\n",
|
||||
"The method 'delete_study()' will delete the study."
|
||||
"The method 'delete()' will delete the study."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1571,7 +1675,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"vizier_client.delete_study({\"name\": STUDY_NAME})"
|
||||
"study.delete()"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1598,6 +1702,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"delete_bucket = False\n",
|
||||
"\n",
|
||||
"if os.getenv(\"IS_TESTING\"):\n",
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
]
|
||||
|
||||
@@ -38,8 +38,14 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_cmek_training.ipynb\">\n",
|
||||
" Open in Google Cloud Notebooks\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_cmek_training.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_with_cmek_training.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
"</table>\n",
|
||||
@@ -58,17 +64,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with AutoML training with a customer managed encyrption key CMEK."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:flowers,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset you will use in this tutorial is stored in a public #(GCS) bucket. The trained model predicts the type of flower an image is from a class of five flowers: daisy, dandelion, rose, sunflower, or tulip.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -91,6 +86,37 @@
|
||||
"- Train an AutoML model with CMEK encryption."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:flowers,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Flowers dataset](https://www.tensorflow.org/datasets/catalog/tf_flowers) from [TensorFlow](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset in this tutorial is stored in a public #(GCS) bucket. The trained model predicts the type of flower an image is from a class of five flowers: daisy, dandelion, rose, sunflower, or tulip.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "5e2eba58ad71"
|
||||
},
|
||||
"source": [
|
||||
"### Costs \n",
|
||||
"\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"* Vertex AI\n",
|
||||
"* Cloud Storage\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI\n",
|
||||
"pricing](https://cloud.google.com/vertex-ai/pricing) and [Cloud Storage\n",
|
||||
"pricing](https://cloud.google.com/storage/pricing), and use the [Pricing\n",
|
||||
"Calculator](https://cloud.google.com/products/calculator/)\n",
|
||||
"to generate a cost estimate based on your projected usage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -110,10 +136,21 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"USER_FLAG = \"--user\"\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG\n",
|
||||
"! pip3 install --upgrade google-cloud-kms $USER_FLAG"
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG -q\n",
|
||||
"! pip3 install --upgrade google-cloud-kms $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -145,6 +182,39 @@
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "013daf3de88e"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "d1afc945645f"
|
||||
},
|
||||
"source": [
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). \n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -248,6 +318,82 @@
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "d35af059208d"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already\n",
|
||||
"authenticated. Skip this step."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "a00567d0660a"
|
||||
},
|
||||
"source": [
|
||||
"**If you are using Colab**, run the cell below and follow the instructions\n",
|
||||
"when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"1. In the Cloud Console, go to the [**Create service account key**\n",
|
||||
" page](https://console.cloud.google.com/apis/credentials/serviceaccountkey).\n",
|
||||
"\n",
|
||||
"2. Click **Create service account**.\n",
|
||||
"\n",
|
||||
"3. In the **Service account name** field, enter a name, and\n",
|
||||
" click **Create**.\n",
|
||||
"\n",
|
||||
"4. In the **Grant this service account access to project** section, click the **Role** drop-down list. Type \"Vertex AI\"\n",
|
||||
"into the filter box, and select\n",
|
||||
" **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"5. Click *Create*. A JSON file that contains your key downloads to your\n",
|
||||
"local environment.\n",
|
||||
"\n",
|
||||
"6. Enter the path to your service account key as the\n",
|
||||
"`GOOGLE_APPLICATION_CREDENTIALS` variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "40160162ea4c"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -271,7 +417,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"BUCKET_NAME = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
"BUCKET_URI = \"gs://[your-bucket-name]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -282,8 +428,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if BUCKET_NAME == \"\" or BUCKET_NAME is None or BUCKET_NAME == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_NAME = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
"if BUCKET_URI == \"\" or BUCKET_URI is None or BUCKET_URI == \"gs://[your-bucket-name]\":\n",
|
||||
" BUCKET_URI = \"gs://\" + PROJECT_ID + \"aip-\" + TIMESTAMP"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -303,7 +449,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil mb -l $REGION $BUCKET_NAME"
|
||||
"! gsutil mb -l $REGION $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -323,7 +469,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gsutil ls -al $BUCKET_NAME"
|
||||
"! gsutil ls -al $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -346,7 +492,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import google.cloud.aiplatform as aip\n",
|
||||
"import google.cloud.aiplatform as aiplatform\n",
|
||||
"from google.cloud import kms"
|
||||
]
|
||||
},
|
||||
@@ -369,7 +515,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aip.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_NAME)"
|
||||
"aiplatform.init(project=PROJECT_ID, location=REGION, staging_bucket=BUCKET_URI)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -384,7 +530,7 @@
|
||||
"\n",
|
||||
"### Enable KMS API\n",
|
||||
"\n",
|
||||
"First, you enble the [Cloud Key Management Service (KMS)](https://console.cloud.google.com/flows/enableapi?apiid=cloudkms.googleapis.com)\n",
|
||||
"First, you enable the [Cloud Key Management Service (KMS)](https://console.cloud.google.com/flows/enableapi?apiid=cloudkms.googleapis.com)\n",
|
||||
"\n",
|
||||
"Learn more about [Customer managed encryption keys (CMEK)](https://cloud.google.com/vertex-ai/docs/general/cmek)"
|
||||
]
|
||||
@@ -549,6 +695,8 @@
|
||||
"\n",
|
||||
"Next, you set permissions for your Vertex AI service account to encrypt and decrypt resources using your key.\n",
|
||||
"\n",
|
||||
"Note: Compute Engine default service account which is used by this notebook instance for authentication purposes during Google API calls, should be granted the role of Cloud KMS Admin.\n",
|
||||
"\n",
|
||||
"Learn more about [Grant Vertex AI permissions](https://cloud.google.com/vertex-ai/docs/general/cmek#grant_permissions)"
|
||||
]
|
||||
},
|
||||
@@ -638,9 +786,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aip.init(\n",
|
||||
"aiplatform.init(\n",
|
||||
" project=PROJECT_ID,\n",
|
||||
" staging_bucket=BUCKET_NAME,\n",
|
||||
" staging_bucket=BUCKET_URI,\n",
|
||||
" location=REGION,\n",
|
||||
" encryption_spec_key_name=ENCRYPTION_SPEC_KEY_NAME,\n",
|
||||
")"
|
||||
@@ -689,10 +837,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dataset = aip.ImageDataset.create(\n",
|
||||
"dataset = aiplatform.ImageDataset.create(\n",
|
||||
" display_name=\"flowers_\" + TIMESTAMP,\n",
|
||||
" gcs_source=[IMPORT_FILE],\n",
|
||||
" import_schema_uri=aip.schema.dataset.ioformat.image.single_label_classification,\n",
|
||||
" import_schema_uri=aiplatform.schema.dataset.ioformat.image.single_label_classification,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(dataset.resource_name)"
|
||||
@@ -727,7 +875,7 @@
|
||||
"\n",
|
||||
"# This will take around half an hour to run\n",
|
||||
"model = job.run(\n",
|
||||
" dataset=ds,\n",
|
||||
" dataset=dataset,\n",
|
||||
" model_display_name=\"flowers_\" + TIMESTAMP,\n",
|
||||
" training_fraction_split=0.6,\n",
|
||||
" validation_fraction_split=0.2,\n",
|
||||
@@ -827,6 +975,25 @@
|
||||
"endpoint.undeploy_all()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ba77c4e02355"
|
||||
},
|
||||
"source": [
|
||||
"## Cleaning up\n",
|
||||
"\n",
|
||||
"To clean up all Google Cloud resources used in this project, you can [delete the Google Cloud\n",
|
||||
"project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects) you used for the tutorial.\n",
|
||||
"\n",
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial:\n",
|
||||
"\n",
|
||||
"- Model\n",
|
||||
"- Dataset\n",
|
||||
"- Cloud Storage Bucket\n",
|
||||
"- Endpoint"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -835,17 +1002,54 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# missing\n",
|
||||
"# Delete endpoint resource\n",
|
||||
"endpoint.delete()\n",
|
||||
"\n",
|
||||
"# Delete model resource\n",
|
||||
"model.delete()\n",
|
||||
"\n",
|
||||
"# Delete dataset resource\n",
|
||||
"dataset.delete()\n",
|
||||
"\n",
|
||||
"! gcloud kms keys versions destroy key-version \\\n",
|
||||
" --key key {KEY_ID} \\\n",
|
||||
"# Set this to true only if you'd like to delete your bucket\n",
|
||||
"delete_bucket = False\n",
|
||||
"\n",
|
||||
"if delete_bucket or os.getenv(\"IS_TESTING\"):\n",
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "d88c8a053a90"
|
||||
},
|
||||
"source": [
|
||||
"## Destroying CMEK by providing key-version value and other parameters."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "5d8d2fc34346"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gcloud kms keys versions destroy 1 \\\n",
|
||||
" --key {KEY_ID} \\\n",
|
||||
" --keyring={KEY_RING_ID} \\\n",
|
||||
" --location={REGION} "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "f7e42e642ad3"
|
||||
},
|
||||
"source": [
|
||||
"## List of keys "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
|
||||
+1446
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,710 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "copyright"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Copyright 2022 Google LLC\n",
|
||||
"#\n",
|
||||
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
|
||||
"# you may not use this file except in compliance with the License.\n",
|
||||
"# You may obtain a copy of the License at\n",
|
||||
"#\n",
|
||||
"# https://www.apache.org/licenses/LICENSE-2.0\n",
|
||||
"#\n",
|
||||
"# Unless required by applicable law or agreed to in writing, software\n",
|
||||
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
|
||||
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
|
||||
"# See the License for the specific language governing permissions and\n",
|
||||
"# limitations under the License."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "title:generic,gcp"
|
||||
},
|
||||
"source": [
|
||||
"# E2E ML on GCP: MLOps stage 2 : experimentation: get started with Logging\n",
|
||||
"\n",
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_logging.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_logging.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_with_logging.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
"</table>\n",
|
||||
"<br/><br/><br/>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "overview:mlops"
|
||||
},
|
||||
"source": [
|
||||
"## Overview\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with Logging."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "objective:mlops,stage2,get_started_vertex_experiments"
|
||||
},
|
||||
"source": [
|
||||
"### Objective\n",
|
||||
"\n",
|
||||
"In this tutorial, you learn how to use Python and Cloud logging when training with `Vertex AI`.\n",
|
||||
"\n",
|
||||
"This tutorial uses the following Google Cloud ML services:\n",
|
||||
"\n",
|
||||
"- `Cloud Logging`\n",
|
||||
"\n",
|
||||
"The steps performed include:\n",
|
||||
"\n",
|
||||
"- Use Python logging to log training configuration/results locally.\n",
|
||||
"- Use Google Cloud Logging to log training configuration/results in cloud storage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "recommendation:mlops,stage2,logging"
|
||||
},
|
||||
"source": [
|
||||
"### Recommendations\n",
|
||||
"\n",
|
||||
"When doing E2E MLOps on Google Cloud, the following are some of the best practices for logging data when experimenting or formally training a model.\n",
|
||||
"\n",
|
||||
"#### Python Logging\n",
|
||||
"\n",
|
||||
"Use Python's logging package when doing ad-hoc training locally.\n",
|
||||
"\n",
|
||||
"#### Cloud Logging\n",
|
||||
"\n",
|
||||
"Use `Google Cloud Logging` when doing training on the cloud.\n",
|
||||
"\n",
|
||||
"#### Experiments\n",
|
||||
"\n",
|
||||
"Use Vertex AI Experiments in conjunction with logging when performing experiments to compare results for different experiment configurations."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "5341f31587c8"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"This tutorial does not use a dataset. References to example datasets is for demonstration purposes."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "41512a89f379"
|
||||
},
|
||||
"source": [
|
||||
"### Costs\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"- Vertex AI\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "install_mlops"
|
||||
},
|
||||
"source": [
|
||||
"## Installations\n",
|
||||
"\n",
|
||||
"Install the following packages for executing this notebook."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "install_mlops"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade google-cloud-logging $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "restart"
|
||||
},
|
||||
"source": [
|
||||
"### Restart the kernel\n",
|
||||
"\n",
|
||||
"Once you've installed the additional packages, you need to restart the notebook kernel so it can find the packages."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "restart"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"if not os.getenv(\"IS_TESTING\"):\n",
|
||||
" # Automatically restart kernel after installs\n",
|
||||
" import IPython\n",
|
||||
"\n",
|
||||
" app = IPython.Application.instance()\n",
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "project_id"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI, Compute Engine, Cloud Storage and Cloud Logging APIs](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,compute_component,storage_component,logging).\n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "5aee4379e8e5"
|
||||
},
|
||||
"source": [
|
||||
"#### Set your project ID\n",
|
||||
"\n",
|
||||
"**If you don't know your project ID**, you may be able to get your project ID using `gcloud`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "set_project_id"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "autoset_project_id"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if PROJECT_ID == \"\" or PROJECT_ID is None or PROJECT_ID == \"[your-project-id]\":\n",
|
||||
" # Get your GCP project id from gcloud\n",
|
||||
" shell_output = ! gcloud config list --format 'value(core.project)' 2>/dev/null\n",
|
||||
" PROJECT_ID = shell_output[0]\n",
|
||||
" print(\"Project ID:\", PROJECT_ID)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "set_gcloud_project_id"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! gcloud config set project $PROJECT_ID"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "region"
|
||||
},
|
||||
"source": [
|
||||
"#### Region\n",
|
||||
"\n",
|
||||
"You can also change the `REGION` variable, which is used for operations\n",
|
||||
"throughout the rest of this notebook. Below are regions supported for Vertex AI. We recommend that you choose the region closest to you.\n",
|
||||
"\n",
|
||||
"- Americas: `us-central1`\n",
|
||||
"- Europe: `europe-west4`\n",
|
||||
"- Asia Pacific: `asia-east1`\n",
|
||||
"\n",
|
||||
"You may not use a multi-regional bucket for training with Vertex AI. Not all regions provide support for all Vertex AI services.\n",
|
||||
"\n",
|
||||
"Learn more about [Vertex AI regions](https://cloud.google.com/vertex-ai/docs/general/locations)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "region"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"[your-region]\" # @param {type: \"string\"}\n",
|
||||
"\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "timestamp"
|
||||
},
|
||||
"source": [
|
||||
"#### Timestamp\n",
|
||||
"\n",
|
||||
"If you are in a live tutorial session, you might be using a shared test account or project. To avoid name collisions between users on resources created, you create a timestamp for each instance session, and append the timestamp onto the name of resources you create in this tutorial."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "timestamp"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "f3bd8c0d0469"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"In the Cloud Console, go to the [Create service account key](https://console.cloud.google.com/apis/credentials/serviceaccountkey) page.\n",
|
||||
"\n",
|
||||
"1. **Click Create service account**.\n",
|
||||
"\n",
|
||||
"2. In the **Service account name** field, enter a name, and click **Create**.\n",
|
||||
"\n",
|
||||
"3. In the **Grant this service account access to project** section, click the Role drop-down list. Type \"Vertex AI\" into the filter box, and select **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"4. Click Create. A JSON file that contains your key downloads to your local environment.\n",
|
||||
"\n",
|
||||
"5. Enter the path to your service account key as the GOOGLE_APPLICATION_CREDENTIALS variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "e0953a00668e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = \"google.colab\" in sys.modules\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "setup_vars"
|
||||
},
|
||||
"source": [
|
||||
"### Set up variables\n",
|
||||
"\n",
|
||||
"Next, set up some variables used throughout the tutorial.\n",
|
||||
"### Import libraries"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "import_aip:mbsdk"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import logging\n",
|
||||
"\n",
|
||||
"import google.cloud.aiplatform as aiplatform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "init_aip:mbsdk,region"
|
||||
},
|
||||
"source": [
|
||||
"### Initialize Vertex AI SDK for Python\n",
|
||||
"\n",
|
||||
"Initialize the Vertex AI SDK for Python for your project and corresponding bucket."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "init_aip:mbsdk,region"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"aiplatform.init(project=PROJECT_ID, location=REGION)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "python_logging"
|
||||
},
|
||||
"source": [
|
||||
"## Python Logging\n",
|
||||
"\n",
|
||||
"The Python logging package is widely used for logging within Python scripts. Commonly used features:\n",
|
||||
"\n",
|
||||
"- Set logging levels.\n",
|
||||
"- Send log output to console.\n",
|
||||
"- Send log output to a file.\n",
|
||||
"\n",
|
||||
"### Logging Levels in Python Logging\n",
|
||||
"\n",
|
||||
"The logging levels in order (from least to highest) and each level inclusive of the previous level are :\n",
|
||||
"\n",
|
||||
"1. Informational\n",
|
||||
"2. Warnings\n",
|
||||
"3. Errors\n",
|
||||
"4. Debugging\n",
|
||||
"\n",
|
||||
"By default, the logging level is set to error level.\n",
|
||||
"\n",
|
||||
"### Logging output to console\n",
|
||||
"\n",
|
||||
"By default, the Python logging package outputs to the console. Note, in the example the debug log message is not outputted since the default logging level is set to error."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "python_logging"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def logging_examples():\n",
|
||||
" logging.info(\"Model training started...\")\n",
|
||||
" logging.warning(\"Using older version of package ...\")\n",
|
||||
" logging.error(\"Training was terminated ...\")\n",
|
||||
" logging.debug(\"Hyperparameters were ...\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"logging_examples()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "python_logging_level"
|
||||
},
|
||||
"source": [
|
||||
"### Setting logging level\n",
|
||||
"\n",
|
||||
"To set the logging level, you get the logging handler using `getLogger()`. You can have multiple logging handles. When `getLogger()` is called without any arguments, it gets the default handler named ROOT. With the handler, you set the logging level with the method `setLevel()`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "python_logging_level"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"logging.getLogger().setLevel(logging.DEBUG)\n",
|
||||
"\n",
|
||||
"logging_examples()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "python_logging_remove"
|
||||
},
|
||||
"source": [
|
||||
"### Clearing handlers\n",
|
||||
"\n",
|
||||
"At times, you may desire to reconfigure your logging. A common practice in this case is to first remove all existing logging handles for a fresh start."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "python_logging_remove"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"for handler in logging.root.handlers[:]:\n",
|
||||
" logging.root.removeHandler(handler)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "python_logging_file"
|
||||
},
|
||||
"source": [
|
||||
"### Output to a local file\n",
|
||||
"\n",
|
||||
"You can preserve your logging output to a file that is local to where the Python script is running with the method `BasicConfig()`, that takes the following parameters:\n",
|
||||
"\n",
|
||||
"- `filename`: The file path to the local file to write the log output to.\n",
|
||||
"- `level`: Sets the level of logging that is written to the logging file.\n",
|
||||
"\n",
|
||||
"*Note:* You cannot use a Cloud Storage bucket as the output file."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "python_logging_file"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"logging.basicConfig(filename=\"mylog.log\", level=logging.DEBUG)\n",
|
||||
"\n",
|
||||
"logging_examples()\n",
|
||||
"\n",
|
||||
"! cat mylog.log"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "cloud_logging"
|
||||
},
|
||||
"source": [
|
||||
"## Logging with Google Cloud Logging\n",
|
||||
"\n",
|
||||
"You can preserve and retrieve your logging output to `Google Cloud Logging` service. Commonly used features:\n",
|
||||
"\n",
|
||||
"- Set logging levels.\n",
|
||||
"- Send log output to storage.\n",
|
||||
"- Retrieve log output from storage.\n",
|
||||
"\n",
|
||||
"### Logging Levels in Cloud Logging\n",
|
||||
"\n",
|
||||
"The logging levels in order (from least to highest) are, with each level inclusive of the previous level:\n",
|
||||
"\n",
|
||||
"1. Informational\n",
|
||||
"2. Warnings\n",
|
||||
"3. Errors\n",
|
||||
"4. Debugging\n",
|
||||
"\n",
|
||||
"By default, the logging level is set to warning level.\n",
|
||||
"\n",
|
||||
"### Configurable and storing log data.\n",
|
||||
"\n",
|
||||
"To use the `Google Cloud Logging` service, you do the following steps:\n",
|
||||
"\n",
|
||||
"1. Create a client to the service.\n",
|
||||
"2. Obtain a handler for the service.\n",
|
||||
"3. Create a logger instance and set logging level.\n",
|
||||
"4. Attach logger instance to the service.\n",
|
||||
"\n",
|
||||
"Learn more about [Logging client libraries](https://cloud.google.com/logging/docs/reference/libraries)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "cloud_logging"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import google.cloud.logging\n",
|
||||
"from google.cloud.logging.handlers import CloudLoggingHandler\n",
|
||||
"\n",
|
||||
"# Connect to the Cloud Logging service\n",
|
||||
"cl_client = google.cloud.logging.Client(project=PROJECT_ID)\n",
|
||||
"handler = CloudLoggingHandler(cl_client, name=\"mylog\")\n",
|
||||
"\n",
|
||||
"# Create a logger instance and logging level\n",
|
||||
"cloud_logger = logging.getLogger(\"cloudLogger\")\n",
|
||||
"cloud_logger.setLevel(logging.INFO)\n",
|
||||
"\n",
|
||||
"# Attach the logger instance to the service.\n",
|
||||
"cloud_logger.addHandler(handler)\n",
|
||||
"\n",
|
||||
"# Log something\n",
|
||||
"cloud_logger.error(\"bad news\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "cloud_logging_write"
|
||||
},
|
||||
"source": [
|
||||
"### Logging output\n",
|
||||
"\n",
|
||||
"Logging output at specific levels is identical to Python logging with respect to method and method names. The only difference is that you use your instance of the cloud logger in place of logging."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "cloud_logging_write"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"cloud_logger.info(\"Model training started...\")\n",
|
||||
"cloud_logger.warning(\"Using older version of package ...\")\n",
|
||||
"cloud_logger.error(\"Training was terminated ...\")\n",
|
||||
"cloud_logger.debug(\"Hyperparameters were ...\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "cloud_logging_list"
|
||||
},
|
||||
"source": [
|
||||
"### Get logging entries\n",
|
||||
"\n",
|
||||
"To get the logged output, you:\n",
|
||||
"\n",
|
||||
"1. Retrieve the log handle to the service.\n",
|
||||
"2. Using the handle, call the method `list_entries()`.\n",
|
||||
"3. Iterate through the entries."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "cloud_logging_list"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"logger = cl_client.logger(\"mylog\")\n",
|
||||
"\n",
|
||||
"for entry in logger.list_entries():\n",
|
||||
" timestamp = entry.timestamp.isoformat()\n",
|
||||
" print(\"* {}: {}: {}\".format(timestamp, entry.severity, entry.payload))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "cleanup:mbsdk"
|
||||
},
|
||||
"source": [
|
||||
"# Cleaning up\n",
|
||||
"\n",
|
||||
"To clean up all Google Cloud resources used in this project, you can [delete the Google Cloud\n",
|
||||
"project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#shutting_down_projects) you used for the tutorial.\n",
|
||||
"\n",
|
||||
"Otherwise, you can delete the individual resources you created in this tutorial."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"name": "get_started_with_logging.ipynb",
|
||||
"toc_visible": true
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"name": "python3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -34,18 +34,18 @@
|
||||
"<table align=\"left\">\n",
|
||||
"\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/community/ml_ops/stage2/get_started_with_tabnet.ipynb\">\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_tabnet.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samplestree/master/notebooks/community/ml_ops/stage2/get_started_with_tabnet.ipynb\">\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_tabnet.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/master/notebooks/community/ml_ops/stage2/get_started_with_tabnet.ipynb\">\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_with_tabnet.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
@@ -67,15 +67,18 @@
|
||||
"\n",
|
||||
"TabNet uses a machine learning technique called sequential attention to select which model features to reason from at each step in the model. This mechanism makes it possible to explain how the model arrives at its predictions and helps it learn more accurate models. TabNet not only outperforms other neural networks and decision trees but also provides interpretable feature attributions. \n",
|
||||
"\n",
|
||||
"Research paper: [TabNet: Attentive Interpretable Tabular Learning](https://arxiv.org/pdf/1908.07442.pdf)\n",
|
||||
"\n",
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"This tutorial uses the `petfinder` in the public Cloud Storage bucket `gs://cloud-samples-data/ai-platform-unified/datasets/tabular/`, which was generated from the [PetFinder.my Adoption Prediction](https://www.kaggle.com/c/petfinder-adoption-prediction). This dataset predicts how quickly an animal will be adopted.\n",
|
||||
"\n",
|
||||
"Research paper: [TabNet: Attentive Interpretable Tabular Learning](https://arxiv.org/pdf/1908.07442.pdf)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "c5040751873a"
|
||||
},
|
||||
"source": [
|
||||
"### Objective\n",
|
||||
"\n",
|
||||
"In this notebook, you will learn how to run `Vertex AI TabNet` built algorithm for training custom tabular models.\n",
|
||||
"In this notebook, you learn how to run `Vertex AI TabNet` built algorithm for training custom tabular models.\n",
|
||||
"\n",
|
||||
"This tutorial uses the following Google Cloud ML services and resources:\n",
|
||||
"\n",
|
||||
@@ -93,11 +96,28 @@
|
||||
"- Deploy the `Vertex AI Model` resource to a `Vertex AI Endpoint` resource.\n",
|
||||
"- Make a prediction with the deployed model.\n",
|
||||
"- Hyperparameter tuning the `Vertex AI TabNet` model.\n",
|
||||
"- Train the model using `Vertex AI Training` using BigQuery table.\n",
|
||||
"- Train the model using `Vertex AI Training` using BigQuery table."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ac8c8586ab03"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"This tutorial uses the `petfinder` in the public Cloud Storage bucket `gs://cloud-samples-data/ai-platform-unified/datasets/tabular/`, which was generated from the [PetFinder.my Adoption Prediction](https://www.kaggle.com/c/petfinder-adoption-prediction). This dataset predicts how quickly an animal is adopted.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "4fc0ad661ebb"
|
||||
},
|
||||
"source": [
|
||||
"### Costs \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"* Vertex AI\n",
|
||||
@@ -132,14 +152,19 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook\n",
|
||||
"if os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"else:\n",
|
||||
" USER_FLAG = \"\"\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"! pip3 install {USER_FLAG} --upgrade tensorflow\n",
|
||||
"! pip3 install {USER_FLAG} --upgrade google-cloud-aiplatform tensorboard-plugin-profile\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"! pip3 install {USER_FLAG} --upgrade tensorflow -q\n",
|
||||
"! pip3 install {USER_FLAG} --upgrade google-cloud-aiplatform tensorboard-plugin-profile -q\n",
|
||||
"! gcloud components update --quiet"
|
||||
]
|
||||
},
|
||||
@@ -193,9 +218,9 @@
|
||||
"\n",
|
||||
"2. [Make sure that billing is enabled for your project.](https://cloud.google.com/billing/docs/how-to/modify-project)\n",
|
||||
"\n",
|
||||
"3. [Enable the following APIs: Vertex AI APIs, Compute Engine APIs, and Cloud Storage.](https://console.cloud.google.com/flows/enableapi?apiid=ml.googleapis.com,compute_component,storage-component.googleapis.com)\n",
|
||||
"3. [Enable the following APIs: Vertex AI APIs, Compute Engine APIs, and Cloud Storage.](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,compute_component,storage-component.googleapis.com)\n",
|
||||
"\n",
|
||||
"4. If you are running this notebook locally, you will need to install the [Cloud SDK]((https://cloud.google.com/sdk)).\n",
|
||||
"4. If you are running this notebook locally, you need to install the [Cloud SDK]((https://cloud.google.com/sdk)).\n",
|
||||
"\n",
|
||||
"5. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
@@ -317,7 +342,7 @@
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Google Cloud Notebooks**, your environment is already\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already\n",
|
||||
"authenticated. Skip this step."
|
||||
]
|
||||
},
|
||||
@@ -359,20 +384,21 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"# The Google Cloud Notebook product has specific requirements\n",
|
||||
"IS_GOOGLE_CLOUD_NOTEBOOK = os.path.exists(\"/opt/deeplearning/metadata/env_version\")\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Google Cloud Notebooks, then don't execute this code\n",
|
||||
"if not IS_GOOGLE_CLOUD_NOTEBOOK:\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
@@ -482,8 +508,6 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import re\n",
|
||||
"import time\n",
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"import google.cloud.aiplatform as aip\n",
|
||||
@@ -1312,27 +1336,31 @@
|
||||
"print(\"Service Account:\", SERVICE_ACCOUNT)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"MODEL_DIR = OUTPUT_DIR \n",
|
||||
"MODEL_DIR = OUTPUT_DIR\n",
|
||||
"\n",
|
||||
"if TRAIN_GPU:\n",
|
||||
" model_bq = job.run(model_display_name=f\"{DATASET_NAME}_{TIMESTAMP}\",\n",
|
||||
" args=CMDARGS, \n",
|
||||
" replica_count=1, \n",
|
||||
" machine_type=TRAIN_COMPUTE, \n",
|
||||
" base_output_dir=MODEL_DIR,\n",
|
||||
" accelerator_type=TRAIN_GPU.name,\n",
|
||||
" accelerator_count=TRAIN_NGPU,\n",
|
||||
" service_account=SERVICE_ACCOUNT,\n",
|
||||
" sync=True)\n",
|
||||
" model_bq = job.run(\n",
|
||||
" model_display_name=f\"{DATASET_NAME}_{TIMESTAMP}\",\n",
|
||||
" args=CMDARGS,\n",
|
||||
" replica_count=1,\n",
|
||||
" machine_type=TRAIN_COMPUTE,\n",
|
||||
" base_output_dir=MODEL_DIR,\n",
|
||||
" accelerator_type=TRAIN_GPU.name,\n",
|
||||
" accelerator_count=TRAIN_NGPU,\n",
|
||||
" service_account=SERVICE_ACCOUNT,\n",
|
||||
" sync=True,\n",
|
||||
" )\n",
|
||||
"else:\n",
|
||||
" model_bq = job.run(model_display_name=f\"{DATASET_NAME}_{TIMESTAMP}\",\n",
|
||||
" args=CMDARGS, \n",
|
||||
" replica_count=1, \n",
|
||||
" machine_type=TRAIN_COMPUTE, \n",
|
||||
" base_output_dir=MODEL_DIR,\n",
|
||||
" service_account=SERVICE_ACCOUNT,\n",
|
||||
" sync=True)\n",
|
||||
" \n",
|
||||
" model_bq = job.run(\n",
|
||||
" model_display_name=f\"{DATASET_NAME}_{TIMESTAMP}\",\n",
|
||||
" args=CMDARGS,\n",
|
||||
" replica_count=1,\n",
|
||||
" machine_type=TRAIN_COMPUTE,\n",
|
||||
" base_output_dir=MODEL_DIR,\n",
|
||||
" service_account=SERVICE_ACCOUNT,\n",
|
||||
" sync=True,\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"print(model_bq.gca_resource)"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -33,18 +33,19 @@
|
||||
"\n",
|
||||
"<table align=\"left\">\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_with_tfhub_models.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_with_tfhub_models.ipynb\">\n",
|
||||
" <a href=\"https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_tfhub_models.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\">\n",
|
||||
" View on GitHub\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage1/get_started_with_tfhub_models.ipynb\">\n",
|
||||
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/get_started_with_tfhub_models.ipynb\">\n",
|
||||
" <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Colab logo\"> Run in Colab\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/get_started_with_tfhub_models.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
@@ -64,17 +65,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation: get started with prebuilt TensorFlow Hub (TFHub) models."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:flowers,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [CIFAR10 dataset](https://www.tensorflow.org/datasets/catalog/cifar10) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset you will use is built into TensorFlow. The trained model predicts which type of class an image is from ten classes: airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -102,6 +92,17 @@
|
||||
" - Save model artifacts and upload as Vertex AI Model resource."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:flowers,icn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [CIFAR10 dataset](https://www.tensorflow.org/datasets/catalog/cifar10) from [TensorFlow Datasets](https://www.tensorflow.org/datasets/catalog/overview). The version of the dataset is built into TensorFlow. The trained model predicts which type of class an image is from ten classes: airplane, automobile, bird, cat, deer, dog, frog, horse, ship, truck."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -143,34 +144,21 @@
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# Google Cloud Notebook\n",
|
||||
"if os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"else:\n",
|
||||
" USER_FLAG = \"\"\n",
|
||||
"\n",
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG\n",
|
||||
"! pip3 install tensorflow-datasets $USER_FLAG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "install_storage"
|
||||
},
|
||||
"source": [
|
||||
"Install the latest GA version of *google-cloud-storage* library as well."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "install_storage"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip3 install -U google-cloud-storage $USER_FLAG"
|
||||
"! pip3 install --upgrade google-cloud-aiplatform $USER_FLAG -q\n",
|
||||
"! pip3 install tensorflow-datasets $USER_FLAG -q\n",
|
||||
"! pip3 install -U google-cloud-storage $USER_FLAG -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -222,9 +210,9 @@
|
||||
"\n",
|
||||
"2. [Make sure that billing is enabled for your project.](https://cloud.google.com/billing/docs/how-to/modify-project)\n",
|
||||
"\n",
|
||||
"3. [Enable the following APIs: Vertex AI APIs, Compute Engine APIs, and Cloud Storage.](https://console.cloud.google.com/flows/enableapi?apiid=ml.googleapis.com,compute_component,storage-component.googleapis.com)\n",
|
||||
"3. [Enable the following APIs: Vertex AI APIs, Compute Engine APIs, and Cloud Storage.](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com,compute_component,storage-component.googleapis.com)\n",
|
||||
"\n",
|
||||
"4. If you are running this notebook locally, you will need to install the [Cloud SDK]((https://cloud.google.com/sdk)).\n",
|
||||
"4. If you are running this notebook locally, you need to install the [Cloud SDK]((https://cloud.google.com/sdk)).\n",
|
||||
"\n",
|
||||
"5. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
@@ -346,7 +334,7 @@
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Google Cloud Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
@@ -381,9 +369,13 @@
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Google Cloud Notebook, then don't execute this code\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\"):\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = False\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" IS_COLAB = True\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
@@ -1386,7 +1378,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"delete_bucket = True\n",
|
||||
"delete_bucket = False\n",
|
||||
"\n",
|
||||
"if delete_bucket and \"BUCKET_URI\" in globals():\n",
|
||||
" ! gsutil rm -r $BUCKET_URI"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,12 +39,15 @@
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
" <td>\n",
|
||||
" <a href=\"https://console.cloud.google.com/ai/platform/notebooks/deploy-notebook?download_url=https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/ml_ops/stage2/mlops_experimentation.ipynb\">\n",
|
||||
" Open in Google Cloud Notebooks\n",
|
||||
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/vertex-ai-samples/main/notebooks/community/ml_ops/stage2/mlops_experimentation.ipynb\">\n",
|
||||
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\">\n",
|
||||
" Open in Vertex AI Workbench\n",
|
||||
" </a>\n",
|
||||
" </td>\n",
|
||||
"</table>\n",
|
||||
"<br/><br/><br/>"
|
||||
"<br/><br/><br/>\n",
|
||||
"\n",
|
||||
"*Note: This notebook is not supported for execution in Colab*"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -59,17 +62,6 @@
|
||||
"This tutorial demonstrates how to use Vertex AI for E2E MLOps on Google Cloud in production. This tutorial covers stage 2 : experimentation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:bq,chicago,lbn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Chicago Taxi](https://www.kaggle.com/chicago/chicago-taxi-trips-bq). The version of the dataset you will use in this tutorial is stored in a public BigQuery table. The trained model predicts whether someone would leave a tip for a taxi fare."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -154,6 +146,39 @@
|
||||
" - If greater then baseline, then upload model as the new baseline and save evaluation results with the model."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "dataset:bq,chicago,lbn"
|
||||
},
|
||||
"source": [
|
||||
"### Dataset\n",
|
||||
"\n",
|
||||
"The dataset used for this tutorial is the [Chicago Taxi](https://www.kaggle.com/chicago/chicago-taxi-trips-bq). The version of the dataset in this tutorial is stored in a public BigQuery table. The trained model predicts whether someone leaves a tip for a taxi fare."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "costs"
|
||||
},
|
||||
"source": [
|
||||
"### Costs\n",
|
||||
"\n",
|
||||
"This tutorial uses billable components of Google Cloud:\n",
|
||||
"\n",
|
||||
"* BigQuery\n",
|
||||
"* Vision API\n",
|
||||
"* Vertex AI\n",
|
||||
"* Cloud Storage\n",
|
||||
"\n",
|
||||
"Learn about [Vertex AI\n",
|
||||
"pricing](https://cloud.google.com/vertex-ai/pricing), [Vision API pricing](https://cloud.google.com/vision/pricing), [BigQuery pricing](https://cloud.google.com/bigquery/pricing), [Cloud Storage\n",
|
||||
"pricing](https://cloud.google.com/storage/pricing), and use the [Pricing\n",
|
||||
"Calculator](https://cloud.google.com/products/calculator/)\n",
|
||||
"to generate a cost estimate based on your projected usage."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -173,22 +198,33 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# The Vertex AI Workbench Notebook product has specific requirements\n",
|
||||
"IS_WORKBENCH_NOTEBOOK = os.getenv(\"DL_ANACONDA_HOME\") and not os.getenv(\"VIRTUAL_ENV\")\n",
|
||||
"IS_USER_MANAGED_WORKBENCH_NOTEBOOK = os.path.exists(\n",
|
||||
" \"/opt/deeplearning/metadata/env_version\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# Vertex AI Notebook requires dependencies to be installed with '--user'\n",
|
||||
"USER_FLAG = \"\"\n",
|
||||
"if IS_WORKBENCH_NOTEBOOK:\n",
|
||||
" USER_FLAG = \"--user\"\n",
|
||||
"\n",
|
||||
"ONCE_ONLY = False\n",
|
||||
"if ONCE_ONLY:\n",
|
||||
" ! pip3 install -U tensorflow==2.5 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-data-validation==1.2 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-transform==1.2 $USER_FLAG\n",
|
||||
" ! pip3 install -U tensorflow-io==0.18 $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-aiplatform[tensorboard] $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-pipeline-components $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-bigquery $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade google-cloud-logging $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade apache-beam[gcp] $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade pyarrow $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade cloudml-hypertune $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade kfp $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade torchvision $USER_FLAG\n",
|
||||
" ! pip3 install --upgrade rpy2 $USER_FLAG"
|
||||
" ! pip3 install -U {USER_FLAG} -q tensorflow==2.5 \\\n",
|
||||
" tensorflow-data-validation==1.2 \\\n",
|
||||
" tensorflow-transform==1.2 \\\n",
|
||||
" tensorflow-io==0.18 \n",
|
||||
" \n",
|
||||
" ! pip3 install --upgrade {USER_FLAG} -q google-cloud-aiplatform[tensorboard] \\\n",
|
||||
" google-cloud-pipeline-components \\\n",
|
||||
" google-cloud-bigquery \\\n",
|
||||
" google-cloud-logging \\\n",
|
||||
" apache-beam[gcp] \\\n",
|
||||
" pyarrow \\\n",
|
||||
" cloudml-hypertune"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -220,6 +256,32 @@
|
||||
" app.kernel.do_shutdown(True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2721ef0202d9"
|
||||
},
|
||||
"source": [
|
||||
"## Before you begin\n",
|
||||
"\n",
|
||||
"### Set up your Google Cloud project\n",
|
||||
"\n",
|
||||
"**The following steps are required, regardless of your notebook environment.**\n",
|
||||
"\n",
|
||||
"1. [Select or create a Google Cloud project](https://console.cloud.google.com/cloud-resource-manager). When you first create an account, you get a $300 free credit towards your compute/storage costs.\n",
|
||||
"\n",
|
||||
"1. [Make sure that billing is enabled for your project](https://cloud.google.com/billing/docs/how-to/modify-project).\n",
|
||||
"\n",
|
||||
"1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com). \n",
|
||||
"\n",
|
||||
"1. If you are running this notebook locally, you need to install the [Cloud SDK](https://cloud.google.com/sdk).\n",
|
||||
"\n",
|
||||
"1. Enter your project ID in the cell below. Then run the cell to make sure the\n",
|
||||
"Cloud SDK uses the right project for all the commands in this notebook.\n",
|
||||
"\n",
|
||||
"**Note**: Jupyter runs lines prefixed with `!` as shell commands, and it interpolates Python variables prefixed with `$` into these commands."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -296,7 +358,9 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"REGION = \"us-central1\" # @param {type: \"string\"}"
|
||||
"REGION = \"[your-region]\" # @param {type:\"string\"}\n",
|
||||
"if REGION == \"[your-region]\":\n",
|
||||
" REGION = \"us-central1\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -323,6 +387,74 @@
|
||||
"TIMESTAMP = datetime.now().strftime(\"%Y%m%d%H%M%S\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "648aa9824ac6"
|
||||
},
|
||||
"source": [
|
||||
"### Authenticate your Google Cloud account\n",
|
||||
"\n",
|
||||
"**If you are using Vertex AI Workbench Notebooks**, your environment is already\n",
|
||||
"authenticated. Skip this step.\n",
|
||||
"\n",
|
||||
"**If you are using Colab**, run the cell below and follow the instructions\n",
|
||||
"when prompted to authenticate your account via oAuth.\n",
|
||||
"\n",
|
||||
"**Otherwise**, follow these steps:\n",
|
||||
"\n",
|
||||
"1. In the Cloud Console, go to the [**Create service account key**\n",
|
||||
" page](https://console.cloud.google.com/apis/credentials/serviceaccountkey).\n",
|
||||
"\n",
|
||||
"2. Click **Create service account**.\n",
|
||||
"\n",
|
||||
"3. In the **Service account name** field, enter a name, and\n",
|
||||
" click **Create**.\n",
|
||||
"\n",
|
||||
"4. In the **Grant this service account access to project** section, click the **Role** drop-down list. Type \"Vertex AI\"\n",
|
||||
"into the filter box, and select\n",
|
||||
" **Vertex AI Administrator**. Type \"Storage Object Admin\" into the filter box, and select **Storage Object Admin**.\n",
|
||||
"\n",
|
||||
"5. Click *Create*. A JSON file that contains your key downloads to your\n",
|
||||
"local environment.\n",
|
||||
"\n",
|
||||
"6. Enter the path to your service account key as the\n",
|
||||
"`GOOGLE_APPLICATION_CREDENTIALS` variable in the cell below and run the cell."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "535223fa4b84"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you are running this notebook in Colab, run this cell and follow the\n",
|
||||
"# instructions to authenticate your GCP account. This provides access to your\n",
|
||||
"# Cloud Storage bucket and lets you submit training jobs and prediction\n",
|
||||
"# requests.\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import sys\n",
|
||||
"\n",
|
||||
"# If on Vertex AI Workbench, then don't execute this code\n",
|
||||
"IS_COLAB = \"google.colab\" in sys.modules\n",
|
||||
"if not os.path.exists(\"/opt/deeplearning/metadata/env_version\") and not os.getenv(\n",
|
||||
" \"DL_ANACONDA_HOME\"\n",
|
||||
"):\n",
|
||||
" if \"google.colab\" in sys.modules:\n",
|
||||
" from google.colab import auth as google_auth\n",
|
||||
"\n",
|
||||
" google_auth.authenticate_user()\n",
|
||||
"\n",
|
||||
" # If you are running this notebook locally, replace the string below with the\n",
|
||||
" # path to your service account key and run this cell to authenticate your GCP\n",
|
||||
" # account.\n",
|
||||
" elif not os.getenv(\"IS_TESTING\"):\n",
|
||||
" %env GOOGLE_APPLICATION_CREDENTIALS ''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
@@ -436,9 +568,16 @@
|
||||
" or SERVICE_ACCOUNT is None\n",
|
||||
" or SERVICE_ACCOUNT == \"[your-service-account]\"\n",
|
||||
"):\n",
|
||||
" # Get your GCP project id from gcloud\n",
|
||||
" shell_output = !gcloud auth list 2>/dev/null\n",
|
||||
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
|
||||
" # Get your service account from gcloud\n",
|
||||
" if not IS_COLAB:\n",
|
||||
" shell_output = !gcloud auth list 2>/dev/null\n",
|
||||
" SERVICE_ACCOUNT = shell_output[2].replace(\"*\", \"\").strip()\n",
|
||||
"\n",
|
||||
" if IS_COLAB:\n",
|
||||
" shell_output = ! gcloud projects describe $PROJECT_ID\n",
|
||||
" project_number = shell_output[-1].split(\":\")[1].strip().replace(\"'\", \"\")\n",
|
||||
" SERVICE_ACCOUNT = f\"{project_number}-compute@developer.gserviceaccount.com\"\n",
|
||||
"\n",
|
||||
" print(\"Service Account:\", SERVICE_ACCOUNT)"
|
||||
]
|
||||
},
|
||||
@@ -583,6 +722,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"if os.getenv(\"IS_TESTING_TRAIN_GPU\"):\n",
|
||||
" TRAIN_GPU, TRAIN_NGPU = (\n",
|
||||
" aip.gapic.AcceleratorType.NVIDIA_TESLA_K80,\n",
|
||||
@@ -1218,7 +1359,7 @@
|
||||
"setup_cfg = \"[egg_info]\\n\\ntag_build =\\n\\ntag_date = 0\"\n",
|
||||
"! echo \"$setup_cfg\" > custom/setup.cfg\n",
|
||||
"\n",
|
||||
"setup_py = \"import setuptools\\n\\nsetuptools.setup(\\n\\n install_requires=[\\n\\n 'google-cloud-aiplatform',\\n\\n 'cloudml-hypertune',\\n\\n 'tensorflow_datasets==1.3.0',\\n\\n 'tensorflow_data_validation==1.2',\\n\\n ],\\n\\n packages=setuptools.find_packages())\"\n",
|
||||
"setup_py = \"import setuptools\\n\\nsetuptools.setup(\\n\\n install_requires=[\\n\\n 'google-cloud-aiplatform',\\n\\n 'cloudml-hypertune',\\n\\n 'tensorflow_datasets==1.3.0',\\n\\n 'tensorflow==2.5',\\n\\n 'tensorflow_data_validation==1.2',\\n\\n ],\\n\\n packages=setuptools.find_packages())\"\n",
|
||||
"! echo \"$setup_py\" > custom/setup.py\n",
|
||||
"\n",
|
||||
"pkg_info = \"Metadata-Version: 1.0\\n\\nName: Chicago Taxi tabular binary classifier\\n\\nVersion: 0.0.0\\n\\nSummary: Demostration training script\\n\\nHome-page: www.google.com\\n\\nAuthor: Google\\n\\nAuthor-email: cdpe@google.com\\n\\nLicense: Public\\n\\nDescription: Demo\\n\\nPlatform: Vertex AI\"\n",
|
||||
@@ -3011,9 +3152,8 @@
|
||||
},
|
||||
"source": [
|
||||
"## Review model evaluation scores\n",
|
||||
"After your model has finished training, you can review the evaluation scores for it.\n",
|
||||
"\n",
|
||||
"First, you need to get a reference to the new model. As with datasets, you can either use the reference to the model variable you created when you deployed the model or you can list all of the models in your project."
|
||||
"After your model training has finished, you can review the evaluation scores for it using the `list_model_evaluations()` method. This method will return an iterator for each evaluation slice."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -3024,18 +3164,10 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Get model resource ID\n",
|
||||
"models = aip.Model.list(filter=\"display_name=chicago_\" + TIMESTAMP)\n",
|
||||
"model_evaluations = model.list_model_evaluations()\n",
|
||||
"\n",
|
||||
"# Get a reference to the Model Service client\n",
|
||||
"client_options = {\"api_endpoint\": f\"{REGION}-aiplatform.googleapis.com\"}\n",
|
||||
"model_service_client = aip.gapic.ModelServiceClient(client_options=client_options)\n",
|
||||
"\n",
|
||||
"model_evaluations = model_service_client.list_model_evaluations(\n",
|
||||
" parent=models[0].resource_name\n",
|
||||
")\n",
|
||||
"model_evaluation = list(model_evaluations)[0]\n",
|
||||
"print(model_evaluation)"
|
||||
"for model_evaluation in model_evaluations:\n",
|
||||
" print(model_evaluation.to_dict())"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user