首页 文章 精选 留言 我的

精选列表

搜索[基础搭建],共10000篇文章
优秀的个人博客,低调大师

Manifest.xml 入门基础 (五)<Activity>标签

<activity android:allowTaskReparenting=["true" | "false"] android:alwaysRetainTaskState=["true" | "false"] android:clearTaskOnLaunch=["true" | "false"] android:configChanges=["mcc", "mnc", "locale", "touchscreen", "keyboard", "keyboardHidden", "navigation", "orientation", "screenLayout", "fontScale", "uiMode"] android:enabled=["true" | "false"] android:excludeFromRecents=["true" | "false"] android:exported=["true" | "false"] android:finishOnTaskLaunch=["true" | "false"] android:icon="drawable resource" android:label="string resource" android:launchMode=["multiple" | "singleTop" | "singleTask" | "singleInstance"] android:multiprocess=["true" | "false"] android:name="string" android:noHistory=["true" | "false"] android:permission="string" android:process="string" android:screenOrientation=["unspecified" | "user" | "behind" | "landscape" | "portrait" | "sensor" | "nosensor"] android:stateNotNeeded=["true" | "false"] android:taskAffinity="string" android:theme="resource or theme" android:windowSoftInputMode=["stateUnspecified", "stateUnchanged", "stateHidden", "stateAlwaysHidden", "stateVisible", "stateAlwaysVisible", "adjustUnspecified", "adjustResize", "adjustPan"] > </activity> A、android:alwaysRetainTaskState 是否保留状态不变, 比如切换回home, 再从新打开,activity处于最后的状态。比如一个浏览器拥有很多状态(当打开了多个TAB的时候),用户并不希望丢失这些状态时,此时可将此属性设置为true B、android:clearTaskOnLaunch 比如 P 是 activity, Q 是被P 触发的 activity, 然后返回Home, 重新启动 P,是否显示 Q C、android:configChanges 当配置list发生修改时, 是否调用 onConfigurationChanged() 方法 比如 “locale|navigation|orientation”. 这个我用过,主要用来看手机方向改变的. android手机在旋转后,layout会重新布局, 如何做到呢?正常情况下. 如果手机旋转了.当前Activity后杀掉,然后根据方向重新加载这个Activity. 就会从onCreate开始重新加载.如果你设置了 这个选项, 当手机旋转后,当前Activity之后调用onConfigurationChanged() 方法. 而不跑onCreate方法等. D、android:excludeFromRecents 是否可被显示在最近打开的activity列表里,默认是false E、android:finishOnTaskLaunch 当用户重新启动这个任务的时候,是否关闭已打开的activity,默认是false如果这个属性和allowTaskReparenting都是true,这个属性就是王牌。Activity的亲和力将被忽略。该Activity已经被摧毁并非re-parented F、android:launchMode(Activity加载模式) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。这需要为Activity配置特定的加载模式,而不是使用默认的加载模式 Activity有四种加载模式: standard、singleTop、singleTask、singleInstance(其中前两个是一组、后两个是一组),默认为standard standard:就是intent将发送给新的实例,所以每次跳转都会生成新的activity。 singleTop:也是发送新的实例,但不同standard的一点是,在请求的Activity正好位于栈顶时(配置成singleTop的Activity),不会构造新的实例 singleTask:和后面的singleInstance都只创建一个实例,当intent到来,需要创建设置为singleTask的Activity的时候,系统会检查栈里面是否已经有该Activity的实例。如果有直接将intent发送给它。 singleInstance:首先说明一下task这个概念,Task可以认为是一个栈,可放入多个Activity。比如启动一个应用,那么Android就创建了一个Task,然后启动这个应用的入口Activity,那在它的界面上调用其他的Activity也只是在这个task里面。那如果在多个task中共享一个Activity的话怎么办呢。举个例来说,如果开启一个导游服务类的应用程序,里面有个Activity是开启GOOGLE地图的,当按下home键退回到主菜单又启动GOOGLE地图的应用时,显示的就是刚才的地图,实际上是同一个Activity,实际上这就引入了singleInstance。singleInstance模式就是将该Activity单独放入一个栈中,这样这个栈中只有这一个Activity,不同应用的intent都由这个Activity接收和展示,这样就做到了共享。当然前提是这些应用都没有被销毁,所以刚才是按下的HOME键,如果按下了返回键,则无效。 G、android:multiprocess 是否允许多进程,默认是false 在实际开发中,CP有以下两种用法: 1)和应用在一个APK包里 这种情况下和应用在同一进程中。process name和uid都一样。 2)单独在一个APK包里。 这种情况下,如果在AndroidManifest.xml文件里声明了和某个进程同属一个进程,如: package="com.android.providers.telephony" android:sharedUserId="android.uid.phone"> android:allowClearUserData="false" android:label="Dialer Storage" android:icon="@drawable/ic_launcher_phone"> android:authorities="telephony" android:multiprocess="true" 这个里面通过android:sharedUserId=”android.uid.phone”和android:process=”com.android.phone”声明了该CP是和phone进程同属一个进程,拥有同样的process name和uid. 如果没有上述声明,那么该CP是在独立的进程中,拥有属于自己的process name和uid. 以上两种用法可以总结为: 1)CP和某个进程同属一个进程 这种情况下,当该进程启动时,会搜索属于该进程的所有CP,并加载。 2)CP属于独立的一个进程。 这种情况下,只有需要用到该CP时,才会去加载。 那么,当一个进程想要操作一个CP时,先需要获取该CP的对象,系统是如何处理呢: 1)如果该CP属于当前主叫进程,因为在进程启动时就已经加载过了,所以系统会直接返回该CP的对象。 2)如果该CP不属于当前主叫进程,那么系统会进行相关处理(由ActivityManagerService进行,以下简称为AMS): 所有已加载的CP信息都已保存在AMS中。当需要获取某个CP的对象时,AMS会先判断该CP是否已被加载 —-如果已被加载,该CP和当前主叫进程不属一个进程,但是该CP设置了multiprocess的属性(如上例中的android:multiprocess=”true”),并且该CP属于系统级CP,那么就在当前主叫进程内部新生成该CP的对象。否则就需要通过IPC机制进行调用。 —-如果还未被加载,该CP和当前主叫进程不属一个进程,但是该CP设置了multiprocess的属性(如上例中的android:multiprocess=”true”),并且该CP属于系统级CP,那么就在当前主叫进程内部新生成该CP的对象。否则就需要先创建该CP所在的进程,然后再通过IPC机制进行调用。 H、android:noHistory 当用户从Activity上离开并且它在屏幕上不再可见时,Activity是否从Activity stack中清除并结束。默认是false。Activity不会留下历史痕迹 I、android:screenOrientation activity显示的模式 默认为unspecified:由系统自动判断显示方向 landscape横屏模式,宽度比高度大 portrait竖屏模式, 高度比宽度大 user模式,用户当前首选的方向 behind模式:和该Activity下面的那个Activity的方向一致(在Activity堆栈中的) sensor模式:有物理的感应器来决定。如果用户旋转设备这屏幕会横竖屏切换 nosensor模式:忽略物理感应器,这样就不会随着用户旋转设备而更改了 J、android:stateNotNeeded activity被销毁或者成功重启时是否保存状态 K、android:windowSoftInputMode activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Android1.5后的一个新特性。 这个属性能影响两件事情: 【A】当有焦点产生时,软键盘是隐藏还是显示 【B】是否减少活动主窗口大小以便腾出空间放软键盘 各值的含义: 【A】stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置 【B】stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示 【C】stateHidden:用户选择activity时,软键盘总是被隐藏 【D】stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的 【E】stateVisible:软键盘通常是可见的 【F】stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态 【G】adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示 【H】adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间 【I】adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。 一般情况下,在新建一个activity后,为了使intent可以调用此活动,我们要在androidManifest.xml文件中添加一个<activity>标签,<activity>标签的一般格式如下: <activity android:name="my.test.intents.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 其中,”android:name”是活动对应的类名称,”android:label”是活动标题栏显示的内容,<intent-filter>是意图筛选器,<action>是动作名称,是指intent要执行的动作,<category>是类别名称,一般情况下,每个<intent-filter> 中都要显示指定一个默认的类别名称,即<category android:name=”android.intent.category.DEFAULT” />,但是上面的代码中没有指定默认类别名称,这是一个例外情况,因为其<intent-filter> 中的<action>是”android.intent.action.MAIN”,意思是这项活动是应用程序的入口点,这种情况下可以不加默认类别名称。 当然,除<action>和<category>以外,<intent-filter>中还有很多其他元素,在这里不详述。 上面的代码是androidManifest.xml中定义程序入口活动的例子,下面我们写一个自定义的例子: <activity android:name=".MyBrowserActivity" android:label="My Activity" > <intent-filter> <action android:name="my.test.MyBrowser"/> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="http"/> </intent-filter> </activity> 在这个<activity>标签中,我们指定活动的类为MyBrowserActivity.class,活动的标题显示为”My Activity”,<action android:name=”my.test.MyBrowser”/>意味着其他活动可以通过my.test.MyBrowser动作来调用这个活动,”my.test.MyBrowser”只是我们定义的一个动作的名称,写成包的形式是因为这样使我们更容易理解它的含义,如果我们把”my.test.MyBrowser”改成任意的内容如:”somethingelse”,同样,我们可以通过这个新的动作名称,来调用这个活动。<data> 元素指定了活动期望的数据类型,在这里,它期望的数据要以http://前缀开头。

优秀的个人博客,低调大师

几道linux运维重要基础测试题,看看你会几个?

题1: 请把如下字符串 stu494 e222f stu495 bedf3 stu496 92236 stu497 49b91 转为如下形式: stu494=e222f stu495=bedf3 stu496=92236 stu497=49b91 题2: echo I am oldboy training,请把这个输出中的每个字符去重后排序,重复次数多的排到前面。 题3: 已知老男孩12月份将出版新书《跟老男孩学Linux运维:Shell高级编程实战》,下面是第8章的脚本名字,请对脚本名进行排序: 8_10_1.sh 8_1_1.sh 8_13_11.sh 8_2_2.sh 8_4_2.sh 8_6_1.sh 8_7.sh 8_9_2.sh 8_11_1.sh 8_12_1.sh 8_13_12.sh 8_3.sh 8_4_3.sh 8_6_2.sh 8_8.sh 8_11_2.sh 8_1_2.sh 8_2_1.sh 8_4_1.sh 8_4_4.sh 8_6_3.sh 8_9_1.sh 要求排序结果,第一列相同,按第二列排序,第二列相同按第三列排序: 8_1_1.sh 8_1_2.sh 8_2_1.sh 8_2_2.sh 8_3.sh 8_4_1.sh 8_4_2.sh 8_4_3.sh 8_4_4.sh 8_6_1.sh 8_6_2.sh 8_6_3.sh 8_7.sh 8_8.sh 8_9_1.sh 8_9_2.sh 8_10_1.sh 8_11_1.sh 8_11_2.sh 8_12_1.sh 8_13_11.sh 8_13_12.sh 大家练练手啊。 答案见评论:

优秀的个人博客,低调大师

Linux基础之IO重定向及管道详解(涉及tr、tee命令)

我在刚开始接触IO重定向时,经历了由懂到不懂然后了然的过程,当然现在的我也不可能说对于IO重定向就彻底懂了,只是在解决一些问题或实现某些结果时不会因为IO重定向的问题而迷惑了。 什么叫IO重定向? 为了解释这个问题,我们要先明白什么叫IO,什么叫做程序的数据流。 什么叫IO? 在Linux或计算机领域IO指的是信息的输入和输出。 在Linux中可用于输入的设备:文件(Linux中一切皆文件) 具体包括:键盘设备、文件系统上的常规文件、网卡等。 在Linux中用于输出的设备:文件 具体包括:显示器、文件系统上的常规文件、网卡等。 什么叫做数据流? 我们通常描述的信息本质上来说都是数据,因为信息处于动态,我们就将信息或者命令等概念称作流动的数据也就是数据流。 数据流分为输入流(InputStream)和输出流(OutputStream)两类。输入流只能读不能写,而输出流只能写不能读。通常程序中使用输入流读出数据,输出流写入数据,就好像数据流入到程序并从程序中流出。采用数据流使程序的输入输出操作独立与相关设备。输入流可从键盘或文件中获得数据,输出流可向显示器、打印机或文件中传输数据。 在Linux中,程序的数据流有三种: 输入的数据流:←标准输入 STDIN 常用设备:键盘 输出的数据流:→标准输出 STDOUT 常用设备:终端 错误输出流:→错误输出 STDERR 常用设备:终端 在Linux中打开一个文件,在该文件被加载完成后对于系统来说需要用一个数字表示,这个数字叫做fd:file descriptor 文件描述符。 因为Linux系统中一切皆文件,所以对应的标准输入设备,标准输出设备,错误输出设备都有其对应的fd 标准输入:0 标准输出:1 错误输出:2 IO重定向的意思就是将系统原本默认的输入输出的路径重新定向到其他文件。 我知道解释到这里还是会很困惑,别着急,这个概念需要通过一定量的实验来说明。 输出重定向 其常用 >、 >> 、>|这三种表示 >:覆盖输出 >>:追加输出 >|:强行覆盖 因为使用>不当会对原有的数据造成很大的影响,所以有时候我们会手动设定关闭>的特性。其命令为: set -C禁止覆盖输出重定功能 set +C为开启覆盖输出重定向功能 不过上述命令对“>|”无效 下面以具体实验来说明上面内容 实验环境:在/test/目录下 [root@localhosttest]#ll 总用量0 [root@localhosttest]#echo$(date)>t1 [root@localhosttest]#ll 总用量4 -rw-r--r--.1rootroot438月218:15t1 [root@localhosttest]#catt1 2016年08月02日星期二18:15:28CST [root@localhosttest]#echotest>t1 [root@localhosttest]#catt1 test [root@localhosttest]#echo$(who)>>t1 [root@localhosttest]#catt1 test root:02016-08-0210:12(:0)rootpts/02016-08-0210:12(192.168.85.1)rootpts/12016-08-0210:19(192.168.85.1) [root@localhosttest]#set-C [root@localhosttest]#echo111>t1 -bash:t1:无法覆盖已存在的文件 [root@localhosttest]#echo111>|t1 [root@localhosttest]#catt1 111 上面的结果显示了>、>>、>|三者的各自功能 相信看到这里对于输入重定向会有了进一步的认识。 错误输出流重定向 2> 2>> [root@localhosttest]#echoo1>t2 bash:echoo:未找到命令... 当命令错误时,shell会返回错误信息,若我们想将错误信息存到某个文件则可按如下操作 [root@localhosttest]#echoo12>t2 -bash:t2:无法覆盖已存在的文件 [root@localhosttest]#ll 总用量4 -rw-r--r--.1rootroot48月218:18t1 -rw-r--r--.1rootroot08月218:20t2 [root@localhosttest]#echoo12>t3 [root@localhosttest]#catt3 bash:echoo:未找到命令... [root@localhosttest]#echopwqew2>>t3 [root@localhosttest]#catt3 bash:echoo:未找到命令... 相似命令是:'echo' bash:echop:未找到命令... 错误重定向也支持追加。 如果我们不管命令对错都想记录那么可以使用如下格式实现: 1、&>、 &>> [root@localhosttest]#ech2&>>t4 [root@localhosttest]#echoright&>>t4 [root@localhosttest]#catt4 bash:ech2:未找到命令... right 2、command > /path/somewhere ... 2>&1;command >> /path/somewhere ... 2>&1第二种只能为此种格式,不管前面是追加还是覆盖后面均为2>&1。2>>&1为错误格式,使用后在centos7.2下会报错。 [root@localhosttest]#ech2>>t52>&1 [root@localhosttest]#echoright>>t52>&1 [root@localhosttest]#catt5 bash:ech2:未找到命令... right 注:输出重定向的对象可以是各种文件,但不能将其定向至命令的输入,要想实现这个功能则需要用管道。这里大家可能有点迷,下面以例子说明 [root@localhosttest]#who>tra-zA-Z>t6 [root@localhosttest]#catt6 rootpts/02016-08-0210:12(192.168.85.1) [root@localhosttest]#ll 总用量4 -rw-r--r--.1rootroot548月218:53t6 -rw-r--r--.1rootroot08月218:53tr 我们将who显示的命令重定向至tr命令的输入,之后将内容小写转换为大写后再重定向至t6文件。我们想实现的是这个结果,但是并没有实现,反而在过程中出现了tr这个文件。这是因为在第一层的重定向中,默认将tr当做文件名,但是奇怪的是tr内什么都没有,所以这种错误的理解尽早摆脱。 [root@localhosttest]#cattr [root@localhosttest]# 我们可以使用管道完美解决上面的问题。 [root@localhosttest]#who|tra-zA-Z>t6 [root@localhosttest]#catt6 ROOT:02016-08-0210:12(:0) ROOTPTS/02016-08-0210:12(192.168.85.1) ROOTPTS/12016-08-0210:19(192.168.85.1) 什么是管道,我相信通过上面的例子大家应该对它有了个初步的认知。 管道:连接程序,实现将前一个命令的输出直接定向后一个程序当做输入数据流。 其常用表达格式如下: COMMAND1 | COMMAND2 | COMMAND3 |... 它是输出重定向的补充与加强,其本质还是类属于输出重定向。 既然说道管道,这里再多补充点 常用于管道的命令: tee tee - read from standard input and write to standard output and files 显示标准输入的结果并将其写入文件 tee的使用格式: 命令1 | tee 文件名| 命令2 把命令1的STDOUT保存在文件名中,然后管道输入给命令2 作用: 保存不同阶段的输出 复杂管道的故障排除 同时查看和记录输出 下面通过一个简单的例子说明tee的具体作用 [root@localhosttest]#who|teet2|tra-zA-Z ROOT:02016-08-0210:12(:0) ROOTPTS/02016-08-0210:12(192.168.85.1) ROOTPTS/12016-08-0210:19(192.168.85.1) [root@localhosttest]#catt2 root:02016-08-0210:12(:0) rootpts/02016-08-0210:12(192.168.85.1) rootpts/12016-08-0210:19(192.168.85.1) tee可以将前一个的结果记录在t2文件内,同时显示后一个命令的结果。 输入重定向 < 单行模式、 << 多行模式 要了解输入重定向,我们得先了解一个命令 tr tr - translate or delete characters 转换或删除字符 其表达格式如下: tr[OPTION]... SET1 [SET2] 选项: -c或——complerment:取字符集的补集 -d或——delete:删除所有属于第一字符集的字符 -s或—squeeze-repeats:把连续重复的字符以单独一个字符表示 下面我们通过一个例子简要了解下tr的作用 [root@localhosttest]#catt1 root:02016-08-0210:12(:0) rootpts/02016-08-0210:12(192.168.85.1) rootpts/12016-08-0210:19(192.168.85.1) [root@localhosttest]#tra-zA-Z<t1 ROOT:02016-08-0210:12(:0) ROOTPTS/02016-08-0210:12(192.168.85.1) ROOTPTS/12016-08-0210:19(192.168.85.1) t1是上面tee存储的who内容,我们通过输入重定向将其作为tr的输入,并由小写转换为大写。 输入重定向就是将原来用键盘输入的内容通过其他文本内容或文件内容代替。 我想大家对于<<多行重定向有些不理解,这里再对多行重定向在以例子说明一下。 [root@localhost~]#tra-zA-Z<<end >morning,boys >todayisanotherday >pleasebehappy >end MORNING,BOYS TODAYISANOTHERDAY PLEASEBEHAPPY 多行输入重定向后面需要接规定的结尾字符串,通常使用eof或end为结尾标示符。 多行输入重定向需要手动键入内容。单行输入重定向则需要跟文件或前一个命令的输出结果。 我知道看到这里依然会有点懵,下面通过9个实例来综合使用标准输出输入及管道命令。 实验环境CentOS7.2 1、将/etc/issue文件中的内容转换为大写后保存至/test/issue#文件中 [root@localhosttest]#cat/etc/issue|tra-zA-Z>/test/issue1 [root@localhosttest]#echo$(tra-zA-Z</etc/issue)>/test/issue2 [root@localhosttest]#catissue1 \S KERNEL\RONAN\M [root@localhosttest]#catissue2 \SKERNEL\RONAN\M 上面两种方式均可以实现要求,只不过输出格式略有不同,这根命令有关。在没有进一步的限制下,这两种表达方式均可。第一种使用管道,输出重定向,第二种使用命令引用,输入重定向及输出重定向。 2、将当前系统登录用户的信息转换为大写后保存至/test/t2文件中 [root@localhosttest]#who|tra-zA-Z>/test/t2 [root@localhosttest]#catt2 ROOT:02016-08-0210:12(:0) ROOTPTS/02016-08-0210:12(192.168.85.1) ROOTPTS/12016-08-0210:19(192.168.85.1) 3、一个linux用户给root发邮件,要求邮件标题为”help”,邮件正文如下: Hello, I am 用户名,the system version is here,pleasehelp me to check it ,thanks! 操作系统版本信息 我们使用用户gentoo [root@localhost~]#sugentoo [gentoo@localhost/root]$whoami gentoo [gentoo@localhost/root]$cd/home/gentoo/ [gentoo@localhostgentoo]$echo-e"Hello,Iam`whoami`\nThesystemversionishere,pleasehelpmetocheckit,thanks.\nTheversionis`cat/etc/redhat-release`"|mail-s"help"root [gentoo@localhostgentoo]$exit exit 您在/var/spool/mail/root中有新邮件 [root@localhost~]#mail HeirloomMailversion12.57/5/10.Type?forhelp. "/var/spool/mail/root":3messages1new 1gentoo@localhost.locTueAug209:3821/731"help" 2rootTueAug209:4421/741"help" >N3gentoo@localhost.locTueAug219:3720/737"help" &3 Message3: Fromgentoo@localhost.localdomainTueAug219:37:362016 Return-Path:<gentoo@localhost.localdomain> X-Original-To:root Delivered-To:root@localhost.localdomain Date:Tue,02Aug201619:37:36+0800 To:root@localhost.localdomain Subject:help User-Agent:Heirloommailx12.57/5/10 Content-Type:text/plain;charset=us-ascii From:gentoo@localhost.localdomain Status:R -eHello,Iamgentoo Thesystemversionishere,pleasehelpmetocheckit,thanks. TheversionisCentOSLinuxrelease7.2.1511(Core) 这里使用了命令替换来显示用户及版本信息,管道将第一个命令的输出递给下一个命令作为其输入。 4、将/root/下文件列表,显示成一行,并文件名之间用空格隔开 [root@localhosttest]#ls-1/root|tr'\n'''\n anaconda-ks.cfgCSTdead.letterfileinitial-setup-ks.cfgtest.txttr公共模板视频图片文档下载音乐桌面[root@localhosttest]# 上面命令已经满足我们的要求了,只不过不换行看着有些别扭,下面我们在完善下使其输出看着更舒服些。 [root@localhosttest]#echo-e`ls-1/root/|tr'\n'''\n` anaconda-ks.cfgCSTdead.letterfileinitial-setup-ks.cfgtest.txttr公共模板视频图片文档下载音乐桌面 [root@localhosttest]# 使用echo的-e开启转义符使换行\n生效。 5、file1文件的内容为:”1 2 3 4 5 6 7 8 9 10” 计算出所有数字的总和 [root@localhosttest]#cat>file1 12345678910 ^C [root@localhosttest]#catfile1 12345678910 先创建file1文件夹并输入题目要求内容。 [root@localhosttest]#catfile1|tr'''+'|bc 55 6、处理字符串“xt.,l 1 jr#!$mn2 c*/fe3 uz4”,只保留其中的数字和空格 [root@localhosttest]#echo'xt.,l1jr#!$mn2c*/fe3uz4'|tr-cd'[:digit:][:space:]' 1234 这里使用了tr中的-c及-d补集跟删除,灵活使用补集概念可以更准确的帮助我们过滤不需要的信息。 7、将PATH变量每个目录显示在独立的一行 [root@localhosttest]#echo${PATH} /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin [root@localhosttest]#echo${PATH}|tr':''\n' /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /root/bin 这个题很简单只需要将PATH正确显示出来,使用tr将:替换为换行即可 8、删除指定文件的空行 这里我们创建一个含有很多空行的文本文件t9 [root@localhosttest]#catt9 q ere s df sd sd [root@localhosttest]#catt9|tr-s'\n' q ere s df sd sd 这里使用了tr的重复删除-s选项。 9、将文件中每个单词(字母)显示在独立的一行,并无空行 这里我们选择/etc/rc.d/rc0.d/K50netconsole文件,使用head查看下其文件前5行都什么内容 [root@localhosttest]#head-5/etc/rc.d/rc0.d/K50netconsole #!/bin/bash # #netconsoleThisloadsthenetconsolemodulewiththeconfiguredparameters. # #chkconfig:-5050 [root@localhosttest]#cat/etc/rc.d/rc0.d/K50netconsole|tr-cs'[:alpha:]''\n'|head-5 bin bash netconsole This 从结果来看我们实现了题目的要求,不过为什么第一行是空行,这是因为-s是将所有的空行压缩为一行,因此前面会留有一行空行。

优秀的个人博客,低调大师

mysql 基础操作全覆盖(适用与兼职DBA,不定期更新)

1.mysql版本应该怎么选择 由于5.5-5.6对mysql性能做了较大优化,所以一般选择mysql 5.5 或者 5.6 mysql 5.5.xx -5.6.xx 产品的特殊性,所以编译方式也和早期的产品安装方式不同,采用cmake或者gmake方式进行编译安装。即 ./cmake ; make ; make install ,生产场景的具体命令及参数为详见mysql 一键安装脚本 一键安装脚本下载链接 http://down.51cto.com/data/2228998 2.设置mysql的初始密码 mysql 安装完毕后是没有初始用户名密码的,所以我们要为mysql设置一个初始密码 mysqladmin -uroot password 1qaz@WSX? --(备注,是mysqladmin,而不是mysql) 3.查看数据库 show databases ; 4.使用某个库 use 库名 ; 5.查看当前数据库 select database (); 6.删除一个库 drop database test(库名称为test) ; 7.使用某个库 use 库名 ; 8.进入库后查看表 show tables ; 9.查看表结构 desc table名 ; 或者select * from table 名 10.查看所有用户 select host,user from mysql.user ; 11.删除用户 一般删除用户就用drop ,但是如果名字中有大写或者特殊字符,drop可能会有问题,会用delete dropuser''@'localhost';dropuser""@"localhost.localdomain";或者deletefrommysql.userwherehost="127.0.0.1";flushprivileges; 12.新建用户并为用户赋权/新建管理员 grant all on *.* to 'dailiang'@'%' identified by '1qaz@WSX?'; flush privileges; 这样这个用户与管理员的差别就是没有grant权限 grant all on *.* to 'dailiang'@'%' identified by '1qaz@WSX?' with grant option; 13.只设置查询权限 grant select on *.* to 'dailiang'@'%' identified by '1qaz@WSX?' ; flush privileges; grant select on *.* to 'dailiang'@'10.0.0.%' identified by '1qaz@WSX?' ; 表示对10.0.0.x 网段授权 13.查看用户权限 show grants for 'dailiang'@'%'; 或者 select * from mysql.user where user='dailiang'\G; 14. 收回权限之revoke help revoke; REVOKE INSERT ON *.* FROM 'jeffrey'@'localhost'; 15.交互式执行sql,不用登陆数据库 mysql -uroot -p1qaz@WSX? -e "show grants for 'dailiang'@'%';" 16.mysql用户一共18个权限 Select Insert Update Delete Create Drop Grant References Index Alter 17.修改用户密码 UPDATE mysql.user SET password=PASSWORD('新密码') WHERE user='用户名 update mysql.user set password=PASSWORD('111') where user='dailiang' and host='%'; flush privileges; 注意: 1.如果不加WHERE 条件,则会把所有用户的密码都修改为’新密码’ 密码修改完成后,需要进行权限刷新操作才能生效,FLUSH PRIVILEGES; ROOT用户可以修改自己的密码,也可以修改其他用户的密码 其他用户只能修改自己的密码 2.PASSWORD函数 mysql> SELECT PASSWORD('111'); 用于把密码明文进行加密,所得到的密码为原密码的哈希值。 mysql> SELECT PASSWORD('111'); +-------------------------------------------+ | PASSWORD('111') | +-------------------------------------------+ | *832EB84CB764129D05D498ED9CA7E5CE9B8F83EB | +-------------------------------------------+ 1 row in set (0.00 sec) 18.建表语句 建表格式为: create table 表名( 字段名1 类型1, 字段名2 类型2, 地段名3 类型3 ); 备注:注意逗号的位置 建表例子: CREATE table student( id int(4) NOT NULL, name CHAR(20) NOT NULL, age TINYINT(2) NOT NULL DEFAULT '0', dept VARCHAR(16) DEFAULT NULL ); int 整数类型 (4)是指长度 not null 是指不允许是空的 查看表结构如下: mysql> desc student; 查看当初建表语句: show create table student\G; mysql> show create table student\G; *************************** 1. row *************************** Table: student Create Table: CREATE TABLE `student` ( `id` int(4) NOT NULL, `name` char(20) NOT NULL, `age` tinyint(2) NOT NULL DEFAULT '0', `dept` varchar(16) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec) 解释:mysql 5.5以后使用的是innoDB引擎,mysql5.1及以前默认引擎为MyISAM MYSQL表的字段类型: int 整数类型 char 定长字符串类型,当存储时,总是用空格填满右边到指定的长度 varchar 变长字符串类型 19.索引(主键)相关知识 索引就像书的目录一样,如果在字段上建立了索引,那么以索引列为查询条件时可以加快查询速度,这是mysql的优化的重要内容之一 主键索引: 查询数据库,按主键查询是最快的,每个表只能有一个主键列,但是可以有多个普通索引列,主键列要求所有内容必须唯一,而索引列不要求内容必须唯一 主键就类似我们在学校的学号或者×××号一样,是唯一的,索引类是不唯一的 可以这样说: 主键是一个特殊的索引 建立索引: 首先无论建立主键索引还是普通索引,都要在表的对应列上创建,可以对单列创建索引,也可以对多列创建索引 CREATE table student02( id int(4) NOT NULL AUTO_INCREMENT, name CHAR(20) NOT NULL, age TINYINT(2) NOT NULL DEFAULT '0', dept VARCHAR(16) DEFAULT NULL, PRIMARY KEY(id), KEY INDEX_NAME(NAME) ); 解析: AUTO_INCREMENT → 自增 PRIMARY KEY(id) → PRI主键,以id列为主键 KEY INDEX_NAME(NAME) → 普通索引 mysql> desc student02; PRI是主键索引 MUL是普通索引 建表后可以通过alter命令增加主键索引,但是一般不建议这样干 alter table student change id id int primary key auto_increment; 增加主键前: 增加主键后: 查看某个表的索引和主键: Show index from 表名\G; 建表后删除普通索引: alter table student02 drop index index_name ;index_name是索引的名字 建表后增加普通索引: alter table student02 add index index_name(name);index_name 是指索引的名字 name 是这行的名字,就是对name 这行添加 创建联合索引: Create index id_name_dept on student(name,dept); 注:红色为索引名称可以随便起啊,但是为了以后好改还是按标准比较好 创建唯一索引: Create unique index index_ind_name on student(name); 建出来时会是UNI OK,最后我们来说一下索引的具体应用 问题一:既然索引可以加快查询速度,那么为啥不把所有列建立索引啊? 解答:因为索引不但占用系统空间,更新数据库时还需要维护索引数据,因此索引是一把双刃剑,并不是越多越好,例如比较小的表就不需要建索引了,写频繁读少的业务要少建立索引,因为写一次就需要更新一下索引 因为就像word目录一样,你写入一些东西之后就需要更新目录啊,不然是乱的,这就是为什么写频繁的数据库增加索引会很麻烦的原因,表更新了,就需要更新索引 问题二:在哪些列上创建索引更好呢? select host,user from mysql.user where user='xxx';索引一般都会建在where后的条件列上 20.mysql插入之insert 先建一个简单的测试表 create table test (id int(4) NOT NULL AUTO_INCREMENT ,name varchar(20) NOT NULL ,PRIMARY KEY (id)); ok,准备工作做好了,开始插入第一条 插入单条数据: insert into test(id,name) value (1,'dailiang'); 插入多条数据: insert into test(id,name) value (2,'dailiang02'), (3,'dailiang03'); 注意: 数字 2 之类的不需要加单引,但是字符串系列如 dailiang 就需要加单引了 插入数据最好批量插入,不要一条一条的插入 21.mysql之select语句 limit用法: select id,namefrom test limit 2 只查两行 select id,namefrom test limit 0,2; 只查0到2行 条件查询: mysql> selectid,name from test where id=1; mysql> selectid,name from test where name='oldgirl'; Attention: 字符串要接引号 后面加where条件语句:and or mysql> selectid,name from test where name='oldgirl'and id=3; mysql> selectid,name from test where name='oldgirl' or id=1; 范围查询: Select id,name from test where id >2 and id<1 Select id,name from test where id >2 or id<1 排序: 默认是正序 Select id,name from test order by id asc; 正序 Select id,name from test order by id desc; 倒序 22.连表查询: 首先先建三张表做实验: create table student ( Sno int(10) NOT NULL COMMENT '学号',Sname varchar(16) NOT NULLCOMMENT '性名',Ssex char(2) NOT NULL COMMENT '性别',Sage tinyint(2) NOT NULL default '0' COMMENT '学生年龄',Sdept varchar(16) default NULL COMMENT '学生所在系别',primary key (Sno),key index_Sname (Sname) ); create table course(Cno int(10) NOT NULL COMMENT '课程号',Cname varchar(64) NOT NULL COMMENT '课程名',Ccredit tinyint(2) NOT NULL COMMENT '学分',PRIMARY KEY (Cno))ENGINE=InnoDB AUTO_INCREMENT=1 ; create table SC (SCid int(12) not null auto_increment comment '主键',Cno int(10) not null comment '课程号',Sno int(10) not null comment '学号',Grade tinyint(2) not null comment '学生成绩',primary key (SCid))ENGINE=innodb ; 插入内容: insert into student values(0001,'代亮','男',18,'清华计算机'); insert into student values(0002,'张峰来','女',68,'野鸡管理'); insert into student values(0003,'管建宇','女',28,'野鸡管理'); insert into student values(0004,'周新宇','女',19,'野鸡管理'); insert into student values(0005,'林绅武','女',31,'野鸡管理'); insert into student values(0006,'胡麒','女',38,'野鸡管理'); insert into student values(0007,'李楠','女',40,'野鸡管理'); insert into course values(1001,'LINUX高级',1); insert into course values(1002,'小学数学',1); insert into course values(1003,'小学语文',1); insert into course values(1004,'小学英语',1); insert into course values(1005,'大保健培训',6); insert into SC(Sno,Cno,Grade) values (0001,1001,1);insert into SC(Sno,Cno,Grade) values (0002,1002,1);insert into SC(Sno,Cno,Grade) values (0002,1003,1);insert into SC(Sno,Cno,Grade) values (0002,1004,1);insert into SC(Sno,Cno,Grade) values (0002,1005,6);insert into SC(Sno,Cno,Grade) values (0003,1002,1);insert into SC(Sno,Cno,Grade) values (0003,1003,1);insert into SC(Sno,Cno,Grade) values (0003,1004,1);insert into SC(Sno,Cno,Grade) values (0003,1005,6);insert into SC(Sno,Cno,Grade) values (0004,1002,0);insert into SC(Sno,Cno,Grade) values (0004,1003,0);insert into SC(Sno,Cno,Grade) values (0004,1004,0);insert into SC(Sno,Cno,Grade) values (0004,1005,6);insert into SC(Sno,Cno,Grade) values (0005,1002,0);insert into SC(Sno,Cno,Grade) values (0005,1003,0);insert into SC(Sno,Cno,Grade) values (0005,1004,0);insert into SC(Sno,Cno,Grade) values (0005,1005,6); 经典连表查询: select student.Sname,student.Ssex,student.Sage,student.sdept ,course.Cname,SC.Grade from student,course,SC where student.Sage >1 and student.Sno<100; 23.explain命令 用explain命令来查看某个select命令是不是走了索引了啊,如果没有走索引,我们可以见一个啊 但是索引不是乱建的,建索引原则,请看上文 mysql> explain select Sage from student where Sage=18\G; 可以看出where后面的Sage不是索引。。 为这一列添加普通索引:mysql> Alter table student add index index_Sage(Sage); 这下就使用索引了额。。 24.修改表中的数据 更改表数据: update student set Sname='张来' where Sno=2 强烈备注:千万不要忘记where,如果忘记where,那么整个表Sname就全部变了,容易造成生产事故 25.删除整个表 drop tablename 26.删除表内容,但保持表结构 delete table名 或者 truncat table名 两种都是清空表内数据,但是保留表的内容 **删除了指定表中的所有行,但表的结构及其列,约束,索引等保持不变** 27.mysql停从库操作 show processlist; show slave status\G; slave stop; service mysqld stop

优秀的个人博客,低调大师

无需搭建环境,零门槛带你体验Open-Sora文生视频应用

本文分享自华为云社区《Open-Sora 文生视频原来在AI Gallery上也能体验了》,作者:码上开花_Lancer。 体验链接:Open-Sora 文生视频案例体验 不久前,OpenAI Sora 凭借其惊人的视频生成效果迅速走红,在一堆文本转视频模型中脱颖而出,成为全球关注的焦点。之后,Colossal-AI团队又推出了新的开源解决方案“Open-Sora 1.0”,涵盖了整个训练过程,包括数据处理、所有训练细节和模型检查点,与世界各地的AI爱好者携手推进视频创作的新时代。 详细内容请参考:https://hpc-ai.com/blog/open-sora-v1.0 2024年4月份又更新了Open-Sora 1.1,它可以生成2s~15s,144p到720p分辨率的视频,支持文本到图像、文本到视频以及图像到视频的生成,让我们来看看Open-Sora 1.1的实际视频生成效果: 案例体验 ?*本案例需使用 Pytorch-2.0.1 GPU-V100 及以上规格运行 ?* 点击Run in ModelArts,将会进入到ModelArts CodeLab中,这时需要你登录华为云账号,如果没有账号,则需要注册一个,且要进行实名认证,参考《如何创建华为云账号并且实名认证》即可完成账号注册和实名认证。 登录之后,等待片刻,即可进入到CodeLab的运行环境 ?* 出现 Out Of Memory ,请检查是否为您的参数配置过高导致,修改参数配置,重启kernel或更换更高规格资源进行规避❗❗❗ 1. 下载代码和模型 此处运行大约需要1分钟,请耐心等待! import os import moxing as mox ​ if not os.path.exists('Open-Sora'): mox.file.copy_parallel('obs://modelbox-course/open-sora_1.1/Open-Sora', 'Open-Sora') if not os.path.exists('/home/ma-user/.cache/huggingface'): mox.file.copy_parallel('obs://modelbox-course/huggingface', '/home/ma-user/.cache/huggingface') if not os.path.exists('Open-Sora/opensora/models/sd-vae-ft-ema'): mox.file.copy_parallel('obs://modelbox-course/sd-vae-ft-ema', 'Open-Sora/opensora/models/sd-vae-ft-ema') ​ if not os.path.exists('Open-Sora/opensora/models/text_encoder/t5-v1_1-xxl'): mox.file.copy_parallel('obs://modelbox-course/t5-v1_1-xxl', 'Open-Sora/opensora/models/text_encoder/t5-v1_1-xxl') if not os.path.exists('/home/ma-user/work/t5.py'): mox.file.copy_parallel('obs://modelbox-course/open-sora_1.1/t5.py', '/home/ma-user/work/t5.py') if not os.path.exists('Open-Sora/opus-mt-zh-en'): mox.file.copy_parallel('obs://modelarts-labs-bj4-v2/course/ModelBox/opus-mt-zh-en', 'Open-Sora/opus-mt-zh-en') if not os.path.exists('/home/ma-user/work/frpc_linux_amd64'): mox.file.copy_parallel('obs://modelarts-labs-bj4-v2/course/ModelBox/frpc_linux_amd64', '/home/ma-user/work/frpc_linux_amd64') INFO:root:Using MoXing-v2.1.6.879ab2f4-879ab2f4 ​ INFO:root:List OBS time cost: 0.02 seconds. ​ INFO:root:Copy parallel total time cost: 41.71 seconds. ​ INFO:root:List OBS time cost: 0.14 seconds. ​ INFO:root:Copy parallel total time cost: 2.91 seconds. 2. 配置运行环境 本案例依赖Python3.10.10及以上环境,因此我们首先创建虚拟环境: !/home/ma-user/anaconda3/bin/conda clean -i !/home/ma-user/anaconda3/bin/conda create -n python-3.10.10 python=3.10.10 -y --override-channels --channel https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main !/home/ma-user/anaconda3/envs/python-3.10.10/bin/pip install ipykernel /home/ma-user/anaconda3/lib/python3.7/site-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.26.15) or chardet (3.0.4) doesn't match a supported version! RequestsDependencyWarning) /home/ma-user/anaconda3/lib/python3.7/site-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.26.15) or chardet (3.0.4) doesn't match a supported version! RequestsDependencyWarning) Collecting package metadata (current_repodata.json): done Solving environment: failed with repodata from current_repodata.json, will retry with next repodata source. Collecting package metadata (repodata.json): done Solving environment: done ​ ## Package Plan ## ​ environment location: /home/ma-user/anaconda3/envs/python-3.10.10 ​ added / updated specs: - python=3.10.10 The following packages will be downloaded: ​ package * build ---------------------------*----------------- _libgcc_mutex-0.1 * main 3 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main _openmp_mutex-5.1 * 1_gnu 21 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main bzip2-1.0.8 * h5eee18b_6 262 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main ca-certificates-2024.3.11 * h06a4308_0 127 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main ld_impl_linux-64-2.38 * h1181459_1 654 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main libffi-3.4.4 * h6a678d5_1 141 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main libgcc-ng-11.2.0 * h1234567_1 5.3 MB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main libgomp-11.2.0 * h1234567_1 474 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main libstdcxx-ng-11.2.0 * h1234567_1 4.7 MB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main libuuid-1.41.5 * h5eee18b_0 27 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main ncurses-6.4 * h6a678d5_0 914 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main openssl-1.1.1w * h7f8727e_0 3.7 MB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main pip-24.0 * py310h06a4308_0 2.7 MB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main python-3.10.10 * h7a1cb2a_2 26.9 MB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main readline-8.2 * h5eee18b_0 357 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main setuptools-69.5.1 * py310h06a4308_0 1012 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main sqlite-3.45.3 * h5eee18b_0 1.2 MB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main tk-8.6.14 * h39e8969_0 3.4 MB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main tzdata-2024a * h04d1e81_0 116 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main wheel-0.43.0 * py310h06a4308_0 110 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main xz-5.4.6 * h5eee18b_1 643 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main zlib-1.2.13 * h5eee18b_1 111 KB https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main ------------------------------------------------------------ Total: 52.8 MB ​ The following NEW packages will be INSTALLED: ​ _libgcc_mutex anaconda/pkgs/main/linux-64::_libgcc_mutex-0.1-main _openmp_mutex anaconda/pkgs/main/linux-64::_openmp_mutex-5.1-1_gnu bzip2 anaconda/pkgs/main/linux-64::bzip2-1.0.8-h5eee18b_6 ca-certificates anaconda/pkgs/main/linux-64::ca-certificates-2024.3.11-h06a4308_0 ld_impl_linux-64 anaconda/pkgs/main/linux-64::ld_impl_linux-64-2.38-h1181459_1 libffi anaconda/pkgs/main/linux-64::libffi-3.4.4-h6a678d5_1 libgcc-ng anaconda/pkgs/main/linux-64::libgcc-ng-11.2.0-h1234567_1 libgomp anaconda/pkgs/main/linux-64::libgomp-11.2.0-h1234567_1 libstdcxx-ng anaconda/pkgs/main/linux-64::libstdcxx-ng-11.2.0-h1234567_1 libuuid anaconda/pkgs/main/linux-64::libuuid-1.41.5-h5eee18b_0 ncurses anaconda/pkgs/main/linux-64::ncurses-6.4-h6a678d5_0 openssl anaconda/pkgs/main/linux-64::openssl-1.1.1w-h7f8727e_0 pip anaconda/pkgs/main/linux-64::pip-24.0-py310h06a4308_0 python anaconda/pkgs/main/linux-64::python-3.10.10-h7a1cb2a_2 readline anaconda/pkgs/main/linux-64::readline-8.2-h5eee18b_0 setuptools anaconda/pkgs/main/linux-64::setuptools-69.5.1-py310h06a4308_0 sqlite anaconda/pkgs/main/linux-64::sqlite-3.45.3-h5eee18b_0 tk anaconda/pkgs/main/linux-64::tk-8.6.14-h39e8969_0 tzdata anaconda/pkgs/main/noarch::tzdata-2024a-h04d1e81_0 wheel anaconda/pkgs/main/linux-64::wheel-0.43.0-py310h06a4308_0 xz anaconda/pkgs/main/linux-64::xz-5.4.6-h5eee18b_1 zlib anaconda/pkgs/main/linux-64::zlib-1.2.13-h5eee18b_1 Downloading and Extracting Packages libffi-3.4.4 * 141 KB * ##################################### * 100% _openmp_mutex-5.1 * 21 KB * ##################################### * 100% xz-5.4.6 * 643 KB * ##################################### * 100% tzdata-2024a * 116 KB * ##################################### * 100% _libgcc_mutex-0.1 * 3 KB * ##################################### * 100% zlib-1.2.13 * 111 KB * ##################################### * 100% bzip2-1.0.8 * 262 KB * ##################################### * 100% libuuid-1.41.5 * 27 KB * ##################################### * 100% ca-certificates-2024 * 127 KB * ##################################### * 100% libstdcxx-ng-11.2.0 * 4.7 MB * ##################################### * 100% ncurses-6.4 * 914 KB * ##################################### * 100% openssl-1.1.1w * 3.7 MB * ##################################### * 100% wheel-0.43.0 * 110 KB * ##################################### * 100% python-3.10.10 * 26.9 MB * ##################################### * 100% pip-24.0 * 2.7 MB * ##################################### * 100% readline-8.2 * 357 KB * ##################################### * 100% tk-8.6.14 * 3.4 MB * ##################################### * 100% setuptools-69.5.1 * 1012 KB * ##################################### * 100% libgcc-ng-11.2.0 * 5.3 MB * ##################################### * 100% ld_impl_linux-64-2.3 * 654 KB * ##################################### * 100% libgomp-11.2.0 * 474 KB * ##################################### * 100% sqlite-3.45.3 * 1.2 MB * ##################################### * 100% Preparing transaction: done Verifying transaction: done Executing transaction: done # # To activate this environment, use # # $ conda activate python-3.10.10 # # To deactivate an active environment, use # # $ conda deactivate ​ Looking in indexes: http://repo.myhuaweicloud.com/repository/pypi/simple Collecting ipykernel Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/53/9d/40d5207db523363d9b5698f33778c18b0d591e3fdb6e0116b894b2a2491c/ipykernel-6.29.4-py3-none-any.whl (117 kB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m117.1/117.1 kB•[0m •[31m10.6 MB/s•[0m eta •[36m0:00:00•[0m ...... ​ Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/80/03/6ea8b1b2a5ab40a7a60dc464d3daa7aa546e0a74d74a9f8ff551ea7905db/executing-2.0.1-py2.py3-none-any.whl (24 kB) Collecting asttokens>=2.1.0 (from stack-data->ipython>=7.23.1->ipykernel) Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/45/86/4736ac618d82a20d87d2f92ae19441ebc7ac9e7a581d7e58bbe79233b24a/asttokens-2.4.1-py2.py3-none-any.whl (27 kB) Collecting pure-eval (from stack-data->ipython>=7.23.1->ipykernel) Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/2b/27/77f9d5684e6bce929f5cfe18d6cfbe5133013c06cb2fbf5933670e60761d/pure_eval-0.2.2-py3-none-any.whl (11 kB) Installing collected packages: wcwidth, pure-eval, ptyprocess, typing-extensions, traitlets, tornado, six, pyzmq, pygments, psutil, prompt-toolkit, platformdirs, pexpect, parso, packaging, nest-asyncio, executing, exceptiongroup, decorator, debugpy, python-dateutil, matplotlib-inline, jupyter-core, jedi, comm, asttokens, stack-data, jupyter-client, ipython, ipykernel Successfully installed asttokens-2.4.1 comm-0.2.2 debugpy-1.8.1 decorator-5.1.1 exceptiongroup-1.2.1 executing-2.0.1 ipykernel-6.29.4 ipython-8.25.0 jedi-0.19.1 jupyter-client-8.6.2 jupyter-core-5.7.2 matplotlib-inline-0.1.7 nest-asyncio-1.6.0 packaging-24.0 parso-0.8.4 pexpect-4.9.0 platformdirs-4.2.2 prompt-toolkit-3.0.46 psutil-5.9.8 ptyprocess-0.7.0 pure-eval-0.2.2 pygments-2.18.0 python-dateutil-2.9.0.post0 pyzmq-26.0.3 six-1.16.0 stack-data-0.6.3 tornado-6.4 traitlets-5.14.3 typing-extensions-4.12.1 wcwidth-0.2.13 import json import os ​ data = { "display_name": "python-3.10.10", "env": { "PATH": "/home/ma-user/anaconda3/envs/python-3.10.10/bin:/home/ma-user/anaconda3/envs/python-3.7.10/bin:/modelarts/authoring/notebook-conda/bin:/opt/conda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/ma-user/modelarts/ma-cli/bin:/home/ma-user/modelarts/ma-cli/bin:/home/ma-user/anaconda3/envs/PyTorch-1.8/bin" }, "language": "python", "argv": [ "/home/ma-user/anaconda3/envs/python-3.10.10/bin/python", "-m", "ipykernel", "-f", "{connection_file}" ] } ​ if not os.path.exists("/home/ma-user/anaconda3/share/jupyter/kernels/python-3.10.10/"): os.mkdir("/home/ma-user/anaconda3/share/jupyter/kernels/python-3.10.10/") ​ with open('/home/ma-user/anaconda3/share/jupyter/kernels/python-3.10.10/kernel.json', 'w') as f: json.dump(data, f, indent=4) conda env list /home/ma-user/anaconda3/lib/python3.7/site-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.26.15) or chardet (3.0.4) doesn't match a supported version! RequestsDependencyWarning) # conda environments: # base * /home/ma-user/anaconda3 python-3.10.10 /home/ma-user/anaconda3/envs/python-3.10.10 python-3.7.10 /home/ma-user/anaconda3/envs/python-3.7.10 Note: you may need to restart the kernel to use updated packages. 创建完成后,稍等片刻,或刷新页面,点击右上角kernel选择python-3.10.10 查看Python版本 !python -V Python 3.10.10 检查可用GPU,至少需要32GB显存 !nvidia-smi Wed Jun 5 16:22:37 2024 +-----------------------------------------------------------------------------+ * NVIDIA-SMI 470.57.02 Driver Version: 470.57.02 CUDA Version: 11.4 * *-------------------------------+----------------------+----------------------+ * GPU Name Persistence-M* Bus-Id Disp.A * Volatile Uncorr. ECC * * Fan Temp Perf Pwr:Usage/Cap* Memory-Usage * GPU-Util Compute M. * * * * MIG M. * *===============================+======================+======================* * 0 Tesla V100-PCIE... On * 00000000:00:0D.0 Off * 0 * * N/A 28C P0 25W / 250W * 0MiB / 32510MiB * 0% Default * * * * N/A * +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ * Processes: * * GPU GI CI PID Type Process name GPU Memory * * ID ID Usage * *=============================================================================* * No running processes found * +-----------------------------------------------------------------------------+ 安装依赖包 !pip install --upgrade pip !pip install torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 xformers==0.0.22 Looking in indexes: http://repo.myhuaweicloud.com/repository/pypi/simple Requirement already satisfied: pip in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (24.0) Looking in indexes: http://repo.myhuaweicloud.com/repository/pypi/simple Collecting torch==2.0.1 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/8c/4d/17e07377c9c3d1a0c4eb3fde1c7c16b5a0ce6133ddbabc08ceef6b7f2645/torch-2.0.1-cp310-cp310-manylinux1_x86_64.whl (619.9 MB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m619.9/619.9 MB•[0m •[31m8.2 MB/s•[0m eta •[36m0:00:00•[0m00:01•[0m00:01•[0m •[?25hCollecting torchvision==0.15.2 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/87/0f/88f023bf6176d9af0f85feedf4be129f9cf2748801c4d9c690739a10c100/torchvision-0.15.2-cp310-cp310-manylinux1_x86_64.whl (6.0 MB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m6.0/6.0 MB•[0m •[31m109.5 MB/s•[0m eta •[36m0:00:00•[0ma •[36m0:00:01•[0m •[?25hCollecting torchaudio==2.0.2 Downloading •[?25hCollecting certifi>=2017.4.17 (from requests->torchvision==0.15.2) Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/5b/11/1e78951465b4a225519b8c3ad29769c49e0d8d157a070f681d5b6d64737f/certifi-2024.6.2-py3-none-any.whl (164 kB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m164.4/164.4 kB•[0m •[31m23.1 MB/s•[0m eta •[36m0:00:00•[0m •[?25hCollecting mpmath<1.4.0,>=1.1.0 (from sympy->torch==2.0.1) Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl (536 kB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m536.2/536.2 kB•[0m •[31m32.8 MB/s•[0m eta •[36m0:00:00•[0m •[?25hInstalling collected packages: mpmath, lit, urllib3, sympy, pillow, nvidia-nvtx-cu11, nvidia-nccl-cu11, nvidia-cusparse-cu11, nvidia-curand-cu11, nvidia-cufft-cu11, nvidia-cuda-runtime-cu11, nvidia-cuda-nvrtc-cu11, nvidia-cuda-cupti-cu11, nvidia-cublas-cu11, numpy, networkx, MarkupSafe, idna, filelock, cmake, charset-normalizer, certifi, requests, nvidia-cusolver-cu11, nvidia-cudnn-cu11, jinja2, triton, torch, xformers, torchvision, torchaudio Successfully installed MarkupSafe-2.1.5 certifi-2024.6.2 charset-normalizer-3.3.2 cmake-3.29.3 filelock-3.14.0 idna-3.7 jinja2-3.1.4 lit-18.1.6 mpmath-1.3.0 networkx-3.3 numpy-1.26.4 nvidia-cublas-cu11-11.10.3.66 nvidia-cuda-cupti-cu11-11.7.101 nvidia-cuda-nvrtc-cu11-11.7.99 nvidia-cuda-runtime-cu11-11.7.99 nvidia-cudnn-cu11-8.5.0.96 nvidia-cufft-cu11-10.9.0.58 nvidia-curand-cu11-10.2.10.91 nvidia-cusolver-cu11-11.4.0.1 nvidia-cusparse-cu11-11.7.4.91 nvidia-nccl-cu11-2.14.3 nvidia-nvtx-cu11-11.7.91 pillow-10.3.0 requests-2.32.3 sympy-1.12.1 torch-2.0.1 torchaudio-2.0.2 torchvision-0.15.2 triton-2.0.0 urllib3-2.2.1 xformers-0.0.22 %cd Open-Sora /home/ma-user/work/ma_share/open-spra_1/Open-Sora /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/IPython/core/magics/osm.py:417: UserWarning: This is now an optional IPython functionality, setting dhist requires you to install the `pickleshare` library. self.shell.db['dhist'] = compress_dhist(dhist)[-100:] '/home/ma-user/work/ma_share/open-spra_1/Open-Sora' !pip install colossalai==0.3.6 accelerate==0.29.2 diffusers==0.27.2 ftfy==6.2.0 gdown==5.1.0 mmengine==0.10.3 pre-commit==3.7.0 pyav==12.0.5 tensorboard==2.16.2 timm==0.9.16 transformers==4.39.3 wandb==0.16.6 Looking in indexes: http://repo.myhuaweicloud.com/repository/pypi/simple Collecting colossalai==0.3.6 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/05/ed/57e80620ea8e35c3aa63a3207720b1890700fd12eea38b6592e9833e5c1b/colossalai-0.3.6.tar.gz (1.1 MB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m1.1/1.1 MB•[0m •[31m36.5 MB/s•[0m eta •[36m0:00:00•[0m •[?25h Preparing metadata (setup.py) ... •[?25ldone •[?25hCollecting accelerate==0.29.2 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/1b/e8/2fc7af3fa77ddac89a9c9b390d2d31d1db0612247ba2274009946959604e/accelerate-0.29.2-py3-none-any.whl (297 kB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m297.4/297.4 kB•[0m •[31m14.5 MB/s•[0m eta •[36m0:00:00•[0m •[?25hCollecting diffusers==0.27.2 Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/75/c5/3b84fd731dd93c549a0c25657e4ce5a957aeccd32d60dba2958cd3cdac23/diffusers-0.27.2-py3-none-any.whl (2.0 MB) ​ !pip install . Looking in indexes: http://repo.myhuaweicloud.com/repository/pypi/simple Processing /home/ma-user/work/ma_share/open-spra_1/Open-Sora Preparing metadata (setup.py) ... •[?25ldone •[?25hRequirement already satisfied: colossalai in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (0.3.6) Requirement already satisfied: accelerate in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (0.29.2) Requirement already satisfied: diffusers in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (0.27.2) Requirement already satisfied: ftfy in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (6.2.0) Requirement already satisfied: gdown in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (5.1.0) Requirement already satisfied: mmengine in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (0.10.3) Collecting pandas (from opensora==1.1.0) Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/89/1b/12521efcbc6058e2673583bb096c2b5046a9df39bd73eca392c1efed24e5/pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (13.0 MB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m13.0/13.0 MB•[0m •[31m60.4 MB/s•[0m eta •[36m0:00:00•[0m00:01•[0m00:01•[0m •[?25hRequirement already satisfied: pre-commit in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (3.7.0) Collecting pyarrow (from opensora==1.1.0) Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/91/83/57572c088ec185582f04b607d545a4a6ef7599c0a3c1e60d397743b0d609/pyarrow-16.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (40.9 MB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m40.9/40.9 MB•[0m •[31m36.9 MB/s•[0m eta •[36m0:00:00•[0m00:01•[0m00:01•[0m •[?25hCollecting av (from opensora==1.1.0) Downloading http://repo.myhuaweicloud.com/repository/pypi/packages/0a/11/2b501d0a4de22826217a0b909e832f52fb5d503df50f424f3e31023a7bcc/av-12.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (34.3 MB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m34.3/34.3 MB•[0m •[31m96.1 MB/s•[0m eta •[36m0:00:00•[0m00:01•[0m00:01•[0m •[?25hRequirement already satisfied: tensorboard in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (2.16.2) Requirement already satisfied: timm in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (0.9.16) Requirement already satisfied: tqdm in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (4.66.4) Requirement already satisfied: transformers in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (4.39.3) Requirement already satisfied: wandb in /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages (from opensora==1.1.0) (0.16.6) Collecting rotary_embedding_torch (from opensora==1.1.0) Downloading Building wheels for collected packages: opensora, pandarallel Building wheel for opensora (setup.py) ... •[?25ldone •[?25h Created wheel for opensora: filename=opensora-1.1.0-py3-none-any.whl size=195249 sha256=86c66de7ded305b2e4fb07992d0147c0408086cc31cdc31d97bcea44d8f69596 Stored in directory: /home/ma-user/.cache/pip/wheels/ae/34/85/7f84dd36f2e448d8d4455272d3358f557d0a570011d1701074 Building wheel for pandarallel (setup.py) ... •[?25ldone •[?25h Created wheel for pandarallel: filename=pandarallel-1.6.5-py3-none-any.whl size=16673 sha256=b97386c92d34443f19cc88ea717c6cca143ef2b8f1f1ac79f4645c37d230bafc Stored in directory: /home/ma-user/.cache/pip/wheels/f6/dd/25/a1c3775e721641ff67c71b3652e901e7e52611c6c3091784c9 Successfully built opensora pandarallel Installing collected packages: pytz, tzdata, pyarrow, dill, beartype, av, pandas, pandarallel, rotary_embedding_torch, opensora Successfully installed av-12.1.0 beartype-0.18.5 dill-0.3.8 opensora-1.1.0 pandarallel-1.6.5 pandas-2.2.2 pyarrow-16.1.0 pytz-2024.1 rotary_embedding_torch-0.6.2 tzdata-2024.1 !pip install spaces gradio MoviePy -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn !cp /home/ma-user/work/frpc_linux_amd64 /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/gradio/frpc_linux_amd64_v0.2 !chmod +x /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/gradio/frpc_linux_amd64_v0.2 Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting spaces Downloading https://pypi.tuna.tsinghua.edu.cn/packages/b2/3c/6205090507ea96e6e56d0deda8d0fc4c507026ef3772e55b637a5d0b7c61/spaces-0.28.3-py3-none-any.whl (18 kB) Collecting gradio Downloading https://pypi.tuna.tsinghua.edu.cn/packages/d1/37/f49320600cdf1fa856cc605a2e20e9debd34b5425b53f49abdb2ea463716/gradio-4.32.2-py3-none-any.whl (12.3 MB) •[2K •[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━•[0m •[32m12.3/12.3 MB•[0m •[31m5.2 MB/s•[0m eta •[36m0:00:00•[0m00:01•[0m00:01•[0m ​ Successfully uninstalled decorator-5.1.1 •[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. fabric 3.2.2 requires decorator>=5, but you have decorator 4.4.2 which is incompatible.•[0m•[31m •[0mSuccessfully installed MoviePy-1.0.3 aiofiles-23.2.1 altair-5.3.0 anyio-4.4.0 decorator-4.4.2 dnspython-2.6.1 email_validator-2.1.1 fastapi-0.111.0 fastapi-cli-0.0.4 ffmpy-0.3.2 gradio-4.32.2 gradio-client-0.17.0 h11-0.14.0 httpcore-1.0.5 httptools-0.6.1 httpx-0.27.0 imageio-2.34.1 imageio_ffmpeg-0.5.1 importlib-resources-6.4.0 orjson-3.10.3 proglog-0.1.10 pydub-0.25.1 python-dotenv-1.0.1 python-multipart-0.0.9 ruff-0.4.7 semantic-version-2.10.0 shellingham-1.5.4 sniffio-1.3.1 spaces-0.28.3 starlette-0.37.2 tomlkit-0.12.0 toolz-0.12.1 typer-0.12.3 ujson-5.10.0 uvicorn-0.30.1 uvloop-0.19.0 watchfiles-0.22.0 websockets-11.0.3 3. 生成视频 修改模型配置文件: %%writefile configs/opensora-v1-1/inference/sample.py num_frames = 16 frame_interval = 3 fps = 24 image_size = (240, 426) multi_resolution = "STDiT2" ​ # Define model model = dict( type="STDiT2-XL/2", from_pretrained="hpcai-tech/OpenSora-STDiT-v2-stage3", input_sq_size=512, # 使用huggingface上下载好的模型权重 qk_norm=True, enable_flash_attn=True, enable_layernorm_kernel=True, ) vae = dict( type="VideoAutoencoderKL", from_pretrained="./opensora/models/sd-vae-ft-ema", cache_dir=None, # 修改为从当前目录加载 micro_batch_size=4, ) text_encoder = dict( type="t5", from_pretrained="./opensora/models/text_encoder/t5-v1_1-xxl", cache_dir=None, # 修改为从当前目录加载 model_max_length=200, ) scheduler = dict( type="iddpm", num_sampling_steps=100, cfg_scale=7.0, cfg_channel=3, # or None ) dtype = "fp16" ​ # Condition prompt_path = "./assets/texts/t2v_samples.txt" prompt = None # prompt has higher priority than prompt_path ​ # Others batch_size = 1 seed = 42 save_dir = "./samples/samples/" Overwriting configs/opensora-v1-1/inference/sample.py import os ​ os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' !cp /home/ma-user/work/t5.py /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/opensora/models/text_encoder/t5.py # text to video !python scripts/inference.py configs/opensora-v1-1/inference/sample.py --prompt "A fashion girl walking on the streets of Tokyo" --num-frames 32 --image-size 240 426 /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/colossalai/shardformer/layer/normalization.py:45: UserWarning: Please install apex from source (https://github.com/NVIDIA/apex) to use the fused layernorm kernel warnings.warn("Please install apex from source (https://github.com/NVIDIA/apex) to use the fused layernorm kernel") Config (path: configs/opensora-v1-1/inference/sample.py): {'num_frames': 32, 'frame_interval': 3, 'fps': 24, 'image_size': [240, 426], 'multi_resolution': 'STDiT2', 'model': {'type': 'STDiT2-XL/2', 'from_pretrained': 'hpcai-tech/OpenSora-STDiT-v2-stage3', 'input_sq_size': 512, 'qk_norm': True, 'enable_flash_attn': True, 'enable_layernorm_kernel': True}, 'vae': {'type': 'VideoAutoencoderKL', 'from_pretrained': './opensora/models/sd-vae-ft-ema', 'cache_dir': None, 'micro_batch_size': 4}, 'text_encoder': {'type': 't5', 'from_pretrained': './opensora/models/text_encoder/t5-v1_1-xxl', 'cache_dir': None, 'model_max_length': 200}, 'scheduler': {'type': 'iddpm', 'num_sampling_steps': 100, 'cfg_scale': 7.0, 'cfg_channel': 3}, 'dtype': 'fp16', 'prompt_path': './assets/texts/t2v_samples.txt', 'prompt': ['A fashion girl walking on the streets of Tokyo'], 'batch_size': 1, 'seed': 42, 'save_dir': './samples/samples/', 'config': 'configs/opensora-v1-1/inference/sample.py', 'prompt_as_path': False, 'reference_path': None, 'loop': 1, 'sample_name': None, 'num_sample': 1} Loading checkpoint shards: 0%* * 0/2 [00:00<?, ?it/s]/home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/torch/_utils.py:776: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly. To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage() return self.fget.__get__(instance, owner)() Loading checkpoint shards: 100%*██████████████████* 2/2 [00:35<00:00, 17.87s/it] /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`. warnings.warn( 100%*█████████████████████████████████████████* 100/100 [02:11<00:00, 1.32s/it] Prompt: A fashion girl walking on the streets of Tokyo Saved to ./samples/samples/sample_0.mp4 生成的视频保存在Open-Sora/samples文件夹中,随机查看: import os import random from moviepy.editor import * from IPython.display import Image ​ # 视频存放目录 video_root = 'samples/samples' # 列出所有文件 videos = os.listdir(video_root) # 随机抽取视频 video = random.sample(videos, 1)[0] # 视频输入路径 video_path = os.path.join(video_root, video) # 加载原始视频 clip = VideoFileClip(video_path) # 保存为GIF文件 clip.write_gif("output_animation.gif", fps=10) # 显示生成结果 Image(open('output_animation.gif','rb').read()) MoviePy - Building file output_animation.gif with imageio. 4. Gradio 界面 修改配置文件: %%writefile configs/opensora-v1-1/inference/sample-ref.py num_frames = 16 frame_interval = 3 fps = 24 image_size = (240, 426) multi_resolution = "STDiT2" ​ # Condition prompt_path = None prompt = [ "A car driving on the ocean.", "In an ornate, historical hall, a massive tidal wave peaks and begins to crash. Two surfers, seizing the moment, skillfully navigate the face of the wave.", ] ​ loop = 2 condition_frame_length = 4 # ( # loop id, [the loop index of the condition image or video] # reference id, [the index of the condition image or video in the reference_path] # reference start, [the start frame of the condition image or video] # target start, [the location to insert] # length, [the number of frames to insert] # edit_ratio [the edit rate of the condition image or video] # ) # See https://github.com/hpcaitech/Open-Sora/blob/main/docs/config.md#advanced-inference-config for more details # See https://github.com/hpcaitech/Open-Sora/blob/main/docs/commands.md#inference-with-open-sora-11 for more examples mask_strategy = [ "0,0,0,0,8,0.3", None, "0", ] reference_path = [ "https://cdn.openai.com/tmp/s/interp/d0.mp4", None, "assets/images/condition/wave.png", ] ​ # Define model model = dict( type="STDiT2-XL/2", from_pretrained="hpcai-tech/OpenSora-STDiT-v2-stage3", input_sq_size=512, # 使用huggingface上下载好的模型权重 qk_norm=True, enable_flash_attn=True, enable_layernorm_kernel=True, ) vae = dict( type="VideoAutoencoderKL", from_pretrained="./opensora/models/sd-vae-ft-ema", cache_dir=None, # 修改为从当前目录加载 micro_batch_size=4, ) text_encoder = dict( type="t5", from_pretrained="./opensora/models/text_encoder/t5-v1_1-xxl", cache_dir=None, # 修改为从当前目录加载 model_max_length=200, ) scheduler = dict( type="iddpm", num_sampling_steps=100, cfg_scale=7.0, cfg_channel=3, # or None ) dtype = "fp16" ​ # Others batch_size = 1 seed = 42 save_dir = "./samples/samples/" Overwriting configs/opensora-v1-1/inference/sample-ref.py 修改Gradio应用: %%writefile gradio/app-ref.py import argparse import importlib import os import subprocess import sys import re import json import math import spaces import torch import gradio as gr from tempfile import NamedTemporaryFile import datetime from transformers import pipeline ​ zh2en = pipeline("translation", model="./opus-mt-zh-en") ​ MODEL_TYPES = ["v1.1-stage2", "v1.1-stage3"] CONFIG_MAP = { "v1.1-stage2": "configs/opensora-v1-1/inference/sample-ref.py", "v1.1-stage3": "configs/opensora-v1-1/inference/sample-ref.py", } HF_STDIT_MAP = { "v1.1-stage2": "hpcai-tech/OpenSora-STDiT-v2-stage2", "v1.1-stage3": "hpcai-tech/OpenSora-STDiT-v2-stage3", } RESOLUTION_MAP = { "144p": { "16:9": (256, 144), "9:16": (144, 256), "4:3": (221, 165), "3:4": (165, 221), "1:1": (192, 192), }, "240p": { "16:9": (426, 240), "9:16": (240, 426), "4:3": (370, 278), "3:4": (278, 370), "1:1": (320, 320), }, "360p": { "16:9": (640, 360), "9:16": (360, 640), "4:3": (554, 416), "3:4": (416, 554), "1:1": (480, 480), }, "480p": { "16:9": (854, 480), "9:16": (480, 854), "4:3": (740, 555), "3:4": (555, 740), "1:1": (640, 640), }, "720p": { "16:9": (1280, 720), "9:16": (720, 1280), "4:3": (1108, 832), "3:4": (832, 1110), "1:1": (960, 960), }, } ​ ​ # ============================ # Utils # ============================ def collect_references_batch(reference_paths, vae, image_size): from opensora.datasets.utils import read_from_path ​ refs_x = [] for reference_path in reference_paths: if reference_path is None: refs_x.append([]) continue ref_path = reference_path.split(";") ref = [] for r_path in ref_path: r = read_from_path(r_path, image_size, transform_name="resize_crop") r_x = vae.encode(r.unsqueeze(0).to(vae.device, vae.dtype)) r_x = r_x.squeeze(0) ref.append(r_x) refs_x.append(ref) # refs_x: [batch, ref_num, C, T, H, W] return refs_x ​ ​ def process_mask_strategy(mask_strategy): mask_batch = [] mask_strategy = mask_strategy.split(";") for mask in mask_strategy: mask_group = mask.split(",") assert len(mask_group) >= 1 and len(mask_group) <= 6, f"Invalid mask strategy: {mask}" if len(mask_group) == 1: mask_group.extend(["0", "0", "0", "1", "0"]) elif len(mask_group) == 2: mask_group.extend(["0", "0", "1", "0"]) elif len(mask_group) == 3: mask_group.extend(["0", "1", "0"]) elif len(mask_group) == 4: mask_group.extend(["1", "0"]) elif len(mask_group) == 5: mask_group.append("0") mask_batch.append(mask_group) return mask_batch ​ ​ def apply_mask_strategy(z, refs_x, mask_strategys, loop_i): masks = [] for i, mask_strategy in enumerate(mask_strategys): mask = torch.ones(z.shape[2], dtype=torch.float, device=z.device) if mask_strategy is None: masks.append(mask) continue mask_strategy = process_mask_strategy(mask_strategy) for mst in mask_strategy: loop_id, m_id, m_ref_start, m_target_start, m_length, edit_ratio = mst loop_id = int(loop_id) if loop_id != loop_i: continue m_id = int(m_id) m_ref_start = int(m_ref_start) m_length = int(m_length) m_target_start = int(m_target_start) edit_ratio = float(edit_ratio) ref = refs_x[i][m_id] # [C, T, H, W] if m_ref_start < 0: m_ref_start = ref.shape[1] + m_ref_start if m_target_start < 0: # z: [B, C, T, H, W] m_target_start = z.shape[2] + m_target_start z[i, :, m_target_start : m_target_start + m_length] = ref[:, m_ref_start : m_ref_start + m_length] mask[m_target_start : m_target_start + m_length] = edit_ratio masks.append(mask) masks = torch.stack(masks) return masks ​ ​ def process_prompts(prompts, num_loop): from opensora.models.text_encoder.t5 import text_preprocessing ​ ret_prompts = [] for prompt in prompts: if prompt.startswith("*0*"): prompt_list = prompt.split("*")[1:] text_list = [] for i in range(0, len(prompt_list), 2): start_loop = int(prompt_list[i]) text = prompt_list[i + 1] text = text_preprocessing(text) end_loop = int(prompt_list[i + 2]) if i + 2 < len(prompt_list) else num_loop text_list.extend([text] * (end_loop - start_loop)) assert len(text_list) == num_loop, f"Prompt loop mismatch: {len(text_list)} != {num_loop}" ret_prompts.append(text_list) else: prompt = text_preprocessing(prompt) ret_prompts.append([prompt] * num_loop) return ret_prompts ​ ​ def extract_json_from_prompts(prompts): additional_infos = [] ret_prompts = [] for prompt in prompts: parts = re.split(r"(?=[{\[])", prompt) assert len(parts) <= 2, f"Invalid prompt: {prompt}" ret_prompts.append(parts[0]) if len(parts) == 1: additional_infos.append({}) else: additional_infos.append(json.loads(parts[1])) return ret_prompts, additional_infos ​ ​ # ============================ # Model-related # ============================ def read_config(config_path): """ Read the configuration file. """ from mmengine.config import Config ​ return Config.fromfile(config_path) ​ ​ def build_models(model_type, config, enable_optimization=False): """ Build the models for the given model type and configuration. """ # build vae from opensora.registry import MODELS, build_module ​ vae = build_module(config.vae, MODELS).cuda() ​ # build text encoder text_encoder = build_module(config.text_encoder, MODELS) # T5 must be fp32 text_encoder.t5.model = text_encoder.t5.model.cuda() ​ # build stdit # we load model from HuggingFace directly so that we don't need to # handle model download logic in HuggingFace Space from opensora.models.stdit.stdit2 import STDiT2 ​ stdit = STDiT2.from_pretrained( HF_STDIT_MAP[model_type], enable_flash_attn=enable_optimization, trust_remote_code=True, ).cuda() ​ # build scheduler from opensora.registry import SCHEDULERS ​ scheduler = build_module(config.scheduler, SCHEDULERS) ​ # hack for classifier-free guidance text_encoder.y_embedder = stdit.y_embedder ​ # move modelst to device vae = vae.to(torch.float16).eval() text_encoder.t5.model = text_encoder.t5.model.eval() # t5 must be in fp32 stdit = stdit.to(torch.float16).eval() ​ # clear cuda torch.cuda.empty_cache() return vae, text_encoder, stdit, scheduler ​ ​ def parse_args(): parser = argparse.ArgumentParser() parser.add_argument( "--model-type", default="v1.1-stage3", choices=MODEL_TYPES, help=f"The type of model to run for the Gradio App, can only be {MODEL_TYPES}", ) parser.add_argument("--output", default="./outputs", type=str, help="The path to the output folder") parser.add_argument("--port", default=None, type=int, help="The port to run the Gradio App on.") parser.add_argument("--host", default=None, type=str, help="The host to run the Gradio App on.") parser.add_argument("--share", action="store_true", help="Whether to share this gradio demo.") parser.add_argument( "--enable-optimization", action="store_true", help="Whether to enable optimization such as flash attention and fused layernorm", ) return parser.parse_args() ​ ​ # ============================ # Main Gradio Script # ============================ # as `run_inference` needs to be wrapped by `spaces.GPU` and the input can only be the prompt text # so we can't pass the models to `run_inference` as arguments. # instead, we need to define them globally so that we can access these models inside `run_inference` ​ # read config args = parse_args() config = read_config(CONFIG_MAP[args.model_type]) ​ # make outputs dir os.makedirs(args.output, exist_ok=True) ​ # disable torch jit as it can cause failure in gradio SDK # gradio sdk uses torch with cuda 11.3 torch.jit._state.disable() ​ # import after installation from opensora.datasets import IMG_FPS, save_sample from opensora.utils.misc import to_torch_dtype ​ # some global variables dtype = to_torch_dtype(config.dtype) device = torch.device("cuda") ​ # build model vae, text_encoder, stdit, scheduler = build_models(args.model_type, config, enable_optimization=args.enable_optimization) ​ ​ def run_inference(mode, prompt_text, resolution, aspect_ratio, length, reference_image, seed, sampling_steps, cfg_scale): torch.manual_seed(seed) with torch.inference_mode(): # ====================== # 1. Preparation # ====================== # parse the inputs resolution = RESOLUTION_MAP[resolution][aspect_ratio] ​ # gather args from config num_frames = config.num_frames frame_interval = config.frame_interval fps = config.fps condition_frame_length = config.condition_frame_length ​ # compute number of loops if mode == "Text2Image": num_frames = 1 num_loop = 1 else: num_seconds = int(length.rstrip('s')) if num_seconds <= 16: num_frames = num_seconds * fps // frame_interval num_loop = 1 else: config.num_frames = 16 total_number_of_frames = num_seconds * fps / frame_interval num_loop = math.ceil((total_number_of_frames - condition_frame_length) / (num_frames - condition_frame_length)) ​ # prepare model args if config.num_frames == 1: fps = IMG_FPS ​ model_args = dict() height_tensor = torch.tensor([resolution[0]], device=device, dtype=dtype) width_tensor = torch.tensor([resolution[1]], device=device, dtype=dtype) num_frames_tensor = torch.tensor([num_frames], device=device, dtype=dtype) ar_tensor = torch.tensor([resolution[0] / resolution[1]], device=device, dtype=dtype) fps_tensor = torch.tensor([fps], device=device, dtype=dtype) model_args["height"] = height_tensor model_args["width"] = width_tensor model_args["num_frames"] = num_frames_tensor model_args["ar"] = ar_tensor model_args["fps"] = fps_tensor ​ # compute latent size input_size = (num_frames, *resolution) latent_size = vae.get_latent_size(input_size) ​ # process prompt prompt = zh2en(prompt_text)[0].get("translation_text") prompt_raw = [prompt] print(prompt_raw) prompt_raw, _ = extract_json_from_prompts(prompt_raw) prompt_loops = process_prompts(prompt_raw, num_loop) video_clips = [] ​ # prepare mask strategy if mode == "Text2Image": mask_strategy = [None] elif mode == "Text2Video": if reference_image is not None: mask_strategy = ['0'] else: mask_strategy = [None] else: raise ValueError(f"Invalid mode: {mode}") ​ # ========================= # 2. Load reference images # ========================= if mode == "Text2Image": refs_x = collect_references_batch([None], vae, resolution) elif mode == "Text2Video": if reference_image is not None: # save image to disk from PIL import Image im = Image.fromarray(reference_image) ​ with NamedTemporaryFile(suffix=".jpg") as temp_file: im.save(temp_file.name) refs_x = collect_references_batch([temp_file.name], vae, resolution) else: refs_x = collect_references_batch([None], vae, resolution) else: raise ValueError(f"Invalid mode: {mode}") ​ # 4.3. long video generation for loop_i in range(num_loop): # 4.4 sample in hidden space batch_prompts = [prompt[loop_i] for prompt in prompt_loops] z = torch.randn(len(batch_prompts), vae.out_channels, *latent_size, device=device, dtype=dtype) ​ # 4.5. apply mask strategy masks = None ​ # if cfg.reference_path is not None: if loop_i > 0: ref_x = vae.encode(video_clips[-1]) for j, refs in enumerate(refs_x): if refs is None: refs_x[j] = [ref_x[j]] else: refs.append(ref_x[j]) if mask_strategy[j] is None: mask_strategy[j] = "" else: mask_strategy[j] += ";" mask_strategy[ j ] += f"{loop_i},{len(refs)-1},-{condition_frame_length},0,{condition_frame_length}" ​ masks = apply_mask_strategy(z, refs_x, mask_strategy, loop_i) ​ # 4.6. diffusion sampling # hack to update num_sampling_steps and cfg_scale scheduler_kwargs = config.scheduler.copy() scheduler_kwargs.pop('type') scheduler_kwargs['num_sampling_steps'] = sampling_steps scheduler_kwargs['cfg_scale'] = cfg_scale ​ scheduler.__init__( **scheduler_kwargs ) samples = scheduler.sample( stdit, text_encoder, z=z, prompts=batch_prompts, device=device, additional_args=model_args, mask=masks, # scheduler must support mask ) samples = vae.decode(samples.to(dtype)) video_clips.append(samples) ​ # 4.7. save video if loop_i == num_loop - 1: video_clips_list = [ video_clips[0][0]] + [video_clips[i][0][:, config.condition_frame_length :] for i in range(1, num_loop) ] video = torch.cat(video_clips_list, dim=1) current_datetime = datetime.datetime.now() timestamp = current_datetime.timestamp() save_path = os.path.join(args.output, f"output_{timestamp}") saved_path = save_sample(video, save_path=save_path, fps=config.fps // config.frame_interval) return saved_path ​ @spaces.GPU(duration=200) def run_image_inference(prompt_text, resolution, aspect_ratio, length, reference_image, seed, sampling_steps, cfg_scale): return run_inference("Text2Image", prompt_text, resolution, aspect_ratio, length, reference_image, seed, sampling_steps, cfg_scale) ​ @spaces.GPU(duration=200) def run_video_inference(prompt_text, resolution, aspect_ratio, length, reference_image, seed, sampling_steps, cfg_scale): return run_inference("Text2Video", prompt_text, resolution, aspect_ratio, length, reference_image, seed, sampling_steps, cfg_scale) ​ ​ def main(): # create demo with gr.Blocks() as demo: with gr.Row(): with gr.Column(): gr.HTML("""<h1 align="center">Open-Sora 1.1</h1>""") ​ with gr.Row(): with gr.Column(): prompt_text = gr.Textbox( label="Prompt", placeholder="请输入中文提示词", lines=4, ) resolution = gr.Radio( choices=["144p", "240p", "360p", "480p", "720p"], value="240p", label="Resolution", ) aspect_ratio = gr.Radio( choices=["9:16", "16:9", "3:4", "4:3", "1:1"], value="9:16", label="Aspect Ratio (H:W)", ) length = gr.Radio( choices=["2s", "4s", "8s", "16s"], value="2s", label="Video Length (only effective for video generation)", info="8s may fail as Hugging Face ZeroGPU has the limitation of max 200 seconds inference time." ) ​ with gr.Row(): seed = gr.Slider( value=1024, minimum=1, maximum=2048, step=1, label="Seed" ) ​ sampling_steps = gr.Slider( value=100, minimum=1, maximum=200, step=1, label="Sampling steps" ) cfg_scale = gr.Slider( value=7.0, minimum=0.0, maximum=10.0, step=0.1, label="CFG Scale" ) reference_image = gr.Image( label="Reference Image (Optional)", ) with gr.Column(): output_video = gr.Video( label="Output Video", height="100%" ) ​ with gr.Row(): image_gen_button = gr.Button("Generate image") video_gen_button = gr.Button("Generate video") ​ image_gen_button.click( fn=run_image_inference, inputs=[prompt_text, resolution, aspect_ratio, length, reference_image, seed, sampling_steps, cfg_scale], outputs=reference_image ) video_gen_button.click( fn=run_video_inference, inputs=[prompt_text, resolution, aspect_ratio, length, reference_image, seed, sampling_steps, cfg_scale], outputs=output_video ) ​ # launch demo.launch(share=True, inbrowser=True) ​ if __name__ == "__main__": main() Writing gradio/app-ref.py 运行Gradio应用,运行成功后点击 Running on public URL 后的网页链接即可体验! !python gradio/app-ref.py /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/torch/_utils.py:776: UserWarning: TypedStorage is deprecated. It will be removed in the future and UntypedStorage will be the only storage class. This should only matter to you if you are using storages directly. To access UntypedStorage directly, use tensor.untyped_storage() instead of tensor.storage() return self.fget.__get__(instance, owner)() /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/transformers/models/marian/tokenization_marian.py:197: UserWarning: Recommended: pip install sacremoses. warnings.warn("Recommended: pip install sacremoses.") /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/colossalai/shardformer/layer/normalization.py:45: UserWarning: Please install apex from source (https://github.com/NVIDIA/apex) to use the fused layernorm kernel warnings.warn("Please install apex from source (https://github.com/NVIDIA/apex) to use the fused layernorm kernel") Loading checkpoint shards: 100%*██████████████████* 2/2 [00:32<00:00, 16.15s/it] /home/ma-user/anaconda3/envs/python-3.10.10/lib/python3.10/site-packages/huggingface_hub/file_download.py:1132: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`. warnings.warn( Running on local URL: http://127.0.0.1:7860 Running on public URL: https://64147712240bbb3753.gradio.live ​ This share link expires in 72 hours. For free permanent hosting and GPU upgrades, run `gradio deploy` from Terminal to deploy to Spaces (https://huggingface.co/spaces) 我们也准备了一些提示词以供参考: 一只穿着紫色长袍的胖兔子穿过奇幻的风景 海浪冲击着孤零零的灯塔,不祥的灯光 一个神秘的森林展示了旅行者的冒险经历 一个蓝头发的法师在唱歌 一个超现实的景观,漂浮的岛屿和空中的瀑布 一只蓝鸟站在水里 一个年轻人独自走在海边 粉红色的玫瑰在玻璃表面滴,特写 驱车远眺,一列地铁正从隧道中驶出 太空中所有的行星都是绿色和粉色的,背景是明亮的白色恒星 一座漂浮在星体空间的城市,有星星和星云 高楼顶上的日出 粉色和青色粉末爆炸 树林里的鹿在阳光下凝视着相机 一道闪电,一个巫师从稀薄的空气中出现了,他的长袍在风中翻腾 夜晚的未来赛博朋克城市景观,高耸的霓虹灯照亮的摩天大楼 在这里,树木、花朵和动物聚集在一起,谱写出一曲大自然的交响乐 一艘幽灵般的船在云层中航行,在月光下的天空中航行 日落和美丽的海滩 一个年轻人独自走在森林里 生成好的视频也可以使用MusicGen进行配乐,使用AI进行短视频创作。 5. 视频效果展示 提示词:一个极端的特写一个头发花白的胡子的男人在他的60年代,他在思想深处思考宇宙的历史,他坐在一家咖啡馆在巴黎,他的眼睛关注人私生活方面大多像他坐在他们走不动,他穿着一件羊毛外套西装外套和一件衬衫,他穿着一件棕色的贝雷帽,眼镜和有一个非常专业的外表,和结束他提供了一个微妙的封闭式的笑容好像找到了答案的神秘生活,灯光非常电影化,金色的灯光和巴黎的街道和城市作为背景,景深,电影化的35mm胶片。 提示词:无人机拍摄的海浪冲击着大苏尔加雷角海滩上崎岖的悬崖。蓝色的海水拍打着白色的波浪,夕阳的金色光芒照亮了岩石海岸。远处有一座小岛,岛上有一座灯塔,悬崖边上长满了绿色的灌木丛。从公路到海滩的陡峭落差是一个戏剧性的壮举,悬崖的边缘突出在海面上。这是一幅捕捉到海岸原始美景和太平洋海岸公路崎岖景观的景色。 提示词:一段高耸的无人机镜头捕捉到了海岸悬崖的雄伟之美,它的红色和黄色分层岩石表面色彩丰富,映衬着充满活力的绿松石般的大海。可以看到海鸟在悬崖峭壁上飞翔。当无人机从不同角度缓慢移动时,变化的阳光投射出移动的阴影,突出了悬崖的崎岖纹理和周围平静的大海。水轻轻地拍打着岩石基座和附着在悬崖顶部的绿色植物,这一场景给人一种宁静的感觉,在海洋的边缘孤立。这段视频捕捉了未受人类建筑影响的原始自然美的本质。 ​ ​ 提示词:雄伟美丽的瀑布从悬崖上倾泻而下,进入宁静的湖泊。瀑布,以其强大的流量,是视频的中心焦点。周围的景色郁郁葱葱,树木和树叶增添了自然美景。相机角度提供了瀑布的鸟瞰图,让观众欣赏瀑布的全部高度和壮观。这段视频令人惊叹地展现了大自然的力量和美。 ​ 提示词:夜晚熙熙攘攘的城市街道,充满了汽车前灯的光辉和街灯的环境光。场景是一个模糊的运动,汽车飞驰而过,行人在人行横道上穿行。城市景观是高耸的建筑和照明标志的混合,创造了一个充满活力和动态的氛围。视频的视角是高角度的,提供了街道及其周围环境的鸟瞰图。整个视频的风格充满活力和活力,捕捉到了夜晚城市生活的精髓。 ​ 提示词:森林地区宁静的夜景。第一个画面是一个宁静的湖泊,倒映着繁星满天的夜空。第二帧展示了美丽的日落,在风景上投下温暖的光芒。第三帧展示了夜空,充满了星星和充满活力的银河系。这段视频是延时拍摄的,捕捉了从白天到夜晚的过渡,湖泊和森林作为恒定的背景。视频的风格是自然主义的,强调夜空的美丽和森林的宁静。 点击关注,第一时间了解华为云新鲜技术~

优秀的个人博客,低调大师

用 Spring Boot 3.2 虚拟线程搭建静态文件服务器有多快?

Spring Boot 3.2 于 2023 年 11 月大张旗鼓地发布,标志着 Java 开发领域的一个关键时刻。这一突破性的版本引入了一系列革命性的功能,包括: 虚拟线程:利用 Project Loom 的虚拟线程释放可扩展性,从而减少资源消耗并增强并发性。 Native Image支持:通过Native Image编译制作速度极快的应用程序,减少启动时间并优化资源利用率。 JVM 检查点:利用 CRaC 项目的 JVM 检查点机制实现应用程序的快速重启,无需冗长的重新初始化。 RestClient:采用新的 RestClient 接口的功能方法,简化 HTTP 交互并简化代码。 Spring for Apache Pulsar:利用 Apache Pulsar 的强大功能实现强大的消息传递功能,无缝集成到您的 Spring Boot 应用程序中。 其中,虚拟线程是最近 Java 版本中引入的最具变革性的特性之一。正如官方文件所述:虚拟线程是轻量级线程,可减少编写、维护和调试高吞吐量并发应用程序的工作量。线程是可以调度的最小处理单元。它与其他此类单位同时运行,并且在很大程度上独立于其他此类单元运行。它是 java.lang.Thread 的一个实例。有两种线程:平台线程和虚拟线程。平台线程是作为操作系统 (OS) 线程的瘦包装器实现的。平台线程在其底层操作系统线程上运行 Java 代码,平台线程在平台线程的整个生命周期内捕获其操作系统线程。因此,可用平台线程数限制为操作系统线程数。与平台线程一样,虚拟线程也是 java.lang.Thread 的实例。但是,虚拟线程不绑定到特定的操作系统线程。虚拟线程仍在操作系统线程上运行代码。但是,当在虚拟线程中运行的代码调用阻塞 I/O 操作时,Java 运行时会挂起虚拟线程,直到它可以恢复为止。与挂起的虚拟线程关联的操作系统线程现在可以自由地对其他虚拟线程执行操作。虚拟线程适用于运行大部分时间被阻塞的任务,通常等待 I/O 操作完成。但是,它们不适用于长时间运行的 CPU 密集型操作。 虽然人们普遍认为虚拟线程在 I/O 密集型方案中表现出色,但它们在 CPU 密集型任务中的性能仍然是一个问号。本系列文章深入探讨了虚拟线程在各种用例中的潜在优势,从基本的“hello world”到静态文件服务(I/O 密集型)、QR 码生成(CPU 密集型)和多部分/表单数据处理(混合工作负载)等实际应用。 在本系列的开头文章中,我们已经了解了虚拟线程与物理线程相比在最简单(且不切实际)的 hello world 情况下的性能。物理线程和虚拟线程之间几乎没有任何性能或资源使用差异。在本文中,我们将更加“实用”,并针对静态文件服务器情况进行比较。这绝对是一个常见且“真实世界”的案例。让我们看看这次我们发现了什么。 如果大家正在做Spring Boot 2.3升级Spring 3.2,这里顺手给大家推荐Spring Boot 2.x 到 3.2 的升级指南。 测试环境 所有测试均在配备 16G RAM、8 个物理内核和 4 个效率内核的 MacBook Pro M2 上执行。测试工具是 Bombardier,它是更快的 HTTP 负载测试器之一(用 Go 编写)。 软件版本为: Java v21.0.1 Spring Boot 3.2.1 程序配置 除了主 Java 类之外,不需要编写任何 Java 文件,静态文件服务器只能通过配置就能发挥作用。 application.properties文件如下: server.port=3000 spring.mvc.static-path-pattern=/static/** spring.web.resources.static-locations=file:/Users/mayankc/Work/source/perfComparisons/static/ 使用虚拟线程时,我们将通过添加以下行来启用它们: spring.threads.virtual.enabled=true pom.xml内容: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.1</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>21</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> 测试数据 大小完全相同但数据不同的 100K 文件被放置在静态资源目录中。每个文件大小正好是 102400 字节。 文件的命名范围为 1 到 100000。 使用 Bombardier 的修改版本,为每次运行生成随机请求 URL: http://localhost:3000/static/<file-name> 应用场景 为了确保结果一致,每个测试在开始数据收集之前都会经历 5K 请求预热阶段。 然后,在不同范围的并发连接级别(50、100 和 300)中仔细记录测量结果,每个级别都承受 500 万个请求工作负载。 结果评估 除了简单地跟踪原始速度之外,我们还将采用详细的指标框架来捕获延迟分布(最小值、百分位数、最大值)和吞吐量(每秒请求数)。 CPU 和内存的资源使用情况监控将补充此分析,从而提供不同工作负载下系统性能的全面了解。 测试结果 结果以图表形式呈现如下: 总结 对静态文件服务的分析表明,物理线程在性能和资源效率方面略胜一筹(与我们的预期相反)。 不过,这种受 I/O 限制的场景可能并不是充分发挥虚拟线程潜力的理想场所。涉及数据库交互的任务可能会显示出更多令人信服的优势。也许负载不足以让虚拟线程发挥出最大的作用。为了找出答案,我们将在接下来的文章中介绍 URL短链(数据库驱动)、二维码生成(CPU受限)和混合工作负载场景(如表单数据处理),旨在揭示虚拟线程真正出类拔萃的案例。 欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册