From da2c133f69253161b393fef97a94127356a6d70d Mon Sep 17 00:00:00 2001 From: Jiawei Wang Date: Fri, 4 Dec 2020 00:12:17 +0800 Subject: [PATCH] Merge pull request #900 from wangjiawei04/imagenet_pipeline Imagenet pipeline --- .../examples/imagenet/resnet50_rpc_client.py | 3 +- .../examples/imagenet/resnet50_web_service.py | 5 +- python/examples/lac/lac_web_service.py | 15 +- python/examples/pipeline/imagenet/README.md | 19 + .../examples/pipeline/imagenet/README_CN.md | 19 + python/examples/pipeline/imagenet/config.yml | 30 + python/examples/pipeline/imagenet/daisy.jpg | Bin 0 -> 39696 bytes .../examples/pipeline/imagenet/get_model.sh | 5 + .../examples/pipeline/imagenet/imagenet.label | 1000 +++++++++++++++++ .../pipeline/imagenet/pipeline_rpc_client.py | 36 + .../pipeline/imagenet/resnet50_web_service.py | 71 ++ python/examples/senta/senta_web_service.py | 6 +- python/pipeline/operator.py | 2 +- python/pipeline/pipeline_client.py | 7 +- 14 files changed, 1206 insertions(+), 12 deletions(-) create mode 100644 python/examples/pipeline/imagenet/README.md create mode 100644 python/examples/pipeline/imagenet/README_CN.md create mode 100644 python/examples/pipeline/imagenet/config.yml create mode 100644 python/examples/pipeline/imagenet/daisy.jpg create mode 100644 python/examples/pipeline/imagenet/get_model.sh create mode 100644 python/examples/pipeline/imagenet/imagenet.label create mode 100644 python/examples/pipeline/imagenet/pipeline_rpc_client.py create mode 100644 python/examples/pipeline/imagenet/resnet50_web_service.py diff --git a/python/examples/imagenet/resnet50_rpc_client.py b/python/examples/imagenet/resnet50_rpc_client.py index 7888ab63..b23f9917 100644 --- a/python/examples/imagenet/resnet50_rpc_client.py +++ b/python/examples/imagenet/resnet50_rpc_client.py @@ -38,7 +38,8 @@ start = time.time() image_file = "https://paddle-serving.bj.bcebos.com/imagenet-example/daisy.jpg" for i in range(10): img = seq(image_file) - fetch_map = client.predict(feed={"image": img}, fetch=["score"]) + fetch_map = client.predict( + feed={"image": img}, fetch=["score"], batch=False) prob = max(fetch_map["score"][0]) label = label_dict[fetch_map["score"][0].tolist().index(prob)].strip( ).replace(",", "") diff --git a/python/examples/imagenet/resnet50_web_service.py b/python/examples/imagenet/resnet50_web_service.py index 4c982275..70331037 100644 --- a/python/examples/imagenet/resnet50_web_service.py +++ b/python/examples/imagenet/resnet50_web_service.py @@ -13,7 +13,7 @@ # limitations under the License. import sys from paddle_serving_client import Client - +import numpy as np from paddle_serving_app.reader import Sequential, URL2Image, Resize, CenterCrop, RGB2BGR, Transpose, Div, Normalize, Base64ToImage if len(sys.argv) != 4: @@ -44,12 +44,13 @@ class ImageService(WebService): def preprocess(self, feed=[], fetch=[]): feed_batch = [] + is_batch = True for ins in feed: if "image" not in ins: raise ("feed data error!") img = self.seq(ins["image"]) feed_batch.append({"image": img[np.newaxis, :]}) - return feed_batch, fetch + return feed_batch, fetch, is_batch def postprocess(self, feed=[], fetch=[], fetch_map={}): score_list = fetch_map["score"] diff --git a/python/examples/lac/lac_web_service.py b/python/examples/lac/lac_web_service.py index bed89f54..cf37f662 100644 --- a/python/examples/lac/lac_web_service.py +++ b/python/examples/lac/lac_web_service.py @@ -15,6 +15,7 @@ from paddle_serving_server.web_service import WebService import sys from paddle_serving_app.reader import LACReader +import numpy as np class LACService(WebService): @@ -23,13 +24,21 @@ class LACService(WebService): def preprocess(self, feed={}, fetch=[]): feed_batch = [] + fetch = ["crf_decode"] + lod_info = [0] + is_batch = True for ins in feed: if "words" not in ins: raise ("feed data error!") feed_data = self.reader.process(ins["words"]) - feed_batch.append({"words": feed_data}) - fetch = ["crf_decode"] - return feed_batch, fetch + feed_batch.append(np.array(feed_data).reshape(len(feed_data), 1)) + lod_info.append(lod_info[-1] + len(feed_data)) + feed_dict = { + "words": np.concatenate( + feed_batch, axis=0), + "words.lod": lod_info + } + return feed_dict, fetch, is_batch def postprocess(self, feed={}, fetch=[], fetch_map={}): batch_ret = [] diff --git a/python/examples/pipeline/imagenet/README.md b/python/examples/pipeline/imagenet/README.md new file mode 100644 index 00000000..d0fa99e6 --- /dev/null +++ b/python/examples/pipeline/imagenet/README.md @@ -0,0 +1,19 @@ +# Imagenet Pipeline WebService + +This document will takes Imagenet service as an example to introduce how to use Pipeline WebService. + +## Get model +``` +sh get_model.sh +``` + +## Start server + +``` +python resnet50_web_service.py &>log.txt & +``` + +## RPC test +``` +python pipeline_rpc_client.py +``` diff --git a/python/examples/pipeline/imagenet/README_CN.md b/python/examples/pipeline/imagenet/README_CN.md new file mode 100644 index 00000000..325a64e7 --- /dev/null +++ b/python/examples/pipeline/imagenet/README_CN.md @@ -0,0 +1,19 @@ +# Imagenet Pipeline WebService + +这里以 Uci 服务为例来介绍 Pipeline WebService 的使用。 + +## 获取模型 +``` +sh get_data.sh +``` + +## 启动服务 + +``` +python web_service.py &>log.txt & +``` + +## 测试 +``` +curl -X POST -k http://localhost:18082/uci/prediction -d '{"key": ["x"], "value": ["0.0137, -0.1136, 0.2553, -0.0692, 0.0582, -0.0727, -0.1583, -0.0584, 0.6283, 0.4919, 0.1856, 0.0795, -0.0332"]}' +``` diff --git a/python/examples/pipeline/imagenet/config.yml b/python/examples/pipeline/imagenet/config.yml new file mode 100644 index 00000000..52ddab6f --- /dev/null +++ b/python/examples/pipeline/imagenet/config.yml @@ -0,0 +1,30 @@ +#worker_num, 最大并发数。当build_dag_each_worker=True时, 框架会创建worker_num个进程,每个进程内构建grpcSever和DAG +##当build_dag_each_worker=False时,框架会设置主线程grpc线程池的max_workers=worker_num +worker_num: 1 + +#http端口, rpc_port和http_port不允许同时为空。当rpc_port可用且http_port为空时,不自动生成http_port +http_port: 18082 +rpc_port: 9999 + +dag: + #op资源类型, True, 为线程模型;False,为进程模型 + is_thread_op: False +op: + imagenet: + #当op配置没有server_endpoints时,从local_service_conf读取本地服务配置 + local_service_conf: + + #并发数,is_thread_op=True时,为线程并发;否则为进程并发 + concurrency: 2 + + #uci模型路径 + model_config: ResNet50_vd_model + + #计算硬件ID,当devices为""或不写时为CPU预测;当devices为"0", "0,1,2"时为GPU预测,表示使用的GPU卡 + devices: "0" # "0,1" + + #client类型,包括brpc, grpc和local_predictor.local_predictor不启动Serving服务,进程内预测 + client_type: local_predictor + + #Fetch结果列表,以client_config中fetch_var的alias_name为准 + fetch_list: ["score"] diff --git a/python/examples/pipeline/imagenet/daisy.jpg b/python/examples/pipeline/imagenet/daisy.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7edeca63e5f32e68550ef720d81f59df58a8eabc GIT binary patch literal 39696 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 W##>Ru&v$Q>Ac6~0A8IH*&;Qw&gu-k9 literal 0 HcmV?d00001 diff --git a/python/examples/pipeline/imagenet/get_model.sh b/python/examples/pipeline/imagenet/get_model.sh new file mode 100644 index 00000000..1964c79a --- /dev/null +++ b/python/examples/pipeline/imagenet/get_model.sh @@ -0,0 +1,5 @@ +wget --no-check-certificate https://paddle-serving.bj.bcebos.com/imagenet-example/ResNet50_vd.tar.gz +tar -xzvf ResNet50_vd.tar.gz + +wget --no-check-certificate https://paddle-serving.bj.bcebos.com/imagenet-example/image_data.tar.gz +tar -xzvf image_data.tar.gz diff --git a/python/examples/pipeline/imagenet/imagenet.label b/python/examples/pipeline/imagenet/imagenet.label new file mode 100644 index 00000000..d7146735 --- /dev/null +++ b/python/examples/pipeline/imagenet/imagenet.label @@ -0,0 +1,1000 @@ +tench, Tinca tinca, +goldfish, Carassius auratus, +great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias, +tiger shark, Galeocerdo cuvieri, +hammerhead, hammerhead shark, +electric ray, crampfish, numbfish, torpedo, +stingray, +cock, +hen, +ostrich, Struthio camelus, +brambling, Fringilla montifringilla, +goldfinch, Carduelis carduelis, +house finch, linnet, Carpodacus mexicanus, +junco, snowbird, +indigo bunting, indigo finch, indigo bird, Passerina cyanea, +robin, American robin, Turdus migratorius, +bulbul, +jay, +magpie, +chickadee, +water ouzel, dipper, +kite, +bald eagle, American eagle, Haliaeetus leucocephalus, +vulture, +great grey owl, great gray owl, Strix nebulosa, +European fire salamander, Salamandra salamandra, +common newt, Triturus vulgaris, +eft, +spotted salamander, Ambystoma maculatum, +axolotl, mud puppy, Ambystoma mexicanum, +bullfrog, Rana catesbeiana, +tree frog, tree-frog, +tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui, +loggerhead, loggerhead turtle, Caretta caretta, +leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea, +mud turtle, +terrapin, +box turtle, box tortoise, +banded gecko, +common iguana, iguana, Iguana iguana, +American chameleon, anole, Anolis carolinensis, +whiptail, whiptail lizard, +agama, +frilled lizard, Chlamydosaurus kingi, +alligator lizard, +Gila monster, Heloderma suspectum, +green lizard, Lacerta viridis, +African chameleon, Chamaeleo chamaeleon, +Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis, +African crocodile, Nile crocodile, Crocodylus niloticus, +American alligator, Alligator mississipiensis, +triceratops, +thunder snake, worm snake, Carphophis amoenus, +ringneck snake, ring-necked snake, ring snake, +hognose snake, puff adder, sand viper, +green snake, grass snake, +king snake, kingsnake, +garter snake, grass snake, +water snake, +vine snake, +night snake, Hypsiglena torquata, +boa constrictor, Constrictor constrictor, +rock python, rock snake, Python sebae, +Indian cobra, Naja naja, +green mamba, +sea snake, +horned viper, cerastes, sand viper, horned asp, Cerastes cornutus, +diamondback, diamondback rattlesnake, Crotalus adamanteus, +sidewinder, horned rattlesnake, Crotalus cerastes, +trilobite, +harvestman, daddy longlegs, Phalangium opilio, +scorpion, +black and gold garden spider, Argiope aurantia, +barn spider, Araneus cavaticus, +garden spider, Aranea diademata, +black widow, Latrodectus mactans, +tarantula, +wolf spider, hunting spider, +tick, +centipede, +black grouse, +ptarmigan, +ruffed grouse, partridge, Bonasa umbellus, +prairie chicken, prairie grouse, prairie fowl, +peacock, +quail, +partridge, +African grey, African gray, Psittacus erithacus, +macaw, +sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita, +lorikeet, +coucal, +bee eater, +hornbill, +hummingbird, +jacamar, +toucan, +drake, +red-breasted merganser, Mergus serrator, +goose, +black swan, Cygnus atratus, +tusker, +echidna, spiny anteater, anteater, +platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus, +wallaby, brush kangaroo, +koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus, +wombat, +jellyfish, +sea anemone, anemone, +brain coral, +flatworm, platyhelminth, +nematode, nematode worm, roundworm, +conch, +snail, +slug, +sea slug, nudibranch, +chiton, coat-of-mail shell, sea cradle, polyplacophore, +chambered nautilus, pearly nautilus, nautilus, +Dungeness crab, Cancer magister, +rock crab, Cancer irroratus, +fiddler crab, +king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica, +American lobster, Northern lobster, Maine lobster, Homarus americanus, +spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish, +crayfish, crawfish, crawdad, crawdaddy, +hermit crab, +isopod, +white stork, Ciconia ciconia, +black stork, Ciconia nigra, +spoonbill, +flamingo, +little blue heron, Egretta caerulea, +American egret, great white heron, Egretta albus, +bittern, +crane, +limpkin, Aramus pictus, +European gallinule, Porphyrio porphyrio, +American coot, marsh hen, mud hen, water hen, Fulica americana, +bustard, +ruddy turnstone, Arenaria interpres, +red-backed sandpiper, dunlin, Erolia alpina, +redshank, Tringa totanus, +dowitcher, +oystercatcher, oyster catcher, +pelican, +king penguin, Aptenodytes patagonica, +albatross, mollymawk, +grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus, +killer whale, killer, orca, grampus, sea wolf, Orcinus orca, +dugong, Dugong dugon, +sea lion, +Chihuahua, +Japanese spaniel, +Maltese dog, Maltese terrier, Maltese, +Pekinese, Pekingese, Peke, +Shih-Tzu, +Blenheim spaniel, +papillon, +toy terrier, +Rhodesian ridgeback, +Afghan hound, Afghan, +basset, basset hound, +beagle, +bloodhound, sleuthhound, +bluetick, +black-and-tan coonhound, +Walker hound, Walker foxhound, +English foxhound, +redbone, +borzoi, Russian wolfhound, +Irish wolfhound, +Italian greyhound, +whippet, +Ibizan hound, Ibizan Podenco, +Norwegian elkhound, elkhound, +otterhound, otter hound, +Saluki, gazelle hound, +Scottish deerhound, deerhound, +Weimaraner, +Staffordshire bullterrier, Staffordshire bull terrier, +American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier, +Bedlington terrier, +Border terrier, +Kerry blue terrier, +Irish terrier, +Norfolk terrier, +Norwich terrier, +Yorkshire terrier, +wire-haired fox terrier, +Lakeland terrier, +Sealyham terrier, Sealyham, +Airedale, Airedale terrier, +cairn, cairn terrier, +Australian terrier, +Dandie Dinmont, Dandie Dinmont terrier, +Boston bull, Boston terrier, +miniature schnauzer, +giant schnauzer, +standard schnauzer, +Scotch terrier, Scottish terrier, Scottie, +Tibetan terrier, chrysanthemum dog, +silky terrier, Sydney silky, +soft-coated wheaten terrier, +West Highland white terrier, +Lhasa, Lhasa apso, +flat-coated retriever, +curly-coated retriever, +golden retriever, +Labrador retriever, +Chesapeake Bay retriever, +German short-haired pointer, +vizsla, Hungarian pointer, +English setter, +Irish setter, red setter, +Gordon setter, +Brittany spaniel, +clumber, clumber spaniel, +English springer, English springer spaniel, +Welsh springer spaniel, +cocker spaniel, English cocker spaniel, cocker, +Sussex spaniel, +Irish water spaniel, +kuvasz, +schipperke, +groenendael, +malinois, +briard, +kelpie, +komondor, +Old English sheepdog, bobtail, +Shetland sheepdog, Shetland sheep dog, Shetland, +collie, +Border collie, +Bouvier des Flandres, Bouviers des Flandres, +Rottweiler, +German shepherd, German shepherd dog, German police dog, alsatian, +Doberman, Doberman pinscher, +miniature pinscher, +Greater Swiss Mountain dog, +Bernese mountain dog, +Appenzeller, +EntleBucher, +boxer, +bull mastiff, +Tibetan mastiff, +French bulldog, +Great Dane, +Saint Bernard, St Bernard, +Eskimo dog, husky, +malamute, malemute, Alaskan malamute, +Siberian husky, +dalmatian, coach dog, carriage dog, +affenpinscher, monkey pinscher, monkey dog, +basenji, +pug, pug-dog, +Leonberg, +Newfoundland, Newfoundland dog, +Great Pyrenees, +Samoyed, Samoyede, +Pomeranian, +chow, chow chow, +keeshond, +Brabancon griffon, +Pembroke, Pembroke Welsh corgi, +Cardigan, Cardigan Welsh corgi, +toy poodle, +miniature poodle, +standard poodle, +Mexican hairless, +timber wolf, grey wolf, gray wolf, Canis lupus, +white wolf, Arctic wolf, Canis lupus tundrarum, +red wolf, maned wolf, Canis rufus, Canis niger, +coyote, prairie wolf, brush wolf, Canis latrans, +dingo, warrigal, warragal, Canis dingo, +dhole, Cuon alpinus, +African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus, +hyena, hyaena, +red fox, Vulpes vulpes, +kit fox, Vulpes macrotis, +Arctic fox, white fox, Alopex lagopus, +grey fox, gray fox, Urocyon cinereoargenteus, +tabby, tabby cat, +tiger cat, +Persian cat, +Siamese cat, Siamese, +Egyptian cat, +cougar, puma, catamount, mountain lion, painter, panther, Felis concolor, +lynx, catamount, +leopard, Panthera pardus, +snow leopard, ounce, Panthera uncia, +jaguar, panther, Panthera onca, Felis onca, +lion, king of beasts, Panthera leo, +tiger, Panthera tigris, +cheetah, chetah, Acinonyx jubatus, +brown bear, bruin, Ursus arctos, +American black bear, black bear, Ursus americanus, Euarctos americanus, +ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus, +sloth bear, Melursus ursinus, Ursus ursinus, +mongoose, +meerkat, mierkat, +tiger beetle, +ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle, +ground beetle, carabid beetle, +long-horned beetle, longicorn, longicorn beetle, +leaf beetle, chrysomelid, +dung beetle, +rhinoceros beetle, +weevil, +fly, +bee, +ant, emmet, pismire, +grasshopper, hopper, +cricket, +walking stick, walkingstick, stick insect, +cockroach, roach, +mantis, mantid, +cicada, cicala, +leafhopper, +lacewing, lacewing fly, +"dragonfly, darning needle, devils darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk", +damselfly, +admiral, +ringlet, ringlet butterfly, +monarch, monarch butterfly, milkweed butterfly, Danaus plexippus, +cabbage butterfly, +sulphur butterfly, sulfur butterfly, +lycaenid, lycaenid butterfly, +starfish, sea star, +sea urchin, +sea cucumber, holothurian, +wood rabbit, cottontail, cottontail rabbit, +hare, +Angora, Angora rabbit, +hamster, +porcupine, hedgehog, +fox squirrel, eastern fox squirrel, Sciurus niger, +marmot, +beaver, +guinea pig, Cavia cobaya, +sorrel, +zebra, +hog, pig, grunter, squealer, Sus scrofa, +wild boar, boar, Sus scrofa, +warthog, +hippopotamus, hippo, river horse, Hippopotamus amphibius, +ox, +water buffalo, water ox, Asiatic buffalo, Bubalus bubalis, +bison, +ram, tup, +bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis, +ibex, Capra ibex, +hartebeest, +impala, Aepyceros melampus, +gazelle, +Arabian camel, dromedary, Camelus dromedarius, +llama, +weasel, +mink, +polecat, fitch, foulmart, foumart, Mustela putorius, +black-footed ferret, ferret, Mustela nigripes, +otter, +skunk, polecat, wood pussy, +badger, +armadillo, +three-toed sloth, ai, Bradypus tridactylus, +orangutan, orang, orangutang, Pongo pygmaeus, +gorilla, Gorilla gorilla, +chimpanzee, chimp, Pan troglodytes, +gibbon, Hylobates lar, +siamang, Hylobates syndactylus, Symphalangus syndactylus, +guenon, guenon monkey, +patas, hussar monkey, Erythrocebus patas, +baboon, +macaque, +langur, +colobus, colobus monkey, +proboscis monkey, Nasalis larvatus, +marmoset, +capuchin, ringtail, Cebus capucinus, +howler monkey, howler, +titi, titi monkey, +spider monkey, Ateles geoffroyi, +squirrel monkey, Saimiri sciureus, +Madagascar cat, ring-tailed lemur, Lemur catta, +indri, indris, Indri indri, Indri brevicaudatus, +Indian elephant, Elephas maximus, +African elephant, Loxodonta africana, +lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens, +giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca, +barracouta, snoek, +eel, +coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch, +rock beauty, Holocanthus tricolor, +anemone fish, +sturgeon, +gar, garfish, garpike, billfish, Lepisosteus osseus, +lionfish, +puffer, pufferfish, blowfish, globefish, +abacus, +abaya, +"academic gown, academic robe, judges robe", +accordion, piano accordion, squeeze box, +acoustic guitar, +aircraft carrier, carrier, flattop, attack aircraft carrier, +airliner, +airship, dirigible, +altar, +ambulance, +amphibian, amphibious vehicle, +analog clock, +apiary, bee house, +apron, +ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin, +assault rifle, assault gun, +backpack, back pack, knapsack, packsack, rucksack, haversack, +bakery, bakeshop, bakehouse, +balance beam, beam, +balloon, +ballpoint, ballpoint pen, ballpen, Biro, +Band Aid, +banjo, +bannister, banister, balustrade, balusters, handrail, +barbell, +barber chair, +barbershop, +barn, +barometer, +barrel, cask, +barrow, garden cart, lawn cart, wheelbarrow, +baseball, +basketball, +bassinet, +bassoon, +bathing cap, swimming cap, +bath towel, +bathtub, bathing tub, bath, tub, +beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon, +beacon, lighthouse, beacon light, pharos, +beaker, +bearskin, busby, shako, +beer bottle, +beer glass, +bell cote, bell cot, +bib, +bicycle-built-for-two, tandem bicycle, tandem, +bikini, two-piece, +binder, ring-binder, +binoculars, field glasses, opera glasses, +birdhouse, +boathouse, +bobsled, bobsleigh, bob, +bolo tie, bolo, bola tie, bola, +bonnet, poke bonnet, +bookcase, +bookshop, bookstore, bookstall, +bottlecap, +bow, +bow tie, bow-tie, bowtie, +brass, memorial tablet, plaque, +brassiere, bra, bandeau, +breakwater, groin, groyne, mole, bulwark, seawall, jetty, +breastplate, aegis, egis, +broom, +bucket, pail, +buckle, +bulletproof vest, +bullet train, bullet, +butcher shop, meat market, +cab, hack, taxi, taxicab, +caldron, cauldron, +candle, taper, wax light, +cannon, +canoe, +can opener, tin opener, +cardigan, +car mirror, +carousel, carrousel, merry-go-round, roundabout, whirligig, +"carpenters kit, tool kit", +carton, +car wheel, +cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM, +cassette, +cassette player, +castle, +catamaran, +CD player, +cello, violoncello, +cellular telephone, cellular phone, cellphone, cell, mobile phone, +chain, +chainlink fence, +chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour, +chain saw, chainsaw, +chest, +chiffonier, commode, +chime, bell, gong, +china cabinet, china closet, +Christmas stocking, +church, church building, +cinema, movie theater, movie theatre, movie house, picture palace, +cleaver, meat cleaver, chopper, +cliff dwelling, +cloak, +clog, geta, patten, sabot, +cocktail shaker, +coffee mug, +coffeepot, +coil, spiral, volute, whorl, helix, +combination lock, +computer keyboard, keypad, +confectionery, confectionary, candy store, +container ship, containership, container vessel, +convertible, +corkscrew, bottle screw, +cornet, horn, trumpet, trump, +cowboy boot, +cowboy hat, ten-gallon hat, +cradle, +crane, +crash helmet, +crate, +crib, cot, +Crock Pot, +croquet ball, +crutch, +cuirass, +dam, dike, dyke, +desk, +desktop computer, +dial telephone, dial phone, +diaper, nappy, napkin, +digital clock, +digital watch, +dining table, board, +dishrag, dishcloth, +dishwasher, dish washer, dishwashing machine, +disk brake, disc brake, +dock, dockage, docking facility, +dogsled, dog sled, dog sleigh, +dome, +doormat, welcome mat, +drilling platform, offshore rig, +drum, membranophone, tympan, +drumstick, +dumbbell, +Dutch oven, +electric fan, blower, +electric guitar, +electric locomotive, +entertainment center, +envelope, +espresso maker, +face powder, +feather boa, boa, +file, file cabinet, filing cabinet, +fireboat, +fire engine, fire truck, +fire screen, fireguard, +flagpole, flagstaff, +flute, transverse flute, +folding chair, +football helmet, +forklift, +fountain, +fountain pen, +four-poster, +freight car, +French horn, horn, +frying pan, frypan, skillet, +fur coat, +garbage truck, dustcart, +gasmask, respirator, gas helmet, +gas pump, gasoline pump, petrol pump, island dispenser, +goblet, +go-kart, +golf ball, +golfcart, golf cart, +gondola, +gong, tam-tam, +gown, +grand piano, grand, +greenhouse, nursery, glasshouse, +grille, radiator grille, +grocery store, grocery, food market, market, +guillotine, +hair slide, +hair spray, +half track, +hammer, +hamper, +hand blower, blow dryer, blow drier, hair dryer, hair drier, +hand-held computer, hand-held microcomputer, +handkerchief, hankie, hanky, hankey, +hard disc, hard disk, fixed disk, +harmonica, mouth organ, harp, mouth harp, +harp, +harvester, reaper, +hatchet, +holster, +home theater, home theatre, +honeycomb, +hook, claw, +hoopskirt, crinoline, +horizontal bar, high bar, +horse cart, horse-cart, +hourglass, +iPod, +iron, smoothing iron, +"jack-o-lantern", +jean, blue jean, denim, +jeep, landrover, +jersey, T-shirt, tee shirt, +jigsaw puzzle, +jinrikisha, ricksha, rickshaw, +joystick, +kimono, +knee pad, +knot, +lab coat, laboratory coat, +ladle, +lampshade, lamp shade, +laptop, laptop computer, +lawn mower, mower, +lens cap, lens cover, +letter opener, paper knife, paperknife, +library, +lifeboat, +lighter, light, igniter, ignitor, +limousine, limo, +liner, ocean liner, +lipstick, lip rouge, +Loafer, +lotion, +loudspeaker, speaker, speaker unit, loudspeaker system, speaker system, +"loupe, jewelers loupe", +lumbermill, sawmill, +magnetic compass, +mailbag, postbag, +mailbox, letter box, +maillot, +maillot, tank suit, +manhole cover, +maraca, +marimba, xylophone, +mask, +matchstick, +maypole, +maze, labyrinth, +measuring cup, +medicine chest, medicine cabinet, +megalith, megalithic structure, +microphone, mike, +microwave, microwave oven, +military uniform, +milk can, +minibus, +miniskirt, mini, +minivan, +missile, +mitten, +mixing bowl, +mobile home, manufactured home, +Model T, +modem, +monastery, +monitor, +moped, +mortar, +mortarboard, +mosque, +mosquito net, +motor scooter, scooter, +mountain bike, all-terrain bike, off-roader, +mountain tent, +mouse, computer mouse, +mousetrap, +moving van, +muzzle, +nail, +neck brace, +necklace, +nipple, +notebook, notebook computer, +obelisk, +oboe, hautboy, hautbois, +ocarina, sweet potato, +odometer, hodometer, mileometer, milometer, +oil filter, +organ, pipe organ, +oscilloscope, scope, cathode-ray oscilloscope, CRO, +overskirt, +oxcart, +oxygen mask, +packet, +paddle, boat paddle, +paddlewheel, paddle wheel, +padlock, +paintbrush, +"pajama, pyjama, pjs, jammies", +palace, +panpipe, pandean pipe, syrinx, +paper towel, +parachute, chute, +parallel bars, bars, +park bench, +parking meter, +passenger car, coach, carriage, +patio, terrace, +pay-phone, pay-station, +pedestal, plinth, footstall, +pencil box, pencil case, +pencil sharpener, +perfume, essence, +Petri dish, +photocopier, +pick, plectrum, plectron, +pickelhaube, +picket fence, paling, +pickup, pickup truck, +pier, +piggy bank, penny bank, +pill bottle, +pillow, +ping-pong ball, +pinwheel, +pirate, pirate ship, +pitcher, ewer, +"plane, carpenters plane, woodworking plane", +planetarium, +plastic bag, +plate rack, +plow, plough, +"plunger, plumbers helper", +Polaroid camera, Polaroid Land camera, +pole, +police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria, +poncho, +pool table, billiard table, snooker table, +pop bottle, soda bottle, +pot, flowerpot, +"potters wheel", +power drill, +prayer rug, prayer mat, +printer, +prison, prison house, +projectile, missile, +projector, +puck, hockey puck, +punching bag, punch bag, punching ball, punchball, +purse, +quill, quill pen, +quilt, comforter, comfort, puff, +racer, race car, racing car, +racket, racquet, +radiator, +radio, wireless, +radio telescope, radio reflector, +rain barrel, +recreational vehicle, RV, R.V., +reel, +reflex camera, +refrigerator, icebox, +remote control, remote, +restaurant, eating house, eating place, eatery, +revolver, six-gun, six-shooter, +rifle, +rocking chair, rocker, +rotisserie, +rubber eraser, rubber, pencil eraser, +rugby ball, +rule, ruler, +running shoe, +safe, +safety pin, +saltshaker, salt shaker, +sandal, +sarong, +sax, saxophone, +scabbard, +scale, weighing machine, +school bus, +schooner, +scoreboard, +screen, CRT screen, +screw, +screwdriver, +seat belt, seatbelt, +sewing machine, +shield, buckler, +shoe shop, shoe-shop, shoe store, +shoji, +shopping basket, +shopping cart, +shovel, +shower cap, +shower curtain, +ski, +ski mask, +sleeping bag, +slide rule, slipstick, +sliding door, +slot, one-armed bandit, +snorkel, +snowmobile, +snowplow, snowplough, +soap dispenser, +soccer ball, +sock, +solar dish, solar collector, solar furnace, +sombrero, +soup bowl, +space bar, +space heater, +space shuttle, +spatula, +speedboat, +"spider web, spiders web", +spindle, +sports car, sport car, +spotlight, spot, +stage, +steam locomotive, +steel arch bridge, +steel drum, +stethoscope, +stole, +stone wall, +stopwatch, stop watch, +stove, +strainer, +streetcar, tram, tramcar, trolley, trolley car, +stretcher, +studio couch, day bed, +stupa, tope, +submarine, pigboat, sub, U-boat, +suit, suit of clothes, +sundial, +sunglass, +sunglasses, dark glasses, shades, +sunscreen, sunblock, sun blocker, +suspension bridge, +swab, swob, mop, +sweatshirt, +swimming trunks, bathing trunks, +swing, +switch, electric switch, electrical switch, +syringe, +table lamp, +tank, army tank, armored combat vehicle, armoured combat vehicle, +tape player, +teapot, +teddy, teddy bear, +television, television system, +tennis ball, +thatch, thatched roof, +theater curtain, theatre curtain, +thimble, +thresher, thrasher, threshing machine, +throne, +tile roof, +toaster, +tobacco shop, tobacconist shop, tobacconist, +toilet seat, +torch, +totem pole, +tow truck, tow car, wrecker, +toyshop, +tractor, +trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi, +tray, +trench coat, +tricycle, trike, velocipede, +trimaran, +tripod, +triumphal arch, +trolleybus, trolley coach, trackless trolley, +trombone, +tub, vat, +turnstile, +typewriter keyboard, +umbrella, +unicycle, monocycle, +upright, upright piano, +vacuum, vacuum cleaner, +vase, +vault, +velvet, +vending machine, +vestment, +viaduct, +violin, fiddle, +volleyball, +waffle iron, +wall clock, +wallet, billfold, notecase, pocketbook, +wardrobe, closet, press, +warplane, military plane, +washbasin, handbasin, washbowl, lavabo, wash-hand basin, +washer, automatic washer, washing machine, +water bottle, +water jug, +water tower, +whiskey jug, +whistle, +wig, +window screen, +window shade, +Windsor tie, +wine bottle, +wing, +wok, +wooden spoon, +wool, woolen, woollen, +worm fence, snake fence, snake-rail fence, Virginia fence, +wreck, +yawl, +yurt, +web site, website, internet site, site, +comic book, +crossword puzzle, crossword, +street sign, +traffic light, traffic signal, stoplight, +book jacket, dust cover, dust jacket, dust wrapper, +menu, +plate, +guacamole, +consomme, +hot pot, hotpot, +trifle, +ice cream, icecream, +ice lolly, lolly, lollipop, popsicle, +French loaf, +bagel, beigel, +pretzel, +cheeseburger, +hotdog, hot dog, red hot, +mashed potato, +head cabbage, +broccoli, +cauliflower, +zucchini, courgette, +spaghetti squash, +acorn squash, +butternut squash, +cucumber, cuke, +artichoke, globe artichoke, +bell pepper, +cardoon, +mushroom, +Granny Smith, +strawberry, +orange, +lemon, +fig, +pineapple, ananas, +banana, +jackfruit, jak, jack, +custard apple, +pomegranate, +hay, +carbonara, +chocolate sauce, chocolate syrup, +dough, +meat loaf, meatloaf, +pizza, pizza pie, +potpie, +burrito, +red wine, +espresso, +cup, +eggnog, +alp, +bubble, +cliff, drop, drop-off, +coral reef, +geyser, +lakeside, lakeshore, +promontory, headland, head, foreland, +sandbar, sand bar, +seashore, coast, seacoast, sea-coast, +valley, vale, +volcano, +ballplayer, baseball player, +groom, bridegroom, +scuba diver, +rapeseed, +daisy, +"yellow ladys slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum", +corn, +acorn, +hip, rose hip, rosehip, +buckeye, horse chestnut, conker, +coral fungus, +agaric, +gyromitra, +stinkhorn, carrion fungus, +earthstar, +hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa, +bolete, +ear, spike, capitulum, +toilet tissue, toilet paper, bathroom tissue diff --git a/python/examples/pipeline/imagenet/pipeline_rpc_client.py b/python/examples/pipeline/imagenet/pipeline_rpc_client.py new file mode 100644 index 00000000..3220e6c2 --- /dev/null +++ b/python/examples/pipeline/imagenet/pipeline_rpc_client.py @@ -0,0 +1,36 @@ +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from paddle_serving_server_gpu.pipeline import PipelineClient +import numpy as np +import requests +import json +import cv2 +import base64 +import os + +client = PipelineClient() +client.connect(['127.0.0.1:9999']) + + +def cv2_to_base64(image): + return base64.b64encode(image).decode('utf8') + + +with open("daisy.jpg", 'rb') as file: + image_data = file.read() +image = cv2_to_base64(image_data) + +for i in range(1): + ret = client.predict(feed_dict={"image": image}, fetch=["label", "prob"]) + print(ret) diff --git a/python/examples/pipeline/imagenet/resnet50_web_service.py b/python/examples/pipeline/imagenet/resnet50_web_service.py new file mode 100644 index 00000000..ece3befe --- /dev/null +++ b/python/examples/pipeline/imagenet/resnet50_web_service.py @@ -0,0 +1,71 @@ +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import sys +from paddle_serving_app.reader import Sequential, URL2Image, Resize, CenterCrop, RGB2BGR, Transpose, Div, Normalize, Base64ToImage +try: + from paddle_serving_server_gpu.web_service import WebService, Op +except ImportError: + from paddle_serving_server.web_service import WebService, Op +import logging +import numpy as np +import base64, cv2 + + +class ImagenetOp(Op): + def init_op(self): + self.seq = Sequential([ + Resize(256), CenterCrop(224), RGB2BGR(), Transpose((2, 0, 1)), + Div(255), Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225], + True) + ]) + self.label_dict = {} + label_idx = 0 + with open("imagenet.label") as fin: + for line in fin: + self.label_dict[label_idx] = line.strip() + label_idx += 1 + + def preprocess(self, input_dicts, data_id, log_id): + (_, input_dict), = input_dicts.items() + data = base64.b64decode(input_dict["image"].encode('utf8')) + data = np.fromstring(data, np.uint8) + # Note: class variables(self.var) can only be used in process op mode + im = cv2.imdecode(data, cv2.IMREAD_COLOR) + img = self.seq(im) + return {"image": img[np.newaxis, :].copy()}, False, None, "" + + def postprocess(self, input_dicts, fetch_dict, log_id): + print(fetch_dict) + score_list = fetch_dict["score"] + result = {"label": [], "prob": []} + for score in score_list: + score = score.tolist() + max_score = max(score) + result["label"].append(self.label_dict[score.index(max_score)] + .strip().replace(",", "")) + result["prob"].append(max_score) + result["label"] = str(result["label"]) + result["prob"] = str(result["prob"]) + return result, None, "" + + +class ImageService(WebService): + def get_pipeline_response(self, read_op): + image_op = ImagenetOp(name="imagenet", input_ops=[read_op]) + return image_op + + +uci_service = ImageService(name="imagenet") +uci_service.prepare_pipeline_config("config.yml") +uci_service.run_service() diff --git a/python/examples/senta/senta_web_service.py b/python/examples/senta/senta_web_service.py index 477064f3..6a100941 100644 --- a/python/examples/senta/senta_web_service.py +++ b/python/examples/senta/senta_web_service.py @@ -37,6 +37,7 @@ class SentaService(WebService): #定义senta模型预测服务的预处理,调用顺序:lac reader->lac模型预测->预测结果后处理->senta reader def preprocess(self, feed=[], fetch=[]): feed_batch = [] + is_batch = True words_lod = [0] for ins in feed: if "words" not in ins: @@ -64,14 +65,13 @@ class SentaService(WebService): return { "words": np.concatenate(feed_batch), "words.lod": words_lod - }, fetch + }, fetch, is_batch senta_service = SentaService(name="senta") senta_service.load_model_config("senta_bilstm_model") senta_service.prepare_server(workdir="workdir") senta_service.init_lac_client( - lac_port=9300, - lac_client_config="lac/lac_model/serving_server_conf.prototxt") + lac_port=9300, lac_client_config="lac_model/serving_server_conf.prototxt") senta_service.run_rpc_service() senta_service.run_web_service() diff --git a/python/pipeline/operator.py b/python/pipeline/operator.py index 2cf8a10c..92e0c0c6 100644 --- a/python/pipeline/operator.py +++ b/python/pipeline/operator.py @@ -1343,7 +1343,7 @@ class ResponseOp(Op): type(var))) _LOGGER.error("(logid={}) Failed to pack RPC " "response package: {}".format( - channeldata.id, resp.error_info)) + channeldata.id, resp.err_msg)) break resp.value.append(var) resp.key.append(name) diff --git a/python/pipeline/pipeline_client.py b/python/pipeline/pipeline_client.py index 971f3da7..265f88c4 100644 --- a/python/pipeline/pipeline_client.py +++ b/python/pipeline/pipeline_client.py @@ -23,7 +23,7 @@ import socket from .channel import ChannelDataErrcode from .proto import pipeline_service_pb2 from .proto import pipeline_service_pb2_grpc - +import six _LOGGER = logging.getLogger(__name__) @@ -53,7 +53,10 @@ class PipelineClient(object): if logid is None: req.logid = 0 else: - req.logid = long(logid) + if six.PY2: + req.logid = long(logid) + elif six.PY3: + req.logid = int(log_id) feed_dict.pop("logid") clientip = feed_dict.get("clientip") -- GitLab